1 /*
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 
17 package android.hardware.display;
18 
19 import static android.view.Display.DEFAULT_DISPLAY;
20 import static android.view.Display.HdrCapabilities.HdrType;
21 
22 import android.Manifest;
23 import android.annotation.FloatRange;
24 import android.annotation.IntDef;
25 import android.annotation.IntRange;
26 import android.annotation.LongDef;
27 import android.annotation.NonNull;
28 import android.annotation.Nullable;
29 import android.annotation.RequiresPermission;
30 import android.annotation.SystemApi;
31 import android.annotation.SystemService;
32 import android.annotation.TestApi;
33 import android.app.KeyguardManager;
34 import android.compat.annotation.UnsupportedAppUsage;
35 import android.content.Context;
36 import android.content.pm.IPackageManager;
37 import android.content.res.Resources;
38 import android.graphics.Point;
39 import android.media.projection.MediaProjection;
40 import android.os.Build;
41 import android.os.Handler;
42 import android.os.HandlerExecutor;
43 import android.os.Looper;
44 import android.os.Process;
45 import android.os.RemoteException;
46 import android.os.ServiceManager;
47 import android.util.Pair;
48 import android.util.Slog;
49 import android.util.SparseArray;
50 import android.view.Display;
51 import android.view.Surface;
52 
53 import com.android.internal.R;
54 import com.android.internal.annotations.GuardedBy;
55 
56 import java.lang.annotation.Retention;
57 import java.lang.annotation.RetentionPolicy;
58 import java.lang.ref.WeakReference;
59 import java.util.ArrayList;
60 import java.util.List;
61 import java.util.Objects;
62 import java.util.concurrent.Executor;
63 import java.util.function.Predicate;
64 
65 
66 /**
67  * Manages the properties of attached displays.
68  */
69 @SystemService(Context.DISPLAY_SERVICE)
70 public final class DisplayManager {
71     private static final String TAG = "DisplayManager";
72     private static final boolean DEBUG = false;
73     private static final boolean ENABLE_VIRTUAL_DISPLAY_REFRESH_RATE = true;
74 
75     /**
76      * The hdr output control feature flag, the value should be read via
77      * {@link android.provider.DeviceConfig#getBoolean(String, String, boolean)} with
78      * {@link android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER} as the namespace.
79      * @hide
80      */
81     @TestApi
82     public static final String HDR_OUTPUT_CONTROL_FLAG = "enable_hdr_output_control";
83 
84     private final Context mContext;
85     private final DisplayManagerGlobal mGlobal;
86 
87     private final Object mLock = new Object();
88     @GuardedBy("mLock")
89     private final WeakDisplayCache mDisplayCache = new WeakDisplayCache();
90 
91     /**
92      * Broadcast receiver that indicates when the Wifi display status changes.
93      * <p>
94      * The status is provided as a {@link WifiDisplayStatus} object in the
95      * {@link #EXTRA_WIFI_DISPLAY_STATUS} extra.
96      * </p><p>
97      * This broadcast is only sent to registered receivers and can only be sent by the system.
98      * </p>
99      * @hide
100      */
101     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
102     public static final String ACTION_WIFI_DISPLAY_STATUS_CHANGED =
103             "android.hardware.display.action.WIFI_DISPLAY_STATUS_CHANGED";
104 
105     /**
106      * Contains a {@link WifiDisplayStatus} object.
107      * @hide
108      */
109     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
110     public static final String EXTRA_WIFI_DISPLAY_STATUS =
111             "android.hardware.display.extra.WIFI_DISPLAY_STATUS";
112 
113     /**
114      * Display category: Presentation displays.
115      * <p>
116      * This category can be used to identify secondary displays that are suitable for
117      * use as presentation displays such as external or wireless displays.  Applications
118      * may automatically project their content to presentation displays to provide
119      * richer second screen experiences.
120      * </p>
121      *
122      * @see android.app.Presentation
123      * @see Display#FLAG_PRESENTATION
124      * @see #getDisplays(String)
125      */
126     public static final String DISPLAY_CATEGORY_PRESENTATION =
127             "android.hardware.display.category.PRESENTATION";
128 
129     /**
130      * Display category: Rear displays.
131      * <p>
132      * This category can be used to identify complementary internal displays that are facing away
133      * from the user.
134      * Certain applications may present to this display.
135      * Similar to presentation displays.
136      * </p>
137      *
138      * @see android.app.Presentation
139      * @see Display#FLAG_PRESENTATION
140      * @see #getDisplays(String)
141      * @hide
142      */
143     @TestApi
144     public static final String DISPLAY_CATEGORY_REAR =
145             "android.hardware.display.category.REAR";
146 
147     /**
148      * Display category: All displays, including disabled displays.
149      * <p>
150      * This returns all displays, including currently disabled and inaccessible displays.
151      *
152      * @see #getDisplays(String)
153      * @hide
154      */
155     public static final String DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED =
156             "android.hardware.display.category.ALL_INCLUDING_DISABLED";
157 
158     /** @hide **/
159     @IntDef(prefix = "VIRTUAL_DISPLAY_FLAG_", flag = true, value = {
160             VIRTUAL_DISPLAY_FLAG_PUBLIC,
161             VIRTUAL_DISPLAY_FLAG_PRESENTATION,
162             VIRTUAL_DISPLAY_FLAG_SECURE,
163             VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY,
164             VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
165             VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD,
166             VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH,
167             VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT,
168             VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL,
169             VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS,
170             VIRTUAL_DISPLAY_FLAG_TRUSTED,
171             VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP,
172             VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED,
173             VIRTUAL_DISPLAY_FLAG_TOUCH_FEEDBACK_DISABLED,
174             VIRTUAL_DISPLAY_FLAG_OWN_FOCUS,
175             VIRTUAL_DISPLAY_FLAG_STEAL_TOP_FOCUS_DISABLED,
176     })
177     @Retention(RetentionPolicy.SOURCE)
178     public @interface VirtualDisplayFlag {}
179 
180     /**
181      * Virtual display flag: Create a public display.
182      *
183      * <h3>Public virtual displays</h3>
184      * <p>
185      * When this flag is set, the virtual display is public.
186      * </p><p>
187      * A public virtual display behaves just like most any other display that is connected
188      * to the system such as an external or wireless display.  Applications can open
189      * windows on the display and the system may mirror the contents of other displays
190      * onto it.
191      * </p><p>
192      * Creating a public virtual display that isn't restricted to own-content only implicitly
193      * creates an auto-mirroring display. See {@link #VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR} for
194      * restrictions on who is allowed to create an auto-mirroring display.
195      * </p>
196      *
197      * <h3>Private virtual displays</h3>
198      * <p>
199      * When this flag is not set, the virtual display is private as defined by the
200      * {@link Display#FLAG_PRIVATE} display flag.
201      * </p>
202      *
203      * <p>
204      * A private virtual display belongs to the application that created it.  Only the a owner of a
205      * private virtual display and the apps that are already on that display are allowed to place
206      * windows upon it.  The private virtual display also does not participate in display mirroring:
207      * it will neither receive mirrored content from another display nor allow its own content to be
208      * mirrored elsewhere.  More precisely, the only processes that are allowed to enumerate or
209      * interact with the private display are those that have the same UID as the application that
210      * originally created the private virtual display or as the activities that are already on that
211      * display.
212      * </p>
213      *
214      * @see #createVirtualDisplay
215      * @see #VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY
216      * @see #VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR
217      */
218     public static final int VIRTUAL_DISPLAY_FLAG_PUBLIC = 1 << 0;
219 
220     /**
221      * Virtual display flag: Create a presentation display.
222      *
223      * <h3>Presentation virtual displays</h3>
224      * <p>
225      * When this flag is set, the virtual display is registered as a presentation
226      * display in the {@link #DISPLAY_CATEGORY_PRESENTATION presentation display category}.
227      * Applications may automatically project their content to presentation displays
228      * to provide richer second screen experiences.
229      * </p>
230      *
231      * <h3>Non-presentation virtual displays</h3>
232      * <p>
233      * When this flag is not set, the virtual display is not registered as a presentation
234      * display.  Applications can still project their content on the display but they
235      * will typically not do so automatically.  This option is appropriate for
236      * more special-purpose displays.
237      * </p>
238      *
239      * @see android.app.Presentation
240      * @see #createVirtualDisplay
241      * @see #DISPLAY_CATEGORY_PRESENTATION
242      * @see Display#FLAG_PRESENTATION
243      */
244     public static final int VIRTUAL_DISPLAY_FLAG_PRESENTATION = 1 << 1;
245 
246     /**
247      * Virtual display flag: Create a secure display.
248      *
249      * <h3>Secure virtual displays</h3>
250      * <p>
251      * When this flag is set, the virtual display is considered secure as defined
252      * by the {@link Display#FLAG_SECURE} display flag.  The caller promises to take
253      * reasonable measures, such as over-the-air encryption, to prevent the contents
254      * of the display from being intercepted or recorded on a persistent medium.
255      * </p><p>
256      * Creating a secure virtual display requires the CAPTURE_SECURE_VIDEO_OUTPUT permission.
257      * This permission is reserved for use by system components and is not available to
258      * third-party applications.
259      * </p>
260      *
261      * <h3>Non-secure virtual displays</h3>
262      * <p>
263      * When this flag is not set, the virtual display is considered unsecure.
264      * The content of secure windows will be blanked if shown on this display.
265      * </p>
266      *
267      * @see Display#FLAG_SECURE
268      * @see #createVirtualDisplay
269      */
270     public static final int VIRTUAL_DISPLAY_FLAG_SECURE = 1 << 2;
271 
272     /**
273      * Virtual display flag: Only show this display's own content; do not mirror
274      * the content of another display.
275      *
276      * <p>
277      * This flag is used in conjunction with {@link #VIRTUAL_DISPLAY_FLAG_PUBLIC}.
278      * Ordinarily public virtual displays will automatically mirror the content of the
279      * default display if they have no windows of their own.  When this flag is
280      * specified, the virtual display will only ever show its own content and
281      * will be blanked instead if it has no windows.
282      * </p>
283      *
284      * <p>
285      * This flag is mutually exclusive with {@link #VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR}.  If both
286      * flags are specified then the own-content only behavior will be applied.
287      * </p>
288      *
289      * <p>
290      * This behavior of this flag is implied whenever neither {@link #VIRTUAL_DISPLAY_FLAG_PUBLIC}
291      * nor {@link #VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR} have been set.  This flag is only required to
292      * override the default behavior when creating a public display.
293      * </p>
294      *
295      * @see #createVirtualDisplay
296      */
297     public static final int VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY = 1 << 3;
298 
299 
300     /**
301      * Virtual display flag: Allows content to be mirrored on private displays when no content is
302      * being shown.
303      *
304      * <p>
305      * This flag is mutually exclusive with {@link #VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY}.
306      * If both flags are specified then the own-content only behavior will be applied.
307      * </p>
308      *
309      * <p>
310      * The behavior of this flag is implied whenever {@link #VIRTUAL_DISPLAY_FLAG_PUBLIC} is set
311      * and {@link #VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY} has not been set.   This flag is only
312      * required to override the default behavior when creating a private display.
313      * </p>
314      *
315      * <p>
316      * Creating an auto-mirroing virtual display requires the CAPTURE_VIDEO_OUTPUT
317      * or CAPTURE_SECURE_VIDEO_OUTPUT permission.
318      * These permissions are reserved for use by system components and are not available to
319      * third-party applications.
320      *
321      * Alternatively, an appropriate {@link MediaProjection} may be used to create an
322      * auto-mirroring virtual display.
323      * </p>
324      *
325      * @see #createVirtualDisplay
326      */
327     public static final int VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR = 1 << 4;
328 
329     /**
330      * Virtual display flag: Allows content to be displayed on private virtual displays when
331      * keyguard is shown but is insecure.
332      *
333      * <p>
334      * This might be used in a case when the content of a virtual display is captured and sent to an
335      * external hardware display that is not visible to the system directly. This flag will allow
336      * the continued display of content while other displays will be covered by a keyguard which
337      * doesn't require providing credentials to unlock. This means that there is either no password
338      * or other authentication method set, or the device is in a trusted state -
339      * {@link android.service.trust.TrustAgentService} has available and active trust agent.
340      * </p><p>
341      * This flag can only be applied to private displays as defined by the
342      * {@link Display#FLAG_PRIVATE} display flag. It is mutually exclusive with
343      * {@link #VIRTUAL_DISPLAY_FLAG_PUBLIC}. If both flags are specified then this flag's behavior
344      * will not be applied.
345      * </p>
346      *
347      * @see #createVirtualDisplay
348      * @see KeyguardManager#isDeviceSecure()
349      * @see KeyguardManager#isDeviceLocked()
350      * @hide
351      */
352     // TODO (b/114338689): Remove the flag and use IWindowManager#shouldShowWithInsecureKeyguard
353     // TODO: Update name and documentation and un-hide the flag. Don't change the value before that.
354     public static final int VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD = 1 << 5;
355 
356     /**
357      * Virtual display flag: Specifies that the virtual display can be associated with a
358      * touchpad device that matches its uniqueId.
359      *
360      * @see #createVirtualDisplay
361      * @hide
362      */
363     public static final int VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH = 1 << 6;
364 
365     /**
366      * Virtual display flag: Indicates that the orientation of this display device is coupled to
367      * the rotation of its associated logical display.
368      *
369      * @see #createVirtualDisplay
370      * @hide
371      */
372     public static final int VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT = 1 << 7;
373 
374     /**
375      * Virtual display flag: Indicates that the contents will be destroyed once
376      * the display is removed.
377      *
378      * Public virtual displays without this flag will move their content to main display
379      * stack once they're removed. Private vistual displays will always destroy their
380      * content on removal even without this flag.
381      *
382      * @see #createVirtualDisplay
383      * @hide
384      */
385     // TODO (b/114338689): Remove the flag and use WindowManager#REMOVE_CONTENT_MODE_DESTROY
386     public static final int VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL = 1 << 8;
387 
388     /**
389      * Virtual display flag: Indicates that the display should support system decorations. Virtual
390      * displays without this flag shouldn't show home, IME or any other system decorations.
391      * <p>This flag doesn't work without {@link #VIRTUAL_DISPLAY_FLAG_TRUSTED}</p>
392      *
393      * @see #createVirtualDisplay
394      * @see #VIRTUAL_DISPLAY_FLAG_TRUSTED
395      * @hide
396      */
397     // TODO (b/114338689): Remove the flag and use IWindowManager#setShouldShowSystemDecors
398     @TestApi
399     public static final int VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = 1 << 9;
400 
401     /**
402      * Virtual display flags: Indicates that the display is trusted to show system decorations and
403      * receive inputs without users' touch.
404      *
405      * @see #createVirtualDisplay
406      * @see #VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
407      * @hide
408      */
409     @SystemApi
410     public static final int VIRTUAL_DISPLAY_FLAG_TRUSTED = 1 << 10;
411 
412     /**
413      * Virtual display flags: Indicates that the display should not be a part of the default
414      * DisplayGroup and instead be part of a new DisplayGroup.
415      *
416      * @see #createVirtualDisplay
417      * @hide
418      */
419     public static final int VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP = 1 << 11;
420 
421     /**
422      * Virtual display flags: Indicates that the virtual display should always be unlocked and not
423      * have keyguard displayed on it. Only valid for virtual displays that aren't in the default
424      * display group.
425      *
426      * @see #createVirtualDisplay
427      * @see #VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP
428      * @hide
429      */
430     public static final int VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED = 1 << 12;
431 
432     /**
433      * Virtual display flags: Indicates that the display should not play sound effects or perform
434      * haptic feedback when the user touches the screen.
435      *
436      * @see #createVirtualDisplay
437      * @hide
438      */
439     public static final int VIRTUAL_DISPLAY_FLAG_TOUCH_FEEDBACK_DISABLED = 1 << 13;
440 
441     /**
442      * Virtual display flags: Indicates that the display maintains its own focus and touch mode.
443      *
444      * This flag is similar to {@link com.android.internal.R.bool.config_perDisplayFocusEnabled} in
445      * behavior, but only applies to the specific display instead of system-wide to all displays.
446      *
447      * Note: The display must be trusted in order to have its own focus.
448      *
449      * @see #createVirtualDisplay
450      * @see #VIRTUAL_DISPLAY_FLAG_TRUSTED
451      * @hide
452      */
453     @TestApi
454     public static final int VIRTUAL_DISPLAY_FLAG_OWN_FOCUS = 1 << 14;
455 
456     /**
457      * Virtual display flags: Indicates that the display should not be a part of the default
458      * DisplayGroup and instead be part of a DisplayGroup associated with its virtual device.
459      *
460      * @see #createVirtualDisplay
461      * @hide
462      */
463     public static final int VIRTUAL_DISPLAY_FLAG_DEVICE_DISPLAY_GROUP = 1 << 15;
464 
465 
466     /**
467      * Virtual display flags: Indicates that the display should not become the top focused display
468      * by stealing the top focus from another display.
469      *
470      * @see Display#FLAG_STEAL_TOP_FOCUS_DISABLED
471      * @see #createVirtualDisplay
472      * @see #VIRTUAL_DISPLAY_FLAG_OWN_FOCUS
473      * @hide
474      */
475     @SystemApi
476     public static final int VIRTUAL_DISPLAY_FLAG_STEAL_TOP_FOCUS_DISABLED = 1 << 16;
477 
478     /** @hide */
479     @IntDef(prefix = {"MATCH_CONTENT_FRAMERATE_"}, value = {
480             MATCH_CONTENT_FRAMERATE_UNKNOWN,
481             MATCH_CONTENT_FRAMERATE_NEVER,
482             MATCH_CONTENT_FRAMERATE_SEAMLESSS_ONLY,
483             MATCH_CONTENT_FRAMERATE_ALWAYS,
484     })
485     @Retention(RetentionPolicy.SOURCE)
486     public @interface MatchContentFrameRateType {}
487 
488     /**
489      * Match content frame rate user preference is unknown.
490      */
491     public static final int MATCH_CONTENT_FRAMERATE_UNKNOWN = -1;
492 
493     /**
494      * No mode switching is allowed.
495      */
496     public static final int MATCH_CONTENT_FRAMERATE_NEVER = 0;
497 
498     /**
499      * Only refresh rate switches without visual interruptions are allowed.
500      */
501     public static final int MATCH_CONTENT_FRAMERATE_SEAMLESSS_ONLY = 1;
502 
503     /**
504      * Refresh rate switches between all refresh rates are allowed even if they have visual
505      * interruptions for the user.
506      */
507     public static final int MATCH_CONTENT_FRAMERATE_ALWAYS = 2;
508 
509     /** @hide */
510     @IntDef(prefix = {"SWITCHING_TYPE_"}, value = {
511             SWITCHING_TYPE_NONE,
512             SWITCHING_TYPE_WITHIN_GROUPS,
513             SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS,
514             SWITCHING_TYPE_RENDER_FRAME_RATE_ONLY,
515     })
516     @Retention(RetentionPolicy.SOURCE)
517     public @interface SwitchingType {}
518 
519     /**
520      * No display mode switching will happen.
521      * @hide
522      */
523     @TestApi
524     public static final int SWITCHING_TYPE_NONE = 0;
525 
526     /**
527      * Allow only refresh rate switching between modes in the same configuration group. This way
528      * only switches without visual interruptions for the user will be allowed.
529      * @hide
530      */
531     @TestApi
532     public static final int SWITCHING_TYPE_WITHIN_GROUPS = 1;
533 
534     /**
535      * Allow refresh rate switching between all refresh rates even if the switch with have visual
536      * interruptions for the user.
537      * @hide
538      */
539     @TestApi
540     public static final int SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS = 2;
541 
542     /**
543      * Allow render frame rate switches, but not physical modes.
544      * @hide
545      */
546     @TestApi
547     public static final int SWITCHING_TYPE_RENDER_FRAME_RATE_ONLY = 3;
548 
549     /**
550      * @hide
551      */
552     @LongDef(flag = true, prefix = {"EVENT_FLAG_"}, value = {
553             EVENT_FLAG_DISPLAY_ADDED,
554             EVENT_FLAG_DISPLAY_CHANGED,
555             EVENT_FLAG_DISPLAY_REMOVED,
556             EVENT_FLAG_DISPLAY_BRIGHTNESS,
557             EVENT_FLAG_HDR_SDR_RATIO_CHANGED
558     })
559     @Retention(RetentionPolicy.SOURCE)
560     public @interface EventsMask {}
561 
562     /**
563      * Event type for when a new display is added.
564      *
565      * @see #registerDisplayListener(DisplayListener, Handler, long)
566      *
567      * @hide
568      */
569     public static final long EVENT_FLAG_DISPLAY_ADDED = 1L << 0;
570 
571     /**
572      * Event type for when a display is removed.
573      *
574      * @see #registerDisplayListener(DisplayListener, Handler, long)
575      *
576      * @hide
577      */
578     public static final long EVENT_FLAG_DISPLAY_REMOVED = 1L << 1;
579 
580     /**
581      * Event type for when a display is changed.
582      *
583      * @see #registerDisplayListener(DisplayListener, Handler, long)
584      *
585      * @hide
586      */
587     public static final long EVENT_FLAG_DISPLAY_CHANGED = 1L << 2;
588 
589     /**
590      * Event flag to register for a display's brightness changes. This notification is sent
591      * through the {@link DisplayListener#onDisplayChanged} callback method. New brightness
592      * values can be retrieved via {@link android.view.Display#getBrightnessInfo()}.
593      *
594      * @see #registerDisplayListener(DisplayListener, Handler, long)
595      *
596      * @hide
597      */
598     public static final long EVENT_FLAG_DISPLAY_BRIGHTNESS = 1L << 3;
599 
600     /**
601      * Event flag to register for a display's hdr/sdr ratio changes. This notification is sent
602      * through the {@link DisplayListener#onDisplayChanged} callback method. New hdr/sdr
603      * values can be retrieved via {@link Display#getHdrSdrRatio()}.
604      *
605      * Requires that {@link Display#isHdrSdrRatioAvailable()} is true.
606      *
607      * @see #registerDisplayListener(DisplayListener, Handler, long)
608      *
609      * @hide
610      */
611     public static final long EVENT_FLAG_HDR_SDR_RATIO_CHANGED = 1L << 4;
612 
613     /** @hide */
DisplayManager(Context context)614     public DisplayManager(Context context) {
615         mContext = context;
616         mGlobal = DisplayManagerGlobal.getInstance();
617     }
618 
619     /**
620      * Gets information about a logical display.
621      *
622      * The display metrics may be adjusted to provide compatibility
623      * for legacy applications.
624      *
625      * @param displayId The logical display id.
626      * @return The display object, or null if there is no valid display with the given id.
627      */
getDisplay(int displayId)628     public Display getDisplay(int displayId) {
629         return getOrCreateDisplay(displayId, false /*assumeValid*/);
630     }
631 
632     /**
633      * Gets all currently valid logical displays.
634      *
635      * @return An array containing all displays.
636      */
getDisplays()637     public Display[] getDisplays() {
638         return getDisplays(null);
639     }
640 
641     /**
642      * Gets all currently valid logical displays of the specified category.
643      * <p>
644      * When there are multiple displays in a category the returned displays are sorted
645      * of preference.  For example, if the requested category is
646      * {@link #DISPLAY_CATEGORY_PRESENTATION} and there are multiple presentation displays
647      * then the displays are sorted so that the first display in the returned array
648      * is the most preferred presentation display.  The application may simply
649      * use the first display or allow the user to choose.
650      * </p>
651      *
652      * @param category The requested display category or null to return all displays.
653      * @return An array containing all displays sorted by order of preference.
654      *
655      * @see #DISPLAY_CATEGORY_PRESENTATION
656      */
getDisplays(String category)657     public Display[] getDisplays(String category) {
658         boolean includeDisabled = (category != null
659                 && category.equals(DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED));
660         final int[] displayIds = mGlobal.getDisplayIds(includeDisabled);
661         if (DISPLAY_CATEGORY_PRESENTATION.equals(category)) {
662             return getDisplays(displayIds, DisplayManager::isPresentationDisplay);
663         } else if (DISPLAY_CATEGORY_REAR.equals(category)) {
664             return getDisplays(displayIds, DisplayManager::isRearDisplay);
665         } else if (category == null || DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED.equals(category)) {
666             return getDisplays(displayIds, Objects::nonNull);
667         }
668         return new Display[0];
669     }
670 
getDisplays(int[] displayIds, Predicate<Display> predicate)671     private Display[] getDisplays(int[] displayIds, Predicate<Display> predicate) {
672         ArrayList<Display> tmpDisplays = new ArrayList<>();
673         for (int displayId : displayIds) {
674             Display display = getOrCreateDisplay(displayId, /*assumeValid=*/true);
675             if (predicate.test(display)) {
676                 tmpDisplays.add(display);
677             }
678         }
679         return tmpDisplays.toArray(new Display[tmpDisplays.size()]);
680     }
681 
isPresentationDisplay(@ullable Display display)682     private static boolean isPresentationDisplay(@Nullable Display display) {
683         if (display == null || (display.getDisplayId() == DEFAULT_DISPLAY)
684                 || (display.getFlags() & Display.FLAG_PRESENTATION) == 0) {
685             return false;
686         }
687         switch (display.getType()) {
688             case Display.TYPE_INTERNAL:
689             case Display.TYPE_EXTERNAL:
690             case Display.TYPE_WIFI:
691             case Display.TYPE_OVERLAY:
692             case Display.TYPE_VIRTUAL:
693                 return true;
694             default:
695                 return false;
696         }
697     }
698 
isRearDisplay(@ullable Display display)699     private static boolean isRearDisplay(@Nullable Display display) {
700         return display != null && display.getDisplayId() != DEFAULT_DISPLAY
701                 && display.getType() == Display.TYPE_INTERNAL
702                 && (display.getFlags() & Display.FLAG_REAR) != 0;
703     }
704 
getOrCreateDisplay(int displayId, boolean assumeValid)705     private Display getOrCreateDisplay(int displayId, boolean assumeValid) {
706         Display display;
707         synchronized (mLock) {
708             display = mDisplayCache.get(displayId);
709             if (display == null) {
710                 // TODO: We cannot currently provide any override configurations for metrics on
711                 // displays other than the display the context is associated with.
712                 final Resources resources = mContext.getDisplayId() == displayId
713                         ? mContext.getResources() : null;
714 
715                 display = mGlobal.getCompatibleDisplay(displayId, resources);
716                 if (display != null) {
717                     mDisplayCache.put(display);
718                 }
719             } else if (!assumeValid && !display.isValid()) {
720                 display = null;
721             }
722         }
723         return display;
724     }
725 
726     /**
727      * Registers a display listener to receive notifications about when
728      * displays are added, removed or changed.
729      *
730      * @param listener The listener to register.
731      * @param handler The handler on which the listener should be invoked, or null
732      * if the listener should be invoked on the calling thread's looper.
733      *
734      * @see #unregisterDisplayListener
735      */
registerDisplayListener(DisplayListener listener, Handler handler)736     public void registerDisplayListener(DisplayListener listener, Handler handler) {
737         registerDisplayListener(listener, handler, EVENT_FLAG_DISPLAY_ADDED
738                 | EVENT_FLAG_DISPLAY_CHANGED | EVENT_FLAG_DISPLAY_REMOVED);
739     }
740 
741     /**
742      * Registers a display listener to receive notifications about given display event types.
743      *
744      * @param listener The listener to register.
745      * @param handler The handler on which the listener should be invoked, or null
746      * if the listener should be invoked on the calling thread's looper.
747      * @param eventsMask A bitmask of the event types for which this listener is subscribed.
748      *
749      * @see #EVENT_FLAG_DISPLAY_ADDED
750      * @see #EVENT_FLAG_DISPLAY_CHANGED
751      * @see #EVENT_FLAG_DISPLAY_REMOVED
752      * @see #EVENT_FLAG_DISPLAY_BRIGHTNESS
753      * @see #registerDisplayListener(DisplayListener, Handler)
754      * @see #unregisterDisplayListener
755      *
756      * @hide
757      */
registerDisplayListener(@onNull DisplayListener listener, @Nullable Handler handler, @EventsMask long eventsMask)758     public void registerDisplayListener(@NonNull DisplayListener listener,
759             @Nullable Handler handler, @EventsMask long eventsMask) {
760         mGlobal.registerDisplayListener(listener, handler, eventsMask);
761     }
762 
763     /**
764      * Unregisters a display listener.
765      *
766      * @param listener The listener to unregister.
767      *
768      * @see #registerDisplayListener
769      */
unregisterDisplayListener(DisplayListener listener)770     public void unregisterDisplayListener(DisplayListener listener) {
771         mGlobal.unregisterDisplayListener(listener);
772     }
773 
774     /**
775      * Starts scanning for available Wifi displays.
776      * The results are sent as a {@link #ACTION_WIFI_DISPLAY_STATUS_CHANGED} broadcast.
777      * <p>
778      * Calls to this method nest and must be matched by an equal number of calls to
779      * {@link #stopWifiDisplayScan()}.
780      * </p><p>
781      * Requires {@link android.Manifest.permission#CONFIGURE_WIFI_DISPLAY}.
782      * </p>
783      *
784      * @hide
785      */
786     @UnsupportedAppUsage
startWifiDisplayScan()787     public void startWifiDisplayScan() {
788         mGlobal.startWifiDisplayScan();
789     }
790 
791     /**
792      * Stops scanning for available Wifi displays.
793      * <p>
794      * Requires {@link android.Manifest.permission#CONFIGURE_WIFI_DISPLAY}.
795      * </p>
796      *
797      * @hide
798      */
799     @UnsupportedAppUsage
stopWifiDisplayScan()800     public void stopWifiDisplayScan() {
801         mGlobal.stopWifiDisplayScan();
802     }
803 
804     /**
805      * Connects to a Wifi display.
806      * The results are sent as a {@link #ACTION_WIFI_DISPLAY_STATUS_CHANGED} broadcast.
807      * <p>
808      * Automatically remembers the display after a successful connection, if not
809      * already remembered.
810      * </p><p>
811      * Requires {@link android.Manifest.permission#CONFIGURE_WIFI_DISPLAY}.
812      * </p>
813      *
814      * @param deviceAddress The MAC address of the device to which we should connect.
815      * @hide
816      */
817     @UnsupportedAppUsage
connectWifiDisplay(String deviceAddress)818     public void connectWifiDisplay(String deviceAddress) {
819         mGlobal.connectWifiDisplay(deviceAddress);
820     }
821 
822     /** @hide */
823     @UnsupportedAppUsage
pauseWifiDisplay()824     public void pauseWifiDisplay() {
825         mGlobal.pauseWifiDisplay();
826     }
827 
828     /** @hide */
829     @UnsupportedAppUsage
resumeWifiDisplay()830     public void resumeWifiDisplay() {
831         mGlobal.resumeWifiDisplay();
832     }
833 
834     /**
835      * Disconnects from the current Wifi display.
836      * The results are sent as a {@link #ACTION_WIFI_DISPLAY_STATUS_CHANGED} broadcast.
837      * @hide
838      */
839     @UnsupportedAppUsage
disconnectWifiDisplay()840     public void disconnectWifiDisplay() {
841         mGlobal.disconnectWifiDisplay();
842     }
843 
844     /**
845      * Renames a Wifi display.
846      * <p>
847      * The display must already be remembered for this call to succeed.  In other words,
848      * we must already have successfully connected to the display at least once and then
849      * not forgotten it.
850      * </p><p>
851      * Requires {@link android.Manifest.permission#CONFIGURE_WIFI_DISPLAY}.
852      * </p>
853      *
854      * @param deviceAddress The MAC address of the device to rename.
855      * @param alias The alias name by which to remember the device, or null
856      * or empty if no alias should be used.
857      * @hide
858      */
859     @UnsupportedAppUsage
renameWifiDisplay(String deviceAddress, String alias)860     public void renameWifiDisplay(String deviceAddress, String alias) {
861         mGlobal.renameWifiDisplay(deviceAddress, alias);
862     }
863 
864     /**
865      * Forgets a previously remembered Wifi display.
866      * <p>
867      * Automatically disconnects from the display if currently connected to it.
868      * </p><p>
869      * Requires {@link android.Manifest.permission#CONFIGURE_WIFI_DISPLAY}.
870      * </p>
871      *
872      * @param deviceAddress The MAC address of the device to forget.
873      * @hide
874      */
875     @UnsupportedAppUsage
forgetWifiDisplay(String deviceAddress)876     public void forgetWifiDisplay(String deviceAddress) {
877         mGlobal.forgetWifiDisplay(deviceAddress);
878     }
879 
880     /**
881      * Gets the current Wifi display status.
882      * Watch for changes in the status by registering a broadcast receiver for
883      * {@link #ACTION_WIFI_DISPLAY_STATUS_CHANGED}.
884      *
885      * @return The current Wifi display status.
886      * @hide
887      */
888     @UnsupportedAppUsage
getWifiDisplayStatus()889     public WifiDisplayStatus getWifiDisplayStatus() {
890         return mGlobal.getWifiDisplayStatus();
891     }
892 
893     /**
894      * Set the level of color saturation to apply to the display.
895      * @param level The amount of saturation to apply, between 0 and 1 inclusive.
896      * 0 produces a grayscale image, 1 is normal.
897      *
898      * @hide
899      * @deprecated use {@link ColorDisplayManager#setSaturationLevel(int)} instead. The level passed
900      * as a parameter here will be rounded to the nearest hundredth.
901      */
902     @SystemApi
903     @RequiresPermission(Manifest.permission.CONTROL_DISPLAY_SATURATION)
setSaturationLevel(float level)904     public void setSaturationLevel(float level) {
905         if (level < 0f || level > 1f) {
906             throw new IllegalArgumentException("Saturation level must be between 0 and 1");
907         }
908         final ColorDisplayManager cdm = mContext.getSystemService(ColorDisplayManager.class);
909         cdm.setSaturationLevel(Math.round(level * 100f));
910     }
911 
912     /**
913      * Sets the HDR types that have been disabled by user.
914      * @param userDisabledTypes the HDR types to disable.
915      * @hide
916      */
917     @TestApi
918     @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
setUserDisabledHdrTypes(@onNull @drType int[] userDisabledTypes)919     public void setUserDisabledHdrTypes(@NonNull @HdrType int[] userDisabledTypes) {
920         mGlobal.setUserDisabledHdrTypes(userDisabledTypes);
921     }
922 
923     /**
924      * Sets whether or not the user disabled HDR types are returned from
925      * {@link Display#getHdrCapabilities}.
926      *
927      * @param areUserDisabledHdrTypesAllowed If true, the user-disabled types
928      * are ignored and returned, if the display supports them. If false, the
929      * user-disabled types are taken into consideration and are never returned,
930      * even if the display supports them.
931      * @hide
932      */
933     @TestApi
934     @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
setAreUserDisabledHdrTypesAllowed(boolean areUserDisabledHdrTypesAllowed)935     public void setAreUserDisabledHdrTypesAllowed(boolean areUserDisabledHdrTypesAllowed) {
936         mGlobal.setAreUserDisabledHdrTypesAllowed(areUserDisabledHdrTypesAllowed);
937     }
938 
939     /**
940      * Returns whether or not the user-disabled HDR types are returned from
941      * {@link Display#getHdrCapabilities}.
942      *
943      * @hide
944      */
945     @TestApi
areUserDisabledHdrTypesAllowed()946     public boolean areUserDisabledHdrTypesAllowed() {
947         return mGlobal.areUserDisabledHdrTypesAllowed();
948     }
949 
950     /**
951      * Returns the HDR formats disabled by the user.
952      *
953      * @hide
954      */
955     @TestApi
getUserDisabledHdrTypes()956     public @NonNull int[] getUserDisabledHdrTypes() {
957         return mGlobal.getUserDisabledHdrTypes();
958     }
959 
960     /**
961      * Overrides HDR modes for a display device.
962      *
963      * @hide
964      */
965     @RequiresPermission(Manifest.permission.ACCESS_SURFACE_FLINGER)
966     @TestApi
overrideHdrTypes(int displayId, @NonNull int[] modes)967     public void overrideHdrTypes(int displayId, @NonNull int[] modes) {
968         mGlobal.overrideHdrTypes(displayId, modes);
969     }
970 
971     /**
972      * Creates a virtual display.
973      *
974      * @see #createVirtualDisplay(String, int, int, int, Surface, int,
975      * VirtualDisplay.Callback, Handler)
976      */
createVirtualDisplay(@onNull String name, @IntRange(from = 1) int width, @IntRange(from = 1) int height, @IntRange(from = 1) int densityDpi, @Nullable Surface surface, @VirtualDisplayFlag int flags)977     public VirtualDisplay createVirtualDisplay(@NonNull String name,
978             @IntRange(from = 1) int width,
979             @IntRange(from = 1) int height,
980             @IntRange(from = 1) int densityDpi,
981             @Nullable Surface surface,
982             @VirtualDisplayFlag int flags) {
983         return createVirtualDisplay(name, width, height, densityDpi, surface, flags, null, null);
984     }
985 
986     /**
987      * Creates a virtual display.
988      * <p>
989      * The content of a virtual display is rendered to a {@link Surface} provided
990      * by the application.
991      * </p><p>
992      * The virtual display should be {@link VirtualDisplay#release released}
993      * when no longer needed.  Because a virtual display renders to a surface
994      * provided by the application, it will be released automatically when the
995      * process terminates and all remaining windows on it will be forcibly removed.
996      * </p><p>
997      * The behavior of the virtual display depends on the flags that are provided
998      * to this method.  By default, virtual displays are created to be private,
999      * non-presentation and unsecure.  Permissions may be required to use certain flags.
1000      * </p><p>
1001      * As of {@link android.os.Build.VERSION_CODES#KITKAT_WATCH}, the surface may
1002      * be attached or detached dynamically using {@link VirtualDisplay#setSurface}.
1003      * Previously, the surface had to be non-null when {@link #createVirtualDisplay}
1004      * was called and could not be changed for the lifetime of the display.
1005      * </p><p>
1006      * Detaching the surface that backs a virtual display has a similar effect to
1007      * turning off the screen.
1008      * </p>
1009      *
1010      * @param name The name of the virtual display, must be non-empty.
1011      * @param width The width of the virtual display in pixels, must be greater than 0.
1012      * @param height The height of the virtual display in pixels, must be greater than 0.
1013      * @param densityDpi The density of the virtual display in dpi, must be greater than 0.
1014      * @param surface The surface to which the content of the virtual display should
1015      * be rendered, or null if there is none initially.
1016      * @param flags A combination of virtual display flags:
1017      * {@link #VIRTUAL_DISPLAY_FLAG_PUBLIC}, {@link #VIRTUAL_DISPLAY_FLAG_PRESENTATION},
1018      * {@link #VIRTUAL_DISPLAY_FLAG_SECURE}, {@link #VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY},
1019      * or {@link #VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR}.
1020      * @param callback Callback to call when the state of the {@link VirtualDisplay} changes
1021      * @param handler The handler on which the listener should be invoked, or null
1022      * if the listener should be invoked on the calling thread's looper.
1023      * @return The newly created virtual display, or null if the application could
1024      * not create the virtual display.
1025      *
1026      * @throws SecurityException if the caller does not have permission to create
1027      * a virtual display with the specified flags.
1028      */
createVirtualDisplay(@onNull String name, @IntRange(from = 1) int width, @IntRange(from = 1) int height, @IntRange(from = 1) int densityDpi, @Nullable Surface surface, @VirtualDisplayFlag int flags, @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler)1029     public VirtualDisplay createVirtualDisplay(@NonNull String name,
1030             @IntRange(from = 1) int width,
1031             @IntRange(from = 1) int height,
1032             @IntRange(from = 1) int densityDpi,
1033             @Nullable Surface surface,
1034             @VirtualDisplayFlag int flags,
1035             @Nullable VirtualDisplay.Callback callback,
1036             @Nullable Handler handler) {
1037         final VirtualDisplayConfig.Builder builder =
1038                 new VirtualDisplayConfig.Builder(name, width, height, densityDpi);
1039         builder.setFlags(flags);
1040         if (surface != null) {
1041             builder.setSurface(surface);
1042         }
1043         return createVirtualDisplay(builder.build(), handler, callback);
1044     }
1045 
1046     /**
1047      * Creates a virtual display.
1048      *
1049      * @see #createVirtualDisplay(VirtualDisplayConfig, Handler, VirtualDisplay.Callback)
1050      */
1051     @Nullable
createVirtualDisplay(@onNull VirtualDisplayConfig config)1052     public VirtualDisplay createVirtualDisplay(@NonNull VirtualDisplayConfig config) {
1053         return createVirtualDisplay(config, /*handler=*/null, /*callback=*/null);
1054     }
1055 
1056     /**
1057      * Creates a virtual display.
1058      * <p>
1059      * The content of a virtual display is rendered to a {@link Surface} provided
1060      * by the application.
1061      * </p><p>
1062      * The virtual display should be {@link VirtualDisplay#release released}
1063      * when no longer needed.  Because a virtual display renders to a surface
1064      * provided by the application, it will be released automatically when the
1065      * process terminates and all remaining windows on it will be forcibly removed.
1066      * </p><p>
1067      * The behavior of the virtual display depends on the flags that are provided
1068      * to this method.  By default, virtual displays are created to be private,
1069      * non-presentation and unsecure.  Permissions may be required to use certain flags.
1070      * </p><p>
1071      * As of {@link android.os.Build.VERSION_CODES#KITKAT_WATCH}, the surface may
1072      * be attached or detached dynamically using {@link VirtualDisplay#setSurface}.
1073      * Previously, the surface had to be non-null when {@link #createVirtualDisplay}
1074      * was called and could not be changed for the lifetime of the display.
1075      * </p><p>
1076      * Detaching the surface that backs a virtual display has a similar effect to
1077      * turning off the screen.
1078      * </p>
1079      *
1080      * @param config The configuration of the virtual display, must be non-null.
1081      * @param handler The handler on which the listener should be invoked, or null
1082      * if the listener should be invoked on the calling thread's looper.
1083      * @param callback Callback to call when the state of the {@link VirtualDisplay} changes
1084      * @return The newly created virtual display, or null if the application could
1085      * not create the virtual display.
1086      *
1087      * @throws SecurityException if the caller does not have permission to create
1088      * a virtual display with flags specified in the configuration.
1089      */
1090     @Nullable
createVirtualDisplay( @onNull VirtualDisplayConfig config, @Nullable Handler handler, @Nullable VirtualDisplay.Callback callback)1091     public VirtualDisplay createVirtualDisplay(
1092             @NonNull VirtualDisplayConfig config,
1093             @Nullable Handler handler,
1094             @Nullable VirtualDisplay.Callback callback) {
1095         return createVirtualDisplay(null /* projection */, config, callback, handler);
1096     }
1097 
1098     // TODO : Remove this hidden API after remove all callers. (Refer to MultiDisplayService)
1099     /** @hide */
createVirtualDisplay( @ullable MediaProjection projection, @NonNull String name, @IntRange(from = 1) int width, @IntRange(from = 1) int height, @IntRange(from = 1) int densityDpi, @Nullable Surface surface, @VirtualDisplayFlag int flags, @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler, @Nullable String uniqueId)1100     public VirtualDisplay createVirtualDisplay(
1101             @Nullable MediaProjection projection,
1102             @NonNull String name,
1103             @IntRange(from = 1) int width,
1104             @IntRange(from = 1) int height,
1105             @IntRange(from = 1) int densityDpi,
1106             @Nullable Surface surface,
1107             @VirtualDisplayFlag int flags,
1108             @Nullable VirtualDisplay.Callback callback,
1109             @Nullable Handler handler,
1110             @Nullable String uniqueId) {
1111         final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(name, width,
1112                 height, densityDpi);
1113         builder.setFlags(flags);
1114         if (uniqueId != null) {
1115             builder.setUniqueId(uniqueId);
1116         }
1117         if (surface != null) {
1118             builder.setSurface(surface);
1119         }
1120         return createVirtualDisplay(projection, builder.build(), callback, handler);
1121     }
1122 
1123     /** @hide */
createVirtualDisplay(@ullable MediaProjection projection, @NonNull VirtualDisplayConfig virtualDisplayConfig, @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler)1124     public VirtualDisplay createVirtualDisplay(@Nullable MediaProjection projection,
1125             @NonNull VirtualDisplayConfig virtualDisplayConfig,
1126             @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
1127         Executor executor = null;
1128         // If callback is null, the executor will not be used. Avoid creating the handler and the
1129         // handler executor.
1130         if (callback != null) {
1131             executor = new HandlerExecutor(
1132                     Handler.createAsync(handler != null ? handler.getLooper() : Looper.myLooper()));
1133         }
1134         return mGlobal.createVirtualDisplay(mContext, projection, virtualDisplayConfig, callback,
1135                 executor);
1136     }
1137 
1138     /**
1139      * Gets the stable device display size, in pixels.
1140      *
1141      * This should really only be used for things like server-side filtering of available
1142      * applications. Most applications don't need the level of stability guaranteed by this and
1143      * should instead query either the size of the display they're currently running on or the
1144      * size of the default display.
1145      * @hide
1146      */
1147     @SystemApi
getStableDisplaySize()1148     public Point getStableDisplaySize() {
1149         return mGlobal.getStableDisplaySize();
1150     }
1151 
1152     /**
1153      * Fetch {@link BrightnessChangeEvent}s.
1154      * @hide until we make it a system api.
1155      */
1156     @SystemApi
1157     @RequiresPermission(Manifest.permission.BRIGHTNESS_SLIDER_USAGE)
getBrightnessEvents()1158     public List<BrightnessChangeEvent> getBrightnessEvents() {
1159         return mGlobal.getBrightnessEvents(mContext.getOpPackageName());
1160     }
1161 
1162     /**
1163      * Fetch {@link AmbientBrightnessDayStats}s.
1164      *
1165      * @hide until we make it a system api
1166      */
1167     @SystemApi
1168     @RequiresPermission(Manifest.permission.ACCESS_AMBIENT_LIGHT_STATS)
getAmbientBrightnessStats()1169     public List<AmbientBrightnessDayStats> getAmbientBrightnessStats() {
1170         return mGlobal.getAmbientBrightnessStats();
1171     }
1172 
1173     /**
1174      * Sets the global display brightness configuration.
1175      *
1176      * @hide
1177      */
1178     @SystemApi
1179     @RequiresPermission(Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS)
setBrightnessConfiguration(BrightnessConfiguration c)1180     public void setBrightnessConfiguration(BrightnessConfiguration c) {
1181         setBrightnessConfigurationForUser(c, mContext.getUserId(), mContext.getPackageName());
1182     }
1183 
1184     /**
1185      * Sets the brightness configuration for the specified display.
1186      * If the specified display doesn't exist, then this will return and do nothing.
1187      *
1188      * @hide
1189      */
1190     @SystemApi
1191     @RequiresPermission(Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS)
setBrightnessConfigurationForDisplay(@onNull BrightnessConfiguration c, @NonNull String uniqueId)1192     public void setBrightnessConfigurationForDisplay(@NonNull BrightnessConfiguration c,
1193             @NonNull String uniqueId) {
1194         mGlobal.setBrightnessConfigurationForDisplay(c, uniqueId, mContext.getUserId(),
1195                 mContext.getPackageName());
1196     }
1197 
1198     /**
1199      * Gets the brightness configuration for the specified display and default user.
1200      * Returns the default configuration if unset or display is invalid.
1201      *
1202      * @hide
1203      */
1204     @Nullable
1205     @SystemApi
1206     @RequiresPermission(Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS)
getBrightnessConfigurationForDisplay( @onNull String uniqueId)1207     public BrightnessConfiguration getBrightnessConfigurationForDisplay(
1208             @NonNull String uniqueId) {
1209         return mGlobal.getBrightnessConfigurationForDisplay(uniqueId, mContext.getUserId());
1210     }
1211 
1212     /**
1213      * Sets the global display brightness configuration for a specific user.
1214      *
1215      * Note this requires the INTERACT_ACROSS_USERS permission if setting the configuration for a
1216      * user other than the one you're currently running as.
1217      *
1218      * @hide
1219      */
setBrightnessConfigurationForUser(BrightnessConfiguration c, int userId, String packageName)1220     public void setBrightnessConfigurationForUser(BrightnessConfiguration c, int userId,
1221             String packageName) {
1222         mGlobal.setBrightnessConfigurationForUser(c, userId, packageName);
1223     }
1224 
1225     /**
1226      * Gets the global display brightness configuration or the default curve if one hasn't been set.
1227      *
1228      * @hide
1229      */
1230     @SystemApi
1231     @RequiresPermission(Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS)
getBrightnessConfiguration()1232     public BrightnessConfiguration getBrightnessConfiguration() {
1233         return getBrightnessConfigurationForUser(mContext.getUserId());
1234     }
1235 
1236     /**
1237      * Gets the global display brightness configuration or the default curve if one hasn't been set
1238      * for a specific user.
1239      *
1240      * Note this requires the INTERACT_ACROSS_USERS permission if getting the configuration for a
1241      * user other than the one you're currently running as.
1242      *
1243      * @hide
1244      */
getBrightnessConfigurationForUser(int userId)1245     public BrightnessConfiguration getBrightnessConfigurationForUser(int userId) {
1246         return mGlobal.getBrightnessConfigurationForUser(userId);
1247     }
1248 
1249     /**
1250      * Gets the default global display brightness configuration or null one hasn't
1251      * been configured.
1252      *
1253      * @hide
1254      */
1255     @SystemApi
1256     @RequiresPermission(Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS)
1257     @Nullable
getDefaultBrightnessConfiguration()1258     public BrightnessConfiguration getDefaultBrightnessConfiguration() {
1259         return mGlobal.getDefaultBrightnessConfiguration();
1260     }
1261 
1262 
1263     /**
1264      * Gets the last requested minimal post processing setting for the display with displayId.
1265      *
1266      * @hide
1267      */
1268     @TestApi
isMinimalPostProcessingRequested(int displayId)1269     public boolean isMinimalPostProcessingRequested(int displayId) {
1270         return mGlobal.isMinimalPostProcessingRequested(displayId);
1271     }
1272 
1273     /**
1274      * Temporarily sets the brightness of the display.
1275      * <p>
1276      * Requires the {@link android.Manifest.permission#CONTROL_DISPLAY_BRIGHTNESS} permission.
1277      * </p>
1278      *
1279      * @param brightness The brightness value from 0.0f to 1.0f.
1280      *
1281      * @hide Requires signature permission.
1282      */
setTemporaryBrightness(int displayId, float brightness)1283     public void setTemporaryBrightness(int displayId, float brightness) {
1284         mGlobal.setTemporaryBrightness(displayId, brightness);
1285     }
1286 
1287 
1288     /**
1289      * Sets the brightness of the specified display.
1290      * <p>
1291      * Requires the {@link android.Manifest.permission#CONTROL_DISPLAY_BRIGHTNESS}
1292      * permission.
1293      * </p>
1294      *
1295      * @param displayId the logical display id
1296      * @param brightness The brightness value from 0.0f to 1.0f.
1297      *
1298      * @hide
1299      */
1300     @RequiresPermission(Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS)
setBrightness(int displayId, @FloatRange(from = 0f, to = 1f) float brightness)1301     public void setBrightness(int displayId, @FloatRange(from = 0f, to = 1f) float brightness) {
1302         mGlobal.setBrightness(displayId, brightness);
1303     }
1304 
1305 
1306     /**
1307      * Gets the brightness of the specified display.
1308      * <p>
1309      * Requires the {@link android.Manifest.permission#CONTROL_DISPLAY_BRIGHTNESS}
1310      * permission.
1311      * </p>
1312      *
1313      * @param displayId The display of which brightness value to get from.
1314      *
1315      * @hide
1316      */
1317     @RequiresPermission(Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS)
1318     @FloatRange(from = 0f, to = 1f)
getBrightness(int displayId)1319     public float getBrightness(int displayId) {
1320         return mGlobal.getBrightness(displayId);
1321     }
1322 
1323 
1324     /**
1325      * Temporarily sets the auto brightness adjustment factor.
1326      * <p>
1327      * Requires the {@link android.Manifest.permission#CONTROL_DISPLAY_BRIGHTNESS} permission.
1328      * </p>
1329      *
1330      * @param adjustment The adjustment factor from -1.0 to 1.0.
1331      *
1332      * @hide Requires signature permission.
1333      */
setTemporaryAutoBrightnessAdjustment(float adjustment)1334     public void setTemporaryAutoBrightnessAdjustment(float adjustment) {
1335         mGlobal.setTemporaryAutoBrightnessAdjustment(adjustment);
1336     }
1337 
1338     /**
1339      * Returns the minimum brightness curve, which guarantess that any brightness curve that dips
1340      * below it is rejected by the system.
1341      * This prevent auto-brightness from setting the screen so dark as to prevent the user from
1342      * resetting or disabling it, and maps lux to the absolute minimum nits that are still readable
1343      * in that ambient brightness.
1344      *
1345      * @return The minimum brightness curve (as lux values and their corresponding nits values).
1346      *
1347      * @hide
1348      */
1349     @SystemApi
getMinimumBrightnessCurve()1350     public Pair<float[], float[]> getMinimumBrightnessCurve() {
1351         return mGlobal.getMinimumBrightnessCurve();
1352     }
1353 
1354     /**
1355      * Sets the global default {@link Display.Mode}.  The display mode includes preference for
1356      * resolution and refresh rate. The mode change is applied globally, i.e. to all the connected
1357      * displays. If the mode specified is not supported by a connected display, then no mode change
1358      * occurs for that display.
1359      *
1360      * @param mode The {@link Display.Mode} to set, which can include resolution and/or
1361      * refresh-rate. It is created using {@link Display.Mode.Builder}.
1362      *`
1363      * @hide
1364      */
1365     @TestApi
1366     @RequiresPermission(Manifest.permission.MODIFY_USER_PREFERRED_DISPLAY_MODE)
setGlobalUserPreferredDisplayMode(@onNull Display.Mode mode)1367     public void setGlobalUserPreferredDisplayMode(@NonNull Display.Mode mode) {
1368         // Create a new object containing default values for the unused fields like mode ID and
1369         // alternative refresh rates.
1370         Display.Mode preferredMode = new Display.Mode(mode.getPhysicalWidth(),
1371                 mode.getPhysicalHeight(), mode.getRefreshRate());
1372         mGlobal.setUserPreferredDisplayMode(Display.INVALID_DISPLAY, preferredMode);
1373     }
1374 
1375     /**
1376      * Removes the global user preferred display mode.
1377      * User preferred display mode is cleared for all the connected displays.
1378      *
1379      * @hide
1380      */
1381     @TestApi
1382     @RequiresPermission(Manifest.permission.MODIFY_USER_PREFERRED_DISPLAY_MODE)
clearGlobalUserPreferredDisplayMode()1383     public void clearGlobalUserPreferredDisplayMode() {
1384         mGlobal.setUserPreferredDisplayMode(Display.INVALID_DISPLAY, null);
1385     }
1386 
1387     /**
1388      * Returns the global user preferred display mode.
1389      * If no user preferred mode has been set, or it has been cleared, this method returns null.
1390      *
1391      * @hide
1392      */
1393     @TestApi
1394     @Nullable
getGlobalUserPreferredDisplayMode()1395     public Display.Mode getGlobalUserPreferredDisplayMode() {
1396         return mGlobal.getUserPreferredDisplayMode(Display.INVALID_DISPLAY);
1397     }
1398 
1399     /**
1400      * Sets the HDR conversion mode for the device.
1401      *
1402      * @param hdrConversionMode The {@link HdrConversionMode} to set.
1403      * Note, {@code HdrConversionMode.preferredHdrOutputType} is only applicable when
1404      * {@code HdrConversionMode.conversionMode} is {@link HdrConversionMode#HDR_CONVERSION_FORCE}.
1405      * If {@code HdrConversionMode.preferredHdrOutputType} is not set in case when
1406      * {@code HdrConversionMode.conversionMode} is {@link HdrConversionMode#HDR_CONVERSION_FORCE},
1407      * it means that preferred output type is SDR.
1408      *
1409      * @throws IllegalArgumentException if hdrConversionMode.preferredHdrOutputType is set but
1410      * hdrConversionMode.conversionMode is not {@link HdrConversionMode#HDR_CONVERSION_FORCE}.
1411      *
1412      * @see #getHdrConversionMode
1413      * @see #getHdrConversionModeSetting
1414      * @see #getSupportedHdrOutputTypes
1415      * @hide
1416      */
1417     @TestApi
1418     @RequiresPermission(Manifest.permission.MODIFY_HDR_CONVERSION_MODE)
setHdrConversionMode(@onNull HdrConversionMode hdrConversionMode)1419     public void setHdrConversionMode(@NonNull HdrConversionMode hdrConversionMode) {
1420         mGlobal.setHdrConversionMode(hdrConversionMode);
1421     }
1422 
1423     /**
1424      * Returns the {@link HdrConversionMode} of the device, which is set by the user.
1425      *
1426      * When {@link HdrConversionMode#getConversionMode} is
1427      * {@link HdrConversionMode#HDR_CONVERSION_SYSTEM}, the
1428      * {@link HdrConversionMode#getPreferredHdrOutputType} depicts the systemPreferredHdrOutputType.
1429      * The HDR conversion mode chosen by user which considers the app override is returned. Apps can
1430      * override HDR conversion using
1431      * {@link android.view.WindowManager.LayoutParams#setHdrConversionEnabled(boolean)}.
1432      */
1433     @NonNull
getHdrConversionMode()1434     public HdrConversionMode getHdrConversionMode() {
1435         return mGlobal.getHdrConversionMode();
1436     }
1437 
1438     /**
1439      * Returns the {@link HdrConversionMode} of the device, which is set by the user.
1440 
1441      * The HDR conversion mode chosen by user is returned irrespective of whether HDR conversion
1442      * is disabled by an app.
1443      *
1444      * @see #setHdrConversionMode
1445      * @see #getSupportedHdrOutputTypes
1446      * @see #getHdrConversionMode
1447      * @hide
1448      */
1449     @TestApi
1450     @NonNull
getHdrConversionModeSetting()1451     public HdrConversionMode getHdrConversionModeSetting() {
1452         return mGlobal.getHdrConversionModeSetting();
1453     }
1454 
1455     /**
1456      * Returns the HDR output types supported by the device.
1457      *
1458      * @see #getHdrConversionMode
1459      * @see #setHdrConversionMode
1460      * @hide
1461      */
1462     @TestApi
1463     @NonNull
getSupportedHdrOutputTypes()1464     public @HdrType int[] getSupportedHdrOutputTypes() {
1465         return mGlobal.getSupportedHdrOutputTypes();
1466     }
1467 
1468     /**
1469      * When enabled the app requested mode is always selected regardless of user settings and
1470      * policies for low brightness, low battery, etc.
1471      *
1472      * @hide
1473      */
1474     @TestApi
1475     @RequiresPermission(Manifest.permission.OVERRIDE_DISPLAY_MODE_REQUESTS)
setShouldAlwaysRespectAppRequestedMode(boolean enabled)1476     public void setShouldAlwaysRespectAppRequestedMode(boolean enabled) {
1477         mGlobal.setShouldAlwaysRespectAppRequestedMode(enabled);
1478     }
1479 
1480     /**
1481      * Returns whether we are running in a mode which always selects the app requested display mode
1482      * and ignores user settings and policies for low brightness, low battery etc.
1483      *
1484      * @hide
1485      */
1486     @TestApi
1487     @RequiresPermission(Manifest.permission.OVERRIDE_DISPLAY_MODE_REQUESTS)
shouldAlwaysRespectAppRequestedMode()1488     public boolean shouldAlwaysRespectAppRequestedMode() {
1489         return mGlobal.shouldAlwaysRespectAppRequestedMode();
1490     }
1491 
1492     /**
1493      * Returns whether device supports seamless refresh rate switching.
1494      *
1495      * Match content frame rate setting has three options: seamless, non-seamless and never.
1496      * The seamless option does nothing if the device does not support seamless refresh rate
1497      * switching. This API is used in such a case to hide the seamless option.
1498      *
1499      * @see DisplayManager#setRefreshRateSwitchingType
1500      * @see DisplayManager#getMatchContentFrameRateUserPreference
1501      * @hide
1502      */
supportsSeamlessRefreshRateSwitching()1503     public boolean supportsSeamlessRefreshRateSwitching() {
1504         return mContext.getResources().getBoolean(
1505                 R.bool.config_supportsSeamlessRefreshRateSwitching);
1506     }
1507 
1508     /**
1509      * Sets the refresh rate switching type.
1510      * This matches {@link android.provider.Settings.Secure.MATCH_CONTENT_FRAME_RATE}
1511      *
1512      * @hide
1513      */
1514     @TestApi
1515     @RequiresPermission(Manifest.permission.MODIFY_REFRESH_RATE_SWITCHING_TYPE)
setRefreshRateSwitchingType(@witchingType int newValue)1516     public void setRefreshRateSwitchingType(@SwitchingType int newValue) {
1517         mGlobal.setRefreshRateSwitchingType(newValue);
1518     }
1519 
1520     /**
1521      * Returns the user preference for "Match content frame rate".
1522      * <p>
1523      * Never: Even if the app requests it, the device will never try to match its output to the
1524      * original frame rate of the content.
1525      * </p><p>
1526      * Seamless: If the app requests it, the device will match its output to the original frame
1527      * rate of the content, ONLY if the display can transition seamlessly.
1528      * </p><p>
1529      * Always: If the app requests it, the device will match its output to the original
1530      * frame rate of the content. This may cause the screen to go blank for a
1531      * second when exiting or entering a video playback.
1532      * </p>
1533      */
getMatchContentFrameRateUserPreference()1534     @MatchContentFrameRateType public int getMatchContentFrameRateUserPreference() {
1535         return toMatchContentFrameRateSetting(mGlobal.getRefreshRateSwitchingType());
1536     }
1537 
1538     @MatchContentFrameRateType
toMatchContentFrameRateSetting(@witchingType int switchingType)1539     private int toMatchContentFrameRateSetting(@SwitchingType int switchingType) {
1540         switch (switchingType) {
1541             case SWITCHING_TYPE_NONE:
1542                 return MATCH_CONTENT_FRAMERATE_NEVER;
1543             case SWITCHING_TYPE_RENDER_FRAME_RATE_ONLY:
1544             case SWITCHING_TYPE_WITHIN_GROUPS:
1545                 return MATCH_CONTENT_FRAMERATE_SEAMLESSS_ONLY;
1546             case SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS:
1547                 return MATCH_CONTENT_FRAMERATE_ALWAYS;
1548             default:
1549                 Slog.e(TAG, switchingType + " is not a valid value of switching type.");
1550                 return MATCH_CONTENT_FRAMERATE_UNKNOWN;
1551         }
1552     }
1553 
1554     /**
1555      * Creates a VirtualDisplay that will mirror the content of displayIdToMirror
1556      * @param name The name for the virtual display
1557      * @param width The initial width for the virtual display
1558      * @param height The initial height for the virtual display
1559      * @param displayIdToMirror The displayId that will be mirrored into the virtual display.
1560      * @return VirtualDisplay that can be used to update properties.
1561      *
1562      * @hide
1563      */
1564     @RequiresPermission(Manifest.permission.CAPTURE_VIDEO_OUTPUT)
1565     @Nullable
1566     @SystemApi
createVirtualDisplay(@onNull String name, int width, int height, int displayIdToMirror, @Nullable Surface surface)1567     public static VirtualDisplay createVirtualDisplay(@NonNull String name, int width, int height,
1568             int displayIdToMirror, @Nullable Surface surface) {
1569         IDisplayManager sDm = IDisplayManager.Stub.asInterface(
1570                 ServiceManager.getService(Context.DISPLAY_SERVICE));
1571         IPackageManager sPackageManager = IPackageManager.Stub.asInterface(
1572                 ServiceManager.getService("package"));
1573 
1574         // Density doesn't matter since this virtual display is only used for mirroring.
1575         VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(name, width,
1576                 height, 1 /* densityDpi */)
1577                 .setFlags(VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR)
1578                 .setDisplayIdToMirror(displayIdToMirror);
1579         if (surface != null) {
1580             builder.setSurface(surface);
1581         }
1582         VirtualDisplayConfig virtualDisplayConfig = builder.build();
1583 
1584         String[] packages;
1585         try {
1586             packages = sPackageManager.getPackagesForUid(Process.myUid());
1587         } catch (RemoteException ex) {
1588             throw ex.rethrowFromSystemServer();
1589         }
1590 
1591         // Just use the first one since it just needs to match the package when looking it up by
1592         // calling UID in system server.
1593         // The call may come from a rooted device, in that case the requesting uid will be root so
1594         // it will not have any package name
1595         String packageName = packages == null ? null : packages[0];
1596         DisplayManagerGlobal.VirtualDisplayCallback
1597                 callbackWrapper = new DisplayManagerGlobal.VirtualDisplayCallback(null, null);
1598         int displayId;
1599         try {
1600             displayId = sDm.createVirtualDisplay(virtualDisplayConfig, callbackWrapper, null,
1601                     packageName);
1602         } catch (RemoteException ex) {
1603             throw ex.rethrowFromSystemServer();
1604         }
1605         return DisplayManagerGlobal.getInstance().createVirtualDisplayWrapper(virtualDisplayConfig,
1606                 callbackWrapper, displayId);
1607     }
1608 
1609     /**
1610      * Listens for changes in available display devices.
1611      */
1612     public interface DisplayListener {
1613         /**
1614          * Called whenever a logical display has been added to the system.
1615          * Use {@link DisplayManager#getDisplay} to get more information about
1616          * the display.
1617          *
1618          * @param displayId The id of the logical display that was added.
1619          */
onDisplayAdded(int displayId)1620         void onDisplayAdded(int displayId);
1621 
1622         /**
1623          * Called whenever a logical display has been removed from the system.
1624          *
1625          * @param displayId The id of the logical display that was removed.
1626          */
onDisplayRemoved(int displayId)1627         void onDisplayRemoved(int displayId);
1628 
1629         /**
1630          * Called whenever the properties of a logical {@link android.view.Display},
1631          * such as size and density, have changed.
1632          *
1633          * @param displayId The id of the logical display that changed.
1634          */
onDisplayChanged(int displayId)1635         void onDisplayChanged(int displayId);
1636     }
1637 
1638     /**
1639      * Interface for accessing keys belonging to {@link
1640      * android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER}.
1641      * @hide
1642      */
1643     public interface DeviceConfig {
1644 
1645         /**
1646          * Key for refresh rate in the low zone defined by thresholds.
1647          *
1648          * Note that the name and value don't match because they were added before we had a high
1649          * zone to consider.
1650          * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER
1651          * @see android.R.integer#config_defaultZoneBehavior
1652          */
1653         String KEY_REFRESH_RATE_IN_LOW_ZONE = "refresh_rate_in_zone";
1654 
1655         /**
1656          * Key for accessing the low display brightness thresholds for the configured refresh
1657          * rate zone.
1658          * The value will be a pair of comma separated integers representing the minimum and maximum
1659          * thresholds of the zone, respectively, in display backlight units (i.e. [0, 255]).
1660          *
1661          * Note that the name and value don't match because they were added before we had a high
1662          * zone to consider.
1663          *
1664          * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER
1665          * @see android.R.array#config_brightnessThresholdsOfPeakRefreshRate
1666          * @hide
1667          */
1668         String KEY_FIXED_REFRESH_RATE_LOW_DISPLAY_BRIGHTNESS_THRESHOLDS =
1669                 "peak_refresh_rate_brightness_thresholds";
1670 
1671         /**
1672          * Key for accessing the low ambient brightness thresholds for the configured refresh
1673          * rate zone. The value will be a pair of comma separated integers representing the minimum
1674          * and maximum thresholds of the zone, respectively, in lux.
1675          *
1676          * Note that the name and value don't match because they were added before we had a high
1677          * zone to consider.
1678          *
1679          * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER
1680          * @see android.R.array#config_ambientThresholdsOfPeakRefreshRate
1681          * @hide
1682          */
1683         String KEY_FIXED_REFRESH_RATE_LOW_AMBIENT_BRIGHTNESS_THRESHOLDS =
1684                 "peak_refresh_rate_ambient_thresholds";
1685         /**
1686          * Key for refresh rate in the high zone defined by thresholds.
1687          *
1688          * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER
1689          * @see android.R.integer#config_fixedRefreshRateInHighZone
1690          */
1691         String KEY_REFRESH_RATE_IN_HIGH_ZONE = "refresh_rate_in_high_zone";
1692 
1693         /**
1694          * Key for accessing the display brightness thresholds for the configured refresh rate zone.
1695          * The value will be a pair of comma separated integers representing the minimum and maximum
1696          * thresholds of the zone, respectively, in display backlight units (i.e. [0, 255]).
1697          *
1698          * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER
1699          * @see android.R.array#config_brightnessHighThresholdsOfFixedRefreshRate
1700          * @hide
1701          */
1702         String KEY_FIXED_REFRESH_RATE_HIGH_DISPLAY_BRIGHTNESS_THRESHOLDS =
1703                 "fixed_refresh_rate_high_display_brightness_thresholds";
1704 
1705         /**
1706          * Key for accessing the ambient brightness thresholds for the configured refresh rate zone.
1707          * The value will be a pair of comma separated integers representing the minimum and maximum
1708          * thresholds of the zone, respectively, in lux.
1709          *
1710          * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER
1711          * @see android.R.array#config_ambientHighThresholdsOfFixedRefreshRate
1712          * @hide
1713          */
1714         String KEY_FIXED_REFRESH_RATE_HIGH_AMBIENT_BRIGHTNESS_THRESHOLDS =
1715                 "fixed_refresh_rate_high_ambient_brightness_thresholds";
1716 
1717         /**
1718          * Key for refresh rate when the device is in high brightness mode for sunlight visility.
1719          *
1720          * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER
1721          * @see android.R.integer#config_defaultRefreshRateInHbmSunlight
1722          */
1723         String KEY_REFRESH_RATE_IN_HBM_SUNLIGHT = "refresh_rate_in_hbm_sunlight";
1724 
1725         /**
1726          * Key for refresh rate when the device is in high brightness mode for HDR.
1727          *
1728          * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER
1729          * @see android.R.integer#config_defaultRefreshRateInHbmHdr
1730          */
1731         String KEY_REFRESH_RATE_IN_HBM_HDR = "refresh_rate_in_hbm_hdr";
1732 
1733         /**
1734          * Key for default peak refresh rate
1735          *
1736          * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER
1737          * @see android.R.integer#config_defaultPeakRefreshRate
1738          * @hide
1739          */
1740         String KEY_PEAK_REFRESH_RATE_DEFAULT = "peak_refresh_rate_default";
1741 
1742         // TODO(b/162536543): rename it once it is proved not harmful for users.
1743         /**
1744          * Key for controlling which packages are explicitly blocked from running at refresh rates
1745          * higher than 60hz. An app may be added to this list if they exhibit performance issues at
1746          * higher refresh rates.
1747          *
1748          * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER
1749          * @see android.R.array#config_highRefreshRateBlacklist
1750          * @hide
1751          */
1752         String KEY_HIGH_REFRESH_RATE_BLACKLIST = "high_refresh_rate_blacklist";
1753 
1754         /**
1755          * Key for the brightness throttling data as a String formatted:
1756          * <displayId>,<no of throttling levels>,[<severity as string>,<brightness cap>]
1757          * [,<throttlingId>]?
1758          * Where [<severity as string>,<brightness cap>] is repeated for each throttling level.
1759          * The entirety is repeated for each display and throttling id, separated by a semicolon.
1760          * For example:
1761          * 123,1,critical,0.8;456,2,moderate,0.9,critical,0.7
1762          * 123,1,critical,0.8,default;123,1,moderate,0.6,id_2;456,2,moderate,0.9,critical,0.7
1763          */
1764         String KEY_BRIGHTNESS_THROTTLING_DATA = "brightness_throttling_data";
1765 
1766         /**
1767          * Key for new power controller feature flag. If enabled new DisplayPowerController will
1768          * be used.
1769          * Read value via {@link android.provider.DeviceConfig#getBoolean(String, String, boolean)}
1770          * with {@link android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER} as the namespace.
1771          * @hide
1772          */
1773         String KEY_NEW_POWER_CONTROLLER = "use_newly_structured_display_power_controller";
1774 
1775         /**
1776          * Key for normal brightness mode controller feature flag.
1777          * It enables NormalBrightnessModeController.
1778          * Read value via {@link android.provider.DeviceConfig#getBoolean(String, String, boolean)}
1779          * with {@link android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER} as the namespace.
1780          * @hide
1781          */
1782         String KEY_USE_NORMAL_BRIGHTNESS_MODE_CONTROLLER = "use_normal_brightness_mode_controller";
1783 
1784         /**
1785          * Key for disabling screen wake locks while apps are in cached state.
1786          * Read value via {@link android.provider.DeviceConfig#getBoolean(String, String, boolean)}
1787          * with {@link android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER} as the namespace.
1788          * @hide
1789          */
1790         String KEY_DISABLE_SCREEN_WAKE_LOCKS_WHILE_CACHED =
1791                 "disable_screen_wake_locks_while_cached";
1792     }
1793 
1794     /**
1795      * Helper class to maintain cache of weak references to Display instances.
1796      *
1797      * Note this class is not thread-safe, so external synchronization is needed if accessed
1798      * concurrently.
1799      */
1800     private static final class WeakDisplayCache {
1801         private final SparseArray<WeakReference<Display>> mDisplayCache = new SparseArray<>();
1802 
1803         /**
1804          * Return cached {@link Display} instance for the provided display id.
1805          *
1806          * @param displayId - display id of the requested {@link Display} instance.
1807          * @return cached {@link Display} instance or null
1808          */
get(int displayId)1809         Display get(int displayId) {
1810             WeakReference<Display> wrDisplay = mDisplayCache.get(displayId);
1811             if (wrDisplay == null) {
1812                 return null;
1813             }
1814             return wrDisplay.get();
1815         }
1816 
1817         /**
1818          * Insert new {@link Display} instance in the cache. This replaced the previously cached
1819          * {@link Display} instance, if there's already one with the same display id.
1820          *
1821          * @param display - Display instance to cache.
1822          */
put(Display display)1823         void put(Display display) {
1824             removeStaleEntries();
1825             mDisplayCache.put(display.getDisplayId(), new WeakReference<>(display));
1826         }
1827 
1828         /**
1829          * Evict gc-ed entries from the cache.
1830          */
removeStaleEntries()1831         private void removeStaleEntries() {
1832             ArrayList<Integer> staleEntriesIndices = new ArrayList();
1833             for (int i = 0; i < mDisplayCache.size(); i++) {
1834                 if (mDisplayCache.valueAt(i).get() == null) {
1835                     staleEntriesIndices.add(i);
1836                 }
1837             }
1838 
1839             for (int i = 0; i < staleEntriesIndices.size(); i++) {
1840                 // removeAt call to SparseArray doesn't compact the underlying array
1841                 // so the indices stay valid even after removal.
1842                 mDisplayCache.removeAt(staleEntriesIndices.get(i));
1843             }
1844         }
1845     }
1846 }
1847