synchronzie on xmpp service around all state changes
This commit is contained in:
		
							parent
							
								
									1ed2445c1d
								
							
						
					
					
						commit
						0303c28ad9
					
				| @ -298,7 +298,7 @@ public class XmppConnectionService extends Service { | |||||||
| 				mOnAccountUpdate.onAccountUpdate(); | 				mOnAccountUpdate.onAccountUpdate(); | ||||||
| 			} | 			} | ||||||
| 			if (account.getStatus() == Account.State.ONLINE) { | 			if (account.getStatus() == Account.State.ONLINE) { | ||||||
| 				synchronized (mLowPingTimeoutMode) { | 				synchronized (XmppConnectionService.this) { | ||||||
| 					if (mLowPingTimeoutMode.remove(account.getJid().toBareJid())) { | 					if (mLowPingTimeoutMode.remove(account.getJid().toBareJid())) { | ||||||
| 						Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": leaving low ping timeout mode"); | 						Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": leaving low ping timeout mode"); | ||||||
| 					} | 					} | ||||||
| @ -335,33 +335,35 @@ public class XmppConnectionService extends Service { | |||||||
| 				} | 				} | ||||||
| 				account.pendingConferenceJoins.clear(); | 				account.pendingConferenceJoins.clear(); | ||||||
| 				scheduleWakeUpCall(Config.PING_MAX_INTERVAL, account.getUuid().hashCode()); | 				scheduleWakeUpCall(Config.PING_MAX_INTERVAL, account.getUuid().hashCode()); | ||||||
| 			} else if (account.getStatus() == Account.State.OFFLINE || account.getStatus() == Account.State.DISABLED) { | 			} else { | ||||||
| 				resetSendingToWaiting(account); | 				synchronized (XmppConnectionService.this) { | ||||||
| 				if (!account.isOptionSet(Account.OPTION_DISABLED)) { | 					if (account.getStatus() == Account.State.OFFLINE || account.getStatus() == Account.State.DISABLED) { | ||||||
| 					synchronized (mLowPingTimeoutMode) { | 						resetSendingToWaiting(account); | ||||||
| 						if (mLowPingTimeoutMode.contains(account.getJid().toBareJid())) { | 						if (!account.isOptionSet(Account.OPTION_DISABLED)) { | ||||||
| 							Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": went into offline state during low ping mode. reconnecting now"); | 							if (mLowPingTimeoutMode.contains(account.getJid().toBareJid())) { | ||||||
| 							reconnectAccount(account, true, false); | 								Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": went into offline state during low ping mode. reconnecting now"); | ||||||
| 						} else { | 								reconnectAccount(account, true, false); | ||||||
| 							int timeToReconnect = mRandom.nextInt(20) + 10; | 							} else { | ||||||
| 							scheduleWakeUpCall(timeToReconnect, account.getUuid().hashCode()); | 								int timeToReconnect = mRandom.nextInt(20) + 10; | ||||||
|  | 								scheduleWakeUpCall(timeToReconnect, account.getUuid().hashCode()); | ||||||
|  | 							} | ||||||
|  | 						} | ||||||
|  | 					} else if (account.getStatus() == Account.State.REGISTRATION_SUCCESSFUL) { | ||||||
|  | 						databaseBackend.updateAccount(account); | ||||||
|  | 						reconnectAccount(account, true, false); | ||||||
|  | 					} else if ((account.getStatus() != Account.State.CONNECTING) | ||||||
|  | 							&& (account.getStatus() != Account.State.NO_INTERNET)) { | ||||||
|  | 						resetSendingToWaiting(account); | ||||||
|  | 						if (connection != null) { | ||||||
|  | 							int next = connection.getTimeToNextAttempt(); | ||||||
|  | 							Log.d(Config.LOGTAG, account.getJid().toBareJid() | ||||||
|  | 									+ ": error connecting account. try again in " | ||||||
|  | 									+ next + "s for the " | ||||||
|  | 									+ (connection.getAttempt() + 1) + " time"); | ||||||
|  | 							scheduleWakeUpCall(next, account.getUuid().hashCode()); | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 			} else if (account.getStatus() == Account.State.REGISTRATION_SUCCESSFUL) { |  | ||||||
| 				databaseBackend.updateAccount(account); |  | ||||||
| 				reconnectAccount(account, true, false); |  | ||||||
| 			} else if ((account.getStatus() != Account.State.CONNECTING) |  | ||||||
| 					&& (account.getStatus() != Account.State.NO_INTERNET)) { |  | ||||||
| 				resetSendingToWaiting(account); |  | ||||||
| 				if (connection != null) { |  | ||||||
| 					int next = connection.getTimeToNextAttempt(); |  | ||||||
| 					Log.d(Config.LOGTAG, account.getJid().toBareJid() |  | ||||||
| 							+ ": error connecting account. try again in " |  | ||||||
| 							+ next + "s for the " |  | ||||||
| 							+ (connection.getAttempt() + 1) + " time"); |  | ||||||
| 					scheduleWakeUpCall(next, account.getUuid().hashCode()); |  | ||||||
| 				} |  | ||||||
| 			} | 			} | ||||||
| 			getNotificationService().updateErrorNotification(); | 			getNotificationService().updateErrorNotification(); | ||||||
| 		} | 		} | ||||||
| @ -611,105 +613,110 @@ public class XmppConnectionService extends Service { | |||||||
| 					break; | 					break; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		this.wakeLock.acquire(); | 		synchronized (this) { | ||||||
| 
 | 			this.wakeLock.acquire(); | ||||||
| 		boolean pingNow = false; | 			boolean pingNow = false; | ||||||
| 		HashSet<Account> pingCandidates = new HashSet<>(); | 			HashSet<Account> pingCandidates = new HashSet<>(); | ||||||
| 
 | 			for (Account account : accounts) { | ||||||
| 		for (Account account : accounts) { | 				pingNow |= processAccountState(account, | ||||||
| 			if (!account.isOptionSet(Account.OPTION_DISABLED)) { | 						interactive, | ||||||
| 				if (!hasInternetConnection()) { | 						"ui".equals(action), | ||||||
| 					account.setStatus(Account.State.NO_INTERNET); | 						CryptoHelper.getAccountFingerprint(account).equals(pushedAccountHash), | ||||||
| 					if (statusListener != null) { | 						pingCandidates); | ||||||
| 						statusListener.onStatusChanged(account); |  | ||||||
| 					} |  | ||||||
| 				} else { |  | ||||||
| 					if (account.getStatus() == Account.State.NO_INTERNET) { |  | ||||||
| 						account.setStatus(Account.State.OFFLINE); |  | ||||||
| 						if (statusListener != null) { |  | ||||||
| 							statusListener.onStatusChanged(account); |  | ||||||
| 						} |  | ||||||
| 					} |  | ||||||
| 					if (account.getStatus() == Account.State.ONLINE) { |  | ||||||
| 						synchronized (mLowPingTimeoutMode) { |  | ||||||
| 							long lastReceived = account.getXmppConnection().getLastPacketReceived(); |  | ||||||
| 							long lastSent = account.getXmppConnection().getLastPingSent(); |  | ||||||
| 							long pingInterval = "ui".equals(action) ? Config.PING_MIN_INTERVAL * 1000 : Config.PING_MAX_INTERVAL * 1000; |  | ||||||
| 							long msToNextPing = (Math.max(lastReceived, lastSent) + pingInterval) - SystemClock.elapsedRealtime(); |  | ||||||
| 							int pingTimeout = mLowPingTimeoutMode.contains(account.getJid().toBareJid()) ? Config.LOW_PING_TIMEOUT * 1000 : Config.PING_TIMEOUT * 1000; |  | ||||||
| 							long pingTimeoutIn = (lastSent + pingTimeout) - SystemClock.elapsedRealtime(); |  | ||||||
| 							if (lastSent > lastReceived) { |  | ||||||
| 								if (pingTimeoutIn < 0) { |  | ||||||
| 									Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": ping timeout"); |  | ||||||
| 									this.reconnectAccount(account, true, interactive); |  | ||||||
| 								} else { |  | ||||||
| 									int secs = (int) (pingTimeoutIn / 1000); |  | ||||||
| 									this.scheduleWakeUpCall(secs, account.getUuid().hashCode()); |  | ||||||
| 								} |  | ||||||
| 							} else { |  | ||||||
| 								pingCandidates.add(account); |  | ||||||
| 								if (CryptoHelper.getAccountFingerprint(account).equals(pushedAccountHash)) { |  | ||||||
| 									pingNow = true; |  | ||||||
| 									if (mLowPingTimeoutMode.add(account.getJid().toBareJid())) { |  | ||||||
| 										Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": entering low ping timeout mode"); |  | ||||||
| 									} |  | ||||||
| 								} else if (msToNextPing <= 0) { |  | ||||||
| 									pingNow = true; |  | ||||||
| 								} else { |  | ||||||
| 									this.scheduleWakeUpCall((int) (msToNextPing / 1000), account.getUuid().hashCode()); |  | ||||||
| 									if (mLowPingTimeoutMode.remove(account.getJid().toBareJid())) { |  | ||||||
| 										Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": leaving low ping timeout mode"); |  | ||||||
| 									} |  | ||||||
| 								} |  | ||||||
| 							} |  | ||||||
| 						} |  | ||||||
| 					} else if (account.getStatus() == Account.State.OFFLINE) { |  | ||||||
| 						reconnectAccount(account, true, interactive); |  | ||||||
| 					} else if (account.getStatus() == Account.State.CONNECTING) { |  | ||||||
| 						long secondsSinceLastConnect = (SystemClock.elapsedRealtime() - account.getXmppConnection().getLastConnect()) / 1000; |  | ||||||
| 						long secondsSinceLastDisco = (SystemClock.elapsedRealtime() - account.getXmppConnection().getLastDiscoStarted()) / 1000; |  | ||||||
| 						long discoTimeout = Config.CONNECT_DISCO_TIMEOUT - secondsSinceLastDisco; |  | ||||||
| 						long timeout = Config.CONNECT_TIMEOUT - secondsSinceLastConnect; |  | ||||||
| 						if (timeout < 0) { |  | ||||||
| 							Log.d(Config.LOGTAG, account.getJid() + ": time out during connect reconnecting"); |  | ||||||
| 							account.getXmppConnection().resetAttemptCount(false); |  | ||||||
| 							reconnectAccount(account, true, interactive); |  | ||||||
| 						} else if (discoTimeout < 0) { |  | ||||||
| 							account.getXmppConnection().sendDiscoTimeout(); |  | ||||||
| 							scheduleWakeUpCall((int) Math.min(timeout,discoTimeout), account.getUuid().hashCode()); |  | ||||||
| 						} else { |  | ||||||
| 							scheduleWakeUpCall((int) Math.min(timeout,discoTimeout), account.getUuid().hashCode()); |  | ||||||
| 						} |  | ||||||
| 					} else { |  | ||||||
| 						if (account.getXmppConnection().getTimeToNextAttempt() <= 0) { |  | ||||||
| 							reconnectAccount(account, true, interactive); |  | ||||||
| 						} |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 				if (mOnAccountUpdate != null) { |  | ||||||
| 					mOnAccountUpdate.onAccountUpdate(); |  | ||||||
| 				} |  | ||||||
| 			} | 			} | ||||||
| 		} | 			if (pingNow) { | ||||||
| 		if (pingNow) { | 				for (Account account : pingCandidates) { | ||||||
| 			for (Account account : pingCandidates) { |  | ||||||
| 				synchronized (mLowPingTimeoutMode) { |  | ||||||
| 					final boolean lowTimeout = mLowPingTimeoutMode.contains(account.getJid().toBareJid()); | 					final boolean lowTimeout = mLowPingTimeoutMode.contains(account.getJid().toBareJid()); | ||||||
| 					account.getXmppConnection().sendPing(); | 					account.getXmppConnection().sendPing(); | ||||||
| 					Log.d(Config.LOGTAG, account.getJid().toBareJid() + " send ping (action=" + action + ",lowTimeout=" + Boolean.toString(lowTimeout) + ")"); | 					Log.d(Config.LOGTAG, account.getJid().toBareJid() + " send ping (action=" + action + ",lowTimeout=" + Boolean.toString(lowTimeout) + ")"); | ||||||
| 					scheduleWakeUpCall(lowTimeout ? Config.LOW_PING_TIMEOUT : Config.PING_TIMEOUT, account.getUuid().hashCode()); | 					scheduleWakeUpCall(lowTimeout ? Config.LOW_PING_TIMEOUT : Config.PING_TIMEOUT, account.getUuid().hashCode()); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 			if (wakeLock.isHeld()) { | ||||||
| 		if (wakeLock.isHeld()) { | 				try { | ||||||
| 			try { | 					wakeLock.release(); | ||||||
| 				wakeLock.release(); | 				} catch (final RuntimeException ignored) { | ||||||
| 			} catch (final RuntimeException ignored) { | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		return START_STICKY; | 		return START_STICKY; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	private boolean processAccountState(Account account, boolean interactive, boolean isUiAction, boolean isAccountPushed, HashSet<Account> pingCandidates) { | ||||||
|  | 		boolean pingNow = false; | ||||||
|  | 		if (!account.isOptionSet(Account.OPTION_DISABLED)) { | ||||||
|  | 			if (!hasInternetConnection()) { | ||||||
|  | 				account.setStatus(Account.State.NO_INTERNET); | ||||||
|  | 				if (statusListener != null) { | ||||||
|  | 					statusListener.onStatusChanged(account); | ||||||
|  | 				} | ||||||
|  | 			} else { | ||||||
|  | 				if (account.getStatus() == Account.State.NO_INTERNET) { | ||||||
|  | 					account.setStatus(Account.State.OFFLINE); | ||||||
|  | 					if (statusListener != null) { | ||||||
|  | 						statusListener.onStatusChanged(account); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 				if (account.getStatus() == Account.State.ONLINE) { | ||||||
|  | 					synchronized (mLowPingTimeoutMode) { | ||||||
|  | 						long lastReceived = account.getXmppConnection().getLastPacketReceived(); | ||||||
|  | 						long lastSent = account.getXmppConnection().getLastPingSent(); | ||||||
|  | 						long pingInterval = isUiAction ? Config.PING_MIN_INTERVAL * 1000 : Config.PING_MAX_INTERVAL * 1000; | ||||||
|  | 						long msToNextPing = (Math.max(lastReceived, lastSent) + pingInterval) - SystemClock.elapsedRealtime(); | ||||||
|  | 						int pingTimeout = mLowPingTimeoutMode.contains(account.getJid().toBareJid()) ? Config.LOW_PING_TIMEOUT * 1000 : Config.PING_TIMEOUT * 1000; | ||||||
|  | 						long pingTimeoutIn = (lastSent + pingTimeout) - SystemClock.elapsedRealtime(); | ||||||
|  | 						if (lastSent > lastReceived) { | ||||||
|  | 							if (pingTimeoutIn < 0) { | ||||||
|  | 								Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": ping timeout"); | ||||||
|  | 								this.reconnectAccount(account, true, interactive); | ||||||
|  | 							} else { | ||||||
|  | 								int secs = (int) (pingTimeoutIn / 1000); | ||||||
|  | 								this.scheduleWakeUpCall(secs, account.getUuid().hashCode()); | ||||||
|  | 							} | ||||||
|  | 						} else { | ||||||
|  | 							pingCandidates.add(account); | ||||||
|  | 							if (isAccountPushed) { | ||||||
|  | 								pingNow = true; | ||||||
|  | 								if (mLowPingTimeoutMode.add(account.getJid().toBareJid())) { | ||||||
|  | 									Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": entering low ping timeout mode"); | ||||||
|  | 								} | ||||||
|  | 							} else if (msToNextPing <= 0) { | ||||||
|  | 								pingNow = true; | ||||||
|  | 							} else { | ||||||
|  | 								this.scheduleWakeUpCall((int) (msToNextPing / 1000), account.getUuid().hashCode()); | ||||||
|  | 								if (mLowPingTimeoutMode.remove(account.getJid().toBareJid())) { | ||||||
|  | 									Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": leaving low ping timeout mode"); | ||||||
|  | 								} | ||||||
|  | 							} | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 				} else if (account.getStatus() == Account.State.OFFLINE) { | ||||||
|  | 					reconnectAccount(account, true, interactive); | ||||||
|  | 				} else if (account.getStatus() == Account.State.CONNECTING) { | ||||||
|  | 					long secondsSinceLastConnect = (SystemClock.elapsedRealtime() - account.getXmppConnection().getLastConnect()) / 1000; | ||||||
|  | 					long secondsSinceLastDisco = (SystemClock.elapsedRealtime() - account.getXmppConnection().getLastDiscoStarted()) / 1000; | ||||||
|  | 					long discoTimeout = Config.CONNECT_DISCO_TIMEOUT - secondsSinceLastDisco; | ||||||
|  | 					long timeout = Config.CONNECT_TIMEOUT - secondsSinceLastConnect; | ||||||
|  | 					if (timeout < 0) { | ||||||
|  | 						Log.d(Config.LOGTAG, account.getJid() + ": time out during connect reconnecting"); | ||||||
|  | 						account.getXmppConnection().resetAttemptCount(false); | ||||||
|  | 						reconnectAccount(account, true, interactive); | ||||||
|  | 					} else if (discoTimeout < 0) { | ||||||
|  | 						account.getXmppConnection().sendDiscoTimeout(); | ||||||
|  | 						scheduleWakeUpCall((int) Math.min(timeout,discoTimeout), account.getUuid().hashCode()); | ||||||
|  | 					} else { | ||||||
|  | 						scheduleWakeUpCall((int) Math.min(timeout,discoTimeout), account.getUuid().hashCode()); | ||||||
|  | 					} | ||||||
|  | 				} else { | ||||||
|  | 					if (account.getXmppConnection().getTimeToNextAttempt() <= 0) { | ||||||
|  | 						reconnectAccount(account, true, interactive); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		return pingNow; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	public boolean isDataSaverDisabled() { | 	public boolean isDataSaverDisabled() { | ||||||
| 		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { | 		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { | ||||||
| 			ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE); | 			ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE); | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Daniel Gultsch
						Daniel Gultsch