diff options
| author | 2021-11-19 20:28:17 +0800 | |
|---|---|---|
| committer | 2021-11-22 23:25:02 +0800 | |
| commit | f649375c439402f92372a4e42bc8a2226e11f8ea (patch) | |
| tree | c2ca59300774777125d3be90b194d960cc6db332 | |
| parent | 07d5ae6a67875ac66c3f39c0d27c2ca82018bd02 (diff) | |
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
5 files changed, 57 insertions, 45 deletions
diff --git a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java index badb1f5a0a12..963f3265757d 100644 --- a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java +++ b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java @@ -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, diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index f175eec15064..7349594483a8 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -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) { diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java index 08b1a2f39953..e24be378d29a 100644 --- a/services/core/java/com/android/server/wm/WallpaperController.java +++ b/services/core/java/com/android/server/wm/WallpaperController.java @@ -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 */); + } } } diff --git a/services/core/java/com/android/server/wm/WallpaperWindowToken.java b/services/core/java/com/android/server/wm/WallpaperWindowToken.java index 3a639f50603f..fe405e5b3af8 100644 --- a/services/core/java/com/android/server/wm/WallpaperWindowToken.java +++ b/services/core/java/com/android/server/wm/WallpaperWindowToken.java @@ -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) { - // Before setting mVisibleRequested so we can track changes. - mTransitionController.collect(this); + if (mVisibleRequested != visible) { + // Before setting mVisibleRequested so we can track changes. + mTransitionController.collect(this); - setVisibleRequested(visible); + setVisibleRequested(visible); + } // If in a transition, defer commits for activities that are going invisible if (!visible && (mTransitionController.inTransition() diff --git a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java index f366f57bae08..caaf4e495e63 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java @@ -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) { |