Skip to content

Commit

Permalink
Merge pull request #886 from AltBeacon/fix-alarm-crash-on-user-switch
Browse files Browse the repository at this point in the history
Prevent crash on alarms going off with a different user active
  • Loading branch information
davidgyoung authored May 29, 2019
2 parents 7d346db + 967c58d commit 720dcaa
Showing 1 changed file with 31 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@
import android.app.PendingIntent;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.PowerManager;
import android.os.SystemClock;
import android.support.annotation.AnyThread;
import android.support.annotation.MainThread;
Expand Down Expand Up @@ -52,6 +55,7 @@ public abstract class CycledLeScanner {
// avoid doing too many scans in a limited time on Android 7.0 or because we are capable of
// multiple detections. If true, it indicates scanning needs to be stopped when we finish.
private boolean mScanningLeftOn = false;
private BroadcastReceiver mCancelAlarmOnUserSwitchBroadcastReceiver = null;

protected long mBetweenScanPeriod;

Expand Down Expand Up @@ -260,7 +264,6 @@ public void destroy() {

// Remove any postDelayed Runnables queued for the next scan cycle
mHandler.removeCallbacksAndMessages(null);

// We cannot quit the thread used by the handler until queued Runnables have been processed,
// because the handler is what stops scanning, and we do not want scanning left on.
// So we stop the thread using the handler, so we make sure it happens after all other
Expand All @@ -273,6 +276,7 @@ public void run() {
mScanThread.quit();
}
});
cleanupCancelAlarmOnUserSwitch();
}

protected abstract void stopScan();
Expand Down Expand Up @@ -484,12 +488,37 @@ protected void setWakeUpAlarm() {
if (milliseconds < mScanPeriod) {
milliseconds = mScanPeriod;
}

AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + milliseconds, getWakeUpOperation());
LogManager.d(TAG, "Set a wakeup alarm to go off in %s ms: %s", milliseconds, getWakeUpOperation());
cancelAlarmOnUserSwitch();
}

// Added to prevent crash on switching users. See #876
protected void cancelAlarmOnUserSwitch() {
if (mCancelAlarmOnUserSwitchBroadcastReceiver == null) {
IntentFilter filter = new IntentFilter();
filter.addAction( Intent.ACTION_USER_BACKGROUND );
filter.addAction( Intent.ACTION_USER_FOREGROUND );

mCancelAlarmOnUserSwitchBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
LogManager.w(TAG, "User switch detected. Cancelling alarm to prevent potential crash.");
cancelWakeUpAlarm();
}
};
mContext.registerReceiver(mCancelAlarmOnUserSwitchBroadcastReceiver, filter);
}
}
protected void cleanupCancelAlarmOnUserSwitch() {
if (mCancelAlarmOnUserSwitchBroadcastReceiver != null) {
mContext.unregisterReceiver(mCancelAlarmOnUserSwitchBroadcastReceiver);
mCancelAlarmOnUserSwitchBroadcastReceiver = null;
}
}


protected PendingIntent getWakeUpOperation() {
if (mWakeUpOperation == null) {
Intent wakeupIntent = new Intent(mContext, StartupBroadcastReceiver.class);
Expand Down

0 comments on commit 720dcaa

Please sign in to comment.