Only consider occluding transient below-task for wallpaper target
Otherwise if keyguard is not locked (recents will be moved to top),
the wallpaper target may be updated to the window of below-task
temporally when swiping-up. Which causes the wallpaper window cannot
apply the same fixed-rotation transform if the recents activity has
the transform. Such as when swiping up to portrait home from a
landscape activity, the wallpaper will be rotated to landscape and
trigger an unnecessary display rotation animation.
Bug: 230582311
Test: atest WallpaperControllerTests# \
testFixedRotationRecentsAnimatingTask
Test: adb shell setprop persist.wm.debug.shell_transit 1; reboot
Swipe landscape app to home and no additional display
rotation animation for rotated wallpaper.
With show-when-locked activity on lockscreen, the wallpaper
can be visible when swiping up.
Change-Id: Ibd47e9d78c2f6767a78255db62284bbbf176918c
This commit is contained in:
@@ -21,6 +21,7 @@ import static android.app.WallpaperManager.COMMAND_UNFREEZE;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
|
||||
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
|
||||
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
|
||||
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
|
||||
|
||||
@@ -181,16 +182,11 @@ class WallpaperController {
|
||||
mFindResults.setUseTopWallpaperAsTarget(true);
|
||||
}
|
||||
|
||||
final RecentsAnimationController recentsAnimationController =
|
||||
mService.getRecentsAnimationController();
|
||||
final boolean animationWallpaper = animatingContainer != null
|
||||
&& animatingContainer.getAnimation() != null
|
||||
&& animatingContainer.getAnimation().getShowWallpaper();
|
||||
final boolean hasWallpaper = w.hasWallpaper() || animationWallpaper;
|
||||
final boolean isRecentsTransitionTarget = (recentsAnimationController != null
|
||||
&& recentsAnimationController.isWallpaperVisible(w))
|
||||
|| w.mTransitionController.isTransientHide(w.getTask());
|
||||
if (isRecentsTransitionTarget) {
|
||||
if (isRecentsTransitionTarget(w)) {
|
||||
if (DEBUG_WALLPAPER) Slog.v(TAG, "Found recents animation wallpaper target: " + w);
|
||||
mFindResults.setWallpaperTarget(w);
|
||||
return true;
|
||||
@@ -214,6 +210,22 @@ class WallpaperController {
|
||||
return false;
|
||||
};
|
||||
|
||||
private boolean isRecentsTransitionTarget(WindowState w) {
|
||||
if (w.mTransitionController.isShellTransitionsEnabled()) {
|
||||
// Because the recents activity is invisible in background while keyguard is occluded
|
||||
// (the activity window is on screen while keyguard is locked) with recents animation,
|
||||
// the task animating by recents needs to be wallpaper target to make wallpaper visible.
|
||||
// While for unlocked case, because recents activity will be moved to top, it can be
|
||||
// the wallpaper target naturally.
|
||||
return w.mActivityRecord != null && w.mAttrs.type == TYPE_BASE_APPLICATION
|
||||
&& mDisplayContent.isKeyguardLocked()
|
||||
&& w.mTransitionController.isTransientHide(w.getTask());
|
||||
}
|
||||
// The window is either the recents activity or is in the task animating by the recents.
|
||||
final RecentsAnimationController controller = mService.getRecentsAnimationController();
|
||||
return controller != null && controller.isWallpaperVisible(w);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #computeLastWallpaperZoomOut()
|
||||
*/
|
||||
|
||||
@@ -35,6 +35,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyFloat;
|
||||
@@ -82,10 +83,7 @@ public class WallpaperControllerTests extends WindowTestsBase {
|
||||
assertFalse(dc.mWallpaperController.canScreenshotWallpaper());
|
||||
|
||||
// No wallpaper WSA Surface
|
||||
WindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm, mock(IBinder.class),
|
||||
true, dc, true /* ownerCanManageAppTokens */);
|
||||
WindowState wallpaperWindow = createWindow(null /* parent */, TYPE_WALLPAPER,
|
||||
wallpaperWindowToken, "wallpaperWindow");
|
||||
final WindowState wallpaperWindow = createWallpaperWindow(dc);
|
||||
assertFalse(dc.mWallpaperController.canScreenshotWallpaper());
|
||||
|
||||
// Wallpaper with not visible WSA surface.
|
||||
@@ -107,13 +105,10 @@ public class WallpaperControllerTests extends WindowTestsBase {
|
||||
@Test
|
||||
public void testWallpaperSizeWithFixedTransform() {
|
||||
// No wallpaper
|
||||
final DisplayContent dc = createNewDisplay();
|
||||
final DisplayContent dc = mDisplayContent;
|
||||
|
||||
// No wallpaper WSA Surface
|
||||
WindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm, mock(IBinder.class),
|
||||
true, dc, true /* ownerCanManageAppTokens */);
|
||||
WindowState wallpaperWindow = createWindow(null /* parent */, TYPE_WALLPAPER,
|
||||
wallpaperWindowToken, "wallpaperWindow");
|
||||
final WindowState wallpaperWindow = createWallpaperWindow(dc);
|
||||
|
||||
WindowManager.LayoutParams attrs = wallpaperWindow.getAttrs();
|
||||
Rect bounds = dc.getBounds();
|
||||
@@ -153,7 +148,7 @@ public class WallpaperControllerTests extends WindowTestsBase {
|
||||
final WmDisplayCutout cutout = dc.calculateDisplayCutoutForRotation(Surface.ROTATION_0);
|
||||
final DisplayFrames displayFrames = new DisplayFrames(dc.getDisplayId(), new InsetsState(),
|
||||
info, cutout, RoundedCorners.NO_ROUNDED_CORNERS, new PrivacyIndicatorBounds());
|
||||
wallpaperWindowToken.applyFixedRotationTransform(info, displayFrames, config);
|
||||
wallpaperWindow.mToken.applyFixedRotationTransform(info, displayFrames, config);
|
||||
|
||||
// Check that the wallpaper has the same frame in landscape than in portrait
|
||||
assertEquals(Configuration.ORIENTATION_LANDSCAPE, dc.getConfiguration().orientation);
|
||||
@@ -163,10 +158,7 @@ public class WallpaperControllerTests extends WindowTestsBase {
|
||||
@Test
|
||||
public void testWallpaperZoom() throws RemoteException {
|
||||
final DisplayContent dc = mWm.mRoot.getDefaultDisplay();
|
||||
final WallpaperWindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm,
|
||||
mock(IBinder.class), true, dc, true /* ownerCanManageAppTokens */);
|
||||
final WindowState wallpaperWindow = createWindow(null, TYPE_WALLPAPER, wallpaperWindowToken,
|
||||
"wallpaperWindow");
|
||||
final WindowState wallpaperWindow = createWallpaperWindow(dc);
|
||||
wallpaperWindow.getAttrs().privateFlags |=
|
||||
WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS;
|
||||
|
||||
@@ -189,10 +181,7 @@ public class WallpaperControllerTests extends WindowTestsBase {
|
||||
@Test
|
||||
public void testWallpaperZoom_shouldNotScaleWallpaper() throws RemoteException {
|
||||
final DisplayContent dc = mWm.mRoot.getDefaultDisplay();
|
||||
final WallpaperWindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm,
|
||||
mock(IBinder.class), true, dc, true /* ownerCanManageAppTokens */);
|
||||
final WindowState wallpaperWindow = createWindow(null, TYPE_WALLPAPER, wallpaperWindowToken,
|
||||
"wallpaperWindow");
|
||||
final WindowState wallpaperWindow = createWallpaperWindow(dc);
|
||||
wallpaperWindow.getAttrs().privateFlags |=
|
||||
WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS;
|
||||
|
||||
@@ -219,11 +208,7 @@ public class WallpaperControllerTests extends WindowTestsBase {
|
||||
@Test
|
||||
public void testWallpaperZoom_multipleCallers() {
|
||||
final DisplayContent dc = mWm.mRoot.getDefaultDisplay();
|
||||
final WallpaperWindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm,
|
||||
mock(IBinder.class), true, dc,
|
||||
true /* ownerCanManageAppTokens */);
|
||||
final WindowState wallpaperWindow = createWindow(null, TYPE_WALLPAPER, wallpaperWindowToken,
|
||||
"wallpaperWindow");
|
||||
final WindowState wallpaperWindow = createWallpaperWindow(dc);
|
||||
wallpaperWindow.getAttrs().privateFlags |=
|
||||
WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS;
|
||||
|
||||
@@ -278,37 +263,51 @@ public class WallpaperControllerTests extends WindowTestsBase {
|
||||
assertEquals(WINDOWING_MODE_FULLSCREEN, token.getWindowingMode());
|
||||
}
|
||||
|
||||
@UseTestDisplay(addWindows = W_ACTIVITY)
|
||||
@Test
|
||||
public void testFixedRotationRecentsAnimatingTask() {
|
||||
final WindowState wallpaperWindow = createWallpaperWindow(mDisplayContent);
|
||||
final WallpaperWindowToken wallpaperToken = wallpaperWindow.mToken.asWallpaperToken();
|
||||
final WindowState appWin = createWindow(null, TYPE_BASE_APPLICATION, "app");
|
||||
makeWindowVisible(appWin);
|
||||
final ActivityRecord r = appWin.mActivityRecord;
|
||||
final RecentsAnimationController recentsController = mock(RecentsAnimationController.class);
|
||||
doReturn(true).when(recentsController).isWallpaperVisible(eq(mAppWindow));
|
||||
doReturn(true).when(recentsController).isWallpaperVisible(eq(appWin));
|
||||
mWm.setRecentsAnimationController(recentsController);
|
||||
|
||||
mAppWindow.mActivityRecord.applyFixedRotationTransform(mDisplayContent.getDisplayInfo(),
|
||||
r.applyFixedRotationTransform(mDisplayContent.getDisplayInfo(),
|
||||
mDisplayContent.mDisplayFrames, mDisplayContent.getConfiguration());
|
||||
mAppWindow.mActivityRecord.mVisibleRequested = true;
|
||||
mDisplayContent.mWallpaperController.adjustWallpaperWindows();
|
||||
|
||||
assertEquals(mAppWindow, mDisplayContent.mWallpaperController.getWallpaperTarget());
|
||||
// Wallpaper should link the transform of its target.
|
||||
assertTrue(mAppWindow.mActivityRecord.hasFixedRotationTransform());
|
||||
|
||||
mAppWindow.mActivityRecord.finishFixedRotationTransform();
|
||||
// Invisible requested activity should not share its rotation transform.
|
||||
mAppWindow.mActivityRecord.mVisibleRequested = false;
|
||||
r.mVisibleRequested = false;
|
||||
mDisplayContent.mWallpaperController.adjustWallpaperWindows();
|
||||
assertFalse(wallpaperToken.hasFixedRotationTransform());
|
||||
|
||||
assertFalse(mAppWindow.mActivityRecord.hasFixedRotationTransform());
|
||||
// Wallpaper should link the transform of its target.
|
||||
r.mVisibleRequested = true;
|
||||
mDisplayContent.mWallpaperController.adjustWallpaperWindows();
|
||||
assertEquals(appWin, mDisplayContent.mWallpaperController.getWallpaperTarget());
|
||||
assertTrue(r.hasFixedRotationTransform());
|
||||
assertTrue(wallpaperToken.hasFixedRotationTransform());
|
||||
|
||||
// The case with shell transition.
|
||||
registerTestTransitionPlayer();
|
||||
final Transition t = r.mTransitionController.createTransition(TRANSIT_OPEN);
|
||||
final ActivityRecord recents = mock(ActivityRecord.class);
|
||||
t.collect(r.getTask());
|
||||
r.mTransitionController.setTransientLaunch(recents, r.getTask());
|
||||
// The activity in restore-below task should not be the target if keyguard is not locked.
|
||||
mDisplayContent.mWallpaperController.adjustWallpaperWindows();
|
||||
assertNotEquals(appWin, mDisplayContent.mWallpaperController.getWallpaperTarget());
|
||||
// The activity in restore-below task should be the target if keyguard is occluded.
|
||||
doReturn(true).when(mDisplayContent).isKeyguardLocked();
|
||||
mDisplayContent.mWallpaperController.adjustWallpaperWindows();
|
||||
assertEquals(appWin, mDisplayContent.mWallpaperController.getWallpaperTarget());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWallpaperTokenVisibility() {
|
||||
final DisplayContent dc = mWm.mRoot.getDefaultDisplay();
|
||||
final WallpaperWindowToken token = new WallpaperWindowToken(mWm, mock(IBinder.class),
|
||||
true, dc, true /* ownerCanManageAppTokens */);
|
||||
final WindowState wallpaperWindow = createWindow(null, TYPE_WALLPAPER, token,
|
||||
"wallpaperWindow");
|
||||
final WindowState wallpaperWindow = createWallpaperWindow(dc);
|
||||
final WallpaperWindowToken token = wallpaperWindow.mToken.asWallpaperToken();
|
||||
wallpaperWindow.setHasSurface(true);
|
||||
|
||||
// Set-up mock shell transitions
|
||||
@@ -350,6 +349,13 @@ public class WallpaperControllerTests extends WindowTestsBase {
|
||||
assertTrue(token.isVisible());
|
||||
}
|
||||
|
||||
private WindowState createWallpaperWindow(DisplayContent dc) {
|
||||
final WindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm, mock(IBinder.class),
|
||||
true /* explicit */, dc, true /* ownerCanManageAppTokens */);
|
||||
return createWindow(null /* parent */, TYPE_WALLPAPER, wallpaperWindowToken,
|
||||
"wallpaperWindow");
|
||||
}
|
||||
|
||||
private WindowState createWallpaperTargetWindow(DisplayContent dc) {
|
||||
final ActivityRecord homeActivity = new ActivityBuilder(mWm.mAtmService)
|
||||
.setTask(dc.getDefaultTaskDisplayArea().getRootHomeTask())
|
||||
|
||||
Reference in New Issue
Block a user