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