summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author dakinola <dakinola@google.com> 2023-09-07 12:44:48 +0000
committer dakinola <dakinola@google.com> 2023-09-13 13:45:40 +0000
commit1bc7a32560e8b1485de98289fd35d6a3388c29e6 (patch)
tree6aa7e46c59242da7670093cfd0ba4cea96641cf1
parentdead0f9ca81872e3a1ccd3e28b4cbea980f3b33c (diff)
Stop active MediaProjection callbacks before registering new callbacks
A race condition when starting a new mediaprojection session during an active one was caused by new callbacks being registered then immediately stopped when cleaning up callbacks from the previous session. Instead, existing callbacks should be stopped before new callbacks are registered. Bug: 279417791 Test: atest FrameworksServicesTests:MediaProjectionManagerServiceTest#testCreateProjection_priorProjectionGrant Test: smoke test on Felix & Tangor Change-Id: I7c61f0da14f9be5c5a49792c9b336070b9a40e6e
-rw-r--r--services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java21
2 files changed, 26 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 802a7f2954af..9954a903be5c 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -975,9 +975,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 = () -> {
@@ -1022,6 +1019,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 ddd1221e4c91..b0fd60672853 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
@@ -202,6 +202,24 @@ public class MediaProjectionManagerServiceTest {
}
@Test
+ public void testCreateProjection_priorProjectionGrant() throws NameNotFoundException {
+ // 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 second projection's callback hasn't been stopped.
+ assertThat(callback1.mStopped).isTrue();
+ assertThat(callback2.mStopped).isFalse();
+ }
+
+ @Test
public void testCreateProjection_attemptReuse_noPriorProjectionGrant()
throws NameNotFoundException {
// Create a first projection.
@@ -785,8 +803,11 @@ public class MediaProjectionManagerServiceTest {
}
private static class FakeIMediaProjectionCallback extends IMediaProjectionCallback.Stub {
+ boolean mStopped = false;
+
@Override
public void onStop() throws RemoteException {
+ mStopped = true;
}
@Override