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