summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/res/res/values/config.xml5
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--services/core/java/com/android/server/display/LogicalDisplay.java13
-rw-r--r--services/core/java/com/android/server/policy/DisplayFoldController.java114
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java15
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerInternal.java16
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java10
-rw-r--r--services/core/java/com/android/server/wm/utils/WmDisplayCutout.java5
8 files changed, 174 insertions, 5 deletions
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index c05795de4751..1db8135d31c7 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -861,6 +861,11 @@
The default is false. -->
<bool name="config_lidControlsSleep">false</bool>
+ <!-- Indicate whether closing the lid causes the device to enter the folded state which means
+ to get a smaller screen and opening the lid causes the device to enter the unfolded state
+ which means to get a larger screen. -->
+ <bool name="config_lidControlsDisplayFold">false</bool>
+
<!-- Desk dock behavior -->
<!-- The number of degrees to rotate the display when the device is in a desk dock.
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index f79e22d1f94e..9f15321f1653 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3511,6 +3511,7 @@
<java-symbol type="integer" name="config_defaultRingVibrationIntensity" />
<java-symbol type="bool" name="config_maskMainBuiltInDisplayCutout" />
+ <java-symbol type="bool" name="config_lidControlsDisplayFold" />
<java-symbol type="array" name="config_disableApksUnlessMatchedSku_apk_list" />
<java-symbol type="array" name="config_disableApkUnlessMatchedSku_skus_list" />
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index 95665989cc34..7414e55ed94a 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -418,10 +418,15 @@ final class LogicalDisplay {
// Now add back the offset for the masked area.
mTempDisplayRect.offset(maskingInsets.left, maskingInsets.top);
- mTempDisplayRect.left += mDisplayOffsetX;
- mTempDisplayRect.right += mDisplayOffsetX;
- mTempDisplayRect.top += mDisplayOffsetY;
- mTempDisplayRect.bottom += mDisplayOffsetY;
+ if (orientation == Surface.ROTATION_0) {
+ mTempDisplayRect.offset(mDisplayOffsetX, mDisplayOffsetY);
+ } else if (orientation == Surface.ROTATION_90) {
+ mTempDisplayRect.offset(mDisplayOffsetY, -mDisplayOffsetX);
+ } else if (orientation == Surface.ROTATION_180) {
+ mTempDisplayRect.offset(-mDisplayOffsetX, -mDisplayOffsetY);
+ } else { // Surface.ROTATION_270
+ mTempDisplayRect.offset(-mDisplayOffsetY, mDisplayOffsetX);
+ }
device.setProjectionLocked(t, orientation, mTempLayerStackRect, mTempDisplayRect);
}
diff --git a/services/core/java/com/android/server/policy/DisplayFoldController.java b/services/core/java/com/android/server/policy/DisplayFoldController.java
new file mode 100644
index 000000000000..71d6dfc9c598
--- /dev/null
+++ b/services/core/java/com/android/server/policy/DisplayFoldController.java
@@ -0,0 +1,114 @@
+/*
+ * 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.policy;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.hardware.display.DisplayManagerInternal;
+import android.view.DisplayInfo;
+
+import com.android.server.LocalServices;
+import com.android.server.wm.WindowManagerInternal;
+
+/**
+ * Controls the behavior of foldable devices whose screen can literally bend and fold.
+ */
+class DisplayFoldController {
+
+ private static final String TAG = "DisplayFoldController";
+ private final WindowManagerInternal mWindowManagerInternal;
+ private final DisplayManagerInternal mDisplayManagerInternal;
+ private final int mDisplayId;
+
+ /** The display area while device is folded. */
+ private final Rect mFoldedArea;
+
+ private final DisplayInfo mNonOverrideDisplayInfo = new DisplayInfo();
+ private Boolean mFolded;
+
+ DisplayFoldController(WindowManagerInternal windowManagerInternal,
+ DisplayManagerInternal displayManagerInternal, int displayId, Rect foldedArea) {
+ mWindowManagerInternal = windowManagerInternal;
+ mDisplayManagerInternal = displayManagerInternal;
+ mDisplayId = displayId;
+ mFoldedArea = new Rect(foldedArea);
+ }
+
+ void setDeviceFolded(boolean folded) {
+ if (mFolded != null && mFolded == folded) {
+ return;
+ }
+ if (folded) {
+ mDisplayManagerInternal.getNonOverrideDisplayInfo(mDisplayId, mNonOverrideDisplayInfo);
+ final int dx = (mNonOverrideDisplayInfo.logicalWidth - mFoldedArea.width()) / 2
+ - mFoldedArea.left;
+ final int dy = (mNonOverrideDisplayInfo.logicalHeight - mFoldedArea.height()) / 2
+ - mFoldedArea.top;
+
+ mWindowManagerInternal.setForcedDisplaySize(mDisplayId, mFoldedArea.width(),
+ mFoldedArea.height());
+ mDisplayManagerInternal.setDisplayOffsets(mDisplayId, -dx, -dy);
+ } else {
+ mWindowManagerInternal.clearForcedDisplaySize(mDisplayId);
+ mDisplayManagerInternal.setDisplayOffsets(mDisplayId, 0, 0);
+ }
+ mFolded = folded;
+ }
+
+ /**
+ * Only used for the case that persist.debug.force_foldable is set.
+ * This is using proximity sensor to simulate the fold state switch.
+ */
+ static DisplayFoldController createWithProxSensor(Context context, int displayId) {
+ final SensorManager sensorManager = context.getSystemService(SensorManager.class);
+ final Sensor proxSensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
+ if (proxSensor == null) {
+ return null;
+ }
+
+ final DisplayFoldController result = create(displayId);
+ sensorManager.registerListener(new SensorEventListener() {
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ result.setDeviceFolded(event.values[0] < 1f);
+ }
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {
+ // Ignore.
+ }
+ }, proxSensor, SensorManager.SENSOR_DELAY_NORMAL);
+
+ return result;
+ }
+
+ static DisplayFoldController create(int displayId) {
+ final DisplayManagerInternal displayService =
+ LocalServices.getService(DisplayManagerInternal.class);
+ final DisplayInfo displayInfo = new DisplayInfo();
+ displayService.getNonOverrideDisplayInfo(displayId, displayInfo);
+ final Rect foldedArea = new Rect(0, displayInfo.logicalHeight / 2,
+ displayInfo.logicalWidth, displayInfo.logicalHeight);
+
+ return new DisplayFoldController(LocalServices.getService(WindowManagerInternal.class),
+ displayService, displayId, foldedArea);
+ }
+}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 13c4d886e7b1..25cfc7202bbb 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -374,6 +374,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
SearchManager mSearchManager;
AccessibilityManager mAccessibilityManager;
BurnInProtectionHelper mBurnInProtectionHelper;
+ private DisplayFoldController mDisplayFoldController;
AppOpsManager mAppOpsManager;
private ScreenshotHelper mScreenshotHelper;
private boolean mHasFeatureWatch;
@@ -471,6 +472,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
int mLidNavigationAccessibility;
boolean mLidControlsScreenLock;
boolean mLidControlsSleep;
+ private boolean mLidControlsDisplayFold;
int mShortPressOnPowerBehavior;
int mLongPressOnPowerBehavior;
int mVeryLongPressOnPowerBehavior;
@@ -1794,6 +1796,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
com.android.internal.R.bool.config_lidControlsScreenLock);
mLidControlsSleep = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_lidControlsSleep);
+ mLidControlsDisplayFold = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_lidControlsDisplayFold);
mAllowTheaterModeWakeFromKey = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_allowTheaterModeWakeFromKey);
@@ -1850,6 +1854,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
readConfigurationDependentBehaviors();
+ if (mLidControlsDisplayFold) {
+ mDisplayFoldController = DisplayFoldController.create(DEFAULT_DISPLAY);
+ } else if (SystemProperties.getBoolean("persist.debug.force_foldable", false)) {
+ mDisplayFoldController = DisplayFoldController.createWithProxSensor(context,
+ DEFAULT_DISPLAY);
+ }
+
mAccessibilityManager = (AccessibilityManager) context.getSystemService(
Context.ACCESSIBILITY_SERVICE);
@@ -4972,7 +4983,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private void applyLidSwitchState() {
final int lidState = mDefaultDisplayPolicy.getLidState();
- if (lidState == LID_CLOSED && mLidControlsSleep) {
+ if (mLidControlsDisplayFold && mDisplayFoldController != null) {
+ mDisplayFoldController.setDeviceFolded(lidState == LID_CLOSED);
+ } else if (lidState == LID_CLOSED && mLidControlsSleep) {
goToSleep(SystemClock.uptimeMillis(), PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH,
PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
} else if (lidState == LID_CLOSED && mLidControlsScreenLock) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index e204697e46cf..33e46f4af301 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -313,6 +313,22 @@ public abstract class WindowManagerInternal {
public abstract void waitForAllWindowsDrawn(Runnable callback, long timeout);
/**
+ * Overrides the display size.
+ *
+ * @param displayId The display to override the display size.
+ * @param width The width to override.
+ * @param height The height to override.
+ */
+ public abstract void setForcedDisplaySize(int displayId, int width, int height);
+
+ /**
+ * Recover the display size to real display size.
+ *
+ * @param displayId The display to recover the display size.
+ */
+ public abstract void clearForcedDisplaySize(int displayId);
+
+ /**
* Adds a window token for a given window type.
*
* @param token The token to add.
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index e6581df233ef..12b858c81ca0 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -6937,6 +6937,16 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
+ public void setForcedDisplaySize(int displayId, int width, int height) {
+ WindowManagerService.this.setForcedDisplaySize(displayId, width, height);
+ }
+
+ @Override
+ public void clearForcedDisplaySize(int displayId) {
+ WindowManagerService.this.clearForcedDisplaySize(displayId);
+ }
+
+ @Override
public void addWindowToken(IBinder token, int type, int displayId) {
WindowManagerService.this.addWindowToken(token, type, displayId);
}
diff --git a/services/core/java/com/android/server/wm/utils/WmDisplayCutout.java b/services/core/java/com/android/server/wm/utils/WmDisplayCutout.java
index ea3f758fb209..98bad93e09e2 100644
--- a/services/core/java/com/android/server/wm/utils/WmDisplayCutout.java
+++ b/services/core/java/com/android/server/wm/utils/WmDisplayCutout.java
@@ -170,4 +170,9 @@ public class WmDisplayCutout {
public int hashCode() {
return Objects.hash(mInner, mFrameSize);
}
+
+ @Override
+ public String toString() {
+ return "WmDisplayCutout{" + mInner + ", mFrameSize=" + mFrameSize + '}';
+ }
}