Loading services/core/java/com/android/server/wallpaper/WallpaperManagerService.java +46 −18 Original line number Diff line number Diff line Loading @@ -118,6 +118,7 @@ import android.service.wallpaper.WallpaperService; import android.system.ErrnoException; import android.system.Os; import android.text.TextUtils; import android.util.ArraySet; import android.util.EventLog; import android.util.IntArray; import android.util.Slog; Loading Loading @@ -160,6 +161,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.function.Consumer; import java.util.function.Predicate; Loading Loading @@ -805,13 +807,39 @@ public class WallpaperManagerService extends IWallpaperManager.Stub final WallpaperDisplayHelper mWallpaperDisplayHelper; final WallpaperCropper mWallpaperCropper; private boolean supportsMultiDisplay(WallpaperConnection connection) { if (connection != null) { return connection.mInfo == null // This is image wallpaper || connection.mInfo.supportsMultipleDisplays(); } // TODO(b/384519749): Remove this set after we introduce the aspect ratio check. private final Set<Integer> mWallpaperCompatibleDisplaysForTest = new ArraySet<>(); private boolean isWallpaperCompatibleForDisplay(int displayId, WallpaperConnection connection) { if (connection == null) { return false; } // Non image wallpaper. if (connection.mInfo != null) { return connection.mInfo.supportsMultipleDisplays(); } // Image wallpaper if (enableConnectedDisplaysWallpaper()) { // TODO(b/384519749): check display's resolution and image wallpaper cropped image // aspect ratio. return displayId == DEFAULT_DISPLAY || mWallpaperCompatibleDisplaysForTest.contains(displayId); } // When enableConnectedDisplaysWallpaper is off, we assume the image wallpaper supports all // usable displays. return true; } @VisibleForTesting void addWallpaperCompatibleDisplayForTest(int displayId) { mWallpaperCompatibleDisplaysForTest.add(displayId); } @VisibleForTesting void removeWallpaperCompatibleDisplayForTest(int displayId) { mWallpaperCompatibleDisplaysForTest.remove(displayId); } private void updateFallbackConnection() { if (mLastWallpaper == null || mFallbackWallpaper == null) return; Loading @@ -821,7 +849,9 @@ public class WallpaperManagerService extends IWallpaperManager.Stub Slog.w(TAG, "Fallback wallpaper connection has not been created yet!!"); return; } if (supportsMultiDisplay(systemConnection)) { // TODO(b/384520326) Passing DEFAULT_DISPLAY temporarily before we revamp the // multi-display supports. if (isWallpaperCompatibleForDisplay(DEFAULT_DISPLAY, systemConnection)) { if (fallbackConnection.mDisplayConnector.size() != 0) { fallbackConnection.forEachDisplayConnector(connector -> { if (connector.mEngine != null) { Loading Loading @@ -996,16 +1026,14 @@ public class WallpaperManagerService extends IWallpaperManager.Stub private void initDisplayState() { // Do not initialize fallback wallpaper if (!mWallpaper.equals(mFallbackWallpaper)) { if (supportsMultiDisplay(this)) { // The system wallpaper is image wallpaper or it can supports multiple displays. appendConnectorWithCondition(display -> mWallpaperDisplayHelper.isUsableDisplay(display, mClientUid)); } else { // The system wallpaper does not support multiple displays, so just attach it on // default display. mDisplayConnector.append(DEFAULT_DISPLAY, new DisplayConnector(DEFAULT_DISPLAY)); appendConnectorWithCondition(display -> { final int displayId = display.getDisplayId(); if (display.getDisplayId() == DEFAULT_DISPLAY) { return true; } return mWallpaperDisplayHelper.isUsableDisplay(display, mClientUid) && isWallpaperCompatibleForDisplay(displayId, /* connection= */ this); }); } } Loading Loading @@ -3990,7 +4018,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub for (int i = 0; i < wallpapers.size(); i++) { WallpaperData wallpaper = wallpapers.get(i); if (supportsMultiDisplay(wallpaper.connection)) { if (isWallpaperCompatibleForDisplay(displayId, wallpaper.connection)) { final DisplayConnector connector = wallpaper.connection.getDisplayConnectorOrCreate(displayId); if (connector != null) { Loading @@ -4012,7 +4040,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } mFallbackWallpaper.mWhich = useFallbackWallpaperWhich; } else { if (supportsMultiDisplay(mLastWallpaper.connection)) { if (isWallpaperCompatibleForDisplay(displayId, mLastWallpaper.connection)) { final DisplayConnector connector = mLastWallpaper.connection.getDisplayConnectorOrCreate(displayId); if (connector == null) return; Loading services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java +77 −10 Original line number Diff line number Diff line Loading @@ -728,7 +728,7 @@ public class WallpaperManagerServiceTests { final int testDisplayId = 2; setUpDisplays(List.of(DEFAULT_DISPLAY, testDisplayId)); // WHEN displayId, 2, is ready. // WHEN display ID, 2, is ready. WallpaperManagerInternal wallpaperManagerInternal = LocalServices.getService( WallpaperManagerInternal.class); wallpaperManagerInternal.onDisplayReady(testDisplayId); Loading Loading @@ -768,7 +768,7 @@ public class WallpaperManagerServiceTests { final int testDisplayId = 2; setUpDisplays(List.of(DEFAULT_DISPLAY, testDisplayId)); // WHEN displayId, 2, is ready. // WHEN display ID, 2, is ready. WallpaperManagerInternal wallpaperManagerInternal = LocalServices.getService( WallpaperManagerInternal.class); wallpaperManagerInternal.onDisplayReady(testDisplayId); Loading Loading @@ -800,6 +800,40 @@ public class WallpaperManagerServiceTests { /* info= */ any(), /* description= */ any()); } @Test @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WALLPAPER) public void displayAdded_wallpaperIncompatibleForDisplay_shouldAttachFallbackWallpaperService() throws Exception { final int testUserId = USER_SYSTEM; mService.switchUser(testUserId, null); IWallpaperService mockIWallpaperService = mock(IWallpaperService.class); mService.mFallbackWallpaper.connection.mService = mockIWallpaperService; // GIVEN there are two displays: DEFAULT_DISPLAY, 2 final int testDisplayId = 2; setUpDisplays(List.of(DEFAULT_DISPLAY, testDisplayId)); // GIVEN the wallpaper isn't compatible with display ID, 2 mService.removeWallpaperCompatibleDisplayForTest(testDisplayId); // WHEN display ID, 2, is ready. WallpaperManagerInternal wallpaperManagerInternal = LocalServices.getService( WallpaperManagerInternal.class); wallpaperManagerInternal.onDisplayReady(testDisplayId); // Then there is a connection established for the fallback wallpaper for display ID, 2. verify(mockIWallpaperService).attach( /* connection= */ eq(mService.mFallbackWallpaper.connection), /* windowToken= */ any(), /* windowType= */ anyInt(), /* isPreview= */ anyBoolean(), /* reqWidth= */ anyInt(), /* reqHeight= */ anyInt(), /* padding= */ any(), /* displayId= */ eq(testDisplayId), /* which= */ eq(FLAG_SYSTEM | FLAG_LOCK), /* info= */ any(), /* description= */ any()); } // Verify a secondary display added end // Verify a secondary display removed started Loading Loading @@ -827,11 +861,11 @@ public class WallpaperManagerServiceTests { WallpaperManagerService.DisplayConnector displayConnector = wallpaper.connection.getDisplayConnectorOrCreate(testDisplayId); // WHEN displayId, 2, is removed. // WHEN display ID, 2, is removed. DisplayListener displayListener = displayListenerCaptor.getValue(); displayListener.onDisplayRemoved(testDisplayId); // Then the wallpaper connection for displayId, 2, is detached. // Then the wallpaper connection for display ID, 2, is detached. verify(mockIWallpaperService).detach(eq(displayConnector.mToken)); } Loading Loading @@ -861,21 +895,53 @@ public class WallpaperManagerServiceTests { WallpaperManagerInternal wallpaperManagerInternal = LocalServices.getService( WallpaperManagerInternal.class); wallpaperManagerInternal.onDisplayReady(testDisplayId); // Save displayConnectors for displayId 2 before display removal. // Save displayConnectors for display ID, 2, before display removal. WallpaperManagerService.DisplayConnector systemWallpaperDisplayConnector = systemWallpaper.connection.getDisplayConnectorOrCreate(testDisplayId); WallpaperManagerService.DisplayConnector lockWallpaperDisplayConnector = lockWallpaper.connection.getDisplayConnectorOrCreate(testDisplayId); // WHEN displayId, 2, is removed. // WHEN display ID, 2, is removed. DisplayListener displayListener = displayListenerCaptor.getValue(); displayListener.onDisplayRemoved(testDisplayId); // Then the system wallpaper connection for displayId, 2, is detached. // Then the system wallpaper connection for display ID, 2, is detached. verify(mockIWallpaperService).detach(eq(systemWallpaperDisplayConnector.mToken)); // Then the lock wallpaper connection for displayId, 2, is detached. // Then the lock wallpaper connection for display ID, 2, is detached. verify(mockIWallpaperService).detach(eq(lockWallpaperDisplayConnector.mToken)); } @Test @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WALLPAPER) public void displayRemoved_fallbackWallpaper_shouldDetachFallbackWallpaperService() throws Exception { ArgumentCaptor<DisplayListener> displayListenerCaptor = ArgumentCaptor.forClass( DisplayListener.class); verify(mDisplayManager).registerDisplayListener(displayListenerCaptor.capture(), eq(null)); final int testUserId = USER_SYSTEM; mService.switchUser(testUserId, null); IWallpaperService mockIWallpaperService = mock(IWallpaperService.class); mService.mFallbackWallpaper.connection.mService = mockIWallpaperService; // GIVEN there are two displays: DEFAULT_DISPLAY, 2 final int testDisplayId = 2; setUpDisplays(List.of(DEFAULT_DISPLAY, testDisplayId)); // GIVEN display ID, 2, is incompatible with the wallpaper. mService.removeWallpaperCompatibleDisplayForTest(testDisplayId); // GIVEN wallpaper connections have been established for display ID, 2. WallpaperManagerInternal wallpaperManagerInternal = LocalServices.getService( WallpaperManagerInternal.class); wallpaperManagerInternal.onDisplayReady(testDisplayId); // Save fallback wallpaper displayConnector for display ID, 2, before display removal. WallpaperManagerService.DisplayConnector fallbackWallpaperConnector = mService.mFallbackWallpaper.connection.getDisplayConnectorOrCreate(testDisplayId); // WHEN displayId, 2, is removed. DisplayListener displayListener = displayListenerCaptor.getValue(); displayListener.onDisplayRemoved(testDisplayId); // Then the fallback wallpaper connection for display ID, 2, is detached. verify(mockIWallpaperService).detach(eq(fallbackWallpaperConnector.mToken)); } // Verify a secondary display removed ended // Test fallback wallpaper after enabling connected display supports. Loading Loading @@ -971,6 +1037,7 @@ public class WallpaperManagerServiceTests { doReturn(mockDisplay).when(mDisplayManager).getDisplay(eq(displayId)); doReturn(displayId).when(mockDisplay).getDisplayId(); doReturn(true).when(mockDisplay).hasAccess(anyInt()); mService.addWallpaperCompatibleDisplayForTest(displayId); } doReturn(mockDisplays).when(mDisplayManager).getDisplays(); Loading Loading
services/core/java/com/android/server/wallpaper/WallpaperManagerService.java +46 −18 Original line number Diff line number Diff line Loading @@ -118,6 +118,7 @@ import android.service.wallpaper.WallpaperService; import android.system.ErrnoException; import android.system.Os; import android.text.TextUtils; import android.util.ArraySet; import android.util.EventLog; import android.util.IntArray; import android.util.Slog; Loading Loading @@ -160,6 +161,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.function.Consumer; import java.util.function.Predicate; Loading Loading @@ -805,13 +807,39 @@ public class WallpaperManagerService extends IWallpaperManager.Stub final WallpaperDisplayHelper mWallpaperDisplayHelper; final WallpaperCropper mWallpaperCropper; private boolean supportsMultiDisplay(WallpaperConnection connection) { if (connection != null) { return connection.mInfo == null // This is image wallpaper || connection.mInfo.supportsMultipleDisplays(); } // TODO(b/384519749): Remove this set after we introduce the aspect ratio check. private final Set<Integer> mWallpaperCompatibleDisplaysForTest = new ArraySet<>(); private boolean isWallpaperCompatibleForDisplay(int displayId, WallpaperConnection connection) { if (connection == null) { return false; } // Non image wallpaper. if (connection.mInfo != null) { return connection.mInfo.supportsMultipleDisplays(); } // Image wallpaper if (enableConnectedDisplaysWallpaper()) { // TODO(b/384519749): check display's resolution and image wallpaper cropped image // aspect ratio. return displayId == DEFAULT_DISPLAY || mWallpaperCompatibleDisplaysForTest.contains(displayId); } // When enableConnectedDisplaysWallpaper is off, we assume the image wallpaper supports all // usable displays. return true; } @VisibleForTesting void addWallpaperCompatibleDisplayForTest(int displayId) { mWallpaperCompatibleDisplaysForTest.add(displayId); } @VisibleForTesting void removeWallpaperCompatibleDisplayForTest(int displayId) { mWallpaperCompatibleDisplaysForTest.remove(displayId); } private void updateFallbackConnection() { if (mLastWallpaper == null || mFallbackWallpaper == null) return; Loading @@ -821,7 +849,9 @@ public class WallpaperManagerService extends IWallpaperManager.Stub Slog.w(TAG, "Fallback wallpaper connection has not been created yet!!"); return; } if (supportsMultiDisplay(systemConnection)) { // TODO(b/384520326) Passing DEFAULT_DISPLAY temporarily before we revamp the // multi-display supports. if (isWallpaperCompatibleForDisplay(DEFAULT_DISPLAY, systemConnection)) { if (fallbackConnection.mDisplayConnector.size() != 0) { fallbackConnection.forEachDisplayConnector(connector -> { if (connector.mEngine != null) { Loading Loading @@ -996,16 +1026,14 @@ public class WallpaperManagerService extends IWallpaperManager.Stub private void initDisplayState() { // Do not initialize fallback wallpaper if (!mWallpaper.equals(mFallbackWallpaper)) { if (supportsMultiDisplay(this)) { // The system wallpaper is image wallpaper or it can supports multiple displays. appendConnectorWithCondition(display -> mWallpaperDisplayHelper.isUsableDisplay(display, mClientUid)); } else { // The system wallpaper does not support multiple displays, so just attach it on // default display. mDisplayConnector.append(DEFAULT_DISPLAY, new DisplayConnector(DEFAULT_DISPLAY)); appendConnectorWithCondition(display -> { final int displayId = display.getDisplayId(); if (display.getDisplayId() == DEFAULT_DISPLAY) { return true; } return mWallpaperDisplayHelper.isUsableDisplay(display, mClientUid) && isWallpaperCompatibleForDisplay(displayId, /* connection= */ this); }); } } Loading Loading @@ -3990,7 +4018,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub for (int i = 0; i < wallpapers.size(); i++) { WallpaperData wallpaper = wallpapers.get(i); if (supportsMultiDisplay(wallpaper.connection)) { if (isWallpaperCompatibleForDisplay(displayId, wallpaper.connection)) { final DisplayConnector connector = wallpaper.connection.getDisplayConnectorOrCreate(displayId); if (connector != null) { Loading @@ -4012,7 +4040,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } mFallbackWallpaper.mWhich = useFallbackWallpaperWhich; } else { if (supportsMultiDisplay(mLastWallpaper.connection)) { if (isWallpaperCompatibleForDisplay(displayId, mLastWallpaper.connection)) { final DisplayConnector connector = mLastWallpaper.connection.getDisplayConnectorOrCreate(displayId); if (connector == null) return; Loading
services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java +77 −10 Original line number Diff line number Diff line Loading @@ -728,7 +728,7 @@ public class WallpaperManagerServiceTests { final int testDisplayId = 2; setUpDisplays(List.of(DEFAULT_DISPLAY, testDisplayId)); // WHEN displayId, 2, is ready. // WHEN display ID, 2, is ready. WallpaperManagerInternal wallpaperManagerInternal = LocalServices.getService( WallpaperManagerInternal.class); wallpaperManagerInternal.onDisplayReady(testDisplayId); Loading Loading @@ -768,7 +768,7 @@ public class WallpaperManagerServiceTests { final int testDisplayId = 2; setUpDisplays(List.of(DEFAULT_DISPLAY, testDisplayId)); // WHEN displayId, 2, is ready. // WHEN display ID, 2, is ready. WallpaperManagerInternal wallpaperManagerInternal = LocalServices.getService( WallpaperManagerInternal.class); wallpaperManagerInternal.onDisplayReady(testDisplayId); Loading Loading @@ -800,6 +800,40 @@ public class WallpaperManagerServiceTests { /* info= */ any(), /* description= */ any()); } @Test @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WALLPAPER) public void displayAdded_wallpaperIncompatibleForDisplay_shouldAttachFallbackWallpaperService() throws Exception { final int testUserId = USER_SYSTEM; mService.switchUser(testUserId, null); IWallpaperService mockIWallpaperService = mock(IWallpaperService.class); mService.mFallbackWallpaper.connection.mService = mockIWallpaperService; // GIVEN there are two displays: DEFAULT_DISPLAY, 2 final int testDisplayId = 2; setUpDisplays(List.of(DEFAULT_DISPLAY, testDisplayId)); // GIVEN the wallpaper isn't compatible with display ID, 2 mService.removeWallpaperCompatibleDisplayForTest(testDisplayId); // WHEN display ID, 2, is ready. WallpaperManagerInternal wallpaperManagerInternal = LocalServices.getService( WallpaperManagerInternal.class); wallpaperManagerInternal.onDisplayReady(testDisplayId); // Then there is a connection established for the fallback wallpaper for display ID, 2. verify(mockIWallpaperService).attach( /* connection= */ eq(mService.mFallbackWallpaper.connection), /* windowToken= */ any(), /* windowType= */ anyInt(), /* isPreview= */ anyBoolean(), /* reqWidth= */ anyInt(), /* reqHeight= */ anyInt(), /* padding= */ any(), /* displayId= */ eq(testDisplayId), /* which= */ eq(FLAG_SYSTEM | FLAG_LOCK), /* info= */ any(), /* description= */ any()); } // Verify a secondary display added end // Verify a secondary display removed started Loading Loading @@ -827,11 +861,11 @@ public class WallpaperManagerServiceTests { WallpaperManagerService.DisplayConnector displayConnector = wallpaper.connection.getDisplayConnectorOrCreate(testDisplayId); // WHEN displayId, 2, is removed. // WHEN display ID, 2, is removed. DisplayListener displayListener = displayListenerCaptor.getValue(); displayListener.onDisplayRemoved(testDisplayId); // Then the wallpaper connection for displayId, 2, is detached. // Then the wallpaper connection for display ID, 2, is detached. verify(mockIWallpaperService).detach(eq(displayConnector.mToken)); } Loading Loading @@ -861,21 +895,53 @@ public class WallpaperManagerServiceTests { WallpaperManagerInternal wallpaperManagerInternal = LocalServices.getService( WallpaperManagerInternal.class); wallpaperManagerInternal.onDisplayReady(testDisplayId); // Save displayConnectors for displayId 2 before display removal. // Save displayConnectors for display ID, 2, before display removal. WallpaperManagerService.DisplayConnector systemWallpaperDisplayConnector = systemWallpaper.connection.getDisplayConnectorOrCreate(testDisplayId); WallpaperManagerService.DisplayConnector lockWallpaperDisplayConnector = lockWallpaper.connection.getDisplayConnectorOrCreate(testDisplayId); // WHEN displayId, 2, is removed. // WHEN display ID, 2, is removed. DisplayListener displayListener = displayListenerCaptor.getValue(); displayListener.onDisplayRemoved(testDisplayId); // Then the system wallpaper connection for displayId, 2, is detached. // Then the system wallpaper connection for display ID, 2, is detached. verify(mockIWallpaperService).detach(eq(systemWallpaperDisplayConnector.mToken)); // Then the lock wallpaper connection for displayId, 2, is detached. // Then the lock wallpaper connection for display ID, 2, is detached. verify(mockIWallpaperService).detach(eq(lockWallpaperDisplayConnector.mToken)); } @Test @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WALLPAPER) public void displayRemoved_fallbackWallpaper_shouldDetachFallbackWallpaperService() throws Exception { ArgumentCaptor<DisplayListener> displayListenerCaptor = ArgumentCaptor.forClass( DisplayListener.class); verify(mDisplayManager).registerDisplayListener(displayListenerCaptor.capture(), eq(null)); final int testUserId = USER_SYSTEM; mService.switchUser(testUserId, null); IWallpaperService mockIWallpaperService = mock(IWallpaperService.class); mService.mFallbackWallpaper.connection.mService = mockIWallpaperService; // GIVEN there are two displays: DEFAULT_DISPLAY, 2 final int testDisplayId = 2; setUpDisplays(List.of(DEFAULT_DISPLAY, testDisplayId)); // GIVEN display ID, 2, is incompatible with the wallpaper. mService.removeWallpaperCompatibleDisplayForTest(testDisplayId); // GIVEN wallpaper connections have been established for display ID, 2. WallpaperManagerInternal wallpaperManagerInternal = LocalServices.getService( WallpaperManagerInternal.class); wallpaperManagerInternal.onDisplayReady(testDisplayId); // Save fallback wallpaper displayConnector for display ID, 2, before display removal. WallpaperManagerService.DisplayConnector fallbackWallpaperConnector = mService.mFallbackWallpaper.connection.getDisplayConnectorOrCreate(testDisplayId); // WHEN displayId, 2, is removed. DisplayListener displayListener = displayListenerCaptor.getValue(); displayListener.onDisplayRemoved(testDisplayId); // Then the fallback wallpaper connection for display ID, 2, is detached. verify(mockIWallpaperService).detach(eq(fallbackWallpaperConnector.mToken)); } // Verify a secondary display removed ended // Test fallback wallpaper after enabling connected display supports. Loading Loading @@ -971,6 +1037,7 @@ public class WallpaperManagerServiceTests { doReturn(mockDisplay).when(mDisplayManager).getDisplay(eq(displayId)); doReturn(displayId).when(mockDisplay).getDisplayId(); doReturn(true).when(mockDisplay).hasAccess(anyInt()); mService.addWallpaperCompatibleDisplayForTest(displayId); } doReturn(mockDisplays).when(mDisplayManager).getDisplays(); Loading