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

Commit 6cfcecc8 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Do not skip wake-and-unlock animation

When systemui requests WAKE_AND_UNLOCK (from standalone fingerprint
sensor), DisplayPolicy will have mScreenOnEarly but no mScreenOnFully
yet. If the animation is skipped, a snapshot starting window with
fixed rotation transform won't be notified by finishing transition to
restore the state. Also because the screen will be fully on, the
animation can still be visible.

This change passes ignoreScreenOn with considering isKeyguardGoingAway.
And refactor the logic to a method deferCommitVisibilityChange so it
is easier to read. Also add a quick path for shell transition because
if it is enabled, isTransitionSet and isAnimating(TYPE_RECENTS) will
always be false.

Fixes: 258383126
Test: atest ActivityRecordTests#testSetVisibility_invisibleToVisible

Change-Id: I2519eb558262a9f9126ed093448a9a6cefb76faa
parent 8d6647d4
Loading
Loading
Loading
Loading
+56 −36
Original line number Diff line number Diff line
@@ -5249,47 +5249,67 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        }
        // If we are preparing an app transition, then delay changing
        // the visibility of this token until we execute that transition.
        // Note that we ignore display frozen since we want the opening / closing transition type
        // can be updated correctly even display frozen, and it's safe since in applyAnimation will
        // still check DC#okToAnimate again if the transition animation is fine to apply.
        // TODO(new-app-transition): Rewrite this logic using WM Shell.
        final boolean recentsAnimating = isAnimating(PARENTS, ANIMATION_TYPE_RECENTS);
        final boolean isEnteringPipWithoutVisibleChange = mWaitForEnteringPinnedMode
                && mVisible == visible;
        if (okToAnimate(true /* ignoreFrozen */, canTurnScreenOn())
                && (appTransition.isTransitionSet()
                || (recentsAnimating && !isActivityTypeHome()))
        if (deferCommitVisibilityChange(visible)) {
            return;
        }

        commitVisibility(visible, true /* performLayout */);
        updateReportedVisibilityLocked();
    }

    /**
     * Returns {@code true} if this activity is either added to opening-apps or closing-apps.
     * Then its visibility will be committed until the transition is ready.
     */
    private boolean deferCommitVisibilityChange(boolean visible) {
        if (!mDisplayContent.mAppTransition.isTransitionSet()) {
            if (mTransitionController.isShellTransitionsEnabled()) {
                // Shell transition doesn't use opening/closing sets.
                return false;
            }
            // Defer committing visibility for non-home app which is animating by recents.
            if (isActivityTypeHome() || !isAnimating(PARENTS, ANIMATION_TYPE_RECENTS)) {
                return false;
            }
        }
        if (mWaitForEnteringPinnedMode && mVisible == visible) {
            // If the visibility is not changed during enter PIP, we don't want to include it in
            // app transition to affect the animation theme, because the Pip organizer will
            // animate the entering PIP instead.
                && !isEnteringPipWithoutVisibleChange) {
            return false;
        }

        // The animation will be visible soon so do not skip by screen off.
        final boolean ignoreScreenOn = canTurnScreenOn() || mTaskSupervisor.getKeyguardController()
                .isKeyguardGoingAway(mDisplayContent.mDisplayId);
        // Ignore display frozen so the opening / closing transition type can be updated correctly
        // even if the display is frozen. And it's safe since in applyAnimation will still check
        // DC#okToAnimate again if the transition animation is fine to apply.
        if (!okToAnimate(true /* ignoreFrozen */, ignoreScreenOn)) {
            return false;
        }
        if (visible) {
                displayContent.mOpeningApps.add(this);
            mDisplayContent.mOpeningApps.add(this);
            mEnteringAnimation = true;
        } else if (mVisible) {
                displayContent.mClosingApps.add(this);
            mDisplayContent.mClosingApps.add(this);
            mEnteringAnimation = false;
        }
            if ((appTransition.getTransitFlags() & TRANSIT_FLAG_OPEN_BEHIND) != 0) {
                // We're launchingBehind, add the launching activity to mOpeningApps.
                final WindowState win = getDisplayContent().findFocusedWindow();
        if ((mDisplayContent.mAppTransition.getTransitFlags() & TRANSIT_FLAG_OPEN_BEHIND) != 0) {
            // Add the launching-behind activity to mOpeningApps.
            final WindowState win = mDisplayContent.findFocusedWindow();
            if (win != null) {
                final ActivityRecord focusedActivity = win.mActivityRecord;
                if (focusedActivity != null) {
                    ProtoLog.d(WM_DEBUG_APP_TRANSITIONS,
                            "TRANSIT_FLAG_OPEN_BEHIND,  adding %s to mOpeningApps",
                            focusedActivity);

                    // Force animation to be loaded.
                        displayContent.mOpeningApps.add(focusedActivity);
                    }
                    mDisplayContent.mOpeningApps.add(focusedActivity);
                }
            }
            return;
        }

        commitVisibility(visible, true /* performLayout */);
        updateReportedVisibilityLocked();
        return true;
    }

    @Override
+2 −3
Original line number Diff line number Diff line
@@ -4935,9 +4935,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    @Override
    boolean okToAnimate(boolean ignoreFrozen, boolean ignoreScreenOn) {
        return okToDisplay(ignoreFrozen, ignoreScreenOn)
                && (mDisplayId != DEFAULT_DISPLAY
                || mWmService.mPolicy.okToAnimate(ignoreScreenOn))
                && getDisplayPolicy().isScreenOnFully();
                && (mDisplayId != DEFAULT_DISPLAY || mWmService.mPolicy.okToAnimate(ignoreScreenOn))
                && (ignoreFrozen || mDisplayPolicy.isScreenOnFully());
    }

    static final class TaskForResizePointSearchResult implements Predicate<Task> {
+11 −0
Original line number Diff line number Diff line
@@ -3091,6 +3091,17 @@ public class ActivityRecordTests extends WindowTestsBase {
        assertTrue(activity.mVisibleRequested);
        assertTrue(activity.mDisplayContent.mOpeningApps.contains(activity));
        assertFalse(activity.mDisplayContent.mClosingApps.contains(activity));

        // There should still be animation (add to opening) if keyguard is going away while the
        // screen is off because it will be visible after screen is turned on by unlocking.
        mDisplayContent.mOpeningApps.remove(activity);
        mDisplayContent.mClosingApps.remove(activity);
        activity.commitVisibility(false /* visible */, false /* performLayout */);
        mDisplayContent.getDisplayPolicy().screenTurnedOff();
        final KeyguardController controller = mSupervisor.getKeyguardController();
        doReturn(true).when(controller).isKeyguardGoingAway(anyInt());
        activity.setVisibility(true);
        assertTrue(mDisplayContent.mOpeningApps.contains(activity));
    }

    @Test