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 final var account = connection.getAccount();
30 final var features = connection.getFeatures();
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(
43 Account.OPTION_HTTP_UPLOAD_AVAILABLE, account.httpUploadAvailable(0));
44 if (loggedInSuccessfully || gainedFeature || sosModified) {
45 service.databaseBackend.updateAccount(account);
46 }
47
48 if (loggedInSuccessfully) {
49 final String displayName = account.getDisplayName();
50 if (!Strings.isNullOrEmpty(displayName)) {
51 Log.d(
52 Config.LOGTAG,
53 account.getJid().asBareJid()
54 + ": display name wasn't empty on first log in. publishing");
55 getManager(NickManager.class).publish(displayName);
56 }
57 }
58
59 connection.getManager(RosterManager.class).clearPresences();
60 synchronized (account.inProgressConferenceJoins) {
61 account.inProgressConferenceJoins.clear();
62 }
63 synchronized (account.inProgressConferencePings) {
64 account.inProgressConferencePings.clear();
65 }
66 service.getJingleConnectionManager().notifyRebound(account);
67 service.getQuickConversationsService().considerSyncBackground(false);
68
69 getManager(RosterManager.class).request();
70
71 if (getManager(BookmarkManager.class).hasFeature()) {
72 connection.getManager(BookmarkManager.class).fetch();
73 } else if (getManager(LegacyBookmarkManager.class).hasConversion()) {
74 Log.d(
75 Config.LOGTAG,
76 account.getJid() + ": not fetching bookmarks. waiting for server to push");
77 } else {
78 connection.getManager(PrivateStorageManager.class).fetchBookmarks();
79 }
80
81 if (features.mds()) {
82 connection.getManager(MessageDisplayedSynchronizationManager.class).fetch();
83 } else {
84 Log.d(Config.LOGTAG, account.getJid() + ": server has no support for mds");
85 }
86 final boolean bind2 = features.bind2();
87 final boolean flexible = features.flexibleOfflineMessageRetrieval();
88 final boolean catchup = service.getMessageArchiveService().inCatchup(account);
89 final boolean trackOfflineMessageRetrieval;
90 if (!bind2 && flexible && catchup && connection.isMamPreferenceAlways()) {
91 trackOfflineMessageRetrieval = false;
92 connection.sendIqPacket(
93 IqGenerator.purgeOfflineMessages(),
94 (packet) -> {
95 if (packet.getType() == Iq.Type.RESULT) {
96 Log.d(
97 Config.LOGTAG,
98 account.getJid().asBareJid()
99 + ": successfully purged offline messages");
100 }
101 });
102 } else {
103 trackOfflineMessageRetrieval = true;
104 }
105 service.sendPresence(account);
106 connection.trackOfflineMessageRetrieval(trackOfflineMessageRetrieval);
107 if (service.getPushManagementService().available(account)) {
108 service.getPushManagementService().registerPushTokenOnServer(account);
109 }
110 service.connectMultiModeConversations(account);
111 connection.getManager(RosterManager.class).syncDirtyContacts();
112
113 service.getUnifiedPushBroker().renewUnifiedPushEndpointsOnBind(account);
114 }
115}