Loading services/core/java/com/android/server/wm/WallpaperController.java +18 −6 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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() */ Loading services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java +44 −38 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. Loading @@ -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(); Loading Loading @@ -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); Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; // Invisible requested activity should not share its rotation transform. r.mVisibleRequested = false; mDisplayContent.mWallpaperController.adjustWallpaperWindows(); assertFalse(wallpaperToken.hasFixedRotationTransform()); 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 = true; mDisplayContent.mWallpaperController.adjustWallpaperWindows(); assertEquals(appWin, mDisplayContent.mWallpaperController.getWallpaperTarget()); assertTrue(r.hasFixedRotationTransform()); assertTrue(wallpaperToken.hasFixedRotationTransform()); assertFalse(mAppWindow.mActivityRecord.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 Loading Loading @@ -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()) Loading Loading
services/core/java/com/android/server/wm/WallpaperController.java +18 −6 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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() */ Loading
services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java +44 −38 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. Loading @@ -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(); Loading Loading @@ -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); Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; // Invisible requested activity should not share its rotation transform. r.mVisibleRequested = false; mDisplayContent.mWallpaperController.adjustWallpaperWindows(); assertFalse(wallpaperToken.hasFixedRotationTransform()); 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 = true; mDisplayContent.mWallpaperController.adjustWallpaperWindows(); assertEquals(appWin, mDisplayContent.mWallpaperController.getWallpaperTarget()); assertTrue(r.hasFixedRotationTransform()); assertTrue(wallpaperToken.hasFixedRotationTransform()); assertFalse(mAppWindow.mActivityRecord.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 Loading Loading @@ -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()) Loading