492 lines
17 KiB
Java
492 lines
17 KiB
Java
![]() |
/*
|
||
|
* Copyright (C) 2020 The Android Open Source Project
|
||
|
*
|
||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
* you may not use this file except in compliance with the License.
|
||
|
* You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*/
|
||
|
|
||
|
package android.hardware.display;
|
||
|
|
||
|
import static android.view.Display.DEFAULT_DISPLAY;
|
||
|
|
||
|
import android.annotation.FlaggedApi;
|
||
|
import android.annotation.FloatRange;
|
||
|
import android.annotation.IntRange;
|
||
|
import android.annotation.NonNull;
|
||
|
import android.annotation.Nullable;
|
||
|
import android.annotation.SystemApi;
|
||
|
import android.hardware.display.DisplayManager.VirtualDisplayFlag;
|
||
|
import android.media.projection.MediaProjection;
|
||
|
import android.os.Handler;
|
||
|
import android.os.Parcel;
|
||
|
import android.os.Parcelable;
|
||
|
import android.util.ArraySet;
|
||
|
import android.view.Display;
|
||
|
import android.view.Surface;
|
||
|
|
||
|
import java.util.Collections;
|
||
|
import java.util.Objects;
|
||
|
import java.util.Set;
|
||
|
|
||
|
/**
|
||
|
* Holds configuration used to create {@link VirtualDisplay} instances.
|
||
|
*
|
||
|
* @see DisplayManager#createVirtualDisplay(VirtualDisplayConfig, Handler, VirtualDisplay.Callback)
|
||
|
* @see MediaProjection#createVirtualDisplay(String, int, int, int, int, Surface,
|
||
|
* VirtualDisplay.Callback, Handler)
|
||
|
*/
|
||
|
public final class VirtualDisplayConfig implements Parcelable {
|
||
|
|
||
|
private final String mName;
|
||
|
private final int mWidth;
|
||
|
private final int mHeight;
|
||
|
private final int mDensityDpi;
|
||
|
private final int mFlags;
|
||
|
private final Surface mSurface;
|
||
|
private final String mUniqueId;
|
||
|
private final int mDisplayIdToMirror;
|
||
|
private final boolean mWindowManagerMirroringEnabled;
|
||
|
private ArraySet<String> mDisplayCategories = null;
|
||
|
private final float mRequestedRefreshRate;
|
||
|
private final boolean mIsHomeSupported;
|
||
|
|
||
|
private VirtualDisplayConfig(
|
||
|
@NonNull 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) {
|
||
|
mName = name;
|
||
|
mWidth = width;
|
||
|
mHeight = height;
|
||
|
mDensityDpi = densityDpi;
|
||
|
mFlags = flags;
|
||
|
mSurface = surface;
|
||
|
mUniqueId = uniqueId;
|
||
|
mDisplayIdToMirror = displayIdToMirror;
|
||
|
mWindowManagerMirroringEnabled = windowManagerMirroringEnabled;
|
||
|
mDisplayCategories = displayCategories;
|
||
|
mRequestedRefreshRate = requestedRefreshRate;
|
||
|
mIsHomeSupported = isHomeSupported;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the name of the virtual display.
|
||
|
*/
|
||
|
@NonNull
|
||
|
public String getName() {
|
||
|
return mName;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the width of the virtual display in pixels.
|
||
|
*/
|
||
|
public int getWidth() {
|
||
|
return mWidth;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the height of the virtual display in pixels.
|
||
|
*/
|
||
|
public int getHeight() {
|
||
|
return mHeight;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the density of the virtual display in dpi.
|
||
|
*/
|
||
|
public int getDensityDpi() {
|
||
|
return mDensityDpi;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the virtual display flags.
|
||
|
*
|
||
|
* @see Builder#setFlags
|
||
|
*/
|
||
|
public int getFlags() {
|
||
|
return mFlags;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the surface to which the content of the virtual display should be rendered, if any.
|
||
|
*
|
||
|
* @see Builder#setSurface
|
||
|
*/
|
||
|
@Nullable
|
||
|
public Surface getSurface() {
|
||
|
return mSurface;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the unique identifier for the display. Shouldn't be displayed to the user.
|
||
|
* @hide
|
||
|
*/
|
||
|
@Nullable
|
||
|
public String getUniqueId() {
|
||
|
return mUniqueId;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the id of the display that the virtual display should mirror, or
|
||
|
* {@link android.view.Display#DEFAULT_DISPLAY} if there is none.
|
||
|
* @hide
|
||
|
*/
|
||
|
public int getDisplayIdToMirror() {
|
||
|
return mDisplayIdToMirror;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Whether if WindowManager is responsible for mirroring content to this VirtualDisplay, or
|
||
|
* if DisplayManager should record contents instead.
|
||
|
* @hide
|
||
|
*/
|
||
|
public boolean isWindowManagerMirroringEnabled() {
|
||
|
return mWindowManagerMirroringEnabled;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Whether this virtual display supports showing home activity and wallpaper.
|
||
|
*
|
||
|
* @see Builder#setHomeSupported
|
||
|
* @hide
|
||
|
*/
|
||
|
@FlaggedApi(android.companion.virtual.flags.Flags.FLAG_VDM_CUSTOM_HOME)
|
||
|
@SystemApi
|
||
|
public boolean isHomeSupported() {
|
||
|
return android.companion.virtual.flags.Flags.vdmCustomHome() && mIsHomeSupported;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the display categories.
|
||
|
*
|
||
|
* @see Builder#setDisplayCategories
|
||
|
*/
|
||
|
@NonNull
|
||
|
public Set<String> getDisplayCategories() {
|
||
|
return Collections.unmodifiableSet(mDisplayCategories);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the refresh rate of a virtual display in frames per second, or zero if it is using a
|
||
|
* default refresh rate chosen by the system.
|
||
|
*
|
||
|
* @see Builder#setRequestedRefreshRate
|
||
|
*/
|
||
|
public float getRequestedRefreshRate() {
|
||
|
return mRequestedRefreshRate;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||
|
dest.writeString8(mName);
|
||
|
dest.writeInt(mWidth);
|
||
|
dest.writeInt(mHeight);
|
||
|
dest.writeInt(mDensityDpi);
|
||
|
dest.writeInt(mFlags);
|
||
|
dest.writeTypedObject(mSurface, flags);
|
||
|
dest.writeString8(mUniqueId);
|
||
|
dest.writeInt(mDisplayIdToMirror);
|
||
|
dest.writeBoolean(mWindowManagerMirroringEnabled);
|
||
|
dest.writeArraySet(mDisplayCategories);
|
||
|
dest.writeFloat(mRequestedRefreshRate);
|
||
|
dest.writeBoolean(mIsHomeSupported);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public int describeContents() { return 0; }
|
||
|
|
||
|
@Override
|
||
|
public boolean equals(Object o) {
|
||
|
if (this == o) {
|
||
|
return true;
|
||
|
}
|
||
|
if (!(o instanceof VirtualDisplayConfig)) {
|
||
|
return false;
|
||
|
}
|
||
|
VirtualDisplayConfig that = (VirtualDisplayConfig) o;
|
||
|
return Objects.equals(mName, that.mName)
|
||
|
&& mWidth == that.mWidth
|
||
|
&& mHeight == that.mHeight
|
||
|
&& mDensityDpi == that.mDensityDpi
|
||
|
&& mFlags == that.mFlags
|
||
|
&& Objects.equals(mSurface, that.mSurface)
|
||
|
&& Objects.equals(mUniqueId, that.mUniqueId)
|
||
|
&& mDisplayIdToMirror == that.mDisplayIdToMirror
|
||
|
&& mWindowManagerMirroringEnabled == that.mWindowManagerMirroringEnabled
|
||
|
&& Objects.equals(mDisplayCategories, that.mDisplayCategories)
|
||
|
&& mRequestedRefreshRate == that.mRequestedRefreshRate
|
||
|
&& mIsHomeSupported == that.mIsHomeSupported;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public int hashCode() {
|
||
|
int hashCode = Objects.hash(
|
||
|
mName, mWidth, mHeight, mDensityDpi, mFlags, mSurface, mUniqueId,
|
||
|
mDisplayIdToMirror, mWindowManagerMirroringEnabled, mDisplayCategories,
|
||
|
mRequestedRefreshRate, mIsHomeSupported);
|
||
|
return hashCode;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
@NonNull
|
||
|
public String toString() {
|
||
|
return "VirtualDisplayConfig("
|
||
|
+ " mName=" + mName
|
||
|
+ " mHeight=" + mHeight
|
||
|
+ " mWidth=" + mWidth
|
||
|
+ " mDensityDpi=" + mDensityDpi
|
||
|
+ " mFlags=" + mFlags
|
||
|
+ " mSurface=" + mSurface
|
||
|
+ " mUniqueId=" + mUniqueId
|
||
|
+ " mDisplayIdToMirror=" + mDisplayIdToMirror
|
||
|
+ " mWindowManagerMirroringEnabled=" + mWindowManagerMirroringEnabled
|
||
|
+ " mDisplayCategories=" + mDisplayCategories
|
||
|
+ " mRequestedRefreshRate=" + mRequestedRefreshRate
|
||
|
+ " mIsHomeSupported=" + mIsHomeSupported
|
||
|
+ ")";
|
||
|
}
|
||
|
|
||
|
private VirtualDisplayConfig(@NonNull Parcel in) {
|
||
|
mName = in.readString8();
|
||
|
mWidth = in.readInt();
|
||
|
mHeight = in.readInt();
|
||
|
mDensityDpi = in.readInt();
|
||
|
mFlags = in.readInt();
|
||
|
mSurface = in.readTypedObject(Surface.CREATOR);
|
||
|
mUniqueId = in.readString8();
|
||
|
mDisplayIdToMirror = in.readInt();
|
||
|
mWindowManagerMirroringEnabled = in.readBoolean();
|
||
|
mDisplayCategories = (ArraySet<String>) in.readArraySet(null);
|
||
|
mRequestedRefreshRate = in.readFloat();
|
||
|
mIsHomeSupported = in.readBoolean();
|
||
|
}
|
||
|
|
||
|
@NonNull
|
||
|
public static final Parcelable.Creator<VirtualDisplayConfig> CREATOR
|
||
|
= new Parcelable.Creator<VirtualDisplayConfig>() {
|
||
|
@Override
|
||
|
public VirtualDisplayConfig[] newArray(int size) {
|
||
|
return new VirtualDisplayConfig[size];
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public VirtualDisplayConfig createFromParcel(@NonNull Parcel in) {
|
||
|
return new VirtualDisplayConfig(in);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* A builder for {@link VirtualDisplayConfig}.
|
||
|
*/
|
||
|
public static final class Builder {
|
||
|
private final String mName;
|
||
|
private final int mWidth;
|
||
|
private final int mHeight;
|
||
|
private final int mDensityDpi;
|
||
|
private int mFlags = 0;
|
||
|
private Surface mSurface = null;
|
||
|
private String mUniqueId = null;
|
||
|
private int mDisplayIdToMirror = DEFAULT_DISPLAY;
|
||
|
private boolean mWindowManagerMirroringEnabled = false;
|
||
|
private ArraySet<String> mDisplayCategories = new ArraySet<>();
|
||
|
private float mRequestedRefreshRate = 0.0f;
|
||
|
private boolean mIsHomeSupported = false;
|
||
|
|
||
|
/**
|
||
|
* Creates a new Builder.
|
||
|
*
|
||
|
* @param name The name of the virtual display, must be non-empty.
|
||
|
* @param width The width of the virtual display in pixels. Must be greater than 0.
|
||
|
* @param height The height of the virtual display in pixels. Must be greater than 0.
|
||
|
* @param densityDpi The density of the virtual display in dpi. Must be greater than 0.
|
||
|
*/
|
||
|
public Builder(
|
||
|
@NonNull String name,
|
||
|
@IntRange(from = 1) int width,
|
||
|
@IntRange(from = 1) int height,
|
||
|
@IntRange(from = 1) int densityDpi) {
|
||
|
if (name == null) {
|
||
|
throw new IllegalArgumentException("Virtual display name is required");
|
||
|
}
|
||
|
if (width <= 0) {
|
||
|
throw new IllegalArgumentException("Virtual display width must be positive");
|
||
|
}
|
||
|
if (height <= 0) {
|
||
|
throw new IllegalArgumentException("Virtual display height must be positive");
|
||
|
}
|
||
|
if (densityDpi <= 0) {
|
||
|
throw new IllegalArgumentException("Virtual display density must be positive");
|
||
|
}
|
||
|
mName = name;
|
||
|
mWidth = width;
|
||
|
mHeight = height;
|
||
|
mDensityDpi = densityDpi;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets the virtual display flags, a combination of
|
||
|
* {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_PUBLIC},
|
||
|
* {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_PRESENTATION},
|
||
|
* {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_SECURE},
|
||
|
* {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY},
|
||
|
* or {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR}.
|
||
|
*/
|
||
|
@NonNull
|
||
|
public Builder setFlags(@VirtualDisplayFlag int flags) {
|
||
|
mFlags = flags;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets the surface to which the content of the virtual display should be rendered.
|
||
|
*
|
||
|
* <p>The surface can also be set after the display creation using
|
||
|
* {@link VirtualDisplay#setSurface(Surface)}.
|
||
|
*/
|
||
|
@NonNull
|
||
|
public Builder setSurface(@Nullable Surface surface) {
|
||
|
mSurface = surface;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets the unique identifier for the display.
|
||
|
* @hide
|
||
|
*/
|
||
|
@NonNull
|
||
|
public Builder setUniqueId(@Nullable String uniqueId) {
|
||
|
mUniqueId = uniqueId;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets the id of the display that the virtual display should mirror.
|
||
|
* @hide
|
||
|
*/
|
||
|
@NonNull
|
||
|
public Builder setDisplayIdToMirror(int displayIdToMirror) {
|
||
|
mDisplayIdToMirror = displayIdToMirror;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets whether WindowManager is responsible for mirroring content to this VirtualDisplay.
|
||
|
* If unset or false, DisplayManager should record contents instead.
|
||
|
* @hide
|
||
|
*/
|
||
|
@NonNull
|
||
|
public Builder setWindowManagerMirroringEnabled(boolean windowManagerMirroringEnabled) {
|
||
|
mWindowManagerMirroringEnabled = windowManagerMirroringEnabled;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets the display categories.
|
||
|
*
|
||
|
* <p>The categories of the display indicate the type of activities allowed to run on that
|
||
|
* display. Activities can declare a display category using
|
||
|
* {@link android.content.pm.ActivityInfo#requiredDisplayCategory}.
|
||
|
*/
|
||
|
@NonNull
|
||
|
public Builder setDisplayCategories(@NonNull Set<String> displayCategories) {
|
||
|
mDisplayCategories.clear();
|
||
|
mDisplayCategories.addAll(Objects.requireNonNull(displayCategories));
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Adds a display category.
|
||
|
*
|
||
|
* @see #setDisplayCategories
|
||
|
*/
|
||
|
@NonNull
|
||
|
public Builder addDisplayCategory(@NonNull String displayCategory) {
|
||
|
mDisplayCategories.add(Objects.requireNonNull(displayCategory));
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets the refresh rate of a virtual display in frames per second.
|
||
|
*
|
||
|
* <p>For best results, specify a divisor of the physical refresh rate, e.g., 30 or 60 on
|
||
|
* a 120hz display. If an arbitrary refresh rate is specified, the rate will be rounded up
|
||
|
* to a divisor of the physical display. If unset or zero, the virtual display will be
|
||
|
* refreshed at the physical display refresh rate.
|
||
|
*
|
||
|
* @see Display#getRefreshRate()
|
||
|
*/
|
||
|
@NonNull
|
||
|
public Builder setRequestedRefreshRate(
|
||
|
@FloatRange(from = 0.0f) float requestedRefreshRate) {
|
||
|
if (requestedRefreshRate < 0.0f) {
|
||
|
throw new IllegalArgumentException(
|
||
|
"Virtual display requested refresh rate must be non-negative");
|
||
|
}
|
||
|
mRequestedRefreshRate = requestedRefreshRate;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets whether this display supports showing home activities and wallpaper.
|
||
|
*
|
||
|
* <p>If set to {@code true}, then the home activity relevant to this display will be
|
||
|
* automatically launched upon the display creation. If unset or set to {@code false}, the
|
||
|
* display will not host any activities upon creation.</p>
|
||
|
*
|
||
|
* <p>Note: setting to {@code true} requires the display to be trusted and to not mirror
|
||
|
* content of other displays. If the display is not trusted, or if it mirrors content of
|
||
|
* other displays, this property is ignored.</p>
|
||
|
*
|
||
|
* @param isHomeSupported whether home activities are supported on the display
|
||
|
* @see DisplayManager#VIRTUAL_DISPLAY_FLAG_TRUSTED
|
||
|
* @see DisplayManager#VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR
|
||
|
* @see DisplayManager#VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY
|
||
|
* @hide
|
||
|
*/
|
||
|
@FlaggedApi(android.companion.virtual.flags.Flags.FLAG_VDM_CUSTOM_HOME)
|
||
|
@SystemApi
|
||
|
@NonNull
|
||
|
public Builder setHomeSupported(boolean isHomeSupported) {
|
||
|
mIsHomeSupported = isHomeSupported;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Builds the {@link VirtualDisplayConfig} instance.
|
||
|
*/
|
||
|
@NonNull
|
||
|
public VirtualDisplayConfig build() {
|
||
|
return new VirtualDisplayConfig(
|
||
|
mName,
|
||
|
mWidth,
|
||
|
mHeight,
|
||
|
mDensityDpi,
|
||
|
mFlags,
|
||
|
mSurface,
|
||
|
mUniqueId,
|
||
|
mDisplayIdToMirror,
|
||
|
mWindowManagerMirroringEnabled,
|
||
|
mDisplayCategories,
|
||
|
mRequestedRefreshRate,
|
||
|
mIsHomeSupported);
|
||
|
}
|
||
|
}
|
||
|
}
|