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 android.Manifest;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.annotation.RequiresPermission;
23 import android.annotation.SystemApi;
24 import android.annotation.SystemService;
25 import android.annotation.TestApi;
26 import android.app.KeyguardManager;
27 import android.compat.annotation.UnsupportedAppUsage;
28 import android.content.Context;
29 import android.content.res.Resources;
30 import android.graphics.Point;
31 import android.media.projection.MediaProjection;
32 import android.os.Handler;
33 import android.util.Pair;
34 import android.util.SparseArray;
35 import android.view.Display;
36 import android.view.Surface;
37 
38 import java.util.ArrayList;
39 import java.util.List;
40 
41 /**
42  * Manages the properties of attached displays.
43  */
44 @SystemService(Context.DISPLAY_SERVICE)
45 public final class DisplayManager {
46     private static final String TAG = "DisplayManager";
47     private static final boolean DEBUG = false;
48 
49     private final Context mContext;
50     private final DisplayManagerGlobal mGlobal;
51 
52     private final Object mLock = new Object();
53     private final SparseArray<Display> mDisplays = new SparseArray<Display>();
54 
55     private final ArrayList<Display> mTempDisplays = new ArrayList<Display>();
56 
57     /**
58      * Broadcast receiver that indicates when the Wifi display status changes.
59      * <p>
60      * The status is provided as a {@link WifiDisplayStatus} object in the
61      * {@link #EXTRA_WIFI_DISPLAY_STATUS} extra.
62      * </p><p>
63      * This broadcast is only sent to registered receivers and can only be sent by the system.
64      * </p>
65      * @hide
66      */
67     @UnsupportedAppUsage
68     public static final String ACTION_WIFI_DISPLAY_STATUS_CHANGED =
69             "android.hardware.display.action.WIFI_DISPLAY_STATUS_CHANGED";
70 
71     /**
72      * Contains a {@link WifiDisplayStatus} object.
73      * @hide
74      */
75     @UnsupportedAppUsage
76     public static final String EXTRA_WIFI_DISPLAY_STATUS =
77             "android.hardware.display.extra.WIFI_DISPLAY_STATUS";
78 
79     /**
80      * Display category: Presentation displays.
81      * <p>
82      * This category can be used to identify secondary displays that are suitable for
83      * use as presentation displays such as external or wireless displays.  Applications
84      * may automatically project their content to presentation displays to provide
85      * richer second screen experiences.
86      * </p>
87      *
88      * @see android.app.Presentation
89      * @see Display#FLAG_PRESENTATION
90      * @see #getDisplays(String)
91      */
92     public static final String DISPLAY_CATEGORY_PRESENTATION =
93             "android.hardware.display.category.PRESENTATION";
94 
95     /**
96      * Virtual display flag: Create a public display.
97      *
98      * <h3>Public virtual displays</h3>
99      * <p>
100      * When this flag is set, the virtual display is public.
101      * </p><p>
102      * A public virtual display behaves just like most any other display that is connected
103      * to the system such as an external or wireless display.  Applications can open
104      * windows on the display and the system may mirror the contents of other displays
105      * onto it.
106      * </p><p>
107      * Creating a public virtual display that isn't restricted to own-content only implicitly
108      * creates an auto-mirroring display. See {@link #VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR} for
109      * restrictions on who is allowed to create an auto-mirroring display.
110      * </p>
111      *
112      * <h3>Private virtual displays</h3>
113      * <p>
114      * When this flag is not set, the virtual display is private as defined by the
115      * {@link Display#FLAG_PRIVATE} display flag.
116      * </p>
117      *
118      * <p>
119      * A private virtual display belongs to the application that created it.  Only the a owner of a
120      * private virtual display and the apps that are already on that display are allowed to place
121      * windows upon it.  The private virtual display also does not participate in display mirroring:
122      * it will neither receive mirrored content from another display nor allow its own content to be
123      * mirrored elsewhere.  More precisely, the only processes that are allowed to enumerate or
124      * interact with the private display are those that have the same UID as the application that
125      * originally created the private virtual display or as the activities that are already on that
126      * display.
127      * </p>
128      *
129      * @see #createVirtualDisplay
130      * @see #VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY
131      * @see #VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR
132      */
133     public static final int VIRTUAL_DISPLAY_FLAG_PUBLIC = 1 << 0;
134 
135     /**
136      * Virtual display flag: Create a presentation display.
137      *
138      * <h3>Presentation virtual displays</h3>
139      * <p>
140      * When this flag is set, the virtual display is registered as a presentation
141      * display in the {@link #DISPLAY_CATEGORY_PRESENTATION presentation display category}.
142      * Applications may automatically project their content to presentation displays
143      * to provide richer second screen experiences.
144      * </p>
145      *
146      * <h3>Non-presentation virtual displays</h3>
147      * <p>
148      * When this flag is not set, the virtual display is not registered as a presentation
149      * display.  Applications can still project their content on the display but they
150      * will typically not do so automatically.  This option is appropriate for
151      * more special-purpose displays.
152      * </p>
153      *
154      * @see android.app.Presentation
155      * @see #createVirtualDisplay
156      * @see #DISPLAY_CATEGORY_PRESENTATION
157      * @see Display#FLAG_PRESENTATION
158      */
159     public static final int VIRTUAL_DISPLAY_FLAG_PRESENTATION = 1 << 1;
160 
161     /**
162      * Virtual display flag: Create a secure display.
163      *
164      * <h3>Secure virtual displays</h3>
165      * <p>
166      * When this flag is set, the virtual display is considered secure as defined
167      * by the {@link Display#FLAG_SECURE} display flag.  The caller promises to take
168      * reasonable measures, such as over-the-air encryption, to prevent the contents
169      * of the display from being intercepted or recorded on a persistent medium.
170      * </p><p>
171      * Creating a secure virtual display requires the CAPTURE_SECURE_VIDEO_OUTPUT permission.
172      * This permission is reserved for use by system components and is not available to
173      * third-party applications.
174      * </p>
175      *
176      * <h3>Non-secure virtual displays</h3>
177      * <p>
178      * When this flag is not set, the virtual display is considered unsecure.
179      * The content of secure windows will be blanked if shown on this display.
180      * </p>
181      *
182      * @see Display#FLAG_SECURE
183      * @see #createVirtualDisplay
184      */
185     public static final int VIRTUAL_DISPLAY_FLAG_SECURE = 1 << 2;
186 
187     /**
188      * Virtual display flag: Only show this display's own content; do not mirror
189      * the content of another display.
190      *
191      * <p>
192      * This flag is used in conjunction with {@link #VIRTUAL_DISPLAY_FLAG_PUBLIC}.
193      * Ordinarily public virtual displays will automatically mirror the content of the
194      * default display if they have no windows of their own.  When this flag is
195      * specified, the virtual display will only ever show its own content and
196      * will be blanked instead if it has no windows.
197      * </p>
198      *
199      * <p>
200      * This flag is mutually exclusive with {@link #VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR}.  If both
201      * flags are specified then the own-content only behavior will be applied.
202      * </p>
203      *
204      * <p>
205      * This behavior of this flag is implied whenever neither {@link #VIRTUAL_DISPLAY_FLAG_PUBLIC}
206      * nor {@link #VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR} have been set.  This flag is only required to
207      * override the default behavior when creating a public display.
208      * </p>
209      *
210      * @see #createVirtualDisplay
211      */
212     public static final int VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY = 1 << 3;
213 
214 
215     /**
216      * Virtual display flag: Allows content to be mirrored on private displays when no content is
217      * being shown.
218      *
219      * <p>
220      * This flag is mutually exclusive with {@link #VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY}.
221      * If both flags are specified then the own-content only behavior will be applied.
222      * </p>
223      *
224      * <p>
225      * The behavior of this flag is implied whenever {@link #VIRTUAL_DISPLAY_FLAG_PUBLIC} is set
226      * and {@link #VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY} has not been set.   This flag is only
227      * required to override the default behavior when creating a private display.
228      * </p>
229      *
230      * <p>
231      * Creating an auto-mirroing virtual display requires the CAPTURE_VIDEO_OUTPUT
232      * or CAPTURE_SECURE_VIDEO_OUTPUT permission.
233      * These permissions are reserved for use by system components and are not available to
234      * third-party applications.
235      *
236      * Alternatively, an appropriate {@link MediaProjection} may be used to create an
237      * auto-mirroring virtual display.
238      * </p>
239      *
240      * @see #createVirtualDisplay
241      */
242     public static final int VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR = 1 << 4;
243 
244     /**
245      * Virtual display flag: Allows content to be displayed on private virtual displays when
246      * keyguard is shown but is insecure.
247      *
248      * <p>
249      * This might be used in a case when the content of a virtual display is captured and sent to an
250      * external hardware display that is not visible to the system directly. This flag will allow
251      * the continued display of content while other displays will be covered by a keyguard which
252      * doesn't require providing credentials to unlock. This means that there is either no password
253      * or other authentication method set, or the device is in a trusted state -
254      * {@link android.service.trust.TrustAgentService} has available and active trust agent.
255      * </p><p>
256      * This flag can only be applied to private displays as defined by the
257      * {@link Display#FLAG_PRIVATE} display flag. It is mutually exclusive with
258      * {@link #VIRTUAL_DISPLAY_FLAG_PUBLIC}. If both flags are specified then this flag's behavior
259      * will not be applied.
260      * </p>
261      *
262      * @see #createVirtualDisplay
263      * @see KeyguardManager#isDeviceSecure()
264      * @see KeyguardManager#isDeviceLocked()
265      * @hide
266      */
267     // TODO (b/114338689): Remove the flag and use IWindowManager#shouldShowWithInsecureKeyguard
268     // TODO: Update name and documentation and un-hide the flag. Don't change the value before that.
269     public static final int VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD = 1 << 5;
270 
271     /**
272      * Virtual display flag: Specifies that the virtual display can be associated with a
273      * touchpad device that matches its uniqueId.
274      *
275      * @see #createVirtualDisplay
276      * @hide
277      */
278     public static final int VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH = 1 << 6;
279 
280     /**
281      * Virtual display flag: Indicates that the orientation of this display device is coupled to
282      * the rotation of its associated logical display.
283      *
284      * @see #createVirtualDisplay
285      * @hide
286      */
287     public static final int VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT = 1 << 7;
288 
289     /**
290      * Virtual display flag: Indicates that the contents will be destroyed once
291      * the display is removed.
292      *
293      * Public virtual displays without this flag will move their content to main display
294      * stack once they're removed. Private vistual displays will always destroy their
295      * content on removal even without this flag.
296      *
297      * @see #createVirtualDisplay
298      * @hide
299      */
300     // TODO (b/114338689): Remove the flag and use WindowManager#REMOVE_CONTENT_MODE_DESTROY
301     public static final int VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL = 1 << 8;
302 
303     /**
304      * Virtual display flag: Indicates that the display should support system decorations. Virtual
305      * displays without this flag shouldn't show home, IME or any other system decorations.
306      * <p>This flag doesn't work without {@link #VIRTUAL_DISPLAY_FLAG_TRUSTED}</p>
307      *
308      * @see #createVirtualDisplay
309      * @see #VIRTUAL_DISPLAY_FLAG_TRUSTED
310      * @hide
311      */
312     // TODO (b/114338689): Remove the flag and use IWindowManager#setShouldShowSystemDecors
313     public static final int VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = 1 << 9;
314 
315     /**
316      * Virtual display flags: Indicates that the display is trusted to show system decorations and
317      * receive inputs without users' touch.
318      *
319      * @see #createVirtualDisplay
320      * @see #VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
321      * @hide
322      */
323     public static final int VIRTUAL_DISPLAY_FLAG_TRUSTED = 1 << 10;
324 
325     /** @hide */
DisplayManager(Context context)326     public DisplayManager(Context context) {
327         mContext = context;
328         mGlobal = DisplayManagerGlobal.getInstance();
329     }
330 
331     /**
332      * Gets information about a logical display.
333      *
334      * The display metrics may be adjusted to provide compatibility
335      * for legacy applications.
336      *
337      * @param displayId The logical display id.
338      * @return The display object, or null if there is no valid display with the given id.
339      */
getDisplay(int displayId)340     public Display getDisplay(int displayId) {
341         synchronized (mLock) {
342             return getOrCreateDisplayLocked(displayId, false /*assumeValid*/);
343         }
344     }
345 
346     /**
347      * Gets all currently valid logical displays.
348      *
349      * @return An array containing all displays.
350      */
getDisplays()351     public Display[] getDisplays() {
352         return getDisplays(null);
353     }
354 
355     /**
356      * Gets all currently valid logical displays of the specified category.
357      * <p>
358      * When there are multiple displays in a category the returned displays are sorted
359      * of preference.  For example, if the requested category is
360      * {@link #DISPLAY_CATEGORY_PRESENTATION} and there are multiple presentation displays
361      * then the displays are sorted so that the first display in the returned array
362      * is the most preferred presentation display.  The application may simply
363      * use the first display or allow the user to choose.
364      * </p>
365      *
366      * @param category The requested display category or null to return all displays.
367      * @return An array containing all displays sorted by order of preference.
368      *
369      * @see #DISPLAY_CATEGORY_PRESENTATION
370      */
getDisplays(String category)371     public Display[] getDisplays(String category) {
372         final int[] displayIds = mGlobal.getDisplayIds();
373         synchronized (mLock) {
374             try {
375                 if (category == null) {
376                     addAllDisplaysLocked(mTempDisplays, displayIds);
377                 } else if (category.equals(DISPLAY_CATEGORY_PRESENTATION)) {
378                     addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_WIFI);
379                     addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_EXTERNAL);
380                     addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_OVERLAY);
381                     addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_VIRTUAL);
382                 }
383                 return mTempDisplays.toArray(new Display[mTempDisplays.size()]);
384             } finally {
385                 mTempDisplays.clear();
386             }
387         }
388     }
389 
addAllDisplaysLocked(ArrayList<Display> displays, int[] displayIds)390     private void addAllDisplaysLocked(ArrayList<Display> displays, int[] displayIds) {
391         for (int i = 0; i < displayIds.length; i++) {
392             Display display = getOrCreateDisplayLocked(displayIds[i], true /*assumeValid*/);
393             if (display != null) {
394                 displays.add(display);
395             }
396         }
397     }
398 
addPresentationDisplaysLocked( ArrayList<Display> displays, int[] displayIds, int matchType)399     private void addPresentationDisplaysLocked(
400             ArrayList<Display> displays, int[] displayIds, int matchType) {
401         for (int i = 0; i < displayIds.length; i++) {
402             Display display = getOrCreateDisplayLocked(displayIds[i], true /*assumeValid*/);
403             if (display != null
404                     && (display.getFlags() & Display.FLAG_PRESENTATION) != 0
405                     && display.getType() == matchType) {
406                 displays.add(display);
407             }
408         }
409     }
410 
getOrCreateDisplayLocked(int displayId, boolean assumeValid)411     private Display getOrCreateDisplayLocked(int displayId, boolean assumeValid) {
412         Display display = mDisplays.get(displayId);
413         if (display == null) {
414             // TODO: We cannot currently provide any override configurations for metrics on displays
415             // other than the display the context is associated with.
416             final Resources resources = mContext.getDisplayId() == displayId
417                     ? mContext.getResources() : null;
418 
419             display = mGlobal.getCompatibleDisplay(displayId, resources);
420             if (display != null) {
421                 mDisplays.put(displayId, display);
422             }
423         } else if (!assumeValid && !display.isValid()) {
424             display = null;
425         }
426         return display;
427     }
428 
429     /**
430      * Registers an display listener to receive notifications about when
431      * displays are added, removed or changed.
432      *
433      * @param listener The listener to register.
434      * @param handler The handler on which the listener should be invoked, or null
435      * if the listener should be invoked on the calling thread's looper.
436      *
437      * @see #unregisterDisplayListener
438      */
registerDisplayListener(DisplayListener listener, Handler handler)439     public void registerDisplayListener(DisplayListener listener, Handler handler) {
440         mGlobal.registerDisplayListener(listener, handler);
441     }
442 
443     /**
444      * Unregisters a display listener.
445      *
446      * @param listener The listener to unregister.
447      *
448      * @see #registerDisplayListener
449      */
unregisterDisplayListener(DisplayListener listener)450     public void unregisterDisplayListener(DisplayListener listener) {
451         mGlobal.unregisterDisplayListener(listener);
452     }
453 
454     /**
455      * Starts scanning for available Wifi displays.
456      * The results are sent as a {@link #ACTION_WIFI_DISPLAY_STATUS_CHANGED} broadcast.
457      * <p>
458      * Calls to this method nest and must be matched by an equal number of calls to
459      * {@link #stopWifiDisplayScan()}.
460      * </p><p>
461      * Requires {@link android.Manifest.permission#CONFIGURE_WIFI_DISPLAY}.
462      * </p>
463      *
464      * @hide
465      */
466     @UnsupportedAppUsage
startWifiDisplayScan()467     public void startWifiDisplayScan() {
468         mGlobal.startWifiDisplayScan();
469     }
470 
471     /**
472      * Stops scanning for available Wifi displays.
473      * <p>
474      * Requires {@link android.Manifest.permission#CONFIGURE_WIFI_DISPLAY}.
475      * </p>
476      *
477      * @hide
478      */
479     @UnsupportedAppUsage
stopWifiDisplayScan()480     public void stopWifiDisplayScan() {
481         mGlobal.stopWifiDisplayScan();
482     }
483 
484     /**
485      * Connects to a Wifi display.
486      * The results are sent as a {@link #ACTION_WIFI_DISPLAY_STATUS_CHANGED} broadcast.
487      * <p>
488      * Automatically remembers the display after a successful connection, if not
489      * already remembered.
490      * </p><p>
491      * Requires {@link android.Manifest.permission#CONFIGURE_WIFI_DISPLAY}.
492      * </p>
493      *
494      * @param deviceAddress The MAC address of the device to which we should connect.
495      * @hide
496      */
497     @UnsupportedAppUsage
connectWifiDisplay(String deviceAddress)498     public void connectWifiDisplay(String deviceAddress) {
499         mGlobal.connectWifiDisplay(deviceAddress);
500     }
501 
502     /** @hide */
503     @UnsupportedAppUsage
pauseWifiDisplay()504     public void pauseWifiDisplay() {
505         mGlobal.pauseWifiDisplay();
506     }
507 
508     /** @hide */
509     @UnsupportedAppUsage
resumeWifiDisplay()510     public void resumeWifiDisplay() {
511         mGlobal.resumeWifiDisplay();
512     }
513 
514     /**
515      * Disconnects from the current Wifi display.
516      * The results are sent as a {@link #ACTION_WIFI_DISPLAY_STATUS_CHANGED} broadcast.
517      * @hide
518      */
519     @UnsupportedAppUsage
disconnectWifiDisplay()520     public void disconnectWifiDisplay() {
521         mGlobal.disconnectWifiDisplay();
522     }
523 
524     /**
525      * Renames a Wifi display.
526      * <p>
527      * The display must already be remembered for this call to succeed.  In other words,
528      * we must already have successfully connected to the display at least once and then
529      * not forgotten it.
530      * </p><p>
531      * Requires {@link android.Manifest.permission#CONFIGURE_WIFI_DISPLAY}.
532      * </p>
533      *
534      * @param deviceAddress The MAC address of the device to rename.
535      * @param alias The alias name by which to remember the device, or null
536      * or empty if no alias should be used.
537      * @hide
538      */
539     @UnsupportedAppUsage
renameWifiDisplay(String deviceAddress, String alias)540     public void renameWifiDisplay(String deviceAddress, String alias) {
541         mGlobal.renameWifiDisplay(deviceAddress, alias);
542     }
543 
544     /**
545      * Forgets a previously remembered Wifi display.
546      * <p>
547      * Automatically disconnects from the display if currently connected to it.
548      * </p><p>
549      * Requires {@link android.Manifest.permission#CONFIGURE_WIFI_DISPLAY}.
550      * </p>
551      *
552      * @param deviceAddress The MAC address of the device to forget.
553      * @hide
554      */
555     @UnsupportedAppUsage
forgetWifiDisplay(String deviceAddress)556     public void forgetWifiDisplay(String deviceAddress) {
557         mGlobal.forgetWifiDisplay(deviceAddress);
558     }
559 
560     /**
561      * Gets the current Wifi display status.
562      * Watch for changes in the status by registering a broadcast receiver for
563      * {@link #ACTION_WIFI_DISPLAY_STATUS_CHANGED}.
564      *
565      * @return The current Wifi display status.
566      * @hide
567      */
568     @UnsupportedAppUsage
getWifiDisplayStatus()569     public WifiDisplayStatus getWifiDisplayStatus() {
570         return mGlobal.getWifiDisplayStatus();
571     }
572 
573     /**
574      * Set the level of color saturation to apply to the display.
575      * @param level The amount of saturation to apply, between 0 and 1 inclusive.
576      * 0 produces a grayscale image, 1 is normal.
577      *
578      * @hide
579      * @deprecated use {@link ColorDisplayManager#setSaturationLevel(int)} instead. The level passed
580      * as a parameter here will be rounded to the nearest hundredth.
581      */
582     @SystemApi
583     @RequiresPermission(Manifest.permission.CONTROL_DISPLAY_SATURATION)
setSaturationLevel(float level)584     public void setSaturationLevel(float level) {
585         if (level < 0f || level > 1f) {
586             throw new IllegalArgumentException("Saturation level must be between 0 and 1");
587         }
588         final ColorDisplayManager cdm = mContext.getSystemService(ColorDisplayManager.class);
589         cdm.setSaturationLevel(Math.round(level * 100f));
590     }
591 
592     /**
593      * Creates a virtual display.
594      *
595      * @see #createVirtualDisplay(String, int, int, int, Surface, int,
596      * VirtualDisplay.Callback, Handler)
597      */
createVirtualDisplay(@onNull String name, int width, int height, int densityDpi, @Nullable Surface surface, int flags)598     public VirtualDisplay createVirtualDisplay(@NonNull String name,
599             int width, int height, int densityDpi, @Nullable Surface surface, int flags) {
600         return createVirtualDisplay(name, width, height, densityDpi, surface, flags, null, null);
601     }
602 
603     /**
604      * Creates a virtual display.
605      * <p>
606      * The content of a virtual display is rendered to a {@link Surface} provided
607      * by the application.
608      * </p><p>
609      * The virtual display should be {@link VirtualDisplay#release released}
610      * when no longer needed.  Because a virtual display renders to a surface
611      * provided by the application, it will be released automatically when the
612      * process terminates and all remaining windows on it will be forcibly removed.
613      * </p><p>
614      * The behavior of the virtual display depends on the flags that are provided
615      * to this method.  By default, virtual displays are created to be private,
616      * non-presentation and unsecure.  Permissions may be required to use certain flags.
617      * </p><p>
618      * As of {@link android.os.Build.VERSION_CODES#KITKAT_WATCH}, the surface may
619      * be attached or detached dynamically using {@link VirtualDisplay#setSurface}.
620      * Previously, the surface had to be non-null when {@link #createVirtualDisplay}
621      * was called and could not be changed for the lifetime of the display.
622      * </p><p>
623      * Detaching the surface that backs a virtual display has a similar effect to
624      * turning off the screen.
625      * </p>
626      *
627      * @param name The name of the virtual display, must be non-empty.
628      * @param width The width of the virtual display in pixels, must be greater than 0.
629      * @param height The height of the virtual display in pixels, must be greater than 0.
630      * @param densityDpi The density of the virtual display in dpi, must be greater than 0.
631      * @param surface The surface to which the content of the virtual display should
632      * be rendered, or null if there is none initially.
633      * @param flags A combination of virtual display flags:
634      * {@link #VIRTUAL_DISPLAY_FLAG_PUBLIC}, {@link #VIRTUAL_DISPLAY_FLAG_PRESENTATION},
635      * {@link #VIRTUAL_DISPLAY_FLAG_SECURE}, {@link #VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY},
636      * or {@link #VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR}.
637      * @param callback Callback to call when the state of the {@link VirtualDisplay} changes
638      * @param handler The handler on which the listener should be invoked, or null
639      * if the listener should be invoked on the calling thread's looper.
640      * @return The newly created virtual display, or null if the application could
641      * not create the virtual display.
642      *
643      * @throws SecurityException if the caller does not have permission to create
644      * a virtual display with the specified flags.
645      */
createVirtualDisplay(@onNull String name, int width, int height, int densityDpi, @Nullable Surface surface, int flags, @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler)646     public VirtualDisplay createVirtualDisplay(@NonNull String name,
647             int width, int height, int densityDpi, @Nullable Surface surface, int flags,
648             @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
649         final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(name, width,
650                 height, densityDpi);
651         builder.setFlags(flags);
652         if (surface != null) {
653             builder.setSurface(surface);
654         }
655         return createVirtualDisplay(null /* projection */, builder.build(), callback, handler);
656     }
657 
658     // TODO : Remove this hidden API after remove all callers. (Refer to MultiDisplayService)
659     /** @hide */
createVirtualDisplay(@ullable MediaProjection projection, @NonNull String name, int width, int height, int densityDpi, @Nullable Surface surface, int flags, @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler, @Nullable String uniqueId)660     public VirtualDisplay createVirtualDisplay(@Nullable MediaProjection projection,
661             @NonNull String name, int width, int height, int densityDpi, @Nullable Surface surface,
662             int flags, @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler,
663             @Nullable String uniqueId) {
664         final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(name, width,
665                 height, densityDpi);
666         builder.setFlags(flags);
667         if (uniqueId != null) {
668             builder.setUniqueId(uniqueId);
669         }
670         if (surface != null) {
671             builder.setSurface(surface);
672         }
673         return createVirtualDisplay(projection, builder.build(), callback, handler);
674     }
675 
676     /** @hide */
createVirtualDisplay(@ullable MediaProjection projection, @NonNull VirtualDisplayConfig virtualDisplayConfig, @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler)677     public VirtualDisplay createVirtualDisplay(@Nullable MediaProjection projection,
678             @NonNull VirtualDisplayConfig virtualDisplayConfig,
679             @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
680         return mGlobal.createVirtualDisplay(mContext, projection, virtualDisplayConfig, callback,
681                 handler);
682     }
683 
684     /**
685      * Gets the stable device display size, in pixels.
686      *
687      * This should really only be used for things like server-side filtering of available
688      * applications. Most applications don't need the level of stability guaranteed by this and
689      * should instead query either the size of the display they're currently running on or the
690      * size of the default display.
691      * @hide
692      */
693     @SystemApi
694     @TestApi
getStableDisplaySize()695     public Point getStableDisplaySize() {
696         return mGlobal.getStableDisplaySize();
697     }
698 
699     /**
700      * Fetch {@link BrightnessChangeEvent}s.
701      * @hide until we make it a system api.
702      */
703     @SystemApi
704     @TestApi
705     @RequiresPermission(Manifest.permission.BRIGHTNESS_SLIDER_USAGE)
getBrightnessEvents()706     public List<BrightnessChangeEvent> getBrightnessEvents() {
707         return mGlobal.getBrightnessEvents(mContext.getOpPackageName());
708     }
709 
710     /**
711      * Fetch {@link AmbientBrightnessDayStats}s.
712      *
713      * @hide until we make it a system api
714      */
715     @SystemApi
716     @TestApi
717     @RequiresPermission(Manifest.permission.ACCESS_AMBIENT_LIGHT_STATS)
getAmbientBrightnessStats()718     public List<AmbientBrightnessDayStats> getAmbientBrightnessStats() {
719         return mGlobal.getAmbientBrightnessStats();
720     }
721 
722     /**
723      * Sets the global display brightness configuration.
724      *
725      * @hide
726      */
727     @SystemApi
728     @TestApi
729     @RequiresPermission(Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS)
setBrightnessConfiguration(BrightnessConfiguration c)730     public void setBrightnessConfiguration(BrightnessConfiguration c) {
731         setBrightnessConfigurationForUser(c, mContext.getUserId(), mContext.getPackageName());
732     }
733 
734     /**
735      * Sets the global display brightness configuration for a specific user.
736      *
737      * Note this requires the INTERACT_ACROSS_USERS permission if setting the configuration for a
738      * user other than the one you're currently running as.
739      *
740      * @hide
741      */
setBrightnessConfigurationForUser(BrightnessConfiguration c, int userId, String packageName)742     public void setBrightnessConfigurationForUser(BrightnessConfiguration c, int userId,
743             String packageName) {
744         mGlobal.setBrightnessConfigurationForUser(c, userId, packageName);
745     }
746 
747     /**
748      * Gets the global display brightness configuration or the default curve if one hasn't been set.
749      *
750      * @hide
751      */
752     @SystemApi
753     @TestApi
754     @RequiresPermission(Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS)
getBrightnessConfiguration()755     public BrightnessConfiguration getBrightnessConfiguration() {
756         return getBrightnessConfigurationForUser(mContext.getUserId());
757     }
758 
759     /**
760      * Gets the global display brightness configuration or the default curve if one hasn't been set
761      * for a specific user.
762      *
763      * Note this requires the INTERACT_ACROSS_USERS permission if getting the configuration for a
764      * user other than the one you're currently running as.
765      *
766      * @hide
767      */
getBrightnessConfigurationForUser(int userId)768     public BrightnessConfiguration getBrightnessConfigurationForUser(int userId) {
769         return mGlobal.getBrightnessConfigurationForUser(userId);
770     }
771 
772     /**
773      * Gets the default global display brightness configuration or null one hasn't
774      * been configured.
775      *
776      * @hide
777      */
778     @SystemApi
779     @TestApi
780     @RequiresPermission(Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS)
781     @Nullable
getDefaultBrightnessConfiguration()782     public BrightnessConfiguration getDefaultBrightnessConfiguration() {
783         return mGlobal.getDefaultBrightnessConfiguration();
784     }
785 
786 
787     /**
788      * Gets the last requested minimal post processing setting for the display with displayId.
789      *
790      * @hide
791      */
792     @TestApi
isMinimalPostProcessingRequested(int displayId)793     public boolean isMinimalPostProcessingRequested(int displayId) {
794         return mGlobal.isMinimalPostProcessingRequested(displayId);
795     }
796 
797     /**
798      * Temporarily sets the brightness of the display.
799      * <p>
800      * Requires the {@link android.Manifest.permission#CONTROL_DISPLAY_BRIGHTNESS} permission.
801      * </p>
802      *
803      * @param brightness The brightness value from 0.0f to 1.0f.
804      *
805      * @hide Requires signature permission.
806      */
setTemporaryBrightness(float brightness)807     public void setTemporaryBrightness(float brightness) {
808         mGlobal.setTemporaryBrightness(brightness);
809     }
810 
811     /**
812      * Temporarily sets the auto brightness adjustment factor.
813      * <p>
814      * Requires the {@link android.Manifest.permission#CONTROL_DISPLAY_BRIGHTNESS} permission.
815      * </p>
816      *
817      * @param adjustment The adjustment factor from -1.0 to 1.0.
818      *
819      * @hide Requires signature permission.
820      */
setTemporaryAutoBrightnessAdjustment(float adjustment)821     public void setTemporaryAutoBrightnessAdjustment(float adjustment) {
822         mGlobal.setTemporaryAutoBrightnessAdjustment(adjustment);
823     }
824 
825     /**
826      * Returns the minimum brightness curve, which guarantess that any brightness curve that dips
827      * below it is rejected by the system.
828      * This prevent auto-brightness from setting the screen so dark as to prevent the user from
829      * resetting or disabling it, and maps lux to the absolute minimum nits that are still readable
830      * in that ambient brightness.
831      *
832      * @return The minimum brightness curve (as lux values and their corresponding nits values).
833      *
834      * @hide
835      */
836     @SystemApi
getMinimumBrightnessCurve()837     public Pair<float[], float[]> getMinimumBrightnessCurve() {
838         return mGlobal.getMinimumBrightnessCurve();
839     }
840 
841     /**
842      * Listens for changes in available display devices.
843      */
844     public interface DisplayListener {
845         /**
846          * Called whenever a logical display has been added to the system.
847          * Use {@link DisplayManager#getDisplay} to get more information about
848          * the display.
849          *
850          * @param displayId The id of the logical display that was added.
851          */
onDisplayAdded(int displayId)852         void onDisplayAdded(int displayId);
853 
854         /**
855          * Called whenever a logical display has been removed from the system.
856          *
857          * @param displayId The id of the logical display that was removed.
858          */
onDisplayRemoved(int displayId)859         void onDisplayRemoved(int displayId);
860 
861         /**
862          * Called whenever the properties of a logical {@link android.view.Display},
863          * such as size and density, have changed.
864          *
865          * @param displayId The id of the logical display that changed.
866          */
onDisplayChanged(int displayId)867         void onDisplayChanged(int displayId);
868     }
869 
870     /**
871      * Interface for accessing keys belonging to {@link
872      * android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER}.
873      * @hide
874      */
875     public interface DeviceConfig {
876 
877         /**
878          * Key for refresh rate in the zone defined by thresholds.
879          *
880          * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER
881          * @see android.R.integer#config_defaultZoneBehavior
882          */
883         String KEY_REFRESH_RATE_IN_ZONE = "refresh_rate_in_zone";
884 
885         /**
886          * Key for accessing the display brightness thresholds for the configured refresh rate zone.
887          * The value will be a pair of comma separated integers representing the minimum and maximum
888          * thresholds of the zone, respectively, in display backlight units (i.e. [0, 255]).
889          *
890          * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER
891          * @see android.R.array#config_brightnessThresholdsOfPeakRefreshRate
892          * @hide
893          */
894         String KEY_PEAK_REFRESH_RATE_DISPLAY_BRIGHTNESS_THRESHOLDS =
895                 "peak_refresh_rate_brightness_thresholds";
896 
897         /**
898          * Key for accessing the ambient brightness thresholds for the configured refresh rate zone.
899          * The value will be a pair of comma separated integers representing the minimum and maximum
900          * thresholds of the zone, respectively, in lux.
901          *
902          * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER
903          * @see android.R.array#config_ambientThresholdsOfPeakRefreshRate
904          * @hide
905          */
906         String KEY_PEAK_REFRESH_RATE_AMBIENT_BRIGHTNESS_THRESHOLDS =
907                 "peak_refresh_rate_ambient_thresholds";
908 
909         /**
910          * Key for default peak refresh rate
911          *
912          * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER
913          * @see android.R.integer#config_defaultPeakRefreshRate
914          * @hide
915          */
916         String KEY_PEAK_REFRESH_RATE_DEFAULT = "peak_refresh_rate_default";
917 
918         /**
919          * Key for controlling which packages are explicitly blocked from running at refresh rates
920          * higher than 60hz. An app may be added to this list if they exhibit performance issues at
921          * higher refresh rates.
922          *
923          * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER
924          * @see android.R.array#config_highRefreshRateBlacklist
925          * @hide
926          */
927         String KEY_HIGH_REFRESH_RATE_BLACKLIST = "high_refresh_rate_blacklist";
928     }
929 }
930