diff options
| -rw-r--r-- | services/core/java/com/android/server/wm/BackNavigationController.java | 71 | ||||
| -rw-r--r-- | services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java | 30 |
2 files changed, 70 insertions, 31 deletions
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java index e15512678104..cd7f73c28cc0 100644 --- a/services/core/java/com/android/server/wm/BackNavigationController.java +++ b/services/core/java/com/android/server/wm/BackNavigationController.java @@ -423,7 +423,6 @@ class BackNavigationController { // Searching previous final ActivityRecord prevActivity = currentTask.getActivity((below) -> !below.finishing, currentActivity, false /*includeBoundary*/, true /*traverseTopToBottom*/); - final TaskFragment currTF = currentActivity.getTaskFragment(); if (currTF != null && currTF.asTask() == null) { // The currentActivity is embedded, search for the candidate previous activities. @@ -432,13 +431,34 @@ class BackNavigationController { outPrevActivities.add(prevActivity); return true; } - if (currTF.getAdjacentTaskFragment() != null) { - // The two TFs are adjacent (visually displayed side-by-side), search if any - // activity below the lowest one - // If companion, those two TF will be closed together. - if (currTF.getCompanionTaskFragment() != null) { + if (currTF.getAdjacentTaskFragment() == null) { + final TaskFragment nextTF = findNextTaskFragment(currentTask, currTF); + if (isSecondCompanionToFirst(currTF, nextTF)) { + // TF is isStacked, search bottom activity from companion TF. + // + // Sample hierarchy: search for underPrevious if any. + // Current TF + // Companion TF (bottomActivityInCompanion) + // Bottom Activity not inside companion TF (underPrevious) + // find bottom activity in Companion TF. + final ActivityRecord bottomActivityInCompanion = nextTF.getActivity( + (below) -> !below.finishing, false /* traverseTopToBottom */); + final ActivityRecord underPrevious = currentTask.getActivity( + (below) -> !below.finishing, bottomActivityInCompanion, + false /*includeBoundary*/, true /*traverseTopToBottom*/); + if (underPrevious != null) { + outPrevActivities.add(underPrevious); + addPreviousAdjacentActivityIfExist(underPrevious, outPrevActivities); + } + return true; + } + } else { + // If adjacent TF has companion to current TF, those two TF will be closed together. + final TaskFragment adjacentTF = currTF.getAdjacentTaskFragment(); + if (isSecondCompanionToFirst(currTF, adjacentTF)) { + // The two TFs are adjacent (visually displayed side-by-side), search if any + // activity below the lowest one. final WindowContainer commonParent = currTF.getParent(); - final TaskFragment adjacentTF = currTF.getAdjacentTaskFragment(); final TaskFragment lowerTF = commonParent.mChildren.indexOf(currTF) < commonParent.mChildren.indexOf(adjacentTF) ? currTF : adjacentTF; @@ -452,25 +472,6 @@ class BackNavigationController { // Unable to predict if no companion, it can only close current activity and make // prev Activity full screened. return false; - } else if (currTF.getCompanionTaskFragment() != null) { - // TF is isStacked, search bottom activity from companion TF. - // - // Sample hierarchy: search for underPrevious if any. - // Current TF - // Companion TF (bottomActivityInCompanion) - // Bottom Activity not inside companion TF (underPrevious) - final TaskFragment companionTF = currTF.getCompanionTaskFragment(); - // find bottom activity in Companion TF. - final ActivityRecord bottomActivityInCompanion = companionTF.getActivity( - (below) -> !below.finishing, false /* traverseTopToBottom */); - final ActivityRecord underPrevious = currentTask.getActivity( - (below) -> !below.finishing, bottomActivityInCompanion, - false /*includeBoundary*/, true /*traverseTopToBottom*/); - if (underPrevious != null) { - outPrevActivities.add(underPrevious); - addPreviousAdjacentActivityIfExist(underPrevious, outPrevActivities); - } - return true; } } @@ -485,6 +486,24 @@ class BackNavigationController { return true; } + private static TaskFragment findNextTaskFragment(@NonNull Task currentTask, + @NonNull TaskFragment topTF) { + final int topIndex = currentTask.mChildren.indexOf(topTF); + if (topIndex <= 0) { + return null; + } + final WindowContainer next = currentTask.mChildren.get(topIndex - 1); + return next.asTaskFragment(); + } + + /** + * Whether the second TF has set companion to first TF. + * When set, the second TF will be removed by organizer if the first TF is removed. + */ + private static boolean isSecondCompanionToFirst(TaskFragment first, TaskFragment second) { + return second != null && second.getCompanionTaskFragment() == first; + } + private static void addPreviousAdjacentActivityIfExist(@NonNull ActivityRecord prevActivity, @NonNull ArrayList<ActivityRecord> outPrevActivities) { final TaskFragment prevTF = prevActivity.getTaskFragment(); 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 c29547f123aa..9b2a880881f8 100644 --- a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java @@ -291,13 +291,22 @@ public class BackNavigationControllerTests extends WindowTestsBase { assertTrue(predictable); outPrevActivities.clear(); - // Stacked + companion => predict for previous task + // Stacked + top companion to bottom but bottom didn't => predict for previous activity tf2.setCompanionTaskFragment(tf1); predictable = BackNavigationController.getAnimatablePrevActivities(task, topAr, outPrevActivities); - assertTrue(outPrevActivities.isEmpty()); + assertTrue(outPrevActivities.contains(prevAr)); assertTrue(predictable); tf2.setCompanionTaskFragment(null); + outPrevActivities.clear(); + + // Stacked + next companion to top => predict for previous task + tf1.setCompanionTaskFragment(tf2); + predictable = BackNavigationController.getAnimatablePrevActivities(task, topAr, + outPrevActivities); + assertTrue(outPrevActivities.isEmpty()); + assertTrue(predictable); + tf1.setCompanionTaskFragment(null); // Adjacent + no companion => unable to predict // TF1 | TF2 @@ -314,11 +323,13 @@ public class BackNavigationControllerTests extends WindowTestsBase { // Adjacent + companion => predict for previous task tf1.setCompanionTaskFragment(tf2); - tf2.setCompanionTaskFragment(tf1); predictable = BackNavigationController.getAnimatablePrevActivities(task, topAr, outPrevActivities); assertTrue(outPrevActivities.isEmpty()); assertTrue(predictable); + tf1.setCompanionTaskFragment(null); + + tf2.setCompanionTaskFragment(tf1); predictable = BackNavigationController.getAnimatablePrevActivities(task, prevAr, outPrevActivities); assertTrue(outPrevActivities.isEmpty()); @@ -361,18 +372,27 @@ public class BackNavigationControllerTests extends WindowTestsBase { tf3.setAdjacentTaskFragment(null); final TaskFragment tf4 = createTaskFragmentWithActivity(task); - // Stacked + companion => predict for previous activity below companion. + // Stacked + next companion to top => predict for previous activity below companion. // Tf4 // TF3 // TF2 // TF1 - tf4.setCompanionTaskFragment(tf3); tf3.setCompanionTaskFragment(tf4); topAr = tf4.getTopMostActivity(); predictable = BackNavigationController.getAnimatablePrevActivities(task, topAr, outPrevActivities); assertTrue(outPrevActivities.contains(tf2.getTopMostActivity())); assertTrue(predictable); + outPrevActivities.clear(); + tf3.setCompanionTaskFragment(null); + + // Stacked + top companion to next but next one didn't => predict for previous activity. + tf4.setCompanionTaskFragment(tf3); + topAr = tf4.getTopMostActivity(); + predictable = BackNavigationController.getAnimatablePrevActivities(task, topAr, + outPrevActivities); + assertTrue(outPrevActivities.contains(tf3.getTopMostActivity())); + assertTrue(predictable); } @Test |