Loading services/core/java/com/android/server/wallpaper/WallpaperManagerService.java +98 −14 Original line number Diff line number Diff line Loading @@ -781,13 +781,71 @@ public class WallpaperManagerService extends IWallpaperManager.Stub if (mLastWallpaper == null || mFallbackWallpaper == null) return; final WallpaperConnection systemConnection = mLastWallpaper.connection; final WallpaperConnection fallbackConnection = mFallbackWallpaper.connection; final WallpaperConnection lockConnection; if (mLastLockWallpaper != null) { lockConnection = mLastLockWallpaper.connection; } else { lockConnection = null; } if (fallbackConnection == null) { Slog.w(TAG, "Fallback wallpaper connection has not been created yet!!"); return; } // TODO(b/384520326) Passing DEFAULT_DISPLAY temporarily before we revamp the // multi-display supports. if (isWallpaperCompatibleForDisplay(DEFAULT_DISPLAY, systemConnection)) { if (enableConnectedDisplaysWallpaper()) { mWallpaperDisplayHelper.forEachDisplayData(displayData -> { int displayId = displayData.mDisplayId; // If the display is already connected to the desired wallpaper(s), either the // same wallpaper for both lock and system, or different wallpapers for each, // any existing fallback wallpaper connection will be removed. if (systemConnection.containsDisplay(displayId) && (lockConnection == null || lockConnection.containsDisplay(displayId))) { DisplayConnector fallbackConnector = mFallbackWallpaper.connection.mDisplayConnector.get(displayId); if (fallbackConnector != null && fallbackConnector.mEngine != null) { fallbackConnector.disconnectLocked(mFallbackWallpaper.connection); mFallbackWallpaper.connection.mDisplayConnector.remove(displayId); } return; } // Identify if the fallback wallpaper should be use for lock or system or both. int which = 0; if (!systemConnection.containsDisplay(displayId)) { which |= FLAG_SYSTEM; } if (lockConnection == null || !lockConnection.containsDisplay(displayId)) { which |= FLAG_LOCK; } if (mFallbackWallpaper.connection.containsDisplay(displayId)) { // For existing fallback wallpaper connection, update the `which` flags. DisplayConnector fallbackConnector = mFallbackWallpaper.connection.mDisplayConnector.get(displayId); try { if (fallbackConnector != null && fallbackConnector.mEngine != null && fallbackConnector.mWhich != which) { fallbackConnector.mEngine.setWallpaperFlags(which); mWindowManagerInternal.setWallpaperShowWhenLocked( fallbackConnector.mToken, /* showWhenLocked= */ (which & FLAG_LOCK) != 0); fallbackConnector.mWhich = which; } } catch (RemoteException e) { Slog.e(TAG, "Failed to update fallback wallpaper engine flags", e); } } else { // For new fallback connection, establish the connection with the desired // `which` flag. DisplayConnector fallbackConnector = mFallbackWallpaper.connection.getDisplayConnectorOrCreate(displayId); if (fallbackConnector != null && fallbackConnector.mEngine != null) { fallbackConnector.mWhich = which; fallbackConnector.connectLocked(mFallbackWallpaper.connection, mFallbackWallpaper); } } }); } else if (isWallpaperCompatibleForDisplay(DEFAULT_DISPLAY, systemConnection)) { if (fallbackConnection.mDisplayConnector.size() != 0) { fallbackConnection.forEachDisplayConnector(connector -> { if (connector.mEngine != null) { Loading Loading @@ -820,8 +878,13 @@ public class WallpaperManagerService extends IWallpaperManager.Stub boolean mDimensionsChanged; boolean mPaddingChanged; DisplayConnector(int displayId) { // This field is added for the fallback wallpaper, which may have a different which flag for // a different display. int mWhich; DisplayConnector(int displayId, int which) { mDisplayId = displayId; mWhich = which; } void ensureStatusHandled() { Loading Loading @@ -850,13 +913,17 @@ public class WallpaperManagerService extends IWallpaperManager.Stub Slog.w(TAG, "WallpaperService is not connected yet"); return; } int which = wallpaper.mWhich; if (enableConnectedDisplaysWallpaper()) { which = mWhich; } TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG); t.traceBegin("WPMS.connectLocked-" + wallpaper.getComponent()); if (DEBUG) Slog.v(TAG, "Adding window token: " + mToken); mWindowManagerInternal.addWindowToken(mToken, TYPE_WALLPAPER, mDisplayId, null /* options */); mWindowManagerInternal.setWallpaperShowWhenLocked( mToken, (wallpaper.mWhich & FLAG_LOCK) != 0); mToken, (which & FLAG_LOCK) != 0); if (multiCrop() && mImageWallpaper.equals(wallpaper.getComponent())) { mWindowManagerInternal.setWallpaperCropHints(mToken, mWallpaperCropper.getRelativeCropHints(wallpaper)); Loading @@ -868,16 +935,15 @@ public class WallpaperManagerService extends IWallpaperManager.Stub try { if (liveWallpaperContentHandling()) { connection.mService.attach(connection, mToken, TYPE_WALLPAPER, false, wpdData.mWidth, wpdData.mHeight, wpdData.mPadding, mDisplayId, wallpaper.mWhich, connection.mInfo, wallpaper.getDescription()); wpdData.mWidth, wpdData.mHeight, wpdData.mPadding, mDisplayId, which, connection.mInfo, wallpaper.getDescription()); } else { WallpaperDescription desc = new WallpaperDescription.Builder().setComponent( (connection.mInfo != null) ? connection.mInfo.getComponent() : null).build(); connection.mService.attach(connection, mToken, TYPE_WALLPAPER, false, wpdData.mWidth, wpdData.mHeight, wpdData.mPadding, mDisplayId, wallpaper.mWhich, connection.mInfo, desc); wpdData.mWidth, wpdData.mHeight, wpdData.mPadding, mDisplayId, which, connection.mInfo, desc); } } catch (RemoteException e) { Slog.w(TAG, "Failed attaching wallpaper on display", e); Loading Loading @@ -980,7 +1046,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub final int displayId = display.getDisplayId(); final DisplayConnector connector = mDisplayConnector.get(displayId); if (connector == null) { mDisplayConnector.append(displayId, new DisplayConnector(displayId)); mDisplayConnector.append(displayId, new DisplayConnector(displayId, mWallpaper.mWhich)); } } } Loading @@ -1006,7 +1073,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub DisplayConnector connector = mDisplayConnector.get(displayId); if (connector == null) { if (mWallpaperDisplayHelper.isUsableDisplay(displayId, mClientUid)) { connector = new DisplayConnector(displayId); connector = new DisplayConnector(displayId, mWallpaper.mWhich); mDisplayConnector.append(displayId, connector); } } Loading Loading @@ -1364,6 +1431,17 @@ public class WallpaperManagerService extends IWallpaperManager.Stub Slog.v(TAG, "static system+lock to system failure"); } WallpaperData currentSystem = mWallpaperMap.get(mNewWallpaper.userId); // In the constructor, we copied the system+lock wallpaper to // mOriginalSystem. However, the copied WallpaperData#connection is a // reference, not a deep copy. This means // currentSystem.connection.mWallpaper points to mOriginalSystem, so // changes to currentSystem.mWhich alone won't update the corresponding // flag in currentSystem.connection.mWallpaper.mWhich. Let's point // currentSystem.connection.mWallpaper back to currentSystem. if (enableConnectedDisplaysWallpaper() && currentSystem.connection != null) { currentSystem.connection.mWallpaper = currentSystem; } currentSystem.mWhich = FLAG_SYSTEM | FLAG_LOCK; updateEngineFlags(currentSystem); mLockWallpaperMap.remove(mNewWallpaper.userId); Loading @@ -1385,6 +1463,11 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } WallpaperData currentSystem = mWallpaperMap.get(mNewWallpaper.userId); if (currentSystem.wallpaperId == mOriginalSystem.wallpaperId) { // Fixing the reference, see above for more details. if (enableConnectedDisplaysWallpaper() && currentSystem.connection != null) { currentSystem.connection.mWallpaper = currentSystem; } currentSystem.mWhich = FLAG_SYSTEM; updateEngineFlags(currentSystem); } Loading Loading @@ -3814,6 +3897,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub wallpaper.connection.forEachDisplayConnector( connector -> { try { connector.mWhich = wallpaper.mWhich; if (connector.mEngine != null) { connector.mEngine.setWallpaperFlags(wallpaper.mWhich); mWindowManagerInternal.setWallpaperShowWhenLocked( Loading Loading @@ -3949,8 +4033,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub if (mLastWallpaper == null) { return; } if (enableConnectedDisplaysWallpaper()) { int useFallbackWallpaperWhich = 0; if (enableConnectedDisplaysWallpaper()) { List<WallpaperData> wallpapers = new ArrayList<>(); wallpapers.add(mLastWallpaper); // If the system and the lock wallpapers are not the same, we should also Loading Loading @@ -3981,7 +4065,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub || mFallbackWallpaper.connection == null) { return; } mFallbackWallpaper.mWhich = useFallbackWallpaperWhich; } else { if (isWallpaperCompatibleForDisplay(displayId, mLastWallpaper.connection)) { final DisplayConnector connector = Loading @@ -3999,6 +4082,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub final DisplayConnector connector = mFallbackWallpaper .connection.getDisplayConnectorOrCreate(displayId); if (connector == null) return; connector.mWhich = useFallbackWallpaperWhich; connector.connectLocked(mFallbackWallpaper.connection, mFallbackWallpaper); } else { Slog.w(TAG, "No wallpaper can be added to the new display"); Loading services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java +148 −0 Original line number Diff line number Diff line Loading @@ -1028,6 +1028,154 @@ public class WallpaperManagerServiceTests { } // Verify a secondary display removes system decorations ended // Test setWallpaperComponent on multiple displays. // GIVEN 3 displays, 0, 2, 3, the new wallpaper is only compatible for display 0 and 3 but not // 2. // WHEN the new wallpaper is set for system and lock via setWallpaperComponent. // THEN there are 2 connections in mLastWallpaper and 1 connection in mFallbackWallpaper. @Test @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WALLPAPER) public void setWallpaperComponent_multiDisplays_shouldHaveExpectedConnections() { // Skip if there is no pre-defined default wallpaper component. assumeThat(sDefaultWallpaperComponent, not(CoreMatchers.equalTo(sImageWallpaperComponentName))); final int testUserId = USER_SYSTEM; mService.switchUser(testUserId, null); final int incompatibleDisplayId = 2; final int compatibleDisplayId = 3; setUpDisplays(List.of(DEFAULT_DISPLAY, incompatibleDisplayId, compatibleDisplayId)); mService.removeWallpaperCompatibleDisplayForTest(incompatibleDisplayId); mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(), FLAG_SYSTEM | FLAG_LOCK, testUserId); verifyLastWallpaperData(testUserId, sImageWallpaperComponentName); verifyCurrentSystemData(testUserId); assertThat(mService.mLastWallpaper.connection.getConnectedEngineSize()).isEqualTo(2); assertThat(mService.mLastWallpaper.connection.containsDisplay(DEFAULT_DISPLAY)).isTrue(); assertThat(mService.mLastWallpaper.connection.containsDisplay(compatibleDisplayId)) .isTrue(); assertThat(mService.mFallbackWallpaper.connection.getConnectedEngineSize()).isEqualTo(1); assertThat(mService.mFallbackWallpaper.connection.containsDisplay(incompatibleDisplayId)) .isTrue(); assertThat(mService.mLastLockWallpaper).isNull(); } // Test setWallpaperComponent on multiple displays. // GIVEN 3 displays, 0, 2, 3, the existing wallpaper is only compatible for display 0 and 3 but // not 2. // GIVEN the new wallpaper is compatible to 2. // WHEN the new wallpaper is set for system and lock via setWallpaperComponent. // THEN there are 3 connections in mLastWallpaper and 0 connection in mFallbackWallpaper. @Test @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WALLPAPER) public void setWallpaperComponent_multiDisplays_displayBecomeCompatible_shouldHaveExpectedConnections() { // Skip if there is no pre-defined default wallpaper component. assumeThat(sDefaultWallpaperComponent, not(CoreMatchers.equalTo(sImageWallpaperComponentName))); final int testUserId = USER_SYSTEM; mService.switchUser(testUserId, null); final int display2 = 2; final int display3 = 3; setUpDisplays(List.of(DEFAULT_DISPLAY, display2, display3)); mService.removeWallpaperCompatibleDisplayForTest(display2); mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(), FLAG_SYSTEM | FLAG_LOCK, testUserId); mService.addWallpaperCompatibleDisplayForTest(display2); mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(), FLAG_SYSTEM | FLAG_LOCK, testUserId); verifyLastWallpaperData(testUserId, sImageWallpaperComponentName); verifyCurrentSystemData(testUserId); assertThat(mService.mLastWallpaper.connection.getConnectedEngineSize()).isEqualTo(3); assertThat(mService.mLastWallpaper.connection.containsDisplay(DEFAULT_DISPLAY)).isTrue(); assertThat(mService.mLastWallpaper.connection.containsDisplay(display2)).isTrue(); assertThat(mService.mLastWallpaper.connection.containsDisplay(display3)).isTrue(); assertThat(mService.mFallbackWallpaper.connection.getConnectedEngineSize()).isEqualTo(0); assertThat(mService.mLastLockWallpaper).isNull(); } // Test setWallpaperComponent on multiple displays. // GIVEN 3 displays, 0, 2, 3, the existing wallpaper is only compatible for display 0 and 3 but // not 2. // GIVEN the new wallpaper is incompatible to 2 and 3. // WHEN the new wallpaper is set for system and lock via setWallpaperComponent. // THEN there are 1 connections in mLastWallpaper and 2 connection in mFallbackWallpaper. @Test @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WALLPAPER) public void setWallpaperComponent_multiDisplays_displayBecomeIncompatible_shouldHaveExpectedConnections() { // Skip if there is no pre-defined default wallpaper component. assumeThat(sDefaultWallpaperComponent, not(CoreMatchers.equalTo(sImageWallpaperComponentName))); final int testUserId = USER_SYSTEM; mService.switchUser(testUserId, null); final int display2 = 2; final int display3 = 3; setUpDisplays(List.of(DEFAULT_DISPLAY, display2, display3)); mService.removeWallpaperCompatibleDisplayForTest(display2); mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(), FLAG_SYSTEM | FLAG_LOCK, testUserId); mService.removeWallpaperCompatibleDisplayForTest(display3); mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(), FLAG_SYSTEM | FLAG_LOCK, testUserId); verifyLastWallpaperData(testUserId, sImageWallpaperComponentName); verifyCurrentSystemData(testUserId); assertThat(mService.mLastWallpaper.connection.getConnectedEngineSize()).isEqualTo(1); assertThat(mService.mLastWallpaper.connection.containsDisplay(DEFAULT_DISPLAY)).isTrue(); assertThat(mService.mFallbackWallpaper.connection.getConnectedEngineSize()).isEqualTo(2); assertThat(mService.mFallbackWallpaper.connection.containsDisplay(display2)).isTrue(); assertThat(mService.mFallbackWallpaper.connection.containsDisplay(display3)).isTrue(); assertThat(mService.mLastLockWallpaper).isNull(); } // Test setWallpaperComponent on multiple displays. // GIVEN 3 displays, 0, 2, 3, the new wallpaper is only compatible for display 0 and 3 but not // 2. // WHEN two different wallpapers set for system and lock via setWallpaperComponent. // THEN there are two connections in mLastWallpaper, two connection in mLastLockWallpaper and // one connection in mFallbackWallpaper. @Test @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WALLPAPER) public void setWallpaperComponent_systemAndLockWallpapers_multiDisplays_shouldHaveExpectedConnections() { // Skip if there is no pre-defined default wallpaper component. assumeThat(sDefaultWallpaperComponent, not(CoreMatchers.equalTo(sImageWallpaperComponentName))); final int testUserId = USER_SYSTEM; mService.switchUser(testUserId, null); final int incompatibleDisplayId = 2; final int compatibleDisplayId = 3; setUpDisplays(List.of(DEFAULT_DISPLAY, incompatibleDisplayId, compatibleDisplayId)); mService.removeWallpaperCompatibleDisplayForTest(incompatibleDisplayId); mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(), FLAG_SYSTEM, testUserId); mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(), FLAG_LOCK, testUserId); verifyLastWallpaperData(testUserId, sImageWallpaperComponentName); verifyLastLockWallpaperData(testUserId, sImageWallpaperComponentName); verifyCurrentSystemData(testUserId); assertThat(mService.mLastWallpaper.connection.getConnectedEngineSize()).isEqualTo(2); assertThat(mService.mLastWallpaper.connection.containsDisplay(DEFAULT_DISPLAY)).isTrue(); assertThat(mService.mLastWallpaper.connection.containsDisplay(compatibleDisplayId)) .isTrue(); assertThat(mService.mLastLockWallpaper.connection.getConnectedEngineSize()).isEqualTo(2); assertThat(mService.mLastLockWallpaper.connection.containsDisplay(DEFAULT_DISPLAY)) .isTrue(); assertThat(mService.mLastLockWallpaper.connection.containsDisplay(compatibleDisplayId)) .isTrue(); assertThat(mService.mFallbackWallpaper.connection.getConnectedEngineSize()).isEqualTo(1); assertThat(mService.mFallbackWallpaper.connection.containsDisplay(incompatibleDisplayId)) .isTrue(); } // Verify that after continue switch user from userId 0 to lastUserId, the wallpaper data for // non-current user must not bind to wallpaper service. private void verifyNoConnectionBeforeLastUser(int lastUserId) { Loading Loading
services/core/java/com/android/server/wallpaper/WallpaperManagerService.java +98 −14 Original line number Diff line number Diff line Loading @@ -781,13 +781,71 @@ public class WallpaperManagerService extends IWallpaperManager.Stub if (mLastWallpaper == null || mFallbackWallpaper == null) return; final WallpaperConnection systemConnection = mLastWallpaper.connection; final WallpaperConnection fallbackConnection = mFallbackWallpaper.connection; final WallpaperConnection lockConnection; if (mLastLockWallpaper != null) { lockConnection = mLastLockWallpaper.connection; } else { lockConnection = null; } if (fallbackConnection == null) { Slog.w(TAG, "Fallback wallpaper connection has not been created yet!!"); return; } // TODO(b/384520326) Passing DEFAULT_DISPLAY temporarily before we revamp the // multi-display supports. if (isWallpaperCompatibleForDisplay(DEFAULT_DISPLAY, systemConnection)) { if (enableConnectedDisplaysWallpaper()) { mWallpaperDisplayHelper.forEachDisplayData(displayData -> { int displayId = displayData.mDisplayId; // If the display is already connected to the desired wallpaper(s), either the // same wallpaper for both lock and system, or different wallpapers for each, // any existing fallback wallpaper connection will be removed. if (systemConnection.containsDisplay(displayId) && (lockConnection == null || lockConnection.containsDisplay(displayId))) { DisplayConnector fallbackConnector = mFallbackWallpaper.connection.mDisplayConnector.get(displayId); if (fallbackConnector != null && fallbackConnector.mEngine != null) { fallbackConnector.disconnectLocked(mFallbackWallpaper.connection); mFallbackWallpaper.connection.mDisplayConnector.remove(displayId); } return; } // Identify if the fallback wallpaper should be use for lock or system or both. int which = 0; if (!systemConnection.containsDisplay(displayId)) { which |= FLAG_SYSTEM; } if (lockConnection == null || !lockConnection.containsDisplay(displayId)) { which |= FLAG_LOCK; } if (mFallbackWallpaper.connection.containsDisplay(displayId)) { // For existing fallback wallpaper connection, update the `which` flags. DisplayConnector fallbackConnector = mFallbackWallpaper.connection.mDisplayConnector.get(displayId); try { if (fallbackConnector != null && fallbackConnector.mEngine != null && fallbackConnector.mWhich != which) { fallbackConnector.mEngine.setWallpaperFlags(which); mWindowManagerInternal.setWallpaperShowWhenLocked( fallbackConnector.mToken, /* showWhenLocked= */ (which & FLAG_LOCK) != 0); fallbackConnector.mWhich = which; } } catch (RemoteException e) { Slog.e(TAG, "Failed to update fallback wallpaper engine flags", e); } } else { // For new fallback connection, establish the connection with the desired // `which` flag. DisplayConnector fallbackConnector = mFallbackWallpaper.connection.getDisplayConnectorOrCreate(displayId); if (fallbackConnector != null && fallbackConnector.mEngine != null) { fallbackConnector.mWhich = which; fallbackConnector.connectLocked(mFallbackWallpaper.connection, mFallbackWallpaper); } } }); } else if (isWallpaperCompatibleForDisplay(DEFAULT_DISPLAY, systemConnection)) { if (fallbackConnection.mDisplayConnector.size() != 0) { fallbackConnection.forEachDisplayConnector(connector -> { if (connector.mEngine != null) { Loading Loading @@ -820,8 +878,13 @@ public class WallpaperManagerService extends IWallpaperManager.Stub boolean mDimensionsChanged; boolean mPaddingChanged; DisplayConnector(int displayId) { // This field is added for the fallback wallpaper, which may have a different which flag for // a different display. int mWhich; DisplayConnector(int displayId, int which) { mDisplayId = displayId; mWhich = which; } void ensureStatusHandled() { Loading Loading @@ -850,13 +913,17 @@ public class WallpaperManagerService extends IWallpaperManager.Stub Slog.w(TAG, "WallpaperService is not connected yet"); return; } int which = wallpaper.mWhich; if (enableConnectedDisplaysWallpaper()) { which = mWhich; } TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG); t.traceBegin("WPMS.connectLocked-" + wallpaper.getComponent()); if (DEBUG) Slog.v(TAG, "Adding window token: " + mToken); mWindowManagerInternal.addWindowToken(mToken, TYPE_WALLPAPER, mDisplayId, null /* options */); mWindowManagerInternal.setWallpaperShowWhenLocked( mToken, (wallpaper.mWhich & FLAG_LOCK) != 0); mToken, (which & FLAG_LOCK) != 0); if (multiCrop() && mImageWallpaper.equals(wallpaper.getComponent())) { mWindowManagerInternal.setWallpaperCropHints(mToken, mWallpaperCropper.getRelativeCropHints(wallpaper)); Loading @@ -868,16 +935,15 @@ public class WallpaperManagerService extends IWallpaperManager.Stub try { if (liveWallpaperContentHandling()) { connection.mService.attach(connection, mToken, TYPE_WALLPAPER, false, wpdData.mWidth, wpdData.mHeight, wpdData.mPadding, mDisplayId, wallpaper.mWhich, connection.mInfo, wallpaper.getDescription()); wpdData.mWidth, wpdData.mHeight, wpdData.mPadding, mDisplayId, which, connection.mInfo, wallpaper.getDescription()); } else { WallpaperDescription desc = new WallpaperDescription.Builder().setComponent( (connection.mInfo != null) ? connection.mInfo.getComponent() : null).build(); connection.mService.attach(connection, mToken, TYPE_WALLPAPER, false, wpdData.mWidth, wpdData.mHeight, wpdData.mPadding, mDisplayId, wallpaper.mWhich, connection.mInfo, desc); wpdData.mWidth, wpdData.mHeight, wpdData.mPadding, mDisplayId, which, connection.mInfo, desc); } } catch (RemoteException e) { Slog.w(TAG, "Failed attaching wallpaper on display", e); Loading Loading @@ -980,7 +1046,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub final int displayId = display.getDisplayId(); final DisplayConnector connector = mDisplayConnector.get(displayId); if (connector == null) { mDisplayConnector.append(displayId, new DisplayConnector(displayId)); mDisplayConnector.append(displayId, new DisplayConnector(displayId, mWallpaper.mWhich)); } } } Loading @@ -1006,7 +1073,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub DisplayConnector connector = mDisplayConnector.get(displayId); if (connector == null) { if (mWallpaperDisplayHelper.isUsableDisplay(displayId, mClientUid)) { connector = new DisplayConnector(displayId); connector = new DisplayConnector(displayId, mWallpaper.mWhich); mDisplayConnector.append(displayId, connector); } } Loading Loading @@ -1364,6 +1431,17 @@ public class WallpaperManagerService extends IWallpaperManager.Stub Slog.v(TAG, "static system+lock to system failure"); } WallpaperData currentSystem = mWallpaperMap.get(mNewWallpaper.userId); // In the constructor, we copied the system+lock wallpaper to // mOriginalSystem. However, the copied WallpaperData#connection is a // reference, not a deep copy. This means // currentSystem.connection.mWallpaper points to mOriginalSystem, so // changes to currentSystem.mWhich alone won't update the corresponding // flag in currentSystem.connection.mWallpaper.mWhich. Let's point // currentSystem.connection.mWallpaper back to currentSystem. if (enableConnectedDisplaysWallpaper() && currentSystem.connection != null) { currentSystem.connection.mWallpaper = currentSystem; } currentSystem.mWhich = FLAG_SYSTEM | FLAG_LOCK; updateEngineFlags(currentSystem); mLockWallpaperMap.remove(mNewWallpaper.userId); Loading @@ -1385,6 +1463,11 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } WallpaperData currentSystem = mWallpaperMap.get(mNewWallpaper.userId); if (currentSystem.wallpaperId == mOriginalSystem.wallpaperId) { // Fixing the reference, see above for more details. if (enableConnectedDisplaysWallpaper() && currentSystem.connection != null) { currentSystem.connection.mWallpaper = currentSystem; } currentSystem.mWhich = FLAG_SYSTEM; updateEngineFlags(currentSystem); } Loading Loading @@ -3814,6 +3897,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub wallpaper.connection.forEachDisplayConnector( connector -> { try { connector.mWhich = wallpaper.mWhich; if (connector.mEngine != null) { connector.mEngine.setWallpaperFlags(wallpaper.mWhich); mWindowManagerInternal.setWallpaperShowWhenLocked( Loading Loading @@ -3949,8 +4033,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub if (mLastWallpaper == null) { return; } if (enableConnectedDisplaysWallpaper()) { int useFallbackWallpaperWhich = 0; if (enableConnectedDisplaysWallpaper()) { List<WallpaperData> wallpapers = new ArrayList<>(); wallpapers.add(mLastWallpaper); // If the system and the lock wallpapers are not the same, we should also Loading Loading @@ -3981,7 +4065,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub || mFallbackWallpaper.connection == null) { return; } mFallbackWallpaper.mWhich = useFallbackWallpaperWhich; } else { if (isWallpaperCompatibleForDisplay(displayId, mLastWallpaper.connection)) { final DisplayConnector connector = Loading @@ -3999,6 +4082,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub final DisplayConnector connector = mFallbackWallpaper .connection.getDisplayConnectorOrCreate(displayId); if (connector == null) return; connector.mWhich = useFallbackWallpaperWhich; connector.connectLocked(mFallbackWallpaper.connection, mFallbackWallpaper); } else { Slog.w(TAG, "No wallpaper can be added to the new display"); Loading
services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java +148 −0 Original line number Diff line number Diff line Loading @@ -1028,6 +1028,154 @@ public class WallpaperManagerServiceTests { } // Verify a secondary display removes system decorations ended // Test setWallpaperComponent on multiple displays. // GIVEN 3 displays, 0, 2, 3, the new wallpaper is only compatible for display 0 and 3 but not // 2. // WHEN the new wallpaper is set for system and lock via setWallpaperComponent. // THEN there are 2 connections in mLastWallpaper and 1 connection in mFallbackWallpaper. @Test @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WALLPAPER) public void setWallpaperComponent_multiDisplays_shouldHaveExpectedConnections() { // Skip if there is no pre-defined default wallpaper component. assumeThat(sDefaultWallpaperComponent, not(CoreMatchers.equalTo(sImageWallpaperComponentName))); final int testUserId = USER_SYSTEM; mService.switchUser(testUserId, null); final int incompatibleDisplayId = 2; final int compatibleDisplayId = 3; setUpDisplays(List.of(DEFAULT_DISPLAY, incompatibleDisplayId, compatibleDisplayId)); mService.removeWallpaperCompatibleDisplayForTest(incompatibleDisplayId); mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(), FLAG_SYSTEM | FLAG_LOCK, testUserId); verifyLastWallpaperData(testUserId, sImageWallpaperComponentName); verifyCurrentSystemData(testUserId); assertThat(mService.mLastWallpaper.connection.getConnectedEngineSize()).isEqualTo(2); assertThat(mService.mLastWallpaper.connection.containsDisplay(DEFAULT_DISPLAY)).isTrue(); assertThat(mService.mLastWallpaper.connection.containsDisplay(compatibleDisplayId)) .isTrue(); assertThat(mService.mFallbackWallpaper.connection.getConnectedEngineSize()).isEqualTo(1); assertThat(mService.mFallbackWallpaper.connection.containsDisplay(incompatibleDisplayId)) .isTrue(); assertThat(mService.mLastLockWallpaper).isNull(); } // Test setWallpaperComponent on multiple displays. // GIVEN 3 displays, 0, 2, 3, the existing wallpaper is only compatible for display 0 and 3 but // not 2. // GIVEN the new wallpaper is compatible to 2. // WHEN the new wallpaper is set for system and lock via setWallpaperComponent. // THEN there are 3 connections in mLastWallpaper and 0 connection in mFallbackWallpaper. @Test @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WALLPAPER) public void setWallpaperComponent_multiDisplays_displayBecomeCompatible_shouldHaveExpectedConnections() { // Skip if there is no pre-defined default wallpaper component. assumeThat(sDefaultWallpaperComponent, not(CoreMatchers.equalTo(sImageWallpaperComponentName))); final int testUserId = USER_SYSTEM; mService.switchUser(testUserId, null); final int display2 = 2; final int display3 = 3; setUpDisplays(List.of(DEFAULT_DISPLAY, display2, display3)); mService.removeWallpaperCompatibleDisplayForTest(display2); mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(), FLAG_SYSTEM | FLAG_LOCK, testUserId); mService.addWallpaperCompatibleDisplayForTest(display2); mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(), FLAG_SYSTEM | FLAG_LOCK, testUserId); verifyLastWallpaperData(testUserId, sImageWallpaperComponentName); verifyCurrentSystemData(testUserId); assertThat(mService.mLastWallpaper.connection.getConnectedEngineSize()).isEqualTo(3); assertThat(mService.mLastWallpaper.connection.containsDisplay(DEFAULT_DISPLAY)).isTrue(); assertThat(mService.mLastWallpaper.connection.containsDisplay(display2)).isTrue(); assertThat(mService.mLastWallpaper.connection.containsDisplay(display3)).isTrue(); assertThat(mService.mFallbackWallpaper.connection.getConnectedEngineSize()).isEqualTo(0); assertThat(mService.mLastLockWallpaper).isNull(); } // Test setWallpaperComponent on multiple displays. // GIVEN 3 displays, 0, 2, 3, the existing wallpaper is only compatible for display 0 and 3 but // not 2. // GIVEN the new wallpaper is incompatible to 2 and 3. // WHEN the new wallpaper is set for system and lock via setWallpaperComponent. // THEN there are 1 connections in mLastWallpaper and 2 connection in mFallbackWallpaper. @Test @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WALLPAPER) public void setWallpaperComponent_multiDisplays_displayBecomeIncompatible_shouldHaveExpectedConnections() { // Skip if there is no pre-defined default wallpaper component. assumeThat(sDefaultWallpaperComponent, not(CoreMatchers.equalTo(sImageWallpaperComponentName))); final int testUserId = USER_SYSTEM; mService.switchUser(testUserId, null); final int display2 = 2; final int display3 = 3; setUpDisplays(List.of(DEFAULT_DISPLAY, display2, display3)); mService.removeWallpaperCompatibleDisplayForTest(display2); mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(), FLAG_SYSTEM | FLAG_LOCK, testUserId); mService.removeWallpaperCompatibleDisplayForTest(display3); mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(), FLAG_SYSTEM | FLAG_LOCK, testUserId); verifyLastWallpaperData(testUserId, sImageWallpaperComponentName); verifyCurrentSystemData(testUserId); assertThat(mService.mLastWallpaper.connection.getConnectedEngineSize()).isEqualTo(1); assertThat(mService.mLastWallpaper.connection.containsDisplay(DEFAULT_DISPLAY)).isTrue(); assertThat(mService.mFallbackWallpaper.connection.getConnectedEngineSize()).isEqualTo(2); assertThat(mService.mFallbackWallpaper.connection.containsDisplay(display2)).isTrue(); assertThat(mService.mFallbackWallpaper.connection.containsDisplay(display3)).isTrue(); assertThat(mService.mLastLockWallpaper).isNull(); } // Test setWallpaperComponent on multiple displays. // GIVEN 3 displays, 0, 2, 3, the new wallpaper is only compatible for display 0 and 3 but not // 2. // WHEN two different wallpapers set for system and lock via setWallpaperComponent. // THEN there are two connections in mLastWallpaper, two connection in mLastLockWallpaper and // one connection in mFallbackWallpaper. @Test @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WALLPAPER) public void setWallpaperComponent_systemAndLockWallpapers_multiDisplays_shouldHaveExpectedConnections() { // Skip if there is no pre-defined default wallpaper component. assumeThat(sDefaultWallpaperComponent, not(CoreMatchers.equalTo(sImageWallpaperComponentName))); final int testUserId = USER_SYSTEM; mService.switchUser(testUserId, null); final int incompatibleDisplayId = 2; final int compatibleDisplayId = 3; setUpDisplays(List.of(DEFAULT_DISPLAY, incompatibleDisplayId, compatibleDisplayId)); mService.removeWallpaperCompatibleDisplayForTest(incompatibleDisplayId); mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(), FLAG_SYSTEM, testUserId); mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(), FLAG_LOCK, testUserId); verifyLastWallpaperData(testUserId, sImageWallpaperComponentName); verifyLastLockWallpaperData(testUserId, sImageWallpaperComponentName); verifyCurrentSystemData(testUserId); assertThat(mService.mLastWallpaper.connection.getConnectedEngineSize()).isEqualTo(2); assertThat(mService.mLastWallpaper.connection.containsDisplay(DEFAULT_DISPLAY)).isTrue(); assertThat(mService.mLastWallpaper.connection.containsDisplay(compatibleDisplayId)) .isTrue(); assertThat(mService.mLastLockWallpaper.connection.getConnectedEngineSize()).isEqualTo(2); assertThat(mService.mLastLockWallpaper.connection.containsDisplay(DEFAULT_DISPLAY)) .isTrue(); assertThat(mService.mLastLockWallpaper.connection.containsDisplay(compatibleDisplayId)) .isTrue(); assertThat(mService.mFallbackWallpaper.connection.getConnectedEngineSize()).isEqualTo(1); assertThat(mService.mFallbackWallpaper.connection.containsDisplay(incompatibleDisplayId)) .isTrue(); } // Verify that after continue switch user from userId 0 to lastUserId, the wallpaper data for // non-current user must not bind to wallpaper service. private void verifyNoConnectionBeforeLastUser(int lastUserId) { Loading