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) { if (surface != null) {
builder.setSurface(surface); 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) // TODO : Remove this hidden API after remove all callers. (Refer to MultiDisplayService)
@@ -882,15 +883,17 @@ public final class DisplayManager {
if (surface != null) { if (surface != null) {
builder.setSurface(surface); builder.setSurface(surface);
} }
return createVirtualDisplay(projection, builder.build(), callback, handler); return createVirtualDisplay(projection, builder.build(), callback, handler,
null /* windowContext */);
} }
/** @hide */ /** @hide */
public VirtualDisplay createVirtualDisplay(@Nullable MediaProjection projection, public VirtualDisplay createVirtualDisplay(@Nullable MediaProjection projection,
@NonNull VirtualDisplayConfig virtualDisplayConfig, @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, 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, public VirtualDisplay createVirtualDisplay(@NonNull Context context, MediaProjection projection,
@NonNull VirtualDisplayConfig virtualDisplayConfig, VirtualDisplay.Callback callback, @NonNull VirtualDisplayConfig virtualDisplayConfig, VirtualDisplay.Callback callback,
Handler handler) { Handler handler, @Nullable Context windowContext) {
VirtualDisplayCallback callbackWrapper = new VirtualDisplayCallback(callback, handler); VirtualDisplayCallback callbackWrapper = new VirtualDisplayCallback(callback, handler);
IMediaProjection projectionToken = projection != null ? projection.getProjection() : null; IMediaProjection projectionToken = projection != null ? projection.getProjection() : null;
int displayId; int displayId;
@@ -609,7 +609,7 @@ public final class DisplayManagerGlobal {
return null; return null;
} }
return new VirtualDisplay(this, display, callbackWrapper, return new VirtualDisplay(this, display, callbackWrapper,
virtualDisplayConfig.getSurface()); virtualDisplayConfig.getSurface(), windowContext);
} }
public void setVirtualDisplaySurface(IVirtualDisplayCallback token, Surface surface) { public void setVirtualDisplaySurface(IVirtualDisplayCallback token, Surface surface) {

View File

@@ -15,6 +15,8 @@
*/ */
package android.hardware.display; package android.hardware.display;
import android.annotation.Nullable;
import android.content.Context;
import android.view.Display; import android.view.Display;
import android.view.Surface; import android.view.Surface;
@@ -36,13 +38,19 @@ public final class VirtualDisplay {
private final Display mDisplay; private final Display mDisplay;
private IVirtualDisplayCallback mToken; private IVirtualDisplayCallback mToken;
private Surface mSurface; 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, VirtualDisplay(DisplayManagerGlobal global, Display display,
IVirtualDisplayCallback token, Surface surface) { IVirtualDisplayCallback token, Surface surface, Context windowContext) {
mGlobal = global; mGlobal = global;
mDisplay = display; mDisplay = display;
mToken = token; mToken = token;
mSurface = surface; mSurface = surface;
mWindowContext = windowContext;
} }
/** /**

View File

@@ -25,6 +25,7 @@ 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.os.Handler; import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException; import android.os.RemoteException;
import android.util.ArrayMap; import android.util.ArrayMap;
import android.util.Log; import android.util.Log;
@@ -50,13 +51,6 @@ public final class MediaProjection {
private final Context mContext; private final Context mContext;
private final Map<Callback, CallbackRecord> mCallbacks; 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 */ /** @hide */
public MediaProjection(Context context, IMediaProjection impl) { public MediaProjection(Context context, IMediaProjection impl) {
mCallbacks = new ArrayMap<Callback, CallbackRecord>(); mCallbacks = new ArrayMap<Callback, CallbackRecord>();
@@ -107,19 +101,22 @@ public final class MediaProjection {
public VirtualDisplay createVirtualDisplay(@NonNull String name, public VirtualDisplay createVirtualDisplay(@NonNull String name,
int width, int height, int dpi, boolean isSecure, @Nullable Surface surface, int width, int height, int dpi, boolean isSecure, @Nullable Surface surface,
@Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) { @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
DisplayManager dm = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR
| DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION; | DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION;
if (isSecure) { if (isSecure) {
flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE; flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
} }
Context windowContext = mContext.createWindowContext(mContext.getDisplayNoVerify(),
TYPE_APPLICATION, null /* options */);
final VirtualDisplayConfig.Builder builder = buildMirroredVirtualDisplay(name, width, final VirtualDisplayConfig.Builder builder = buildMirroredVirtualDisplay(name, width,
height, dpi); height, dpi, windowContext.getWindowContextToken());
builder.setFlags(flags); builder.setFlags(flags);
if (surface != null) { if (surface != null) {
builder.setSurface(surface); 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, 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) {
Context windowContext = mContext.createWindowContext(mContext.getDisplayNoVerify(),
TYPE_APPLICATION, null /* options */);
final VirtualDisplayConfig.Builder builder = buildMirroredVirtualDisplay(name, width, final VirtualDisplayConfig.Builder builder = buildMirroredVirtualDisplay(name, width,
height, dpi); height, dpi, windowContext.getWindowContextToken());
builder.setFlags(flags); builder.setFlags(flags);
if (surface != null) { if (surface != null) {
builder.setSurface(surface); 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 * @return a config representing a VirtualDisplay
*/ */
private VirtualDisplayConfig.Builder buildMirroredVirtualDisplay(@NonNull String name, private VirtualDisplayConfig.Builder buildMirroredVirtualDisplay(@NonNull String name,
int width, int height, int dpi) { int width, int height, int dpi, IBinder windowContextToken) {
mWindowContext = mContext.createWindowContext(mContext.getDisplayNoVerify(),
TYPE_APPLICATION, null /* options */);
final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(name, width, final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(name, width,
height, dpi); height, dpi);
builder.setWindowTokenClientToMirror(mWindowContext.getWindowContextToken()); builder.setWindowTokenClientToMirror(windowContextToken);
return builder; return builder;
} }
@@ -183,20 +182,22 @@ public final class MediaProjection {
* *
* @param virtualDisplayConfig The arguments for the virtual display configuration. See * @param virtualDisplayConfig The arguments for the virtual display configuration. See
* {@link VirtualDisplayConfig} for using it. * {@link VirtualDisplayConfig} for using it.
* @param callback Callback to call when the virtual display's state * @param callback Callback to call when the virtual display's state changes, or null if none.
* changes, or null if none. * @param handler The {@link android.os.Handler} on which the callback should be invoked, or
* @param handler The {@link android.os.Handler} on which the callback should be * null if the callback should be invoked on the calling thread's main
* invoked, or null if the callback should be invoked on the calling * {@link android.os.Looper}.
* thread's main {@link android.os.Looper}. * @param windowContext the WindowContext associated with the caller.
* *
* @see android.hardware.display.VirtualDisplay * @see android.hardware.display.VirtualDisplay
* @hide * @hide
*/ */
@Nullable @Nullable
public VirtualDisplay createVirtualDisplay(@NonNull VirtualDisplayConfig virtualDisplayConfig, 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); 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.setUniqueId(UNIQUE_DISPLAY_ID);
builder.setFlags(flags); builder.setFlags(flags);
mVirtualDisplay = mDisplayManager.createVirtualDisplay(null /* projection */, mVirtualDisplay = mDisplayManager.createVirtualDisplay(null /* projection */,
builder.build(), null /* callback */, null /* handler */); builder.build(), null /* callback */, null /* handler */,
null /* windowContext */);
if (mVirtualDisplay != null) { if (mVirtualDisplay != null) {
updateDisplayId(mVirtualDisplay.getDisplay().getDisplayId()); updateDisplayId(mVirtualDisplay.getDisplay().getDisplayId());