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
This commit is contained in:
@@ -139,9 +139,6 @@ class EnsureActivitiesVisibleHelper {
|
|||||||
setActivityVisibilityState(child.asActivityRecord(), starting, resumeTopActivity);
|
setActivityVisibilityState(child.asActivityRecord(), starting, resumeTopActivity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mTaskFragment.mTransitionController.isShellTransitionsEnabled()) {
|
|
||||||
mTaskFragment.getDisplayContent().mWallpaperController.adjustWallpaperWindows();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setActivityVisibilityState(ActivityRecord r, ActivityRecord starting,
|
private void setActivityVisibilityState(ActivityRecord r, ActivityRecord starting,
|
||||||
|
|||||||
@@ -244,11 +244,11 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
|
|||||||
}
|
}
|
||||||
mParticipants.add(wc);
|
mParticipants.add(wc);
|
||||||
if (info.mShowWallpaper) {
|
if (info.mShowWallpaper) {
|
||||||
// Collect the wallpaper so it is part of the sync set.
|
// Collect the wallpaper token (for isWallpaper(wc)) so it is part of the sync set.
|
||||||
final WindowContainer wallpaper =
|
final WindowState wallpaper =
|
||||||
wc.getDisplayContent().mWallpaperController.getTopVisibleWallpaper();
|
wc.getDisplayContent().mWallpaperController.getTopVisibleWallpaper();
|
||||||
if (wallpaper != null) {
|
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);
|
Slog.e(TAG, "Unexpected Sync ID " + syncId + ". Expected " + mSyncId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int displayId = DEFAULT_DISPLAY;
|
boolean hasWallpaper = false;
|
||||||
for (WindowContainer container : mParticipants) {
|
DisplayContent dc = null;
|
||||||
if (container.mDisplayContent == null) continue;
|
for (int i = mParticipants.size() - 1; i >= 0; --i) {
|
||||||
displayId = container.mDisplayContent.getDisplayId();
|
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) {
|
if (mState == STATE_ABORT) {
|
||||||
mController.abort(this);
|
mController.abort(this);
|
||||||
mController.mAtm.mRootWindowContainer.getDisplayContent(displayId)
|
dc.getPendingTransaction().merge(transaction);
|
||||||
.getPendingTransaction().merge(transaction);
|
|
||||||
mSyncId = -1;
|
mSyncId = -1;
|
||||||
mOverrideOptions = null;
|
mOverrideOptions = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Ensure that wallpaper visibility is updated with the latest wallpaper target.
|
||||||
|
if (hasWallpaper) {
|
||||||
|
dc.mWallpaperController.adjustWallpaperWindows();
|
||||||
|
}
|
||||||
|
|
||||||
mState = STATE_PLAYING;
|
mState = STATE_PLAYING;
|
||||||
mController.moveToPlaying(this);
|
mController.moveToPlaying(this);
|
||||||
|
|
||||||
if (mController.mAtm.mTaskSupervisor.getKeyguardController().isKeyguardLocked(displayId)) {
|
if (dc.isKeyguardLocked()) {
|
||||||
mFlags |= TRANSIT_FLAG_KEYGUARD_LOCKED;
|
mFlags |= TRANSIT_FLAG_KEYGUARD_LOCKED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -523,9 +533,9 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
|
|||||||
info.setAnimationOptions(mOverrideOptions);
|
info.setAnimationOptions(mOverrideOptions);
|
||||||
|
|
||||||
// TODO(b/188669821): Move to animation impl in shell.
|
// TODO(b/188669821): Move to animation impl in shell.
|
||||||
handleLegacyRecentsStartBehavior(displayId, info);
|
handleLegacyRecentsStartBehavior(dc, info);
|
||||||
|
|
||||||
handleNonAppWindowsInTransition(displayId, mType, mFlags);
|
handleNonAppWindowsInTransition(dc, mType, mFlags);
|
||||||
|
|
||||||
reportStartReasonsToLogger();
|
reportStartReasonsToLogger();
|
||||||
|
|
||||||
@@ -627,14 +637,11 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @see RecentsAnimationController#attachNavigationBarToApp */
|
/** @see RecentsAnimationController#attachNavigationBarToApp */
|
||||||
private void handleLegacyRecentsStartBehavior(int displayId, TransitionInfo info) {
|
private void handleLegacyRecentsStartBehavior(DisplayContent dc, TransitionInfo info) {
|
||||||
if ((mFlags & TRANSIT_FLAG_IS_RECENTS) == 0) {
|
if ((mFlags & TRANSIT_FLAG_IS_RECENTS) == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final DisplayContent dc =
|
mRecentsDisplayId = dc.mDisplayId;
|
||||||
mController.mAtm.mRootWindowContainer.getDisplayContent(displayId);
|
|
||||||
if (dc == null) return;
|
|
||||||
mRecentsDisplayId = displayId;
|
|
||||||
|
|
||||||
// Recents has an input-consumer to grab input from the "live tile" app. Set that up here
|
// Recents has an input-consumer to grab input from the "live tile" app. Set that up here
|
||||||
final InputConsumerImpl recentsAnimationInputConsumer =
|
final InputConsumerImpl recentsAnimationInputConsumer =
|
||||||
@@ -679,7 +686,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
|
|||||||
// Find the top-most non-home, closing app.
|
// Find the top-most non-home, closing app.
|
||||||
for (int i = 0; i < info.getChanges().size(); ++i) {
|
for (int i = 0; i < info.getChanges().size(); ++i) {
|
||||||
final TransitionInfo.Change c = info.getChanges().get(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.getTaskInfo().getActivityType() != ACTIVITY_TYPE_STANDARD
|
||||||
|| !(c.getMode() == TRANSIT_CLOSE || c.getMode() == TRANSIT_TO_BACK)) {
|
|| !(c.getMode() == TRANSIT_CLOSE || c.getMode() == TRANSIT_TO_BACK)) {
|
||||||
continue;
|
continue;
|
||||||
@@ -710,7 +717,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
|
|||||||
t.setLayer(navSurfaceControl, Integer.MAX_VALUE);
|
t.setLayer(navSurfaceControl, Integer.MAX_VALUE);
|
||||||
}
|
}
|
||||||
if (mController.mStatusBar != null) {
|
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) {
|
@TransitionType int transit, @TransitionFlags int flags) {
|
||||||
final DisplayContent dc =
|
|
||||||
mController.mAtm.mRootWindowContainer.getDisplayContent(displayId);
|
|
||||||
if (dc == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ((transit == TRANSIT_KEYGUARD_GOING_AWAY
|
if ((transit == TRANSIT_KEYGUARD_GOING_AWAY
|
||||||
|| (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY) != 0)
|
|| (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY) != 0)
|
||||||
&& !WindowManagerService.sEnableRemoteKeyguardGoingAwayAnimation) {
|
&& !WindowManagerService.sEnableRemoteKeyguardGoingAwayAnimation) {
|
||||||
|
|||||||
@@ -611,8 +611,9 @@ class WallpaperController {
|
|||||||
private void updateWallpaperTokens(boolean visible) {
|
private void updateWallpaperTokens(boolean visible) {
|
||||||
for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
|
for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
|
||||||
final WallpaperWindowToken token = mWallpaperTokens.get(curTokenNdx);
|
final WallpaperWindowToken token = mWallpaperTokens.get(curTokenNdx);
|
||||||
token.updateWallpaperWindows(visible);
|
if (token.updateWallpaperWindows(visible)) {
|
||||||
token.getDisplayContent().assignWindowLayers(false);
|
token.mDisplayContent.assignWindowLayers(false /* setLayoutNeeded */);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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) {
|
if (isVisible() != visible) {
|
||||||
ProtoLog.d(WM_DEBUG_WALLPAPER, "Wallpaper token %s visible=%b",
|
ProtoLog.d(WM_DEBUG_WALLPAPER, "Wallpaper token %s visible=%b",
|
||||||
token, visible);
|
token, visible);
|
||||||
setVisibility(visible);
|
setVisibility(visible);
|
||||||
|
changed = true;
|
||||||
}
|
}
|
||||||
final WallpaperController wallpaperController = mDisplayContent.mWallpaperController;
|
|
||||||
if (mTransitionController.isShellTransitionsEnabled()) {
|
if (mTransitionController.isShellTransitionsEnabled()) {
|
||||||
return;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
final WindowState wallpaperTarget = wallpaperController.getWallpaperTarget();
|
final WindowState wallpaperTarget =
|
||||||
|
mDisplayContent.mWallpaperController.getWallpaperTarget();
|
||||||
|
|
||||||
if (visible && wallpaperTarget != null) {
|
if (visible && wallpaperTarget != null) {
|
||||||
final RecentsAnimationController recentsAnimationController =
|
final RecentsAnimationController recentsAnimationController =
|
||||||
@@ -137,6 +140,7 @@ class WallpaperWindowToken extends WindowToken {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setVisible(visible);
|
setVisible(visible);
|
||||||
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setVisible(boolean visible) {
|
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.
|
* transition. In that situation, make sure to call {@link #commitVisibility} when done.
|
||||||
*/
|
*/
|
||||||
void setVisibility(boolean visible) {
|
void setVisibility(boolean visible) {
|
||||||
|
if (mVisibleRequested != visible) {
|
||||||
// Before setting mVisibleRequested so we can track changes.
|
// Before setting mVisibleRequested so we can track changes.
|
||||||
mTransitionController.collect(this);
|
mTransitionController.collect(this);
|
||||||
|
|
||||||
setVisibleRequested(visible);
|
setVisibleRequested(visible);
|
||||||
|
}
|
||||||
|
|
||||||
// If in a transition, defer commits for activities that are going invisible
|
// If in a transition, defer commits for activities that are going invisible
|
||||||
if (!visible && (mTransitionController.inTransition()
|
if (!visible && (mTransitionController.inTransition()
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ import android.view.RoundedCorners;
|
|||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
import android.view.SurfaceControl;
|
import android.view.SurfaceControl;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.window.ITransitionPlayer;
|
|
||||||
|
|
||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
@@ -313,11 +312,7 @@ public class WallpaperControllerTests extends WindowTestsBase {
|
|||||||
wallpaperWindow.setHasSurface(true);
|
wallpaperWindow.setHasSurface(true);
|
||||||
|
|
||||||
// Set-up mock shell transitions
|
// Set-up mock shell transitions
|
||||||
final IBinder mockBinder = mock(IBinder.class);
|
registerTestTransitionPlayer();
|
||||||
final ITransitionPlayer mockPlayer = mock(ITransitionPlayer.class);
|
|
||||||
doReturn(mockBinder).when(mockPlayer).asBinder();
|
|
||||||
mWm.mAtmService.getTransitionController().registerTransitionPlayer(mockPlayer,
|
|
||||||
null /* appThread */);
|
|
||||||
|
|
||||||
Transition transit =
|
Transition transit =
|
||||||
mWm.mAtmService.getTransitionController().createTransition(TRANSIT_OPEN);
|
mWm.mAtmService.getTransitionController().createTransition(TRANSIT_OPEN);
|
||||||
@@ -338,10 +333,21 @@ public class WallpaperControllerTests extends WindowTestsBase {
|
|||||||
assertFalse(token.isVisibleRequested());
|
assertFalse(token.isVisibleRequested());
|
||||||
assertTrue(token.isVisible());
|
assertTrue(token.isVisible());
|
||||||
|
|
||||||
transit.onTransactionReady(transit.getSyncId(), mock(SurfaceControl.Transaction.class));
|
final SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class);
|
||||||
transit.finishTransition();
|
token.finishSync(t, false /* cancel */);
|
||||||
|
transit.onTransactionReady(transit.getSyncId(), t);
|
||||||
|
dc.mTransitionController.finishTransition(transit);
|
||||||
assertFalse(wallpaperWindow.isVisible());
|
assertFalse(wallpaperWindow.isVisible());
|
||||||
assertFalse(token.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) {
|
private WindowState createWallpaperTargetWindow(DisplayContent dc) {
|
||||||
|
|||||||
Reference in New Issue
Block a user