summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Naomi Musgrave <nmusgrave@google.com> 2023-05-16 11:19:54 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2023-05-16 11:19:54 +0000
commit9736133ffc5a676d32ee6fe7ad2304dd4582e88d (patch)
tree65c345bde74d9109a7cf3f3c439a45c6c96c36a7
parentbc87fa6fc441386137b693ee2607404e4a331030 (diff)
parentd8a8b3dad12fef634c333db3005345f5bc088e90 (diff)
Merge "(5/N)[MediaProjection] Send no frames until user reviews consent" into udc-dev
-rw-r--r--core/java/android/view/ContentRecordingSession.java40
-rw-r--r--data/etc/services.core.protolog.json12
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java2
-rw-r--r--services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java6
-rw-r--r--services/core/java/com/android/server/wm/ContentRecorder.java6
-rw-r--r--services/core/java/com/android/server/wm/ContentRecordingController.java43
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java5
-rw-r--r--services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java18
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ContentRecordingControllerTests.java51
11 files changed, 138 insertions, 53 deletions
diff --git a/core/java/android/view/ContentRecordingSession.java b/core/java/android/view/ContentRecordingSession.java
index fdecb8bc61ab..a89f79540c65 100644
--- a/core/java/android/view/ContentRecordingSession.java
+++ b/core/java/android/view/ContentRecordingSession.java
@@ -87,7 +87,7 @@ public final class ContentRecordingSession implements Parcelable {
*
* <p>Only set on the server side to sanitize any input from the client process.
*/
- private boolean mWaitingToRecord = false;
+ private boolean mWaitingForConsent = false;
/**
* Default instance, with recording the display.
@@ -181,7 +181,7 @@ public final class ContentRecordingSession implements Parcelable {
@RecordContent int contentToRecord,
int displayToRecord,
@Nullable IBinder tokenToRecord,
- boolean waitingToRecord) {
+ boolean waitingForConsent) {
this.mVirtualDisplayId = virtualDisplayId;
this.mContentToRecord = contentToRecord;
@@ -195,7 +195,7 @@ public final class ContentRecordingSession implements Parcelable {
this.mDisplayToRecord = displayToRecord;
this.mTokenToRecord = tokenToRecord;
- this.mWaitingToRecord = waitingToRecord;
+ this.mWaitingForConsent = waitingForConsent;
// onConstructed(); // You can define this method to get a callback
}
@@ -246,8 +246,8 @@ public final class ContentRecordingSession implements Parcelable {
* <p>Only set on the server side to sanitize any input from the client process.
*/
@DataClass.Generated.Member
- public boolean isWaitingToRecord() {
- return mWaitingToRecord;
+ public boolean isWaitingForConsent() {
+ return mWaitingForConsent;
}
/**
@@ -309,8 +309,8 @@ public final class ContentRecordingSession implements Parcelable {
* <p>Only set on the server side to sanitize any input from the client process.
*/
@DataClass.Generated.Member
- public @NonNull ContentRecordingSession setWaitingToRecord( boolean value) {
- mWaitingToRecord = value;
+ public @NonNull ContentRecordingSession setWaitingForConsent( boolean value) {
+ mWaitingForConsent = value;
return this;
}
@@ -325,7 +325,7 @@ public final class ContentRecordingSession implements Parcelable {
"contentToRecord = " + recordContentToString(mContentToRecord) + ", " +
"displayToRecord = " + mDisplayToRecord + ", " +
"tokenToRecord = " + mTokenToRecord + ", " +
- "waitingToRecord = " + mWaitingToRecord +
+ "waitingForConsent = " + mWaitingForConsent +
" }";
}
@@ -346,7 +346,7 @@ public final class ContentRecordingSession implements Parcelable {
&& mContentToRecord == that.mContentToRecord
&& mDisplayToRecord == that.mDisplayToRecord
&& java.util.Objects.equals(mTokenToRecord, that.mTokenToRecord)
- && mWaitingToRecord == that.mWaitingToRecord;
+ && mWaitingForConsent == that.mWaitingForConsent;
}
@Override
@@ -360,7 +360,7 @@ public final class ContentRecordingSession implements Parcelable {
_hash = 31 * _hash + mContentToRecord;
_hash = 31 * _hash + mDisplayToRecord;
_hash = 31 * _hash + java.util.Objects.hashCode(mTokenToRecord);
- _hash = 31 * _hash + Boolean.hashCode(mWaitingToRecord);
+ _hash = 31 * _hash + Boolean.hashCode(mWaitingForConsent);
return _hash;
}
@@ -371,7 +371,7 @@ public final class ContentRecordingSession implements Parcelable {
// void parcelFieldName(Parcel dest, int flags) { ... }
byte flg = 0;
- if (mWaitingToRecord) flg |= 0x10;
+ if (mWaitingForConsent) flg |= 0x10;
if (mTokenToRecord != null) flg |= 0x8;
dest.writeByte(flg);
dest.writeInt(mVirtualDisplayId);
@@ -392,7 +392,7 @@ public final class ContentRecordingSession implements Parcelable {
// static FieldType unparcelFieldName(Parcel in) { ... }
byte flg = in.readByte();
- boolean waitingToRecord = (flg & 0x10) != 0;
+ boolean waitingForConsent = (flg & 0x10) != 0;
int virtualDisplayId = in.readInt();
int contentToRecord = in.readInt();
int displayToRecord = in.readInt();
@@ -411,7 +411,7 @@ public final class ContentRecordingSession implements Parcelable {
this.mDisplayToRecord = displayToRecord;
this.mTokenToRecord = tokenToRecord;
- this.mWaitingToRecord = waitingToRecord;
+ this.mWaitingForConsent = waitingForConsent;
// onConstructed(); // You can define this method to get a callback
}
@@ -441,7 +441,7 @@ public final class ContentRecordingSession implements Parcelable {
private @RecordContent int mContentToRecord;
private int mDisplayToRecord;
private @Nullable IBinder mTokenToRecord;
- private boolean mWaitingToRecord;
+ private boolean mWaitingForConsent;
private long mBuilderFieldsSet = 0L;
@@ -506,10 +506,10 @@ public final class ContentRecordingSession implements Parcelable {
* <p>Only set on the server side to sanitize any input from the client process.
*/
@DataClass.Generated.Member
- public @NonNull Builder setWaitingToRecord(boolean value) {
+ public @NonNull Builder setWaitingForConsent(boolean value) {
checkNotUsed();
mBuilderFieldsSet |= 0x10;
- mWaitingToRecord = value;
+ mWaitingForConsent = value;
return this;
}
@@ -531,14 +531,14 @@ public final class ContentRecordingSession implements Parcelable {
mTokenToRecord = null;
}
if ((mBuilderFieldsSet & 0x10) == 0) {
- mWaitingToRecord = false;
+ mWaitingForConsent = false;
}
ContentRecordingSession o = new ContentRecordingSession(
mVirtualDisplayId,
mContentToRecord,
mDisplayToRecord,
mTokenToRecord,
- mWaitingToRecord);
+ mWaitingForConsent);
return o;
}
@@ -551,10 +551,10 @@ public final class ContentRecordingSession implements Parcelable {
}
@DataClass.Generated(
- time = 1679855157534L,
+ time = 1683628463074L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/view/ContentRecordingSession.java",
- inputSignatures = "public static final int RECORD_CONTENT_DISPLAY\npublic static final int RECORD_CONTENT_TASK\nprivate int mVirtualDisplayId\nprivate @android.view.ContentRecordingSession.RecordContent int mContentToRecord\nprivate int mDisplayToRecord\nprivate @android.annotation.Nullable android.os.IBinder mTokenToRecord\nprivate boolean mWaitingToRecord\npublic static android.view.ContentRecordingSession createDisplaySession(int)\npublic static android.view.ContentRecordingSession createTaskSession(android.os.IBinder)\npublic static boolean isValid(android.view.ContentRecordingSession)\npublic static boolean isProjectionOnSameDisplay(android.view.ContentRecordingSession,android.view.ContentRecordingSession)\nclass ContentRecordingSession extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genToString=true, genSetters=true, genEqualsHashCode=true)")
+ inputSignatures = "public static final int RECORD_CONTENT_DISPLAY\npublic static final int RECORD_CONTENT_TASK\nprivate int mVirtualDisplayId\nprivate @android.view.ContentRecordingSession.RecordContent int mContentToRecord\nprivate int mDisplayToRecord\nprivate @android.annotation.Nullable android.os.IBinder mTokenToRecord\nprivate boolean mWaitingForConsent\npublic static android.view.ContentRecordingSession createDisplaySession(int)\npublic static android.view.ContentRecordingSession createTaskSession(android.os.IBinder)\npublic static boolean isValid(android.view.ContentRecordingSession)\npublic static boolean isProjectionOnSameDisplay(android.view.ContentRecordingSession,android.view.ContentRecordingSession)\nclass ContentRecordingSession extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genToString=true, genSetters=true, genEqualsHashCode=true)")
@Deprecated
private void __metadata() {}
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 2a0e476d2726..4b4e7220cb29 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -1675,6 +1675,12 @@
"group": "WM_DEBUG_CONFIGURATION",
"at": "com\/android\/server\/am\/ActivityManagerService.java"
},
+ "-584061725": {
+ "message": "Content Recording: Accept session updating same display %d with granted consent, with an existing session %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/ContentRecordingController.java"
+ },
"-583031528": {
"message": "%s",
"level": "INFO",
@@ -2167,6 +2173,12 @@
"group": "WM_DEBUG_BACK_PREVIEW",
"at": "com\/android\/server\/wm\/TaskFragment.java"
},
+ "-125383273": {
+ "message": "Content Recording: waiting to record, so do nothing",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/ContentRecorder.java"
+ },
"-124316973": {
"message": "Translucent=%s Floating=%s ShowWallpaper=%s Disable=%s",
"level": "VERBOSE",
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 5771a04b9607..34ad91c4c808 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -1560,7 +1560,7 @@ public final class DisplayManagerService extends SystemService {
// VirtualDisplay has been successfully constructed.
session.setVirtualDisplayId(displayId);
// Don't start mirroring until user re-grants consent.
- session.setWaitingToRecord(waitForPermissionConsent);
+ session.setWaitingForConsent(waitForPermissionConsent);
// We set the content recording session here on the server side instead of using
// a second AIDL call in MediaProjection. By ensuring that a virtual display has
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 377b8cf1230e..38631c8ad1cf 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -406,7 +406,7 @@ public final class MediaProjectionManagerService extends SystemService
return;
}
if (mProjectionGrant.mSession == null
- || !mProjectionGrant.mSession.isWaitingToRecord()) {
+ || !mProjectionGrant.mSession.isWaitingForConsent()) {
Slog.w(TAG, "Reusing token: Ignore consent result " + consentResult
+ " if not waiting for the result.");
return;
@@ -445,7 +445,7 @@ public final class MediaProjectionManagerService extends SystemService
*/
private void setReviewedConsentSessionLocked(@Nullable ContentRecordingSession session) {
if (session != null) {
- session.setWaitingToRecord(false);
+ session.setWaitingForConsent(false);
session.setVirtualDisplayId(mProjectionGrant.mVirtualDisplayId);
}
@@ -490,7 +490,7 @@ public final class MediaProjectionManagerService extends SystemService
// Supposedly the package has re-used the user's consent; confirm the provided details
// against the current projection token before re-using the current projection.
if (mProjectionGrant == null || mProjectionGrant.mSession == null
- || !mProjectionGrant.mSession.isWaitingToRecord()) {
+ || !mProjectionGrant.mSession.isWaitingForConsent()) {
Slog.e(TAG, "Reusing token: Not possible to reuse the current projection "
+ "instance");
return null;
diff --git a/services/core/java/com/android/server/wm/ContentRecorder.java b/services/core/java/com/android/server/wm/ContentRecorder.java
index b808a55d2952..6a7e76411fee 100644
--- a/services/core/java/com/android/server/wm/ContentRecorder.java
+++ b/services/core/java/com/android/server/wm/ContentRecorder.java
@@ -276,6 +276,12 @@ final class ContentRecorder implements WindowContainerListener {
return;
}
+ if (mContentRecordingSession.isWaitingForConsent()) {
+ ProtoLog.v(WM_DEBUG_CONTENT_RECORDING, "Content Recording: waiting to record, so do "
+ + "nothing");
+ return;
+ }
+
mRecordedWindowContainer = retrieveRecordedWindowContainer();
if (mRecordedWindowContainer == null) {
// Either the token is missing, or the window associated with the token is missing.
diff --git a/services/core/java/com/android/server/wm/ContentRecordingController.java b/services/core/java/com/android/server/wm/ContentRecordingController.java
index 4da55e20382e..f24ba5a45885 100644
--- a/services/core/java/com/android/server/wm/ContentRecordingController.java
+++ b/services/core/java/com/android/server/wm/ContentRecordingController.java
@@ -56,8 +56,8 @@ final class ContentRecordingController {
* Updates the current recording session.
* <p>Handles the following scenarios:
* <ul>
- * <li>Invalid scenarios: The incoming session is malformed, or the incoming session is
- * identical to the current session</li>
+ * <li>Invalid scenarios: The incoming session is malformed.</li>
+ * <li>Ignored scenario: the incoming session is identical to the current session.</li>
* <li>Start Scenario: Starting a new session. Recording begins immediately.</li>
* <li>Takeover Scenario: Occurs during a Start Scenario, if a pre-existing session was
* in-progress. For example, recording on VirtualDisplay "app_foo" was ongoing. A
@@ -66,6 +66,8 @@ final class ContentRecordingController {
* begin.</li>
* <li>Stopping scenario: The incoming session is null and there is currently an ongoing
* session. The controller stops recording.</li>
+ * <li>Updating scenario: There is an update for the same display, where recording
+ * was previously not taking place but is now permitted to go ahead.</li>
* </ul>
*
* @param incomingSession The incoming recording session (either an update to a current session
@@ -78,20 +80,28 @@ final class ContentRecordingController {
if (incomingSession != null && !ContentRecordingSession.isValid(incomingSession)) {
return;
}
- // Invalid scenario: ignore identical incoming session.
+ final boolean hasSessionUpdatedWithConsent =
+ mSession != null && incomingSession != null && mSession.isWaitingForConsent()
+ && !incomingSession.isWaitingForConsent();
if (ContentRecordingSession.isProjectionOnSameDisplay(mSession, incomingSession)) {
- // TODO(242833866): if incoming session is no longer waiting to record, allow
- // the update through.
-
- ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
- "Content Recording: Ignoring session on same display %d, with an existing "
- + "session %s",
- incomingSession.getVirtualDisplayId(), mSession.getVirtualDisplayId());
- return;
+ if (hasSessionUpdatedWithConsent) {
+ // Updating scenario: accept an incoming session updating the current display.
+ ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+ "Content Recording: Accept session updating same display %d with granted "
+ + "consent, with an existing session %s",
+ incomingSession.getVirtualDisplayId(), mSession.getVirtualDisplayId());
+ } else {
+ // Ignored scenario: ignore identical incoming session.
+ ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+ "Content Recording: Ignoring session on same display %d, with an existing "
+ + "session %s",
+ incomingSession.getVirtualDisplayId(), mSession.getVirtualDisplayId());
+ return;
+ }
}
DisplayContent incomingDisplayContent = null;
- // Start scenario: recording begins immediately.
if (incomingSession != null) {
+ // Start scenario: recording begins immediately.
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
"Content Recording: Handle incoming session on display %d, with a "
+ "pre-existing session %s", incomingSession.getVirtualDisplayId(),
@@ -106,11 +116,14 @@ final class ContentRecordingController {
return;
}
incomingDisplayContent.setContentRecordingSession(incomingSession);
- // TODO(b/270118861): When user grants consent to re-use, explicitly ask ContentRecorder
- // to update, since no config/display change arrives. Mark recording as black.
+ // Updating scenario: Explicitly ask ContentRecorder to update, since no config or
+ // display change will trigger an update from the DisplayContent.
+ if (hasSessionUpdatedWithConsent) {
+ incomingDisplayContent.updateRecording();
+ }
}
// Takeover and stopping scenario: stop recording on the pre-existing session.
- if (mSession != null) {
+ if (mSession != null && !hasSessionUpdatedWithConsent) {
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
"Content Recording: Pause the recording session on display %s",
mDisplayContent.getDisplayId());
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 251a087916e3..fb6d036b9eb9 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -6693,9 +6693,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
/**
* Start recording if this DisplayContent no longer has content. Stop recording if it now
- * has content or the display is not on.
+ * has content or the display is not on. Update recording if the content has changed (for
+ * example, the user has granted consent to token re-use, so we can now start mirroring).
*/
- @VisibleForTesting void updateRecording() {
+ void updateRecording() {
if (mContentRecorder == null || !mContentRecorder.isContentRecordingSessionSet()) {
if (!setDisplayMirroring()) {
return;
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
index acfc0736282e..54387507f4c2 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -1079,7 +1079,7 @@ public class DisplayManagerServiceTest {
verify(mMockProjectionService, atLeastOnce()).setContentRecordingSession(
mContentRecordingSessionCaptor.capture(), nullable(IMediaProjection.class));
ContentRecordingSession session = mContentRecordingSessionCaptor.getValue();
- assertThat(session.isWaitingToRecord()).isTrue();
+ assertThat(session.isWaitingForConsent()).isTrue();
}
@Test
@@ -1114,7 +1114,7 @@ public class DisplayManagerServiceTest {
assertThat(session.getContentToRecord()).isEqualTo(RECORD_CONTENT_DISPLAY);
assertThat(session.getVirtualDisplayId()).isEqualTo(displayId);
assertThat(session.getDisplayToRecord()).isEqualTo(displayToRecord);
- assertThat(session.isWaitingToRecord()).isFalse();
+ assertThat(session.isWaitingForConsent()).isFalse();
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
index 275533fb1c37..b91a6cbf05a0 100644
--- a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
@@ -139,7 +139,7 @@ public class MediaProjectionManagerServiceTest {
doReturn(mPackageManager).when(mContext).getPackageManager();
mClock = new OffsettableClock.Stopped();
- mWaitingDisplaySession.setWaitingToRecord(true);
+ mWaitingDisplaySession.setWaitingForConsent(true);
mWaitingDisplaySession.setVirtualDisplayId(5);
mAppInfo.targetSdkVersion = 32;
@@ -484,7 +484,7 @@ public class MediaProjectionManagerServiceTest {
mSessionCaptor.capture());
// Examine latest value.
final ContentRecordingSession capturedSession = mSessionCaptor.getValue();
- assertThat(capturedSession.isWaitingToRecord()).isFalse();
+ assertThat(capturedSession.isWaitingForConsent()).isFalse();
assertThat(capturedSession.getVirtualDisplayId()).isEqualTo(INVALID_DISPLAY);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
index ad9f710fbbcc..bbec091b9924 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
@@ -79,6 +79,8 @@ public class ContentRecorderTests extends WindowTestsBase {
private Task mTask;
private final ContentRecordingSession mDisplaySession =
ContentRecordingSession.createDisplaySession(DEFAULT_DISPLAY);
+ private final ContentRecordingSession mWaitingDisplaySession =
+ ContentRecordingSession.createDisplaySession(DEFAULT_DISPLAY);
private ContentRecordingSession mTaskSession;
private static Point sSurfaceSize;
private ContentRecorder mContentRecorder;
@@ -120,6 +122,10 @@ public class ContentRecorderTests extends WindowTestsBase {
mTaskSession = ContentRecordingSession.createTaskSession(sTaskWindowContainerToken);
mTaskSession.setVirtualDisplayId(displayId);
+ // GIVEN a session is waiting for the user to review consent.
+ mWaitingDisplaySession.setVirtualDisplayId(displayId);
+ mWaitingDisplaySession.setWaitingForConsent(true);
+
mConfigListener = new ConfigListener();
DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
mContext.getMainExecutor(), mConfigListener);
@@ -221,6 +227,18 @@ public class ContentRecorderTests extends WindowTestsBase {
}
@Test
+ public void testUpdateRecording_waitingForConsent() {
+ mContentRecorder.setContentRecordingSession(mWaitingDisplaySession);
+ mContentRecorder.updateRecording();
+ assertThat(mContentRecorder.isCurrentlyRecording()).isFalse();
+
+
+ mContentRecorder.setContentRecordingSession(mDisplaySession);
+ mContentRecorder.updateRecording();
+ assertThat(mContentRecorder.isCurrentlyRecording()).isTrue();
+ }
+
+ @Test
public void testOnConfigurationChanged_neverRecording() {
mContentRecorder.onConfigurationChanged(ORIENTATION_PORTRAIT);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ContentRecordingControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/ContentRecordingControllerTests.java
index 6cda0381d245..52226c2be298 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ContentRecordingControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ContentRecordingControllerTests.java
@@ -24,10 +24,8 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
-import android.os.IBinder;
import android.platform.test.annotations.Presubmit;
import android.view.ContentRecordingSession;
@@ -36,6 +34,8 @@ import androidx.test.filters.SmallTest;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
/**
* Tests for the {@link ContentRecordingController} class.
@@ -49,12 +49,20 @@ import org.junit.runner.RunWith;
public class ContentRecordingControllerTests extends WindowTestsBase {
private final ContentRecordingSession mDefaultSession =
ContentRecordingSession.createDisplaySession(DEFAULT_DISPLAY);
+ private final ContentRecordingSession mWaitingDisplaySession =
+ ContentRecordingSession.createDisplaySession(DEFAULT_DISPLAY);
private int mVirtualDisplayId;
private DisplayContent mVirtualDisplayContent;
+ private WindowContainer.RemoteToken mRootTaskToken;
+
+ @Mock
+ private WindowContainer mTaskWindowContainer;
@Before
public void setup() {
+ MockitoAnnotations.initMocks(this);
+
// GIVEN the VirtualDisplay associated with the session (so the display has state ON).
mVirtualDisplayContent = new TestDisplayContent.Builder(mAtm, 500, 600).build();
mVirtualDisplayId = mVirtualDisplayContent.getDisplayId();
@@ -62,6 +70,11 @@ public class ContentRecordingControllerTests extends WindowTestsBase {
spyOn(mVirtualDisplayContent);
mDefaultSession.setVirtualDisplayId(mVirtualDisplayId);
+ mWaitingDisplaySession.setVirtualDisplayId(mVirtualDisplayId);
+ mWaitingDisplaySession.setWaitingForConsent(true);
+
+ mRootTaskToken = new WindowContainer.RemoteToken(mTaskWindowContainer);
+ mTaskWindowContainer.mRemoteToken = mRootTaskToken;
}
@Test
@@ -92,7 +105,7 @@ public class ContentRecordingControllerTests extends WindowTestsBase {
}
@Test
- public void testSetContentRecordingSessionLocked_newDisplaySession_accepted() {
+ public void testSetContentRecordingSessionLocked_newSession_accepted() {
ContentRecordingController controller = new ContentRecordingController();
// GIVEN a valid display session.
// WHEN updating the session.
@@ -104,15 +117,37 @@ public class ContentRecordingControllerTests extends WindowTestsBase {
}
@Test
- public void testSetContentRecordingSessionLocked_updateCurrentDisplaySession_notAccepted() {
+ public void testSetContentRecordingSessionLocked_updateSession_noLongerWaiting_accepted() {
+ ContentRecordingController controller = new ContentRecordingController();
+ // GIVEN a valid display session already in place.
+ controller.setContentRecordingSessionLocked(mWaitingDisplaySession, mWm);
+ verify(mVirtualDisplayContent, atLeastOnce()).setContentRecordingSession(
+ mWaitingDisplaySession);
+
+ // WHEN updating the session on the same display, so no longer waiting to record.
+ ContentRecordingSession sessionUpdate = ContentRecordingSession.createTaskSession(
+ mRootTaskToken.toWindowContainerToken().asBinder());
+ sessionUpdate.setVirtualDisplayId(mVirtualDisplayId);
+ sessionUpdate.setWaitingForConsent(false);
+ controller.setContentRecordingSessionLocked(sessionUpdate, mWm);
+
+ ContentRecordingSession resultingSession = controller.getContentRecordingSessionLocked();
+ // THEN the session was accepted.
+ assertThat(resultingSession).isEqualTo(sessionUpdate);
+ verify(mVirtualDisplayContent, atLeastOnce()).setContentRecordingSession(sessionUpdate);
+ verify(mVirtualDisplayContent).updateRecording();
+ }
+
+ @Test
+ public void testSetContentRecordingSessionLocked_invalidUpdateSession_notWaiting_notAccepted() {
ContentRecordingController controller = new ContentRecordingController();
// GIVEN a valid display session already in place.
controller.setContentRecordingSessionLocked(mDefaultSession, mWm);
verify(mVirtualDisplayContent, atLeastOnce()).setContentRecordingSession(mDefaultSession);
// WHEN updating the session on the same display.
- ContentRecordingSession sessionUpdate =
- ContentRecordingSession.createTaskSession(mock(IBinder.class));
+ ContentRecordingSession sessionUpdate = ContentRecordingSession.createTaskSession(
+ mRootTaskToken.toWindowContainerToken().asBinder());
sessionUpdate.setVirtualDisplayId(mVirtualDisplayId);
controller.setContentRecordingSessionLocked(sessionUpdate, mWm);
@@ -123,7 +158,7 @@ public class ContentRecordingControllerTests extends WindowTestsBase {
}
@Test
- public void testSetContentRecordingSessionLocked_disableCurrentDisplaySession_accepted() {
+ public void testSetContentRecordingSessionLocked_disableCurrentSession_accepted() {
ContentRecordingController controller = new ContentRecordingController();
// GIVEN a valid display session already in place.
controller.setContentRecordingSessionLocked(mDefaultSession, mWm);
@@ -141,7 +176,7 @@ public class ContentRecordingControllerTests extends WindowTestsBase {
}
@Test
- public void testSetContentRecordingSessionLocked_takeOverCurrentDisplaySession_accepted() {
+ public void testSetContentRecordingSessionLocked_takeOverCurrentSession_accepted() {
ContentRecordingController controller = new ContentRecordingController();
// GIVEN a valid display session already in place.
controller.setContentRecordingSessionLocked(mDefaultSession, mWm);