diff options
| author | 2025-02-06 18:03:14 -0800 | |
|---|---|---|
| committer | 2025-02-06 18:03:14 -0800 | |
| commit | bd53bc80d6d548ac656b207db551f93e8a58de6a (patch) | |
| tree | f5cd0e9d50cde29a28fdef094b0b5d0797da84f0 | |
| parent | b1d4e2ef49da6ae500a677570e7e6cd8db91ffaa (diff) | |
| parent | 679e30ab425b6b3509c66ff2e8bdef4d203590bd (diff) | |
Merge "Fix fallback wallpaper connections after reboot" into main
5 files changed, 126 insertions, 55 deletions
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java index ef63229f55e2..69b2b9b326ba 100644 --- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java +++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java @@ -777,7 +777,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub mWallpaperCompatibleDisplaysForTest.remove(displayId); } - private void updateFallbackConnection() { + private void updateFallbackConnection(int clientUid) { if (mLastWallpaper == null || mFallbackWallpaper == null) return; final WallpaperConnection systemConnection = mLastWallpaper.connection; final WallpaperConnection fallbackConnection = mFallbackWallpaper.connection; @@ -793,8 +793,12 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } if (isDeviceEligibleForDesktopExperienceWallpaper(mContext)) { - mWallpaperDisplayHelper.forEachDisplayData(displayData -> { - int displayId = displayData.mDisplayId; + Display[] displays = mWallpaperDisplayHelper.getDisplays(); + for (int i = displays.length - 1; i >= 0; i--) { + int displayId = displays[i].getDisplayId(); + if (!mWallpaperDisplayHelper.isUsableDisplay(displayId, clientUid)) { + continue; + } // 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. @@ -802,11 +806,13 @@ public class WallpaperManagerService extends IWallpaperManager.Stub && (lockConnection == null || lockConnection.containsDisplay(displayId))) { DisplayConnector fallbackConnector = mFallbackWallpaper.connection.mDisplayConnector.get(displayId); - if (fallbackConnector != null && fallbackConnector.mEngine != null) { - fallbackConnector.disconnectLocked(mFallbackWallpaper.connection); + if (fallbackConnector != null) { + if (fallbackConnector.mEngine != null) { + fallbackConnector.disconnectLocked(mFallbackWallpaper.connection); + } mFallbackWallpaper.connection.mDisplayConnector.remove(displayId); } - return; + continue; } // Identify if the fallback wallpaper should be use for lock or system or both. @@ -844,7 +850,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub mFallbackWallpaper); } } - }); + } } else if (isWallpaperCompatibleForDisplay(DEFAULT_DISPLAY, systemConnection)) { if (fallbackConnection.mDisplayConnector.size() != 0) { fallbackConnection.forEachDisplayConnector(connector -> { @@ -3787,7 +3793,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub wallpaper.connection = newConn; newConn.mReply = reply; updateCurrentWallpapers(wallpaper); - updateFallbackConnection(); + updateFallbackConnection(componentUid); } catch (RemoteException e) { String msg = "Remote exception for " + componentName + "\n" + e; if (fromUser) { diff --git a/services/tests/mockingservicestests/AndroidManifest.xml b/services/tests/mockingservicestests/AndroidManifest.xml index aa3930ac7c07..b509b0f9fd92 100644 --- a/services/tests/mockingservicestests/AndroidManifest.xml +++ b/services/tests/mockingservicestests/AndroidManifest.xml @@ -52,6 +52,16 @@ <uses-library android:name="android.test.runner" /> <activity android:name="android.service.games.GameSessionTrampolineActivityTest$TestActivity" /> + <service android:name="com.android.server.wallpaper.TestWallpaperService" + android:label="Test Wallpaper Service" + android:exported="true" + android:permission="android.permission.BIND_WALLPAPER"> + <intent-filter> + <action android:name="android.service.wallpaper.WallpaperService"/> + </intent-filter> + <meta-data android:name="android.service.wallpaper" + android:resource="@xml/test_wallpaper"/> + </service> </application> <instrumentation diff --git a/services/tests/mockingservicestests/res/xml/test_wallpaper.xml b/services/tests/mockingservicestests/res/xml/test_wallpaper.xml new file mode 100644 index 000000000000..4eed477337b5 --- /dev/null +++ b/services/tests/mockingservicestests/res/xml/test_wallpaper.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright 2025 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> +<wallpaper xmlns:android="http://schemas.android.com/apk/res/android" + android:label="Test Wallpaper" + android:supportsMultipleDisplays="true" /> diff --git a/services/tests/mockingservicestests/src/com/android/server/wallpaper/TestWallpaperService.java b/services/tests/mockingservicestests/src/com/android/server/wallpaper/TestWallpaperService.java new file mode 100644 index 000000000000..85ea5a0f2c2e --- /dev/null +++ b/services/tests/mockingservicestests/src/com/android/server/wallpaper/TestWallpaperService.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.wallpaper; + +import android.service.wallpaper.WallpaperService; + +public final class TestWallpaperService extends WallpaperService { + @Override + public Engine onCreateEngine() { + return new Engine(); + } +} diff --git a/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java b/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java index a5073599b29e..cd365396c74b 100644 --- a/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java +++ b/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java @@ -136,6 +136,10 @@ public class WallpaperManagerServiceTests { private static final String TAG = "WallpaperManagerServiceTests"; private static final int DISPLAY_SIZE_DIMENSION = 100; + + private static final ComponentName TEST_WALLPAPER_COMPONENT = ComponentName.createRelative( + "com.android.frameworks.mockingservicestests", + "com.android.server.wallpaper.TestWallpaperService"); private static StaticMockitoSession sMockitoSession; @ClassRule @@ -212,6 +216,7 @@ public class WallpaperManagerServiceTests { } sContext.addMockService(sImageWallpaperComponentName, sWallpaperService); + sContext.addMockService(TEST_WALLPAPER_COMPONENT, sWallpaperService); if (sFallbackWallpaperComponentName != null) { sContext.addMockService(sFallbackWallpaperComponentName, sWallpaperService); } @@ -1033,35 +1038,33 @@ 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. + // Test fallback connection is correctly established for multiple displays after reboot. + // GIVEN 3 displays, 0, 2, 3, the wallpaper is only compatible for display 0 and 3 but not 2. + // WHEN the device is booted. // 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); + public void deviceBooted_multiDisplays_shouldHaveExpectedConnections() { 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); + final int testUserId = USER_SYSTEM; + // After reboot, a switch user triggers the wallpapers initialization. + mService.switchUser(testUserId, null); 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.mLastWallpaper.connection.containsDisplay(incompatibleDisplayId)) + .isFalse(); + assertThat(mService.mFallbackWallpaper.connection.containsDisplay(DEFAULT_DISPLAY)) + .isFalse(); + assertThat(mService.mFallbackWallpaper.connection.containsDisplay(compatibleDisplayId)) + .isFalse(); assertThat(mService.mFallbackWallpaper.connection.containsDisplay(incompatibleDisplayId)) .isTrue(); assertThat(mService.mLastLockWallpaper).isNull(); @@ -1076,30 +1079,31 @@ public class WallpaperManagerServiceTests { @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(), + final int testUserId = USER_SYSTEM; + mService.switchUser(testUserId, null); + // Switch to a test wallpaper and then image wallpaper later to simulate a wallpaper change. + mService.setWallpaperComponent(TEST_WALLPAPER_COMPONENT, 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.mFallbackWallpaper.connection.containsDisplay(DEFAULT_DISPLAY)).isFalse(); + assertThat( + mService.mFallbackWallpaper.connection.containsDisplay(display2)).isFalse(); + assertThat( + mService.mFallbackWallpaper.connection.containsDisplay(display3)).isFalse(); assertThat(mService.mLastLockWallpaper).isNull(); } @@ -1112,28 +1116,27 @@ public class WallpaperManagerServiceTests { @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(), + final int testUserId = USER_SYSTEM; + mService.switchUser(testUserId, null); + // Switch to a test wallpaper and then image wallpaper later to simulate a wallpaper change. + mService.setWallpaperComponent(TEST_WALLPAPER_COMPONENT, 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.mLastWallpaper.connection.containsDisplay(display2)).isFalse(); + assertThat(mService.mLastWallpaper.connection.containsDisplay(display3)).isFalse(); + assertThat( + mService.mFallbackWallpaper.connection.containsDisplay(DEFAULT_DISPLAY)).isFalse(); assertThat(mService.mFallbackWallpaper.connection.containsDisplay(display2)).isTrue(); assertThat(mService.mFallbackWallpaper.connection.containsDisplay(display3)).isTrue(); assertThat(mService.mLastLockWallpaper).isNull(); @@ -1148,35 +1151,40 @@ public class WallpaperManagerServiceTests { @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)); + final int testUserId = USER_SYSTEM; + mService.switchUser(testUserId, null); + // Switch to a test wallpaper and then image wallpaper later to simulate a wallpaper change. + mService.setWallpaperComponent(TEST_WALLPAPER_COMPONENT, sContext.getOpPackageName(), + FLAG_SYSTEM | FLAG_LOCK, testUserId); 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); + verifyLastLockWallpaperData(testUserId, TEST_WALLPAPER_COMPONENT); 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.mLastWallpaper.connection.containsDisplay(incompatibleDisplayId)) + .isFalse(); + // mLastLockWallpaper is TEST_WALLPAPER_COMPONENT, which declares external displays support + // in the wallpaper metadata. assertThat(mService.mLastLockWallpaper.connection.containsDisplay(DEFAULT_DISPLAY)) .isTrue(); assertThat(mService.mLastLockWallpaper.connection.containsDisplay(compatibleDisplayId)) .isTrue(); - assertThat(mService.mFallbackWallpaper.connection.getConnectedEngineSize()).isEqualTo(1); + assertThat(mService.mLastLockWallpaper.connection.containsDisplay(incompatibleDisplayId)) + .isTrue(); + assertThat(mService.mFallbackWallpaper.connection.containsDisplay(DEFAULT_DISPLAY)) + .isFalse(); + assertThat(mService.mFallbackWallpaper.connection.containsDisplay(compatibleDisplayId)) + .isFalse(); assertThat(mService.mFallbackWallpaper.connection.containsDisplay(incompatibleDisplayId)) .isTrue(); } @@ -1281,4 +1289,6 @@ public class WallpaperManagerServiceTests { assertEquals(pfdContents, fileContents); } } + + } |