Loading services/core/java/com/android/server/wm/RootWindowContainer.java +40 −9 Original line number Diff line number Diff line Loading @@ -3426,6 +3426,25 @@ class RootWindowContainer extends WindowContainer<DisplayContent> return null; } /** Returns the top direct activity if it should be idle but has not yet been reported. */ @Nullable private static ActivityRecord getNotYetIdleActivity(@NonNull TaskFragment visibleTf) { for (int i = visibleTf.getChildCount() - 1; i >= 0; i--) { final ActivityRecord r = visibleTf.getChildAt(i).asActivityRecord(); if (r == null || r.finishing) { continue; } if (!r.idle && (r.isState(RESUMED) // Its process is not attached yet and it may resume later. || (r.app == null && r.isFocusable()))) { return r; } // Only check the top running activity. break; } return null; } boolean allResumedActivitiesIdle() { for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { final DisplayContent display = getChildAt(displayNdx); Loading @@ -3434,20 +3453,32 @@ class RootWindowContainer extends WindowContainer<DisplayContent> continue; } final boolean foundNotIdle = display.forAllLeafTaskFragments(tf -> { final boolean foundNotIdle = display.forAllLeafTasks(task -> { if (!task.isVisibleRequested()) { return false; } final ActivityRecord notIdle = getNotYetIdleActivity(task); if (notIdle != null) { ProtoLog.d(WM_DEBUG_STATES, "allResumedActivitiesIdle: %s not idle", notIdle); return true; } if (task.isLeafTaskFragment()) { // The task doesn't contain child TaskFragment. return false; } return task.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); final ActivityRecord tfNotIdle = getNotYetIdleActivity(tf); if (tfNotIdle != null) { ProtoLog.d(WM_DEBUG_STATES, "allResumedActivitiesIdle: %s not idle", tfNotIdle); return true; } return false; }); }); if (foundNotIdle) { return false; } Loading services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java +16 −0 Original line number Diff line number Diff line Loading @@ -224,6 +224,22 @@ public class RootWindowContainerTests extends WindowTestsBase { activity1.idle = false; activity1.setVisibleRequested(false); assertThat(mWm.mRoot.allResumedActivitiesIdle()).isTrue(); final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm) .setParentTask(activity2.getTask()).build(); final ActivityRecord activity3 = new ActivityBuilder(mAtm).build(); taskFragment.addChild(activity3); taskFragment.setVisibleRequested(true); activity3.setState(RESUMED, "test"); activity3.idle = true; assertThat(mWm.mRoot.allResumedActivitiesIdle()).isTrue(); activity3.idle = false; assertThat(mWm.mRoot.allResumedActivitiesIdle()).isFalse(); activity2.idle = false; activity3.idle = true; assertThat(mWm.mRoot.allResumedActivitiesIdle()).isFalse(); } @Test Loading Loading
services/core/java/com/android/server/wm/RootWindowContainer.java +40 −9 Original line number Diff line number Diff line Loading @@ -3426,6 +3426,25 @@ class RootWindowContainer extends WindowContainer<DisplayContent> return null; } /** Returns the top direct activity if it should be idle but has not yet been reported. */ @Nullable private static ActivityRecord getNotYetIdleActivity(@NonNull TaskFragment visibleTf) { for (int i = visibleTf.getChildCount() - 1; i >= 0; i--) { final ActivityRecord r = visibleTf.getChildAt(i).asActivityRecord(); if (r == null || r.finishing) { continue; } if (!r.idle && (r.isState(RESUMED) // Its process is not attached yet and it may resume later. || (r.app == null && r.isFocusable()))) { return r; } // Only check the top running activity. break; } return null; } boolean allResumedActivitiesIdle() { for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { final DisplayContent display = getChildAt(displayNdx); Loading @@ -3434,20 +3453,32 @@ class RootWindowContainer extends WindowContainer<DisplayContent> continue; } final boolean foundNotIdle = display.forAllLeafTaskFragments(tf -> { final boolean foundNotIdle = display.forAllLeafTasks(task -> { if (!task.isVisibleRequested()) { return false; } final ActivityRecord notIdle = getNotYetIdleActivity(task); if (notIdle != null) { ProtoLog.d(WM_DEBUG_STATES, "allResumedActivitiesIdle: %s not idle", notIdle); return true; } if (task.isLeafTaskFragment()) { // The task doesn't contain child TaskFragment. return false; } return task.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); final ActivityRecord tfNotIdle = getNotYetIdleActivity(tf); if (tfNotIdle != null) { ProtoLog.d(WM_DEBUG_STATES, "allResumedActivitiesIdle: %s not idle", tfNotIdle); return true; } return false; }); }); if (foundNotIdle) { return false; } Loading
services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java +16 −0 Original line number Diff line number Diff line Loading @@ -224,6 +224,22 @@ public class RootWindowContainerTests extends WindowTestsBase { activity1.idle = false; activity1.setVisibleRequested(false); assertThat(mWm.mRoot.allResumedActivitiesIdle()).isTrue(); final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm) .setParentTask(activity2.getTask()).build(); final ActivityRecord activity3 = new ActivityBuilder(mAtm).build(); taskFragment.addChild(activity3); taskFragment.setVisibleRequested(true); activity3.setState(RESUMED, "test"); activity3.idle = true; assertThat(mWm.mRoot.allResumedActivitiesIdle()).isTrue(); activity3.idle = false; assertThat(mWm.mRoot.allResumedActivitiesIdle()).isFalse(); activity2.idle = false; activity3.idle = true; assertThat(mWm.mRoot.allResumedActivitiesIdle()).isFalse(); } @Test Loading