Merge "Revert "MediaProjection captures DisplayArea"" into sc-v2-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
93a74ca03b
@@ -21,7 +21,6 @@ import android.annotation.Nullable;
|
|||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.hardware.SensorManager;
|
import android.hardware.SensorManager;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.util.IntArray;
|
import android.util.IntArray;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
@@ -340,28 +339,6 @@ public abstract class DisplayManagerInternal {
|
|||||||
*/
|
*/
|
||||||
public abstract List<RefreshRateLimitation> getRefreshRateLimitations(int displayId);
|
public abstract List<RefreshRateLimitation> getRefreshRateLimitations(int displayId);
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the window token of the level of the WindowManager hierarchy to mirror. Returns null
|
|
||||||
* if layer mirroring by SurfaceFlinger should not be performed for the given displayId.
|
|
||||||
* For now, only used for mirroring started from MediaProjection.
|
|
||||||
*/
|
|
||||||
public abstract IBinder getWindowTokenClientToMirror(int displayId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For the given displayId, updates the window token of the level of the WindowManager hierarchy
|
|
||||||
* to mirror. If windowToken is null, then SurfaceFlinger performs no layer mirroring to the
|
|
||||||
* given display.
|
|
||||||
* For now, only used for mirroring started from MediaProjection.
|
|
||||||
*/
|
|
||||||
public abstract void setWindowTokenClientToMirror(int displayId, IBinder windowToken);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the default size of the surface associated with the display, or null if the surface
|
|
||||||
* is not provided for layer mirroring by SurfaceFlinger.
|
|
||||||
* For now, only used for mirroring started from MediaProjection.
|
|
||||||
*/
|
|
||||||
public abstract Point getDisplaySurfaceDefaultSize(int displayId);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes the requested power state of the display.
|
* Describes the requested power state of the display.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import android.annotation.NonNull;
|
|||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.media.projection.MediaProjection;
|
import android.media.projection.MediaProjection;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
@@ -92,16 +91,9 @@ public final class VirtualDisplayConfig implements Parcelable {
|
|||||||
*/
|
*/
|
||||||
private int mDisplayIdToMirror = DEFAULT_DISPLAY;
|
private int mDisplayIdToMirror = DEFAULT_DISPLAY;
|
||||||
|
|
||||||
/**
|
|
||||||
* The window token of the level of the WindowManager hierarchy to mirror, or null if mirroring
|
|
||||||
* should not be performed.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
private IBinder mWindowTokenClientToMirror = null;
|
|
||||||
|
|
||||||
|
|
||||||
|
// Code below generated by codegen v1.0.20.
|
||||||
// Code below generated by codegen v1.0.23.
|
|
||||||
//
|
//
|
||||||
// DO NOT MODIFY!
|
// DO NOT MODIFY!
|
||||||
// CHECKSTYLE:OFF Generated code
|
// CHECKSTYLE:OFF Generated code
|
||||||
@@ -123,8 +115,7 @@ public final class VirtualDisplayConfig implements Parcelable {
|
|||||||
int flags,
|
int flags,
|
||||||
@Nullable Surface surface,
|
@Nullable Surface surface,
|
||||||
@Nullable String uniqueId,
|
@Nullable String uniqueId,
|
||||||
int displayIdToMirror,
|
int displayIdToMirror) {
|
||||||
@Nullable IBinder windowTokenClientToMirror) {
|
|
||||||
this.mName = name;
|
this.mName = name;
|
||||||
com.android.internal.util.AnnotationValidations.validate(
|
com.android.internal.util.AnnotationValidations.validate(
|
||||||
NonNull.class, null, mName);
|
NonNull.class, null, mName);
|
||||||
@@ -144,7 +135,6 @@ public final class VirtualDisplayConfig implements Parcelable {
|
|||||||
this.mSurface = surface;
|
this.mSurface = surface;
|
||||||
this.mUniqueId = uniqueId;
|
this.mUniqueId = uniqueId;
|
||||||
this.mDisplayIdToMirror = displayIdToMirror;
|
this.mDisplayIdToMirror = displayIdToMirror;
|
||||||
this.mWindowTokenClientToMirror = windowTokenClientToMirror;
|
|
||||||
|
|
||||||
// onConstructed(); // You can define this method to get a callback
|
// onConstructed(); // You can define this method to get a callback
|
||||||
}
|
}
|
||||||
@@ -222,15 +212,6 @@ public final class VirtualDisplayConfig implements Parcelable {
|
|||||||
return mDisplayIdToMirror;
|
return mDisplayIdToMirror;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The window token of the level of the WindowManager hierarchy to mirror, or null if mirroring
|
|
||||||
* should not be performed.
|
|
||||||
*/
|
|
||||||
@DataClass.Generated.Member
|
|
||||||
public @Nullable IBinder getWindowTokenClientToMirror() {
|
|
||||||
return mWindowTokenClientToMirror;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@DataClass.Generated.Member
|
@DataClass.Generated.Member
|
||||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||||
@@ -240,7 +221,6 @@ public final class VirtualDisplayConfig implements Parcelable {
|
|||||||
int flg = 0;
|
int flg = 0;
|
||||||
if (mSurface != null) flg |= 0x20;
|
if (mSurface != null) flg |= 0x20;
|
||||||
if (mUniqueId != null) flg |= 0x40;
|
if (mUniqueId != null) flg |= 0x40;
|
||||||
if (mWindowTokenClientToMirror != null) flg |= 0x100;
|
|
||||||
dest.writeInt(flg);
|
dest.writeInt(flg);
|
||||||
dest.writeString(mName);
|
dest.writeString(mName);
|
||||||
dest.writeInt(mWidth);
|
dest.writeInt(mWidth);
|
||||||
@@ -250,7 +230,6 @@ public final class VirtualDisplayConfig implements Parcelable {
|
|||||||
if (mSurface != null) dest.writeTypedObject(mSurface, flags);
|
if (mSurface != null) dest.writeTypedObject(mSurface, flags);
|
||||||
if (mUniqueId != null) dest.writeString(mUniqueId);
|
if (mUniqueId != null) dest.writeString(mUniqueId);
|
||||||
dest.writeInt(mDisplayIdToMirror);
|
dest.writeInt(mDisplayIdToMirror);
|
||||||
if (mWindowTokenClientToMirror != null) dest.writeStrongBinder(mWindowTokenClientToMirror);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -273,7 +252,6 @@ public final class VirtualDisplayConfig implements Parcelable {
|
|||||||
Surface surface = (flg & 0x20) == 0 ? null : (Surface) in.readTypedObject(Surface.CREATOR);
|
Surface surface = (flg & 0x20) == 0 ? null : (Surface) in.readTypedObject(Surface.CREATOR);
|
||||||
String uniqueId = (flg & 0x40) == 0 ? null : in.readString();
|
String uniqueId = (flg & 0x40) == 0 ? null : in.readString();
|
||||||
int displayIdToMirror = in.readInt();
|
int displayIdToMirror = in.readInt();
|
||||||
IBinder windowTokenClientToMirror = (flg & 0x100) == 0 ? null : (IBinder) in.readStrongBinder();
|
|
||||||
|
|
||||||
this.mName = name;
|
this.mName = name;
|
||||||
com.android.internal.util.AnnotationValidations.validate(
|
com.android.internal.util.AnnotationValidations.validate(
|
||||||
@@ -294,7 +272,6 @@ public final class VirtualDisplayConfig implements Parcelable {
|
|||||||
this.mSurface = surface;
|
this.mSurface = surface;
|
||||||
this.mUniqueId = uniqueId;
|
this.mUniqueId = uniqueId;
|
||||||
this.mDisplayIdToMirror = displayIdToMirror;
|
this.mDisplayIdToMirror = displayIdToMirror;
|
||||||
this.mWindowTokenClientToMirror = windowTokenClientToMirror;
|
|
||||||
|
|
||||||
// onConstructed(); // You can define this method to get a callback
|
// onConstructed(); // You can define this method to get a callback
|
||||||
}
|
}
|
||||||
@@ -328,7 +305,6 @@ public final class VirtualDisplayConfig implements Parcelable {
|
|||||||
private @Nullable Surface mSurface;
|
private @Nullable Surface mSurface;
|
||||||
private @Nullable String mUniqueId;
|
private @Nullable String mUniqueId;
|
||||||
private int mDisplayIdToMirror;
|
private int mDisplayIdToMirror;
|
||||||
private @Nullable IBinder mWindowTokenClientToMirror;
|
|
||||||
|
|
||||||
private long mBuilderFieldsSet = 0L;
|
private long mBuilderFieldsSet = 0L;
|
||||||
|
|
||||||
@@ -463,22 +439,10 @@ public final class VirtualDisplayConfig implements Parcelable {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The window token of the level of the WindowManager hierarchy to mirror, or null if mirroring
|
|
||||||
* should not be performed.
|
|
||||||
*/
|
|
||||||
@DataClass.Generated.Member
|
|
||||||
public @NonNull Builder setWindowTokenClientToMirror(@NonNull IBinder value) {
|
|
||||||
checkNotUsed();
|
|
||||||
mBuilderFieldsSet |= 0x100;
|
|
||||||
mWindowTokenClientToMirror = value;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Builds the instance. This builder should not be touched after calling this! */
|
/** Builds the instance. This builder should not be touched after calling this! */
|
||||||
public @NonNull VirtualDisplayConfig build() {
|
public @NonNull VirtualDisplayConfig build() {
|
||||||
checkNotUsed();
|
checkNotUsed();
|
||||||
mBuilderFieldsSet |= 0x200; // Mark builder used
|
mBuilderFieldsSet |= 0x100; // Mark builder used
|
||||||
|
|
||||||
if ((mBuilderFieldsSet & 0x10) == 0) {
|
if ((mBuilderFieldsSet & 0x10) == 0) {
|
||||||
mFlags = 0;
|
mFlags = 0;
|
||||||
@@ -492,9 +456,6 @@ public final class VirtualDisplayConfig implements Parcelable {
|
|||||||
if ((mBuilderFieldsSet & 0x80) == 0) {
|
if ((mBuilderFieldsSet & 0x80) == 0) {
|
||||||
mDisplayIdToMirror = DEFAULT_DISPLAY;
|
mDisplayIdToMirror = DEFAULT_DISPLAY;
|
||||||
}
|
}
|
||||||
if ((mBuilderFieldsSet & 0x100) == 0) {
|
|
||||||
mWindowTokenClientToMirror = null;
|
|
||||||
}
|
|
||||||
VirtualDisplayConfig o = new VirtualDisplayConfig(
|
VirtualDisplayConfig o = new VirtualDisplayConfig(
|
||||||
mName,
|
mName,
|
||||||
mWidth,
|
mWidth,
|
||||||
@@ -503,13 +464,12 @@ public final class VirtualDisplayConfig implements Parcelable {
|
|||||||
mFlags,
|
mFlags,
|
||||||
mSurface,
|
mSurface,
|
||||||
mUniqueId,
|
mUniqueId,
|
||||||
mDisplayIdToMirror,
|
mDisplayIdToMirror);
|
||||||
mWindowTokenClientToMirror);
|
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkNotUsed() {
|
private void checkNotUsed() {
|
||||||
if ((mBuilderFieldsSet & 0x200) != 0) {
|
if ((mBuilderFieldsSet & 0x100) != 0) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"This Builder should not be reused. Use a new Builder instance instead");
|
"This Builder should not be reused. Use a new Builder instance instead");
|
||||||
}
|
}
|
||||||
@@ -517,10 +477,10 @@ public final class VirtualDisplayConfig implements Parcelable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@DataClass.Generated(
|
@DataClass.Generated(
|
||||||
time = 1620657851981L,
|
time = 1604456298440L,
|
||||||
codegenVersion = "1.0.23",
|
codegenVersion = "1.0.20",
|
||||||
sourceFile = "frameworks/base/core/java/android/hardware/display/VirtualDisplayConfig.java",
|
sourceFile = "frameworks/base/core/java/android/hardware/display/VirtualDisplayConfig.java",
|
||||||
inputSignatures = "private @android.annotation.NonNull java.lang.String mName\nprivate @android.annotation.IntRange int mWidth\nprivate @android.annotation.IntRange int mHeight\nprivate @android.annotation.IntRange int mDensityDpi\nprivate int mFlags\nprivate @android.annotation.Nullable android.view.Surface mSurface\nprivate @android.annotation.Nullable java.lang.String mUniqueId\nprivate int mDisplayIdToMirror\nprivate @android.annotation.Nullable android.os.IBinder mWindowTokenClientToMirror\nclass VirtualDisplayConfig extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genAidl=true, genBuilder=true)")
|
inputSignatures = "private @android.annotation.NonNull java.lang.String mName\nprivate @android.annotation.IntRange int mWidth\nprivate @android.annotation.IntRange int mHeight\nprivate @android.annotation.IntRange 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
|
@Deprecated
|
||||||
private void __metadata() {}
|
private void __metadata() {}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import android.graphics.Canvas;
|
|||||||
import android.graphics.ColorSpace;
|
import android.graphics.ColorSpace;
|
||||||
import android.graphics.HardwareRenderer;
|
import android.graphics.HardwareRenderer;
|
||||||
import android.graphics.Matrix;
|
import android.graphics.Matrix;
|
||||||
import android.graphics.Point;
|
|
||||||
import android.graphics.RecordingCanvas;
|
import android.graphics.RecordingCanvas;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.RenderNode;
|
import android.graphics.RenderNode;
|
||||||
@@ -408,20 +407,6 @@ public class Surface implements Parcelable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the default size of this Surface provided by the consumer of the surface.
|
|
||||||
* Should only be used by the producer of the surface.
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
public Point getDefaultSize() {
|
|
||||||
synchronized (mLock) {
|
|
||||||
checkNotReleasedLocked();
|
|
||||||
return new Point(nativeGetWidth(mNativeObject), nativeGetHeight(mNativeObject));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a {@link Canvas} for drawing into this surface.
|
* Gets a {@link Canvas} for drawing into this surface.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -16,14 +16,14 @@
|
|||||||
|
|
||||||
package android.media.projection;
|
package android.media.projection;
|
||||||
|
|
||||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
|
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.hardware.display.DisplayManager;
|
import android.hardware.display.DisplayManager;
|
||||||
import android.hardware.display.VirtualDisplay;
|
import android.hardware.display.VirtualDisplay;
|
||||||
import android.hardware.display.VirtualDisplayConfig;
|
import android.hardware.display.VirtualDisplayConfig;
|
||||||
|
import android.media.projection.IMediaProjection;
|
||||||
|
import android.media.projection.IMediaProjectionCallback;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
@@ -106,7 +106,7 @@ public final class MediaProjection {
|
|||||||
if (isSecure) {
|
if (isSecure) {
|
||||||
flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
|
flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
|
||||||
}
|
}
|
||||||
final VirtualDisplayConfig.Builder builder = buildMirroredVirtualDisplay(name, width,
|
final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(name, width,
|
||||||
height, dpi);
|
height, dpi);
|
||||||
builder.setFlags(flags);
|
builder.setFlags(flags);
|
||||||
if (surface != null) {
|
if (surface != null) {
|
||||||
@@ -141,7 +141,7 @@ public final class MediaProjection {
|
|||||||
public VirtualDisplay createVirtualDisplay(@NonNull String name,
|
public VirtualDisplay createVirtualDisplay(@NonNull String name,
|
||||||
int width, int height, int dpi, int flags, @Nullable Surface surface,
|
int width, int height, int dpi, int flags, @Nullable Surface surface,
|
||||||
@Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
|
@Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
|
||||||
final VirtualDisplayConfig.Builder builder = buildMirroredVirtualDisplay(name, width,
|
final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(name, width,
|
||||||
height, dpi);
|
height, dpi);
|
||||||
builder.setFlags(flags);
|
builder.setFlags(flags);
|
||||||
if (surface != null) {
|
if (surface != null) {
|
||||||
@@ -150,26 +150,6 @@ public final class MediaProjection {
|
|||||||
return createVirtualDisplay(builder.build(), callback, handler);
|
return createVirtualDisplay(builder.build(), callback, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a {@link VirtualDisplayConfig.Builder}, which will mirror the contents of a
|
|
||||||
* DisplayArea. The DisplayArea to mirror is from the DisplayArea the caller is launched on.
|
|
||||||
*
|
|
||||||
* @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 dpi The density of the virtual display in dpi. Must be greater than 0.
|
|
||||||
* @return a config representing a VirtualDisplay
|
|
||||||
*/
|
|
||||||
private VirtualDisplayConfig.Builder buildMirroredVirtualDisplay(@NonNull String name,
|
|
||||||
int width, int height, int dpi) {
|
|
||||||
Context windowContext = mContext.createWindowContext(mContext.getDisplayNoVerify(),
|
|
||||||
TYPE_APPLICATION, null /* options */);
|
|
||||||
final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(name, width,
|
|
||||||
height, dpi);
|
|
||||||
builder.setWindowTokenClientToMirror(windowContext.getWindowContextToken());
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@link android.hardware.display.VirtualDisplay} to capture the
|
* Creates a {@link android.hardware.display.VirtualDisplay} to capture the
|
||||||
* contents of the screen.
|
* contents of the screen.
|
||||||
|
|||||||
@@ -16,9 +16,7 @@
|
|||||||
|
|
||||||
package com.android.server.display;
|
package com.android.server.display;
|
||||||
|
|
||||||
import android.annotation.Nullable;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Point;
|
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.hardware.display.DisplayViewport;
|
import android.hardware.display.DisplayViewport;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
@@ -106,34 +104,6 @@ abstract class DisplayDevice {
|
|||||||
return Display.DEFAULT_DISPLAY;
|
return Display.DEFAULT_DISPLAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the window token of the level of the WindowManager hierarchy to mirror, or null
|
|
||||||
* if layer mirroring by SurfaceFlinger should not be performed.
|
|
||||||
* For now, only used for mirroring started from MediaProjection.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
public IBinder getWindowTokenClientToMirrorLocked() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the window token of the level of the level of the WindowManager hierarchy to mirror.
|
|
||||||
* If windowToken is null, then no layer mirroring by SurfaceFlinger to should be performed.
|
|
||||||
* For now, only used for mirroring started from MediaProjection.
|
|
||||||
*/
|
|
||||||
public void setWindowTokenClientToMirrorLocked(IBinder windowToken) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the default size of the surface associated with the display, or null if the surface
|
|
||||||
* is not provided for layer mirroring by SurfaceFlinger.
|
|
||||||
* For now, only used for mirroring started from MediaProjection.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
public Point getDisplaySurfaceDefaultSize() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the name of the display device.
|
* Gets the name of the display device.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ import android.hardware.display.DisplayManagerGlobal;
|
|||||||
import android.hardware.display.DisplayManagerInternal;
|
import android.hardware.display.DisplayManagerInternal;
|
||||||
import android.hardware.display.DisplayManagerInternal.DisplayGroupListener;
|
import android.hardware.display.DisplayManagerInternal.DisplayGroupListener;
|
||||||
import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener;
|
import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener;
|
||||||
|
import android.hardware.display.DisplayManagerInternal.RefreshRateLimitation;
|
||||||
|
import android.hardware.display.DisplayManagerInternal.RefreshRateRange;
|
||||||
import android.hardware.display.DisplayViewport;
|
import android.hardware.display.DisplayViewport;
|
||||||
import android.hardware.display.DisplayedContentSample;
|
import android.hardware.display.DisplayedContentSample;
|
||||||
import android.hardware.display.DisplayedContentSamplingAttributes;
|
import android.hardware.display.DisplayedContentSamplingAttributes;
|
||||||
@@ -1747,13 +1749,10 @@ public final class DisplayManagerService extends SystemService {
|
|||||||
final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
|
final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
|
||||||
final boolean ownContent = (info.flags & DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY) != 0;
|
final boolean ownContent = (info.flags & DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY) != 0;
|
||||||
|
|
||||||
// Mirror the part of WM hierarchy that corresponds to the provided window token.
|
|
||||||
IBinder windowTokenClientToMirror = device.getWindowTokenClientToMirrorLocked();
|
|
||||||
|
|
||||||
// Find the logical display that the display device is showing.
|
// Find the logical display that the display device is showing.
|
||||||
// Certain displays only ever show their own content.
|
// Certain displays only ever show their own content.
|
||||||
LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device);
|
LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device);
|
||||||
if (!ownContent && windowTokenClientToMirror == null) {
|
if (!ownContent) {
|
||||||
if (display != null && !display.hasContentLocked()) {
|
if (display != null && !display.hasContentLocked()) {
|
||||||
// If the display does not have any content of its own, then
|
// If the display does not have any content of its own, then
|
||||||
// automatically mirror the requested logical display contents if possible.
|
// automatically mirror the requested logical display contents if possible.
|
||||||
@@ -3315,40 +3314,6 @@ public final class DisplayManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
return config.getRefreshRateLimitations();
|
return config.getRefreshRateLimitations();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public IBinder getWindowTokenClientToMirror(int displayId) {
|
|
||||||
final DisplayDevice device;
|
|
||||||
synchronized (mSyncRoot) {
|
|
||||||
device = getDeviceForDisplayLocked(displayId);
|
|
||||||
if (device == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return device.getWindowTokenClientToMirrorLocked();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setWindowTokenClientToMirror(int displayId, IBinder windowToken) {
|
|
||||||
synchronized (mSyncRoot) {
|
|
||||||
final DisplayDevice device = getDeviceForDisplayLocked(displayId);
|
|
||||||
if (device != null) {
|
|
||||||
device.setWindowTokenClientToMirrorLocked(windowToken);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Point getDisplaySurfaceDefaultSize(int displayId) {
|
|
||||||
final DisplayDevice device;
|
|
||||||
synchronized (mSyncRoot) {
|
|
||||||
device = getDeviceForDisplayLocked(displayId);
|
|
||||||
if (device == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return device.getDisplaySurfaceDefaultSize();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class DesiredDisplayModeSpecsObserver
|
class DesiredDisplayModeSpecsObserver
|
||||||
|
|||||||
@@ -31,9 +31,7 @@ import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUST
|
|||||||
import static com.android.server.display.DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP;
|
import static com.android.server.display.DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP;
|
||||||
import static com.android.server.display.DisplayDeviceInfo.FLAG_TRUSTED;
|
import static com.android.server.display.DisplayDeviceInfo.FLAG_TRUSTED;
|
||||||
|
|
||||||
import android.annotation.Nullable;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Point;
|
|
||||||
import android.hardware.display.IVirtualDisplayCallback;
|
import android.hardware.display.IVirtualDisplayCallback;
|
||||||
import android.hardware.display.VirtualDisplayConfig;
|
import android.hardware.display.VirtualDisplayConfig;
|
||||||
import android.media.projection.IMediaProjection;
|
import android.media.projection.IMediaProjection;
|
||||||
@@ -233,7 +231,6 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
|
|||||||
private Display.Mode mMode;
|
private Display.Mode mMode;
|
||||||
private boolean mIsDisplayOn;
|
private boolean mIsDisplayOn;
|
||||||
private int mDisplayIdToMirror;
|
private int mDisplayIdToMirror;
|
||||||
private IBinder mWindowTokenClientToMirror;
|
|
||||||
|
|
||||||
public VirtualDisplayDevice(IBinder displayToken, IBinder appToken,
|
public VirtualDisplayDevice(IBinder displayToken, IBinder appToken,
|
||||||
int ownerUid, String ownerPackageName, Surface surface, int flags,
|
int ownerUid, String ownerPackageName, Surface surface, int flags,
|
||||||
@@ -256,7 +253,6 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
|
|||||||
mUniqueIndex = uniqueIndex;
|
mUniqueIndex = uniqueIndex;
|
||||||
mIsDisplayOn = surface != null;
|
mIsDisplayOn = surface != null;
|
||||||
mDisplayIdToMirror = virtualDisplayConfig.getDisplayIdToMirror();
|
mDisplayIdToMirror = virtualDisplayConfig.getDisplayIdToMirror();
|
||||||
mWindowTokenClientToMirror = virtualDisplayConfig.getWindowTokenClientToMirror();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -286,26 +282,6 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
|
|||||||
return mDisplayIdToMirror;
|
return mDisplayIdToMirror;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public IBinder getWindowTokenClientToMirrorLocked() {
|
|
||||||
return mWindowTokenClientToMirror;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setWindowTokenClientToMirrorLocked(IBinder windowToken) {
|
|
||||||
if (mWindowTokenClientToMirror != windowToken) {
|
|
||||||
mWindowTokenClientToMirror = windowToken;
|
|
||||||
sendDisplayDeviceEventLocked(this, DISPLAY_DEVICE_EVENT_CHANGED);
|
|
||||||
sendTraversalRequestLocked();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Point getDisplaySurfaceDefaultSize() {
|
|
||||||
return mSurface.getDefaultSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
Surface getSurfaceLocked() {
|
Surface getSurfaceLocked() {
|
||||||
return mSurface;
|
return mSurface;
|
||||||
@@ -386,7 +362,6 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
|
|||||||
pw.println("mDisplayState=" + Display.stateToString(mDisplayState));
|
pw.println("mDisplayState=" + Display.stateToString(mDisplayState));
|
||||||
pw.println("mStopped=" + mStopped);
|
pw.println("mStopped=" + mStopped);
|
||||||
pw.println("mDisplayIdToMirror=" + mDisplayIdToMirror);
|
pw.println("mDisplayIdToMirror=" + mDisplayIdToMirror);
|
||||||
pw.println("mWindowTokenClientToMirror=" + mWindowTokenClientToMirror);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -298,22 +298,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
|||||||
*/
|
*/
|
||||||
private final SurfaceControl mWindowingLayer;
|
private final SurfaceControl mWindowingLayer;
|
||||||
|
|
||||||
/**
|
|
||||||
* The window token of the layer of the hierarchy to mirror, or null if this DisplayContent
|
|
||||||
* is not being used for layer mirroring.
|
|
||||||
*/
|
|
||||||
@VisibleForTesting IBinder mTokenToMirror = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The surface for mirroring the contents of this hierarchy.
|
|
||||||
*/
|
|
||||||
private SurfaceControl mMirroredSurface = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The last bounds of the DisplayArea to mirror.
|
|
||||||
*/
|
|
||||||
private Rect mLastMirroredDisplayAreaBounds = null;
|
|
||||||
|
|
||||||
// Contains all IME window containers. Note that the z-ordering of the IME windows will depend
|
// Contains all IME window containers. Note that the z-ordering of the IME windows will depend
|
||||||
// on the IME target. We mainly have this container grouping so we can keep track of all the IME
|
// on the IME target. We mainly have this container grouping so we can keep track of all the IME
|
||||||
// window containers together and move them in-sync if/when needed. We use a subclass of
|
// window containers together and move them in-sync if/when needed. We use a subclass of
|
||||||
@@ -1133,10 +1117,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
|||||||
if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Creating display=" + display);
|
if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Creating display=" + display);
|
||||||
|
|
||||||
mWmService.mDisplayWindowSettings.applySettingsToDisplayLocked(this);
|
mWmService.mDisplayWindowSettings.applySettingsToDisplayLocked(this);
|
||||||
|
|
||||||
// Check if this DisplayContent is for a new VirtualDisplay, that should use layer mirroring
|
|
||||||
// to capture the contents of a DisplayArea.
|
|
||||||
startMirrorIfNeeded();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isReady() {
|
boolean isReady() {
|
||||||
@@ -2491,25 +2471,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
|||||||
// Update IME parent if needed.
|
// Update IME parent if needed.
|
||||||
updateImeParent();
|
updateImeParent();
|
||||||
|
|
||||||
// Update mirroring surface for MediaProjection, if this DisplayContent is being used
|
|
||||||
// for layer mirroring.
|
|
||||||
if (mMirroredSurface != null) {
|
|
||||||
// Retrieve the size of the DisplayArea to mirror, and continue with the update if the
|
|
||||||
// bounds have changed.
|
|
||||||
final WindowContainer wc = mWmService.mWindowContextListenerController.getContainer(
|
|
||||||
mTokenToMirror);
|
|
||||||
if (wc != null && mLastMirroredDisplayAreaBounds != null) {
|
|
||||||
// Retrieve the size of the DisplayArea to mirror, and continue with the update
|
|
||||||
// if the bounds or orientation has changed.
|
|
||||||
final Rect displayAreaBounds = wc.getDisplayContent().getBounds();
|
|
||||||
int displayAreaOrientation = wc.getDisplayContent().getOrientation();
|
|
||||||
if (!mLastMirroredDisplayAreaBounds.equals(displayAreaBounds)
|
|
||||||
|| lastOrientation != displayAreaOrientation) {
|
|
||||||
updateMirroredSurface(mWmService.mTransactionFactory.get(), displayAreaBounds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lastOrientation != getConfiguration().orientation) {
|
if (lastOrientation != getConfiguration().orientation) {
|
||||||
getMetricsLogger().write(
|
getMetricsLogger().write(
|
||||||
new LogMaker(MetricsEvent.ACTION_PHONE_ORIENTATION_CHANGED)
|
new LogMaker(MetricsEvent.ACTION_PHONE_ORIENTATION_CHANGED)
|
||||||
@@ -4368,7 +4329,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
|||||||
mTmpApplySurfaceChangesTransactionState.preferMinimalPostProcessing,
|
mTmpApplySurfaceChangesTransactionState.preferMinimalPostProcessing,
|
||||||
true /* inTraversal, must call performTraversalInTrans... below */);
|
true /* inTraversal, must call performTraversalInTrans... below */);
|
||||||
}
|
}
|
||||||
updateMirroring();
|
|
||||||
|
|
||||||
final boolean wallpaperVisible = mWallpaperController.isWallpaperVisible();
|
final boolean wallpaperVisible = mWallpaperController.isWallpaperVisible();
|
||||||
if (wallpaperVisible != mLastWallpaperVisible) {
|
if (wallpaperVisible != mLastWallpaperVisible) {
|
||||||
@@ -5930,133 +5890,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
|||||||
return mSandboxDisplayApis;
|
return mSandboxDisplayApis;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Start mirroring to this DisplayContent if it does not have its own content. Captures the
|
|
||||||
* content of a WindowContainer indicated by a WindowToken. If unable to start mirroring, falls
|
|
||||||
* back to original MediaProjection approach.
|
|
||||||
*/
|
|
||||||
private void startMirrorIfNeeded() {
|
|
||||||
// Only mirror if this display does not have its own content.
|
|
||||||
if (mLastHasContent) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Given the WindowToken of the DisplayArea to mirror, retrieve the associated
|
|
||||||
// SurfaceControl.
|
|
||||||
IBinder tokenToMirror = mWmService.mDisplayManagerInternal.getWindowTokenClientToMirror(
|
|
||||||
mDisplayId);
|
|
||||||
|
|
||||||
if (tokenToMirror == null) {
|
|
||||||
// This DisplayContent instance is not involved in layer mirroring. If the display
|
|
||||||
// has been created for capturing, fall back to prior MediaProjection approach.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final WindowContainer wc = mWmService.mWindowContextListenerController.getContainer(
|
|
||||||
tokenToMirror);
|
|
||||||
if (wc == null) {
|
|
||||||
// Un-set the window token to mirror for this VirtualDisplay, to fall back to the
|
|
||||||
// original MediaProjection approach.
|
|
||||||
mWmService.mDisplayManagerInternal.setWindowTokenClientToMirror(mDisplayId, null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
SurfaceControl sc = wc.getDisplayContent().getSurfaceControl();
|
|
||||||
|
|
||||||
// Create a mirrored hierarchy for the SurfaceControl of the DisplayArea to capture.
|
|
||||||
mMirroredSurface = SurfaceControl.mirrorSurface(sc);
|
|
||||||
SurfaceControl.Transaction transaction = mWmService.mTransactionFactory.get()
|
|
||||||
// Set the mMirroredSurface's parent to the root SurfaceControl for this
|
|
||||||
// DisplayContent. This brings the new mirrored hierarchy under this DisplayContent,
|
|
||||||
// so SurfaceControl will write the layers of this hierarchy to the output surface
|
|
||||||
// provided by the app.
|
|
||||||
.reparent(mMirroredSurface, mSurfaceControl)
|
|
||||||
// Reparent the SurfaceControl of this DisplayContent to null, to prevent content
|
|
||||||
// being added to it. This ensures that no app launched explicitly on the
|
|
||||||
// VirtualDisplay will show up as part of the mirrored content.
|
|
||||||
.reparent(mWindowingLayer, null);
|
|
||||||
// Retrieve the size of the DisplayArea to mirror.
|
|
||||||
updateMirroredSurface(transaction, wc.getDisplayContent().getBounds());
|
|
||||||
mTokenToMirror = tokenToMirror;
|
|
||||||
|
|
||||||
// No need to clean up. In SurfaceFlinger, parents hold references to their children. The
|
|
||||||
// mirrored SurfaceControl is alive since the parent DisplayContent SurfaceControl is
|
|
||||||
// holding a reference to it. Therefore, the mirrored SurfaceControl will be cleaned up
|
|
||||||
// when the VirtualDisplay is destroyed - which will clean up this DisplayContent.
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start or stop mirroring if this DisplayContent now has content, or no longer has content.
|
|
||||||
*/
|
|
||||||
private void updateMirroring() {
|
|
||||||
if (mLastHasContent && mMirroredSurface != null) {
|
|
||||||
// Display now has content, so stop mirroring to it.
|
|
||||||
mWmService.mTransactionFactory.get()
|
|
||||||
// Remove the reference to mMirroredSurface, to clean up associated memory.
|
|
||||||
.remove(mMirroredSurface)
|
|
||||||
// Reparent the SurfaceControl of this DisplayContent back to mSurfaceControl,
|
|
||||||
// to allow content to be added to it. This allows this DisplayContent to stop
|
|
||||||
// mirroring and show content normally.
|
|
||||||
.reparent(mWindowingLayer, mSurfaceControl).apply();
|
|
||||||
// Stop mirroring by destroying the reference to the mirrored layer.
|
|
||||||
mMirroredSurface = null;
|
|
||||||
// Do not un-set the token, in case content is removed and mirroring should begin again.
|
|
||||||
} else if (!mLastHasContent && mMirroredSurface == null) {
|
|
||||||
// Display no longer has content, so start mirroring to it.
|
|
||||||
startMirrorIfNeeded();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Apply transformations to the mirrored surface to ensure the captured contents are scaled to
|
|
||||||
* fit and centred in the output surface.
|
|
||||||
*
|
|
||||||
* @param transaction the transaction to include transformations of mMirroredSurface
|
|
||||||
* to. Transaction is not applied before returning.
|
|
||||||
* @param displayAreaBounds bounds of the DisplayArea to mirror to the surface provided by
|
|
||||||
* the app.
|
|
||||||
*/
|
|
||||||
@VisibleForTesting
|
|
||||||
void updateMirroredSurface(SurfaceControl.Transaction transaction,
|
|
||||||
Rect displayAreaBounds) {
|
|
||||||
// Retrieve the default size of the surface the app provided to
|
|
||||||
// MediaProjection#createVirtualDisplay. Note the app is the consumer of the surface,
|
|
||||||
// since it reads out buffers from the surface, and SurfaceFlinger is the producer since
|
|
||||||
// it writes the mirrored layers to the buffers.
|
|
||||||
final Point surfaceSize = mWmService.mDisplayManagerInternal.getDisplaySurfaceDefaultSize(
|
|
||||||
mDisplayId);
|
|
||||||
|
|
||||||
// Calculate the scale to apply to the root mirror SurfaceControl to fit the size of the
|
|
||||||
// output surface.
|
|
||||||
float scaleX = surfaceSize.x / (float) displayAreaBounds.width();
|
|
||||||
float scaleY = surfaceSize.y / (float) displayAreaBounds.height();
|
|
||||||
float scale = Math.min(scaleX, scaleY);
|
|
||||||
int scaledWidth = Math.round(scale * (float) displayAreaBounds.width());
|
|
||||||
int scaledHeight = Math.round(scale * (float) displayAreaBounds.height());
|
|
||||||
|
|
||||||
// Calculate the shift to apply to the root mirror SurfaceControl to centre the mirrored
|
|
||||||
// contents in the output surface.
|
|
||||||
int shiftedX = 0;
|
|
||||||
if (scaledWidth != surfaceSize.x) {
|
|
||||||
shiftedX = (surfaceSize.x - scaledWidth) / 2;
|
|
||||||
}
|
|
||||||
int shiftedY = 0;
|
|
||||||
if (scaledHeight != surfaceSize.y) {
|
|
||||||
shiftedY = (surfaceSize.y - scaledHeight) / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
transaction
|
|
||||||
// Crop the area to capture to exclude the 'extra' wallpaper that is used
|
|
||||||
// for parallax (b/189930234).
|
|
||||||
.setWindowCrop(mMirroredSurface, displayAreaBounds.width(),
|
|
||||||
displayAreaBounds.height())
|
|
||||||
// Scale the root mirror SurfaceControl, based upon the size difference between the
|
|
||||||
// source (DisplayArea to capture) and output (surface the app reads images from).
|
|
||||||
.setMatrix(mMirroredSurface, scale, 0 /* dtdx */, 0 /* dtdy */, scale)
|
|
||||||
// Position needs to be updated when the mirrored DisplayArea has changed, since
|
|
||||||
// the content will no longer be centered in the output surface.
|
|
||||||
.setPosition(mMirroredSurface, shiftedX /* x */, shiftedY /* y */)
|
|
||||||
.apply();
|
|
||||||
mLastMirroredDisplayAreaBounds = new Rect(displayAreaBounds);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The entry for proceeding to handle {@link #mFixedRotationLaunchingApp}. */
|
/** The entry for proceeding to handle {@link #mFixedRotationLaunchingApp}. */
|
||||||
class FixedRotationTransitionListener extends WindowManagerInternal.AppTransitionListener {
|
class FixedRotationTransitionListener extends WindowManagerInternal.AppTransitionListener {
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,6 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
|
|||||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
|
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
|
||||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
|
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
|
||||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
|
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
|
||||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
|
|
||||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
|
import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
|
||||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset;
|
import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset;
|
||||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.same;
|
import static com.android.dx.mockito.inline.extended.ExtendedMockito.same;
|
||||||
@@ -108,12 +107,9 @@ import android.app.WindowConfiguration;
|
|||||||
import android.app.servertransaction.FixedRotationAdjustmentsItem;
|
import android.app.servertransaction.FixedRotationAdjustmentsItem;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Insets;
|
import android.graphics.Insets;
|
||||||
import android.graphics.Point;
|
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.Region;
|
import android.graphics.Region;
|
||||||
import android.metrics.LogMaker;
|
import android.metrics.LogMaker;
|
||||||
import android.os.Binder;
|
|
||||||
import android.os.IBinder;
|
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.platform.test.annotations.Presubmit;
|
import android.platform.test.annotations.Presubmit;
|
||||||
@@ -146,8 +142,6 @@ import org.junit.Test;
|
|||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.MockitoSession;
|
|
||||||
import org.mockito.quality.Strictness;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -2226,113 +2220,6 @@ public class DisplayContentTests extends WindowTestsBase {
|
|||||||
assertNotEquals(imeMenuDialog, mDisplayContent.findFocusedWindow());
|
assertNotEquals(imeMenuDialog, mDisplayContent.findFocusedWindow());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testVirtualDisplayContent() {
|
|
||||||
MockitoSession mockSession = mockitoSession()
|
|
||||||
.initMocks(this)
|
|
||||||
.spyStatic(SurfaceControl.class)
|
|
||||||
.strictness(Strictness.LENIENT)
|
|
||||||
.startMocking();
|
|
||||||
|
|
||||||
// GIVEN MediaProjection has already initialized the WindowToken of the DisplayArea to
|
|
||||||
// mirror.
|
|
||||||
final IBinder tokenToMirror = setUpDefaultTaskDisplayAreaWindowToken();
|
|
||||||
|
|
||||||
// GIVEN SurfaceControl can successfully mirror the provided surface.
|
|
||||||
Point surfaceSize = new Point(
|
|
||||||
mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().width(),
|
|
||||||
mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().height());
|
|
||||||
surfaceControlMirrors(surfaceSize);
|
|
||||||
|
|
||||||
// WHEN creating the DisplayContent for a new virtual display.
|
|
||||||
final DisplayContent virtualDisplay = new TestDisplayContent.Builder(mAtm,
|
|
||||||
mDisplayInfo).build();
|
|
||||||
|
|
||||||
// THEN mirroring is initiated for the default display's DisplayArea.
|
|
||||||
assertThat(virtualDisplay.mTokenToMirror).isEqualTo(tokenToMirror);
|
|
||||||
|
|
||||||
mockSession.finishMocking();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testVirtualDisplayContent_capturedAreaResized() {
|
|
||||||
MockitoSession mockSession = mockitoSession()
|
|
||||||
.initMocks(this)
|
|
||||||
.spyStatic(SurfaceControl.class)
|
|
||||||
.strictness(Strictness.LENIENT)
|
|
||||||
.startMocking();
|
|
||||||
|
|
||||||
// GIVEN MediaProjection has already initialized the WindowToken of the DisplayArea to
|
|
||||||
// mirror.
|
|
||||||
final IBinder tokenToMirror = setUpDefaultTaskDisplayAreaWindowToken();
|
|
||||||
|
|
||||||
// GIVEN SurfaceControl can successfully mirror the provided surface.
|
|
||||||
Point surfaceSize = new Point(
|
|
||||||
mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().width(),
|
|
||||||
mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().height());
|
|
||||||
SurfaceControl mirroredSurface = surfaceControlMirrors(surfaceSize);
|
|
||||||
|
|
||||||
// WHEN creating the DisplayContent for a new virtual display.
|
|
||||||
final DisplayContent virtualDisplay = new TestDisplayContent.Builder(mAtm,
|
|
||||||
mDisplayInfo).build();
|
|
||||||
|
|
||||||
// THEN mirroring is initiated for the default display's DisplayArea.
|
|
||||||
assertThat(virtualDisplay.mTokenToMirror).isEqualTo(tokenToMirror);
|
|
||||||
|
|
||||||
float xScale = 0.7f;
|
|
||||||
float yScale = 2f;
|
|
||||||
Rect displayAreaBounds = new Rect(0, 0, Math.round(surfaceSize.x * xScale),
|
|
||||||
Math.round(surfaceSize.y * yScale));
|
|
||||||
virtualDisplay.updateMirroredSurface(mTransaction, displayAreaBounds);
|
|
||||||
|
|
||||||
// THEN content in the captured DisplayArea is scaled to fit the surface size.
|
|
||||||
verify(mTransaction, atLeastOnce()).setMatrix(mirroredSurface, 1.0f / yScale, 0, 0,
|
|
||||||
1.0f / yScale);
|
|
||||||
// THEN captured content is positioned in the centre of the output surface.
|
|
||||||
float scaledWidth = displayAreaBounds.width() / xScale;
|
|
||||||
float xInset = (surfaceSize.x - scaledWidth) / 2;
|
|
||||||
verify(mTransaction, atLeastOnce()).setPosition(mirroredSurface, xInset, 0);
|
|
||||||
|
|
||||||
mockSession.finishMocking();
|
|
||||||
}
|
|
||||||
|
|
||||||
private class TestToken extends Binder {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a WindowToken associated with the default task DisplayArea, in order for that
|
|
||||||
* DisplayArea to be mirrored.
|
|
||||||
*/
|
|
||||||
private IBinder setUpDefaultTaskDisplayAreaWindowToken() {
|
|
||||||
// GIVEN MediaProjection has already initialized the WindowToken of the DisplayArea to
|
|
||||||
// mirror.
|
|
||||||
final IBinder tokenToMirror = new TestToken();
|
|
||||||
doReturn(tokenToMirror).when(mWm.mDisplayManagerInternal).getWindowTokenClientToMirror(
|
|
||||||
anyInt());
|
|
||||||
|
|
||||||
// GIVEN the default task display area is represented by the WindowToken.
|
|
||||||
spyOn(mWm.mWindowContextListenerController);
|
|
||||||
doReturn(mDefaultDisplay.getDefaultTaskDisplayArea()).when(
|
|
||||||
mWm.mWindowContextListenerController).getContainer(any());
|
|
||||||
return tokenToMirror;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SurfaceControl successfully creates a mirrored surface of the given size.
|
|
||||||
*/
|
|
||||||
private SurfaceControl surfaceControlMirrors(Point surfaceSize) {
|
|
||||||
// Do not set the parent, since the mirrored surface is the root of a new surface hierarchy.
|
|
||||||
SurfaceControl mirroredSurface = new SurfaceControl.Builder()
|
|
||||||
.setName("mirroredSurface")
|
|
||||||
.setBufferSize(surfaceSize.x, surfaceSize.y)
|
|
||||||
.setCallsite("mirrorSurface")
|
|
||||||
.build();
|
|
||||||
doReturn(mirroredSurface).when(() -> SurfaceControl.mirrorSurface(any()));
|
|
||||||
doReturn(surfaceSize).when(mWm.mDisplayManagerInternal).getDisplaySurfaceDefaultSize(
|
|
||||||
anyInt());
|
|
||||||
return mirroredSurface;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void removeRootTaskTests(Runnable runnable) {
|
private void removeRootTaskTests(Runnable runnable) {
|
||||||
final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
|
final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
|
||||||
final Task rootTask1 = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
|
final Task rootTask1 = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
|
||||||
|
|||||||
Reference in New Issue
Block a user