1818
1919import android .content .Context ;
2020import 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 ;
2722import android .view .CompatibilityInfoHolder ;
2823import 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