Merge "[MediaProjection] Store WindowContext in VirtualDisplay" into sc-v2-dev am: dce45ccae5

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15739903

Change-Id: Ie569e2e34788cb7f590520ad9e610c801887e47d
This commit is contained in:
Naomi Musgrave
2021-09-03 10:38:47 +00:00
committed by Automerger Merge Worker
5 changed files with 44 additions and 31 deletions

View File

@@ -864,7 +864,8 @@ public final class DisplayManager {
if (surface != null) {
builder.setSurface(surface);
}
return createVirtualDisplay(null /* projection */, builder.build(), callback, handler);
return createVirtualDisplay(null /* projection */, builder.build(), callback, handler,
null /* windowContext */);
}
// TODO : Remove this hidden API after remove all callers. (Refer to MultiDisplayService)
@@ -882,15 +883,17 @@ public final class DisplayManager {
if (surface != null) {
builder.setSurface(surface);
}
return createVirtualDisplay(projection, builder.build(), callback, handler);
return createVirtualDisplay(projection, builder.build(), callback, handler,
null /* windowContext */);
}
/** @hide */
public VirtualDisplay createVirtualDisplay(@Nullable MediaProjection projection,
@NonNull VirtualDisplayConfig virtualDisplayConfig,
@Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
@Nullable VirtualDisplay.Callback callback, @Nullable Handler handler,
@Nullable Context windowContext) {
return mGlobal.createVirtualDisplay(mContext, projection, virtualDisplayConfig, callback,
handler);
handler, windowContext);
}
/**

View File

@@ -583,7 +583,7 @@ public final class DisplayManagerGlobal {
public VirtualDisplay createVirtualDisplay(@NonNull Context context, MediaProjection projection,
@NonNull VirtualDisplayConfig virtualDisplayConfig, VirtualDisplay.Callback callback,
Handler handler) {
Handler handler, @Nullable Context windowContext) {
VirtualDisplayCallback callbackWrapper = new VirtualDisplayCallback(callback, handler);
IMediaProjection projectionToken = projection != null ? projection.getProjection() : null;
int displayId;
@@ -609,7 +609,7 @@ public final class DisplayManagerGlobal {
return null;
}
return new VirtualDisplay(this, display, callbackWrapper,
virtualDisplayConfig.getSurface());
virtualDisplayConfig.getSurface(), windowContext);
}
public void setVirtualDisplaySurface(IVirtualDisplayCallback token, Surface surface) {

View File

@@ -15,6 +15,8 @@
*/
package android.hardware.display;
import android.annotation.Nullable;
import android.content.Context;
import android.view.Display;
import android.view.Surface;
@@ -36,13 +38,19 @@ public final class VirtualDisplay {
private final Display mDisplay;
private IVirtualDisplayCallback mToken;
private Surface mSurface;
/**
* Store the WindowContext in a field. If it is a local variable, and it is garbage collected
* during a MediaProjection session, the WindowContainer listener no longer exists.
*/
@Nullable private final Context mWindowContext;
VirtualDisplay(DisplayManagerGlobal global, Display display,
IVirtualDisplayCallback token, Surface surface) {
IVirtualDisplayCallback token, Surface surface, Context windowContext) {
mGlobal = global;
mDisplay = display;
mToken = token;
mSurface = surface;
mWindowContext = windowContext;
}
/**

View File

@@ -25,6 +25,7 @@ import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.hardware.display.VirtualDisplayConfig;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.ArrayMap;
import android.util.Log;
@@ -50,13 +51,6 @@ public final class MediaProjection {
private final Context mContext;
private final Map<Callback, CallbackRecord> mCallbacks;
/**
* Store the WindowContext in a field. If it is a local variable, and it is garbage collected
* during a MediaProjection session, the WindowContainer listener no longer exists.
*/
@Nullable
private Context mWindowContext;
/** @hide */
public MediaProjection(Context context, IMediaProjection impl) {
mCallbacks = new ArrayMap<Callback, CallbackRecord>();
@@ -107,19 +101,22 @@ public final class MediaProjection {
public VirtualDisplay createVirtualDisplay(@NonNull String name,
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 = DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR
| DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION;
if (isSecure) {
flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
}
Context windowContext = mContext.createWindowContext(mContext.getDisplayNoVerify(),
TYPE_APPLICATION, null /* options */);
final VirtualDisplayConfig.Builder builder = buildMirroredVirtualDisplay(name, width,
height, dpi);
height, dpi, windowContext.getWindowContextToken());
builder.setFlags(flags);
if (surface != null) {
builder.setSurface(surface);
}
return dm.createVirtualDisplay(this, builder.build(), callback, handler);
VirtualDisplay virtualDisplay = createVirtualDisplay(builder.build(), callback, handler,
windowContext);
return virtualDisplay;
}
/**
@@ -148,13 +145,17 @@ 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) {
Context windowContext = mContext.createWindowContext(mContext.getDisplayNoVerify(),
TYPE_APPLICATION, null /* options */);
final VirtualDisplayConfig.Builder builder = buildMirroredVirtualDisplay(name, width,
height, dpi);
height, dpi, windowContext.getWindowContextToken());
builder.setFlags(flags);
if (surface != null) {
builder.setSurface(surface);
}
return createVirtualDisplay(builder.build(), callback, handler);
VirtualDisplay virtualDisplay = createVirtualDisplay(builder.build(), callback, handler,
windowContext);
return virtualDisplay;
}
/**
@@ -168,12 +169,10 @@ public final class MediaProjection {
* @return a config representing a VirtualDisplay
*/
private VirtualDisplayConfig.Builder buildMirroredVirtualDisplay(@NonNull String name,
int width, int height, int dpi) {
mWindowContext = mContext.createWindowContext(mContext.getDisplayNoVerify(),
TYPE_APPLICATION, null /* options */);
int width, int height, int dpi, IBinder windowContextToken) {
final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(name, width,
height, dpi);
builder.setWindowTokenClientToMirror(mWindowContext.getWindowContextToken());
builder.setWindowTokenClientToMirror(windowContextToken);
return builder;
}
@@ -183,20 +182,22 @@ public final class MediaProjection {
*
* @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}.
* @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}.
* @param windowContext the WindowContext associated with the caller.
*
* @see android.hardware.display.VirtualDisplay
* @hide
*/
@Nullable
public VirtualDisplay createVirtualDisplay(@NonNull VirtualDisplayConfig virtualDisplayConfig,
@Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
@Nullable VirtualDisplay.Callback callback, @Nullable Handler handler,
Context windowContext) {
DisplayManager dm = mContext.getSystemService(DisplayManager.class);
return dm.createVirtualDisplay(this, virtualDisplayConfig, callback, handler);
return dm.createVirtualDisplay(this, virtualDisplayConfig, callback, handler,
windowContext);
}
/**

View File

@@ -302,7 +302,8 @@ class Vr2dDisplay {
builder.setUniqueId(UNIQUE_DISPLAY_ID);
builder.setFlags(flags);
mVirtualDisplay = mDisplayManager.createVirtualDisplay(null /* projection */,
builder.build(), null /* callback */, null /* handler */);
builder.build(), null /* callback */, null /* handler */,
null /* windowContext */);
if (mVirtualDisplay != null) {
updateDisplayId(mVirtualDisplay.getDisplay().getDisplayId());