Merge "Add new system API for stable display size" into oc-mr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
c217d744b4
@@ -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";
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
* <color-mode>0</color-mode>
|
||||
* </display>
|
||||
* </display-states>
|
||||
* <stable-device-values>
|
||||
* <stable-display-height>1920<stable-display-height>
|
||||
* <stable-display-width>1080<stable-display-width>
|
||||
* </stable-device-values>
|
||||
* </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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user