Add new system API for stable display size
Fixes: 34388294
Test: manual
Change-Id: Ie380230bbd82370f507161b4cdb6f0d100b09f11
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 8269042..d0a1d9e 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -31,6 +31,8 @@
import android.annotation.NonNull;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.graphics.Point;
import android.hardware.SensorManager;
import android.hardware.display.DisplayManagerGlobal;
import android.hardware.display.DisplayManagerInternal;
@@ -211,6 +213,12 @@
// The virtual display adapter, or null if not registered.
private VirtualDisplayAdapter mVirtualDisplayAdapter;
+ // The stable device screen height and width. These are not tied to a specific display, even
+ // the default display, because they need to be stable over the course of the device's entire
+ // life, even if the default display changes (e.g. a new monitor is plugged into a PC-like
+ // device).
+ private Point mStableDisplaySize = new Point();
+
// Viewports of the default display and the display that should receive touch
// input from an external source. Used by the input system.
private final DisplayViewport mDefaultViewport = new DisplayViewport();
@@ -284,7 +292,10 @@
// adapter is up so that we have it's configuration. We could load it lazily, but since
// we're going to have to read it in eventually we may as well do it here rather than after
// we've waited for the display to register itself with us.
- mPersistentDataStore.loadIfNeeded();
+ synchronized(mSyncRoot) {
+ mPersistentDataStore.loadIfNeeded();
+ loadStableDisplayValuesLocked();
+ }
mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS);
publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),
@@ -346,6 +357,34 @@
return mHandler;
}
+ private void loadStableDisplayValuesLocked() {
+ final Point size = mPersistentDataStore.getStableDisplaySize();
+ if (size.x > 0 && size.y > 0) {
+ // Just set these values directly so we don't write the display persistent data again
+ // unnecessarily
+ mStableDisplaySize.set(size.x, size.y);
+ } else {
+ final Resources res = mContext.getResources();
+ final int width = res.getInteger(
+ com.android.internal.R.integer.config_stableDeviceDisplayWidth);
+ final int height = res.getInteger(
+ com.android.internal.R.integer.config_stableDeviceDisplayHeight);
+ if (width > 0 && height > 0) {
+ setStableDisplaySizeLocked(width, height);
+ }
+ }
+ }
+
+ private Point getStableDisplaySizeInternal() {
+ Point r = new Point();
+ synchronized (mSyncRoot) {
+ if (mStableDisplaySize.x > 0 && mStableDisplaySize.y > 0) {
+ r.set(mStableDisplaySize.x, mStableDisplaySize.y);
+ }
+ }
+ return r;
+ }
+
private void registerDisplayTransactionListenerInternal(
DisplayTransactionListener listener) {
// List is self-synchronized copy-on-write.
@@ -770,18 +809,6 @@
if (work != null) {
work.run();
}
- if (display != null && display.getPrimaryDisplayDeviceLocked() == device) {
- int colorMode = mPersistentDataStore.getColorMode(device);
- if (colorMode == Display.COLOR_MODE_INVALID) {
- if ((device.getDisplayDeviceInfoLocked().flags
- & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) {
- colorMode = mDefaultDisplayDefaultColorMode;
- } else {
- colorMode = Display.COLOR_MODE_DEFAULT;
- }
- }
- display.setRequestedColorModeLocked(colorMode);
- }
scheduleTraversalLocked(false);
}
@@ -886,6 +913,11 @@
return null;
}
+ configureColorModeLocked(display, device);
+ if (isDefault) {
+ recordStableDisplayStatsIfNeededLocked(display);
+ }
+
mLogicalDisplays.put(displayId, display);
// Wake up waitForDefaultDisplay.
@@ -907,6 +939,40 @@
return displayId;
}
+ private void configureColorModeLocked(LogicalDisplay display, DisplayDevice device) {
+ if (display.getPrimaryDisplayDeviceLocked() == device) {
+ int colorMode = mPersistentDataStore.getColorMode(device);
+ if (colorMode == Display.COLOR_MODE_INVALID) {
+ if ((device.getDisplayDeviceInfoLocked().flags
+ & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) {
+ colorMode = mDefaultDisplayDefaultColorMode;
+ } else {
+ colorMode = Display.COLOR_MODE_DEFAULT;
+ }
+ }
+ display.setRequestedColorModeLocked(colorMode);
+ }
+ }
+
+ // If we've never recorded stable device stats for this device before and they aren't
+ // explicitly configured, go ahead and record the stable device stats now based on the status
+ // of the default display at first boot.
+ private void recordStableDisplayStatsIfNeededLocked(LogicalDisplay d) {
+ if (mStableDisplaySize.x <= 0 && mStableDisplaySize.y <= 0) {
+ DisplayInfo info = d.getDisplayInfoLocked();
+ setStableDisplaySizeLocked(info.getNaturalWidth(), info.getNaturalHeight());
+ }
+ }
+
+ private void setStableDisplaySizeLocked(int width, int height) {
+ mStableDisplaySize = new Point(width, height);
+ try {
+ mPersistentDataStore.setStableDisplaySize(mStableDisplaySize);
+ } finally {
+ mPersistentDataStore.saveIfNeeded();
+ }
+ }
+
// Updates all existing logical displays given the current set of display devices.
// Removes invalid logical displays.
// Sends notifications if needed.
@@ -1166,6 +1232,8 @@
pw.println(" mDefaultDisplayDefaultColorMode=" + mDefaultDisplayDefaultColorMode);
pw.println(" mSingleDisplayDemoMode=" + mSingleDisplayDemoMode);
pw.println(" mWifiDisplayScanRequestCount=" + mWifiDisplayScanRequestCount);
+ pw.println(" mStableDisplaySize=" + mStableDisplaySize);
+
IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
ipw.increaseIndent();
@@ -1378,6 +1446,19 @@
}
}
+ /**
+ * Returns the stable device display size, in pixels.
+ */
+ @Override // Binder call
+ public Point getStableDisplaySize() {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ return getStableDisplaySizeInternal();
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
@Override // Binder call
public void registerCallback(IDisplayManagerCallback callback) {
if (callback == null) {