From a39fce76745ae0b43b4db5328d48624d7b538666 Mon Sep 17 00:00:00 2001 From: wilsonshih Date: Fri, 10 Nov 2023 07:36:16 +0000 Subject: Skip predict back animation to translucent activity. The cross-activity animation can be weird if previous activity is translucent, also skip animation for those case. Refine canShowWhenLocked condition since previous activity can be multiple Bug: 307459377 Test: manual, trigger back to a translucent activity. Test: atest BackNavigationControllerTests Change-Id: I69fb56e8347ca2bd3237695e6ee6d3ecc84f0fd9 --- .../server/wm/BackNavigationController.java | 32 +++++++++++++++++++--- .../server/wm/BackNavigationControllerTests.java | 23 ++++++++++++++++ 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java index c5902c965b43..c3f1e41d4c5e 100644 --- a/services/core/java/com/android/server/wm/BackNavigationController.java +++ b/services/core/java/com/android/server/wm/BackNavigationController.java @@ -258,11 +258,11 @@ class BackNavigationController { // activity, we won't close the activity. backType = BackNavigationInfo.TYPE_DIALOG_CLOSE; removedWindowContainer = window; - } else if (!currentActivity.occludesParent() || currentActivity.showWallpaper()) { - // skip if current activity is translucent + } else if (hasTranslucentActivity(currentActivity, prevActivities)) { + // skip if one of participant activity is translucent backType = BackNavigationInfo.TYPE_CALLBACK; } else if (prevActivities.size() > 0) { - if (!isOccluded || prevActivities.get(0).canShowWhenLocked()) { + if (!isOccluded || isAllActivitiesCanShowWhenLocked(prevActivities)) { // We have another Activity in the same currentTask to go to final WindowContainer parent = currentActivity.getParent(); final boolean canCustomize = parent != null @@ -307,7 +307,7 @@ class BackNavigationController { findAdjacentActivityIfExist(tmpPre, prevActivities); } if (prevTask == null || prevActivities.isEmpty() - || (isOccluded && !prevActivities.get(0).canShowWhenLocked())) { + || (isOccluded && !isAllActivitiesCanShowWhenLocked(prevActivities))) { backType = BackNavigationInfo.TYPE_CALLBACK; } else if (prevTask.isActivityTypeHome()) { removedWindowContainer = currentTask; @@ -508,6 +508,30 @@ class BackNavigationController { outList.add(topActivity); } + private static boolean hasTranslucentActivity(@NonNull ActivityRecord currentActivity, + @NonNull ArrayList prevActivities) { + if (!currentActivity.occludesParent() || currentActivity.showWallpaper()) { + return true; + } + for (int i = prevActivities.size() - 1; i >= 0; --i) { + final ActivityRecord test = prevActivities.get(i); + if (!test.occludesParent() || test.showWallpaper()) { + return true; + } + } + return false; + } + + private static boolean isAllActivitiesCanShowWhenLocked( + @NonNull ArrayList prevActivities) { + for (int i = prevActivities.size() - 1; i >= 0; --i) { + if (!prevActivities.get(i).canShowWhenLocked()) { + return false; + } + } + return !prevActivities.isEmpty(); + } + boolean isMonitoringTransition() { return mAnimationHandler.mComposed || mNavigationMonitor.isMonitorForRemote(); } diff --git a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java index 4d4d397585b7..ac18f802d1c6 100644 --- a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java @@ -233,6 +233,29 @@ public class BackNavigationControllerTests extends WindowTestsBase { assertThat(typeToString(backNavigationInfo.getType())) .isEqualTo(typeToString(BackNavigationInfo.TYPE_CALLBACK)); + // reset drawing status, test if top activity is translucent + backNavigationInfo.onBackNavigationFinished(false); + mBackNavigationController.clearBackAnimations(); + makeWindowVisibleAndDrawn(testCase.recordFront.findMainWindow()); + // simulate translucent + testCase.recordFront.setOccludesParent(false); + backNavigationInfo = startBackNavigation(); + assertThat(typeToString(backNavigationInfo.getType())) + .isEqualTo(typeToString(BackNavigationInfo.TYPE_CALLBACK)); + testCase.recordFront.setOccludesParent(true); + + // reset drawing status, test if bottom activity is translucent + backNavigationInfo.onBackNavigationFinished(false); + mBackNavigationController.clearBackAnimations(); + makeWindowVisibleAndDrawn(testCase.recordBack.findMainWindow()); + // simulate translucent + testCase.recordBack.setOccludesParent(false); + backNavigationInfo = startBackNavigation(); + assertThat(typeToString(backNavigationInfo.getType())) + .isEqualTo(typeToString(BackNavigationInfo.TYPE_CALLBACK)); + testCase.recordBack.setOccludesParent(true); + + // reset drawing status, test canShowWhenLocked backNavigationInfo.onBackNavigationFinished(false); mBackNavigationController.clearBackAnimations(); doReturn(true).when(testCase.recordBack).canShowWhenLocked(); -- cgit v1.2.3-59-g8ed1b