-
Notifications
You must be signed in to change notification settings - Fork 23
Description
Is this a support request?
No
Describe the bug
Under certain conditions (described below) the alarm set for foreground polling is not cancelled when the app is closed and this can result in that polling period being used to wake the app up in the background.
To reproduce
There is a particular setup required here:
- The SDK is set to "offline" mode on app startup (using
offline(true)) and not set to "online" mode until there is foreground UI. (This is done to prevent the possibility of any network activity in the background). - Background polling is disabled using
disableBackgroundUpdating(true). - Streaming is disabled with
stream(false). pollingIntervalMillisis set to a low value (like the minimum of 5 minutes).
When the app is first foregrounded, the PollingUpdater will register a recurring alarm using the pollingIntervalMillis (which in this case is 5 minutes). Under normal circumstances, when the app moves to the background this alarm will be cancelled (as expected). This is because the ForegroundChecker will trigger onBecameBackground inside ConnectivityManager:
@Override
public void onBecameBackground() {
synchronized (ConnectivityManager.this) {
if (isInternetConnected(application) && !setOffline &&
connectionInformation.getConnectionMode() != backgroundMode) {
throttler.cancel();
attemptTransition(backgroundMode);
}
}
}The attemptTransition(backgroundMode) will then disable all polling since background polling is disabled:
private synchronized void attemptTransition(ConnectionMode nextState) {
...
switch (nextState) {
case SHUTDOWN:
case BACKGROUND_DISABLED:
case SET_OFFLINE:
case OFFLINE:
initialized = true;
callInitCallback();
stopPolling(); // <------------- Here
stopStreaming();
break;However, none of this code runs if the app shuts down in the foreground unexpectedly for any reason (such as an app crash). This leaves the 5 minute alarm in place and it wakes the app back up in the background. However, because the process is running in the background and is initialized in "offline" mode, the alarm also is not cancelled and is therefore allowed to repeat. Alarms are always typically cancelled when the SDK is initialized when ConnectivityManager.startUp is called, but this logic is not run in offline mode:
synchronized boolean startUp(LDUtil.ResultCallback<Void> onCompleteListener) {
initialized = false;
if (setOffline) {
initialized = true;
updateConnectionMode(ConnectionMode.SET_OFFLINE);
voidSuccess(onCompleteListener);
return false; // <------ Stopped here in offline mode
}
boolean connected = isInternetConnected(application);
if (!connected) {
initialized = true;
updateConnectionMode(ConnectionMode.OFFLINE);
voidSuccess(onCompleteListener);
return false;
}
initCallback = onCompleteListener;
eventProcessor.start();
throttler.attemptRun(); // <------- This would reset the alarms if allowed to run.
return true;
}Expected behavior
Polling alarms are always cancelled and reset each time the SDK is initialized (even in offline mode).
More generally, if alarms were not used to implement foreground polling then it would not be possible for foreground polling to accidentally trigger an app to wake up in the background in the first place.
Logs
N/A
SDK version
3.1.4 (and also confirmed with current version 3.2.0)
Language version, developer tools
Kotlin / Java
OS/platform
Android 13
Additional context
N/A