diff options
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); |