Do not update visibility inside clearing task

Otherwise if the top activity doesn't occlude and there is a
pending global config change, the activity behind will be
scheduled a relaunch item and a destroy item. Then there may
be unexpected behavior by the onCreate from the relaunch.

Note that isClearingToReuseTask() is only true when starting a
new activity with clearing task. The visibility will still be
updated later when resuming next activity.

Bug: 238978283
Test: atest TaskTests#testPerformClearTop
Change-Id: I4b926adfef0a159f99d002f78838654e9f27baee
This commit is contained in:
Riddle Hsu
2022-07-16 00:29:41 +08:00
parent 661d05308a
commit 494afca0bf
2 changed files with 17 additions and 1 deletions

View File

@@ -3528,7 +3528,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
final boolean isCurrentVisible = mVisibleRequested || isState(PAUSED, STARTED);
if (updateVisibility && isCurrentVisible) {
if (updateVisibility && isCurrentVisible
// Avoid intermediate lifecycle change when launching with clearing task.
&& !task.isClearingToReuseTask()) {
boolean ensureVisibility = false;
if (occludesParent(true /* includingFinishing */)) {
// If the current activity is not opaque, we need to make sure the visibilities of

View File

@@ -268,6 +268,20 @@ public class TaskTests extends WindowTestsBase {
assertFalse(task.hasChild());
// In real case, the task should be preserved for adding new activity.
assertTrue(task.isAttached());
final ActivityRecord activityA = new ActivityBuilder(mAtm).setTask(task).build();
final ActivityRecord activityB = new ActivityBuilder(mAtm).setTask(task).build();
final ActivityRecord activityC = new ActivityBuilder(mAtm).setTask(task).build();
activityA.setState(ActivityRecord.State.STOPPED, "test");
activityB.setState(ActivityRecord.State.PAUSED, "test");
activityC.setState(ActivityRecord.State.RESUMED, "test");
doReturn(true).when(activityB).shouldBeVisibleUnchecked();
doReturn(true).when(activityC).shouldBeVisibleUnchecked();
activityA.getConfiguration().densityDpi += 100;
assertTrue(task.performClearTop(activityA, 0 /* launchFlags */).finishing);
// The bottom activity should destroy directly without relaunch for config change.
assertEquals(ActivityRecord.State.DESTROYING, activityA.getState());
verify(activityA, never()).startRelaunching();
}
@Test