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

Commit 359bdc62 authored by Chris Göllner's avatar Chris Göllner
Browse files

[Media Projection] Logs STATE_STOPPED

Test: atest FrameworksServicesTests:MediaProjectionManagerServiceTest
Test: atest FrameworksServicesTests:MediaProjectionMetricsLoggerTest
Fixes: 304726295
Change-Id: Ic6a5e82609ca54ab0a9b00a1236a0a76dc628df5
parent de1b030c
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -293,6 +293,12 @@ public final class MediaProjectionManagerService extends SystemService
    private void stopProjectionLocked(final MediaProjection projection) {
        Slog.d(TAG, "Content Recording: Stopped active MediaProjection and "
                + "dispatching stop to callbacks");
        ContentRecordingSession session = projection.mSession;
        int targetUid =
                session != null
                        ? session.getTargetUid()
                        : ContentRecordingSession.TARGET_UID_UNKNOWN;
        mMediaProjectionMetricsLogger.logStopped(projection.uid, targetUid);
        mProjectionToken = null;
        mProjectionGrant = null;
        dispatchStop(projection);
+15 −1
Original line number Diff line number Diff line
@@ -90,7 +90,21 @@ public class MediaProjectionMetricsLogger {
                sessionCreationSource);
    }

    void notifyProjectionStateChange(int hostUid, int state, int sessionCreationSource) {
    /** Logs that the capturing stopped, either normally or because of error. */
    public void logStopped(int hostUid, int targetUid) {
        write(
                mSessionIdGenerator.getCurrentSessionId(),
                FrameworkStatsLog
                        .MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_STOPPED,
                hostUid,
                targetUid,
                TIME_SINCE_LAST_ACTIVE_UNKNOWN,
                FrameworkStatsLog
                        .MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN);
        mTimestampStore.registerActiveSessionEnded();
    }

    public void notifyProjectionStateChange(int hostUid, int state, int sessionCreationSource) {
        write(hostUid, state, sessionCreationSource);
    }

+69 −2
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertThrows;

@@ -311,6 +312,70 @@ public class MediaProjectionManagerServiceTest {
        assertThat(secondProjection).isNotEqualTo(projection);
    }

    @Test
    public void stop_noActiveProjections_doesNotLog() throws Exception {
        MediaProjectionManagerService service =
                new MediaProjectionManagerService(mContext, mMediaProjectionMetricsLoggerInjector);
        MediaProjectionManagerService.MediaProjection projection =
                startProjectionPreconditions(service);

        projection.stop();

        verifyZeroInteractions(mMediaProjectionMetricsLogger);
    }

    @Test
    public void stop_noSession_logsHostUidAndUnknownTargetUid() throws Exception {
        MediaProjectionManagerService service =
                new MediaProjectionManagerService(mContext, mMediaProjectionMetricsLoggerInjector);
        MediaProjectionManagerService.MediaProjection projection =
                startProjectionPreconditions(service);
        projection.start(mIMediaProjectionCallback);

        projection.stop();

        verify(mMediaProjectionMetricsLogger)
                .logStopped(UID, ContentRecordingSession.TARGET_UID_UNKNOWN);
    }

    @Test
    public void stop_displaySession_logsHostUidAndUnknownTargetUidFullScreen() throws Exception {
        MediaProjectionManagerService service =
                new MediaProjectionManagerService(mContext, mMediaProjectionMetricsLoggerInjector);
        MediaProjectionManagerService.MediaProjection projection =
                startProjectionPreconditions(service);
        projection.start(mIMediaProjectionCallback);
        doReturn(true)
                .when(mWindowManagerInternal)
                .setContentRecordingSession(any(ContentRecordingSession.class));
        service.setContentRecordingSession(DISPLAY_SESSION);

        projection.stop();

        verify(mMediaProjectionMetricsLogger)
                .logStopped(UID, ContentRecordingSession.TARGET_UID_FULL_SCREEN);
    }

    @Test
    public void stop_taskSession_logsHostUidAndTargetUid() throws Exception {
        int targetUid = 1234;
        MediaProjectionManagerService service =
                new MediaProjectionManagerService(mContext, mMediaProjectionMetricsLoggerInjector);
        MediaProjectionManagerService.MediaProjection projection =
                startProjectionPreconditions(service);
        projection.start(mIMediaProjectionCallback);
        doReturn(true)
                .when(mWindowManagerInternal)
                .setContentRecordingSession(any(ContentRecordingSession.class));
        ContentRecordingSession taskSession =
                ContentRecordingSession.createTaskSession(mock(IBinder.class), targetUid);
        service.setContentRecordingSession(taskSession);

        projection.stop();

        verify(mMediaProjectionMetricsLogger).logStopped(UID, targetUid);
    }

    @Test
    public void testIsValid_multipleStarts_preventionDisabled() throws NameNotFoundException {
        MediaProjectionManagerService service = new MediaProjectionManagerService(mContext,
@@ -762,8 +827,10 @@ public class MediaProjectionManagerServiceTest {
    public void setContentRecordingSession_success_logsCaptureInProgress()
            throws Exception {
        mService.addCallback(mWatcherCallback);
        MediaProjectionManagerService service = new MediaProjectionManagerService(mContext, mMediaProjectionMetricsLoggerInjector);
        MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions();
        MediaProjectionManagerService service =
                new MediaProjectionManagerService(mContext, mMediaProjectionMetricsLoggerInjector);
        MediaProjectionManagerService.MediaProjection projection =
                startProjectionPreconditions(service);
        projection.start(mIMediaProjectionCallback);
        doReturn(true).when(mWindowManagerInternal).setContentRecordingSession(
                any(ContentRecordingSession.class));
+92 −1
Original line number Diff line number Diff line
@@ -16,11 +16,14 @@

package com.android.server.media.projection;

import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN;
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_INITIATED;
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_STOPPED;
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_UNKNOWN;

import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@@ -34,6 +37,7 @@ import com.android.internal.util.FrameworkStatsLog;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

@@ -50,7 +54,8 @@ import java.time.Duration;
public class MediaProjectionMetricsLoggerTest {

    private static final int TEST_HOST_UID = 123;
    private static final int TEST_CREATION_SOURCE = 456;
    private static final int TEST_TARGET_UID = 456;
    private static final int TEST_CREATION_SOURCE = 789;

    @Mock private FrameworkStatsLogWrapper mFrameworkStatsLogWrapper;
    @Mock private MediaProjectionSessionIdGenerator mSessionIdGenerator;
@@ -142,6 +147,92 @@ public class MediaProjectionMetricsLoggerTest {
                MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_INITIATED);
    }

    @Test
    public void logStopped_logsStateChangedAtomId() {
        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);

        verifyStateChangedAtomIdLogged();
    }

    @Test
    public void logStopped_logsCurrentSessionId() {
        int currentSessionId = 987;
        when(mSessionIdGenerator.getCurrentSessionId()).thenReturn(currentSessionId);

        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);

        verifySessionIdLogged(currentSessionId);
    }

    @Test
    public void logStopped_logsStateStopped() {
        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);

        verifyStateLogged(MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_STOPPED);
    }

    @Test
    public void logStopped_logsHostUid() {
        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);

        verifyHostUidLogged(TEST_HOST_UID);
    }

    @Test
    public void logStopped_logsTargetUid() {
        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);

        verifyTargetUidLogged(TEST_TARGET_UID);
    }

    @Test
    public void logStopped_logsUnknownTimeSinceLastActive() {
        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);

        verifyTimeSinceLastActiveSessionLogged(-1);
    }

    @Test
    public void logStopped_logsUnknownSessionCreationSource() {
        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);

        verifyCreationSourceLogged(
                MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN);
    }

    @Test
    public void logStopped_logsPreviousState() {
        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);
        verifyPreviousStateLogged(
                MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_UNKNOWN);

        mLogger.logInitiated(TEST_HOST_UID, TEST_CREATION_SOURCE);
        verifyPreviousStateLogged(
                MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_STOPPED);

        mLogger.logStopped(TEST_HOST_UID, TEST_CREATION_SOURCE);
        verifyPreviousStateLogged(
                MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_INITIATED);
    }

    @Test
    public void logStopped_registersActiveSessionEnded_afterLogging() {
        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);

        InOrder inOrder = inOrder(mFrameworkStatsLogWrapper, mTimestampStore);
        inOrder.verify(mFrameworkStatsLogWrapper)
                .write(
                        /* code= */ anyInt(),
                        /* sessionId= */ anyInt(),
                        /* state= */ anyInt(),
                        /* previousState= */ anyInt(),
                        /* hostUid= */ anyInt(),
                        /* targetUid= */ anyInt(),
                        /* timeSinceLastActive= */ anyInt(),
                        /* creationSource= */ anyInt());
        inOrder.verify(mTimestampStore).registerActiveSessionEnded();
    }

    private void verifyStateChangedAtomIdLogged() {
        verify(mFrameworkStatsLogWrapper)
                .write(