Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dce45cca authored by Naomi Musgrave's avatar Naomi Musgrave Committed by Android (Google) Code Review
Browse files

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

parents 10b36622 065f4d87
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -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);
    }

    /**
+2 −2
Original line number Diff line number Diff line
@@ -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) {
+9 −1
Original line number Diff line number Diff line
@@ -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;
    }

    /**
+24 −23
Original line number Diff line number Diff line
@@ -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);
    }

    /**
+2 −1
Original line number Diff line number Diff line
@@ -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());