blob: d968a3e942bbba8fe3de6df2af313180f67332e3 [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;
Kenny Guy22bd0442017-10-26 00:15:54 +010020import android.content.pm.ParceledListSlice;
Bryce Lee609bf652017-02-09 16:50:13 -080021import android.content.res.Resources;
Michael Wrighteedcbf12017-08-16 23:14:54 +010022import android.graphics.Point;
Jeff Brownbd6e1502012-08-28 03:27:37 -070023import android.hardware.display.DisplayManager.DisplayListener;
Michael Wrightc39d47a2014-07-08 18:07:36 -070024import android.media.projection.IMediaProjection;
Santos Cordonee8931e2017-04-05 10:31:15 -070025import android.media.projection.MediaProjection;
Jeff Brownbd6e1502012-08-28 03:27:37 -070026import android.os.Handler;
27import android.os.IBinder;
28import android.os.Looper;
29import android.os.Message;
30import android.os.RemoteException;
31import android.os.ServiceManager;
Jeff Browna506a6e2013-06-04 00:02:38 -070032import android.text.TextUtils;
Jeff Brownbd6e1502012-08-28 03:27:37 -070033import android.util.Log;
Dan Gittik122df862018-03-28 16:59:22 +010034import android.util.Pair;
Jeff Brownbd6e1502012-08-28 03:27:37 -070035import android.util.SparseArray;
Jeff Brownbd6e1502012-08-28 03:27:37 -070036import android.view.Display;
Santos Cordonee8931e2017-04-05 10:31:15 -070037import android.view.DisplayAdjustments;
Jeff Brownbd6e1502012-08-28 03:27:37 -070038import android.view.DisplayInfo;
Jeff Browna506a6e2013-06-04 00:02:38 -070039import android.view.Surface;
Jeff Brownbd6e1502012-08-28 03:27:37 -070040
41import java.util.ArrayList;
Kenny Guy22bd0442017-10-26 00:15:54 +010042import java.util.Collections;
43import java.util.List;
Jeff Brownbd6e1502012-08-28 03:27:37 -070044
45/**
46 * Manager communication with the display manager service on behalf of
47 * an application process. You're probably looking for {@link DisplayManager}.
48 *
49 * @hide
50 */
51public final class DisplayManagerGlobal {
52 private static final String TAG = "DisplayManager";
53 private static final boolean DEBUG = false;
54
Jeff Brown4ed8fe72012-08-30 18:18:29 -070055 // True if display info and display ids should be cached.
56 //
57 // FIXME: The cache is currently disabled because it's unclear whether we have the
58 // necessary guarantees that the caches will always be flushed before clients
59 // attempt to observe their new state. For example, depending on the order
60 // in which the binder transactions take place, we might have a problem where
61 // an application could start processing a configuration change due to a display
62 // orientation change before the display info cache has actually been invalidated.
63 private static final boolean USE_CACHE = false;
64
Jeff Brownbd6e1502012-08-28 03:27:37 -070065 public static final int EVENT_DISPLAY_ADDED = 1;
66 public static final int EVENT_DISPLAY_CHANGED = 2;
67 public static final int EVENT_DISPLAY_REMOVED = 3;
68
69 private static DisplayManagerGlobal sInstance;
70
71 private final Object mLock = new Object();
72
73 private final IDisplayManager mDm;
74
75 private DisplayManagerCallback mCallback;
76 private final ArrayList<DisplayListenerDelegate> mDisplayListeners =
77 new ArrayList<DisplayListenerDelegate>();
78
79 private final SparseArray<DisplayInfo> mDisplayInfoCache = new SparseArray<DisplayInfo>();
80 private int[] mDisplayIdCache;
81
Jeff Brownce468a32013-11-21 16:42:03 -080082 private int mWifiDisplayScanNestCount;
83
Jeff Brownbd6e1502012-08-28 03:27:37 -070084 private DisplayManagerGlobal(IDisplayManager dm) {
85 mDm = dm;
86 }
87
88 /**
89 * Gets an instance of the display manager global singleton.
90 *
91 * @return The display manager instance, may be null early in system startup
92 * before the display manager has been fully initialized.
93 */
94 public static DisplayManagerGlobal getInstance() {
95 synchronized (DisplayManagerGlobal.class) {
96 if (sInstance == null) {
97 IBinder b = ServiceManager.getService(Context.DISPLAY_SERVICE);
98 if (b != null) {
99 sInstance = new DisplayManagerGlobal(IDisplayManager.Stub.asInterface(b));
100 }
101 }
102 return sInstance;
103 }
104 }
105
106 /**
107 * Get information about a particular logical display.
108 *
109 * @param displayId The logical display id.
110 * @return Information about the specified display, or null if it does not exist.
111 * This object belongs to an internal cache and should be treated as if it were immutable.
112 */
113 public DisplayInfo getDisplayInfo(int displayId) {
114 try {
115 synchronized (mLock) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700116 DisplayInfo info;
117 if (USE_CACHE) {
118 info = mDisplayInfoCache.get(displayId);
119 if (info != null) {
120 return info;
121 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700122 }
123
124 info = mDm.getDisplayInfo(displayId);
125 if (info == null) {
126 return null;
127 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700128
129 if (USE_CACHE) {
130 mDisplayInfoCache.put(displayId, info);
131 }
132 registerCallbackIfNeededLocked();
133
Jeff Brownbd6e1502012-08-28 03:27:37 -0700134 if (DEBUG) {
135 Log.d(TAG, "getDisplayInfo: displayId=" + displayId + ", info=" + info);
136 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700137 return info;
138 }
139 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700140 throw ex.rethrowFromSystemServer();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700141 }
142 }
143
144 /**
145 * Gets all currently valid logical display ids.
146 *
147 * @return An array containing all display ids.
148 */
149 public int[] getDisplayIds() {
150 try {
151 synchronized (mLock) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700152 if (USE_CACHE) {
153 if (mDisplayIdCache != null) {
154 return mDisplayIdCache;
155 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700156 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700157
158 int[] displayIds = mDm.getDisplayIds();
159 if (USE_CACHE) {
160 mDisplayIdCache = displayIds;
161 }
162 registerCallbackIfNeededLocked();
163 return displayIds;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700164 }
165 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700166 throw ex.rethrowFromSystemServer();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700167 }
168 }
169
170 /**
171 * Gets information about a logical display.
172 *
173 * The display metrics may be adjusted to provide compatibility
Craig Mautner48d0d182013-06-11 07:53:06 -0700174 * for legacy applications or limited screen areas.
Jeff Brownbd6e1502012-08-28 03:27:37 -0700175 *
176 * @param displayId The logical display id.
Craig Mautner48d0d182013-06-11 07:53:06 -0700177 * @param daj The compatibility info and activityToken.
Jeff Brownbd6e1502012-08-28 03:27:37 -0700178 * @return The display object, or null if there is no display with the given id.
179 */
Craig Mautner48d0d182013-06-11 07:53:06 -0700180 public Display getCompatibleDisplay(int displayId, DisplayAdjustments daj) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700181 DisplayInfo displayInfo = getDisplayInfo(displayId);
182 if (displayInfo == null) {
183 return null;
184 }
Craig Mautner48d0d182013-06-11 07:53:06 -0700185 return new Display(this, displayId, displayInfo, daj);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700186 }
187
188 /**
Bryce Lee609bf652017-02-09 16:50:13 -0800189 * Gets information about a logical display.
190 *
191 * The display metrics may be adjusted to provide compatibility
192 * for legacy applications or limited screen areas.
193 *
194 * @param displayId The logical display id.
195 * @param resources Resources providing compatibility info.
196 * @return The display object, or null if there is no display with the given id.
197 */
198 public Display getCompatibleDisplay(int displayId, Resources resources) {
199 DisplayInfo displayInfo = getDisplayInfo(displayId);
200 if (displayInfo == null) {
201 return null;
202 }
203 return new Display(this, displayId, displayInfo, resources);
204 }
205
206 /**
Jeff Brownbd6e1502012-08-28 03:27:37 -0700207 * Gets information about a logical display without applying any compatibility metrics.
208 *
209 * @param displayId The logical display id.
210 * @return The display object, or null if there is no display with the given id.
211 */
212 public Display getRealDisplay(int displayId) {
Craig Mautner48d0d182013-06-11 07:53:06 -0700213 return getCompatibleDisplay(displayId, DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
214 }
215
Jeff Brownbd6e1502012-08-28 03:27:37 -0700216 public void registerDisplayListener(DisplayListener listener, Handler handler) {
217 if (listener == null) {
218 throw new IllegalArgumentException("listener must not be null");
219 }
220
221 synchronized (mLock) {
222 int index = findDisplayListenerLocked(listener);
223 if (index < 0) {
224 mDisplayListeners.add(new DisplayListenerDelegate(listener, handler));
225 registerCallbackIfNeededLocked();
226 }
227 }
228 }
229
230 public void unregisterDisplayListener(DisplayListener listener) {
231 if (listener == null) {
232 throw new IllegalArgumentException("listener must not be null");
233 }
234
235 synchronized (mLock) {
236 int index = findDisplayListenerLocked(listener);
237 if (index >= 0) {
238 DisplayListenerDelegate d = mDisplayListeners.get(index);
239 d.clearEvents();
240 mDisplayListeners.remove(index);
241 }
242 }
243 }
244
245 private int findDisplayListenerLocked(DisplayListener listener) {
246 final int numListeners = mDisplayListeners.size();
247 for (int i = 0; i < numListeners; i++) {
248 if (mDisplayListeners.get(i).mListener == listener) {
249 return i;
250 }
251 }
252 return -1;
253 }
254
255 private void registerCallbackIfNeededLocked() {
256 if (mCallback == null) {
257 mCallback = new DisplayManagerCallback();
258 try {
259 mDm.registerCallback(mCallback);
260 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700261 throw ex.rethrowFromSystemServer();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700262 }
263 }
264 }
265
266 private void handleDisplayEvent(int displayId, int event) {
267 synchronized (mLock) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700268 if (USE_CACHE) {
269 mDisplayInfoCache.remove(displayId);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700270
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700271 if (event == EVENT_DISPLAY_ADDED || event == EVENT_DISPLAY_REMOVED) {
272 mDisplayIdCache = null;
273 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700274 }
275
276 final int numListeners = mDisplayListeners.size();
277 for (int i = 0; i < numListeners; i++) {
278 mDisplayListeners.get(i).sendDisplayEvent(displayId, event);
279 }
280 }
281 }
282
Jeff Brownce468a32013-11-21 16:42:03 -0800283 public void startWifiDisplayScan() {
284 synchronized (mLock) {
285 if (mWifiDisplayScanNestCount++ == 0) {
286 registerCallbackIfNeededLocked();
287 try {
288 mDm.startWifiDisplayScan();
289 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700290 throw ex.rethrowFromSystemServer();
Jeff Brownce468a32013-11-21 16:42:03 -0800291 }
292 }
293 }
294 }
295
296 public void stopWifiDisplayScan() {
297 synchronized (mLock) {
298 if (--mWifiDisplayScanNestCount == 0) {
299 try {
300 mDm.stopWifiDisplayScan();
301 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700302 throw ex.rethrowFromSystemServer();
Jeff Brownce468a32013-11-21 16:42:03 -0800303 }
304 } else if (mWifiDisplayScanNestCount < 0) {
305 Log.wtf(TAG, "Wifi display scan nest count became negative: "
306 + mWifiDisplayScanNestCount);
307 mWifiDisplayScanNestCount = 0;
308 }
Jeff Browne08ae382012-09-07 20:36:36 -0700309 }
310 }
311
312 public void connectWifiDisplay(String deviceAddress) {
313 if (deviceAddress == null) {
314 throw new IllegalArgumentException("deviceAddress must not be null");
315 }
316
317 try {
318 mDm.connectWifiDisplay(deviceAddress);
319 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700320 throw ex.rethrowFromSystemServer();
Jeff Browne08ae382012-09-07 20:36:36 -0700321 }
322 }
323
Chong Zhang1f3ecaa2013-05-03 15:55:36 -0700324 public void pauseWifiDisplay() {
325 try {
326 mDm.pauseWifiDisplay();
327 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700328 throw ex.rethrowFromSystemServer();
Chong Zhang1f3ecaa2013-05-03 15:55:36 -0700329 }
330 }
331
332 public void resumeWifiDisplay() {
333 try {
334 mDm.resumeWifiDisplay();
335 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700336 throw ex.rethrowFromSystemServer();
Chong Zhang1f3ecaa2013-05-03 15:55:36 -0700337 }
338 }
339
Jeff Browne08ae382012-09-07 20:36:36 -0700340 public void disconnectWifiDisplay() {
341 try {
342 mDm.disconnectWifiDisplay();
343 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700344 throw ex.rethrowFromSystemServer();
Jeff Browne08ae382012-09-07 20:36:36 -0700345 }
346 }
347
Jeff Brown89d55462012-09-19 11:33:42 -0700348 public void renameWifiDisplay(String deviceAddress, String alias) {
349 if (deviceAddress == null) {
350 throw new IllegalArgumentException("deviceAddress must not be null");
351 }
352
353 try {
354 mDm.renameWifiDisplay(deviceAddress, alias);
355 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700356 throw ex.rethrowFromSystemServer();
Jeff Brown89d55462012-09-19 11:33:42 -0700357 }
358 }
359
360 public void forgetWifiDisplay(String deviceAddress) {
361 if (deviceAddress == null) {
362 throw new IllegalArgumentException("deviceAddress must not be null");
363 }
364
365 try {
366 mDm.forgetWifiDisplay(deviceAddress);
367 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700368 throw ex.rethrowFromSystemServer();
Jeff Brown89d55462012-09-19 11:33:42 -0700369 }
370 }
371
Jeff Browne08ae382012-09-07 20:36:36 -0700372 public WifiDisplayStatus getWifiDisplayStatus() {
373 try {
374 return mDm.getWifiDisplayStatus();
375 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700376 throw ex.rethrowFromSystemServer();
Jeff Browne08ae382012-09-07 20:36:36 -0700377 }
378 }
379
Michael Wright1c9977b2016-07-12 13:30:10 -0700380 public void requestColorMode(int displayId, int colorMode) {
Michael Wright58e829f2015-09-15 00:13:26 +0100381 try {
Michael Wright1c9977b2016-07-12 13:30:10 -0700382 mDm.requestColorMode(displayId, colorMode);
Michael Wright58e829f2015-09-15 00:13:26 +0100383 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700384 throw ex.rethrowFromSystemServer();
Michael Wright58e829f2015-09-15 00:13:26 +0100385 }
386 }
387
Bryan Mawhinney462e29d2018-03-22 15:52:41 +0000388 /**
389 * Set the level of color saturation to apply to the display.
390 */
391 public void setSaturationLevel(float level) {
392 try {
393 mDm.setSaturationLevel(level);
394 } catch (RemoteException ex) {
395 throw ex.rethrowFromSystemServer();
396 }
397 }
398
Michael Wrightc39d47a2014-07-08 18:07:36 -0700399 public VirtualDisplay createVirtualDisplay(Context context, MediaProjection projection,
400 String name, int width, int height, int densityDpi, Surface surface, int flags,
Santos Cordonee8931e2017-04-05 10:31:15 -0700401 VirtualDisplay.Callback callback, Handler handler, String uniqueId) {
Jeff Browna506a6e2013-06-04 00:02:38 -0700402 if (TextUtils.isEmpty(name)) {
403 throw new IllegalArgumentException("name must be non-null and non-empty");
404 }
405 if (width <= 0 || height <= 0 || densityDpi <= 0) {
406 throw new IllegalArgumentException("width, height, and densityDpi must be "
407 + "greater than 0");
408 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700409
Michael Wright75ee9fc2014-09-01 19:55:22 -0700410 VirtualDisplayCallback callbackWrapper = new VirtualDisplayCallback(callback, handler);
Michael Wrightc39d47a2014-07-08 18:07:36 -0700411 IMediaProjection projectionToken = projection != null ? projection.getProjection() : null;
Jeff Browna506a6e2013-06-04 00:02:38 -0700412 int displayId;
413 try {
Michael Wrightc39d47a2014-07-08 18:07:36 -0700414 displayId = mDm.createVirtualDisplay(callbackWrapper, projectionToken,
Santos Cordonee8931e2017-04-05 10:31:15 -0700415 context.getPackageName(), name, width, height, densityDpi, surface, flags,
416 uniqueId);
Jeff Browna506a6e2013-06-04 00:02:38 -0700417 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700418 throw ex.rethrowFromSystemServer();
Jeff Browna506a6e2013-06-04 00:02:38 -0700419 }
420 if (displayId < 0) {
Jeff Brown7d00aff2013-08-02 19:03:49 -0700421 Log.e(TAG, "Could not create virtual display: " + name);
Jeff Browna506a6e2013-06-04 00:02:38 -0700422 return null;
423 }
424 Display display = getRealDisplay(displayId);
425 if (display == null) {
426 Log.wtf(TAG, "Could not obtain display info for newly created "
Jeff Brown7d00aff2013-08-02 19:03:49 -0700427 + "virtual display: " + name);
Jeff Browna506a6e2013-06-04 00:02:38 -0700428 try {
Michael Wrightc39d47a2014-07-08 18:07:36 -0700429 mDm.releaseVirtualDisplay(callbackWrapper);
Jeff Browna506a6e2013-06-04 00:02:38 -0700430 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700431 throw ex.rethrowFromSystemServer();
Jeff Browna506a6e2013-06-04 00:02:38 -0700432 }
433 return null;
434 }
Michael Wrightc39d47a2014-07-08 18:07:36 -0700435 return new VirtualDisplay(this, display, callbackWrapper, surface);
Jeff Brown92207df2014-04-16 13:16:07 -0700436 }
437
Michael Wright75ee9fc2014-09-01 19:55:22 -0700438 public void setVirtualDisplaySurface(IVirtualDisplayCallback token, Surface surface) {
Jeff Brown92207df2014-04-16 13:16:07 -0700439 try {
440 mDm.setVirtualDisplaySurface(token, surface);
441 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700442 throw ex.rethrowFromSystemServer();
Jeff Brown92207df2014-04-16 13:16:07 -0700443 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700444 }
445
Michael Wright75ee9fc2014-09-01 19:55:22 -0700446 public void resizeVirtualDisplay(IVirtualDisplayCallback token,
Michael Wright01e840f2014-06-26 16:03:25 -0700447 int width, int height, int densityDpi) {
448 try {
449 mDm.resizeVirtualDisplay(token, width, height, densityDpi);
450 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700451 throw ex.rethrowFromSystemServer();
Michael Wright01e840f2014-06-26 16:03:25 -0700452 }
453 }
454
Michael Wright75ee9fc2014-09-01 19:55:22 -0700455 public void releaseVirtualDisplay(IVirtualDisplayCallback token) {
Jeff Browna506a6e2013-06-04 00:02:38 -0700456 try {
457 mDm.releaseVirtualDisplay(token);
458 } catch (RemoteException ex) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700459 throw ex.rethrowFromSystemServer();
Jeff Browna506a6e2013-06-04 00:02:38 -0700460 }
461 }
462
Michael Wrighteedcbf12017-08-16 23:14:54 +0100463 /**
464 * Gets the stable device display size, in pixels.
465 */
466 public Point getStableDisplaySize() {
467 try {
468 return mDm.getStableDisplaySize();
469 } catch (RemoteException ex) {
470 throw ex.rethrowFromSystemServer();
471 }
472 }
473
Kenny Guy22bd0442017-10-26 00:15:54 +0100474 /**
475 * Retrieves brightness change events.
476 */
Kenny Guy29aa30e2017-11-30 13:43:46 +0000477 public List<BrightnessChangeEvent> getBrightnessEvents(String callingPackage) {
Kenny Guy22bd0442017-10-26 00:15:54 +0100478 try {
Kenny Guy29aa30e2017-11-30 13:43:46 +0000479 ParceledListSlice<BrightnessChangeEvent> events =
480 mDm.getBrightnessEvents(callingPackage);
Kenny Guy22bd0442017-10-26 00:15:54 +0100481 if (events == null) {
482 return Collections.emptyList();
483 }
484 return events.getList();
485 } catch (RemoteException ex) {
486 throw ex.rethrowFromSystemServer();
487 }
488 }
489
490 /**
Michael Wrighteef0e132017-11-21 17:57:52 +0000491 * Sets the global brightness configuration for a given user.
492 *
493 * @hide
494 */
Kenny Guy05ce8092018-01-17 13:44:20 +0000495 public void setBrightnessConfigurationForUser(BrightnessConfiguration c, int userId,
496 String packageName) {
Michael Wrighteef0e132017-11-21 17:57:52 +0000497 try {
Kenny Guy05ce8092018-01-17 13:44:20 +0000498 mDm.setBrightnessConfigurationForUser(c, userId, packageName);
Michael Wrighteef0e132017-11-21 17:57:52 +0000499 } catch (RemoteException ex) {
500 throw ex.rethrowFromSystemServer();
501 }
502 }
503
Michael Wrightd8460232018-01-16 18:04:59 +0000504 /**
Kenny Guy6d1009f2018-03-14 14:28:23 +0000505 * Gets the global brightness configuration for a given user or null if one hasn't been set.
506 *
507 * @hide
508 */
509 public BrightnessConfiguration getBrightnessConfigurationForUser(int userId) {
510 try {
511 return mDm.getBrightnessConfigurationForUser(userId);
512 } catch (RemoteException ex) {
513 throw ex.rethrowFromSystemServer();
514 }
515 }
516
517 /**
518 * Gets the default brightness configuration or null if one hasn't been configured.
519 *
520 * @hide
521 */
522 public BrightnessConfiguration getDefaultBrightnessConfiguration() {
523 try {
524 return mDm.getDefaultBrightnessConfiguration();
525 } catch (RemoteException ex) {
526 throw ex.rethrowFromSystemServer();
527 }
528 }
529
530 /**
Michael Wrightd8460232018-01-16 18:04:59 +0000531 * Temporarily sets the brightness of the display.
532 * <p>
533 * Requires the {@link android.Manifest.permission#CONTROL_DISPLAY_BRIGHTNESS} permission.
534 * </p>
535 *
536 * @param brightness The brightness value from 0 to 255.
537 *
538 * @hide Requires signature permission.
539 */
540 public void setTemporaryBrightness(int brightness) {
541 try {
542 mDm.setTemporaryBrightness(brightness);
543 } catch (RemoteException ex) {
544 throw ex.rethrowFromSystemServer();
545 }
546 }
547
548 /**
549 * Temporarily sets the auto brightness adjustment factor.
550 * <p>
551 * Requires the {@link android.Manifest.permission#CONTROL_DISPLAY_BRIGHTNESS} permission.
552 * </p>
553 *
554 * @param adjustment The adjustment factor from -1.0 to 1.0.
555 *
556 * @hide Requires signature permission.
557 */
558 public void setTemporaryAutoBrightnessAdjustment(float adjustment) {
559 try {
560 mDm.setTemporaryAutoBrightnessAdjustment(adjustment);
561 } catch (RemoteException ex) {
562 throw ex.rethrowFromSystemServer();
563 }
564 }
565
Peeyush Agarwalcc155dd2018-01-10 11:51:33 +0000566 /**
Dan Gittik122df862018-03-28 16:59:22 +0100567 * Returns the minimum brightness curve, which guarantess that any brightness curve that dips
568 * below it is rejected by the system.
569 * This prevent auto-brightness from setting the screen so dark as to prevent the user from
570 * resetting or disabling it, and maps lux to the absolute minimum nits that are still readable
571 * in that ambient brightness.
572 *
573 * @return The minimum brightness curve (as lux values and their corresponding nits values).
574 */
575 public Pair<float[], float[]> getMinimumBrightnessCurve() {
576 try {
577 Curve curve = mDm.getMinimumBrightnessCurve();
578 return Pair.create(curve.getX(), curve.getY());
579 } catch (RemoteException ex) {
580 throw ex.rethrowFromSystemServer();
581 }
582 }
583
584 /**
Peeyush Agarwalcc155dd2018-01-10 11:51:33 +0000585 * Retrieves ambient brightness stats.
586 */
587 public List<AmbientBrightnessDayStats> getAmbientBrightnessStats() {
588 try {
589 ParceledListSlice<AmbientBrightnessDayStats> stats = mDm.getAmbientBrightnessStats();
590 if (stats == null) {
591 return Collections.emptyList();
592 }
593 return stats.getList();
594 } catch (RemoteException ex) {
595 throw ex.rethrowFromSystemServer();
596 }
597 }
598
Jeff Brownbd6e1502012-08-28 03:27:37 -0700599 private final class DisplayManagerCallback extends IDisplayManagerCallback.Stub {
600 @Override
601 public void onDisplayEvent(int displayId, int event) {
602 if (DEBUG) {
603 Log.d(TAG, "onDisplayEvent: displayId=" + displayId + ", event=" + event);
604 }
605 handleDisplayEvent(displayId, event);
606 }
607 }
608
609 private static final class DisplayListenerDelegate extends Handler {
610 public final DisplayListener mListener;
611
612 public DisplayListenerDelegate(DisplayListener listener, Handler handler) {
613 super(handler != null ? handler.getLooper() : Looper.myLooper(), null, true /*async*/);
614 mListener = listener;
615 }
616
617 public void sendDisplayEvent(int displayId, int event) {
618 Message msg = obtainMessage(event, displayId, 0);
619 sendMessage(msg);
620 }
621
622 public void clearEvents() {
623 removeCallbacksAndMessages(null);
624 }
625
626 @Override
627 public void handleMessage(Message msg) {
628 switch (msg.what) {
629 case EVENT_DISPLAY_ADDED:
630 mListener.onDisplayAdded(msg.arg1);
631 break;
632 case EVENT_DISPLAY_CHANGED:
633 mListener.onDisplayChanged(msg.arg1);
634 break;
635 case EVENT_DISPLAY_REMOVED:
636 mListener.onDisplayRemoved(msg.arg1);
637 break;
638 }
639 }
640 }
Michael Wrightc39d47a2014-07-08 18:07:36 -0700641
Michael Wright75ee9fc2014-09-01 19:55:22 -0700642 private final static class VirtualDisplayCallback extends IVirtualDisplayCallback.Stub {
643 private VirtualDisplayCallbackDelegate mDelegate;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700644
Michael Wright75ee9fc2014-09-01 19:55:22 -0700645 public VirtualDisplayCallback(VirtualDisplay.Callback callback, Handler handler) {
646 if (callback != null) {
647 mDelegate = new VirtualDisplayCallbackDelegate(callback, handler);
Craig Mautner3d0c57a2014-07-21 14:18:29 -0700648 }
Michael Wrightc39d47a2014-07-08 18:07:36 -0700649 }
650
651 @Override // Binder call
Michael Wright75ee9fc2014-09-01 19:55:22 -0700652 public void onPaused() {
Craig Mautner3d0c57a2014-07-21 14:18:29 -0700653 if (mDelegate != null) {
Michael Wright75ee9fc2014-09-01 19:55:22 -0700654 mDelegate.sendEmptyMessage(VirtualDisplayCallbackDelegate.MSG_DISPLAY_PAUSED);
Craig Mautner3d0c57a2014-07-21 14:18:29 -0700655 }
Michael Wrightc39d47a2014-07-08 18:07:36 -0700656 }
657
658 @Override // Binder call
Michael Wright75ee9fc2014-09-01 19:55:22 -0700659 public void onResumed() {
Craig Mautner3d0c57a2014-07-21 14:18:29 -0700660 if (mDelegate != null) {
Michael Wright75ee9fc2014-09-01 19:55:22 -0700661 mDelegate.sendEmptyMessage(VirtualDisplayCallbackDelegate.MSG_DISPLAY_RESUMED);
Craig Mautner3d0c57a2014-07-21 14:18:29 -0700662 }
Michael Wrightc39d47a2014-07-08 18:07:36 -0700663 }
664
665 @Override // Binder call
Michael Wright75ee9fc2014-09-01 19:55:22 -0700666 public void onStopped() {
Craig Mautner3d0c57a2014-07-21 14:18:29 -0700667 if (mDelegate != null) {
Michael Wright75ee9fc2014-09-01 19:55:22 -0700668 mDelegate.sendEmptyMessage(VirtualDisplayCallbackDelegate.MSG_DISPLAY_STOPPED);
Craig Mautner3d0c57a2014-07-21 14:18:29 -0700669 }
Michael Wrightc39d47a2014-07-08 18:07:36 -0700670 }
671 }
672
Michael Wright75ee9fc2014-09-01 19:55:22 -0700673 private final static class VirtualDisplayCallbackDelegate extends Handler {
Michael Wrightc39d47a2014-07-08 18:07:36 -0700674 public static final int MSG_DISPLAY_PAUSED = 0;
675 public static final int MSG_DISPLAY_RESUMED = 1;
676 public static final int MSG_DISPLAY_STOPPED = 2;
677
Michael Wright75ee9fc2014-09-01 19:55:22 -0700678 private final VirtualDisplay.Callback mCallback;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700679
Michael Wright75ee9fc2014-09-01 19:55:22 -0700680 public VirtualDisplayCallbackDelegate(VirtualDisplay.Callback callback,
Michael Wrightc39d47a2014-07-08 18:07:36 -0700681 Handler handler) {
682 super(handler != null ? handler.getLooper() : Looper.myLooper(), null, true /*async*/);
Michael Wright75ee9fc2014-09-01 19:55:22 -0700683 mCallback = callback;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700684 }
685
686 @Override
687 public void handleMessage(Message msg) {
Michael Wrightc39d47a2014-07-08 18:07:36 -0700688 switch (msg.what) {
689 case MSG_DISPLAY_PAUSED:
Michael Wright75ee9fc2014-09-01 19:55:22 -0700690 mCallback.onPaused();
Michael Wrightc39d47a2014-07-08 18:07:36 -0700691 break;
692 case MSG_DISPLAY_RESUMED:
Michael Wright75ee9fc2014-09-01 19:55:22 -0700693 mCallback.onResumed();
Michael Wrightc39d47a2014-07-08 18:07:36 -0700694 break;
695 case MSG_DISPLAY_STOPPED:
Michael Wright75ee9fc2014-09-01 19:55:22 -0700696 mCallback.onStopped();
Michael Wrightc39d47a2014-07-08 18:07:36 -0700697 break;
698 }
699 }
700 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700701}