Merge "[wm] VirtualDisplayConfig to mirror the non-default display" into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
8885e4f115
@@ -634,17 +634,39 @@ public final class DisplayManager {
|
||||
public VirtualDisplay createVirtualDisplay(@NonNull String name,
|
||||
int width, int height, int densityDpi, @Nullable Surface surface, int flags,
|
||||
@Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
|
||||
return createVirtualDisplay(null /* projection */, name, width, height, densityDpi, surface,
|
||||
flags, callback, handler, null /* uniqueId */);
|
||||
final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(name, width,
|
||||
height, densityDpi);
|
||||
builder.setFlags(flags);
|
||||
if (surface != null) {
|
||||
builder.setSurface(surface);
|
||||
}
|
||||
return createVirtualDisplay(null /* projection */, builder.build(), callback, handler);
|
||||
}
|
||||
|
||||
// TODO : Remove this hidden API after remove all callers. (Refer to MultiDisplayService)
|
||||
/** @hide */
|
||||
public VirtualDisplay createVirtualDisplay(@Nullable MediaProjection projection,
|
||||
@NonNull String name, int width, int height, int densityDpi, @Nullable Surface surface,
|
||||
int flags, @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler,
|
||||
@Nullable String uniqueId) {
|
||||
return mGlobal.createVirtualDisplay(mContext, projection,
|
||||
name, width, height, densityDpi, surface, flags, callback, handler, uniqueId);
|
||||
final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(name, width,
|
||||
height, densityDpi);
|
||||
builder.setFlags(flags);
|
||||
if (uniqueId != null) {
|
||||
builder.setUniqueId(uniqueId);
|
||||
}
|
||||
if (surface != null) {
|
||||
builder.setSurface(surface);
|
||||
}
|
||||
return createVirtualDisplay(projection, builder.build(), callback, handler);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public VirtualDisplay createVirtualDisplay(@Nullable MediaProjection projection,
|
||||
@NonNull VirtualDisplayConfig virtualDisplayConfig,
|
||||
@Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
|
||||
return mGlobal.createVirtualDisplay(mContext, projection, virtualDisplayConfig, callback,
|
||||
handler);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -451,35 +451,26 @@ public final class DisplayManagerGlobal {
|
||||
}
|
||||
}
|
||||
|
||||
public VirtualDisplay createVirtualDisplay(Context context, MediaProjection projection,
|
||||
String name, int width, int height, int densityDpi, Surface surface, int flags,
|
||||
VirtualDisplay.Callback callback, Handler handler, String uniqueId) {
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
throw new IllegalArgumentException("name must be non-null and non-empty");
|
||||
}
|
||||
if (width <= 0 || height <= 0 || densityDpi <= 0) {
|
||||
throw new IllegalArgumentException("width, height, and densityDpi must be "
|
||||
+ "greater than 0");
|
||||
}
|
||||
|
||||
public VirtualDisplay createVirtualDisplay(@NonNull Context context, MediaProjection projection,
|
||||
@NonNull VirtualDisplayConfig virtualDisplayConfig, VirtualDisplay.Callback callback,
|
||||
Handler handler) {
|
||||
VirtualDisplayCallback callbackWrapper = new VirtualDisplayCallback(callback, handler);
|
||||
IMediaProjection projectionToken = projection != null ? projection.getProjection() : null;
|
||||
int displayId;
|
||||
try {
|
||||
displayId = mDm.createVirtualDisplay(callbackWrapper, projectionToken,
|
||||
context.getPackageName(), name, width, height, densityDpi, surface, flags,
|
||||
uniqueId);
|
||||
displayId = mDm.createVirtualDisplay(virtualDisplayConfig, callbackWrapper,
|
||||
projectionToken, context.getPackageName());
|
||||
} catch (RemoteException ex) {
|
||||
throw ex.rethrowFromSystemServer();
|
||||
}
|
||||
if (displayId < 0) {
|
||||
Log.e(TAG, "Could not create virtual display: " + name);
|
||||
Log.e(TAG, "Could not create virtual display: " + virtualDisplayConfig.getName());
|
||||
return null;
|
||||
}
|
||||
Display display = getRealDisplay(displayId);
|
||||
if (display == null) {
|
||||
Log.wtf(TAG, "Could not obtain display info for newly created "
|
||||
+ "virtual display: " + name);
|
||||
+ "virtual display: " + virtualDisplayConfig.getName());
|
||||
try {
|
||||
mDm.releaseVirtualDisplay(callbackWrapper);
|
||||
} catch (RemoteException ex) {
|
||||
@@ -487,7 +478,8 @@ public final class DisplayManagerGlobal {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return new VirtualDisplay(this, display, callbackWrapper, surface);
|
||||
return new VirtualDisplay(this, display, callbackWrapper,
|
||||
virtualDisplayConfig.getSurface());
|
||||
}
|
||||
|
||||
public void setVirtualDisplaySurface(IVirtualDisplayCallback token, Surface surface) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.hardware.display.BrightnessConfiguration;
|
||||
import android.hardware.display.Curve;
|
||||
import android.hardware.display.IDisplayManagerCallback;
|
||||
import android.hardware.display.IVirtualDisplayCallback;
|
||||
import android.hardware.display.VirtualDisplayConfig;
|
||||
import android.hardware.display.WifiDisplay;
|
||||
import android.hardware.display.WifiDisplayStatus;
|
||||
import android.media.projection.IMediaProjection;
|
||||
@@ -71,9 +72,9 @@ interface IDisplayManager {
|
||||
|
||||
// Requires CAPTURE_VIDEO_OUTPUT, CAPTURE_SECURE_VIDEO_OUTPUT, or an appropriate
|
||||
// MediaProjection token for certain combinations of flags.
|
||||
int createVirtualDisplay(in IVirtualDisplayCallback callback,
|
||||
in IMediaProjection projectionToken, String packageName, String name,
|
||||
int width, int height, int densityDpi, in Surface surface, int flags, String uniqueId);
|
||||
int createVirtualDisplay(in VirtualDisplayConfig virtualDisplayConfig,
|
||||
in IVirtualDisplayCallback callback, in IMediaProjection projectionToken,
|
||||
String packageName);
|
||||
|
||||
// No permissions required, but must be same Uid as the creator.
|
||||
void resizeVirtualDisplay(in IVirtualDisplayCallback token,
|
||||
|
||||
19
core/java/android/hardware/display/VirtualDisplayConfig.aidl
Normal file
19
core/java/android/hardware/display/VirtualDisplayConfig.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
parcelable VirtualDisplayConfig;
|
||||
491
core/java/android/hardware/display/VirtualDisplayConfig.java
Normal file
491
core/java/android/hardware/display/VirtualDisplayConfig.java
Normal file
@@ -0,0 +1,491 @@
|
||||
/*
|
||||
* 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.IntRange;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.media.projection.MediaProjection;
|
||||
import android.os.Handler;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.view.Surface;
|
||||
|
||||
import com.android.internal.util.DataClass;
|
||||
|
||||
/**
|
||||
* Holds configuration used to create {@link VirtualDisplay} instances. See
|
||||
* {@link MediaProjection#createVirtualDisplay(VirtualDisplayConfig, VirtualDisplay.Callback, Handler)}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@DataClass(genParcelable = true, genAidl = true, genBuilder = true)
|
||||
public final class VirtualDisplayConfig implements Parcelable {
|
||||
/**
|
||||
* The name of the virtual display, must be non-empty.
|
||||
*/
|
||||
@NonNull
|
||||
private String mName;
|
||||
|
||||
/**
|
||||
* The width of the virtual display in pixels. Must be greater than 0.
|
||||
*/
|
||||
@IntRange(from = 1)
|
||||
private int mWidth;
|
||||
|
||||
/**
|
||||
* The height of the virtual display in pixels. Must be greater than 0.
|
||||
*/
|
||||
@IntRange(from = 1)
|
||||
private int mHeight;
|
||||
|
||||
/**
|
||||
* The density of the virtual display in dpi. Must be greater than 0.
|
||||
*/
|
||||
@IntRange(from = 1)
|
||||
private int mDensityDpi;
|
||||
|
||||
/**
|
||||
* A combination of virtual display flags.
|
||||
* {@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}.
|
||||
*/
|
||||
private int mFlags = 0;
|
||||
|
||||
/**
|
||||
* The surface to which the content of the virtual display should be rendered, or null if
|
||||
* there is none initially.
|
||||
*/
|
||||
@Nullable
|
||||
private Surface mSurface = null;
|
||||
|
||||
/**
|
||||
* The unique identifier for the display. Shouldn't be displayed to the user.
|
||||
* @hide
|
||||
*/
|
||||
@Nullable
|
||||
private String mUniqueId = null;
|
||||
|
||||
/**
|
||||
* The id of the display that the virtual display should mirror, or
|
||||
* {@link android.view.Display#DEFAULT_DISPLAY} if there is none initially.
|
||||
*/
|
||||
private int mDisplayIdToMirror = DEFAULT_DISPLAY;
|
||||
|
||||
|
||||
|
||||
// Code below generated by codegen v1.0.15.
|
||||
//
|
||||
// DO NOT MODIFY!
|
||||
// CHECKSTYLE:OFF Generated code
|
||||
//
|
||||
// To regenerate run:
|
||||
// $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/hardware/display/VirtualDisplayConfig.java
|
||||
//
|
||||
// To exclude the generated code from IntelliJ auto-formatting enable (one-time):
|
||||
// Settings > Editor > Code Style > Formatter Control
|
||||
//@formatter:off
|
||||
|
||||
|
||||
@DataClass.Generated.Member
|
||||
/* package-private */ VirtualDisplayConfig(
|
||||
@NonNull String name,
|
||||
@IntRange(from = 1) int width,
|
||||
@IntRange(from = 1) int height,
|
||||
@IntRange(from = 1) int densityDpi,
|
||||
int flags,
|
||||
@Nullable Surface surface,
|
||||
@Nullable String uniqueId,
|
||||
int displayIdToMirror) {
|
||||
this.mName = name;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
NonNull.class, null, mName);
|
||||
this.mWidth = width;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
IntRange.class, null, mWidth,
|
||||
"from", 1);
|
||||
this.mHeight = height;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
IntRange.class, null, mHeight,
|
||||
"from", 1);
|
||||
this.mDensityDpi = densityDpi;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
IntRange.class, null, mDensityDpi,
|
||||
"from", 1);
|
||||
this.mFlags = flags;
|
||||
this.mSurface = surface;
|
||||
this.mUniqueId = uniqueId;
|
||||
this.mDisplayIdToMirror = displayIdToMirror;
|
||||
|
||||
// onConstructed(); // You can define this method to get a callback
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the virtual display, must be non-empty.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull String getName() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
/**
|
||||
* The width of the virtual display in pixels. Must be greater than 0.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @IntRange(from = 1) int getWidth() {
|
||||
return mWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* The height of the virtual display in pixels. Must be greater than 0.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @IntRange(from = 1) int getHeight() {
|
||||
return mHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* The density of the virtual display in dpi. Must be greater than 0.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @IntRange(from = 1) int getDensityDpi() {
|
||||
return mDensityDpi;
|
||||
}
|
||||
|
||||
/**
|
||||
* A combination of virtual display flags.
|
||||
* {@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}.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public int getFlags() {
|
||||
return mFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* The surface to which the content of the virtual display should be rendered, or null if
|
||||
* there is none initially.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @Nullable Surface getSurface() {
|
||||
return mSurface;
|
||||
}
|
||||
|
||||
/**
|
||||
* The unique identifier for the display. Shouldn't be displayed to the user.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @Nullable String getUniqueId() {
|
||||
return mUniqueId;
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the display that the virtual display should mirror, or
|
||||
* {@link android.view.Display#DEFAULT_DISPLAY} if there is none initially.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public int getDisplayIdToMirror() {
|
||||
return mDisplayIdToMirror;
|
||||
}
|
||||
|
||||
@Override
|
||||
@DataClass.Generated.Member
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
// You can override field parcelling by defining methods like:
|
||||
// void parcelFieldName(Parcel dest, int flags) { ... }
|
||||
|
||||
int flg = 0;
|
||||
if (mSurface != null) flg |= 0x20;
|
||||
if (mUniqueId != null) flg |= 0x40;
|
||||
dest.writeInt(flg);
|
||||
dest.writeString(mName);
|
||||
dest.writeInt(mWidth);
|
||||
dest.writeInt(mHeight);
|
||||
dest.writeInt(mDensityDpi);
|
||||
dest.writeInt(mFlags);
|
||||
if (mSurface != null) dest.writeTypedObject(mSurface, flags);
|
||||
if (mUniqueId != null) dest.writeString(mUniqueId);
|
||||
dest.writeInt(mDisplayIdToMirror);
|
||||
}
|
||||
|
||||
@Override
|
||||
@DataClass.Generated.Member
|
||||
public int describeContents() { return 0; }
|
||||
|
||||
/** @hide */
|
||||
@SuppressWarnings({"unchecked", "RedundantCast"})
|
||||
@DataClass.Generated.Member
|
||||
/* package-private */ VirtualDisplayConfig(@NonNull Parcel in) {
|
||||
// You can override field unparcelling by defining methods like:
|
||||
// static FieldType unparcelFieldName(Parcel in) { ... }
|
||||
|
||||
int flg = in.readInt();
|
||||
String name = in.readString();
|
||||
int width = in.readInt();
|
||||
int height = in.readInt();
|
||||
int densityDpi = in.readInt();
|
||||
int flags = in.readInt();
|
||||
Surface surface = (flg & 0x20) == 0 ? null : (Surface) in.readTypedObject(Surface.CREATOR);
|
||||
String uniqueId = (flg & 0x40) == 0 ? null : in.readString();
|
||||
int displayIdToMirror = in.readInt();
|
||||
|
||||
this.mName = name;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
NonNull.class, null, mName);
|
||||
this.mWidth = width;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
IntRange.class, null, mWidth,
|
||||
"from", 1);
|
||||
this.mHeight = height;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
IntRange.class, null, mHeight,
|
||||
"from", 1);
|
||||
this.mDensityDpi = densityDpi;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
IntRange.class, null, mDensityDpi,
|
||||
"from", 1);
|
||||
this.mFlags = flags;
|
||||
this.mSurface = surface;
|
||||
this.mUniqueId = uniqueId;
|
||||
this.mDisplayIdToMirror = displayIdToMirror;
|
||||
|
||||
// onConstructed(); // You can define this method to get a callback
|
||||
}
|
||||
|
||||
@DataClass.Generated.Member
|
||||
public static final @NonNull 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}
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
@DataClass.Generated.Member
|
||||
public static final class Builder {
|
||||
|
||||
private @NonNull String mName;
|
||||
private @IntRange(from = 1) int mWidth;
|
||||
private @IntRange(from = 1) int mHeight;
|
||||
private @IntRange(from = 1) int mDensityDpi;
|
||||
private int mFlags;
|
||||
private @Nullable Surface mSurface;
|
||||
private @Nullable String mUniqueId;
|
||||
private int mDisplayIdToMirror;
|
||||
|
||||
private long mBuilderFieldsSet = 0L;
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
mName = name;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
NonNull.class, null, mName);
|
||||
mWidth = width;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
IntRange.class, null, mWidth,
|
||||
"from", 1);
|
||||
mHeight = height;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
IntRange.class, null, mHeight,
|
||||
"from", 1);
|
||||
mDensityDpi = densityDpi;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
IntRange.class, null, mDensityDpi,
|
||||
"from", 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the virtual display, must be non-empty.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull Builder setName(@NonNull String value) {
|
||||
checkNotUsed();
|
||||
mBuilderFieldsSet |= 0x1;
|
||||
mName = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The width of the virtual display in pixels. Must be greater than 0.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull Builder setWidth(@IntRange(from = 1) int value) {
|
||||
checkNotUsed();
|
||||
mBuilderFieldsSet |= 0x2;
|
||||
mWidth = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The height of the virtual display in pixels. Must be greater than 0.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull Builder setHeight(@IntRange(from = 1) int value) {
|
||||
checkNotUsed();
|
||||
mBuilderFieldsSet |= 0x4;
|
||||
mHeight = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The density of the virtual display in dpi. Must be greater than 0.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull Builder setDensityDpi(@IntRange(from = 1) int value) {
|
||||
checkNotUsed();
|
||||
mBuilderFieldsSet |= 0x8;
|
||||
mDensityDpi = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* A combination of virtual display flags.
|
||||
* {@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}.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull Builder setFlags(int value) {
|
||||
checkNotUsed();
|
||||
mBuilderFieldsSet |= 0x10;
|
||||
mFlags = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The surface to which the content of the virtual display should be rendered, or null if
|
||||
* there is none initially.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull Builder setSurface(@NonNull Surface value) {
|
||||
checkNotUsed();
|
||||
mBuilderFieldsSet |= 0x20;
|
||||
mSurface = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The unique identifier for the display. Shouldn't be displayed to the user.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull Builder setUniqueId(@NonNull String value) {
|
||||
checkNotUsed();
|
||||
mBuilderFieldsSet |= 0x40;
|
||||
mUniqueId = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the display that the virtual display should mirror, or
|
||||
* {@link android.view.Display#DEFAULT_DISPLAY} if there is none initially.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull Builder setDisplayIdToMirror(int value) {
|
||||
checkNotUsed();
|
||||
mBuilderFieldsSet |= 0x80;
|
||||
mDisplayIdToMirror = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Builds the instance. This builder should not be touched after calling this! */
|
||||
public @NonNull VirtualDisplayConfig build() {
|
||||
checkNotUsed();
|
||||
mBuilderFieldsSet |= 0x100; // Mark builder used
|
||||
|
||||
if ((mBuilderFieldsSet & 0x10) == 0) {
|
||||
mFlags = 0;
|
||||
}
|
||||
if ((mBuilderFieldsSet & 0x20) == 0) {
|
||||
mSurface = null;
|
||||
}
|
||||
if ((mBuilderFieldsSet & 0x40) == 0) {
|
||||
mUniqueId = null;
|
||||
}
|
||||
if ((mBuilderFieldsSet & 0x80) == 0) {
|
||||
mDisplayIdToMirror = DEFAULT_DISPLAY;
|
||||
}
|
||||
VirtualDisplayConfig o = new VirtualDisplayConfig(
|
||||
mName,
|
||||
mWidth,
|
||||
mHeight,
|
||||
mDensityDpi,
|
||||
mFlags,
|
||||
mSurface,
|
||||
mUniqueId,
|
||||
mDisplayIdToMirror);
|
||||
return o;
|
||||
}
|
||||
|
||||
private void checkNotUsed() {
|
||||
if ((mBuilderFieldsSet & 0x100) != 0) {
|
||||
throw new IllegalStateException(
|
||||
"This Builder should not be reused. Use a new Builder instance instead");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DataClass.Generated(
|
||||
time = 1585179350902L,
|
||||
codegenVersion = "1.0.15",
|
||||
sourceFile = "frameworks/base/core/java/android/hardware/display/VirtualDisplayConfig.java",
|
||||
inputSignatures = "private @android.annotation.NonNull java.lang.String mName\nprivate @android.annotation.IntRange(from=1L) int mWidth\nprivate @android.annotation.IntRange(from=1L) int mHeight\nprivate @android.annotation.IntRange(from=1L) int mDensityDpi\nprivate int mFlags\nprivate @android.annotation.Nullable android.view.Surface mSurface\nprivate @android.annotation.Nullable java.lang.String mUniqueId\nprivate int mDisplayIdToMirror\nclass VirtualDisplayConfig extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genAidl=true, genBuilder=true)")
|
||||
@Deprecated
|
||||
private void __metadata() {}
|
||||
|
||||
|
||||
//@formatter:on
|
||||
// End of generated code
|
||||
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.hardware.display.DisplayManager;
|
||||
import android.hardware.display.VirtualDisplay;
|
||||
import android.hardware.display.VirtualDisplayConfig;
|
||||
import android.media.projection.IMediaProjection;
|
||||
import android.media.projection.IMediaProjectionCallback;
|
||||
import android.os.Handler;
|
||||
@@ -100,11 +101,18 @@ public final class MediaProjection {
|
||||
int width, int height, int dpi, boolean isSecure, @Nullable Surface surface,
|
||||
@Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
|
||||
DisplayManager dm = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
|
||||
int flags = isSecure ? DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE : 0;
|
||||
return dm.createVirtualDisplay(this, name, width, height, dpi, surface,
|
||||
flags | DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR |
|
||||
DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION, callback, handler,
|
||||
null /* uniqueId */);
|
||||
int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR
|
||||
| DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION;
|
||||
if (isSecure) {
|
||||
flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
|
||||
}
|
||||
final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(name, width,
|
||||
height, dpi);
|
||||
builder.setFlags(flags);
|
||||
if (surface != null) {
|
||||
builder.setSurface(surface);
|
||||
}
|
||||
return dm.createVirtualDisplay(this, builder.build(), callback, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,9 +141,35 @@ public final class MediaProjection {
|
||||
public VirtualDisplay createVirtualDisplay(@NonNull String name,
|
||||
int width, int height, int dpi, int flags, @Nullable Surface surface,
|
||||
@Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
|
||||
DisplayManager dm = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
|
||||
return dm.createVirtualDisplay(this, name, width, height, dpi, surface, flags, callback,
|
||||
handler, null /* uniqueId */);
|
||||
final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(name, width,
|
||||
height, dpi);
|
||||
builder.setFlags(flags);
|
||||
if (surface != null) {
|
||||
builder.setSurface(surface);
|
||||
}
|
||||
return createVirtualDisplay(builder.build(), callback, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link android.hardware.display.VirtualDisplay} to capture the
|
||||
* contents of the screen.
|
||||
*
|
||||
* @param virtualDisplayConfig The arguments for the virtual display configuration. See
|
||||
* {@link VirtualDisplayConfig} for using it.
|
||||
* @param callback Callback to call when the virtual display's state
|
||||
* changes, or null if none.
|
||||
* @param handler The {@link android.os.Handler} on which the callback should be
|
||||
* invoked, or null if the callback should be invoked on the calling
|
||||
* thread's main {@link android.os.Looper}.
|
||||
*
|
||||
* @see android.hardware.display.VirtualDisplay
|
||||
* @hide
|
||||
*/
|
||||
@Nullable
|
||||
public VirtualDisplay createVirtualDisplay(@NonNull VirtualDisplayConfig virtualDisplayConfig,
|
||||
@Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
|
||||
DisplayManager dm = mContext.getSystemService(DisplayManager.class);
|
||||
return dm.createVirtualDisplay(this, virtualDisplayConfig, callback, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.server.display;
|
||||
import android.graphics.Rect;
|
||||
import android.hardware.display.DisplayViewport;
|
||||
import android.os.IBinder;
|
||||
import android.view.Display;
|
||||
import android.view.DisplayAddress;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceControl;
|
||||
@@ -77,6 +78,13 @@ abstract class DisplayDevice {
|
||||
return mDisplayToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id of the display to mirror.
|
||||
*/
|
||||
public int getDisplayIdToMirrorLocked() {
|
||||
return Display.DEFAULT_DISPLAY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the display device.
|
||||
*
|
||||
|
||||
@@ -57,6 +57,7 @@ import android.hardware.display.DisplayedContentSamplingAttributes;
|
||||
import android.hardware.display.IDisplayManager;
|
||||
import android.hardware.display.IDisplayManagerCallback;
|
||||
import android.hardware.display.IVirtualDisplayCallback;
|
||||
import android.hardware.display.VirtualDisplayConfig;
|
||||
import android.hardware.display.WifiDisplayStatus;
|
||||
import android.hardware.input.InputManagerInternal;
|
||||
import android.media.projection.IMediaProjection;
|
||||
@@ -794,8 +795,8 @@ public final class DisplayManagerService extends SystemService {
|
||||
}
|
||||
|
||||
private int createVirtualDisplayInternal(IVirtualDisplayCallback callback,
|
||||
IMediaProjection projection, int callingUid, String packageName, String name, int width,
|
||||
int height, int densityDpi, Surface surface, int flags, String uniqueId) {
|
||||
IMediaProjection projection, int callingUid, String packageName, Surface surface,
|
||||
int flags, VirtualDisplayConfig virtualDisplayConfig) {
|
||||
synchronized (mSyncRoot) {
|
||||
if (mVirtualDisplayAdapter == null) {
|
||||
Slog.w(TAG, "Rejecting request to create private virtual display "
|
||||
@@ -804,8 +805,8 @@ public final class DisplayManagerService extends SystemService {
|
||||
}
|
||||
|
||||
DisplayDevice device = mVirtualDisplayAdapter.createVirtualDisplayLocked(
|
||||
callback, projection, callingUid, packageName, name, width, height, densityDpi,
|
||||
surface, flags, uniqueId);
|
||||
callback, projection, callingUid, packageName, surface, flags,
|
||||
virtualDisplayConfig);
|
||||
if (device == null) {
|
||||
return -1;
|
||||
}
|
||||
@@ -1480,8 +1481,8 @@ public final class DisplayManagerService extends SystemService {
|
||||
if (!ownContent) {
|
||||
if (display != null && !display.hasContentLocked()) {
|
||||
// If the display does not have any content of its own, then
|
||||
// automatically mirror the default logical display contents.
|
||||
display = null;
|
||||
// automatically mirror the requested logical display contents if possible.
|
||||
display = mLogicalDisplays.get(device.getDisplayIdToMirrorLocked());
|
||||
}
|
||||
if (display == null) {
|
||||
display = mLogicalDisplays.get(Display.DEFAULT_DISPLAY);
|
||||
@@ -1729,6 +1730,28 @@ public final class DisplayManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
int getDisplayIdToMirrorInternal(int displayId) {
|
||||
synchronized (mSyncRoot) {
|
||||
LogicalDisplay display = mLogicalDisplays.get(displayId);
|
||||
if (display != null) {
|
||||
DisplayDevice displayDevice = display.getPrimaryDisplayDeviceLocked();
|
||||
return displayDevice.getDisplayIdToMirrorLocked();
|
||||
}
|
||||
return Display.INVALID_DISPLAY;
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
Surface getVirtualDisplaySurfaceInternal(IBinder appToken) {
|
||||
synchronized (mSyncRoot) {
|
||||
if (mVirtualDisplayAdapter == null) {
|
||||
return null;
|
||||
}
|
||||
return mVirtualDisplayAdapter.getVirtualDisplaySurfaceLocked(appToken);
|
||||
}
|
||||
}
|
||||
|
||||
private final class DisplayManagerHandler extends Handler {
|
||||
public DisplayManagerHandler(Looper looper) {
|
||||
super(looper, null, true /*async*/);
|
||||
@@ -2050,10 +2073,8 @@ public final class DisplayManagerService extends SystemService {
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
public int createVirtualDisplay(IVirtualDisplayCallback callback,
|
||||
IMediaProjection projection, String packageName, String name,
|
||||
int width, int height, int densityDpi, Surface surface, int flags,
|
||||
String uniqueId) {
|
||||
public int createVirtualDisplay(VirtualDisplayConfig virtualDisplayConfig,
|
||||
IVirtualDisplayCallback callback, IMediaProjection projection, String packageName) {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
if (!validatePackageName(callingUid, packageName)) {
|
||||
throw new SecurityException("packageName must match the calling uid");
|
||||
@@ -2061,13 +2082,12 @@ public final class DisplayManagerService extends SystemService {
|
||||
if (callback == null) {
|
||||
throw new IllegalArgumentException("appToken must not be null");
|
||||
}
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
throw new IllegalArgumentException("name must be non-null and non-empty");
|
||||
}
|
||||
if (width <= 0 || height <= 0 || densityDpi <= 0) {
|
||||
throw new IllegalArgumentException("width, height, and densityDpi must be "
|
||||
+ "greater than 0");
|
||||
if (virtualDisplayConfig == null) {
|
||||
throw new IllegalArgumentException("virtualDisplayConfig must not be null");
|
||||
}
|
||||
final Surface surface = virtualDisplayConfig.getSurface();
|
||||
int flags = virtualDisplayConfig.getFlags();
|
||||
|
||||
if (surface != null && surface.isSingleBuffered()) {
|
||||
throw new IllegalArgumentException("Surface can't be single-buffered");
|
||||
}
|
||||
@@ -2128,7 +2148,7 @@ public final class DisplayManagerService extends SystemService {
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
return createVirtualDisplayInternal(callback, projection, callingUid, packageName,
|
||||
name, width, height, densityDpi, surface, flags, uniqueId);
|
||||
surface, flags, virtualDisplayConfig);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPO
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.display.IVirtualDisplayCallback;
|
||||
import android.hardware.display.VirtualDisplayConfig;
|
||||
import android.media.projection.IMediaProjection;
|
||||
import android.media.projection.IMediaProjectionCallback;
|
||||
import android.os.Handler;
|
||||
@@ -84,22 +85,24 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
|
||||
}
|
||||
|
||||
public DisplayDevice createVirtualDisplayLocked(IVirtualDisplayCallback callback,
|
||||
IMediaProjection projection, int ownerUid, String ownerPackageName, String name,
|
||||
int width, int height, int densityDpi, Surface surface, int flags, String uniqueId) {
|
||||
IMediaProjection projection, int ownerUid, String ownerPackageName, Surface surface,
|
||||
int flags, VirtualDisplayConfig virtualDisplayConfig) {
|
||||
String name = virtualDisplayConfig.getName();
|
||||
boolean secure = (flags & VIRTUAL_DISPLAY_FLAG_SECURE) != 0;
|
||||
IBinder appToken = callback.asBinder();
|
||||
IBinder displayToken = mSurfaceControlDisplayFactory.createDisplay(name, secure);
|
||||
final String baseUniqueId =
|
||||
UNIQUE_ID_PREFIX + ownerPackageName + "," + ownerUid + "," + name + ",";
|
||||
final int uniqueIndex = getNextUniqueIndex(baseUniqueId);
|
||||
String uniqueId = virtualDisplayConfig.getUniqueId();
|
||||
if (uniqueId == null) {
|
||||
uniqueId = baseUniqueId + uniqueIndex;
|
||||
} else {
|
||||
uniqueId = UNIQUE_ID_PREFIX + ownerPackageName + ":" + uniqueId;
|
||||
}
|
||||
VirtualDisplayDevice device = new VirtualDisplayDevice(displayToken, appToken,
|
||||
ownerUid, ownerPackageName, name, width, height, densityDpi, surface, flags,
|
||||
new Callback(callback, mHandler), uniqueId, uniqueIndex);
|
||||
ownerUid, ownerPackageName, surface, flags, new Callback(callback, mHandler),
|
||||
uniqueId, uniqueIndex, virtualDisplayConfig);
|
||||
|
||||
mVirtualDisplayDevices.put(appToken, device);
|
||||
|
||||
@@ -127,6 +130,14 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
Surface getVirtualDisplaySurfaceLocked(IBinder appToken) {
|
||||
VirtualDisplayDevice device = mVirtualDisplayDevices.get(appToken);
|
||||
if (device != null) {
|
||||
return device.getSurfaceLocked();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setVirtualDisplaySurfaceLocked(IBinder appToken, Surface surface) {
|
||||
VirtualDisplayDevice device = mVirtualDisplayDevices.get(appToken);
|
||||
@@ -214,20 +225,21 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
|
||||
private int mUniqueIndex;
|
||||
private Display.Mode mMode;
|
||||
private boolean mIsDisplayOn;
|
||||
private int mDisplayIdToMirror;
|
||||
|
||||
public VirtualDisplayDevice(IBinder displayToken, IBinder appToken,
|
||||
int ownerUid, String ownerPackageName,
|
||||
String name, int width, int height, int densityDpi, Surface surface, int flags,
|
||||
Callback callback, String uniqueId, int uniqueIndex) {
|
||||
int ownerUid, String ownerPackageName, Surface surface, int flags,
|
||||
Callback callback, String uniqueId, int uniqueIndex,
|
||||
VirtualDisplayConfig virtualDisplayConfig) {
|
||||
super(VirtualDisplayAdapter.this, displayToken, uniqueId);
|
||||
mAppToken = appToken;
|
||||
mOwnerUid = ownerUid;
|
||||
mOwnerPackageName = ownerPackageName;
|
||||
mName = name;
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
mMode = createMode(width, height, REFRESH_RATE);
|
||||
mDensityDpi = densityDpi;
|
||||
mName = virtualDisplayConfig.getName();
|
||||
mWidth = virtualDisplayConfig.getWidth();
|
||||
mHeight = virtualDisplayConfig.getHeight();
|
||||
mMode = createMode(mWidth, mHeight, REFRESH_RATE);
|
||||
mDensityDpi = virtualDisplayConfig.getDensityDpi();
|
||||
mSurface = surface;
|
||||
mFlags = flags;
|
||||
mCallback = callback;
|
||||
@@ -235,6 +247,7 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
|
||||
mPendingChanges |= PENDING_SURFACE_CHANGE;
|
||||
mUniqueIndex = uniqueIndex;
|
||||
mIsDisplayOn = surface != null;
|
||||
mDisplayIdToMirror = virtualDisplayConfig.getDisplayIdToMirror();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -259,6 +272,16 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDisplayIdToMirrorLocked() {
|
||||
return mDisplayIdToMirror;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
Surface getSurfaceLocked() {
|
||||
return mSurface;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasStableUniqueId() {
|
||||
return false;
|
||||
@@ -332,6 +355,7 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
|
||||
pw.println("mFlags=" + mFlags);
|
||||
pw.println("mDisplayState=" + Display.stateToString(mDisplayState));
|
||||
pw.println("mStopped=" + mStopped);
|
||||
pw.println("mDisplayIdToMirror=" + mDisplayIdToMirror);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import android.content.IntentFilter;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.hardware.display.DisplayManager;
|
||||
import android.hardware.display.VirtualDisplay;
|
||||
import android.hardware.display.VirtualDisplayConfig;
|
||||
import android.media.ImageReader;
|
||||
import android.os.Handler;
|
||||
import android.os.RemoteException;
|
||||
@@ -295,10 +296,12 @@ class Vr2dDisplay {
|
||||
flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL;
|
||||
flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
|
||||
|
||||
final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
|
||||
DISPLAY_NAME, mVirtualDisplayWidth, mVirtualDisplayHeight, mVirtualDisplayDpi);
|
||||
builder.setUniqueId(UNIQUE_DISPLAY_ID);
|
||||
builder.setFlags(flags);
|
||||
mVirtualDisplay = mDisplayManager.createVirtualDisplay(null /* projection */,
|
||||
DISPLAY_NAME, mVirtualDisplayWidth, mVirtualDisplayHeight, mVirtualDisplayDpi,
|
||||
null /* surface */, flags, null /* callback */, null /* handler */,
|
||||
UNIQUE_DISPLAY_ID);
|
||||
builder.build(), null /* callback */, null /* handler */);
|
||||
|
||||
if (mVirtualDisplay != null) {
|
||||
updateDisplayId(mVirtualDisplay.getDisplay().getDisplayId());
|
||||
|
||||
@@ -34,14 +34,17 @@ import android.hardware.display.DisplayViewport;
|
||||
import android.hardware.display.DisplayedContentSample;
|
||||
import android.hardware.display.DisplayedContentSamplingAttributes;
|
||||
import android.hardware.display.IVirtualDisplayCallback;
|
||||
import android.hardware.display.VirtualDisplayConfig;
|
||||
import android.hardware.input.InputManagerInternal;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.view.Display;
|
||||
import android.view.DisplayInfo;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceControl;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.FlakyTest;
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
@@ -67,6 +70,8 @@ import java.util.stream.LongStream;
|
||||
public class DisplayManagerServiceTest {
|
||||
private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1;
|
||||
private static final long SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS = 10;
|
||||
private static final String VIRTUAL_DISPLAY_NAME = "Test Virtual Display";
|
||||
private static final String PACKAGE_NAME = "com.android.frameworks.servicestests";
|
||||
|
||||
private Context mContext;
|
||||
|
||||
@@ -97,6 +102,7 @@ public class DisplayManagerServiceTest {
|
||||
|
||||
@Mock InputManagerInternal mMockInputManagerInternal;
|
||||
@Mock IVirtualDisplayCallback.Stub mMockAppToken;
|
||||
@Mock IVirtualDisplayCallback.Stub mMockAppToken2;
|
||||
@Mock WindowManagerInternal mMockWindowManagerInternal;
|
||||
@Mock LightsManager mMockLightsManager;
|
||||
@Mock VirtualDisplayAdapter mMockVirtualDisplayAdapter;
|
||||
@@ -135,10 +141,12 @@ public class DisplayManagerServiceTest {
|
||||
int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH;
|
||||
|
||||
when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
|
||||
int displayId = bs.createVirtualDisplay(mMockAppToken /* callback */,
|
||||
null /* projection */, "com.android.frameworks.servicestests",
|
||||
"Test Virtual Display", width, height, dpi, null /* surface */, flags /* flags */,
|
||||
uniqueId);
|
||||
final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
|
||||
VIRTUAL_DISPLAY_NAME, width, height, dpi);
|
||||
builder.setUniqueId(uniqueId);
|
||||
builder.setFlags(flags);
|
||||
int displayId = bs.createVirtualDisplay(builder.build(), mMockAppToken /* callback */,
|
||||
null /* projection */, PACKAGE_NAME);
|
||||
|
||||
displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
|
||||
|
||||
@@ -241,10 +249,12 @@ public class DisplayManagerServiceTest {
|
||||
int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT;
|
||||
|
||||
when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
|
||||
int displayId = bs.createVirtualDisplay(mMockAppToken /* callback */,
|
||||
null /* projection */, "com.android.frameworks.servicestests",
|
||||
"Test Virtual Display", width, height, dpi, null /* surface */, flags /* flags */,
|
||||
uniqueId);
|
||||
final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
|
||||
VIRTUAL_DISPLAY_NAME, width, height, dpi);
|
||||
builder.setFlags(flags);
|
||||
builder.setUniqueId(uniqueId);
|
||||
int displayId = bs.createVirtualDisplay(builder.build(), mMockAppToken /* callback */,
|
||||
null /* projection */, PACKAGE_NAME);
|
||||
|
||||
displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
|
||||
|
||||
@@ -409,6 +419,87 @@ public class DisplayManagerServiceTest {
|
||||
assertTrue(samples.length == 0 || LongStream.of(samples).sum() == numPixels);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the virtual display is created with
|
||||
* {@link VirtualDisplayConfig.Builder#setDisplayIdToMirror(int)}
|
||||
*/
|
||||
@Test
|
||||
@FlakyTest(bugId = 127687569)
|
||||
public void testCreateVirtualDisplay_displayIdToMirror() throws Exception {
|
||||
DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector);
|
||||
registerDefaultDisplays(displayManager);
|
||||
|
||||
// This is effectively the DisplayManager service published to ServiceManager.
|
||||
DisplayManagerService.BinderService binderService = displayManager.new BinderService();
|
||||
|
||||
final String uniqueId = "uniqueId --- displayIdToMirrorTest";
|
||||
final int width = 600;
|
||||
final int height = 800;
|
||||
final int dpi = 320;
|
||||
|
||||
when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
|
||||
final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
|
||||
VIRTUAL_DISPLAY_NAME, width, height, dpi);
|
||||
builder.setUniqueId(uniqueId);
|
||||
final int firstDisplayId = binderService.createVirtualDisplay(builder.build(),
|
||||
mMockAppToken /* callback */, null /* projection */, PACKAGE_NAME);
|
||||
|
||||
// The second virtual display requests to mirror the first virtual display.
|
||||
final String uniqueId2 = "uniqueId --- displayIdToMirrorTest #2";
|
||||
when(mMockAppToken2.asBinder()).thenReturn(mMockAppToken2);
|
||||
final VirtualDisplayConfig.Builder builder2 = new VirtualDisplayConfig.Builder(
|
||||
VIRTUAL_DISPLAY_NAME, width, height, dpi).setUniqueId(uniqueId2);
|
||||
builder2.setUniqueId(uniqueId2);
|
||||
builder2.setDisplayIdToMirror(firstDisplayId);
|
||||
final int secondDisplayId = binderService.createVirtualDisplay(builder2.build(),
|
||||
mMockAppToken2 /* callback */, null /* projection */, PACKAGE_NAME);
|
||||
displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
|
||||
|
||||
// flush the handler
|
||||
displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
|
||||
|
||||
// The displayId to mirror should be a default display if there is none initially.
|
||||
assertEquals(displayManager.getDisplayIdToMirrorInternal(firstDisplayId),
|
||||
Display.DEFAULT_DISPLAY);
|
||||
assertEquals(displayManager.getDisplayIdToMirrorInternal(secondDisplayId),
|
||||
firstDisplayId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the virtual display is created with
|
||||
* {@link VirtualDisplayConfig.Builder#setSurface(Surface)}
|
||||
*/
|
||||
@Test
|
||||
@FlakyTest(bugId = 127687569)
|
||||
public void testCreateVirtualDisplay_setSurface() throws Exception {
|
||||
DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector);
|
||||
registerDefaultDisplays(displayManager);
|
||||
|
||||
// This is effectively the DisplayManager service published to ServiceManager.
|
||||
DisplayManagerService.BinderService binderService = displayManager.new BinderService();
|
||||
|
||||
final String uniqueId = "uniqueId --- setSurface";
|
||||
final int width = 600;
|
||||
final int height = 800;
|
||||
final int dpi = 320;
|
||||
final Surface surface = new Surface();
|
||||
|
||||
when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
|
||||
final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
|
||||
VIRTUAL_DISPLAY_NAME, width, height, dpi);
|
||||
builder.setSurface(surface);
|
||||
builder.setUniqueId(uniqueId);
|
||||
final int displayId = binderService.createVirtualDisplay(builder.build(),
|
||||
mMockAppToken /* callback */, null /* projection */, PACKAGE_NAME);
|
||||
|
||||
displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
|
||||
|
||||
// flush the handler
|
||||
displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
|
||||
|
||||
assertEquals(displayManager.getVirtualDisplaySurfaceInternal(mMockAppToken), surface);
|
||||
}
|
||||
|
||||
private void registerDefaultDisplays(DisplayManagerService displayManager) {
|
||||
Handler handler = displayManager.getDisplayHandler();
|
||||
// Would prefer to call displayManager.onStart() directly here but it performs binderService
|
||||
|
||||
Reference in New Issue
Block a user