Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1bc7a325 authored by dakinola's avatar dakinola
Browse files

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
parent dead0f9c
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -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++;
            }
+21 −0
Original line number Diff line number Diff line
@@ -201,6 +201,24 @@ public class MediaProjectionManagerServiceTest {
        assertThat(secondProjection).isNotEqualTo(projection);
    }

    @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 {
@@ -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