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

Commit 66c2aecb authored by Riddle Hsu's avatar Riddle Hsu Committed by Android (Google) Code Review
Browse files

Merge "Respect hierarchy visibility of transient launch" into main

parents 5835f113 36b7fb7f
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -2894,10 +2894,9 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
        private boolean mIncludeInvisibleAndFinishing;
        private boolean mIgnoringKeyguard;

        ActivityRecord getOpaqueActivity(
                @NonNull WindowContainer<?> container, boolean ignoringKeyguard) {
        ActivityRecord getOpaqueActivity(@NonNull WindowContainer<?> container) {
            mIncludeInvisibleAndFinishing = true;
            mIgnoringKeyguard = ignoringKeyguard;
            mIgnoringKeyguard = true;
            return container.getActivity(this,
                    true /* traverseTopToBottom */, null /* boundary */);
        }
+7 −2
Original line number Diff line number Diff line
@@ -1090,8 +1090,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
            return true;
        }
        // Including finishing Activity if the TaskFragment is becoming invisible in the transition.
        return mTaskSupervisor.mOpaqueActivityHelper.getOpaqueActivity(this,
                true /* ignoringKeyguard */) == null;
        return mTaskSupervisor.mOpaqueActivityHelper.getOpaqueActivity(this) == null;
    }

    /**
@@ -1734,6 +1733,12 @@ class TaskFragment extends WindowContainer<WindowContainer> {
        if (!hasDirectChildActivities()) {
            return false;
        }
        if (mResumedActivity != null && mTransitionController.isTransientLaunch(mResumedActivity)) {
            // Even if the transient activity is occluded, defer pausing (addToStopping will still
            // be called) it until the transient transition is done. So the current resuming
            // activity won't need to wait for additional pause complete.
            return false;
        }

        ProtoLog.d(WM_DEBUG_STATES, "startPausing: taskFrag =%s " + "mResumedActivity=%s", this,
                mResumedActivity);
+8 −11
Original line number Diff line number Diff line
@@ -477,20 +477,17 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
            if (transientRoot == null) continue;
            final WindowContainer<?> rootParent = transientRoot.getParent();
            if (rootParent == null || rootParent.getTopChild() == transientRoot) continue;
            final ActivityRecord topOpaque = mController.mAtm.mTaskSupervisor.mOpaqueActivityHelper
                    .getOpaqueActivity(rootParent, true /* ignoringKeyguard */);
            if (transientRoot.compareTo(topOpaque.getRootTask()) < 0) {
            for (int j = rootParent.getChildCount() - 1; j >= 0; --j) {
                final WindowContainer<?> sibling = rootParent.getChildAt(j);
                if (sibling == transientRoot) break;
                if (!sibling.getWindowConfiguration().isAlwaysOnTop() && mController.mAtm
                        .mTaskSupervisor.mOpaqueActivityHelper.getOpaqueActivity(sibling) != null) {
                    occludedCount++;
                    break;
                }
            }
        if (occludedCount == numTransient) {
            for (int i = mTransientLaunches.size() - 1; i >= 0; --i) {
                if (mTransientLaunches.keyAt(i).isDescendantOf(task)) {
                    // Keep transient activity visible until transition finished, so it won't pause
                    // with transient-hide tasks that may delay resuming the next top.
                    return true;
                }
        }
        if (occludedCount == numTransient) {
            // Let transient-hide activities pause before transition is finished.
            return false;
        }
+13 −5
Original line number Diff line number Diff line
@@ -1631,6 +1631,8 @@ public class TransitionTests extends WindowTestsBase {
        transition.collect(taskA);
        transition.setTransientLaunch(recent, taskA);
        taskRecent.moveToFront("move-recent-to-front");
        recent.setVisibility(true);
        recent.setState(ActivityRecord.State.RESUMED, "test");

        // During collecting and playing, the recent is on top so it is visible naturally.
        // While B needs isTransientVisible to keep visibility because it is occluded by recents.
@@ -1643,15 +1645,21 @@ public class TransitionTests extends WindowTestsBase {

        // Switch to another task. For example, use gesture navigation to switch tasks.
        taskB.moveToFront("move-b-to-front");
        appB.setVisibility(true);
        // The previous app (taskA) should be paused first so it loses transient visible. Because
        // visually it is taskA -> taskB, the pause -> resume order should be the same.
        assertFalse(controller.isTransientVisible(taskA));
        // Keep the recent visible so there won't be 2 activities pausing at the same time. It is
        // to avoid the latency to resume the current top, i.e. appB.
        assertTrue(controller.isTransientVisible(taskRecent));
        // The recent is paused after the transient transition is finished.
        controller.finishTransition(ActionChain.testFinish(transition));
        // The recent is occluded by appB.
        assertFalse(controller.isTransientVisible(taskRecent));
        // Active transient launch won't be paused if the transition is not finished. It is to
        // avoid the latency to resume the current top (appB) by waiting for both recent and appA
        // to complete pause.
        assertEquals(recent, taskRecent.getResumedActivity());
        assertFalse(taskRecent.startPausing(false /* uiSleeping */, appB /* resuming */, "test"));
        // ActivityRecord#makeInvisible will add the invisible recent to the stopping list.
        // So when the transition finished, the recent can still be notified to pause and stop.
        mDisplayContent.ensureActivitiesVisible(null /* starting */, true /* notifyClients */);
        assertTrue(mSupervisor.mStoppingActivities.contains(recent));
    }

    @Test