Loading services/core/java/com/android/server/wm/RootWindowContainer.java +16 −12 Original line number Diff line number Diff line Loading @@ -3428,26 +3428,30 @@ class RootWindowContainer extends WindowContainer<DisplayContent> boolean allResumedActivitiesIdle() { for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { // TODO(b/117135575): Check resumed activities on all visible root tasks. final DisplayContent display = getChildAt(displayNdx); if (display.isSleeping()) { // No resumed activities while display is sleeping. continue; } // If the focused root task is not null or not empty, there should have some activities // resuming or resumed. Make sure these activities are idle. final Task rootTask = display.getFocusedRootTask(); if (rootTask == null || !rootTask.hasActivity()) { continue; final boolean foundNotIdle = display.forAllLeafTaskFragments(tf -> { if (!tf.isVisibleRequested()) { return false; } // Note that only activities that will be resumed can report idle. final ActivityRecord r = tf.topRunningActivity(); if (r != null && !r.idle && (r.isState(RESUMED) // Its process is not attached yet and it may resume later. || (r.app == null && r.isFocusable()))) { ProtoLog.d(WM_DEBUG_STATES, "allResumedActivitiesIdle: %s not idle", r); return true; } final ActivityRecord resumedActivity = rootTask.getTopResumedActivity(); if (resumedActivity == null || !resumedActivity.idle) { ProtoLog.d(WM_DEBUG_STATES, "allResumedActivitiesIdle: rootTask=%d %s " + "not idle", rootTask.getRootTaskId(), resumedActivity); return false; }); if (foundNotIdle) { return false; } if (mTransitionController.isTransientLaunch(resumedActivity)) { if (mTransitionController.hasTransientLaunch(display)) { // Not idle if the transient transition animation is running. return false; } Loading services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java +22 −0 Original line number Diff line number Diff line Loading @@ -204,6 +204,28 @@ public class RootWindowContainerTests extends WindowTestsBase { assertThat(mWm.mRoot.allPausedActivitiesComplete()).isTrue(); } @Test public void testAllResumedActivitiesIdle() { final ActivityRecord activity1 = new ActivityBuilder(mAtm).setCreateTask(true).build(); final ActivityRecord activity2 = new ActivityBuilder(mAtm).setCreateTask(true).build(); final WindowProcessController proc2 = activity2.app; activity1.setState(RESUMED, "test"); activity2.detachFromProcess(); assertThat(mWm.mRoot.allResumedActivitiesIdle()).isFalse(); activity1.idle = true; assertThat(mWm.mRoot.allResumedActivitiesIdle()).isFalse(); activity2.setProcess(proc2); activity2.setState(RESUMED, "test"); activity2.idle = true; assertThat(mWm.mRoot.allResumedActivitiesIdle()).isTrue(); activity1.idle = false; activity1.setVisibleRequested(false); assertThat(mWm.mRoot.allResumedActivitiesIdle()).isTrue(); } @Test public void testTaskLayerRank() { final Task rootTask = new TaskBuilder(mSupervisor).build(); Loading services/tests/wmtests/src/com/android/server/wm/TransitionTests.java +0 −4 Original line number Diff line number Diff line Loading @@ -1550,10 +1550,6 @@ public class TransitionTests extends WindowTestsBase { // An active transient launch overrides idle state to avoid clearing power mode before the // transition is finished. spyOn(mRootWindowContainer.mTransitionController); doAnswer(invocation -> controller.isTransientLaunch(invocation.getArgument(0))).when( mRootWindowContainer.mTransitionController).isTransientLaunch(any()); activity2.getTask().setResumedActivity(activity2, "test"); activity2.idle = true; assertFalse(mRootWindowContainer.allResumedActivitiesIdle()); Loading Loading
services/core/java/com/android/server/wm/RootWindowContainer.java +16 −12 Original line number Diff line number Diff line Loading @@ -3428,26 +3428,30 @@ class RootWindowContainer extends WindowContainer<DisplayContent> boolean allResumedActivitiesIdle() { for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { // TODO(b/117135575): Check resumed activities on all visible root tasks. final DisplayContent display = getChildAt(displayNdx); if (display.isSleeping()) { // No resumed activities while display is sleeping. continue; } // If the focused root task is not null or not empty, there should have some activities // resuming or resumed. Make sure these activities are idle. final Task rootTask = display.getFocusedRootTask(); if (rootTask == null || !rootTask.hasActivity()) { continue; final boolean foundNotIdle = display.forAllLeafTaskFragments(tf -> { if (!tf.isVisibleRequested()) { return false; } // Note that only activities that will be resumed can report idle. final ActivityRecord r = tf.topRunningActivity(); if (r != null && !r.idle && (r.isState(RESUMED) // Its process is not attached yet and it may resume later. || (r.app == null && r.isFocusable()))) { ProtoLog.d(WM_DEBUG_STATES, "allResumedActivitiesIdle: %s not idle", r); return true; } final ActivityRecord resumedActivity = rootTask.getTopResumedActivity(); if (resumedActivity == null || !resumedActivity.idle) { ProtoLog.d(WM_DEBUG_STATES, "allResumedActivitiesIdle: rootTask=%d %s " + "not idle", rootTask.getRootTaskId(), resumedActivity); return false; }); if (foundNotIdle) { return false; } if (mTransitionController.isTransientLaunch(resumedActivity)) { if (mTransitionController.hasTransientLaunch(display)) { // Not idle if the transient transition animation is running. return false; } Loading
services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java +22 −0 Original line number Diff line number Diff line Loading @@ -204,6 +204,28 @@ public class RootWindowContainerTests extends WindowTestsBase { assertThat(mWm.mRoot.allPausedActivitiesComplete()).isTrue(); } @Test public void testAllResumedActivitiesIdle() { final ActivityRecord activity1 = new ActivityBuilder(mAtm).setCreateTask(true).build(); final ActivityRecord activity2 = new ActivityBuilder(mAtm).setCreateTask(true).build(); final WindowProcessController proc2 = activity2.app; activity1.setState(RESUMED, "test"); activity2.detachFromProcess(); assertThat(mWm.mRoot.allResumedActivitiesIdle()).isFalse(); activity1.idle = true; assertThat(mWm.mRoot.allResumedActivitiesIdle()).isFalse(); activity2.setProcess(proc2); activity2.setState(RESUMED, "test"); activity2.idle = true; assertThat(mWm.mRoot.allResumedActivitiesIdle()).isTrue(); activity1.idle = false; activity1.setVisibleRequested(false); assertThat(mWm.mRoot.allResumedActivitiesIdle()).isTrue(); } @Test public void testTaskLayerRank() { final Task rootTask = new TaskBuilder(mSupervisor).build(); Loading
services/tests/wmtests/src/com/android/server/wm/TransitionTests.java +0 −4 Original line number Diff line number Diff line Loading @@ -1550,10 +1550,6 @@ public class TransitionTests extends WindowTestsBase { // An active transient launch overrides idle state to avoid clearing power mode before the // transition is finished. spyOn(mRootWindowContainer.mTransitionController); doAnswer(invocation -> controller.isTransientLaunch(invocation.getArgument(0))).when( mRootWindowContainer.mTransitionController).isTransientLaunch(any()); activity2.getTask().setResumedActivity(activity2, "test"); activity2.idle = true; assertFalse(mRootWindowContainer.allResumedActivitiesIdle()); Loading