Loading services/core/java/com/android/server/wm/WindowManagerService.java +31 −17 Original line number Diff line number Diff line Loading @@ -331,6 +331,7 @@ import android.window.WindowContextInfo; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting.Visibility; import com.android.internal.os.IResultReceiver; import com.android.internal.os.TransferPipe; import com.android.internal.policy.IKeyguardDismissCallback; Loading Loading @@ -600,6 +601,7 @@ public class WindowManagerService extends IWindowManager.Stub final boolean mLimitedAlphaCompositing; final int mMaxUiWidth; @NonNull @VisibleForTesting WindowManagerPolicy mPolicy; Loading Loading @@ -1054,13 +1056,16 @@ public class WindowManagerService extends IWindowManager.Stub private boolean mAnimationsDisabled = false; boolean mPointerLocationEnabled = false; @NonNull final AppCompatConfiguration mAppCompatConfiguration; private boolean mIsIgnoreOrientationRequestDisabled; @NonNull final InputManagerService mInputManager; final DisplayManagerInternal mDisplayManagerInternal; final DisplayManager mDisplayManager; @NonNull final ActivityTaskManagerService mAtmService; /** Indicates whether this device supports wide color gamut / HDR rendering */ Loading Loading @@ -1116,7 +1121,9 @@ public class WindowManagerService extends IWindowManager.Stub static WindowManagerThreadPriorityBooster sThreadPriorityBooster = new WindowManagerThreadPriorityBooster(); @NonNull Supplier<SurfaceControl.Builder> mSurfaceControlFactory; @NonNull Supplier<SurfaceControl.Transaction> mTransactionFactory; private final SurfaceControl.Transaction mTransaction; Loading Loading @@ -1188,9 +1195,11 @@ public class WindowManagerService extends IWindowManager.Stub private volatile boolean mDisableSecureWindows = false; public static WindowManagerService main(final Context context, final InputManagerService im, final boolean showBootMsgs, WindowManagerPolicy policy, ActivityTaskManagerService atm) { /** Creates an instance of the WindowManagerService for the system server. */ public static WindowManagerService main(@NonNull final Context context, @NonNull final InputManagerService im, final boolean showBootMsgs, @NonNull final WindowManagerPolicy policy, @NonNull final ActivityTaskManagerService atm) { // Using SysUI context to have access to Material colors extracted from Wallpaper. final AppCompatConfiguration appCompat = new AppCompatConfiguration( ActivityThread.currentActivityThread().getSystemUiContext()); Loading @@ -1204,15 +1213,19 @@ public class WindowManagerService extends IWindowManager.Stub /** * Creates and returns an instance of the WindowManagerService. This call allows the caller * to override factories that can be used to stub native calls during test. * to override factories that can be used to stub native calls during test. Tests should use * {@link WindowManagerServiceTestSupport} instead of calling this directly to ensure * proper initialization and cleanup of dependencies. */ @VisibleForTesting public static WindowManagerService main(final Context context, final InputManagerService im, final boolean showBootMsgs, WindowManagerPolicy policy, ActivityTaskManagerService atm, DisplayWindowSettingsProvider displayWindowSettingsProvider, Supplier<SurfaceControl.Transaction> transactionFactory, Supplier<SurfaceControl.Builder> surfaceControlFactory, AppCompatConfiguration appCompat) { @VisibleForTesting(visibility = Visibility.PRIVATE) static WindowManagerService main(@NonNull final Context context, @NonNull final InputManagerService im, boolean showBootMsgs, @NonNull final WindowManagerPolicy policy, @NonNull final ActivityTaskManagerService atm, @NonNull final DisplayWindowSettingsProvider displayWindowSettingsProvider, @NonNull final Supplier<SurfaceControl.Transaction> transactionFactory, @NonNull final Supplier<SurfaceControl.Builder> surfaceControlFactory, @NonNull final AppCompatConfiguration appCompat) { final WindowManagerService[] wms = new WindowManagerService[1]; DisplayThread.getHandler().runWithScissors(() -> Loading @@ -1238,12 +1251,13 @@ public class WindowManagerService extends IWindowManager.Stub new WindowManagerShellCommand(this).exec(this, in, out, err, args, callback, result); } private WindowManagerService(Context context, InputManagerService inputManager, boolean showBootMsgs, WindowManagerPolicy policy, ActivityTaskManagerService atm, DisplayWindowSettingsProvider displayWindowSettingsProvider, Supplier<SurfaceControl.Transaction> transactionFactory, Supplier<SurfaceControl.Builder> surfaceControlFactory, AppCompatConfiguration appCompat) { private WindowManagerService(@NonNull Context context, @NonNull InputManagerService inputManager, boolean showBootMsgs, @NonNull WindowManagerPolicy policy, @NonNull ActivityTaskManagerService atm, @NonNull DisplayWindowSettingsProvider displayWindowSettingsProvider, @NonNull Supplier<SurfaceControl.Transaction> transactionFactory, @NonNull Supplier<SurfaceControl.Builder> surfaceControlFactory, @NonNull AppCompatConfiguration appCompat) { installLock(this, INDEX_WINDOW); mGlobalLock = atm.getGlobalLock(); mAtmService = atm; Loading services/tests/wmtests/Android.bp +47 −19 Original line number Diff line number Diff line Loading @@ -11,19 +11,46 @@ package { default_applicable_licenses: ["frameworks_base_license"], } // Include all test java files. filegroup { name: "wmtests-sources", name: "wmtests-support-sources", srcs: [ "src/**/*.java", "src/com/android/server/wm/WindowManagerServiceTestSupport.kt", ], path: "src", visibility: ["//visibility:private"], } java_library { name: "wmtests-support", srcs: [":wmtests-support-sources"], static_libs: [ "com.android.window.flags.window-aconfig-java", "kotlin-stdlib", "services.core", ], lint: { test: true, }, visibility: [ "//frameworks/base/services/tests/wmtests", "//frameworks/opt/car/services/updatableServices/tests", ], } // Include all test files, but exclude test support files. filegroup { name: "wmtests-sources", srcs: ["src/**/*.java"], exclude_srcs: [":wmtests-support-sources"], path: "src", visibility: ["//visibility:private"], } java_genrule { name: "wmtests.protologsrc", srcs: [ ":protolog-impl", ":protolog-groups", ":protolog-impl", ":wmtests-sources", ], tools: ["protologtool"], Loading Loading @@ -52,33 +79,34 @@ android_test { ], static_libs: [ "frameworks-base-testutils", "services.core", "service-permission.stubs.system_server", "androidx.test.runner", "CtsSurfaceValidatorLib", "android.view.inputmethod.flags-aconfig-java", "androidx.test.rules", "androidx.test.runner", "com.android.window.flags.window-aconfig-java", "flag-junit", "flickerlib", "frameworks-base-testutils", "hamcrest-library", "junit-params", "mockito-kotlin2", "mockito-target-extended-minus-junit4", "platform-compat-test-rules", "platform-test-annotations", "service-permission.stubs.system_server", "service-sdksandbox.impl", "services.core", "servicestests-utils", "testables", "testng", "truth", "testables", "hamcrest-library", "flag-junit", "platform-compat-test-rules", "CtsSurfaceValidatorLib", "service-sdksandbox.impl", "com.android.window.flags.window-aconfig-java", "android.view.inputmethod.flags-aconfig-java", "flag-junit", "wmtests-support", ], libs: [ "android.hardware.power-V1-java", "android.test.mock.stubs.system", "android.test.base.stubs.system", "android.test.mock.stubs.system", "android.test.runner.stubs.system", ], Loading @@ -94,8 +122,8 @@ android_test { platform_apis: true, test_suites: [ "device-tests", "automotive-tests", "device-tests", ], certificate: "platform", Loading services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java +14 −26 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import static org.mockito.Mockito.CALLS_REAL_METHODS; import static org.mockito.Mockito.when; import static org.mockito.Mockito.withSettings; import android.annotation.Nullable; import android.app.ActivityManagerInternal; import android.app.ActivityThread; import android.app.AppOpsManager; Loading @@ -67,7 +68,6 @@ import android.os.Looper; import android.os.PowerManager; import android.os.PowerManagerInternal; import android.os.PowerSaveState; import android.os.StrictMode; import android.os.UserHandle; import android.os.UserManager; import android.provider.DeviceConfig; Loading @@ -75,7 +75,6 @@ import android.util.Log; import android.view.DisplayInfo; import android.view.InputChannel; import android.view.SurfaceControl; import android.window.ConfigurationChangeSetting; import com.android.dx.mockito.inline.extended.StaticMockitoSession; import com.android.internal.os.BackgroundThread; Loading @@ -96,11 +95,9 @@ import com.android.server.input.InputManagerService; import com.android.server.pm.UserManagerInternal; import com.android.server.pm.UserManagerService; import com.android.server.policy.PermissionPolicyInternal; import com.android.server.policy.WindowManagerPolicy; import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.testutils.StubTransaction; import com.android.server.uri.UriGrantsManagerInternal; import com.android.window.flags.Flags; import org.junit.rules.TestRule; import org.junit.runner.Description; Loading Loading @@ -144,13 +141,15 @@ public class SystemServicesTestRule implements TestRule { private ActivityTaskManagerService mAtmService; private WindowManagerService mWmService; private InputManagerService mImService; private Runnable mOnBeforeServicesCreated; @Nullable private final Runnable mOnBeforeServicesCreated; /** * Spied {@link SurfaceControl.Transaction} class than can be used to verify calls. */ SurfaceControl.Transaction mTransaction; public SystemServicesTestRule(Runnable onBeforeServicesCreated) { public SystemServicesTestRule(@Nullable Runnable onBeforeServicesCreated) { mOnBeforeServicesCreated = onBeforeServicesCreated; } Loading Loading @@ -398,15 +397,13 @@ public class SystemServicesTestRule implements TestRule { } private void setUpWindowManagerService() { TestWindowManagerPolicy wmPolicy = new TestWindowManagerPolicy(); TestDisplayWindowSettingsProvider testDisplayWindowSettingsProvider = new TestDisplayWindowSettingsProvider(); // Suppress StrictMode violation (DisplayWindowSettings) to avoid log flood. DisplayThread.getHandler().post(StrictMode::allowThreadDiskWritesMask); mWmService = WindowManagerService.main( mContext, mImService, false, wmPolicy, mAtmService, testDisplayWindowSettingsProvider, StubTransaction::new, MockSurfaceControlBuilder::new, mAppCompat); // Use a spied Transaction class to prevent native code calls and verify interactions. mTransaction = spy(StubTransaction.class); mWmService = WindowManagerServiceTestSupport.setUpService(mContext, mImService, new TestWindowManagerPolicy(), mAtmService, new TestDisplayWindowSettingsProvider(), mTransaction, new MockSurfaceControlBuilder(), mAppCompat); spyOn(mWmService); spyOn(mWmService.mRoot); // Invoked during {@link ActivityStack} creation. Loading @@ -418,10 +415,6 @@ public class SystemServicesTestRule implements TestRule { spyOn(mWmService.mDisplayWindowSettings); spyOn(mWmService.mDisplayWindowSettingsProvider); // Setup factory classes to prevent calls to native code. mTransaction = spy(StubTransaction.class); // Return a spied Transaction class than can be used to verify calls. mWmService.mTransactionFactory = () -> mTransaction; mWmService.mSurfaceAnimationRunner = new SurfaceAnimationRunner( null, null, mTransaction, mWmService.mPowerManagerInternal); Loading Loading @@ -488,12 +481,12 @@ public class SystemServicesTestRule implements TestRule { } private static void tearDownLocalServices() { WindowManagerServiceTestSupport.tearDownService(); LocalServices.removeServiceForTest(DisplayManagerInternal.class); LocalServices.removeServiceForTest(PowerManagerInternal.class); LocalServices.removeServiceForTest(ActivityManagerInternal.class); LocalServices.removeServiceForTest(ActivityTaskManagerInternal.class); LocalServices.removeServiceForTest(WindowManagerInternal.class); LocalServices.removeServiceForTest(WindowManagerPolicy.class); LocalServices.removeServiceForTest(PackageManagerInternal.class); LocalServices.removeServiceForTest(UriGrantsManagerInternal.class); LocalServices.removeServiceForTest(PermissionPolicyInternal.class); Loading @@ -501,12 +494,7 @@ public class SystemServicesTestRule implements TestRule { LocalServices.removeServiceForTest(UsageStatsManagerInternal.class); LocalServices.removeServiceForTest(StatusBarManagerInternal.class); LocalServices.removeServiceForTest(UserManagerInternal.class); LocalServices.removeServiceForTest(ImeTargetVisibilityPolicy.class); LocalServices.removeServiceForTest(GrammaticalInflectionManagerInternal.class); if (Flags.condenseConfigurationChangeForSimpleMode()) { LocalServices.removeServiceForTest( ConfigurationChangeSetting.ConfigurationChangeSettingInternal.class); } } Description getDescription() { Loading services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTestSupport.kt 0 → 100644 +112 −0 Original line number Diff line number Diff line /* * 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.wm import android.content.Context import android.os.StrictMode import android.view.SurfaceControl import android.window.ConfigurationChangeSetting import com.android.server.DisplayThread import com.android.server.LocalServices import com.android.server.input.InputManagerService import com.android.server.policy.WindowManagerPolicy import com.android.window.flags.Flags /** * Provides support for tests that require a [WindowManagerService]. * * It provides functionalities for setting up and tearing down the service with proper dependencies, * which can be used across different test modules. */ object WindowManagerServiceTestSupport { /** * Sets up and initializes a [WindowManagerService] instance with the provided dependencies. * * This method constructs a [WindowManagerService] using the provided dependencies for testing. * It's marked as `internal` due to the package-private classes [DisplayWindowSettingsProvider] * and [AppCompatConfiguration]. The `@JvmName` annotation is used to bypass name mangling and * allow access from Java via `WindowManagerServiceTestSupport.setUpService`. * * **Important:** Before calling this method, ensure that any previous [WindowManagerService] * instance and its related services are properly torn down. In your test's setup, it is * recommended to call [tearDownService] before calling [setUpService] to handle cases where a * previous test might have crashed and left services in an inconsistent state. This is crucial * for test reliability. * * Example usage in a test's `setUp()` method: * ``` * @Before * fun setUp() { * WindowManagerServiceTestSupport.tearDownService() // Clean up before setup. * mWindowManagerService = WindowManagerServiceTestSupport.setUpService(...) * // ... rest of your setup logic ... * } * ``` * * @param context the [Context]] for the service. * @param im the [InputManagerService] to use. * @param policy the [WindowManagerPolicy] to use. * @param atm the [ActivityTaskManagerService] to use. * @param displayWindowSettingsProvider the [DisplayWindowSettingsProvider] to use. * @param surfaceControlTransaction the [SurfaceControl.Transaction] instance to use. * @param surfaceControlBuilder the [SurfaceControl.Builder] instance to use. * @param appCompat the [AppCompatConfiguration] to use. * @return the created [WindowManagerService] instance. */ @JvmStatic @JvmName("setUpService") internal fun setUpService( context: Context, im: InputManagerService, policy: WindowManagerPolicy, atm: ActivityTaskManagerService, displayWindowSettingsProvider: DisplayWindowSettingsProvider, surfaceControlTransaction: SurfaceControl.Transaction, surfaceControlBuilder: SurfaceControl.Builder, appCompat: AppCompatConfiguration, ): WindowManagerService { // Suppress StrictMode violation (DisplayWindowSettings) to avoid log flood. DisplayThread.getHandler().post { StrictMode.allowThreadDiskWritesMask() } return WindowManagerService.main( context, im, false, /* showBootMsgs */ policy, atm, displayWindowSettingsProvider, { surfaceControlTransaction }, { surfaceControlBuilder }, appCompat, ) } /** Tears down the [WindowManagerService] and removes related local services. */ @JvmStatic fun tearDownService() { LocalServices.removeServiceForTest(WindowManagerPolicy::class.java) LocalServices.removeServiceForTest(WindowManagerInternal::class.java) LocalServices.removeServiceForTest(ImeTargetVisibilityPolicy::class.java) if (Flags.condenseConfigurationChangeForSimpleMode()) { LocalServices.removeServiceForTest( ConfigurationChangeSetting.ConfigurationChangeSettingInternal::class.java, ) } } } Loading
services/core/java/com/android/server/wm/WindowManagerService.java +31 −17 Original line number Diff line number Diff line Loading @@ -331,6 +331,7 @@ import android.window.WindowContextInfo; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting.Visibility; import com.android.internal.os.IResultReceiver; import com.android.internal.os.TransferPipe; import com.android.internal.policy.IKeyguardDismissCallback; Loading Loading @@ -600,6 +601,7 @@ public class WindowManagerService extends IWindowManager.Stub final boolean mLimitedAlphaCompositing; final int mMaxUiWidth; @NonNull @VisibleForTesting WindowManagerPolicy mPolicy; Loading Loading @@ -1054,13 +1056,16 @@ public class WindowManagerService extends IWindowManager.Stub private boolean mAnimationsDisabled = false; boolean mPointerLocationEnabled = false; @NonNull final AppCompatConfiguration mAppCompatConfiguration; private boolean mIsIgnoreOrientationRequestDisabled; @NonNull final InputManagerService mInputManager; final DisplayManagerInternal mDisplayManagerInternal; final DisplayManager mDisplayManager; @NonNull final ActivityTaskManagerService mAtmService; /** Indicates whether this device supports wide color gamut / HDR rendering */ Loading Loading @@ -1116,7 +1121,9 @@ public class WindowManagerService extends IWindowManager.Stub static WindowManagerThreadPriorityBooster sThreadPriorityBooster = new WindowManagerThreadPriorityBooster(); @NonNull Supplier<SurfaceControl.Builder> mSurfaceControlFactory; @NonNull Supplier<SurfaceControl.Transaction> mTransactionFactory; private final SurfaceControl.Transaction mTransaction; Loading Loading @@ -1188,9 +1195,11 @@ public class WindowManagerService extends IWindowManager.Stub private volatile boolean mDisableSecureWindows = false; public static WindowManagerService main(final Context context, final InputManagerService im, final boolean showBootMsgs, WindowManagerPolicy policy, ActivityTaskManagerService atm) { /** Creates an instance of the WindowManagerService for the system server. */ public static WindowManagerService main(@NonNull final Context context, @NonNull final InputManagerService im, final boolean showBootMsgs, @NonNull final WindowManagerPolicy policy, @NonNull final ActivityTaskManagerService atm) { // Using SysUI context to have access to Material colors extracted from Wallpaper. final AppCompatConfiguration appCompat = new AppCompatConfiguration( ActivityThread.currentActivityThread().getSystemUiContext()); Loading @@ -1204,15 +1213,19 @@ public class WindowManagerService extends IWindowManager.Stub /** * Creates and returns an instance of the WindowManagerService. This call allows the caller * to override factories that can be used to stub native calls during test. * to override factories that can be used to stub native calls during test. Tests should use * {@link WindowManagerServiceTestSupport} instead of calling this directly to ensure * proper initialization and cleanup of dependencies. */ @VisibleForTesting public static WindowManagerService main(final Context context, final InputManagerService im, final boolean showBootMsgs, WindowManagerPolicy policy, ActivityTaskManagerService atm, DisplayWindowSettingsProvider displayWindowSettingsProvider, Supplier<SurfaceControl.Transaction> transactionFactory, Supplier<SurfaceControl.Builder> surfaceControlFactory, AppCompatConfiguration appCompat) { @VisibleForTesting(visibility = Visibility.PRIVATE) static WindowManagerService main(@NonNull final Context context, @NonNull final InputManagerService im, boolean showBootMsgs, @NonNull final WindowManagerPolicy policy, @NonNull final ActivityTaskManagerService atm, @NonNull final DisplayWindowSettingsProvider displayWindowSettingsProvider, @NonNull final Supplier<SurfaceControl.Transaction> transactionFactory, @NonNull final Supplier<SurfaceControl.Builder> surfaceControlFactory, @NonNull final AppCompatConfiguration appCompat) { final WindowManagerService[] wms = new WindowManagerService[1]; DisplayThread.getHandler().runWithScissors(() -> Loading @@ -1238,12 +1251,13 @@ public class WindowManagerService extends IWindowManager.Stub new WindowManagerShellCommand(this).exec(this, in, out, err, args, callback, result); } private WindowManagerService(Context context, InputManagerService inputManager, boolean showBootMsgs, WindowManagerPolicy policy, ActivityTaskManagerService atm, DisplayWindowSettingsProvider displayWindowSettingsProvider, Supplier<SurfaceControl.Transaction> transactionFactory, Supplier<SurfaceControl.Builder> surfaceControlFactory, AppCompatConfiguration appCompat) { private WindowManagerService(@NonNull Context context, @NonNull InputManagerService inputManager, boolean showBootMsgs, @NonNull WindowManagerPolicy policy, @NonNull ActivityTaskManagerService atm, @NonNull DisplayWindowSettingsProvider displayWindowSettingsProvider, @NonNull Supplier<SurfaceControl.Transaction> transactionFactory, @NonNull Supplier<SurfaceControl.Builder> surfaceControlFactory, @NonNull AppCompatConfiguration appCompat) { installLock(this, INDEX_WINDOW); mGlobalLock = atm.getGlobalLock(); mAtmService = atm; Loading
services/tests/wmtests/Android.bp +47 −19 Original line number Diff line number Diff line Loading @@ -11,19 +11,46 @@ package { default_applicable_licenses: ["frameworks_base_license"], } // Include all test java files. filegroup { name: "wmtests-sources", name: "wmtests-support-sources", srcs: [ "src/**/*.java", "src/com/android/server/wm/WindowManagerServiceTestSupport.kt", ], path: "src", visibility: ["//visibility:private"], } java_library { name: "wmtests-support", srcs: [":wmtests-support-sources"], static_libs: [ "com.android.window.flags.window-aconfig-java", "kotlin-stdlib", "services.core", ], lint: { test: true, }, visibility: [ "//frameworks/base/services/tests/wmtests", "//frameworks/opt/car/services/updatableServices/tests", ], } // Include all test files, but exclude test support files. filegroup { name: "wmtests-sources", srcs: ["src/**/*.java"], exclude_srcs: [":wmtests-support-sources"], path: "src", visibility: ["//visibility:private"], } java_genrule { name: "wmtests.protologsrc", srcs: [ ":protolog-impl", ":protolog-groups", ":protolog-impl", ":wmtests-sources", ], tools: ["protologtool"], Loading Loading @@ -52,33 +79,34 @@ android_test { ], static_libs: [ "frameworks-base-testutils", "services.core", "service-permission.stubs.system_server", "androidx.test.runner", "CtsSurfaceValidatorLib", "android.view.inputmethod.flags-aconfig-java", "androidx.test.rules", "androidx.test.runner", "com.android.window.flags.window-aconfig-java", "flag-junit", "flickerlib", "frameworks-base-testutils", "hamcrest-library", "junit-params", "mockito-kotlin2", "mockito-target-extended-minus-junit4", "platform-compat-test-rules", "platform-test-annotations", "service-permission.stubs.system_server", "service-sdksandbox.impl", "services.core", "servicestests-utils", "testables", "testng", "truth", "testables", "hamcrest-library", "flag-junit", "platform-compat-test-rules", "CtsSurfaceValidatorLib", "service-sdksandbox.impl", "com.android.window.flags.window-aconfig-java", "android.view.inputmethod.flags-aconfig-java", "flag-junit", "wmtests-support", ], libs: [ "android.hardware.power-V1-java", "android.test.mock.stubs.system", "android.test.base.stubs.system", "android.test.mock.stubs.system", "android.test.runner.stubs.system", ], Loading @@ -94,8 +122,8 @@ android_test { platform_apis: true, test_suites: [ "device-tests", "automotive-tests", "device-tests", ], certificate: "platform", Loading
services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java +14 −26 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import static org.mockito.Mockito.CALLS_REAL_METHODS; import static org.mockito.Mockito.when; import static org.mockito.Mockito.withSettings; import android.annotation.Nullable; import android.app.ActivityManagerInternal; import android.app.ActivityThread; import android.app.AppOpsManager; Loading @@ -67,7 +68,6 @@ import android.os.Looper; import android.os.PowerManager; import android.os.PowerManagerInternal; import android.os.PowerSaveState; import android.os.StrictMode; import android.os.UserHandle; import android.os.UserManager; import android.provider.DeviceConfig; Loading @@ -75,7 +75,6 @@ import android.util.Log; import android.view.DisplayInfo; import android.view.InputChannel; import android.view.SurfaceControl; import android.window.ConfigurationChangeSetting; import com.android.dx.mockito.inline.extended.StaticMockitoSession; import com.android.internal.os.BackgroundThread; Loading @@ -96,11 +95,9 @@ import com.android.server.input.InputManagerService; import com.android.server.pm.UserManagerInternal; import com.android.server.pm.UserManagerService; import com.android.server.policy.PermissionPolicyInternal; import com.android.server.policy.WindowManagerPolicy; import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.testutils.StubTransaction; import com.android.server.uri.UriGrantsManagerInternal; import com.android.window.flags.Flags; import org.junit.rules.TestRule; import org.junit.runner.Description; Loading Loading @@ -144,13 +141,15 @@ public class SystemServicesTestRule implements TestRule { private ActivityTaskManagerService mAtmService; private WindowManagerService mWmService; private InputManagerService mImService; private Runnable mOnBeforeServicesCreated; @Nullable private final Runnable mOnBeforeServicesCreated; /** * Spied {@link SurfaceControl.Transaction} class than can be used to verify calls. */ SurfaceControl.Transaction mTransaction; public SystemServicesTestRule(Runnable onBeforeServicesCreated) { public SystemServicesTestRule(@Nullable Runnable onBeforeServicesCreated) { mOnBeforeServicesCreated = onBeforeServicesCreated; } Loading Loading @@ -398,15 +397,13 @@ public class SystemServicesTestRule implements TestRule { } private void setUpWindowManagerService() { TestWindowManagerPolicy wmPolicy = new TestWindowManagerPolicy(); TestDisplayWindowSettingsProvider testDisplayWindowSettingsProvider = new TestDisplayWindowSettingsProvider(); // Suppress StrictMode violation (DisplayWindowSettings) to avoid log flood. DisplayThread.getHandler().post(StrictMode::allowThreadDiskWritesMask); mWmService = WindowManagerService.main( mContext, mImService, false, wmPolicy, mAtmService, testDisplayWindowSettingsProvider, StubTransaction::new, MockSurfaceControlBuilder::new, mAppCompat); // Use a spied Transaction class to prevent native code calls and verify interactions. mTransaction = spy(StubTransaction.class); mWmService = WindowManagerServiceTestSupport.setUpService(mContext, mImService, new TestWindowManagerPolicy(), mAtmService, new TestDisplayWindowSettingsProvider(), mTransaction, new MockSurfaceControlBuilder(), mAppCompat); spyOn(mWmService); spyOn(mWmService.mRoot); // Invoked during {@link ActivityStack} creation. Loading @@ -418,10 +415,6 @@ public class SystemServicesTestRule implements TestRule { spyOn(mWmService.mDisplayWindowSettings); spyOn(mWmService.mDisplayWindowSettingsProvider); // Setup factory classes to prevent calls to native code. mTransaction = spy(StubTransaction.class); // Return a spied Transaction class than can be used to verify calls. mWmService.mTransactionFactory = () -> mTransaction; mWmService.mSurfaceAnimationRunner = new SurfaceAnimationRunner( null, null, mTransaction, mWmService.mPowerManagerInternal); Loading Loading @@ -488,12 +481,12 @@ public class SystemServicesTestRule implements TestRule { } private static void tearDownLocalServices() { WindowManagerServiceTestSupport.tearDownService(); LocalServices.removeServiceForTest(DisplayManagerInternal.class); LocalServices.removeServiceForTest(PowerManagerInternal.class); LocalServices.removeServiceForTest(ActivityManagerInternal.class); LocalServices.removeServiceForTest(ActivityTaskManagerInternal.class); LocalServices.removeServiceForTest(WindowManagerInternal.class); LocalServices.removeServiceForTest(WindowManagerPolicy.class); LocalServices.removeServiceForTest(PackageManagerInternal.class); LocalServices.removeServiceForTest(UriGrantsManagerInternal.class); LocalServices.removeServiceForTest(PermissionPolicyInternal.class); Loading @@ -501,12 +494,7 @@ public class SystemServicesTestRule implements TestRule { LocalServices.removeServiceForTest(UsageStatsManagerInternal.class); LocalServices.removeServiceForTest(StatusBarManagerInternal.class); LocalServices.removeServiceForTest(UserManagerInternal.class); LocalServices.removeServiceForTest(ImeTargetVisibilityPolicy.class); LocalServices.removeServiceForTest(GrammaticalInflectionManagerInternal.class); if (Flags.condenseConfigurationChangeForSimpleMode()) { LocalServices.removeServiceForTest( ConfigurationChangeSetting.ConfigurationChangeSettingInternal.class); } } Description getDescription() { Loading
services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTestSupport.kt 0 → 100644 +112 −0 Original line number Diff line number Diff line /* * 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.wm import android.content.Context import android.os.StrictMode import android.view.SurfaceControl import android.window.ConfigurationChangeSetting import com.android.server.DisplayThread import com.android.server.LocalServices import com.android.server.input.InputManagerService import com.android.server.policy.WindowManagerPolicy import com.android.window.flags.Flags /** * Provides support for tests that require a [WindowManagerService]. * * It provides functionalities for setting up and tearing down the service with proper dependencies, * which can be used across different test modules. */ object WindowManagerServiceTestSupport { /** * Sets up and initializes a [WindowManagerService] instance with the provided dependencies. * * This method constructs a [WindowManagerService] using the provided dependencies for testing. * It's marked as `internal` due to the package-private classes [DisplayWindowSettingsProvider] * and [AppCompatConfiguration]. The `@JvmName` annotation is used to bypass name mangling and * allow access from Java via `WindowManagerServiceTestSupport.setUpService`. * * **Important:** Before calling this method, ensure that any previous [WindowManagerService] * instance and its related services are properly torn down. In your test's setup, it is * recommended to call [tearDownService] before calling [setUpService] to handle cases where a * previous test might have crashed and left services in an inconsistent state. This is crucial * for test reliability. * * Example usage in a test's `setUp()` method: * ``` * @Before * fun setUp() { * WindowManagerServiceTestSupport.tearDownService() // Clean up before setup. * mWindowManagerService = WindowManagerServiceTestSupport.setUpService(...) * // ... rest of your setup logic ... * } * ``` * * @param context the [Context]] for the service. * @param im the [InputManagerService] to use. * @param policy the [WindowManagerPolicy] to use. * @param atm the [ActivityTaskManagerService] to use. * @param displayWindowSettingsProvider the [DisplayWindowSettingsProvider] to use. * @param surfaceControlTransaction the [SurfaceControl.Transaction] instance to use. * @param surfaceControlBuilder the [SurfaceControl.Builder] instance to use. * @param appCompat the [AppCompatConfiguration] to use. * @return the created [WindowManagerService] instance. */ @JvmStatic @JvmName("setUpService") internal fun setUpService( context: Context, im: InputManagerService, policy: WindowManagerPolicy, atm: ActivityTaskManagerService, displayWindowSettingsProvider: DisplayWindowSettingsProvider, surfaceControlTransaction: SurfaceControl.Transaction, surfaceControlBuilder: SurfaceControl.Builder, appCompat: AppCompatConfiguration, ): WindowManagerService { // Suppress StrictMode violation (DisplayWindowSettings) to avoid log flood. DisplayThread.getHandler().post { StrictMode.allowThreadDiskWritesMask() } return WindowManagerService.main( context, im, false, /* showBootMsgs */ policy, atm, displayWindowSettingsProvider, { surfaceControlTransaction }, { surfaceControlBuilder }, appCompat, ) } /** Tears down the [WindowManagerService] and removes related local services. */ @JvmStatic fun tearDownService() { LocalServices.removeServiceForTest(WindowManagerPolicy::class.java) LocalServices.removeServiceForTest(WindowManagerInternal::class.java) LocalServices.removeServiceForTest(ImeTargetVisibilityPolicy::class.java) if (Flags.condenseConfigurationChangeForSimpleMode()) { LocalServices.removeServiceForTest( ConfigurationChangeSetting.ConfigurationChangeSettingInternal::class.java, ) } } }