diff options
| author | 2023-09-18 18:44:43 +0000 | |
|---|---|---|
| committer | 2023-09-19 18:44:49 +0000 | |
| commit | a7af7b502d48f9b7aa2909ebbd64e2cf3f0dc327 (patch) | |
| tree | 59b302700e8014e530005e2b122456f8a1c262de | |
| parent | cd15fed5854b5155d6892582f4521689270f3e95 (diff) | |
Cancels dual display state when all activities for process are invisible
Uses a ProcessObserver instead of a TaskStackListener to be notified
when a process has no foreground activities. This is a more stable
and correct signal than the onTaskMovedToFront notification.
cancel the dual display request. Fixes bugs previously seen with
tapping on navigation bars or multi-window scenarios.
Fixes: 295195310
Test: DeviceStateManagerServiceTest
Change-Id: I5aed2b204dcbdbf1e439811780a94b3f499b31a3
2 files changed, 36 insertions, 26 deletions
diff --git a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java index add94b1bf937..3aa087acf336 100644 --- a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java +++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java @@ -37,7 +37,8 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; -import android.app.TaskStackListener; +import android.app.ActivityManagerInternal; +import android.app.IProcessObserver; import android.content.Context; import android.hardware.devicestate.DeviceStateInfo; import android.hardware.devicestate.DeviceStateManager; @@ -184,7 +185,30 @@ public final class DeviceStateManagerService extends SystemService { private final SystemPropertySetter mSystemPropertySetter; @VisibleForTesting - TaskStackListener mOverrideRequestTaskStackListener = new OverrideRequestTaskStackListener(); + final IProcessObserver mProcessObserver = new IProcessObserver.Stub() { + @Override + public void onForegroundActivitiesChanged(int pid, int uid, boolean fg) { + synchronized (mLock) { + if (!shouldCancelOverrideRequestWhenRequesterNotOnTop()) { + return; + } + + OverrideRequest request = mActiveOverride.get(); + if (pid != request.getPid() || uid != request.getUid()) { + return; + } + if (!fg) { + mOverrideRequestController.cancelRequest(request); + } + } + } + + @Override + public void onProcessDied(int pid, int uid) {} + + @Override + public void onForegroundServicesChanged(int pid, int uid, int serviceTypes) {} + }; @VisibleForTesting ActivityTaskManagerInternal.ScreenObserver mOverrideRequestScreenObserver = new OverrideRequestScreenObserver(); @@ -239,8 +263,9 @@ public final class DeviceStateManagerService extends SystemService { mFoldedDeviceStates = readFoldedStates(); } - mActivityTaskManagerInternal.registerTaskStackListener(mOverrideRequestTaskStackListener); mActivityTaskManagerInternal.registerScreenObserver(mOverrideRequestScreenObserver); + LocalServices.getService(ActivityManagerInternal.class).registerProcessObserver( + mProcessObserver); } @VisibleForTesting @@ -1289,23 +1314,6 @@ public final class DeviceStateManagerService extends SystemService { return deviceState.hasFlag(DeviceState.FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP); } - private class OverrideRequestTaskStackListener extends TaskStackListener { - @Override - public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo) - throws RemoteException { - synchronized (mLock) { - if (!shouldCancelOverrideRequestWhenRequesterNotOnTop()) { - return; - } - - OverrideRequest request = mActiveOverride.get(); - if (!isTopApp(request.getPid())) { - mOverrideRequestController.cancelRequest(request); - } - } - } - } - private class OverrideRequestScreenObserver implements ActivityTaskManagerInternal.ScreenObserver { diff --git a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java index 668415041129..a22a20ece03c 100644 --- a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java @@ -28,7 +28,6 @@ import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNull; import static org.testng.Assert.assertThrows; -import android.app.ActivityManager; import android.hardware.devicestate.DeviceStateInfo; import android.hardware.devicestate.DeviceStateRequest; import android.hardware.devicestate.IDeviceStateManagerCallback; @@ -582,10 +581,10 @@ public final class DeviceStateManagerServiceTest { // When the app is foreground, the state should not change () -> { int pid = Binder.getCallingPid(); - when(mWindowProcessController.getPid()).thenReturn(pid); + int uid = Binder.getCallingUid(); try { - mService.mOverrideRequestTaskStackListener.onTaskMovedToFront( - new ActivityManager.RunningTaskInfo()); + mService.mProcessObserver.onForegroundActivitiesChanged(pid, uid, + true /* foregroundActivities */); } catch (RemoteException e) { throw new RuntimeException(e); } @@ -594,8 +593,11 @@ public final class DeviceStateManagerServiceTest { () -> { when(mWindowProcessController.getPid()).thenReturn(FAKE_PROCESS_ID); try { - mService.mOverrideRequestTaskStackListener.onTaskMovedToFront( - new ActivityManager.RunningTaskInfo()); + int pid = Binder.getCallingPid(); + int uid = Binder.getCallingUid(); + mService.mProcessObserver.onForegroundActivitiesChanged(pid, uid, + false /* foregroundActivities */); + } catch (RemoteException e) { throw new RuntimeException(e); } |