diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 43dceeda30260..7650fa1f3f5e4 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1183,7 +1183,8 @@ public class WindowManagerService extends IWindowManager.Stub final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy, ActivityTaskManagerService atm) { return main(context, im, showBootMsgs, onlyCore, policy, atm, - SurfaceControl.Transaction::new, Surface::new, SurfaceControl.Builder::new); + new DisplayWindowSettingsProvider(), SurfaceControl.Transaction::new, Surface::new, + SurfaceControl.Builder::new); } /** @@ -1193,12 +1194,14 @@ public class WindowManagerService extends IWindowManager.Stub @VisibleForTesting public static WindowManagerService main(final Context context, final InputManagerService im, final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy, - ActivityTaskManagerService atm, Supplier transactionFactory, + ActivityTaskManagerService atm, DisplayWindowSettingsProvider + displayWindowSettingsProvider, Supplier transactionFactory, Supplier surfaceFactory, Function surfaceControlFactory) { DisplayThread.getHandler().runWithScissors(() -> sInstance = new WindowManagerService(context, im, showBootMsgs, onlyCore, policy, - atm, transactionFactory, surfaceFactory, surfaceControlFactory), 0); + atm, displayWindowSettingsProvider, transactionFactory, surfaceFactory, + surfaceControlFactory), 0); return sInstance; } @@ -1220,7 +1223,8 @@ public class WindowManagerService extends IWindowManager.Stub private WindowManagerService(Context context, InputManagerService inputManager, boolean showBootMsgs, boolean onlyCore, WindowManagerPolicy policy, - ActivityTaskManagerService atm, Supplier transactionFactory, + ActivityTaskManagerService atm, DisplayWindowSettingsProvider + displayWindowSettingsProvider, Supplier transactionFactory, Supplier surfaceFactory, Function surfaceControlFactory) { installLock(this, INDEX_WINDOW); @@ -1370,7 +1374,7 @@ public class WindowManagerService extends IWindowManager.Stub final String displaySettingsPath = Settings.Global.getString(resolver, DEVELOPMENT_WM_DISPLAY_SETTINGS_PATH); - mDisplayWindowSettingsProvider = new DisplayWindowSettingsProvider(); + mDisplayWindowSettingsProvider = displayWindowSettingsProvider; if (displaySettingsPath != null) { mDisplayWindowSettingsProvider.setBaseSettingsFilePath(displaySettingsPath); } diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java index afaf1b1fea0ae..491fe98660c00 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java +++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java @@ -110,6 +110,7 @@ public class SystemServicesTestRule implements TestRule { private ActivityTaskManagerService mAtmService; private WindowManagerService mWmService; private TestWindowManagerPolicy mWMPolicy; + private TestDisplayWindowSettingsProvider mTestDisplayWindowSettingsProvider; private WindowState.PowerManagerWrapper mPowerManagerWrapper; private InputManagerService mImService; private InputChannel mInputChannel; @@ -284,10 +285,12 @@ public class SystemServicesTestRule implements TestRule { mPowerManagerWrapper = mock(WindowState.PowerManagerWrapper.class); mWMPolicy = new TestWindowManagerPolicy(this::getWindowManagerService, mPowerManagerWrapper); + mTestDisplayWindowSettingsProvider = new TestDisplayWindowSettingsProvider(); // Suppress StrictMode violation (DisplayWindowSettings) to avoid log flood. DisplayThread.getHandler().post(StrictMode::allowThreadDiskWritesMask); mWmService = WindowManagerService.main( - mContext, mImService, false, false, mWMPolicy, mAtmService, StubTransaction::new, + mContext, mImService, false, false, mWMPolicy, mAtmService, + mTestDisplayWindowSettingsProvider, StubTransaction::new, () -> mSurfaceFactory.get(), (unused) -> new MockSurfaceControlBuilder()); spyOn(mWmService); spyOn(mWmService.mRoot); diff --git a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java index 777149b600987..ce2d748599316 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java +++ b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java @@ -147,10 +147,6 @@ class TestDisplayContent extends DisplayContent { final Display display = new Display(DisplayManagerGlobal.getInstance(), displayId, mInfo, DEFAULT_DISPLAY_ADJUSTMENTS); final TestDisplayContent newDisplay = createInternal(display); - // Ensure letterbox aspect ratio is not overridden on any device target. - // {@link com.android.internal.R.dimen.config_taskLetterboxAspectRatio}, provided by - // the below method, is set on some device form factors. - mService.mWindowManager.setFixedOrientationLetterboxAspectRatio(0); // disable the normal system decorations final DisplayPolicy displayPolicy = newDisplay.getDisplayPolicy(); spyOn(displayPolicy); diff --git a/services/tests/wmtests/src/com/android/server/wm/TestDisplayWindowSettingsProvider.java b/services/tests/wmtests/src/com/android/server/wm/TestDisplayWindowSettingsProvider.java new file mode 100644 index 0000000000000..b2e44b1421f48 --- /dev/null +++ b/services/tests/wmtests/src/com/android/server/wm/TestDisplayWindowSettingsProvider.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2021 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.annotation.NonNull; +import android.view.DisplayInfo; + +import java.util.HashMap; +import java.util.Map; + +/** + * In-memory DisplayWindowSettingsProvider used in tests. Ensures no settings are read from or + * written to device-specific display settings files. + */ +public final class TestDisplayWindowSettingsProvider extends DisplayWindowSettingsProvider { + + private final Map mOverrideSettingsMap = new HashMap<>(); + + @Override + @NonNull + public SettingsEntry getSettings(@NonNull DisplayInfo info) { + // Because no settings are read from settings files, there is no need to store base + // settings. Only override settings are necessary to track because they can be modified + // during tests (e.g. display size, ignore orientation requests). + return getOverrideSettings(info); + } + + @Override + @NonNull + public SettingsEntry getOverrideSettings(@NonNull DisplayInfo info) { + return new SettingsEntry(getOrCreateOverrideSettingsEntry(info)); + } + + @Override + public void updateOverrideSettings(@NonNull DisplayInfo info, + @NonNull SettingsEntry overrides) { + final SettingsEntry overrideSettings = getOrCreateOverrideSettingsEntry(info); + overrideSettings.setTo(overrides); + } + + @NonNull + private SettingsEntry getOrCreateOverrideSettingsEntry(DisplayInfo info) { + final String identifier = getIdentifier(info); + SettingsEntry settings; + if ((settings = mOverrideSettingsMap.get(identifier)) != null) { + return settings; + } + settings = new SettingsEntry(); + mOverrideSettingsMap.put(identifier, settings); + return settings; + } + + /** + * In {@link TestDisplayWindowSettingsProvider}, always use uniqueId as the identifier. + */ + private static String getIdentifier(DisplayInfo displayInfo) { + return displayInfo.uniqueId; + } +} diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java index 39fdb2d48a703..5bafbbd2bdf79 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java @@ -55,6 +55,8 @@ import static com.android.server.wm.StartingSurfaceController.DEBUG_ENABLE_SHELL import static com.android.server.wm.WindowContainer.POSITION_BOTTOM; import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.mock; @@ -153,6 +155,22 @@ class WindowTestsBase extends SystemServiceTestsBase { */ Transaction mTransaction; + /** + * Whether device-specific global overrides have already been checked in + * {@link WindowTestsBase#setUpBase()}. + */ + private static boolean sGlobalOverridesChecked; + /** + * Whether device-specific overrides have already been checked in + * {@link WindowTestsBase#setUpBase()} when the default display is used. + */ + private static boolean sOverridesCheckedDefaultDisplay; + /** + * Whether device-specific overrides have already been checked in + * {@link WindowTestsBase#setUpBase()} when a {@link TestDisplayContent} is used. + */ + private static boolean sOverridesCheckedTestDisplay; + @BeforeClass public static void setUpOnceBase() { AttributeCache.init(getInstrumentation().getTargetContext()); @@ -190,6 +208,28 @@ class WindowTestsBase extends SystemServiceTestsBase { // {@link com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio}, is set // on some device form factors. mAtm.mWindowManager.setFixedOrientationLetterboxAspectRatio(0); + + checkDeviceSpecificOverridesNotApplied(); + } + + /** + * Check that device-specific overrides are not applied. Only need to check once during entire + * test run for each case: global overrides, default display, and test display. + */ + private void checkDeviceSpecificOverridesNotApplied() { + // Check global overrides + if (!sGlobalOverridesChecked) { + assertEquals(0, mWm.getFixedOrientationLetterboxAspectRatio(), 0 /* delta */); + sGlobalOverridesChecked = true; + } + // Check display-specific overrides + if (!sOverridesCheckedDefaultDisplay && mDisplayContent == mDefaultDisplay) { + assertFalse(mDisplayContent.getIgnoreOrientationRequest()); + sOverridesCheckedDefaultDisplay = true; + } else if (!sOverridesCheckedTestDisplay && mDisplayContent instanceof TestDisplayContent) { + assertFalse(mDisplayContent.getIgnoreOrientationRequest()); + sOverridesCheckedTestDisplay = true; + } } private void createTestDisplay(UseTestDisplay annotation) {