From a546fecc014c52a366f028ed7c10ccc789ca8917 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Fri, 19 Feb 2021 10:42:43 -0300 Subject: [PATCH] Let LockManager only lock current, not future process This fixes a bug on Android 8 where the AlarmManager would re-start a killed BriarService. Then the LockManager lingers around locked and causes an ANR on Android 8.x when the user comes back to it. --- .../briar/android/BriarService.java | 9 ++++++++- .../android/account/LockManagerImpl.java | 20 +++++++++++-------- .../briar/android/account/UnlockActivity.java | 2 +- .../briar/api/android/LockManager.java | 1 + 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java b/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java index a4f4d0b0e..9c9404085 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java @@ -46,6 +46,7 @@ import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION; import static android.os.Build.VERSION.SDK_INT; +import static android.os.Process.myPid; import static androidx.core.app.NotificationCompat.VISIBILITY_SECRET; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; @@ -58,6 +59,7 @@ import static org.briarproject.briar.api.android.AndroidNotificationManager.FAIL import static org.briarproject.briar.api.android.AndroidNotificationManager.ONGOING_CHANNEL_ID; import static org.briarproject.briar.api.android.AndroidNotificationManager.ONGOING_NOTIFICATION_ID; import static org.briarproject.briar.api.android.LockManager.ACTION_LOCK; +import static org.briarproject.briar.api.android.LockManager.EXTRA_PID; public class BriarService extends Service { @@ -202,7 +204,12 @@ public class BriarService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { if (ACTION_LOCK.equals(intent.getAction())) { - lockManager.setLocked(true); + int pid = intent.getIntExtra(EXTRA_PID, -1); + if (pid == myPid()) lockManager.setLocked(true); + else if (LOG.isLoggable(WARNING)) { + LOG.warning("Tried to lock process " + pid + " but this is " + + myPid()); + } } return START_NOT_STICKY; // Don't restart automatically if killed } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/account/LockManagerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/account/LockManagerImpl.java index 0d4edd6d2..fb978bd6a 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/account/LockManagerImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/account/LockManagerImpl.java @@ -32,8 +32,10 @@ import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import static android.app.AlarmManager.ELAPSED_REALTIME; +import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; import static android.app.PendingIntent.getService; import static android.content.Context.ALARM_SERVICE; +import static android.os.Process.myPid; import static android.os.SystemClock.elapsedRealtime; import static java.util.concurrent.TimeUnit.MINUTES; import static java.util.logging.Level.WARNING; @@ -75,23 +77,25 @@ public class LockManagerImpl implements LockManager, Service, EventListener { LockManagerImpl(Application app, SettingsManager settingsManager, AndroidNotificationManager notificationManager, @DatabaseExecutor Executor dbExecutor) { - this.appContext = app.getApplicationContext(); + appContext = app.getApplicationContext(); this.settingsManager = settingsManager; this.notificationManager = notificationManager; this.dbExecutor = dbExecutor; - this.alarmManager = + alarmManager = (AlarmManager) appContext.getSystemService(ALARM_SERVICE); Intent i = new Intent(ACTION_LOCK, null, appContext, BriarService.class); - this.lockIntent = getService(appContext, 0, i, 0); - this.timeoutNever = Integer.valueOf( + i.putExtra(EXTRA_PID, myPid()); + // When not using FLAG_UPDATE_CURRENT, the intent might have no extras + lockIntent = getService(appContext, 0, i, FLAG_UPDATE_CURRENT); + timeoutNever = Integer.parseInt( appContext.getString(R.string.pref_lock_timeout_value_never)); - this.timeoutDefault = Integer.valueOf( + timeoutDefault = Integer.parseInt( appContext.getString(R.string.pref_lock_timeout_value_default)); - this.timeoutMinutes = timeoutNever; + timeoutMinutes = timeoutNever; // setting this in the constructor makes #getValue() @NonNull - this.lockable.setValue(false); + lockable.setValue(false); } @Override @@ -148,7 +152,7 @@ public class LockManagerImpl implements LockManager, Service, EventListener { boolean oldValue = lockable.getValue(); boolean newValue = hasScreenLock(appContext) && lockableSetting; if (oldValue != newValue) { - this.lockable.setValue(newValue); + lockable.setValue(newValue); } } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/account/UnlockActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/account/UnlockActivity.java index d7b7b0e46..c0e91495c 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/account/UnlockActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/account/UnlockActivity.java @@ -77,7 +77,7 @@ public class UnlockActivity extends BaseActivity { @Override protected void onActivityResult(int requestCode, int resultCode, - Intent data) { + @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_KEYGUARD_UNLOCK) { if (resultCode == RESULT_OK) unlock(); diff --git a/briar-android/src/main/java/org/briarproject/briar/api/android/LockManager.java b/briar-android/src/main/java/org/briarproject/briar/api/android/LockManager.java index d8e4b4148..6e038c0b5 100644 --- a/briar-android/src/main/java/org/briarproject/briar/api/android/LockManager.java +++ b/briar-android/src/main/java/org/briarproject/briar/api/android/LockManager.java @@ -8,6 +8,7 @@ import androidx.lifecycle.LiveData; public interface LockManager { String ACTION_LOCK = "lock"; + String EXTRA_PID = "PID"; /** * Stops the inactivity timer when the user interacts with the app.