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