1 /* 2 * Copyright (C) 2020 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 21 import android.annotation.CallbackExecutor; 22 import android.annotation.FlaggedApi; 23 import android.annotation.FloatRange; 24 import android.annotation.IntRange; 25 import android.annotation.NonNull; 26 import android.annotation.Nullable; 27 import android.annotation.SuppressLint; 28 import android.annotation.SystemApi; 29 import android.hardware.display.DisplayManager.VirtualDisplayFlag; 30 import android.media.projection.MediaProjection; 31 import android.os.Handler; 32 import android.os.Parcel; 33 import android.os.Parcelable; 34 import android.os.PowerManager; 35 import android.util.ArraySet; 36 import android.view.Display; 37 import android.view.DisplayCutout; 38 import android.view.Surface; 39 40 import java.util.Collections; 41 import java.util.Objects; 42 import java.util.Set; 43 import java.util.concurrent.Executor; 44 45 /** 46 * Holds configuration used to create {@link VirtualDisplay} instances. 47 * 48 * @see DisplayManager#createVirtualDisplay(VirtualDisplayConfig, Handler, VirtualDisplay.Callback) 49 * @see MediaProjection#createVirtualDisplay(String, int, int, int, int, Surface, 50 * VirtualDisplay.Callback, Handler) 51 */ 52 public final class VirtualDisplayConfig implements Parcelable { 53 54 private final String mName; 55 private final int mWidth; 56 private final int mHeight; 57 private final int mDensityDpi; 58 private final int mFlags; 59 private final Surface mSurface; 60 private final String mUniqueId; 61 private final int mDisplayIdToMirror; 62 private final boolean mWindowManagerMirroringEnabled; 63 private final ArraySet<String> mDisplayCategories; 64 private final float mRequestedRefreshRate; 65 private final boolean mIsHomeSupported; 66 private final DisplayCutout mDisplayCutout; 67 private final boolean mIgnoreActivitySizeRestrictions; 68 private final float mDefaultBrightness; 69 private final float mDimBrightness; 70 private final IBrightnessListener mBrightnessListener; 71 VirtualDisplayConfig( @onNull String name, @IntRange(from = 1) int width, @IntRange(from = 1) int height, @IntRange(from = 1) int densityDpi, @VirtualDisplayFlag int flags, @Nullable Surface surface, @Nullable String uniqueId, int displayIdToMirror, boolean windowManagerMirroringEnabled, @NonNull ArraySet<String> displayCategories, float requestedRefreshRate, boolean isHomeSupported, @Nullable DisplayCutout displayCutout, boolean ignoreActivitySizeRestrictions, @FloatRange(from = 0.0f, to = 1.0f) float defaultBrightness, @FloatRange(from = 0.0f, to = 1.0f) float dimBrightness, IBrightnessListener brightnessListener)72 private VirtualDisplayConfig( 73 @NonNull String name, 74 @IntRange(from = 1) int width, 75 @IntRange(from = 1) int height, 76 @IntRange(from = 1) int densityDpi, 77 @VirtualDisplayFlag int flags, 78 @Nullable Surface surface, 79 @Nullable String uniqueId, 80 int displayIdToMirror, 81 boolean windowManagerMirroringEnabled, 82 @NonNull ArraySet<String> displayCategories, 83 float requestedRefreshRate, 84 boolean isHomeSupported, 85 @Nullable DisplayCutout displayCutout, 86 boolean ignoreActivitySizeRestrictions, 87 @FloatRange(from = 0.0f, to = 1.0f) float defaultBrightness, 88 @FloatRange(from = 0.0f, to = 1.0f) float dimBrightness, 89 IBrightnessListener brightnessListener) { 90 mName = name; 91 mWidth = width; 92 mHeight = height; 93 mDensityDpi = densityDpi; 94 mFlags = flags; 95 mSurface = surface; 96 mUniqueId = uniqueId; 97 mDisplayIdToMirror = displayIdToMirror; 98 mWindowManagerMirroringEnabled = windowManagerMirroringEnabled; 99 mDisplayCategories = displayCategories; 100 mRequestedRefreshRate = requestedRefreshRate; 101 mIsHomeSupported = isHomeSupported; 102 mDisplayCutout = displayCutout; 103 mIgnoreActivitySizeRestrictions = ignoreActivitySizeRestrictions; 104 mDefaultBrightness = defaultBrightness; 105 mDimBrightness = dimBrightness; 106 mBrightnessListener = brightnessListener; 107 } 108 109 /** 110 * Returns the name of the virtual display. 111 */ 112 @NonNull getName()113 public String getName() { 114 return mName; 115 } 116 117 /** 118 * Returns the width of the virtual display in pixels. 119 */ getWidth()120 public int getWidth() { 121 return mWidth; 122 } 123 124 /** 125 * Returns the height of the virtual display in pixels. 126 */ getHeight()127 public int getHeight() { 128 return mHeight; 129 } 130 131 /** 132 * Returns the density of the virtual display in dpi. 133 */ getDensityDpi()134 public int getDensityDpi() { 135 return mDensityDpi; 136 } 137 138 /** 139 * Returns the virtual display flags. 140 * 141 * @see Builder#setFlags 142 */ getFlags()143 public int getFlags() { 144 return mFlags; 145 } 146 147 /** 148 * Returns the surface to which the content of the virtual display should be rendered, if any. 149 * 150 * @see Builder#setSurface 151 */ 152 @Nullable getSurface()153 public Surface getSurface() { 154 return mSurface; 155 } 156 157 /** 158 * Returns the cutout of this display. 159 * 160 * @return the cutout of the display or {@code null} if none is specified. 161 * 162 * @see Builder#setDisplayCutout 163 * @hide 164 */ 165 @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_VIRTUAL_DISPLAY_INSETS) 166 @SystemApi 167 @Nullable getDisplayCutout()168 public DisplayCutout getDisplayCutout() { 169 return mDisplayCutout; 170 } 171 172 /** 173 * Returns the default brightness of the display. 174 * 175 * <p>Value of {@code 0.0} indicates the minimum supported brightness and value of {@code 1.0} 176 * indicates the maximum supported brightness.</p> 177 * 178 * @see Builder#setDefaultBrightness(float) 179 */ 180 @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_DEVICE_AWARE_DISPLAY_POWER) getDefaultBrightness()181 public @FloatRange(from = 0.0f, to = 1.0f) float getDefaultBrightness() { 182 return mDefaultBrightness; 183 } 184 185 /** 186 * Returns the dim brightness of the display. 187 * 188 * <p>Value of {@code 0.0} indicates the minimum supported brightness and value of {@code 1.0} 189 * indicates the maximum supported brightness.</p> 190 * 191 * @see Builder#setDimBrightness(float) 192 */ 193 @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_DEVICE_AWARE_DISPLAY_POWER) getDimBrightness()194 public @FloatRange(from = 0.0f, to = 1.0f) float getDimBrightness() { 195 return mDimBrightness; 196 } 197 198 /** 199 * Returns the listener to get notified about changes in the display brightness. 200 * @hide 201 */ 202 @Nullable getBrightnessListener()203 public IBrightnessListener getBrightnessListener() { 204 return mBrightnessListener; 205 } 206 207 /** 208 * Returns the unique identifier for the display. Shouldn't be displayed to the user. 209 * @hide 210 */ 211 @Nullable getUniqueId()212 public String getUniqueId() { 213 return mUniqueId; 214 } 215 216 /** 217 * Returns the id of the display that the virtual display should mirror, or 218 * {@link android.view.Display#DEFAULT_DISPLAY} if there is none. 219 * @hide 220 */ getDisplayIdToMirror()221 public int getDisplayIdToMirror() { 222 return mDisplayIdToMirror; 223 } 224 225 /** 226 * Whether if WindowManager is responsible for mirroring content to this VirtualDisplay, or 227 * if DisplayManager should record contents instead. 228 * @hide 229 */ isWindowManagerMirroringEnabled()230 public boolean isWindowManagerMirroringEnabled() { 231 return mWindowManagerMirroringEnabled; 232 } 233 234 /** 235 * Whether this virtual display supports showing home activity and wallpaper. 236 * 237 * @see Builder#setHomeSupported 238 * @hide 239 */ 240 @SystemApi isHomeSupported()241 public boolean isHomeSupported() { 242 return mIsHomeSupported; 243 } 244 245 /** 246 * Whether this virtual display ignores fixed orientation, aspect ratio, and resizability 247 * of apps. 248 * 249 * @return Whether orientation, aspect ratio, and resizability restrictions are ignored. 250 * 251 * @see Builder#setIgnoreActivitySizeRestrictions(boolean) 252 * @hide 253 */ 254 @FlaggedApi(com.android.window.flags.Flags.FLAG_VDM_FORCE_APP_UNIVERSAL_RESIZABLE_API) 255 @SystemApi isIgnoreActivitySizeRestrictions()256 public boolean isIgnoreActivitySizeRestrictions() { 257 return mIgnoreActivitySizeRestrictions 258 && com.android.window.flags.Flags.vdmForceAppUniversalResizableApi(); 259 } 260 261 /** 262 * Returns the display categories. 263 * 264 * @see Builder#setDisplayCategories 265 */ 266 @NonNull getDisplayCategories()267 public Set<String> getDisplayCategories() { 268 return Collections.unmodifiableSet(mDisplayCategories); 269 } 270 271 /** 272 * Returns the refresh rate of a virtual display in frames per second, or zero if it is using a 273 * default refresh rate chosen by the system. 274 * 275 * @see Builder#setRequestedRefreshRate 276 */ getRequestedRefreshRate()277 public float getRequestedRefreshRate() { 278 return mRequestedRefreshRate; 279 } 280 281 @Override writeToParcel(@onNull Parcel dest, int flags)282 public void writeToParcel(@NonNull Parcel dest, int flags) { 283 dest.writeString8(mName); 284 dest.writeInt(mWidth); 285 dest.writeInt(mHeight); 286 dest.writeInt(mDensityDpi); 287 dest.writeInt(mFlags); 288 dest.writeTypedObject(mSurface, flags); 289 dest.writeString8(mUniqueId); 290 dest.writeInt(mDisplayIdToMirror); 291 dest.writeBoolean(mWindowManagerMirroringEnabled); 292 dest.writeArraySet(mDisplayCategories); 293 dest.writeFloat(mRequestedRefreshRate); 294 dest.writeBoolean(mIsHomeSupported); 295 DisplayCutout.ParcelableWrapper.writeCutoutToParcel(mDisplayCutout, dest, flags); 296 dest.writeBoolean(mIgnoreActivitySizeRestrictions); 297 dest.writeFloat(mDefaultBrightness); 298 dest.writeFloat(mDimBrightness); 299 dest.writeStrongBinder(mBrightnessListener != null ? mBrightnessListener.asBinder() : null); 300 } 301 302 @Override describeContents()303 public int describeContents() { return 0; } 304 305 @Override equals(Object o)306 public boolean equals(Object o) { 307 if (this == o) { 308 return true; 309 } 310 if (!(o instanceof VirtualDisplayConfig)) { 311 return false; 312 } 313 VirtualDisplayConfig that = (VirtualDisplayConfig) o; 314 return Objects.equals(mName, that.mName) 315 && mWidth == that.mWidth 316 && mHeight == that.mHeight 317 && mDensityDpi == that.mDensityDpi 318 && mFlags == that.mFlags 319 && Objects.equals(mSurface, that.mSurface) 320 && Objects.equals(mUniqueId, that.mUniqueId) 321 && mDisplayIdToMirror == that.mDisplayIdToMirror 322 && mWindowManagerMirroringEnabled == that.mWindowManagerMirroringEnabled 323 && Objects.equals(mDisplayCategories, that.mDisplayCategories) 324 && mRequestedRefreshRate == that.mRequestedRefreshRate 325 && mIsHomeSupported == that.mIsHomeSupported 326 && mIgnoreActivitySizeRestrictions == that.mIgnoreActivitySizeRestrictions 327 && Objects.equals(mDisplayCutout, that.mDisplayCutout) 328 && mDefaultBrightness == that.mDefaultBrightness 329 && mDimBrightness == that.mDimBrightness 330 && Objects.equals(mBrightnessListener, that.mBrightnessListener); 331 } 332 333 @Override hashCode()334 public int hashCode() { 335 int hashCode = Objects.hash( 336 mName, mWidth, mHeight, mDensityDpi, mFlags, mSurface, mUniqueId, 337 mDisplayIdToMirror, mWindowManagerMirroringEnabled, mDisplayCategories, 338 mRequestedRefreshRate, mIsHomeSupported, mDisplayCutout, 339 mIgnoreActivitySizeRestrictions, mDefaultBrightness, mDimBrightness, 340 mBrightnessListener); 341 return hashCode; 342 } 343 344 @Override 345 @NonNull toString()346 public String toString() { 347 return "VirtualDisplayConfig(" 348 + " mName=" + mName 349 + " mHeight=" + mHeight 350 + " mWidth=" + mWidth 351 + " mDensityDpi=" + mDensityDpi 352 + " mFlags=" + mFlags 353 + " mSurface=" + mSurface 354 + " mUniqueId=" + mUniqueId 355 + " mDisplayIdToMirror=" + mDisplayIdToMirror 356 + " mWindowManagerMirroringEnabled=" + mWindowManagerMirroringEnabled 357 + " mDisplayCategories=" + mDisplayCategories 358 + " mRequestedRefreshRate=" + mRequestedRefreshRate 359 + " mIsHomeSupported=" + mIsHomeSupported 360 + " mDisplayCutout=" + mDisplayCutout 361 + " mIgnoreActivitySizeRestrictions=" + mIgnoreActivitySizeRestrictions 362 + " mDefaultBrightness=" + mDefaultBrightness 363 + " mDimBrightness=" + mDimBrightness 364 + ")"; 365 } 366 VirtualDisplayConfig(@onNull Parcel in)367 private VirtualDisplayConfig(@NonNull Parcel in) { 368 mName = in.readString8(); 369 mWidth = in.readInt(); 370 mHeight = in.readInt(); 371 mDensityDpi = in.readInt(); 372 mFlags = in.readInt(); 373 mSurface = in.readTypedObject(Surface.CREATOR); 374 mUniqueId = in.readString8(); 375 mDisplayIdToMirror = in.readInt(); 376 mWindowManagerMirroringEnabled = in.readBoolean(); 377 mDisplayCategories = (ArraySet<String>) in.readArraySet(null); 378 mRequestedRefreshRate = in.readFloat(); 379 mIsHomeSupported = in.readBoolean(); 380 mDisplayCutout = DisplayCutout.ParcelableWrapper.readCutoutFromParcel(in); 381 mIgnoreActivitySizeRestrictions = in.readBoolean(); 382 mDefaultBrightness = in.readFloat(); 383 mDimBrightness = in.readFloat(); 384 mBrightnessListener = IBrightnessListener.Stub.asInterface(in.readStrongBinder()); 385 } 386 387 /** 388 * Listener for display brightness changes. 389 */ 390 @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_DEVICE_AWARE_DISPLAY_POWER) 391 public interface BrightnessListener { 392 393 /** 394 * Called when the display's brightness has changed. 395 * 396 * @param brightness the new brightness of the display. Value of {@code 0.0} indicates the 397 * minimum supported brightness and value of {@code 1.0} indicates the maximum supported 398 * brightness. 399 */ onBrightnessChanged(@loatRangefrom = 0.0f, to = 1.0f) float brightness)400 void onBrightnessChanged(@FloatRange(from = 0.0f, to = 1.0f) float brightness); 401 } 402 403 private static class BrightnessListenerDelegate extends IBrightnessListener.Stub { 404 405 @NonNull 406 private final Executor mExecutor; 407 @NonNull 408 private final BrightnessListener mListener; 409 BrightnessListenerDelegate(@onNull @allbackExecutor Executor executor, @NonNull BrightnessListener listener)410 BrightnessListenerDelegate(@NonNull @CallbackExecutor Executor executor, 411 @NonNull BrightnessListener listener) { 412 mExecutor = executor; 413 mListener = listener; 414 } 415 416 @Override onBrightnessChanged(float brightness)417 public void onBrightnessChanged(float brightness) { 418 mExecutor.execute(() -> mListener.onBrightnessChanged(brightness)); 419 } 420 } 421 422 @NonNull 423 public static final Parcelable.Creator<VirtualDisplayConfig> CREATOR 424 = new Parcelable.Creator<VirtualDisplayConfig>() { 425 @Override 426 public VirtualDisplayConfig[] newArray(int size) { 427 return new VirtualDisplayConfig[size]; 428 } 429 430 @Override 431 public VirtualDisplayConfig createFromParcel(@NonNull Parcel in) { 432 return new VirtualDisplayConfig(in); 433 } 434 }; 435 436 /** 437 * A builder for {@link VirtualDisplayConfig}. 438 */ 439 public static final class Builder { 440 private final String mName; 441 private final int mWidth; 442 private final int mHeight; 443 private final int mDensityDpi; 444 private int mFlags = 0; 445 private Surface mSurface = null; 446 private String mUniqueId = null; 447 private int mDisplayIdToMirror = DEFAULT_DISPLAY; 448 private boolean mWindowManagerMirroringEnabled = false; 449 private ArraySet<String> mDisplayCategories = new ArraySet<>(); 450 private float mRequestedRefreshRate = 0.0f; 451 private boolean mIsHomeSupported = false; 452 private DisplayCutout mDisplayCutout = null; 453 private boolean mIgnoreActivitySizeRestrictions = false; 454 private float mDefaultBrightness = 0.0f; 455 private float mDimBrightness = PowerManager.BRIGHTNESS_INVALID; 456 private IBrightnessListener mBrightnessListener = null; 457 458 /** 459 * Creates a new Builder. 460 * 461 * @param name The name of the virtual display, must be non-empty. 462 * @param width The width of the virtual display in pixels. Must be greater than 0. 463 * @param height The height of the virtual display in pixels. Must be greater than 0. 464 * @param densityDpi The density of the virtual display in dpi. Must be greater than 0. 465 */ Builder( @onNull String name, @IntRange(from = 1) int width, @IntRange(from = 1) int height, @IntRange(from = 1) int densityDpi)466 public Builder( 467 @NonNull String name, 468 @IntRange(from = 1) int width, 469 @IntRange(from = 1) int height, 470 @IntRange(from = 1) int densityDpi) { 471 if (name == null) { 472 throw new IllegalArgumentException("Virtual display name is required"); 473 } 474 if (width <= 0) { 475 throw new IllegalArgumentException("Virtual display width must be positive"); 476 } 477 if (height <= 0) { 478 throw new IllegalArgumentException("Virtual display height must be positive"); 479 } 480 if (densityDpi <= 0) { 481 throw new IllegalArgumentException("Virtual display density must be positive"); 482 } 483 mName = name; 484 mWidth = width; 485 mHeight = height; 486 mDensityDpi = densityDpi; 487 } 488 489 /** 490 * Sets the virtual display flags, a combination of 491 * {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_PUBLIC}, 492 * {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_PRESENTATION}, 493 * {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_SECURE}, 494 * {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY}, 495 * or {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR}. 496 */ 497 @NonNull setFlags(@irtualDisplayFlag int flags)498 public Builder setFlags(@VirtualDisplayFlag int flags) { 499 mFlags = flags; 500 return this; 501 } 502 503 /** 504 * Sets the surface to which the content of the virtual display should be rendered. 505 * 506 * <p>The surface can also be set after the display creation using 507 * {@link VirtualDisplay#setSurface(Surface)}. 508 */ 509 @NonNull setSurface(@ullable Surface surface)510 public Builder setSurface(@Nullable Surface surface) { 511 mSurface = surface; 512 return this; 513 } 514 515 /** 516 * Sets the unique identifier for the display. 517 * @hide 518 */ 519 @NonNull setUniqueId(@ullable String uniqueId)520 public Builder setUniqueId(@Nullable String uniqueId) { 521 mUniqueId = uniqueId; 522 return this; 523 } 524 525 /** 526 * Sets the id of the display that the virtual display should mirror. 527 * @hide 528 */ 529 @NonNull setDisplayIdToMirror(int displayIdToMirror)530 public Builder setDisplayIdToMirror(int displayIdToMirror) { 531 mDisplayIdToMirror = displayIdToMirror; 532 return this; 533 } 534 535 /** 536 * Sets whether WindowManager is responsible for mirroring content to this VirtualDisplay. 537 * If unset or false, DisplayManager should record contents instead. 538 * @hide 539 */ 540 @NonNull setWindowManagerMirroringEnabled(boolean windowManagerMirroringEnabled)541 public Builder setWindowManagerMirroringEnabled(boolean windowManagerMirroringEnabled) { 542 mWindowManagerMirroringEnabled = windowManagerMirroringEnabled; 543 return this; 544 } 545 546 /** 547 * Sets the display categories. 548 * 549 * <p>The categories of the display indicate the type of activities allowed to run on that 550 * display. Activities can declare a display category using 551 * {@link android.content.pm.ActivityInfo#requiredDisplayCategory}. 552 */ 553 @NonNull setDisplayCategories(@onNull Set<String> displayCategories)554 public Builder setDisplayCategories(@NonNull Set<String> displayCategories) { 555 mDisplayCategories.clear(); 556 mDisplayCategories.addAll(Objects.requireNonNull(displayCategories)); 557 return this; 558 } 559 560 /** 561 * Adds a display category. 562 * 563 * @see #setDisplayCategories 564 */ 565 @NonNull addDisplayCategory(@onNull String displayCategory)566 public Builder addDisplayCategory(@NonNull String displayCategory) { 567 mDisplayCategories.add(Objects.requireNonNull(displayCategory)); 568 return this; 569 } 570 571 /** 572 * Sets the refresh rate of a virtual display in frames per second. 573 * 574 * <p>For best results, specify a divisor of the physical refresh rate, e.g., 30 or 60 on 575 * a 120hz display. If an arbitrary refresh rate is specified, the rate will be rounded up 576 * to a divisor of the physical display. If unset or zero, the virtual display will be 577 * refreshed at the physical display refresh rate. 578 * 579 * @see Display#getRefreshRate() 580 */ 581 @NonNull setRequestedRefreshRate( @loatRangefrom = 0.0f) float requestedRefreshRate)582 public Builder setRequestedRefreshRate( 583 @FloatRange(from = 0.0f) float requestedRefreshRate) { 584 if (requestedRefreshRate < 0.0f) { 585 throw new IllegalArgumentException( 586 "Virtual display requested refresh rate must be non-negative"); 587 } 588 mRequestedRefreshRate = requestedRefreshRate; 589 return this; 590 } 591 592 /** 593 * Sets whether this display supports showing home activities and wallpaper. 594 * 595 * <p>If set to {@code true}, then the home activity relevant to this display will be 596 * automatically launched upon the display creation. If unset or set to {@code false}, the 597 * display will not host any activities upon creation.</p> 598 * 599 * <p>Note: setting to {@code true} requires the display to be trusted and to not mirror 600 * content of other displays. If the display is not trusted, or if it mirrors content of 601 * other displays, this property is ignored.</p> 602 * 603 * @param isHomeSupported whether home activities are supported on the display 604 * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_TRUSTED 605 * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR 606 * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY 607 * @hide 608 */ 609 @SystemApi 610 @NonNull setHomeSupported(boolean isHomeSupported)611 public Builder setHomeSupported(boolean isHomeSupported) { 612 mIsHomeSupported = isHomeSupported; 613 return this; 614 } 615 616 /** 617 * Sets the cutout of this display. 618 * 619 * @hide 620 */ 621 @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_VIRTUAL_DISPLAY_INSETS) 622 @SystemApi 623 @NonNull setDisplayCutout(@ullable DisplayCutout displayCutout)624 public Builder setDisplayCutout(@Nullable DisplayCutout displayCutout) { 625 mDisplayCutout = displayCutout; 626 return this; 627 } 628 629 /** 630 * Sets whether this display ignores fixed orientation, aspect ratio and resizability 631 * of apps. 632 * 633 * <p>Note: setting to {@code true} requires the display to have 634 * {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_TRUSTED}. If this is false, this property 635 * is ignored.</p> 636 * 637 * @hide 638 */ 639 @FlaggedApi(com.android.window.flags.Flags.FLAG_VDM_FORCE_APP_UNIVERSAL_RESIZABLE_API) 640 @SystemApi 641 @NonNull setIgnoreActivitySizeRestrictions(boolean enabled)642 public Builder setIgnoreActivitySizeRestrictions(boolean enabled) { 643 mIgnoreActivitySizeRestrictions = enabled; 644 return this; 645 } 646 647 /** 648 * Sets the default brightness of the display. 649 * 650 * <p>The system will use this brightness value whenever the display should be bright, i.e. 651 * it is powered on and not modified due to user activity or app activity.</p> 652 * 653 * <p>Value of {@code 0.0} indicates the minimum supported brightness and value of 654 * {@code 1.0} indicates the maximum supported brightness.</p> 655 * 656 * <p>If unset, defaults to {@code 0.0}</p> 657 * 658 * @throws IllegalArgumentException if the brightness is outside the valid range [0.0, 1.0] 659 * @see android.view.View#setKeepScreenOn(boolean) 660 * @see #setBrightnessListener(Executor, BrightnessListener) 661 */ 662 @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_DEVICE_AWARE_DISPLAY_POWER) 663 @NonNull setDefaultBrightness(@loatRangefrom = 0.0f, to = 1.0f) float brightness)664 public Builder setDefaultBrightness(@FloatRange(from = 0.0f, to = 1.0f) float brightness) { 665 if (!isValidBrightness(brightness)) { 666 throw new IllegalArgumentException( 667 "Virtual display default brightness must be in range [0.0, 1.0]"); 668 } 669 mDefaultBrightness = brightness; 670 return this; 671 } 672 673 /** 674 * Sets the dim brightness of the display. 675 * 676 * <p>The system will use this brightness value whenever the display should be dim, i.e. 677 * it is powered on and dimmed due to user activity or app activity.</p> 678 * 679 * <p>Value of {@code 0.0} indicates the minimum supported brightness and value of 680 * {@code 1.0} indicates the maximum supported brightness.</p> 681 * 682 * <p>If set, the default brightness must also be set to a value greater or equal to the 683 * dim brightness. If unset, defaults to the system default.</p> 684 * 685 * @throws IllegalArgumentException if the brightness is outside the valid range [0.0, 1.0] 686 * @see Builder#setDefaultBrightness(float) 687 * @see #setBrightnessListener(Executor, BrightnessListener) 688 */ 689 @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_DEVICE_AWARE_DISPLAY_POWER) 690 @NonNull setDimBrightness(@loatRangefrom = 0.0f, to = 1.0f) float brightness)691 public Builder setDimBrightness(@FloatRange(from = 0.0f, to = 1.0f) float brightness) { 692 if (!isValidBrightness(brightness)) { 693 throw new IllegalArgumentException( 694 "Virtual display dim brightness must be in range [0.0, 1.0]"); 695 } 696 mDimBrightness = brightness; 697 return this; 698 } 699 700 /** 701 * Sets the listener to get notified about changes in the display brightness. 702 * 703 * @param executor The executor where the callback is executed on. 704 * @param listener The listener to get notified when the display brightness has changed. 705 */ 706 @SuppressLint("MissingGetterMatchingBuilder") // The hidden getter returns the AIDL object 707 @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_DEVICE_AWARE_DISPLAY_POWER) 708 @NonNull setBrightnessListener(@onNull @allbackExecutor Executor executor, @NonNull BrightnessListener listener)709 public Builder setBrightnessListener(@NonNull @CallbackExecutor Executor executor, 710 @NonNull BrightnessListener listener) { 711 mBrightnessListener = new BrightnessListenerDelegate( 712 Objects.requireNonNull(executor), Objects.requireNonNull(listener)); 713 return this; 714 } 715 isValidBrightness(float brightness)716 private boolean isValidBrightness(float brightness) { 717 return !Float.isNaN(brightness) && PowerManager.BRIGHTNESS_MIN <= brightness 718 && brightness <= PowerManager.BRIGHTNESS_MAX; 719 } 720 721 /** 722 * Builds the {@link VirtualDisplayConfig} instance. 723 * 724 * @throws IllegalArgumentException if the dim brightness is set to a value greater than 725 * the default brightness. 726 */ 727 @NonNull build()728 public VirtualDisplayConfig build() { 729 if (isValidBrightness(mDimBrightness) && mDimBrightness > mDefaultBrightness) { 730 throw new IllegalArgumentException( 731 "The dim brightness must not be greater than the default brightness"); 732 } 733 return new VirtualDisplayConfig( 734 mName, 735 mWidth, 736 mHeight, 737 mDensityDpi, 738 mFlags, 739 mSurface, 740 mUniqueId, 741 mDisplayIdToMirror, 742 mWindowManagerMirroringEnabled, 743 mDisplayCategories, 744 mRequestedRefreshRate, 745 mIsHomeSupported, 746 mDisplayCutout, 747 mIgnoreActivitySizeRestrictions, 748 mDefaultBrightness, 749 mDimBrightness, 750 mBrightnessListener); 751 } 752 } 753 } 754