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