Merge "[Media Projection] Require valid token to set session" into tm-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
55ecb4ec82
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.hardware.display.DisplayManagerInternal;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.util.Pair;
|
||||
import android.view.ContentRecordingSession;
|
||||
import android.view.Display;
|
||||
import android.view.IInputFilter;
|
||||
import android.view.IRemoteAnimationFinishedCallback;
|
||||
@@ -869,4 +870,16 @@ public abstract class WindowManagerInternal {
|
||||
*/
|
||||
public abstract boolean isPointInsideWindow(
|
||||
@NonNull IBinder windowToken, int displayId, float displayX, float displayY);
|
||||
|
||||
/**
|
||||
* 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}.
|
||||
* Must be invoked for a valid MediaProjection session.
|
||||
*
|
||||
* @param incomingSession the nullable incoming content recording session
|
||||
*/
|
||||
public abstract void setContentRecordingSession(ContentRecordingSession incomingSession);
|
||||
}
|
||||
|
||||
@@ -2956,16 +2956,6 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the current content mirroring session.
|
||||
*/
|
||||
@Override
|
||||
public void setContentRecordingSession(@Nullable ContentRecordingSession incomingSession) {
|
||||
synchronized (mGlobalLock) {
|
||||
mContentRecordingController.setContentRecordingSessionLocked(incomingSession, this);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(multi-display): remove when no default display use case.
|
||||
void prepareAppTransitionNone() {
|
||||
if (!checkCallingPermission(MANAGE_APP_TOKENS, "prepareAppTransition()")) {
|
||||
@@ -8242,6 +8232,14 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
return w.getBounds().contains((int) displayX, (int) displayY);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentRecordingSession(@Nullable ContentRecordingSession incomingSession) {
|
||||
synchronized (mGlobalLock) {
|
||||
mContentRecordingController.setContentRecordingSessionLocked(incomingSession,
|
||||
WindowManagerService.this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void registerAppFreezeListener(AppFreezeListener listener) {
|
||||
|
||||
@@ -2441,7 +2441,7 @@ public class DisplayContentTests extends WindowTestsBase {
|
||||
ContentRecordingSession session = ContentRecordingSession.createDisplaySession(
|
||||
tokenToMirror);
|
||||
session.setDisplayId(displayId);
|
||||
mWm.setContentRecordingSession(session);
|
||||
mWm.mContentRecordingController.setContentRecordingSessionLocked(session, mWm);
|
||||
actualDC.updateRecording();
|
||||
|
||||
// THEN mirroring is not started, since a null surface indicates the VirtualDisplay is off.
|
||||
@@ -2470,7 +2470,7 @@ public class DisplayContentTests extends WindowTestsBase {
|
||||
ContentRecordingSession session = ContentRecordingSession.createDisplaySession(
|
||||
tokenToMirror);
|
||||
session.setDisplayId(displayId);
|
||||
mWm.setContentRecordingSession(session);
|
||||
mWm.mContentRecordingController.setContentRecordingSessionLocked(session, mWm);
|
||||
mWm.mRoot.onDisplayAdded(displayId);
|
||||
|
||||
// WHEN getting the DisplayContent for the new virtual display.
|
||||
|
||||
Reference in New Issue
Block a user