mirror of
https://github.com/moparisthebest/Conversations
synced 2024-11-24 09:42:17 -05:00
block code when doing unforced disconnect
This commit is contained in:
parent
c1716a35e3
commit
fb7359e6a3
@ -26,10 +26,9 @@ import android.os.SystemClock;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.provider.ContactsContract;
|
||||
import android.security.KeyChain;
|
||||
import android.security.KeyChainException;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.util.LruCache;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Pair;
|
||||
|
||||
import net.java.otr4j.OtrException;
|
||||
@ -38,16 +37,11 @@ import net.java.otr4j.session.SessionID;
|
||||
import net.java.otr4j.session.SessionImpl;
|
||||
import net.java.otr4j.session.SessionStatus;
|
||||
|
||||
import org.bouncycastle.asn1.x500.X500Name;
|
||||
import org.bouncycastle.asn1.x500.style.BCStyle;
|
||||
import org.bouncycastle.asn1.x500.style.IETFUtils;
|
||||
import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
|
||||
import org.openintents.openpgp.util.OpenPgpApi;
|
||||
import org.openintents.openpgp.util.OpenPgpServiceConnection;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.cert.CertificateEncodingException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
@ -124,9 +118,16 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||
|
||||
public static final String ACTION_CLEAR_NOTIFICATION = "clear_notification";
|
||||
public static final String ACTION_DISABLE_FOREGROUND = "disable_foreground";
|
||||
private static final String ACTION_MERGE_PHONE_CONTACTS = "merge_phone_contacts";
|
||||
public static final String ACTION_TRY_AGAIN = "try_again";
|
||||
public static final String ACTION_DISABLE_ACCOUNT = "disable_account";
|
||||
private static final String ACTION_MERGE_PHONE_CONTACTS = "merge_phone_contacts";
|
||||
private final SerialSingleThreadExecutor mFileAddingExecutor = new SerialSingleThreadExecutor();
|
||||
private final SerialSingleThreadExecutor mDatabaseExecutor = new SerialSingleThreadExecutor();
|
||||
private final IBinder mBinder = new XmppConnectionBinder();
|
||||
private final List<Conversation> conversations = new CopyOnWriteArrayList<>();
|
||||
private final IqGenerator mIqGenerator = new IqGenerator(this);
|
||||
private final List<String> mInProgressAvatarFetches = new ArrayList<>();
|
||||
public DatabaseBackend databaseBackend;
|
||||
private ContentObserver contactObserver = new ContentObserver(null) {
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
@ -137,89 +138,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||
startService(intent);
|
||||
}
|
||||
};
|
||||
|
||||
private final SerialSingleThreadExecutor mFileAddingExecutor = new SerialSingleThreadExecutor();
|
||||
private final SerialSingleThreadExecutor mDatabaseExecutor = new SerialSingleThreadExecutor();
|
||||
|
||||
private final IBinder mBinder = new XmppConnectionBinder();
|
||||
private final List<Conversation> conversations = new CopyOnWriteArrayList<>();
|
||||
private final FileObserver fileObserver = new FileObserver(
|
||||
FileBackend.getConversationsImageDirectory()) {
|
||||
|
||||
@Override
|
||||
public void onEvent(int event, String path) {
|
||||
if (event == FileObserver.DELETE) {
|
||||
markFileDeleted(path.split("\\.")[0]);
|
||||
}
|
||||
}
|
||||
};
|
||||
private final OnJinglePacketReceived jingleListener = new OnJinglePacketReceived() {
|
||||
|
||||
@Override
|
||||
public void onJinglePacketReceived(Account account, JinglePacket packet) {
|
||||
mJingleConnectionManager.deliverPacket(account, packet);
|
||||
}
|
||||
};
|
||||
private final OnBindListener mOnBindListener = new OnBindListener() {
|
||||
|
||||
@Override
|
||||
public void onBind(final Account account) {
|
||||
account.getRoster().clearPresences();
|
||||
fetchRosterFromServer(account);
|
||||
fetchBookmarks(account);
|
||||
sendPresence(account);
|
||||
connectMultiModeConversations(account);
|
||||
mMessageArchiveService.executePendingQueries(account);
|
||||
mJingleConnectionManager.cancelInTransmission();
|
||||
syncDirtyContacts(account);
|
||||
account.getAxolotlService().publishBundlesIfNeeded(true, false);
|
||||
}
|
||||
};
|
||||
private final OnMessageAcknowledged mOnMessageAcknowledgedListener = new OnMessageAcknowledged() {
|
||||
|
||||
@Override
|
||||
public void onMessageAcknowledged(Account account, String uuid) {
|
||||
for (final Conversation conversation : getConversations()) {
|
||||
if (conversation.getAccount() == account) {
|
||||
Message message = conversation.findUnsentMessageWithUuid(uuid);
|
||||
if (message != null) {
|
||||
markMessage(message, Message.STATUS_SEND);
|
||||
if (conversation.setLastMessageTransmitted(System.currentTimeMillis())) {
|
||||
databaseBackend.updateConversation(conversation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
private final IqGenerator mIqGenerator = new IqGenerator(this);
|
||||
public DatabaseBackend databaseBackend;
|
||||
public OnContactStatusChanged onContactStatusChanged = new OnContactStatusChanged() {
|
||||
|
||||
@Override
|
||||
public void onContactStatusChanged(Contact contact, boolean online) {
|
||||
Conversation conversation = find(getConversations(), contact);
|
||||
if (conversation != null) {
|
||||
if (online) {
|
||||
conversation.endOtrIfNeeded();
|
||||
if (contact.getPresences().size() == 1) {
|
||||
sendUnsentMessages(conversation);
|
||||
}
|
||||
} else {
|
||||
if (contact.getPresences().size() >= 1) {
|
||||
if (conversation.hasValidOtrSession()) {
|
||||
String otrResource = conversation.getOtrSession().getSessionID().getUserID();
|
||||
if (!(Arrays.asList(contact.getPresences().asStringArray()).contains(otrResource))) {
|
||||
conversation.endOtrIfNeeded();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
conversation.endOtrIfNeeded();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
private FileBackend fileBackend = new FileBackend(this);
|
||||
private MemorizingTrustManager mMemorizingTrustManager;
|
||||
private NotificationService mNotificationService = new NotificationService(
|
||||
@ -244,18 +162,103 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||
private List<Account> accounts;
|
||||
private JingleConnectionManager mJingleConnectionManager = new JingleConnectionManager(
|
||||
this);
|
||||
public OnContactStatusChanged onContactStatusChanged = new OnContactStatusChanged() {
|
||||
|
||||
@Override
|
||||
public void onContactStatusChanged(Contact contact, boolean online) {
|
||||
Conversation conversation = find(getConversations(), contact);
|
||||
if (conversation != null) {
|
||||
if (online) {
|
||||
conversation.endOtrIfNeeded();
|
||||
if (contact.getPresences().size() == 1) {
|
||||
sendUnsentMessages(conversation);
|
||||
}
|
||||
} else {
|
||||
if (contact.getPresences().size() >= 1) {
|
||||
if (conversation.hasValidOtrSession()) {
|
||||
String otrResource = conversation.getOtrSession().getSessionID().getUserID();
|
||||
if (!(Arrays.asList(contact.getPresences().asStringArray()).contains(otrResource))) {
|
||||
conversation.endOtrIfNeeded();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
conversation.endOtrIfNeeded();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
private HttpConnectionManager mHttpConnectionManager = new HttpConnectionManager(
|
||||
this);
|
||||
private AvatarService mAvatarService = new AvatarService(this);
|
||||
private final List<String> mInProgressAvatarFetches = new ArrayList<>();
|
||||
private MessageArchiveService mMessageArchiveService = new MessageArchiveService(this);
|
||||
private OnConversationUpdate mOnConversationUpdate = null;
|
||||
private final FileObserver fileObserver = new FileObserver(
|
||||
FileBackend.getConversationsImageDirectory()) {
|
||||
|
||||
@Override
|
||||
public void onEvent(int event, String path) {
|
||||
if (event == FileObserver.DELETE) {
|
||||
markFileDeleted(path.split("\\.")[0]);
|
||||
}
|
||||
}
|
||||
};
|
||||
private final OnJinglePacketReceived jingleListener = new OnJinglePacketReceived() {
|
||||
|
||||
@Override
|
||||
public void onJinglePacketReceived(Account account, JinglePacket packet) {
|
||||
mJingleConnectionManager.deliverPacket(account, packet);
|
||||
}
|
||||
};
|
||||
private final OnMessageAcknowledged mOnMessageAcknowledgedListener = new OnMessageAcknowledged() {
|
||||
|
||||
@Override
|
||||
public void onMessageAcknowledged(Account account, String uuid) {
|
||||
for (final Conversation conversation : getConversations()) {
|
||||
if (conversation.getAccount() == account) {
|
||||
Message message = conversation.findUnsentMessageWithUuid(uuid);
|
||||
if (message != null) {
|
||||
markMessage(message, Message.STATUS_SEND);
|
||||
if (conversation.setLastMessageTransmitted(System.currentTimeMillis())) {
|
||||
databaseBackend.updateConversation(conversation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
private int convChangedListenerCount = 0;
|
||||
private OnShowErrorToast mOnShowErrorToast = null;
|
||||
private int showErrorToastListenerCount = 0;
|
||||
private int unreadCount = -1;
|
||||
private OnAccountUpdate mOnAccountUpdate = null;
|
||||
private OnCaptchaRequested mOnCaptchaRequested = null;
|
||||
private int accountChangedListenerCount = 0;
|
||||
private int captchaRequestedListenerCount = 0;
|
||||
private OnRosterUpdate mOnRosterUpdate = null;
|
||||
private OnUpdateBlocklist mOnUpdateBlocklist = null;
|
||||
private int updateBlocklistListenerCount = 0;
|
||||
private int rosterChangedListenerCount = 0;
|
||||
private OnMucRosterUpdate mOnMucRosterUpdate = null;
|
||||
private int mucRosterChangedListenerCount = 0;
|
||||
private OnKeyStatusUpdated mOnKeyStatusUpdated = null;
|
||||
private int keyStatusUpdatedListenerCount = 0;
|
||||
private SecureRandom mRandom;
|
||||
private final OnBindListener mOnBindListener = new OnBindListener() {
|
||||
|
||||
@Override
|
||||
public void onBind(final Account account) {
|
||||
account.getRoster().clearPresences();
|
||||
fetchRosterFromServer(account);
|
||||
fetchBookmarks(account);
|
||||
sendPresence(account);
|
||||
connectMultiModeConversations(account);
|
||||
mMessageArchiveService.executePendingQueries(account);
|
||||
mJingleConnectionManager.cancelInTransmission();
|
||||
syncDirtyContacts(account);
|
||||
account.getAxolotlService().publishBundlesIfNeeded(true, false);
|
||||
}
|
||||
};
|
||||
private OnStatusChanged statusListener = new OnStatusChanged() {
|
||||
|
||||
@Override
|
||||
@ -313,17 +316,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||
getNotificationService().updateErrorNotification();
|
||||
}
|
||||
};
|
||||
private int accountChangedListenerCount = 0;
|
||||
private int captchaRequestedListenerCount = 0;
|
||||
private OnRosterUpdate mOnRosterUpdate = null;
|
||||
private OnUpdateBlocklist mOnUpdateBlocklist = null;
|
||||
private int updateBlocklistListenerCount = 0;
|
||||
private int rosterChangedListenerCount = 0;
|
||||
private OnMucRosterUpdate mOnMucRosterUpdate = null;
|
||||
private int mucRosterChangedListenerCount = 0;
|
||||
private OnKeyStatusUpdated mOnKeyStatusUpdated = null;
|
||||
private int keyStatusUpdatedListenerCount = 0;
|
||||
private SecureRandom mRandom;
|
||||
private OpenPgpServiceConnection pgpServiceConnection;
|
||||
private PgpEngine mPgpEngine = null;
|
||||
private WakeLock wakeLock;
|
||||
@ -333,6 +325,11 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||
private EventReceiver mEventReceiver = new EventReceiver();
|
||||
|
||||
private boolean mRestoredFromDatabase = false;
|
||||
|
||||
private static String generateFetchKey(Account account, final Avatar avatar) {
|
||||
return account.getJid().toBareJid() + "_" + avatar.owner + "_" + avatar.sha1sum;
|
||||
}
|
||||
|
||||
public boolean areMessagesInitialized() {
|
||||
return this.mRestoredFromDatabase;
|
||||
}
|
||||
@ -1338,6 +1335,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||
callback.informUser(R.string.account_already_exists);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
callback.informUser(R.string.unable_to_parse_certificate);
|
||||
}
|
||||
}
|
||||
@ -1364,13 +1362,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||
} else {
|
||||
showErrorToastInUi(R.string.jid_does_not_match_certificate);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (KeyChainException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvalidJidException e) {
|
||||
e.printStackTrace();
|
||||
} catch (CertificateEncodingException e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
@ -1378,7 +1370,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||
public void updateAccount(final Account account) {
|
||||
this.statusListener.onStatusChanged(account);
|
||||
databaseBackend.updateAccount(account);
|
||||
reconnectAccount(account, false, true);
|
||||
reconnectAccountInBackground(account);
|
||||
updateAccountUi();
|
||||
getNotificationService().updateErrorNotification();
|
||||
}
|
||||
@ -1791,10 +1783,14 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||
}
|
||||
|
||||
public void leaveMuc(Conversation conversation) {
|
||||
leaveMuc(conversation, false);
|
||||
}
|
||||
|
||||
private void leaveMuc(Conversation conversation, boolean now) {
|
||||
Account account = conversation.getAccount();
|
||||
account.pendingConferenceJoins.remove(conversation);
|
||||
account.pendingConferenceLeaves.remove(conversation);
|
||||
if (account.getStatus() == Account.State.ONLINE) {
|
||||
if (account.getStatus() == Account.State.ONLINE || now) {
|
||||
PresencePacket packet = new PresencePacket();
|
||||
packet.setTo(conversation.getJid());
|
||||
packet.setFrom(conversation.getAccount().getJid());
|
||||
@ -2006,7 +2002,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||
});
|
||||
}
|
||||
|
||||
public void disconnect(Account account, boolean force) {
|
||||
private void disconnect(Account account, boolean force) {
|
||||
if ((account.getStatus() == Account.State.ONLINE)
|
||||
|| (account.getStatus() == Account.State.DISABLED)) {
|
||||
if (!force) {
|
||||
@ -2014,7 +2010,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||
for (Conversation conversation : conversations) {
|
||||
if (conversation.getAccount() == account) {
|
||||
if (conversation.getMode() == Conversation.MODE_MULTI) {
|
||||
leaveMuc(conversation);
|
||||
leaveMuc(conversation, true);
|
||||
} else {
|
||||
if (conversation.endOtrIfNeeded()) {
|
||||
Log.d(Config.LOGTAG, account.getJid().toBareJid()
|
||||
@ -2204,10 +2200,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||
fetchAvatar(account, avatar, null);
|
||||
}
|
||||
|
||||
private static String generateFetchKey(Account account, final Avatar avatar) {
|
||||
return account.getJid().toBareJid()+"_"+avatar.owner+"_"+avatar.sha1sum;
|
||||
}
|
||||
|
||||
public void fetchAvatar(Account account, final Avatar avatar, final UiCallback<Avatar> callback) {
|
||||
final String KEY = generateFetchKey(account, avatar);
|
||||
synchronized (this.mInProgressAvatarFetches) {
|
||||
@ -2385,6 +2377,13 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||
|
||||
if (account.getXmppConnection() == null) {
|
||||
account.setXmppConnection(createConnection(account));
|
||||
} else if (!force) {
|
||||
try {
|
||||
Log.d(Config.LOGTAG, "wait for disconnect");
|
||||
Thread.sleep(500); //sleep wait for disconnect
|
||||
} catch (InterruptedException e) {
|
||||
//ignored
|
||||
}
|
||||
}
|
||||
Thread thread = new Thread(account.getXmppConnection());
|
||||
account.getXmppConnection().setInteractive(interactive);
|
||||
@ -2840,6 +2839,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||
|
||||
public interface OnAccountCreated {
|
||||
void onAccountCreated(Account account);
|
||||
|
||||
void informUser(int r);
|
||||
}
|
||||
|
||||
|
@ -1139,16 +1139,16 @@ public class XmppConnection implements Runnable {
|
||||
}
|
||||
|
||||
public void disconnect(final boolean force) {
|
||||
Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": disconnecting");
|
||||
try {
|
||||
Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": disconnecting force="+Boolean.valueOf(force));
|
||||
if (force) {
|
||||
try {
|
||||
socket.close();
|
||||
return;
|
||||
} catch(Exception e) {
|
||||
Log.d(Config.LOGTAG,account.getJid().toBareJid().toString()+": exception during force close ("+e.getMessage()+")");
|
||||
}
|
||||
new Thread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
return;
|
||||
} else {
|
||||
resetStreamId();
|
||||
if (tagWriter.isActive()) {
|
||||
tagWriter.finish();
|
||||
try {
|
||||
@ -1165,19 +1165,16 @@ public class XmppConnection implements Runnable {
|
||||
if (warned) {
|
||||
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": tag writer has finished");
|
||||
}
|
||||
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": closing stream");
|
||||
tagWriter.writeTag(Tag.end("stream:stream"));
|
||||
socket.close();
|
||||
} catch (final IOException e) {
|
||||
Log.d(Config.LOGTAG,"io exception during disconnect");
|
||||
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": io exception during disconnect ("+e.getMessage()+")");
|
||||
} catch (final InterruptedException e) {
|
||||
Log.d(Config.LOGTAG, "interrupted");
|
||||
}
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
} catch (final IOException e) {
|
||||
Log.d(Config.LOGTAG, "io exception during disconnect");
|
||||
}
|
||||
}
|
||||
|
||||
public void resetStreamId() {
|
||||
|
Loading…
Reference in New Issue
Block a user