Merge "Add new system API for stable display size" into oc-mr1-dev

This commit is contained in:
TreeHugger Robot
2017-08-25 20:56:57 +00:00
committed by Android (Google) Code Review
8 changed files with 224 additions and 14 deletions

View File

@@ -16561,6 +16561,7 @@ package android.hardware.display {
method public android.view.Display getDisplay(int);
method public android.view.Display[] getDisplays();
method public android.view.Display[] getDisplays(java.lang.String);
method public android.graphics.Point getStableDisplaySize();
method public void registerDisplayListener(android.hardware.display.DisplayManager.DisplayListener, android.os.Handler);
method public void unregisterDisplayListener(android.hardware.display.DisplayManager.DisplayListener);
field public static final java.lang.String DISPLAY_CATEGORY_PRESENTATION = "android.hardware.display.category.PRESENTATION";

View File

@@ -18,8 +18,10 @@ package android.hardware.display;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.Context;
import android.graphics.Point;
import android.media.projection.MediaProjection;
import android.os.Handler;
import android.util.SparseArray;
@@ -585,6 +587,20 @@ public final class DisplayManager {
name, width, height, densityDpi, surface, flags, callback, handler, uniqueId);
}
/**
* Gets the stable device display size, in pixels.
*
* This should really only be used for things like server-side filtering of available
* applications. Most applications don't need the level of stability guaranteed by this and
* should instead query either the size of the display they're currently running on or the
* size of the default display.
* @hide
*/
@SystemApi
public Point getStableDisplaySize() {
return mGlobal.getStableDisplaySize();
}
/**
* Listens for changes in available display devices.
*/

View File

@@ -18,6 +18,7 @@ package android.hardware.display;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Point;
import android.hardware.display.DisplayManager.DisplayListener;
import android.media.projection.IMediaProjection;
import android.media.projection.MediaProjection;
@@ -444,6 +445,17 @@ public final class DisplayManagerGlobal {
}
}
/**
* Gets the stable device display size, in pixels.
*/
public Point getStableDisplaySize() {
try {
return mDm.getStableDisplaySize();
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
private final class DisplayManagerCallback extends IDisplayManagerCallback.Stub {
@Override
public void onDisplayEvent(int displayId, int event) {

View File

@@ -16,6 +16,7 @@
package android.hardware.display;
import android.graphics.Point;
import android.hardware.display.IDisplayManagerCallback;
import android.hardware.display.IVirtualDisplayCallback;
import android.hardware.display.WifiDisplay;
@@ -77,4 +78,7 @@ interface IDisplayManager {
// No permissions required but must be same Uid as the creator.
void releaseVirtualDisplay(in IVirtualDisplayCallback token);
// Get a stable metric for the device's display size. No permissions required.
Point getStableDisplaySize();
}

View File

@@ -3044,4 +3044,10 @@
<!-- Allow SystemUI to show the shutdown dialog -->
<bool name="config_showSysuiShutdown">true</bool>
<!-- The stable device width and height in pixels. If these aren't set to a positive number
then the device will use the width and height of the default display the first time it's
booted. -->
<integer name="config_stableDeviceDisplayWidth">-1</integer>
<integer name="config_stableDeviceDisplayHeight">-1</integer>
</resources>

View File

@@ -3069,4 +3069,7 @@
<java-symbol type="layout" name="shutdown_dialog" />
<java-symbol type="dimen" name="chooser_service_spacing" />
<java-symbol type="bool" name="config_showSysuiShutdown" />
<java-symbol type="integer" name="config_stableDeviceDisplayWidth" />
<java-symbol type="integer" name="config_stableDeviceDisplayHeight" />
</resources>

View File

@@ -31,6 +31,8 @@ import android.Manifest;
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 @@ public final class DisplayManagerService extends SystemService {
// 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 @@ public final class DisplayManagerService extends SystemService {
// 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 @@ public final class DisplayManagerService extends SystemService {
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 @@ public final class DisplayManagerService extends SystemService {
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 @@ public final class DisplayManagerService extends SystemService {
return null;
}
configureColorModeLocked(display, device);
if (isDefault) {
recordStableDisplayStatsIfNeededLocked(display);
}
mLogicalDisplays.put(displayId, display);
// Wake up waitForDefaultDisplay.
@@ -907,6 +939,40 @@ public final class DisplayManagerService extends SystemService {
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 @@ public final class DisplayManagerService extends SystemService {
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 @@ public final class DisplayManagerService extends SystemService {
}
}
/**
* 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) {

View File

@@ -23,6 +23,7 @@ import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
import android.graphics.Point;
import android.hardware.display.WifiDisplay;
import android.util.AtomicFile;
import android.util.Slog;
@@ -60,6 +61,10 @@ import libcore.util.Objects;
* &lt;color-mode>0&lt;/color-mode>
* &lt;/display>
* &lt;/display-states>
* &lt;stable-device-values>
* &lt;stable-display-height>1920&lt;stable-display-height>
* &lt;stable-display-width>1080&lt;stable-display-width>
* &lt;/stable-device-values>
* &lt;/display-manager-state>
* </code>
*
@@ -75,6 +80,9 @@ final class PersistentDataStore {
private final HashMap<String, DisplayState> mDisplayStates =
new HashMap<String, DisplayState>();
// Display values which should be stable across the device's lifetime.
private final StableDeviceValues mStableDeviceValues = new StableDeviceValues();
// The atomic file used to safely read or write the file.
private final AtomicFile mAtomicFile;
@@ -162,6 +170,7 @@ final class PersistentDataStore {
}
public boolean forgetWifiDisplay(String deviceAddress) {
loadIfNeeded();
int index = findRememberedWifiDisplay(deviceAddress);
if (index >= 0) {
mRememberedWifiDisplays.remove(index);
@@ -204,6 +213,18 @@ final class PersistentDataStore {
return false;
}
public Point getStableDisplaySize() {
loadIfNeeded();
return mStableDeviceValues.getDisplaySize();
}
public void setStableDisplaySize(Point size) {
loadIfNeeded();
if (mStableDeviceValues.setDisplaySize(size)) {
setDirty();
}
}
private DisplayState getDisplayState(String uniqueId, boolean createIfAbsent) {
loadIfNeeded();
DisplayState state = mDisplayStates.get(uniqueId);
@@ -290,6 +311,9 @@ final class PersistentDataStore {
if (parser.getName().equals("display-states")) {
loadDisplaysFromXml(parser);
}
if (parser.getName().equals("stable-device-values")) {
mStableDeviceValues.loadFromXml(parser);
}
}
}
@@ -363,6 +387,9 @@ final class PersistentDataStore {
serializer.endTag(null, "display");
}
serializer.endTag(null, "display-states");
serializer.startTag(null, "stable-device-values");
mStableDeviceValues.saveToXml(serializer);
serializer.endTag(null, "stable-device-values");
serializer.endTag(null, "display-manager-state");
serializer.endDocument();
}
@@ -382,6 +409,8 @@ final class PersistentDataStore {
pw.println(" " + i++ + ": " + entry.getKey());
entry.getValue().dump(pw, " ");
}
pw.println(" StableDeviceValues:");
mStableDeviceValues.dump(pw, " ");
}
private static final class DisplayState {
@@ -417,8 +446,66 @@ final class PersistentDataStore {
serializer.endTag(null, "color-mode");
}
private void dump(final PrintWriter pw, final String prefix) {
public void dump(final PrintWriter pw, final String prefix) {
pw.println(prefix + "ColorMode=" + mColorMode);
}
}
private static final class StableDeviceValues {
private int mWidth;
private int mHeight;
private Point getDisplaySize() {
return new Point(mWidth, mHeight);
}
public boolean setDisplaySize(Point r) {
if (mWidth != r.x || mHeight != r.y) {
mWidth = r.x;
mHeight = r.y;
return true;
}
return false;
}
public void loadFromXml(XmlPullParser parser) throws IOException, XmlPullParserException {
final int outerDepth = parser.getDepth();
while (XmlUtils.nextElementWithin(parser, outerDepth)) {
switch (parser.getName()) {
case "stable-display-width":
mWidth = loadIntValue(parser);
break;
case "stable-display-height":
mHeight = loadIntValue(parser);
break;
}
}
}
private static int loadIntValue(XmlPullParser parser)
throws IOException, XmlPullParserException {
try {
String value = parser.nextText();
return Integer.parseInt(value);
} catch (NumberFormatException nfe) {
return 0;
}
}
public void saveToXml(XmlSerializer serializer) throws IOException {
if (mWidth > 0 && mHeight > 0) {
serializer.startTag(null, "stable-display-width");
serializer.text(Integer.toString(mWidth));
serializer.endTag(null, "stable-display-width");
serializer.startTag(null, "stable-display-height");
serializer.text(Integer.toString(mHeight));
serializer.endTag(null, "stable-display-height");
}
}
public void dump(final PrintWriter pw, final String prefix) {
pw.println(prefix + "StableDisplayWidth=" + mWidth);
pw.println(prefix + "StableDisplayHeight=" + mHeight);
}
}
}