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.FlaggedApi; 22 import android.annotation.FloatRange; 23 import android.annotation.IntRange; 24 import android.annotation.NonNull; 25 import android.annotation.Nullable; 26 import android.annotation.SystemApi; 27 import android.hardware.display.DisplayManager.VirtualDisplayFlag; 28 import android.media.projection.MediaProjection; 29 import android.os.Handler; 30 import android.os.Parcel; 31 import android.os.Parcelable; 32 import android.util.ArraySet; 33 import android.view.Display; 34 import android.view.Surface; 35 36 import java.util.Collections; 37 import java.util.Objects; 38 import java.util.Set; 39 40 /** 41 * Holds configuration used to create {@link VirtualDisplay} instances. 42 * 43 * @see DisplayManager#createVirtualDisplay(VirtualDisplayConfig, Handler, VirtualDisplay.Callback) 44 * @see MediaProjection#createVirtualDisplay(String, int, int, int, int, Surface, 45 * VirtualDisplay.Callback, Handler) 46 */ 47 public final class VirtualDisplayConfig implements Parcelable { 48 49 private final String mName; 50 private final int mWidth; 51 private final int mHeight; 52 private final int mDensityDpi; 53 private final int mFlags; 54 private final Surface mSurface; 55 private final String mUniqueId; 56 private final int mDisplayIdToMirror; 57 private final boolean mWindowManagerMirroringEnabled; 58 private ArraySet<String> mDisplayCategories = null; 59 private final float mRequestedRefreshRate; 60 private final boolean mIsHomeSupported; 61 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)62 private VirtualDisplayConfig( 63 @NonNull String name, 64 @IntRange(from = 1) int width, 65 @IntRange(from = 1) int height, 66 @IntRange(from = 1) int densityDpi, 67 @VirtualDisplayFlag int flags, 68 @Nullable Surface surface, 69 @Nullable String uniqueId, 70 int displayIdToMirror, 71 boolean windowManagerMirroringEnabled, 72 @NonNull ArraySet<String> displayCategories, 73 float requestedRefreshRate, 74 boolean isHomeSupported) { 75 mName = name; 76 mWidth = width; 77 mHeight = height; 78 mDensityDpi = densityDpi; 79 mFlags = flags; 80 mSurface = surface; 81 mUniqueId = uniqueId; 82 mDisplayIdToMirror = displayIdToMirror; 83 mWindowManagerMirroringEnabled = windowManagerMirroringEnabled; 84 mDisplayCategories = displayCategories; 85 mRequestedRefreshRate = requestedRefreshRate; 86 mIsHomeSupported = isHomeSupported; 87 } 88 89 /** 90 * Returns the name of the virtual display. 91 */ 92 @NonNull getName()93 public String getName() { 94 return mName; 95 } 96 97 /** 98 * Returns the width of the virtual display in pixels. 99 */ getWidth()100 public int getWidth() { 101 return mWidth; 102 } 103 104 /** 105 * Returns the height of the virtual display in pixels. 106 */ getHeight()107 public int getHeight() { 108 return mHeight; 109 } 110 111 /** 112 * Returns the density of the virtual display in dpi. 113 */ getDensityDpi()114 public int getDensityDpi() { 115 return mDensityDpi; 116 } 117 118 /** 119 * Returns the virtual display flags. 120 * 121 * @see Builder#setFlags 122 */ getFlags()123 public int getFlags() { 124 return mFlags; 125 } 126 127 /** 128 * Returns the surface to which the content of the virtual display should be rendered, if any. 129 * 130 * @see Builder#setSurface 131 */ 132 @Nullable getSurface()133 public Surface getSurface() { 134 return mSurface; 135 } 136 137 /** 138 * Returns the unique identifier for the display. Shouldn't be displayed to the user. 139 * @hide 140 */ 141 @Nullable getUniqueId()142 public String getUniqueId() { 143 return mUniqueId; 144 } 145 146 /** 147 * Returns the id of the display that the virtual display should mirror, or 148 * {@link android.view.Display#DEFAULT_DISPLAY} if there is none. 149 * @hide 150 */ getDisplayIdToMirror()151 public int getDisplayIdToMirror() { 152 return mDisplayIdToMirror; 153 } 154 155 /** 156 * Whether if WindowManager is responsible for mirroring content to this VirtualDisplay, or 157 * if DisplayManager should record contents instead. 158 * @hide 159 */ isWindowManagerMirroringEnabled()160 public boolean isWindowManagerMirroringEnabled() { 161 return mWindowManagerMirroringEnabled; 162 } 163 164 /** 165 * Whether this virtual display supports showing home activity and wallpaper. 166 * 167 * @see Builder#setHomeSupported 168 * @hide 169 */ 170 @FlaggedApi(android.companion.virtual.flags.Flags.FLAG_VDM_CUSTOM_HOME) 171 @SystemApi isHomeSupported()172 public boolean isHomeSupported() { 173 return android.companion.virtual.flags.Flags.vdmCustomHome() && mIsHomeSupported; 174 } 175 176 /** 177 * Returns the display categories. 178 * 179 * @see Builder#setDisplayCategories 180 */ 181 @NonNull getDisplayCategories()182 public Set<String> getDisplayCategories() { 183 return Collections.unmodifiableSet(mDisplayCategories); 184 } 185 186 /** 187 * Returns the refresh rate of a virtual display in frames per second, or zero if it is using a 188 * default refresh rate chosen by the system. 189 * 190 * @see Builder#setRequestedRefreshRate 191 */ getRequestedRefreshRate()192 public float getRequestedRefreshRate() { 193 return mRequestedRefreshRate; 194 } 195 196 @Override writeToParcel(@onNull Parcel dest, int flags)197 public void writeToParcel(@NonNull Parcel dest, int flags) { 198 dest.writeString8(mName); 199 dest.writeInt(mWidth); 200 dest.writeInt(mHeight); 201 dest.writeInt(mDensityDpi); 202 dest.writeInt(mFlags); 203 dest.writeTypedObject(mSurface, flags); 204 dest.writeString8(mUniqueId); 205 dest.writeInt(mDisplayIdToMirror); 206 dest.writeBoolean(mWindowManagerMirroringEnabled); 207 dest.writeArraySet(mDisplayCategories); 208 dest.writeFloat(mRequestedRefreshRate); 209 dest.writeBoolean(mIsHomeSupported); 210 } 211 212 @Override describeContents()213 public int describeContents() { return 0; } 214 215 @Override equals(Object o)216 public boolean equals(Object o) { 217 if (this == o) { 218 return true; 219 } 220 if (!(o instanceof VirtualDisplayConfig)) { 221 return false; 222 } 223 VirtualDisplayConfig that = (VirtualDisplayConfig) o; 224 return Objects.equals(mName, that.mName) 225 && mWidth == that.mWidth 226 && mHeight == that.mHeight 227 && mDensityDpi == that.mDensityDpi 228 && mFlags == that.mFlags 229 && Objects.equals(mSurface, that.mSurface) 230 && Objects.equals(mUniqueId, that.mUniqueId) 231 && mDisplayIdToMirror == that.mDisplayIdToMirror 232 && mWindowManagerMirroringEnabled == that.mWindowManagerMirroringEnabled 233 && Objects.equals(mDisplayCategories, that.mDisplayCategories) 234 && mRequestedRefreshRate == that.mRequestedRefreshRate 235 && mIsHomeSupported == that.mIsHomeSupported; 236 } 237 238 @Override hashCode()239 public int hashCode() { 240 int hashCode = Objects.hash( 241 mName, mWidth, mHeight, mDensityDpi, mFlags, mSurface, mUniqueId, 242 mDisplayIdToMirror, mWindowManagerMirroringEnabled, mDisplayCategories, 243 mRequestedRefreshRate, mIsHomeSupported); 244 return hashCode; 245 } 246 247 @Override 248 @NonNull toString()249 public String toString() { 250 return "VirtualDisplayConfig(" 251 + " mName=" + mName 252 + " mHeight=" + mHeight 253 + " mWidth=" + mWidth 254 + " mDensityDpi=" + mDensityDpi 255 + " mFlags=" + mFlags 256 + " mSurface=" + mSurface 257 + " mUniqueId=" + mUniqueId 258 + " mDisplayIdToMirror=" + mDisplayIdToMirror 259 + " mWindowManagerMirroringEnabled=" + mWindowManagerMirroringEnabled 260 + " mDisplayCategories=" + mDisplayCategories 261 + " mRequestedRefreshRate=" + mRequestedRefreshRate 262 + " mIsHomeSupported=" + mIsHomeSupported 263 + ")"; 264 } 265 VirtualDisplayConfig(@onNull Parcel in)266 private VirtualDisplayConfig(@NonNull Parcel in) { 267 mName = in.readString8(); 268 mWidth = in.readInt(); 269 mHeight = in.readInt(); 270 mDensityDpi = in.readInt(); 271 mFlags = in.readInt(); 272 mSurface = in.readTypedObject(Surface.CREATOR); 273 mUniqueId = in.readString8(); 274 mDisplayIdToMirror = in.readInt(); 275 mWindowManagerMirroringEnabled = in.readBoolean(); 276 mDisplayCategories = (ArraySet<String>) in.readArraySet(null); 277 mRequestedRefreshRate = in.readFloat(); 278 mIsHomeSupported = in.readBoolean(); 279 } 280 281 @NonNull 282 public static final Parcelable.Creator<VirtualDisplayConfig> CREATOR 283 = new Parcelable.Creator<VirtualDisplayConfig>() { 284 @Override 285 public VirtualDisplayConfig[] newArray(int size) { 286 return new VirtualDisplayConfig[size]; 287 } 288 289 @Override 290 public VirtualDisplayConfig createFromParcel(@NonNull Parcel in) { 291 return new VirtualDisplayConfig(in); 292 } 293 }; 294 295 /** 296 * A builder for {@link VirtualDisplayConfig}. 297 */ 298 public static final class Builder { 299 private final String mName; 300 private final int mWidth; 301 private final int mHeight; 302 private final int mDensityDpi; 303 private int mFlags = 0; 304 private Surface mSurface = null; 305 private String mUniqueId = null; 306 private int mDisplayIdToMirror = DEFAULT_DISPLAY; 307 private boolean mWindowManagerMirroringEnabled = false; 308 private ArraySet<String> mDisplayCategories = new ArraySet<>(); 309 private float mRequestedRefreshRate = 0.0f; 310 private boolean mIsHomeSupported = false; 311 312 /** 313 * Creates a new Builder. 314 * 315 * @param name The name of the virtual display, must be non-empty. 316 * @param width The width of the virtual display in pixels. Must be greater than 0. 317 * @param height The height of the virtual display in pixels. Must be greater than 0. 318 * @param densityDpi The density of the virtual display in dpi. Must be greater than 0. 319 */ Builder( @onNull String name, @IntRange(from = 1) int width, @IntRange(from = 1) int height, @IntRange(from = 1) int densityDpi)320 public Builder( 321 @NonNull String name, 322 @IntRange(from = 1) int width, 323 @IntRange(from = 1) int height, 324 @IntRange(from = 1) int densityDpi) { 325 if (name == null) { 326 throw new IllegalArgumentException("Virtual display name is required"); 327 } 328 if (width <= 0) { 329 throw new IllegalArgumentException("Virtual display width must be positive"); 330 } 331 if (height <= 0) { 332 throw new IllegalArgumentException("Virtual display height must be positive"); 333 } 334 if (densityDpi <= 0) { 335 throw new IllegalArgumentException("Virtual display density must be positive"); 336 } 337 mName = name; 338 mWidth = width; 339 mHeight = height; 340 mDensityDpi = densityDpi; 341 } 342 343 /** 344 * Sets the virtual display flags, a combination of 345 * {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_PUBLIC}, 346 * {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_PRESENTATION}, 347 * {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_SECURE}, 348 * {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY}, 349 * or {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR}. 350 */ 351 @NonNull setFlags(@irtualDisplayFlag int flags)352 public Builder setFlags(@VirtualDisplayFlag int flags) { 353 mFlags = flags; 354 return this; 355 } 356 357 /** 358 * Sets the surface to which the content of the virtual display should be rendered. 359 * 360 * <p>The surface can also be set after the display creation using 361 * {@link VirtualDisplay#setSurface(Surface)}. 362 */ 363 @NonNull setSurface(@ullable Surface surface)364 public Builder setSurface(@Nullable Surface surface) { 365 mSurface = surface; 366 return this; 367 } 368 369 /** 370 * Sets the unique identifier for the display. 371 * @hide 372 */ 373 @NonNull setUniqueId(@ullable String uniqueId)374 public Builder setUniqueId(@Nullable String uniqueId) { 375 mUniqueId = uniqueId; 376 return this; 377 } 378 379 /** 380 * Sets the id of the display that the virtual display should mirror. 381 * @hide 382 */ 383 @NonNull setDisplayIdToMirror(int displayIdToMirror)384 public Builder setDisplayIdToMirror(int displayIdToMirror) { 385 mDisplayIdToMirror = displayIdToMirror; 386 return this; 387 } 388 389 /** 390 * Sets whether WindowManager is responsible for mirroring content to this VirtualDisplay. 391 * If unset or false, DisplayManager should record contents instead. 392 * @hide 393 */ 394 @NonNull setWindowManagerMirroringEnabled(boolean windowManagerMirroringEnabled)395 public Builder setWindowManagerMirroringEnabled(boolean windowManagerMirroringEnabled) { 396 mWindowManagerMirroringEnabled = windowManagerMirroringEnabled; 397 return this; 398 } 399 400 /** 401 * Sets the display categories. 402 * 403 * <p>The categories of the display indicate the type of activities allowed to run on that 404 * display. Activities can declare a display category using 405 * {@link android.content.pm.ActivityInfo#requiredDisplayCategory}. 406 */ 407 @NonNull setDisplayCategories(@onNull Set<String> displayCategories)408 public Builder setDisplayCategories(@NonNull Set<String> displayCategories) { 409 mDisplayCategories.clear(); 410 mDisplayCategories.addAll(Objects.requireNonNull(displayCategories)); 411 return this; 412 } 413 414 /** 415 * Adds a display category. 416 * 417 * @see #setDisplayCategories 418 */ 419 @NonNull addDisplayCategory(@onNull String displayCategory)420 public Builder addDisplayCategory(@NonNull String displayCategory) { 421 mDisplayCategories.add(Objects.requireNonNull(displayCategory)); 422 return this; 423 } 424 425 /** 426 * Sets the refresh rate of a virtual display in frames per second. 427 * 428 * <p>For best results, specify a divisor of the physical refresh rate, e.g., 30 or 60 on 429 * a 120hz display. If an arbitrary refresh rate is specified, the rate will be rounded up 430 * to a divisor of the physical display. If unset or zero, the virtual display will be 431 * refreshed at the physical display refresh rate. 432 * 433 * @see Display#getRefreshRate() 434 */ 435 @NonNull setRequestedRefreshRate( @loatRangefrom = 0.0f) float requestedRefreshRate)436 public Builder setRequestedRefreshRate( 437 @FloatRange(from = 0.0f) float requestedRefreshRate) { 438 if (requestedRefreshRate < 0.0f) { 439 throw new IllegalArgumentException( 440 "Virtual display requested refresh rate must be non-negative"); 441 } 442 mRequestedRefreshRate = requestedRefreshRate; 443 return this; 444 } 445 446 /** 447 * Sets whether this display supports showing home activities and wallpaper. 448 * 449 * <p>If set to {@code true}, then the home activity relevant to this display will be 450 * automatically launched upon the display creation. If unset or set to {@code false}, the 451 * display will not host any activities upon creation.</p> 452 * 453 * <p>Note: setting to {@code true} requires the display to be trusted and to not mirror 454 * content of other displays. If the display is not trusted, or if it mirrors content of 455 * other displays, this property is ignored.</p> 456 * 457 * @param isHomeSupported whether home activities are supported on the display 458 * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_TRUSTED 459 * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR 460 * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY 461 * @hide 462 */ 463 @FlaggedApi(android.companion.virtual.flags.Flags.FLAG_VDM_CUSTOM_HOME) 464 @SystemApi 465 @NonNull setHomeSupported(boolean isHomeSupported)466 public Builder setHomeSupported(boolean isHomeSupported) { 467 mIsHomeSupported = isHomeSupported; 468 return this; 469 } 470 471 /** 472 * Builds the {@link VirtualDisplayConfig} instance. 473 */ 474 @NonNull build()475 public VirtualDisplayConfig build() { 476 return new VirtualDisplayConfig( 477 mName, 478 mWidth, 479 mHeight, 480 mDensityDpi, 481 mFlags, 482 mSurface, 483 mUniqueId, 484 mDisplayIdToMirror, 485 mWindowManagerMirroringEnabled, 486 mDisplayCategories, 487 mRequestedRefreshRate, 488 mIsHomeSupported); 489 } 490 } 491 } 492