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

Commit f649375c authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Reduce unnecessary collecting for wallpaper with shell transition

The adjustWallpaperWindows is a heavy operation (including assigning
layer), and it has no direct relation with ensure visibility of task.
Especially if there are several tasks, it may increase overhead with
dozens milliseconds in a transition. The original problem should be
fixed by collecting wallpaper token instead of window state.
(Because Transition only recognizes wallpaper by token)

Also
 - Reduce re-assigning layer if visibility is not changed.
 - Collect wallpaper token only when the requested visibility is
   different, that reduces lots of checking transition participants.
 - Update wallpaper visibility before playing transition, which is
   similar to legacy adjustWallpaperWindowsForAppTransitionIfNeeded.

Bug: 206487939
Bug: 187461719
Test: WallpaperControllerTests#testWallpaperTokenVisibility
Test: adb shell setprop  persist.debug.shell_transit 1; reboot
      Check 3 cases:
      1. Rotate display -> latency reduced.
      2. Launch app in different orientation from home
         -> wallpaper is not rotated.
      3. Launch an opaque app from home and it launches a
         non-opaque app immediately -> wallpaper should not flash.
Change-Id: I1819f6aad23eb103f97c9d33bc2ad68db0e6c4ed
parent 07d5ae6a
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -139,9 +139,6 @@ class EnsureActivitiesVisibleHelper {
                setActivityVisibilityState(child.asActivityRecord(), starting, resumeTopActivity);
            }
        }
        if (mTaskFragment.mTransitionController.isShellTransitionsEnabled()) {
            mTaskFragment.getDisplayContent().mWallpaperController.adjustWallpaperWindows();
        }
    }

    private void setActivityVisibilityState(ActivityRecord r, ActivityRecord starting,
+27 −25
Original line number Diff line number Diff line
@@ -244,11 +244,11 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
        }
        mParticipants.add(wc);
        if (info.mShowWallpaper) {
            // Collect the wallpaper so it is part of the sync set.
            final WindowContainer wallpaper =
            // Collect the wallpaper token (for isWallpaper(wc)) so it is part of the sync set.
            final WindowState wallpaper =
                    wc.getDisplayContent().mWallpaperController.getTopVisibleWallpaper();
            if (wallpaper != null) {
                collect(wallpaper);
                collect(wallpaper.mToken);
            }
        }
    }
@@ -495,25 +495,35 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
            Slog.e(TAG, "Unexpected Sync ID " + syncId + ". Expected " + mSyncId);
            return;
        }
        int displayId = DEFAULT_DISPLAY;
        for (WindowContainer container : mParticipants) {
            if (container.mDisplayContent == null) continue;
            displayId = container.mDisplayContent.getDisplayId();
        boolean hasWallpaper = false;
        DisplayContent dc = null;
        for (int i = mParticipants.size() - 1; i >= 0; --i) {
            final WindowContainer<?> wc = mParticipants.valueAt(i);
            if (dc == null && wc.mDisplayContent != null) {
                dc = wc.mDisplayContent;
            }
            if (!hasWallpaper && isWallpaper(wc)) {
                hasWallpaper = true;
            }
        }
        if (dc == null) dc = mController.mAtm.mRootWindowContainer.getDefaultDisplay();

        if (mState == STATE_ABORT) {
            mController.abort(this);
            mController.mAtm.mRootWindowContainer.getDisplayContent(displayId)
                    .getPendingTransaction().merge(transaction);
            dc.getPendingTransaction().merge(transaction);
            mSyncId = -1;
            mOverrideOptions = null;
            return;
        }
        // Ensure that wallpaper visibility is updated with the latest wallpaper target.
        if (hasWallpaper) {
            dc.mWallpaperController.adjustWallpaperWindows();
        }

        mState = STATE_PLAYING;
        mController.moveToPlaying(this);

        if (mController.mAtm.mTaskSupervisor.getKeyguardController().isKeyguardLocked(displayId)) {
        if (dc.isKeyguardLocked()) {
            mFlags |= TRANSIT_FLAG_KEYGUARD_LOCKED;
        }

@@ -523,9 +533,9 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
        info.setAnimationOptions(mOverrideOptions);

        // TODO(b/188669821): Move to animation impl in shell.
        handleLegacyRecentsStartBehavior(displayId, info);
        handleLegacyRecentsStartBehavior(dc, info);

        handleNonAppWindowsInTransition(displayId, mType, mFlags);
        handleNonAppWindowsInTransition(dc, mType, mFlags);

        reportStartReasonsToLogger();

@@ -627,14 +637,11 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
    }

    /** @see RecentsAnimationController#attachNavigationBarToApp */
    private void handleLegacyRecentsStartBehavior(int displayId, TransitionInfo info) {
    private void handleLegacyRecentsStartBehavior(DisplayContent dc, TransitionInfo info) {
        if ((mFlags & TRANSIT_FLAG_IS_RECENTS) == 0) {
            return;
        }
        final DisplayContent dc =
                mController.mAtm.mRootWindowContainer.getDisplayContent(displayId);
        if (dc == null) return;
        mRecentsDisplayId = displayId;
        mRecentsDisplayId = dc.mDisplayId;

        // Recents has an input-consumer to grab input from the "live tile" app. Set that up here
        final InputConsumerImpl recentsAnimationInputConsumer =
@@ -679,7 +686,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
        // Find the top-most non-home, closing app.
        for (int i = 0; i < info.getChanges().size(); ++i) {
            final TransitionInfo.Change c = info.getChanges().get(i);
            if (c.getTaskInfo() == null || c.getTaskInfo().displayId != displayId
            if (c.getTaskInfo() == null || c.getTaskInfo().displayId != mRecentsDisplayId
                    || c.getTaskInfo().getActivityType() != ACTIVITY_TYPE_STANDARD
                    || !(c.getMode() == TRANSIT_CLOSE || c.getMode() == TRANSIT_TO_BACK)) {
                continue;
@@ -710,7 +717,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
            t.setLayer(navSurfaceControl, Integer.MAX_VALUE);
        }
        if (mController.mStatusBar != null) {
            mController.mStatusBar.setNavigationBarLumaSamplingEnabled(displayId, false);
            mController.mStatusBar.setNavigationBarLumaSamplingEnabled(mRecentsDisplayId, false);
        }
    }

@@ -760,13 +767,8 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
        }
    }

    private void handleNonAppWindowsInTransition(int displayId,
    private void handleNonAppWindowsInTransition(@NonNull DisplayContent dc,
            @TransitionType int transit, @TransitionFlags int flags) {
        final DisplayContent dc =
                mController.mAtm.mRootWindowContainer.getDisplayContent(displayId);
        if (dc == null) {
            return;
        }
        if ((transit == TRANSIT_KEYGUARD_GOING_AWAY
                || (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY) != 0)
                && !WindowManagerService.sEnableRemoteKeyguardGoingAwayAnimation) {
+3 −2
Original line number Diff line number Diff line
@@ -611,8 +611,9 @@ class WallpaperController {
    private void updateWallpaperTokens(boolean visible) {
        for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
            final WallpaperWindowToken token = mWallpaperTokens.get(curTokenNdx);
            token.updateWallpaperWindows(visible);
            token.getDisplayContent().assignWindowLayers(false);
            if (token.updateWallpaperWindows(visible)) {
                token.mDisplayContent.assignWindowLayers(false /* setLayoutNeeded */);
            }
        }
    }

+13 −7
Original line number Diff line number Diff line
@@ -104,18 +104,21 @@ class WallpaperWindowToken extends WindowToken {
        }
    }

    void updateWallpaperWindows(boolean visible) {
    /** Returns {@code true} if visibility is changed. */
    boolean updateWallpaperWindows(boolean visible) {
        boolean changed = false;
        if (isVisible() != visible) {
            ProtoLog.d(WM_DEBUG_WALLPAPER, "Wallpaper token %s visible=%b",
                    token, visible);
            setVisibility(visible);
            changed = true;
        }
        final WallpaperController wallpaperController = mDisplayContent.mWallpaperController;
        if (mTransitionController.isShellTransitionsEnabled()) {
            return;
            return changed;
        }

        final WindowState wallpaperTarget = wallpaperController.getWallpaperTarget();
        final WindowState wallpaperTarget =
                mDisplayContent.mWallpaperController.getWallpaperTarget();

        if (visible && wallpaperTarget != null) {
            final RecentsAnimationController recentsAnimationController =
@@ -137,6 +140,7 @@ class WallpaperWindowToken extends WindowToken {
        }

        setVisible(visible);
        return changed;
    }

    private void setVisible(boolean visible) {
@@ -155,10 +159,12 @@ class WallpaperWindowToken extends WindowToken {
     * transition. In that situation, make sure to call {@link #commitVisibility} when done.
     */
    void setVisibility(boolean visible) {
        if (mVisibleRequested != visible) {
            // Before setting mVisibleRequested so we can track changes.
            mTransitionController.collect(this);

            setVisibleRequested(visible);
        }

        // If in a transition, defer commits for activities that are going invisible
        if (!visible && (mTransitionController.inTransition()
+14 −8
Original line number Diff line number Diff line
@@ -54,7 +54,6 @@ import android.view.RoundedCorners;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.WindowManager;
import android.window.ITransitionPlayer;

import androidx.test.filters.SmallTest;

@@ -313,11 +312,7 @@ public class WallpaperControllerTests extends WindowTestsBase {
        wallpaperWindow.setHasSurface(true);

        // Set-up mock shell transitions
        final IBinder mockBinder = mock(IBinder.class);
        final ITransitionPlayer mockPlayer = mock(ITransitionPlayer.class);
        doReturn(mockBinder).when(mockPlayer).asBinder();
        mWm.mAtmService.getTransitionController().registerTransitionPlayer(mockPlayer,
                null /* appThread */);
        registerTestTransitionPlayer();

        Transition transit =
                mWm.mAtmService.getTransitionController().createTransition(TRANSIT_OPEN);
@@ -338,10 +333,21 @@ public class WallpaperControllerTests extends WindowTestsBase {
        assertFalse(token.isVisibleRequested());
        assertTrue(token.isVisible());

        transit.onTransactionReady(transit.getSyncId(), mock(SurfaceControl.Transaction.class));
        transit.finishTransition();
        final SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class);
        token.finishSync(t, false /* cancel */);
        transit.onTransactionReady(transit.getSyncId(), t);
        dc.mTransitionController.finishTransition(transit);
        assertFalse(wallpaperWindow.isVisible());
        assertFalse(token.isVisible());

        // Assume wallpaper was visible. When transaction is ready without wallpaper target,
        // wallpaper should be requested to be invisible.
        token.setVisibility(true);
        transit = dc.mTransitionController.createTransition(TRANSIT_CLOSE);
        dc.mTransitionController.collect(token);
        transit.onTransactionReady(transit.getSyncId(), t);
        assertFalse(token.isVisibleRequested());
        assertTrue(token.isVisible());
    }

    private WindowState createWallpaperTargetWindow(DisplayContent dc) {