summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Riddle Hsu <riddlehsu@google.com> 2021-11-19 20:28:17 +0800
committer Riddle Hsu <riddlehsu@google.com> 2021-11-22 23:25:02 +0800
commitf649375c439402f92372a4e42bc8a2226e11f8ea (patch)
treec2ca59300774777125d3be90b194d960cc6db332
parent07d5ae6a67875ac66c3f39c0d27c2ca82018bd02 (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
-rw-r--r--services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java3
-rw-r--r--services/core/java/com/android/server/wm/Transition.java52
-rw-r--r--services/core/java/com/android/server/wm/WallpaperController.java5
-rw-r--r--services/core/java/com/android/server/wm/WallpaperWindowToken.java20
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java22
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) {