1package im.conversations.android.xmpp.processor;
2
3import android.text.TextUtils;
4import android.util.Log;
5import eu.siacs.conversations.Config;
6import eu.siacs.conversations.entities.Account;
7import eu.siacs.conversations.generator.IqGenerator;
8import eu.siacs.conversations.services.XmppConnectionService;
9import eu.siacs.conversations.xmpp.XmppConnection;
10import eu.siacs.conversations.xmpp.manager.BookmarkManager;
11import eu.siacs.conversations.xmpp.manager.MessageDisplayedSynchronizationManager;
12import eu.siacs.conversations.xmpp.manager.PrivateStorageManager;
13import eu.siacs.conversations.xmpp.manager.RosterManager;
14import im.conversations.android.xmpp.model.stanza.Iq;
15
16public class BindProcessor extends XmppConnection.Delegate implements Runnable {
17
18 private final XmppConnectionService service;
19
20 public BindProcessor(final XmppConnectionService service, final XmppConnection connection) {
21 super(service.getApplicationContext(), connection);
22 this.service = service;
23 }
24
25 @Override
26 public void run() {
27 Log.d(Config.LOGTAG, "begin onBind()");
28 final var account = connection.getAccount();
29 final var features = connection.getFeatures();
30 service.cancelAvatarFetches(account);
31 final boolean loggedInSuccessfully =
32 account.setOption(Account.OPTION_LOGGED_IN_SUCCESSFULLY, true);
33 final boolean sosModified;
34 final var sos = features.getServiceOutageStatus();
35 if (sos != null) {
36 Log.d(Config.LOGTAG, account.getJid().asBareJid() + " server has SOS on " + sos);
37 sosModified = account.setKey(Account.KEY_SOS_URL, sos.toString());
38 } else {
39 sosModified = false;
40 }
41 final boolean gainedFeature =
42 account.setOption(Account.OPTION_HTTP_UPLOAD_AVAILABLE, features.httpUpload(0));
43 if (loggedInSuccessfully || gainedFeature || sosModified) {
44 service.databaseBackend.updateAccount(account);
45 }
46
47 if (loggedInSuccessfully) {
48 if (!TextUtils.isEmpty(account.getDisplayName())) {
49 Log.d(
50 Config.LOGTAG,
51 account.getJid().asBareJid()
52 + ": display name wasn't empty on first log in. publishing");
53 service.publishDisplayName(account);
54 }
55 }
56
57 connection.getManager(RosterManager.class).clearPresences();
58 synchronized (account.inProgressConferenceJoins) {
59 account.inProgressConferenceJoins.clear();
60 }
61 synchronized (account.inProgressConferencePings) {
62 account.inProgressConferencePings.clear();
63 }
64 service.getJingleConnectionManager().notifyRebound(account);
65 service.getQuickConversationsService().considerSyncBackground(false);
66
67 getManager(RosterManager.class).request();
68
69 if (features.bookmarks2()) {
70 connection.getManager(BookmarkManager.class).fetch();
71 // log that we use bookmarks 1 and wait for +notify
72 } else if (!features.bookmarksConversion()) {
73 connection.getManager(PrivateStorageManager.class).fetchBookmarks();
74 }
75
76 if (features.mds()) {
77 connection.getManager(MessageDisplayedSynchronizationManager.class).fetch();
78 } else {
79 Log.d(Config.LOGTAG, account.getJid() + ": server has no support for mds");
80 }
81 final boolean bind2 = features.bind2();
82 final boolean flexible = features.flexibleOfflineMessageRetrieval();
83 final boolean catchup = service.getMessageArchiveService().inCatchup(account);
84 final boolean trackOfflineMessageRetrieval;
85 if (!bind2 && flexible && catchup && connection.isMamPreferenceAlways()) {
86 trackOfflineMessageRetrieval = false;
87 connection.sendIqPacket(
88 IqGenerator.purgeOfflineMessages(),
89 (packet) -> {
90 if (packet.getType() == Iq.Type.RESULT) {
91 Log.d(
92 Config.LOGTAG,
93 account.getJid().asBareJid()
94 + ": successfully purged offline messages");
95 }
96 });
97 } else {
98 trackOfflineMessageRetrieval = true;
99 }
100 service.sendPresence(account);
101 connection.trackOfflineMessageRetrieval(trackOfflineMessageRetrieval);
102 if (service.getPushManagementService().available(account)) {
103 service.getPushManagementService().registerPushTokenOnServer(account);
104 }
105 service.connectMultiModeConversations(account);
106 connection.getManager(RosterManager.class).syncDirtyContacts();
107
108 service.getUnifiedPushBroker().renewUnifiedPushEndpointsOnBind(account);
109 Log.d(Config.LOGTAG, "end onBind()");
110 }
111}