summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/hardware/display/DisplayManagerGlobal.java51
-rw-r--r--core/java/android/os/Handler.java36
-rw-r--r--core/java/android/view/Display.java18
-rw-r--r--core/java/android/view/DisplayInfo.java56
-rw-r--r--core/java/android/view/Surface.java46
5 files changed, 177 insertions, 30 deletions
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index 69c0319..4077964 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -42,6 +42,16 @@ public final class DisplayManagerGlobal {
private static final String TAG = "DisplayManager";
private static final boolean DEBUG = false;
+ // True if display info and display ids should be cached.
+ //
+ // FIXME: The cache is currently disabled because it's unclear whether we have the
+ // necessary guarantees that the caches will always be flushed before clients
+ // attempt to observe their new state. For example, depending on the order
+ // in which the binder transactions take place, we might have a problem where
+ // an application could start processing a configuration change due to a display
+ // orientation change before the display info cache has actually been invalidated.
+ private static final boolean USE_CACHE = false;
+
public static final int EVENT_DISPLAY_ADDED = 1;
public static final int EVENT_DISPLAY_CHANGED = 2;
public static final int EVENT_DISPLAY_REMOVED = 3;
@@ -91,21 +101,27 @@ public final class DisplayManagerGlobal {
public DisplayInfo getDisplayInfo(int displayId) {
try {
synchronized (mLock) {
- DisplayInfo info = mDisplayInfoCache.get(displayId);
- if (info != null) {
- return info;
+ DisplayInfo info;
+ if (USE_CACHE) {
+ info = mDisplayInfoCache.get(displayId);
+ if (info != null) {
+ return info;
+ }
}
info = mDm.getDisplayInfo(displayId);
if (info == null) {
return null;
}
+
+ if (USE_CACHE) {
+ mDisplayInfoCache.put(displayId, info);
+ }
+ registerCallbackIfNeededLocked();
+
if (DEBUG) {
Log.d(TAG, "getDisplayInfo: displayId=" + displayId + ", info=" + info);
}
-
- mDisplayInfoCache.put(displayId, info);
- registerCallbackIfNeededLocked();
return info;
}
} catch (RemoteException ex) {
@@ -122,11 +138,18 @@ public final class DisplayManagerGlobal {
public int[] getDisplayIds() {
try {
synchronized (mLock) {
- if (mDisplayIdCache == null) {
- mDisplayIdCache = mDm.getDisplayIds();
- registerCallbackIfNeededLocked();
+ if (USE_CACHE) {
+ if (mDisplayIdCache != null) {
+ return mDisplayIdCache;
+ }
+ }
+
+ int[] displayIds = mDm.getDisplayIds();
+ if (USE_CACHE) {
+ mDisplayIdCache = displayIds;
}
- return mDisplayIdCache;
+ registerCallbackIfNeededLocked();
+ return displayIds;
}
} catch (RemoteException ex) {
Log.e(TAG, "Could not get display ids from display manager.", ex);
@@ -215,10 +238,12 @@ public final class DisplayManagerGlobal {
private void handleDisplayEvent(int displayId, int event) {
synchronized (mLock) {
- mDisplayInfoCache.remove(displayId);
+ if (USE_CACHE) {
+ mDisplayInfoCache.remove(displayId);
- if (event == EVENT_DISPLAY_ADDED || event == EVENT_DISPLAY_REMOVED) {
- mDisplayIdCache = null;
+ if (event == EVENT_DISPLAY_ADDED || event == EVENT_DISPLAY_REMOVED) {
+ mDisplayIdCache = null;
+ }
}
final int numListeners = mDisplayListeners.size();
diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java
index 0f9be9c..94de448 100644
--- a/core/java/android/os/Handler.java
+++ b/core/java/android/os/Handler.java
@@ -431,7 +431,12 @@ public class Handler {
* set up a Handler thread and need to perform some initialization steps on
* it before continuing execution.
*
+ * If timeout occurs then this method returns <code>false</code> but the runnable
+ * will remain posted on the handler and may already be in progress or
+ * complete at a later time.
+ *
* @param r The Runnable that will be executed synchronously.
+ * @param timeout The timeout in milliseconds, or 0 to wait indefinitely.
*
* @return Returns true if the Runnable was successfully executed.
* Returns false on failure, usually because the
@@ -441,10 +446,13 @@ public class Handler {
* If we ever do make it part of the API, we might want to rename it to something
* less funny like runUnsafe().
*/
- public final boolean runWithScissors(final Runnable r) {
+ public final boolean runWithScissors(final Runnable r, long timeout) {
if (r == null) {
throw new IllegalArgumentException("runnable must not be null");
}
+ if (timeout < 0) {
+ throw new IllegalArgumentException("timeout must be non-negative");
+ }
if (Looper.myLooper() == mLooper) {
r.run();
@@ -452,7 +460,7 @@ public class Handler {
}
BlockingRunnable br = new BlockingRunnable(r);
- return br.postAndWait(this);
+ return br.postAndWait(this, timeout);
}
/**
@@ -743,16 +751,30 @@ public class Handler {
}
}
- public boolean postAndWait(Handler handler) {
+ public boolean postAndWait(Handler handler, long timeout) {
if (!handler.post(this)) {
return false;
}
synchronized (this) {
- while (!mDone) {
- try {
- wait();
- } catch (InterruptedException ex) {
+ if (timeout > 0) {
+ final long expirationTime = SystemClock.uptimeMillis() + timeout;
+ while (!mDone) {
+ long delay = expirationTime - SystemClock.uptimeMillis();
+ if (delay <= 0) {
+ return false; // timeout
+ }
+ try {
+ wait(delay);
+ } catch (InterruptedException ex) {
+ }
+ }
+ } else {
+ while (!mDone) {
+ try {
+ wait();
+ } catch (InterruptedException ex) {
+ }
}
}
}
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index ec635a2..8ac84f7 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -53,6 +53,8 @@ public final class Display {
private final DisplayManagerGlobal mGlobal;
private final int mDisplayId;
+ private final int mLayerStack;
+ private final String mName;
private final CompatibilityInfoHolder mCompatibilityInfo;
private DisplayInfo mDisplayInfo; // never null
@@ -90,6 +92,8 @@ public final class Display {
mGlobal = global;
mDisplayId = displayId;
mDisplayInfo = displayInfo;
+ mLayerStack = displayInfo.layerStack; // can never change as long as the display is valid
+ mName = displayInfo.name; // cannot change as long as the display is valid
mCompatibilityInfo = compatibilityInfo;
mIsValid = true;
}
@@ -146,13 +150,11 @@ public final class Display {
* Each display has its own independent layer stack upon which surfaces
* are placed to be managed by surface flinger.
*
- * @return The layer stack number.
+ * @return The display's layer stack number.
* @hide
*/
public int getLayerStack() {
- // Note: This is the current convention but there is no requirement that
- // the display id and layer stack id be the same.
- return mDisplayId;
+ return mLayerStack;
}
/**
@@ -166,6 +168,14 @@ public final class Display {
}
/**
+ * Gets the name of the display.
+ * @return The display's name.
+ */
+ public String getName() {
+ return mName;
+ }
+
+ /**
* Gets the size of the display, in pixels.
* <p>
* Note that this value should <em>not</em> be used for computing layouts,
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index 593e8c4..b728d71 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -21,12 +21,24 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.util.DisplayMetrics;
+import libcore.util.Objects;
+
/**
* Describes the characteristics of a particular logical display.
* @hide
*/
public final class DisplayInfo implements Parcelable {
/**
+ * The surface flinger layer stack associated with this logical display.
+ */
+ public int layerStack;
+
+ /**
+ * The human-readable name of the display.
+ */
+ public String name;
+
+ /**
* The width of the portion of the display that is available to applications, in pixels.
* Represents the size of the display minus any system decorations.
*/
@@ -147,11 +159,37 @@ public final class DisplayInfo implements Parcelable {
}
@Override
- public int describeContents() {
- return 0;
+ public boolean equals(Object o) {
+ return o instanceof DisplayInfo && equals((DisplayInfo)o);
+ }
+
+ public boolean equals(DisplayInfo other) {
+ return other != null
+ && layerStack == other.layerStack
+ && Objects.equal(name, other.name)
+ && appWidth == other.appWidth
+ && appHeight == other.appHeight
+ && smallestNominalAppWidth == other.smallestNominalAppWidth
+ && smallestNominalAppHeight == other.smallestNominalAppHeight
+ && largestNominalAppWidth == other.largestNominalAppWidth
+ && largestNominalAppHeight == other.largestNominalAppHeight
+ && logicalWidth == other.logicalWidth
+ && logicalHeight == other.logicalHeight
+ && rotation == other.rotation
+ && refreshRate == other.refreshRate
+ && logicalDensityDpi == other.logicalDensityDpi
+ && physicalXDpi == other.physicalXDpi
+ && physicalYDpi == other.physicalYDpi;
+ }
+
+ @Override
+ public int hashCode() {
+ return 0; // don't care
}
public void copyFrom(DisplayInfo other) {
+ layerStack = other.layerStack;
+ name = other.name;
appWidth = other.appWidth;
appHeight = other.appHeight;
smallestNominalAppWidth = other.smallestNominalAppWidth;
@@ -168,6 +206,8 @@ public final class DisplayInfo implements Parcelable {
}
public void readFromParcel(Parcel source) {
+ layerStack = source.readInt();
+ name = source.readString();
appWidth = source.readInt();
appHeight = source.readInt();
smallestNominalAppWidth = source.readInt();
@@ -185,6 +225,8 @@ public final class DisplayInfo implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(layerStack);
+ dest.writeString(name);
dest.writeInt(appWidth);
dest.writeInt(appHeight);
dest.writeInt(smallestNominalAppWidth);
@@ -200,6 +242,11 @@ public final class DisplayInfo implements Parcelable {
dest.writeFloat(physicalYDpi);
}
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
public void getAppMetrics(DisplayMetrics outMetrics, CompatibilityInfoHolder cih) {
getMetricsWithSize(outMetrics, cih, appWidth, appHeight);
}
@@ -231,13 +278,14 @@ public final class DisplayInfo implements Parcelable {
// For debugging purposes
@Override
public String toString() {
- return "app " + appWidth + " x " + appHeight
+ return "DisplayInfo{\"" + name + "\", app " + appWidth + " x " + appHeight
+ ", real " + logicalWidth + " x " + logicalHeight
+ ", largest app " + largestNominalAppWidth + " x " + largestNominalAppHeight
+ ", smallest app " + smallestNominalAppWidth + " x " + smallestNominalAppHeight
+ ", " + refreshRate + " fps"
+ ", rotation " + rotation
+ ", density " + logicalDensityDpi
- + ", " + physicalXDpi + " x " + physicalYDpi + " dpi";
+ + ", " + physicalXDpi + " x " + physicalYDpi + " dpi"
+ + ", layerStack " + layerStack + "}";
}
}
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index cf1767d..6616894 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -743,17 +743,59 @@ public class Surface implements Parcelable {
}
/**
- * Describes the properties of a physical display.
+ * Describes the properties of a physical display known to surface flinger.
* @hide
*/
public static final class PhysicalDisplayInfo {
- // TODO: redesign this
public int width;
public int height;
public float refreshRate;
public float density;
public float xDpi;
public float yDpi;
+
+ public PhysicalDisplayInfo() {
+ }
+
+ public PhysicalDisplayInfo(PhysicalDisplayInfo other) {
+ copyFrom(other);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return o instanceof PhysicalDisplayInfo && equals((PhysicalDisplayInfo)o);
+ }
+
+ public boolean equals(PhysicalDisplayInfo other) {
+ return other != null
+ && width == other.width
+ && height == other.height
+ && refreshRate == other.refreshRate
+ && density == other.density
+ && xDpi == other.xDpi
+ && yDpi == other.yDpi;
+ }
+
+ @Override
+ public int hashCode() {
+ return 0; // don't care
+ }
+
+ public void copyFrom(PhysicalDisplayInfo other) {
+ width = other.width;
+ height = other.height;
+ refreshRate = other.refreshRate;
+ density = other.density;
+ xDpi = other.xDpi;
+ yDpi = other.yDpi;
+ }
+
+ // For debugging purposes
+ @Override
+ public String toString() {
+ return "PhysicalDisplayInfo{" + width + " x " + height + ", " + refreshRate + " fps, "
+ + "density " + density + ", " + xDpi + " x " + yDpi + " dpi}";
+ }
}
/**