Loading services/core/java/com/android/server/am/ActivityDisplay.java +39 −2 Original line number Diff line number Diff line Loading @@ -78,9 +78,13 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> int mDisplayId; Display mDisplay; /** All of the stacks on this display. Order matters, topmost stack is in front of all other * stacks, bottommost behind. Accessed directly by ActivityManager package classes */ /** * All of the stacks on this display. Order matters, topmost stack is in front of all other * stacks, bottommost behind. Accessed directly by ActivityManager package classes. Any calls * changing the list should also call {@link #onStackOrderChanged()}. */ private final ArrayList<ActivityStack> mStacks = new ArrayList<>(); private ArrayList<OnStackOrderChangedListener> mStackOrderChangedCallbacks = new ArrayList<>(); /** Array of all UIDs that are present on the display. */ private IntArray mDisplayAccessUIDs = new IntArray(); Loading Loading @@ -145,6 +149,7 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> mStacks.remove(stack); removeStackReferenceIfNeeded(stack); mSupervisor.mService.updateSleepIfNeededLocked(); onStackOrderChanged(); } void positionChildAtTop(ActivityStack stack) { Loading @@ -163,6 +168,7 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> mStacks.add(insertPosition, stack); mWindowContainerController.positionChildAt(stack.getWindowContainerController(), insertPosition); onStackOrderChanged(); } private int getTopInsertPosition(ActivityStack stack, int candidatePosition) { Loading Loading @@ -770,6 +776,30 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> mSleeping = asleep; } /** * Adds a listener to be notified whenever the stack order in the display changes. Currently * only used by the {@link RecentsAnimation} to determine whether to interrupt and cancel the * current animation when the system state changes. */ void registerStackOrderChangedListener(OnStackOrderChangedListener listener) { if (!mStackOrderChangedCallbacks.contains(listener)) { mStackOrderChangedCallbacks.add(listener); } } /** * Removes a previously registered stack order change listener. */ void unregisterStackOrderChangedListener(OnStackOrderChangedListener listener) { mStackOrderChangedCallbacks.remove(listener); } private void onStackOrderChanged() { for (int i = mStackOrderChangedCallbacks.size() - 1; i >= 0; i--) { mStackOrderChangedCallbacks.get(i).onStackOrderChanged(); } } public void dump(PrintWriter pw, String prefix) { pw.println(prefix + "displayId=" + mDisplayId + " stacks=" + mStacks.size()); final String myPrefix = prefix + " "; Loading Loading @@ -806,4 +836,11 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> } proto.end(token); } /** * Callback for when the order of the stacks in the display changes. */ interface OnStackOrderChangedListener { void onStackOrderChanged(); } } services/core/java/com/android/server/am/ActivityManagerService.java +3 −7 Original line number Diff line number Diff line Loading @@ -5291,14 +5291,9 @@ public class ActivityManagerService extends IActivityManager.Stub final int callingPid = Binder.getCallingPid(); final long origId = Binder.clearCallingIdentity(); try { final int recentsUid; final String recentsPackage; final List<IBinder> topVisibleActivities; synchronized (this) { final ComponentName recentsComponent = mRecentTasks.getRecentsComponent(); recentsPackage = recentsComponent.getPackageName(); recentsUid = mRecentTasks.getRecentsComponentUid(); topVisibleActivities = mStackSupervisor.getTopVisibleActivities(); final int recentsUid = mRecentTasks.getRecentsComponentUid(); // Start a new recents animation final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor, Loading @@ -5314,13 +5309,14 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void cancelRecentsAnimation(boolean restoreHomeStackPosition) { enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()"); final long callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); try { synchronized (this) { // Cancel the recents animation synchronously (do not hold the WM lock) mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition ? REORDER_MOVE_TO_ORIGINAL_POSITION : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation"); : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid); } } finally { Binder.restoreCallingIdentity(origId); services/core/java/com/android/server/am/RecentsAnimation.java +20 −7 Original line number Diff line number Diff line Loading @@ -49,7 +49,8 @@ import com.android.server.wm.WindowManagerService; * Manages the recents animation, including the reordering of the stacks for the transition and * cleanup. See {@link com.android.server.wm.RecentsAnimationController}. */ class RecentsAnimation implements RecentsAnimationCallbacks { class RecentsAnimation implements RecentsAnimationCallbacks, ActivityDisplay.OnStackOrderChangedListener { private static final String TAG = RecentsAnimation.class.getSimpleName(); // TODO (b/73188263): Reset debugging flags private static final boolean DEBUG = true; Loading Loading @@ -140,13 +141,11 @@ class RecentsAnimation implements RecentsAnimationCallbacks { recentsUid, recentsComponent.getPackageName()); } final ActivityDisplay display; if (hasExistingActivity) { // Move the recents activity into place for the animation if it is not top most display = targetActivity.getDisplay(); display.moveStackBehindBottomMostVisibleStack(targetStack); mDefaultDisplay.moveStackBehindBottomMostVisibleStack(targetStack); if (DEBUG) Slog.d(TAG, "Moved stack=" + targetStack + " behind stack=" + display.getStackAbove(targetStack)); + mDefaultDisplay.getStackAbove(targetStack)); // If there are multiple tasks in the target stack (ie. the home stack, with 3p // and default launchers coexisting), then move the task to the top as a part of Loading @@ -173,7 +172,6 @@ class RecentsAnimation implements RecentsAnimationCallbacks { targetActivity = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED, mTargetActivityType).getTopActivity(); display = targetActivity.getDisplay(); // TODO: Maybe wait for app to draw in this particular case? Loading @@ -190,7 +188,8 @@ class RecentsAnimation implements RecentsAnimationCallbacks { mWindowManager.cancelRecentsAnimationSynchronously(REORDER_MOVE_TO_ORIGINAL_POSITION, "startRecentsActivity"); mWindowManager.initializeRecentsAnimation(mTargetActivityType, recentsAnimationRunner, this, display.mDisplayId, mStackSupervisor.mRecentTasks.getRecentTaskIds()); this, mDefaultDisplay.mDisplayId, mStackSupervisor.mRecentTasks.getRecentTaskIds()); // If we updated the launch-behind state, update the visibility of the activities after // we fetch the visible tasks to be controlled by the animation Loading @@ -198,6 +197,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks { mStackSupervisor.getActivityMetricsLogger().notifyActivityLaunched(START_TASK_TO_FRONT, targetActivity); // Register for stack order changes mDefaultDisplay.registerStackOrderChangedListener(this); } catch (Exception e) { Slog.e(TAG, "Failed to start recents activity", e); throw e; Loading @@ -219,6 +221,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks { mAssistDataRequester = null; } // Unregister for stack order changes mDefaultDisplay.unregisterStackOrderChangedListener(this); if (mWindowManager.getRecentsAnimationController() == null) return; // Just to be sure end the launch hint in case the target activity was never launched. Loading Loading @@ -316,6 +321,14 @@ class RecentsAnimation implements RecentsAnimationCallbacks { } } @Override public void onStackOrderChanged() { // If the activity display stack order changes, cancel any running recents animation in // place mWindowManager.cancelRecentsAnimationSynchronously(REORDER_KEEP_IN_PLACE, "stackOrderChanged"); } /** * Called only when the animation should be canceled prior to starting. */ Loading services/core/java/com/android/server/policy/PhoneWindowManager.java +0 −8 Original line number Diff line number Diff line Loading @@ -6092,14 +6092,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { && (!isNavBarVirtKey || mNavBarVirtualKeyHapticFeedbackEnabled) && event.getRepeatCount() == 0; // Cancel any pending remote recents animations before handling the button itself. In the // case where we are going home and the recents animation has already started, just cancel // the recents animation, leaving the home stack in place for the pending start activity if (isNavBarVirtKey && !down && !canceled) { boolean isHomeKey = keyCode == KeyEvent.KEYCODE_HOME; mActivityManagerInternal.cancelRecentsAnimation(!isHomeKey); } // Handle special keys. switch (keyCode) { case KeyEvent.KEYCODE_BACK: { Loading services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java +50 −0 Original line number Diff line number Diff line Loading @@ -565,6 +565,47 @@ public class ActivityStackTests extends ActivityTestsBase { false /* displaySleeping */, false /* expected*/); } @Test public void testStackOrderChangedOnRemoveStack() throws Exception { StackOrderChangedListener listener = new StackOrderChangedListener(); mDefaultDisplay.registerStackOrderChangedListener(listener); try { mDefaultDisplay.removeChild(mStack); } finally { mDefaultDisplay.unregisterStackOrderChangedListener(listener); } assertTrue(listener.changed); } @Test public void testStackOrderChangedOnAddPositionStack() throws Exception { mDefaultDisplay.removeChild(mStack); StackOrderChangedListener listener = new StackOrderChangedListener(); mDefaultDisplay.registerStackOrderChangedListener(listener); try { mDefaultDisplay.addChild(mStack, 0); } finally { mDefaultDisplay.unregisterStackOrderChangedListener(listener); } assertTrue(listener.changed); } @Test public void testStackOrderChangedOnPositionStack() throws Exception { StackOrderChangedListener listener = new StackOrderChangedListener(); try { final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest( mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); mDefaultDisplay.registerStackOrderChangedListener(listener); mDefaultDisplay.positionChildAtBottom(fullscreenStack1); } finally { mDefaultDisplay.unregisterStackOrderChangedListener(listener); } assertTrue(listener.changed); } private void verifyShouldSleepActivities(boolean focusedStack, boolean keyguardGoingAway, boolean displaySleeping, boolean expected) { mSupervisor.mFocusedStack = focusedStack ? mStack : null; Loading @@ -578,4 +619,13 @@ public class ActivityStackTests extends ActivityTestsBase { assertEquals(expected, mStack.shouldSleepActivities()); } private class StackOrderChangedListener implements ActivityDisplay.OnStackOrderChangedListener { boolean changed = false; @Override public void onStackOrderChanged() { changed = true; } } } Loading
services/core/java/com/android/server/am/ActivityDisplay.java +39 −2 Original line number Diff line number Diff line Loading @@ -78,9 +78,13 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> int mDisplayId; Display mDisplay; /** All of the stacks on this display. Order matters, topmost stack is in front of all other * stacks, bottommost behind. Accessed directly by ActivityManager package classes */ /** * All of the stacks on this display. Order matters, topmost stack is in front of all other * stacks, bottommost behind. Accessed directly by ActivityManager package classes. Any calls * changing the list should also call {@link #onStackOrderChanged()}. */ private final ArrayList<ActivityStack> mStacks = new ArrayList<>(); private ArrayList<OnStackOrderChangedListener> mStackOrderChangedCallbacks = new ArrayList<>(); /** Array of all UIDs that are present on the display. */ private IntArray mDisplayAccessUIDs = new IntArray(); Loading Loading @@ -145,6 +149,7 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> mStacks.remove(stack); removeStackReferenceIfNeeded(stack); mSupervisor.mService.updateSleepIfNeededLocked(); onStackOrderChanged(); } void positionChildAtTop(ActivityStack stack) { Loading @@ -163,6 +168,7 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> mStacks.add(insertPosition, stack); mWindowContainerController.positionChildAt(stack.getWindowContainerController(), insertPosition); onStackOrderChanged(); } private int getTopInsertPosition(ActivityStack stack, int candidatePosition) { Loading Loading @@ -770,6 +776,30 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> mSleeping = asleep; } /** * Adds a listener to be notified whenever the stack order in the display changes. Currently * only used by the {@link RecentsAnimation} to determine whether to interrupt and cancel the * current animation when the system state changes. */ void registerStackOrderChangedListener(OnStackOrderChangedListener listener) { if (!mStackOrderChangedCallbacks.contains(listener)) { mStackOrderChangedCallbacks.add(listener); } } /** * Removes a previously registered stack order change listener. */ void unregisterStackOrderChangedListener(OnStackOrderChangedListener listener) { mStackOrderChangedCallbacks.remove(listener); } private void onStackOrderChanged() { for (int i = mStackOrderChangedCallbacks.size() - 1; i >= 0; i--) { mStackOrderChangedCallbacks.get(i).onStackOrderChanged(); } } public void dump(PrintWriter pw, String prefix) { pw.println(prefix + "displayId=" + mDisplayId + " stacks=" + mStacks.size()); final String myPrefix = prefix + " "; Loading Loading @@ -806,4 +836,11 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> } proto.end(token); } /** * Callback for when the order of the stacks in the display changes. */ interface OnStackOrderChangedListener { void onStackOrderChanged(); } }
services/core/java/com/android/server/am/ActivityManagerService.java +3 −7 Original line number Diff line number Diff line Loading @@ -5291,14 +5291,9 @@ public class ActivityManagerService extends IActivityManager.Stub final int callingPid = Binder.getCallingPid(); final long origId = Binder.clearCallingIdentity(); try { final int recentsUid; final String recentsPackage; final List<IBinder> topVisibleActivities; synchronized (this) { final ComponentName recentsComponent = mRecentTasks.getRecentsComponent(); recentsPackage = recentsComponent.getPackageName(); recentsUid = mRecentTasks.getRecentsComponentUid(); topVisibleActivities = mStackSupervisor.getTopVisibleActivities(); final int recentsUid = mRecentTasks.getRecentsComponentUid(); // Start a new recents animation final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor, Loading @@ -5314,13 +5309,14 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void cancelRecentsAnimation(boolean restoreHomeStackPosition) { enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()"); final long callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); try { synchronized (this) { // Cancel the recents animation synchronously (do not hold the WM lock) mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition ? REORDER_MOVE_TO_ORIGINAL_POSITION : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation"); : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid); } } finally { Binder.restoreCallingIdentity(origId);
services/core/java/com/android/server/am/RecentsAnimation.java +20 −7 Original line number Diff line number Diff line Loading @@ -49,7 +49,8 @@ import com.android.server.wm.WindowManagerService; * Manages the recents animation, including the reordering of the stacks for the transition and * cleanup. See {@link com.android.server.wm.RecentsAnimationController}. */ class RecentsAnimation implements RecentsAnimationCallbacks { class RecentsAnimation implements RecentsAnimationCallbacks, ActivityDisplay.OnStackOrderChangedListener { private static final String TAG = RecentsAnimation.class.getSimpleName(); // TODO (b/73188263): Reset debugging flags private static final boolean DEBUG = true; Loading Loading @@ -140,13 +141,11 @@ class RecentsAnimation implements RecentsAnimationCallbacks { recentsUid, recentsComponent.getPackageName()); } final ActivityDisplay display; if (hasExistingActivity) { // Move the recents activity into place for the animation if it is not top most display = targetActivity.getDisplay(); display.moveStackBehindBottomMostVisibleStack(targetStack); mDefaultDisplay.moveStackBehindBottomMostVisibleStack(targetStack); if (DEBUG) Slog.d(TAG, "Moved stack=" + targetStack + " behind stack=" + display.getStackAbove(targetStack)); + mDefaultDisplay.getStackAbove(targetStack)); // If there are multiple tasks in the target stack (ie. the home stack, with 3p // and default launchers coexisting), then move the task to the top as a part of Loading @@ -173,7 +172,6 @@ class RecentsAnimation implements RecentsAnimationCallbacks { targetActivity = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED, mTargetActivityType).getTopActivity(); display = targetActivity.getDisplay(); // TODO: Maybe wait for app to draw in this particular case? Loading @@ -190,7 +188,8 @@ class RecentsAnimation implements RecentsAnimationCallbacks { mWindowManager.cancelRecentsAnimationSynchronously(REORDER_MOVE_TO_ORIGINAL_POSITION, "startRecentsActivity"); mWindowManager.initializeRecentsAnimation(mTargetActivityType, recentsAnimationRunner, this, display.mDisplayId, mStackSupervisor.mRecentTasks.getRecentTaskIds()); this, mDefaultDisplay.mDisplayId, mStackSupervisor.mRecentTasks.getRecentTaskIds()); // If we updated the launch-behind state, update the visibility of the activities after // we fetch the visible tasks to be controlled by the animation Loading @@ -198,6 +197,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks { mStackSupervisor.getActivityMetricsLogger().notifyActivityLaunched(START_TASK_TO_FRONT, targetActivity); // Register for stack order changes mDefaultDisplay.registerStackOrderChangedListener(this); } catch (Exception e) { Slog.e(TAG, "Failed to start recents activity", e); throw e; Loading @@ -219,6 +221,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks { mAssistDataRequester = null; } // Unregister for stack order changes mDefaultDisplay.unregisterStackOrderChangedListener(this); if (mWindowManager.getRecentsAnimationController() == null) return; // Just to be sure end the launch hint in case the target activity was never launched. Loading Loading @@ -316,6 +321,14 @@ class RecentsAnimation implements RecentsAnimationCallbacks { } } @Override public void onStackOrderChanged() { // If the activity display stack order changes, cancel any running recents animation in // place mWindowManager.cancelRecentsAnimationSynchronously(REORDER_KEEP_IN_PLACE, "stackOrderChanged"); } /** * Called only when the animation should be canceled prior to starting. */ Loading
services/core/java/com/android/server/policy/PhoneWindowManager.java +0 −8 Original line number Diff line number Diff line Loading @@ -6092,14 +6092,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { && (!isNavBarVirtKey || mNavBarVirtualKeyHapticFeedbackEnabled) && event.getRepeatCount() == 0; // Cancel any pending remote recents animations before handling the button itself. In the // case where we are going home and the recents animation has already started, just cancel // the recents animation, leaving the home stack in place for the pending start activity if (isNavBarVirtKey && !down && !canceled) { boolean isHomeKey = keyCode == KeyEvent.KEYCODE_HOME; mActivityManagerInternal.cancelRecentsAnimation(!isHomeKey); } // Handle special keys. switch (keyCode) { case KeyEvent.KEYCODE_BACK: { Loading
services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java +50 −0 Original line number Diff line number Diff line Loading @@ -565,6 +565,47 @@ public class ActivityStackTests extends ActivityTestsBase { false /* displaySleeping */, false /* expected*/); } @Test public void testStackOrderChangedOnRemoveStack() throws Exception { StackOrderChangedListener listener = new StackOrderChangedListener(); mDefaultDisplay.registerStackOrderChangedListener(listener); try { mDefaultDisplay.removeChild(mStack); } finally { mDefaultDisplay.unregisterStackOrderChangedListener(listener); } assertTrue(listener.changed); } @Test public void testStackOrderChangedOnAddPositionStack() throws Exception { mDefaultDisplay.removeChild(mStack); StackOrderChangedListener listener = new StackOrderChangedListener(); mDefaultDisplay.registerStackOrderChangedListener(listener); try { mDefaultDisplay.addChild(mStack, 0); } finally { mDefaultDisplay.unregisterStackOrderChangedListener(listener); } assertTrue(listener.changed); } @Test public void testStackOrderChangedOnPositionStack() throws Exception { StackOrderChangedListener listener = new StackOrderChangedListener(); try { final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest( mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); mDefaultDisplay.registerStackOrderChangedListener(listener); mDefaultDisplay.positionChildAtBottom(fullscreenStack1); } finally { mDefaultDisplay.unregisterStackOrderChangedListener(listener); } assertTrue(listener.changed); } private void verifyShouldSleepActivities(boolean focusedStack, boolean keyguardGoingAway, boolean displaySleeping, boolean expected) { mSupervisor.mFocusedStack = focusedStack ? mStack : null; Loading @@ -578,4 +619,13 @@ public class ActivityStackTests extends ActivityTestsBase { assertEquals(expected, mStack.shouldSleepActivities()); } private class StackOrderChangedListener implements ActivityDisplay.OnStackOrderChangedListener { boolean changed = false; @Override public void onStackOrderChanged() { changed = true; } } }