Skip to content

Commit f83ec83

Browse files
Jeff BrownAndroid (Google) Code Review
authored andcommitted
Merge "More improvements to the display manager." into jb-mr1-dev
2 parents 3b9a416 + 4ed8fe7 commit f83ec83

24 files changed

+1733
-789
lines changed

api/current.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23473,6 +23473,7 @@ package android.view {
2347323473
method public int getDisplayId();
2347423474
method public deprecated int getHeight();
2347523475
method public void getMetrics(android.util.DisplayMetrics);
23476+
method public java.lang.String getName();
2347623477
method public deprecated int getOrientation();
2347723478
method public deprecated int getPixelFormat();
2347823479
method public void getRealMetrics(android.util.DisplayMetrics);

core/java/android/hardware/display/DisplayManagerGlobal.java

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,16 @@ public final class DisplayManagerGlobal {
4242
private static final String TAG = "DisplayManager";
4343
private static final boolean DEBUG = false;
4444

45+
// True if display info and display ids should be cached.
46+
//
47+
// FIXME: The cache is currently disabled because it's unclear whether we have the
48+
// necessary guarantees that the caches will always be flushed before clients
49+
// attempt to observe their new state. For example, depending on the order
50+
// in which the binder transactions take place, we might have a problem where
51+
// an application could start processing a configuration change due to a display
52+
// orientation change before the display info cache has actually been invalidated.
53+
private static final boolean USE_CACHE = false;
54+
4555
public static final int EVENT_DISPLAY_ADDED = 1;
4656
public static final int EVENT_DISPLAY_CHANGED = 2;
4757
public static final int EVENT_DISPLAY_REMOVED = 3;
@@ -91,21 +101,27 @@ public static DisplayManagerGlobal getInstance() {
91101
public DisplayInfo getDisplayInfo(int displayId) {
92102
try {
93103
synchronized (mLock) {
94-
DisplayInfo info = mDisplayInfoCache.get(displayId);
95-
if (info != null) {
96-
return info;
104+
DisplayInfo info;
105+
if (USE_CACHE) {
106+
info = mDisplayInfoCache.get(displayId);
107+
if (info != null) {
108+
return info;
109+
}
97110
}
98111

99112
info = mDm.getDisplayInfo(displayId);
100113
if (info == null) {
101114
return null;
102115
}
116+
117+
if (USE_CACHE) {
118+
mDisplayInfoCache.put(displayId, info);
119+
}
120+
registerCallbackIfNeededLocked();
121+
103122
if (DEBUG) {
104123
Log.d(TAG, "getDisplayInfo: displayId=" + displayId + ", info=" + info);
105124
}
106-
107-
mDisplayInfoCache.put(displayId, info);
108-
registerCallbackIfNeededLocked();
109125
return info;
110126
}
111127
} catch (RemoteException ex) {
@@ -122,11 +138,18 @@ public DisplayInfo getDisplayInfo(int displayId) {
122138
public int[] getDisplayIds() {
123139
try {
124140
synchronized (mLock) {
125-
if (mDisplayIdCache == null) {
126-
mDisplayIdCache = mDm.getDisplayIds();
127-
registerCallbackIfNeededLocked();
141+
if (USE_CACHE) {
142+
if (mDisplayIdCache != null) {
143+
return mDisplayIdCache;
144+
}
145+
}
146+
147+
int[] displayIds = mDm.getDisplayIds();
148+
if (USE_CACHE) {
149+
mDisplayIdCache = displayIds;
128150
}
129-
return mDisplayIdCache;
151+
registerCallbackIfNeededLocked();
152+
return displayIds;
130153
}
131154
} catch (RemoteException ex) {
132155
Log.e(TAG, "Could not get display ids from display manager.", ex);
@@ -215,10 +238,12 @@ private void registerCallbackIfNeededLocked() {
215238

216239
private void handleDisplayEvent(int displayId, int event) {
217240
synchronized (mLock) {
218-
mDisplayInfoCache.remove(displayId);
241+
if (USE_CACHE) {
242+
mDisplayInfoCache.remove(displayId);
219243

220-
if (event == EVENT_DISPLAY_ADDED || event == EVENT_DISPLAY_REMOVED) {
221-
mDisplayIdCache = null;
244+
if (event == EVENT_DISPLAY_ADDED || event == EVENT_DISPLAY_REMOVED) {
245+
mDisplayIdCache = null;
246+
}
222247
}
223248

224249
final int numListeners = mDisplayListeners.size();

core/java/android/os/Handler.java

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,12 @@ public final boolean postAtFrontOfQueue(Runnable r)
431431
* set up a Handler thread and need to perform some initialization steps on
432432
* it before continuing execution.
433433
*
434+
* If timeout occurs then this method returns <code>false</code> but the runnable
435+
* will remain posted on the handler and may already be in progress or
436+
* complete at a later time.
437+
*
434438
* @param r The Runnable that will be executed synchronously.
439+
* @param timeout The timeout in milliseconds, or 0 to wait indefinitely.
435440
*
436441
* @return Returns true if the Runnable was successfully executed.
437442
* Returns false on failure, usually because the
@@ -441,18 +446,21 @@ public final boolean postAtFrontOfQueue(Runnable r)
441446
* If we ever do make it part of the API, we might want to rename it to something
442447
* less funny like runUnsafe().
443448
*/
444-
public final boolean runWithScissors(final Runnable r) {
449+
public final boolean runWithScissors(final Runnable r, long timeout) {
445450
if (r == null) {
446451
throw new IllegalArgumentException("runnable must not be null");
447452
}
453+
if (timeout < 0) {
454+
throw new IllegalArgumentException("timeout must be non-negative");
455+
}
448456

449457
if (Looper.myLooper() == mLooper) {
450458
r.run();
451459
return true;
452460
}
453461

454462
BlockingRunnable br = new BlockingRunnable(r);
455-
return br.postAndWait(this);
463+
return br.postAndWait(this, timeout);
456464
}
457465

458466
/**
@@ -743,16 +751,30 @@ public void run() {
743751
}
744752
}
745753

746-
public boolean postAndWait(Handler handler) {
754+
public boolean postAndWait(Handler handler, long timeout) {
747755
if (!handler.post(this)) {
748756
return false;
749757
}
750758

751759
synchronized (this) {
752-
while (!mDone) {
753-
try {
754-
wait();
755-
} catch (InterruptedException ex) {
760+
if (timeout > 0) {
761+
final long expirationTime = SystemClock.uptimeMillis() + timeout;
762+
while (!mDone) {
763+
long delay = expirationTime - SystemClock.uptimeMillis();
764+
if (delay <= 0) {
765+
return false; // timeout
766+
}
767+
try {
768+
wait(delay);
769+
} catch (InterruptedException ex) {
770+
}
771+
}
772+
} else {
773+
while (!mDone) {
774+
try {
775+
wait();
776+
} catch (InterruptedException ex) {
777+
}
756778
}
757779
}
758780
}

core/java/android/view/Display.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ public final class Display {
5353

5454
private final DisplayManagerGlobal mGlobal;
5555
private final int mDisplayId;
56+
private final int mLayerStack;
57+
private final String mName;
5658
private final CompatibilityInfoHolder mCompatibilityInfo;
5759

5860
private DisplayInfo mDisplayInfo; // never null
@@ -90,6 +92,8 @@ public Display(DisplayManagerGlobal global,
9092
mGlobal = global;
9193
mDisplayId = displayId;
9294
mDisplayInfo = displayInfo;
95+
mLayerStack = displayInfo.layerStack; // can never change as long as the display is valid
96+
mName = displayInfo.name; // cannot change as long as the display is valid
9397
mCompatibilityInfo = compatibilityInfo;
9498
mIsValid = true;
9599
}
@@ -146,13 +150,11 @@ public boolean getDisplayInfo(DisplayInfo outDisplayInfo) {
146150
* Each display has its own independent layer stack upon which surfaces
147151
* are placed to be managed by surface flinger.
148152
*
149-
* @return The layer stack number.
153+
* @return The display's layer stack number.
150154
* @hide
151155
*/
152156
public int getLayerStack() {
153-
// Note: This is the current convention but there is no requirement that
154-
// the display id and layer stack id be the same.
155-
return mDisplayId;
157+
return mLayerStack;
156158
}
157159

158160
/**
@@ -165,6 +167,14 @@ public CompatibilityInfoHolder getCompatibilityInfo() {
165167
return mCompatibilityInfo;
166168
}
167169

170+
/**
171+
* Gets the name of the display.
172+
* @return The display's name.
173+
*/
174+
public String getName() {
175+
return mName;
176+
}
177+
168178
/**
169179
* Gets the size of the display, in pixels.
170180
* <p>

core/java/android/view/DisplayInfo.java

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,23 @@
2121
import android.os.Parcelable;
2222
import android.util.DisplayMetrics;
2323

24+
import libcore.util.Objects;
25+
2426
/**
2527
* Describes the characteristics of a particular logical display.
2628
* @hide
2729
*/
2830
public final class DisplayInfo implements Parcelable {
31+
/**
32+
* The surface flinger layer stack associated with this logical display.
33+
*/
34+
public int layerStack;
35+
36+
/**
37+
* The human-readable name of the display.
38+
*/
39+
public String name;
40+
2941
/**
3042
* The width of the portion of the display that is available to applications, in pixels.
3143
* Represents the size of the display minus any system decorations.
@@ -147,11 +159,37 @@ private DisplayInfo(Parcel source) {
147159
}
148160

149161
@Override
150-
public int describeContents() {
151-
return 0;
162+
public boolean equals(Object o) {
163+
return o instanceof DisplayInfo && equals((DisplayInfo)o);
164+
}
165+
166+
public boolean equals(DisplayInfo other) {
167+
return other != null
168+
&& layerStack == other.layerStack
169+
&& Objects.equal(name, other.name)
170+
&& appWidth == other.appWidth
171+
&& appHeight == other.appHeight
172+
&& smallestNominalAppWidth == other.smallestNominalAppWidth
173+
&& smallestNominalAppHeight == other.smallestNominalAppHeight
174+
&& largestNominalAppWidth == other.largestNominalAppWidth
175+
&& largestNominalAppHeight == other.largestNominalAppHeight
176+
&& logicalWidth == other.logicalWidth
177+
&& logicalHeight == other.logicalHeight
178+
&& rotation == other.rotation
179+
&& refreshRate == other.refreshRate
180+
&& logicalDensityDpi == other.logicalDensityDpi
181+
&& physicalXDpi == other.physicalXDpi
182+
&& physicalYDpi == other.physicalYDpi;
183+
}
184+
185+
@Override
186+
public int hashCode() {
187+
return 0; // don't care
152188
}
153189

154190
public void copyFrom(DisplayInfo other) {
191+
layerStack = other.layerStack;
192+
name = other.name;
155193
appWidth = other.appWidth;
156194
appHeight = other.appHeight;
157195
smallestNominalAppWidth = other.smallestNominalAppWidth;
@@ -168,6 +206,8 @@ public void copyFrom(DisplayInfo other) {
168206
}
169207

170208
public void readFromParcel(Parcel source) {
209+
layerStack = source.readInt();
210+
name = source.readString();
171211
appWidth = source.readInt();
172212
appHeight = source.readInt();
173213
smallestNominalAppWidth = source.readInt();
@@ -185,6 +225,8 @@ public void readFromParcel(Parcel source) {
185225

186226
@Override
187227
public void writeToParcel(Parcel dest, int flags) {
228+
dest.writeInt(layerStack);
229+
dest.writeString(name);
188230
dest.writeInt(appWidth);
189231
dest.writeInt(appHeight);
190232
dest.writeInt(smallestNominalAppWidth);
@@ -200,6 +242,11 @@ public void writeToParcel(Parcel dest, int flags) {
200242
dest.writeFloat(physicalYDpi);
201243
}
202244

245+
@Override
246+
public int describeContents() {
247+
return 0;
248+
}
249+
203250
public void getAppMetrics(DisplayMetrics outMetrics, CompatibilityInfoHolder cih) {
204251
getMetricsWithSize(outMetrics, cih, appWidth, appHeight);
205252
}
@@ -231,13 +278,14 @@ private void getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfoHold
231278
// For debugging purposes
232279
@Override
233280
public String toString() {
234-
return "app " + appWidth + " x " + appHeight
281+
return "DisplayInfo{\"" + name + "\", app " + appWidth + " x " + appHeight
235282
+ ", real " + logicalWidth + " x " + logicalHeight
236283
+ ", largest app " + largestNominalAppWidth + " x " + largestNominalAppHeight
237284
+ ", smallest app " + smallestNominalAppWidth + " x " + smallestNominalAppHeight
238285
+ ", " + refreshRate + " fps"
239286
+ ", rotation " + rotation
240287
+ ", density " + logicalDensityDpi
241-
+ ", " + physicalXDpi + " x " + physicalYDpi + " dpi";
288+
+ ", " + physicalXDpi + " x " + physicalYDpi + " dpi"
289+
+ ", layerStack " + layerStack + "}";
242290
}
243291
}

core/java/android/view/Surface.java

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -743,17 +743,59 @@ public OutOfResourcesException(String name) {
743743
}
744744

745745
/**
746-
* Describes the properties of a physical display.
746+
* Describes the properties of a physical display known to surface flinger.
747747
* @hide
748748
*/
749749
public static final class PhysicalDisplayInfo {
750-
// TODO: redesign this
751750
public int width;
752751
public int height;
753752
public float refreshRate;
754753
public float density;
755754
public float xDpi;
756755
public float yDpi;
756+
757+
public PhysicalDisplayInfo() {
758+
}
759+
760+
public PhysicalDisplayInfo(PhysicalDisplayInfo other) {
761+
copyFrom(other);
762+
}
763+
764+
@Override
765+
public boolean equals(Object o) {
766+
return o instanceof PhysicalDisplayInfo && equals((PhysicalDisplayInfo)o);
767+
}
768+
769+
public boolean equals(PhysicalDisplayInfo other) {
770+
return other != null
771+
&& width == other.width
772+
&& height == other.height
773+
&& refreshRate == other.refreshRate
774+
&& density == other.density
775+
&& xDpi == other.xDpi
776+
&& yDpi == other.yDpi;
777+
}
778+
779+
@Override
780+
public int hashCode() {
781+
return 0; // don't care
782+
}
783+
784+
public void copyFrom(PhysicalDisplayInfo other) {
785+
width = other.width;
786+
height = other.height;
787+
refreshRate = other.refreshRate;
788+
density = other.density;
789+
xDpi = other.xDpi;
790+
yDpi = other.yDpi;
791+
}
792+
793+
// For debugging purposes
794+
@Override
795+
public String toString() {
796+
return "PhysicalDisplayInfo{" + width + " x " + height + ", " + refreshRate + " fps, "
797+
+ "density " + density + ", " + xDpi + " x " + yDpi + " dpi}";
798+
}
757799
}
758800

759801
/**

0 commit comments

Comments
 (0)