Loading services/core/java/com/android/server/wm/WindowManagerService.java +57 −1 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LE import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW; import static android.app.StatusBarManager.DISABLE_MASK; import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED; import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT; import static android.content.pm.PackageManager.FEATURE_PC; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.os.Process.SYSTEM_UID; Loading @@ -36,7 +37,9 @@ import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.provider.DeviceConfig.WindowManager.KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE; import static android.provider.DeviceConfig.WindowManager.KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP; import static android.provider.DeviceConfig.WindowManager.KEY_SYSTEM_GESTURE_EXCLUSION_LOG_DEBOUNCE_MILLIS; import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT; import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS; import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; import static android.view.WindowManager.DOCKED_INVALID; Loading Loading @@ -666,7 +669,8 @@ public class WindowManagerService extends IWindowManager.Stub WindowManagerInternal.OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener; SettingsObserver mSettingsObserver; private final class SettingsObserver extends ContentObserver { @VisibleForTesting final class SettingsObserver extends ContentObserver { private final Uri mDisplayInversionEnabledUri = Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED); private final Uri mWindowAnimationScaleUri = Loading @@ -681,6 +685,12 @@ public class WindowManagerService extends IWindowManager.Stub Settings.Global.getUriFor(Settings.Global.POLICY_CONTROL); private final Uri mPointerLocationUri = Settings.System.getUriFor(Settings.System.POINTER_LOCATION); private final Uri mForceDesktopModeOnExternalDisplaysUri = Settings.Global.getUriFor( Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS); private final Uri mFreeformWindowUri = Settings.Global.getUriFor( Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT); private final Uri mForceResizableUri = Settings.Global.getUriFor( DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES); public SettingsObserver() { super(new Handler()); Loading @@ -697,6 +707,10 @@ public class WindowManagerService extends IWindowManager.Stub UserHandle.USER_ALL); resolver.registerContentObserver(mPolicyControlUri, false, this, UserHandle.USER_ALL); resolver.registerContentObserver(mPointerLocationUri, false, this, UserHandle.USER_ALL); resolver.registerContentObserver(mForceDesktopModeOnExternalDisplaysUri, false, this, UserHandle.USER_ALL); resolver.registerContentObserver(mFreeformWindowUri, false, this, UserHandle.USER_ALL); resolver.registerContentObserver(mForceResizableUri, false, this, UserHandle.USER_ALL); } @Override Loading @@ -720,6 +734,21 @@ public class WindowManagerService extends IWindowManager.Stub return; } if (mForceDesktopModeOnExternalDisplaysUri.equals(uri)) { updateForceDesktopModeOnExternalDisplays(); return; } if (mFreeformWindowUri.equals(uri)) { updateFreeformWindowManagement(); return; } if (mForceResizableUri.equals(uri)) { updateForceResizableTasks(); return; } @UpdateAnimationScaleMode final int mode; if (mWindowAnimationScaleUri.equals(uri)) { Loading Loading @@ -762,6 +791,33 @@ public class WindowManagerService extends IWindowManager.Stub mPointerLocationEnabled)); } } void updateForceDesktopModeOnExternalDisplays() { ContentResolver resolver = mContext.getContentResolver(); final boolean enableForceDesktopMode = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, 0) != 0; if (mForceDesktopModeOnExternalDisplays == enableForceDesktopMode) { return; } setForceDesktopModeOnExternalDisplays(enableForceDesktopMode); } void updateFreeformWindowManagement() { ContentResolver resolver = mContext.getContentResolver(); final boolean freeformWindowManagement = mContext.getPackageManager().hasSystemFeature( FEATURE_FREEFORM_WINDOW_MANAGEMENT) || Settings.Global.getInt( resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0; mAtmService.mSupportsFreeformWindowManagement = freeformWindowManagement; } void updateForceResizableTasks() { ContentResolver resolver = mContext.getContentResolver(); final boolean forceResizable = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0; mAtmService.mForceResizableActivities = forceResizable; } } PowerManager mPowerManager; Loading services/tests/wmtests/src/com/android/server/wm/WindowManagerSettingsTests.java 0 → 100644 +111 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 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 static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT; import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS; import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; import static org.junit.Assert.assertEquals; import android.content.ContentResolver; import android.net.Uri; import android.provider.Settings; import androidx.test.filters.SmallTest; import org.junit.Test; /** * Test for {@link WindowManagerService.SettingsObserver}. * * Build/Install/Run: * atest WmTests:WindowManagerSettingsTests */ @SmallTest public class WindowManagerSettingsTests extends WindowTestsBase { @Test public void testForceDesktopModeOnExternalDisplays() { try (SettingsSession forceDesktopModeSession = new SettingsSession(DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS)) { final boolean forceDesktopMode = !forceDesktopModeSession.getSetting(); final Uri forceDesktopModeUri = forceDesktopModeSession.setSetting(forceDesktopMode); mWm.mSettingsObserver.onChange(false, forceDesktopModeUri); assertEquals(mWm.mForceDesktopModeOnExternalDisplays, forceDesktopMode); } } @Test public void testFreeformWindow() { try (SettingsSession freeformWindowSession = new SettingsSession(DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT)) { final boolean freeformWindow = !freeformWindowSession.getSetting(); final Uri freeformWindowUri = freeformWindowSession.setSetting(freeformWindow); mWm.mSettingsObserver.onChange(false, freeformWindowUri); assertEquals(mWm.mAtmService.mSupportsFreeformWindowManagement, freeformWindow); } } @Test public void testForceResizableMode() { try (SettingsSession forceResizableSession = new SettingsSession(DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES)) { final boolean forceResizableMode = !forceResizableSession.getSetting(); final Uri forceResizableUri = forceResizableSession.setSetting(forceResizableMode); mWm.mSettingsObserver.onChange(false, forceResizableUri); assertEquals(mWm.mAtmService.mForceResizableActivities, forceResizableMode); } } private class SettingsSession implements AutoCloseable { private static final int SETTING_VALUE_OFF = 0; private static final int SETTING_VALUE_ON = 1; private final String mSettingName; private final int mInitialValue; SettingsSession(String name) { mSettingName = name; mInitialValue = getSetting() ? SETTING_VALUE_ON : SETTING_VALUE_OFF; } boolean getSetting() { return Settings.Global.getInt(getContentResolver(), mSettingName, 0) != 0; } Uri setSetting(boolean enable) { Settings.Global.putInt(getContentResolver(), mSettingName, enable ? SETTING_VALUE_ON : SETTING_VALUE_OFF); return Settings.Global.getUriFor(mSettingName); } private ContentResolver getContentResolver() { return getInstrumentation().getTargetContext().getContentResolver(); } @Override public void close() { setSetting(mInitialValue == SETTING_VALUE_ON); } } } Loading
services/core/java/com/android/server/wm/WindowManagerService.java +57 −1 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LE import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW; import static android.app.StatusBarManager.DISABLE_MASK; import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED; import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT; import static android.content.pm.PackageManager.FEATURE_PC; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.os.Process.SYSTEM_UID; Loading @@ -36,7 +37,9 @@ import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.provider.DeviceConfig.WindowManager.KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE; import static android.provider.DeviceConfig.WindowManager.KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP; import static android.provider.DeviceConfig.WindowManager.KEY_SYSTEM_GESTURE_EXCLUSION_LOG_DEBOUNCE_MILLIS; import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT; import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS; import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; import static android.view.WindowManager.DOCKED_INVALID; Loading Loading @@ -666,7 +669,8 @@ public class WindowManagerService extends IWindowManager.Stub WindowManagerInternal.OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener; SettingsObserver mSettingsObserver; private final class SettingsObserver extends ContentObserver { @VisibleForTesting final class SettingsObserver extends ContentObserver { private final Uri mDisplayInversionEnabledUri = Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED); private final Uri mWindowAnimationScaleUri = Loading @@ -681,6 +685,12 @@ public class WindowManagerService extends IWindowManager.Stub Settings.Global.getUriFor(Settings.Global.POLICY_CONTROL); private final Uri mPointerLocationUri = Settings.System.getUriFor(Settings.System.POINTER_LOCATION); private final Uri mForceDesktopModeOnExternalDisplaysUri = Settings.Global.getUriFor( Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS); private final Uri mFreeformWindowUri = Settings.Global.getUriFor( Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT); private final Uri mForceResizableUri = Settings.Global.getUriFor( DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES); public SettingsObserver() { super(new Handler()); Loading @@ -697,6 +707,10 @@ public class WindowManagerService extends IWindowManager.Stub UserHandle.USER_ALL); resolver.registerContentObserver(mPolicyControlUri, false, this, UserHandle.USER_ALL); resolver.registerContentObserver(mPointerLocationUri, false, this, UserHandle.USER_ALL); resolver.registerContentObserver(mForceDesktopModeOnExternalDisplaysUri, false, this, UserHandle.USER_ALL); resolver.registerContentObserver(mFreeformWindowUri, false, this, UserHandle.USER_ALL); resolver.registerContentObserver(mForceResizableUri, false, this, UserHandle.USER_ALL); } @Override Loading @@ -720,6 +734,21 @@ public class WindowManagerService extends IWindowManager.Stub return; } if (mForceDesktopModeOnExternalDisplaysUri.equals(uri)) { updateForceDesktopModeOnExternalDisplays(); return; } if (mFreeformWindowUri.equals(uri)) { updateFreeformWindowManagement(); return; } if (mForceResizableUri.equals(uri)) { updateForceResizableTasks(); return; } @UpdateAnimationScaleMode final int mode; if (mWindowAnimationScaleUri.equals(uri)) { Loading Loading @@ -762,6 +791,33 @@ public class WindowManagerService extends IWindowManager.Stub mPointerLocationEnabled)); } } void updateForceDesktopModeOnExternalDisplays() { ContentResolver resolver = mContext.getContentResolver(); final boolean enableForceDesktopMode = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, 0) != 0; if (mForceDesktopModeOnExternalDisplays == enableForceDesktopMode) { return; } setForceDesktopModeOnExternalDisplays(enableForceDesktopMode); } void updateFreeformWindowManagement() { ContentResolver resolver = mContext.getContentResolver(); final boolean freeformWindowManagement = mContext.getPackageManager().hasSystemFeature( FEATURE_FREEFORM_WINDOW_MANAGEMENT) || Settings.Global.getInt( resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0; mAtmService.mSupportsFreeformWindowManagement = freeformWindowManagement; } void updateForceResizableTasks() { ContentResolver resolver = mContext.getContentResolver(); final boolean forceResizable = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0; mAtmService.mForceResizableActivities = forceResizable; } } PowerManager mPowerManager; Loading
services/tests/wmtests/src/com/android/server/wm/WindowManagerSettingsTests.java 0 → 100644 +111 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 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 static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT; import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS; import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; import static org.junit.Assert.assertEquals; import android.content.ContentResolver; import android.net.Uri; import android.provider.Settings; import androidx.test.filters.SmallTest; import org.junit.Test; /** * Test for {@link WindowManagerService.SettingsObserver}. * * Build/Install/Run: * atest WmTests:WindowManagerSettingsTests */ @SmallTest public class WindowManagerSettingsTests extends WindowTestsBase { @Test public void testForceDesktopModeOnExternalDisplays() { try (SettingsSession forceDesktopModeSession = new SettingsSession(DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS)) { final boolean forceDesktopMode = !forceDesktopModeSession.getSetting(); final Uri forceDesktopModeUri = forceDesktopModeSession.setSetting(forceDesktopMode); mWm.mSettingsObserver.onChange(false, forceDesktopModeUri); assertEquals(mWm.mForceDesktopModeOnExternalDisplays, forceDesktopMode); } } @Test public void testFreeformWindow() { try (SettingsSession freeformWindowSession = new SettingsSession(DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT)) { final boolean freeformWindow = !freeformWindowSession.getSetting(); final Uri freeformWindowUri = freeformWindowSession.setSetting(freeformWindow); mWm.mSettingsObserver.onChange(false, freeformWindowUri); assertEquals(mWm.mAtmService.mSupportsFreeformWindowManagement, freeformWindow); } } @Test public void testForceResizableMode() { try (SettingsSession forceResizableSession = new SettingsSession(DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES)) { final boolean forceResizableMode = !forceResizableSession.getSetting(); final Uri forceResizableUri = forceResizableSession.setSetting(forceResizableMode); mWm.mSettingsObserver.onChange(false, forceResizableUri); assertEquals(mWm.mAtmService.mForceResizableActivities, forceResizableMode); } } private class SettingsSession implements AutoCloseable { private static final int SETTING_VALUE_OFF = 0; private static final int SETTING_VALUE_ON = 1; private final String mSettingName; private final int mInitialValue; SettingsSession(String name) { mSettingName = name; mInitialValue = getSetting() ? SETTING_VALUE_ON : SETTING_VALUE_OFF; } boolean getSetting() { return Settings.Global.getInt(getContentResolver(), mSettingName, 0) != 0; } Uri setSetting(boolean enable) { Settings.Global.putInt(getContentResolver(), mSettingName, enable ? SETTING_VALUE_ON : SETTING_VALUE_OFF); return Settings.Global.getUriFor(mSettingName); } private ContentResolver getContentResolver() { return getInstrumentation().getTargetContext().getContentResolver(); } @Override public void close() { setSetting(mInitialValue == SETTING_VALUE_ON); } } }