blob: a8a4eb67f5809a8c587b1dd447c2083e701295c6 [file] [log] [blame]
Jeff Brownbd6e1502012-08-28 03:27:37 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.hardware.display;
18
19import android.content.Context;
Bryce Lee609bf652017-02-09 16:50:13 -080020import android.content.res.Resources;
Michael Wrighteedcbf12017-08-16 23:14:54 +010021import android.graphics.Point;
Jeff Brownbd6e1502012-08-28 03:27:37 -070022import android.hardware.display.DisplayManager.DisplayListener;
Michael Wrightc39d47a2014-07-08 18:07:36 -070023import android.media.projection.IMediaProjection;
Santos Cordonee8931e2017-04-05 10:31:15 -070024import android.media.projection.MediaProjection;
Jeff Brownbd6e1502012-08-28 03:27:37 -070025import android.os.Handler;
26import android.os.IBinder;
27import android.os.Looper;
28import android.os.Message;
29import android.os.RemoteException;
30import android.os.ServiceManager;
Jeff Browna506a6e2013-06-04 00:02:38 -070031import android.text.TextUtils;
Jeff Brownbd6e1502012-08-28 03:27:37 -070032import android.util.Log;
33import android.util.SparseArray;
Jeff Brownbd6e1502012-08-28 03:27:37 -070034import android.view.Display;
Santos Cordonee8931e2017-04-05 10:31:15 -070035import android.view.DisplayAdjustments;
Jeff Brownbd6e1502012-08-28 03:27:37 -070036import android.view.DisplayInfo;
Jeff Browna506a6e2013-06-04 00:02:38 -070037import android.view.Surface;
Jeff Brownbd6e1502012-08-28 03:27:37 -070038
39import java.util.ArrayList;
40
41/**
42 * Manager communication with the display manager service on behalf of
43 * an application process. You're probably looking for {@link DisplayManager}.
44 *
45 * @hide
46 */
47public final class DisplayManagerGlobal {
48 private static final String TAG = "DisplayManager";
49 private static final boolean DEBUG = false;
50
Jeff Brown4ed8fe72012-08-30 18:18:29 -070051 // True if display info and display ids should be cached.
52 //
53 // FIXME: The cache is currently disabled because it's unclear whether we have the
54 // necessary guarantees that the caches will always be flushed before clients
55 // attempt to observe their new state. For example, depending on the order
56 // in which the binder transactions take place, we might have a problem where
57 // an application could start processing a configuration change due to a display
58 // orientation change before the display info cache has actually been invalidated.
59 private static final boolean USE_CACHE = false;
60
Jeff Brownbd6e1502012-08-28 03:27:37 -070061 public static final int EVENT_DISPLAY_ADDED = 1;
62 public static final int EVENT_DISPLAY_CHANGED = 2;
63 public static final int EVENT_DISPLAY_REMOVED = 3;
64
65 private static DisplayManagerGlobal sInstance;
66
67 private final Object mLock = new Object();
68
69 private final IDisplayManager mDm;
70
71 private DisplayManagerCallback mCallback;
72 private final ArrayList<DisplayListenerDelegate> mDisplayListeners =
73 new ArrayList<DisplayListenerDelegate>();
74
75 private final SparseArray<DisplayInfo> mDisplayInfoCache = new SparseArray<DisplayInfo>();
76 private int[] mDisplayIdCache;
77
Jeff Brownce468a32013-11-21 16:42:03 -080078 private int mWifiDisplayScanNestCount;
79
Jeff Brownbd6e1502012-08-28 03:27:37 -070080 private DisplayManagerGlobal(IDisplayManager dm) {
81 mDm = dm;
82 }
83
84 /**
85 * Gets an instance of the display manager global singleton.
86 *
87 * @return The display manager instance, may be null early in system startup
88 * before the display manager has been fully initialized.
89 */
90 public static DisplayManagerGlobal getInstance() {
91 synchronized (DisplayManagerGlobal.class) {
92 if (sInstance == null) {
93 IBinder b = ServiceManager.getService(Context.DISPLAY_SERVICE);
94 if (b != null) {
95 sInstance = new DisplayManagerGlobal(IDisplayManager.Stub.asInterface(b));
96 }
97 }
98 return sInstance;
99 }
100 }
101
102 /**
103 * Get information about a particular logical display.
104 *
105 * @param displayId The logical display id.
106 * @return Information about the specified display, or null if it does not exist.
107 * This object belongs to an internal cache and should be treated as if it were immutable.
108 */
109 public DisplayInfo getDisplayInfo(int displayId) {
110 try {
111 synchronized (mLock) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700112 DisplayInfo info;
113 if (USE_CACHE) {
114 info = mDisplayInfoCache.get(displayId);
115 if (info != null) {
116 return info;
117 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700118 }
119
120 info = mDm.getDisplayInfo(displayId);
121 if (info == null) {
122 return null;
123 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700124
125 if (USE_CACHE) {
126 mDisplayInfoCache.put(displayId, info);
127 }
128 registerCallbackIfNeededLocked();
129
Jeff Brownbd6e1502012-08-28 03:27:37 -0700130 if (DEBUG) {
131 Log.d(TAG, "getDisplayInfo: displayId=" + displayId + ", info=" + info);
132 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700133 return info;
134 }
135 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700136 throw ex.rethrowFromSystemServer();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700137 }
138 }
139
140 /**
141 * Gets all currently valid logical display ids.
142 *
143 * @return An array containing all display ids.
144 */
145 public int[] getDisplayIds() {
146 try {
147 synchronized (mLock) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700148 if (USE_CACHE) {
149 if (mDisplayIdCache != null) {
150 return mDisplayIdCache;
151 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700152 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700153
154 int[] displayIds = mDm.getDisplayIds();
155 if (USE_CACHE) {
156 mDisplayIdCache = displayIds;
157 }
158 registerCallbackIfNeededLocked();
159 return displayIds;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700160 }
161 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700162 throw ex.rethrowFromSystemServer();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700163 }
164 }
165
166 /**
167 * Gets information about a logical display.
168 *
169 * The display metrics may be adjusted to provide compatibility
Craig Mautner48d0d182013-06-11 07:53:06 -0700170 * for legacy applications or limited screen areas.
Jeff Brownbd6e1502012-08-28 03:27:37 -0700171 *
172 * @param displayId The logical display id.
Craig Mautner48d0d182013-06-11 07:53:06 -0700173 * @param daj The compatibility info and activityToken.
Jeff Brownbd6e1502012-08-28 03:27:37 -0700174 * @return The display object, or null if there is no display with the given id.
175 */
Craig Mautner48d0d182013-06-11 07:53:06 -0700176 public Display getCompatibleDisplay(int displayId, DisplayAdjustments daj) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700177 DisplayInfo displayInfo = getDisplayInfo(displayId);
178 if (displayInfo == null) {
179 return null;
180 }
Craig Mautner48d0d182013-06-11 07:53:06 -0700181 return new Display(this, displayId, displayInfo, daj);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700182 }
183
184 /**
Bryce Lee609bf652017-02-09 16:50:13 -0800185 * Gets information about a logical display.
186 *
187 * The display metrics may be adjusted to provide compatibility
188 * for legacy applications or limited screen areas.
189 *
190 * @param displayId The logical display id.
191 * @param resources Resources providing compatibility info.
192 * @return The display object, or null if there is no display with the given id.
193 */
194 public Display getCompatibleDisplay(int displayId, Resources resources) {
195 DisplayInfo displayInfo = getDisplayInfo(displayId);
196 if (displayInfo == null) {
197 return null;
198 }
199 return new Display(this, displayId, displayInfo, resources);
200 }
201
202 /**
Jeff Brownbd6e1502012-08-28 03:27:37 -0700203 * Gets information about a logical display without applying any compatibility metrics.
204 *
205 * @param displayId The logical display id.
206 * @return The display object, or null if there is no display with the given id.
207 */
208 public Display getRealDisplay(int displayId) {
Craig Mautner48d0d182013-06-11 07:53:06 -0700209 return getCompatibleDisplay(displayId, DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
210 }
211
Jeff Brownbd6e1502012-08-28 03:27:37 -0700212 public void registerDisplayListener(DisplayListener listener, Handler handler) {
213 if (listener == null) {
214 throw new IllegalArgumentException("listener must not be null");
215 }
216
217 synchronized (mLock) {
218 int index = findDisplayListenerLocked(listener);
219 if (index < 0) {
220 mDisplayListeners.add(new DisplayListenerDelegate(listener, handler));
221 registerCallbackIfNeededLocked();
222 }
223 }
224 }
225
226 public void unregisterDisplayListener(DisplayListener listener) {
227 if (listener == null) {
228 throw new IllegalArgumentException("listener must not be null");
229 }
230
231 synchronized (mLock) {
232 int index = findDisplayListenerLocked(listener);
233 if (index >= 0) {
234 DisplayListenerDelegate d = mDisplayListeners.get(index);
235 d.clearEvents();
236 mDisplayListeners.remove(index);
237 }
238 }
239 }
240
241 private int findDisplayListenerLocked(DisplayListener listener) {
242 final int numListeners = mDisplayListeners.size();
243 for (int i = 0; i < numListeners; i++) {
244 if (mDisplayListeners.get(i).mListener == listener) {
245 return i;
246 }
247 }
248 return -1;
249 }
250
251 private void registerCallbackIfNeededLocked() {
252 if (mCallback == null) {
253 mCallback = new DisplayManagerCallback();
254 try {
255 mDm.registerCallback(mCallback);
256 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700257 throw ex.rethrowFromSystemServer();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700258 }
259 }
260 }
261
262 private void handleDisplayEvent(int displayId, int event) {
263 synchronized (mLock) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700264 if (USE_CACHE) {
265 mDisplayInfoCache.remove(displayId);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700266
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700267 if (event == EVENT_DISPLAY_ADDED || event == EVENT_DISPLAY_REMOVED) {
268 mDisplayIdCache = null;
269 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700270 }
271
272 final int numListeners = mDisplayListeners.size();
273 for (int i = 0; i < numListeners; i++) {
274 mDisplayListeners.get(i).sendDisplayEvent(displayId, event);
275 }
276 }
277 }
278
Jeff Brownce468a32013-11-21 16:42:03 -0800279 public void startWifiDisplayScan() {
280 synchronized (mLock) {
281 if (mWifiDisplayScanNestCount++ == 0) {
282 registerCallbackIfNeededLocked();
283 try {
284 mDm.startWifiDisplayScan();
285 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700286 throw ex.rethrowFromSystemServer();
Jeff Brownce468a32013-11-21 16:42:03 -0800287 }
288 }
289 }
290 }
291
292 public void stopWifiDisplayScan() {
293 synchronized (mLock) {
294 if (--mWifiDisplayScanNestCount == 0) {
295 try {
296 mDm.stopWifiDisplayScan();
297 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700298 throw ex.rethrowFromSystemServer();
Jeff Brownce468a32013-11-21 16:42:03 -0800299 }
300 } else if (mWifiDisplayScanNestCount < 0) {
301 Log.wtf(TAG, "Wifi display scan nest count became negative: "
302 + mWifiDisplayScanNestCount);
303 mWifiDisplayScanNestCount = 0;
304 }
Jeff Browne08ae382012-09-07 20:36:36 -0700305 }
306 }
307
308 public void connectWifiDisplay(String deviceAddress) {
309 if (deviceAddress == null) {
310 throw new IllegalArgumentException("deviceAddress must not be null");
311 }
312
313 try {
314 mDm.connectWifiDisplay(deviceAddress);
315 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700316 throw ex.rethrowFromSystemServer();
Jeff Browne08ae382012-09-07 20:36:36 -0700317 }
318 }
319
Chong Zhang1f3ecaa2013-05-03 15:55:36 -0700320 public void pauseWifiDisplay() {
321 try {
322 mDm.pauseWifiDisplay();
323 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700324 throw ex.rethrowFromSystemServer();
Chong Zhang1f3ecaa2013-05-03 15:55:36 -0700325 }
326 }
327
328 public void resumeWifiDisplay() {
329 try {
330 mDm.resumeWifiDisplay();
331 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700332 throw ex.rethrowFromSystemServer();
Chong Zhang1f3ecaa2013-05-03 15:55:36 -0700333 }
334 }
335
Jeff Browne08ae382012-09-07 20:36:36 -0700336 public void disconnectWifiDisplay() {
337 try {
338 mDm.disconnectWifiDisplay();
339 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700340 throw ex.rethrowFromSystemServer();
Jeff Browne08ae382012-09-07 20:36:36 -0700341 }
342 }
343
Jeff Brown89d55462012-09-19 11:33:42 -0700344 public void renameWifiDisplay(String deviceAddress, String alias) {
345 if (deviceAddress == null) {
346 throw new IllegalArgumentException("deviceAddress must not be null");
347 }
348
349 try {
350 mDm.renameWifiDisplay(deviceAddress, alias);
351 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700352 throw ex.rethrowFromSystemServer();
Jeff Brown89d55462012-09-19 11:33:42 -0700353 }
354 }
355
356 public void forgetWifiDisplay(String deviceAddress) {
357 if (deviceAddress == null) {
358 throw new IllegalArgumentException("deviceAddress must not be null");
359 }
360
361 try {
362 mDm.forgetWifiDisplay(deviceAddress);
363 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700364 throw ex.rethrowFromSystemServer();
Jeff Brown89d55462012-09-19 11:33:42 -0700365 }
366 }
367
Jeff Browne08ae382012-09-07 20:36:36 -0700368 public WifiDisplayStatus getWifiDisplayStatus() {
369 try {
370 return mDm.getWifiDisplayStatus();
371 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700372 throw ex.rethrowFromSystemServer();
Jeff Browne08ae382012-09-07 20:36:36 -0700373 }
374 }
375
Michael Wright1c9977b2016-07-12 13:30:10 -0700376 public void requestColorMode(int displayId, int colorMode) {
Michael Wright58e829f2015-09-15 00:13:26 +0100377 try {
Michael Wright1c9977b2016-07-12 13:30:10 -0700378 mDm.requestColorMode(displayId, colorMode);
Michael Wright58e829f2015-09-15 00:13:26 +0100379 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700380 throw ex.rethrowFromSystemServer();
Michael Wright58e829f2015-09-15 00:13:26 +0100381 }
382 }
383
Michael Wrightc39d47a2014-07-08 18:07:36 -0700384 public VirtualDisplay createVirtualDisplay(Context context, MediaProjection projection,
385 String name, int width, int height, int densityDpi, Surface surface, int flags,
Santos Cordonee8931e2017-04-05 10:31:15 -0700386 VirtualDisplay.Callback callback, Handler handler, String uniqueId) {
Jeff Browna506a6e2013-06-04 00:02:38 -0700387 if (TextUtils.isEmpty(name)) {
388 throw new IllegalArgumentException("name must be non-null and non-empty");
389 }
390 if (width <= 0 || height <= 0 || densityDpi <= 0) {
391 throw new IllegalArgumentException("width, height, and densityDpi must be "
392 + "greater than 0");
393 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700394
Michael Wright75ee9fc2014-09-01 19:55:22 -0700395 VirtualDisplayCallback callbackWrapper = new VirtualDisplayCallback(callback, handler);
Michael Wrightc39d47a2014-07-08 18:07:36 -0700396 IMediaProjection projectionToken = projection != null ? projection.getProjection() : null;
Jeff Browna506a6e2013-06-04 00:02:38 -0700397 int displayId;
398 try {
Michael Wrightc39d47a2014-07-08 18:07:36 -0700399 displayId = mDm.createVirtualDisplay(callbackWrapper, projectionToken,
Santos Cordonee8931e2017-04-05 10:31:15 -0700400 context.getPackageName(), name, width, height, densityDpi, surface, flags,
401 uniqueId);
Jeff Browna506a6e2013-06-04 00:02:38 -0700402 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700403 throw ex.rethrowFromSystemServer();
Jeff Browna506a6e2013-06-04 00:02:38 -0700404 }
405 if (displayId < 0) {
Jeff Brown7d00aff2013-08-02 19:03:49 -0700406 Log.e(TAG, "Could not create virtual display: " + name);
Jeff Browna506a6e2013-06-04 00:02:38 -0700407 return null;
408 }
409 Display display = getRealDisplay(displayId);
410 if (display == null) {
411 Log.wtf(TAG, "Could not obtain display info for newly created "
Jeff Brown7d00aff2013-08-02 19:03:49 -0700412 + "virtual display: " + name);
Jeff Browna506a6e2013-06-04 00:02:38 -0700413 try {
Michael Wrightc39d47a2014-07-08 18:07:36 -0700414 mDm.releaseVirtualDisplay(callbackWrapper);
Jeff Browna506a6e2013-06-04 00:02:38 -0700415 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700416 throw ex.rethrowFromSystemServer();
Jeff Browna506a6e2013-06-04 00:02:38 -0700417 }
418 return null;
419 }
Michael Wrightc39d47a2014-07-08 18:07:36 -0700420 return new VirtualDisplay(this, display, callbackWrapper, surface);
Jeff Brown92207df2014-04-16 13:16:07 -0700421 }
422
Michael Wright75ee9fc2014-09-01 19:55:22 -0700423 public void setVirtualDisplaySurface(IVirtualDisplayCallback token, Surface surface) {
Jeff Brown92207df2014-04-16 13:16:07 -0700424 try {
425 mDm.setVirtualDisplaySurface(token, surface);
426 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700427 throw ex.rethrowFromSystemServer();
Jeff Brown92207df2014-04-16 13:16:07 -0700428 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700429 }
430
Michael Wright75ee9fc2014-09-01 19:55:22 -0700431 public void resizeVirtualDisplay(IVirtualDisplayCallback token,
Michael Wright01e840f2014-06-26 16:03:25 -0700432 int width, int height, int densityDpi) {
433 try {
434 mDm.resizeVirtualDisplay(token, width, height, densityDpi);
435 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700436 throw ex.rethrowFromSystemServer();
Michael Wright01e840f2014-06-26 16:03:25 -0700437 }
438 }
439
Michael Wright75ee9fc2014-09-01 19:55:22 -0700440 public void releaseVirtualDisplay(IVirtualDisplayCallback token) {
Jeff Browna506a6e2013-06-04 00:02:38 -0700441 try {
442 mDm.releaseVirtualDisplay(token);
443 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700444 throw ex.rethrowFromSystemServer();
Jeff Browna506a6e2013-06-04 00:02:38 -0700445 }
446 }
447
Michael Wrighteedcbf12017-08-16 23:14:54 +0100448 /**
449 * Gets the stable device display size, in pixels.
450 */
451 public Point getStableDisplaySize() {
452 try {
453 return mDm.getStableDisplaySize();
454 } catch (RemoteException ex) {
455 throw ex.rethrowFromSystemServer();
456 }
457 }
458
Jeff Brownbd6e1502012-08-28 03:27:37 -0700459 private final class DisplayManagerCallback extends IDisplayManagerCallback.Stub {
460 @Override
461 public void onDisplayEvent(int displayId, int event) {
462 if (DEBUG) {
463 Log.d(TAG, "onDisplayEvent: displayId=" + displayId + ", event=" + event);
464 }
465 handleDisplayEvent(displayId, event);
466 }
467 }
468
469 private static final class DisplayListenerDelegate extends Handler {
470 public final DisplayListener mListener;
471
472 public DisplayListenerDelegate(DisplayListener listener, Handler handler) {
473 super(handler != null ? handler.getLooper() : Looper.myLooper(), null, true /*async*/);
474 mListener = listener;
475 }
476
477 public void sendDisplayEvent(int displayId, int event) {
478 Message msg = obtainMessage(event, displayId, 0);
479 sendMessage(msg);
480 }
481
482 public void clearEvents() {
483 removeCallbacksAndMessages(null);
484 }
485
486 @Override
487 public void handleMessage(Message msg) {
488 switch (msg.what) {
489 case EVENT_DISPLAY_ADDED:
490 mListener.onDisplayAdded(msg.arg1);
491 break;
492 case EVENT_DISPLAY_CHANGED:
493 mListener.onDisplayChanged(msg.arg1);
494 break;
495 case EVENT_DISPLAY_REMOVED:
496 mListener.onDisplayRemoved(msg.arg1);
497 break;
498 }
499 }
500 }
Michael Wrightc39d47a2014-07-08 18:07:36 -0700501
Michael Wright75ee9fc2014-09-01 19:55:22 -0700502 private final static class VirtualDisplayCallback extends IVirtualDisplayCallback.Stub {
503 private VirtualDisplayCallbackDelegate mDelegate;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700504
Michael Wright75ee9fc2014-09-01 19:55:22 -0700505 public VirtualDisplayCallback(VirtualDisplay.Callback callback, Handler handler) {
506 if (callback != null) {
507 mDelegate = new VirtualDisplayCallbackDelegate(callback, handler);
Craig Mautner3d0c57a2014-07-21 14:18:29 -0700508 }
Michael Wrightc39d47a2014-07-08 18:07:36 -0700509 }
510
511 @Override // Binder call
Michael Wright75ee9fc2014-09-01 19:55:22 -0700512 public void onPaused() {
Craig Mautner3d0c57a2014-07-21 14:18:29 -0700513 if (mDelegate != null) {
Michael Wright75ee9fc2014-09-01 19:55:22 -0700514 mDelegate.sendEmptyMessage(VirtualDisplayCallbackDelegate.MSG_DISPLAY_PAUSED);
Craig Mautner3d0c57a2014-07-21 14:18:29 -0700515 }
Michael Wrightc39d47a2014-07-08 18:07:36 -0700516 }
517
518 @Override // Binder call
Michael Wright75ee9fc2014-09-01 19:55:22 -0700519 public void onResumed() {
Craig Mautner3d0c57a2014-07-21 14:18:29 -0700520 if (mDelegate != null) {
Michael Wright75ee9fc2014-09-01 19:55:22 -0700521 mDelegate.sendEmptyMessage(VirtualDisplayCallbackDelegate.MSG_DISPLAY_RESUMED);
Craig Mautner3d0c57a2014-07-21 14:18:29 -0700522 }
Michael Wrightc39d47a2014-07-08 18:07:36 -0700523 }
524
525 @Override // Binder call
Michael Wright75ee9fc2014-09-01 19:55:22 -0700526 public void onStopped() {
Craig Mautner3d0c57a2014-07-21 14:18:29 -0700527 if (mDelegate != null) {
Michael Wright75ee9fc2014-09-01 19:55:22 -0700528 mDelegate.sendEmptyMessage(VirtualDisplayCallbackDelegate.MSG_DISPLAY_STOPPED);
Craig Mautner3d0c57a2014-07-21 14:18:29 -0700529 }
Michael Wrightc39d47a2014-07-08 18:07:36 -0700530 }
531 }
532
Michael Wright75ee9fc2014-09-01 19:55:22 -0700533 private final static class VirtualDisplayCallbackDelegate extends Handler {
Michael Wrightc39d47a2014-07-08 18:07:36 -0700534 public static final int MSG_DISPLAY_PAUSED = 0;
535 public static final int MSG_DISPLAY_RESUMED = 1;
536 public static final int MSG_DISPLAY_STOPPED = 2;
537
Michael Wright75ee9fc2014-09-01 19:55:22 -0700538 private final VirtualDisplay.Callback mCallback;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700539
Michael Wright75ee9fc2014-09-01 19:55:22 -0700540 public VirtualDisplayCallbackDelegate(VirtualDisplay.Callback callback,
Michael Wrightc39d47a2014-07-08 18:07:36 -0700541 Handler handler) {
542 super(handler != null ? handler.getLooper() : Looper.myLooper(), null, true /*async*/);
Michael Wright75ee9fc2014-09-01 19:55:22 -0700543 mCallback = callback;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700544 }
545
546 @Override
547 public void handleMessage(Message msg) {
Michael Wrightc39d47a2014-07-08 18:07:36 -0700548 switch (msg.what) {
549 case MSG_DISPLAY_PAUSED:
Michael Wright75ee9fc2014-09-01 19:55:22 -0700550 mCallback.onPaused();
Michael Wrightc39d47a2014-07-08 18:07:36 -0700551 break;
552 case MSG_DISPLAY_RESUMED:
Michael Wright75ee9fc2014-09-01 19:55:22 -0700553 mCallback.onResumed();
Michael Wrightc39d47a2014-07-08 18:07:36 -0700554 break;
555 case MSG_DISPLAY_STOPPED:
Michael Wright75ee9fc2014-09-01 19:55:22 -0700556 mCallback.onStopped();
Michael Wrightc39d47a2014-07-08 18:07:36 -0700557 break;
558 }
559 }
560 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700561}