Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 096fe2cc authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Check idle activity from all activity container

The home task could be:
TaskHome
 - TaskFragment
   - ActivityB
 - ActivityA

Then forAllLeafTaskFragments won't iterate ActivityA under TaskHome
because it is a leaf Task but not a leaf TaskFragment. So separate
the procedure to forAllLeafTasks + forAllLeafTaskFragments.

Fix: 360946107
Flag: EXEMPT bugfix
Test: atest RootWindowContainerTests#testAllResumedActivitiesIdle
Change-Id: I2bb4bc7d141163d47f16c0e895afa451f46157d5
parent 53391a0f
Loading
Loading
Loading
Loading
+40 −9
Original line number Diff line number Diff line
@@ -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);
@@ -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;
            }
+16 −0
Original line number Diff line number Diff line
@@ -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