Skip to content

Commit d5ea3b4

Browse files
Jeff BrownAndroid (Google) Code Review
authored andcommitted
Merge "Add initial multi-display support." into jb-mr1-dev
2 parents 0552cbc + bd6e150 commit d5ea3b4

30 files changed

+1774
-457
lines changed

Android.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ LOCAL_SRC_FILES += \
115115
core/java/android/database/IContentObserver.aidl \
116116
core/java/android/hardware/ISerialManager.aidl \
117117
core/java/android/hardware/display/IDisplayManager.aidl \
118+
core/java/android/hardware/display/IDisplayManagerCallback.aidl \
118119
core/java/android/hardware/input/IInputManager.aidl \
119120
core/java/android/hardware/input/IInputDevicesChangedListener.aidl \
120121
core/java/android/hardware/usb/IUsbManager.aidl \

api/current.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9997,7 +9997,8 @@ package android.hardware {
99979997
package android.hardware.display {
99989998

99999999
public final class DisplayManager {
10000-
method public android.view.Display getDisplay(int, android.content.Context);
10000+
method public android.view.Display getDisplay(int);
10001+
method public android.view.Display[] getDisplays();
1000110002
method public void registerDisplayListener(android.hardware.display.DisplayManager.DisplayListener, android.os.Handler);
1000210003
method public void unregisterDisplayListener(android.hardware.display.DisplayManager.DisplayListener);
1000310004
}
@@ -23453,6 +23454,7 @@ package android.view {
2345323454
method public int getRotation();
2345423455
method public void getSize(android.graphics.Point);
2345523456
method public deprecated int getWidth();
23457+
method public boolean isValid();
2345623458
field public static final int DEFAULT_DISPLAY = 0; // 0x0
2345723459
}
2345823460

core/java/android/app/ActivityManager.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import android.graphics.Bitmap;
3232
import android.graphics.Point;
3333
import android.hardware.display.DisplayManager;
34+
import android.hardware.display.DisplayManagerGlobal;
3435
import android.os.Binder;
3536
import android.os.Bundle;
3637
import android.os.Debug;
@@ -376,7 +377,8 @@ static public boolean isHighEndGfx() {
376377
return true;
377378
}
378379

379-
Display display = DisplayManager.getInstance().getRealDisplay(Display.DEFAULT_DISPLAY);
380+
Display display = DisplayManagerGlobal.getInstance().getRealDisplay(
381+
Display.DEFAULT_DISPLAY);
380382
Point p = new Point();
381383
display.getRealSize(p);
382384
int pixels = p.x * p.y;

core/java/android/app/ActivityThread.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import android.graphics.Bitmap;
4444
import android.graphics.Canvas;
4545
import android.hardware.display.DisplayManager;
46+
import android.hardware.display.DisplayManagerGlobal;
4647
import android.net.IConnectivityManager;
4748
import android.net.Proxy;
4849
import android.net.ProxyProperties;
@@ -1557,7 +1558,7 @@ DisplayMetrics getDisplayMetricsLocked(CompatibilityInfo ci, boolean forceUpdate
15571558
return dm;
15581559
}
15591560

1560-
DisplayManager displayManager = DisplayManager.getInstance();
1561+
DisplayManagerGlobal displayManager = DisplayManagerGlobal.getInstance();
15611562
if (displayManager == null) {
15621563
// may be null early in system startup
15631564
dm = new DisplayMetrics();

core/java/android/app/ContextImpl.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -349,10 +349,11 @@ public Object createStaticService() {
349349
return InputManager.getInstance();
350350
}});
351351

352-
registerService(DISPLAY_SERVICE, new StaticServiceFetcher() {
353-
public Object createStaticService() {
354-
return DisplayManager.getInstance();
355-
}});
352+
registerService(DISPLAY_SERVICE, new ServiceFetcher() {
353+
@Override
354+
public Object createService(ContextImpl ctx) {
355+
return new DisplayManager(ctx.getOuterContext());
356+
}});
356357

357358
registerService(INPUT_METHOD_SERVICE, new ServiceFetcher() {
358359
public Object createService(ContextImpl ctx) {

core/java/android/hardware/display/DisplayManager.java

Lines changed: 57 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,12 @@
1818

1919
import android.content.Context;
2020
import android.os.Handler;
21-
import android.os.IBinder;
22-
import android.os.Looper;
23-
import android.os.Message;
24-
import android.os.RemoteException;
25-
import android.os.ServiceManager;
26-
import android.util.Log;
21+
import android.util.SparseArray;
2722
import android.view.CompatibilityInfoHolder;
2823
import android.view.Display;
29-
import android.view.DisplayInfo;
30-
31-
import java.util.ArrayList;
3224

3325
/**
34-
* Manages the properties, media routing and power state of attached displays.
26+
* Manages the properties of attached displays.
3527
* <p>
3628
* Get an instance of this class by calling
3729
* {@link android.content.Context#getSystemService(java.lang.String)
@@ -43,110 +35,79 @@ public final class DisplayManager {
4335
private static final String TAG = "DisplayManager";
4436
private static final boolean DEBUG = false;
4537

46-
private static final int MSG_DISPLAY_ADDED = 1;
47-
private static final int MSG_DISPLAY_REMOVED = 2;
48-
private static final int MSG_DISPLAY_CHANGED = 3;
49-
50-
private static DisplayManager sInstance;
51-
52-
private final IDisplayManager mDm;
53-
54-
// Guarded by mDisplayLock
55-
private final Object mDisplayLock = new Object();
56-
private final ArrayList<DisplayListenerDelegate> mDisplayListeners =
57-
new ArrayList<DisplayListenerDelegate>();
38+
private final Context mContext;
39+
private final DisplayManagerGlobal mGlobal;
5840

41+
private final Object mLock = new Object();
42+
private final SparseArray<Display> mDisplays = new SparseArray<Display>();
5943

60-
private DisplayManager(IDisplayManager dm) {
61-
mDm = dm;
44+
/** @hide */
45+
public DisplayManager(Context context) {
46+
mContext = context;
47+
mGlobal = DisplayManagerGlobal.getInstance();
6248
}
6349

6450
/**
65-
* Gets an instance of the display manager.
51+
* Gets information about a logical display.
6652
*
67-
* @return The display manager instance, may be null early in system startup
68-
* before the display manager has been fully initialized.
53+
* The display metrics may be adjusted to provide compatibility
54+
* for legacy applications.
6955
*
70-
* @hide
56+
* @param displayId The logical display id.
57+
* @return The display object, or null if there is no valid display with the given id.
7158
*/
72-
public static DisplayManager getInstance() {
73-
synchronized (DisplayManager.class) {
74-
if (sInstance == null) {
75-
IBinder b = ServiceManager.getService(Context.DISPLAY_SERVICE);
76-
if (b != null) {
77-
sInstance = new DisplayManager(IDisplayManager.Stub.asInterface(b));
78-
}
79-
}
80-
return sInstance;
59+
public Display getDisplay(int displayId) {
60+
synchronized (mLock) {
61+
return getOrCreateDisplayLocked(displayId, false /*assumeValid*/);
8162
}
8263
}
8364

8465
/**
85-
* Get information about a particular logical display.
66+
* Gets all currently valid logical displays.
8667
*
87-
* @param displayId The logical display id.
88-
* @param outInfo A structure to populate with the display info.
89-
* @return True if the logical display exists, false otherwise.
90-
* @hide
68+
* @return An array containing all displays.
9169
*/
92-
public boolean getDisplayInfo(int displayId, DisplayInfo outInfo) {
93-
try {
94-
return mDm.getDisplayInfo(displayId, outInfo);
95-
} catch (RemoteException ex) {
96-
Log.e(TAG, "Could not get display information from display manager.", ex);
97-
return false;
70+
public Display[] getDisplays() {
71+
int[] displayIds = mGlobal.getDisplayIds();
72+
int expectedCount = displayIds.length;
73+
Display[] displays = new Display[expectedCount];
74+
synchronized (mLock) {
75+
int actualCount = 0;
76+
for (int i = 0; i < expectedCount; i++) {
77+
Display display = getOrCreateDisplayLocked(displayIds[i], true /*assumeValid*/);
78+
if (display != null) {
79+
displays[actualCount++] = display;
80+
}
81+
}
82+
if (actualCount != expectedCount) {
83+
Display[] oldDisplays = displays;
84+
displays = new Display[actualCount];
85+
System.arraycopy(oldDisplays, 0, displays, 0, actualCount);
86+
}
9887
}
88+
return displays;
9989
}
10090

101-
/**
102-
* Gets information about a logical display.
103-
*
104-
* The display metrics may be adjusted to provide compatibility
105-
* for legacy applications.
106-
*
107-
* @param displayId The logical display id.
108-
* @param applicationContext The application context from which to obtain
109-
* compatible metrics.
110-
* @return The display object.
111-
*/
112-
public Display getDisplay(int displayId, Context applicationContext) {
113-
if (applicationContext == null) {
114-
throw new IllegalArgumentException("applicationContext must not be null");
91+
private Display getOrCreateDisplayLocked(int displayId, boolean assumeValid) {
92+
Display display = mDisplays.get(displayId);
93+
if (display == null) {
94+
display = mGlobal.getCompatibleDisplay(displayId,
95+
getCompatibilityInfoForDisplayLocked(displayId));
96+
if (display != null) {
97+
mDisplays.put(displayId, display);
98+
}
99+
} else if (!assumeValid && !display.isValid()) {
100+
display = null;
115101
}
102+
return display;
103+
}
116104

105+
private CompatibilityInfoHolder getCompatibilityInfoForDisplayLocked(int displayId) {
117106
CompatibilityInfoHolder cih = null;
118107
if (displayId == Display.DEFAULT_DISPLAY) {
119-
cih = applicationContext.getCompatibilityInfo();
108+
cih = mContext.getCompatibilityInfo();
120109
}
121-
return getCompatibleDisplay(displayId, cih);
122-
}
123-
124-
/**
125-
* Gets information about a logical display.
126-
*
127-
* The display metrics may be adjusted to provide compatibility
128-
* for legacy applications.
129-
*
130-
* @param displayId The logical display id.
131-
* @param cih The compatibility info, or null if none is required.
132-
* @return The display object.
133-
*
134-
* @hide
135-
*/
136-
public Display getCompatibleDisplay(int displayId, CompatibilityInfoHolder cih) {
137-
return new Display(displayId, cih);
138-
}
139-
140-
/**
141-
* Gets information about a logical display without applying any compatibility metrics.
142-
*
143-
* @param displayId The logical display id.
144-
* @return The display object.
145-
*
146-
* @hide
147-
*/
148-
public Display getRealDisplay(int displayId) {
149-
return getCompatibleDisplay(displayId, null);
110+
return cih;
150111
}
151112

152113
/**
@@ -160,16 +121,7 @@ public Display getRealDisplay(int displayId) {
160121
* @see #unregisterDisplayListener
161122
*/
162123
public void registerDisplayListener(DisplayListener listener, Handler handler) {
163-
if (listener == null) {
164-
throw new IllegalArgumentException("listener must not be null");
165-
}
166-
167-
synchronized (mDisplayLock) {
168-
int index = findDisplayListenerLocked(listener);
169-
if (index < 0) {
170-
mDisplayListeners.add(new DisplayListenerDelegate(listener, handler));
171-
}
172-
}
124+
mGlobal.registerDisplayListener(listener, handler);
173125
}
174126

175127
/**
@@ -180,28 +132,7 @@ public void registerDisplayListener(DisplayListener listener, Handler handler) {
180132
* @see #registerDisplayListener
181133
*/
182134
public void unregisterDisplayListener(DisplayListener listener) {
183-
if (listener == null) {
184-
throw new IllegalArgumentException("listener must not be null");
185-
}
186-
187-
synchronized (mDisplayLock) {
188-
int index = findDisplayListenerLocked(listener);
189-
if (index >= 0) {
190-
DisplayListenerDelegate d = mDisplayListeners.get(index);
191-
d.removeCallbacksAndMessages(null);
192-
mDisplayListeners.remove(index);
193-
}
194-
}
195-
}
196-
197-
private int findDisplayListenerLocked(DisplayListener listener) {
198-
final int numListeners = mDisplayListeners.size();
199-
for (int i = 0; i < numListeners; i++) {
200-
if (mDisplayListeners.get(i).mListener == listener) {
201-
return i;
202-
}
203-
}
204-
return -1;
135+
mGlobal.unregisterDisplayListener(listener);
205136
}
206137

207138
/**
@@ -210,7 +141,8 @@ private int findDisplayListenerLocked(DisplayListener listener) {
210141
public interface DisplayListener {
211142
/**
212143
* Called whenever a logical display has been added to the system.
213-
* Use {@link DisplayManager#getDisplay} to get more information about the display.
144+
* Use {@link DisplayManager#getDisplay} to get more information about
145+
* the display.
214146
*
215147
* @param displayId The id of the logical display that was added.
216148
*/
@@ -230,28 +162,4 @@ public interface DisplayListener {
230162
*/
231163
void onDisplayChanged(int displayId);
232164
}
233-
234-
private static final class DisplayListenerDelegate extends Handler {
235-
public final DisplayListener mListener;
236-
237-
public DisplayListenerDelegate(DisplayListener listener, Handler handler) {
238-
super(handler != null ? handler.getLooper() : Looper.myLooper());
239-
mListener = listener;
240-
}
241-
242-
@Override
243-
public void handleMessage(Message msg) {
244-
switch (msg.what) {
245-
case MSG_DISPLAY_ADDED:
246-
mListener.onDisplayAdded(msg.arg1);
247-
break;
248-
case MSG_DISPLAY_REMOVED:
249-
mListener.onDisplayRemoved(msg.arg1);
250-
break;
251-
case MSG_DISPLAY_CHANGED:
252-
mListener.onDisplayChanged(msg.arg1);
253-
break;
254-
}
255-
}
256-
}
257165
}

0 commit comments

Comments
 (0)