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