From 5050cfdca9b8dd3c7870c7f7665fb514defb26cb Mon Sep 17 00:00:00 2001 From: dakinola Date: Mon, 18 Sep 2023 09:47:05 +0000 Subject: Stop active callbacks from being stopped on starting new projection session Ensuring that previous mediaprojection callbacks are stopped before new callbacks are registered, so new projections aren't immediately stopped after starting. Bug: 279417791 Test: atest FrameworksServicesTests:MediaProjectionManagerServiceTest#testCreateProjection_priorProjectionGrant --iterations=20 (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:9c037fb1252c7b6e31c4637cf5483e32b5cd8f64) Merged-In: Ia8f722bec5e63d7417ed93e2e56c0fccfe8e35a6 Change-Id: Ia8f722bec5e63d7417ed93e2e56c0fccfe8e35a6 --- .../projection/MediaProjectionManagerService.java | 8 ++++--- .../MediaProjectionManagerServiceTest.java | 28 ++++++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) 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 38aac4648e34..d48fa895dd1e 100644 --- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java +++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java @@ -940,9 +940,6 @@ public final class MediaProjectionManagerService extends SystemService throw new SecurityException("Media projections require a foreground service" + " of type ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION"); } - - mCallback = callback; - registerCallback(mCallback); try { mToken = callback.asBinder(); mDeathEater = new IBinder.DeathRecipient() { @@ -988,6 +985,11 @@ public final class MediaProjectionManagerService extends SystemService } } startProjectionLocked(this); + + // Register new callbacks after stop has been dispatched to previous session. + mCallback = callback; + registerCallback(mCallback); + // Mark this token as used when the app gets the MediaProjection instance. mCountStarts++; } 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 c42928eba85f..e75f9e097e93 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 @@ -73,6 +73,9 @@ import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + /** * Tests for the {@link MediaProjectionManagerService} class. * @@ -183,6 +186,29 @@ public class MediaProjectionManagerServiceTest { assertThat(secondProjection).isNotEqualTo(projection); } + @Test + public void testCreateProjection_priorProjectionGrant() throws + NameNotFoundException, InterruptedException { + // Create a first projection. + MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions(); + FakeIMediaProjectionCallback callback1 = new FakeIMediaProjectionCallback(); + projection.start(callback1); + + // Create a second projection. + MediaProjectionManagerService.MediaProjection secondProjection = + startProjectionPreconditions(); + FakeIMediaProjectionCallback callback2 = new FakeIMediaProjectionCallback(); + secondProjection.start(callback2); + + // Check that the first projection get stopped, but not the second projection. + final int timeout = 5; + boolean stoppedCallback1 = callback1.mLatch.await(timeout, TimeUnit.SECONDS); + boolean stoppedCallback2 = callback2.mLatch.await(timeout, TimeUnit.SECONDS); + + assertThat(stoppedCallback1).isTrue(); + assertThat(stoppedCallback2).isFalse(); + } + @Test public void testCreateProjection_attemptReuse_noPriorProjectionGrant() throws NameNotFoundException { @@ -713,8 +739,10 @@ public class MediaProjectionManagerServiceTest { } private static class FakeIMediaProjectionCallback extends IMediaProjectionCallback.Stub { + CountDownLatch mLatch = new CountDownLatch(1); @Override public void onStop() throws RemoteException { + mLatch.countDown(); } @Override -- cgit v1.2.3