summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/IWindowManager.aidl12
-rw-r--r--media/java/android/media/projection/IMediaProjectionManager.aidl12
-rw-r--r--media/java/android/media/projection/MediaProjection.java15
-rw-r--r--services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java24
-rw-r--r--services/core/java/com/android/server/wm/ContentRecorder.java3
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerInternal.java13
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java18
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java4
8 files changed, 71 insertions, 30 deletions
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index c83869c9ee68..fb562d8e97db 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -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;
@@ -874,17 +873,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.
*
* @param listener the listener to be registered
diff --git a/media/java/android/media/projection/IMediaProjectionManager.aidl b/media/java/android/media/projection/IMediaProjectionManager.aidl
index d190fcec6c8c..1d58a409718d 100644
--- a/media/java/android/media/projection/IMediaProjectionManager.aidl
+++ b/media/java/android/media/projection/IMediaProjectionManager.aidl
@@ -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);
}
diff --git a/media/java/android/media/projection/MediaProjection.java b/media/java/android/media/projection/MediaProjection.java
index b5f95938f845..ba7bf3f5f5d3 100644
--- a/media/java/android/media/projection/MediaProjection.java
+++ b/media/java/android/media/projection/MediaProjection.java
@@ -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.
*/
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
index 1937852fa333..098e8f74749c 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -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;
diff --git a/services/core/java/com/android/server/wm/ContentRecorder.java b/services/core/java/com/android/server/wm/ContentRecorder.java
index 87523f44d4b6..5d2d5826f227 100644
--- a/services/core/java/com/android/server/wm/ContentRecorder.java
+++ b/services/core/java/com/android/server/wm/ContentRecorder.java
@@ -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);
}
/**
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index c0d7d1362ac3..9eee7ba871a2 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -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);
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 7a5480401de8..902218621cd0 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -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) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index c5f785ea7680..32f3bfe5166c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -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.