Add dev option to force desktop mode
When turned on, this will:
- Enable system decorations on external screens
- Enable freeform windowing mode on external displays
- TODO: Show mouse pointer on external display
Bug: 112451761
Test: DisplaySettingsTests
Test: DesktopModePreferenceControllerTest
Test: FreeformWindowsPreferenceControllerTest
Change-Id: If46399b9d6b8faa2a11fbdf8a4bbfef1284147c8
diff --git a/services/core/java/com/android/server/wm/ActivityDisplay.java b/services/core/java/com/android/server/wm/ActivityDisplay.java
index 5fb1def..d650871 100644
--- a/services/core/java/com/android/server/wm/ActivityDisplay.java
+++ b/services/core/java/com/android/server/wm/ActivityDisplay.java
@@ -1061,13 +1061,12 @@
}
/**
+ * Checks if system decorations should be shown on this display.
+ *
* @see Display#FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
*/
boolean supportsSystemDecorations() {
- return mDisplay.supportsSystemDecorations()
- // TODO (b/111363427): Remove this and set the new FLAG_SHOULD_SHOW_LAUNCHER flag
- // (b/114338689) whenever vr 2d display id is set.
- || mDisplayId == mSupervisor.mService.mVr2dDisplayId;
+ return mWindowContainerController.supportsSystemDecorations();
}
private boolean shouldDestroyContentOnRemove() {
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 3359eac8..dc07a7c 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -56,7 +56,6 @@
import static android.os.Process.FIRST_APPLICATION_UID;
import static android.os.Process.SYSTEM_UID;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
-import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
@@ -652,8 +651,6 @@
ActivityTaskManager.supportsSplitScreenMultiWindow(mContext);
final boolean supportsMultiDisplay = mContext.getPackageManager()
.hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
- final boolean alwaysFinishActivities =
- Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
final boolean forceResizable = Settings.Global.getInt(
resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 348b2af..570bd23 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -4651,4 +4651,16 @@
pendingLayoutChanges |= changes;
}
+
+ /**
+ * @see Display#FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
+ */
+ boolean supportsSystemDecorations() {
+ // TODO(b/114338689): Read the setting from DisplaySettings.
+ return mDisplay.supportsSystemDecorations()
+ // TODO (b/111363427): Remove this and set the new FLAG_SHOULD_SHOW_LAUNCHER flag
+ // (b/114338689) whenever vr 2d display id is set.
+ || mDisplayId == mService.mVr2dDisplayId
+ || mService.mForceDesktopModeOnExternalDisplays;
+ }
}
diff --git a/services/core/java/com/android/server/wm/DisplaySettings.java b/services/core/java/com/android/server/wm/DisplaySettings.java
index 44956ab..624fbc7 100644
--- a/services/core/java/com/android/server/wm/DisplaySettings.java
+++ b/services/core/java/com/android/server/wm/DisplaySettings.java
@@ -185,15 +185,12 @@
}
// No record is present so use default windowing mode policy.
if (windowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
- if (displayId == Display.DEFAULT_DISPLAY) {
- windowingMode = (mService.mIsPc && mService.mSupportsFreeformWindowManagement)
- ? WindowConfiguration.WINDOWING_MODE_FREEFORM
- : WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
- } else {
- windowingMode = mService.mSupportsFreeformWindowManagement
- ? WindowConfiguration.WINDOWING_MODE_FREEFORM
- : WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
- }
+ final boolean forceDesktopMode = mService.mForceDesktopModeOnExternalDisplays
+ && displayId != Display.DEFAULT_DISPLAY;
+ windowingMode = mService.mSupportsFreeformWindowManagement
+ && (mService.mIsPc || forceDesktopMode)
+ ? WindowConfiguration.WINDOWING_MODE_FREEFORM
+ : WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
}
return windowingMode;
}
diff --git a/services/core/java/com/android/server/wm/DisplayWindowController.java b/services/core/java/com/android/server/wm/DisplayWindowController.java
index f772216..f4f4dd3 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowController.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowController.java
@@ -314,6 +314,17 @@
|| transit == TRANSIT_TASK_TO_FRONT;
}
+ /**
+ * Checks if system decorations should be shown on this display.
+ *
+ * @see Display#FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
+ */
+ public boolean supportsSystemDecorations() {
+ synchronized (mGlobalLock) {
+ return mContainer.supportsSystemDecorations();
+ }
+ }
+
@Override
public String toString() {
return "{DisplayWindowController displayId=" + mDisplayId + "}";
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index a641f75..73cdbd3 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -29,6 +29,7 @@
import static android.os.Process.SYSTEM_UID;
import static android.os.Process.myPid;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
+import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.WindowManager.DOCKED_INVALID;
@@ -538,12 +539,21 @@
int mDockedStackCreateMode = SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
Rect mDockedStackCreateBounds;
- boolean mForceResizableTasks = false;
- boolean mSupportsPictureInPicture = false;
- boolean mSupportsFreeformWindowManagement = false;
- boolean mIsPc = false;
+ boolean mForceResizableTasks;
+ boolean mSupportsPictureInPicture;
+ boolean mSupportsFreeformWindowManagement;
+ boolean mIsPc;
+ /**
+ * Flag that indicates that desktop mode is forced for public secondary screens.
+ *
+ * This includes several settings:
+ * - Set freeform windowing mode on external screen if it's supported and enabled.
+ * - Enable system decorations and IME on external screen.
+ * - TODO: Show mouse pointer on external screen.
+ */
+ boolean mForceDesktopModeOnExternalDisplays;
- boolean mDisableTransitionAnimation = false;
+ boolean mDisableTransitionAnimation;
int getDragLayerLocked() {
return mPolicy.getWindowLayerFromTypeLw(TYPE_DRAG) * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
@@ -976,17 +986,21 @@
}
}, UserHandle.ALL, suspendPackagesFilter, null, null);
+ final ContentResolver resolver = context.getContentResolver();
// Get persisted window scale setting
- mWindowAnimationScaleSetting = Settings.Global.getFloat(context.getContentResolver(),
+ mWindowAnimationScaleSetting = Settings.Global.getFloat(resolver,
Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting);
- mTransitionAnimationScaleSetting = Settings.Global.getFloat(context.getContentResolver(),
+ mTransitionAnimationScaleSetting = Settings.Global.getFloat(resolver,
Settings.Global.TRANSITION_ANIMATION_SCALE,
context.getResources().getFloat(
R.dimen.config_appTransitionAnimationDurationScaleDefault));
- setAnimatorDurationScale(Settings.Global.getFloat(context.getContentResolver(),
+ setAnimatorDurationScale(Settings.Global.getFloat(resolver,
Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScaleSetting));
+ mForceDesktopModeOnExternalDisplays = Settings.Global.getInt(resolver,
+ DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, 0) != 0;
+
IntentFilter filter = new IntentFilter();
// Track changes to DevicePolicyManager state so we can enable/disable keyguard.
filter.addAction(ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
@@ -6406,6 +6420,12 @@
}
}
+ void setForceDesktopModeOnExternalDisplays(boolean forceDesktopModeOnExternalDisplays) {
+ synchronized (mWindowMap) {
+ mForceDesktopModeOnExternalDisplays = forceDesktopModeOnExternalDisplays;
+ }
+ }
+
public void setIsPc(boolean isPc) {
synchronized (mGlobalLock) {
mIsPc = isPc;
@@ -6584,10 +6604,10 @@
final long token = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
- final DisplayContent dc = getDisplayContentOrCreate(displayId, null);
+ final DisplayContent dc = getDisplayContentOrCreate(displayId, null /* token */);
if (dc == null) {
throw new IllegalArgumentException(
- "Trying to register a non existent display.");
+ "Trying to configure a non existent display.");
}
// We usually set the override info in DisplayManager so that we get consistent
// values when displays are changing. However, we don't do this for displays that