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

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

Merge "[Media Projection] Require valid token to set session" into tm-dev

parents 57836676 e3f6b7e1
Loading
Loading
Loading
Loading
+0 −12
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@ import android.graphics.Region;
import android.os.Bundle;
import android.os.IRemoteCallback;
import android.os.ParcelFileDescriptor;
import android.view.ContentRecordingSession;
import android.view.DisplayCutout;
import android.view.DisplayInfo;
import android.view.IAppTransitionAnimationSpecsFuture;
@@ -873,17 +872,6 @@ interface IWindowManager
     */
    void detachWindowContextFromWindowContainer(IBinder clientToken);

    /**
     * Updates the content recording session. If a different session is already in progress, then
     * the pre-existing session is stopped, and the new incoming session takes over.
     *
     * The DisplayContent for the new session will begin recording when
     * {@link RootWindowContainer#onDisplayChanged} is invoked for the new {@link VirtualDisplay}.
     *
     * @param incomingSession the nullable incoming content recording session
     */
    void setContentRecordingSession(in ContentRecordingSession incomingSession);

    /**
     * Registers a listener, which is to be called whenever cross-window blur is enabled/disabled.
     *
+12 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.media.projection.IMediaProjectionCallback;
import android.media.projection.IMediaProjectionWatcherCallback;
import android.media.projection.MediaProjectionInfo;
import android.os.IBinder;
import android.view.ContentRecordingSession;

/** {@hide} */
interface IMediaProjectionManager {
@@ -33,4 +34,15 @@ interface IMediaProjectionManager {
    void stopActiveProjection();
    void addCallback(IMediaProjectionWatcherCallback callback);
    void removeCallback(IMediaProjectionWatcherCallback callback);

    /**
     * Updates the content recording session. If a different session is already in progress, then
     * the pre-existing session is stopped, and the new incoming session takes over. Only updates
     * the session if the given projection is valid.
     *
     * @param incomingSession the nullable incoming content recording session
     * @param projection      the non-null projection the session describes
     */
    void setContentRecordingSession(in ContentRecordingSession incomingSession,
            in IMediaProjection projection);
}
+11 −4
Original line number Diff line number Diff line
@@ -26,12 +26,11 @@ import android.hardware.display.VirtualDisplay;
import android.hardware.display.VirtualDisplayConfig;
import android.os.Handler;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.ArrayMap;
import android.util.Log;
import android.view.ContentRecordingSession;
import android.view.IWindowManager;
import android.view.Surface;
import android.view.WindowManagerGlobal;
import android.window.WindowContainerToken;

import java.util.Map;
@@ -53,6 +52,7 @@ public final class MediaProjection {
    private final IMediaProjection mImpl;
    private final Context mContext;
    private final Map<Callback, CallbackRecord> mCallbacks;
    @Nullable private IMediaProjectionManager mProjectionService = null;

    /** @hide */
    public MediaProjection(Context context, IMediaProjection impl) {
@@ -172,7 +172,6 @@ public final class MediaProjection {
            @NonNull VirtualDisplayConfig.Builder virtualDisplayConfig,
            @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
        try {
            final IWindowManager wmService = WindowManagerGlobal.getWindowManagerService();
            final WindowContainerToken taskWindowContainerToken =
                    mImpl.getTaskRecordingWindowContainerToken();
            Context windowContext = null;
@@ -199,7 +198,7 @@ public final class MediaProjection {
            }
            session.setDisplayId(virtualDisplay.getDisplay().getDisplayId());
            // Successfully set up, so save the current session details.
            wmService.setContentRecordingSession(session);
            getProjectionService().setContentRecordingSession(session, mImpl);
            return virtualDisplay;
        } catch (RemoteException e) {
            // Can not capture if WMS is not accessible, so bail out.
@@ -207,6 +206,14 @@ public final class MediaProjection {
        }
    }

    private IMediaProjectionManager getProjectionService() {
        if (mProjectionService == null) {
            mProjectionService = IMediaProjectionManager.Stub.asInterface(
                    ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE));
        }
        return mProjectionService;
    }

    /**
     * Stops projection.
     */
+23 −1
Original line number Diff line number Diff line
@@ -45,14 +45,15 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.Slog;
import android.view.ContentRecordingSession;
import android.window.WindowContainerToken;

import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.SystemService.TargetUser;
import com.android.server.Watchdog;
import com.android.server.wm.WindowManagerInternal;

import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -381,6 +382,27 @@ public final class MediaProjectionManagerService extends SystemService
            }
        }

        /**
         * Updates the current content mirroring session.
         */
        @Override
        public void setContentRecordingSession(@Nullable ContentRecordingSession incomingSession,
                @NonNull IMediaProjection projection) {
            final long origId = Binder.clearCallingIdentity();
            try {
                synchronized (mLock) {
                    if (!isValidMediaProjection(projection)) {
                        throw new SecurityException("Invalid media projection");
                    }
                    LocalServices.getService(
                            WindowManagerInternal.class).setContentRecordingSession(
                            incomingSession);
                }
            } finally {
                Binder.restoreCallingIdentity(origId);
            }
        }

        @Override // Binder call
        public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
            if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
+2 −1
Original line number Diff line number Diff line
@@ -207,7 +207,8 @@ final class ContentRecorder {
        // Update the cached session state first, since updating the service will result in always
        // returning to this instance to update recording state.
        mContentRecordingSession = null;
        mDisplayContent.mWmService.setContentRecordingSession(null);
        mDisplayContent.mWmService.mContentRecordingController.setContentRecordingSessionLocked(
                null, mDisplayContent.mWmService);
    }

    /**
Loading