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

Commit fbb759fe authored by Anton Potapov's avatar Anton Potapov
Browse files

Choose between a legacy and a thin screen recording service based on the flag.

Flag: com.android.systemui.thin_screen_recording_service
Bug: 368579013
Test: atest ScreenRecordingServiceInteractorTest
Test: manually on a foldable. Check screen recording with hsum
enabled/disabled.

Change-Id: I2acaeafe2cbe725b17ae42525fa6f0c62f57f533
parent 5c435f87
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -42,10 +42,11 @@ import com.android.systemui.mediaprojection.permission.ENTIRE_SCREEN
import com.android.systemui.mediaprojection.permission.SINGLE_APP
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.res.R
import com.android.systemui.settings.UserContextProvider
import com.android.systemui.screenrecord.domain.interactor.screenRecordingStartStopInteractor
import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround
import com.android.systemui.statusbar.phone.SystemUIDialog
import com.android.systemui.statusbar.phone.SystemUIDialogManager
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
@@ -68,12 +69,13 @@ class ScreenRecordPermissionDialogDelegateTest : SysuiTestCase() {

    @Mock private lateinit var starter: ActivityStarter
    @Mock private lateinit var controller: ScreenRecordUxController
    @Mock private lateinit var userContextProvider: UserContextProvider
    @Mock private lateinit var onStartRecordingClicked: Runnable
    @Mock private lateinit var mediaProjectionMetricsLogger: MediaProjectionMetricsLogger
    private val fakeDisplayWindowPropertiesRepository =
        FakeDisplayWindowPropertiesRepository(context)

    private val kosmos = testKosmos()

    private lateinit var dialog: SystemUIDialog
    private lateinit var underTest: ScreenRecordPermissionDialogDelegate

@@ -96,13 +98,13 @@ class ScreenRecordPermissionDialogDelegateTest : SysuiTestCase() {
                TEST_HOST_UID,
                controller,
                starter,
                userContextProvider,
                onStartRecordingClicked,
                mediaProjectionMetricsLogger,
                systemUIDialogFactory,
                context,
                context.getSystemService(DisplayManager::class.java)!!,
                { fakeDisplayWindowPropertiesRepository },
                kosmos.screenRecordingStartStopInteractor,
            )
        dialog = underTest.createDialog()
    }
+9 −4
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@ import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.screenrecord.ScreenRecordingAudioSource
import com.android.systemui.screenrecord.domain.ScreenRecordingParameters
import com.android.systemui.screenrecord.screenRecordUxController
import com.android.systemui.screenrecord.service.FakeScreenRecordingService
import com.android.systemui.screenrecord.service.FakeScreenRecordingServiceCallbackWrapper
import com.android.systemui.screenrecord.service.callbackStatus
@@ -59,6 +61,7 @@ class ScreenRecordingServiceInteractorTest : SysuiTestCase() {
                mockedContext,
                applicationCoroutineScope,
                userRepository,
                screenRecordUxController,
            )
        }
    }
@@ -121,9 +124,11 @@ class ScreenRecordingServiceInteractorTest : SysuiTestCase() {

private fun ScreenRecordingServiceInteractor.startRecording() {
    startRecording(
        ScreenRecordingParameters(
            captureTarget = null,
            audioSource = ScreenRecordingAudioSource.NONE,
            displayId = 0,
            shouldShowTaps = false,
        )
    )
}
+12 −8
Original line number Diff line number Diff line
@@ -144,7 +144,7 @@ constructor(
    @VisibleForTesting
    public override fun handleClick(expandable: Expandable?) {
        if (issueRecordingState.isRecording) {
            stopIssueRecordingService()
            sendStopIssueRecordingServiceIntent()
        } else {
            mUiHandler.post { showPrompt(expandable) }
        }
@@ -154,6 +154,15 @@ constructor(
        screenRecordUxController.startCountdown(
            DELAY_MS,
            INTERVAL_MS,
            { sendStartIssueRecordingServiceIntent() },
            { sendStopIssueRecordingServiceIntent() },
        )

    private fun sendStopIssueRecordingServiceIntent() =
        pendingServiceIntent(getStopIntent(userContextProvider.userContext))
            .send(BroadcastOptions.makeBasic().apply { isInteractive = true }.toBundle())

    private fun sendStartIssueRecordingServiceIntent() =
        pendingServiceIntent(
                getStartIntent(
                    userContextProvider.userContext,
@@ -161,12 +170,7 @@ constructor(
                    issueRecordingState.recordScreen,
                    issueRecordingState.takeBugreport,
                )
            ),
            pendingServiceIntent(getStopIntent(userContextProvider.userContext)),
            )

    private fun stopIssueRecordingService() =
        pendingServiceIntent(getStopIntent(userContextProvider.userContext))
            .send(BroadcastOptions.makeBasic().apply { isInteractive = true }.toBundle())

    private fun pendingServiceIntent(action: Intent) =
+14 −8
Original line number Diff line number Diff line
@@ -65,7 +65,7 @@ constructor(
    override suspend fun handleInput(input: QSTileInput<IssueRecordingModel>) {
        if (input.action is QSTileUserAction.Click) {
            if (input.data.isRecording) {
                stopIssueRecordingService()
                sendStopIntent()
            } else {
                withContext(mainCoroutineContext) { showPrompt(input.action.expandable) }
            }
@@ -105,6 +105,16 @@ constructor(
        screenRecordUxController.startCountdown(
            DELAY_MS,
            INTERVAL_MS,
            { sendStartIntent() },
            { sendStopIntent() },
        )

    private fun sendStopIntent() {
        pendingServiceIntent(getStopIntent(userContextProvider.userContext))
            .send(BroadcastOptions.makeBasic().apply { isInteractive = true }.toBundle())
    }

    private fun sendStartIntent() {
        pendingServiceIntent(
                getStartIntent(
                    userContextProvider.userContext,
@@ -112,13 +122,9 @@ constructor(
                    state.recordScreen,
                    state.takeBugreport,
                )
            ),
            pendingServiceIntent(getStopIntent(userContextProvider.userContext)),
            )

    private fun stopIssueRecordingService() =
        pendingServiceIntent(getStopIntent(userContextProvider.userContext))
            .send(BroadcastOptions.makeBasic().apply { isInteractive = true }.toBundle())
    }

    private fun pendingServiceIntent(action: Intent) =
        PendingIntent.getService(
+20 −22
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ package com.android.systemui.screenrecord;
import static com.android.systemui.screenrecord.ScreenRecordUxController.EXTRA_STATE;
import static com.android.systemui.screenrecord.ScreenRecordUxController.INTENT_UPDATE_STATE;

import android.app.BroadcastOptions;
import android.app.Dialog;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
@@ -27,7 +26,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.projection.StopReason;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Process;
import android.os.UserHandle;
@@ -59,9 +57,8 @@ public class RecordingController
    private final ScreenRecordUxController mScreenRecordUxController;
    private boolean mIsStarting;
    private boolean mIsRecording;
    private PendingIntent mStopIntent;
    private Runnable mStop;
    private @StopReason int mStopReason = StopReason.STOP_UNKNOWN;
    private final Bundle mInteractiveBroadcastOption;
    private CountDownTimer mCountDownTimer = null;
    private final Executor mMainExecutor;
    private final BroadcastDispatcher mBroadcastDispatcher;
@@ -130,10 +127,6 @@ public class RecordingController
        mScreenCaptureDisabledDialogDelegate = screenCaptureDisabledDialogDelegate;
        mScreenRecordPermissionDialogDelegateFactory = screenRecordPermissionDialogDelegateFactory;
        mScreenRecordPermissionContentManagerFactory = screenRecordPermissionContentManagerFactory;

        BroadcastOptions options = BroadcastOptions.makeBasic();
        options.setInteractive(true);
        mInteractiveBroadcastOption = options.toBundle();
    }

    /**
@@ -196,13 +189,12 @@ public class RecordingController
     *
     * @param ms       Total time in ms to wait before starting
     * @param interval Time in ms per countdown step
     * @param startIntent Intent to start a recording
     * @param stopIntent  Intent to stop a recording
     * @param start    Runnable to start a recording
     * @param stop     Runnable to stop a recording
     */
    public void startCountdown(long ms, long interval, PendingIntent startIntent,
            PendingIntent stopIntent) {
    public void startCountdown(long ms, long interval, Runnable start, Runnable stop) {
        mIsStarting = true;
        mStopIntent = stopIntent;
        mStop = stop;

        mCountDownTimer = new CountDownTimer(ms, interval) {
            @Override
@@ -220,15 +212,18 @@ public class RecordingController
                    cb.onCountdownEnd();
                }
                try {
                    startIntent.send(mInteractiveBroadcastOption);
                    start.run();
                    mUserTracker.addCallback(mUserChangedCallback, mMainExecutor);

                    IntentFilter stateFilter = new IntentFilter(INTENT_UPDATE_STATE);
                    mBroadcastDispatcher.registerReceiver(mStateChangeReceiver, stateFilter, null,
                            UserHandle.ALL);
                    mRecordingControllerLogger.logSentStartIntent();
                } catch (PendingIntent.CanceledException e) {
                    mRecordingControllerLogger.logPendingIntentCancelled(e);
                } catch (Throwable e) {
                    if (e instanceof PendingIntent.CanceledException) {
                        mRecordingControllerLogger.logPendingIntentCancelled(
                                (PendingIntent.CanceledException) e);
                    }
                }
            }
        };
@@ -275,15 +270,18 @@ public class RecordingController
    public void stopRecording(@StopReason int stopReason) {
        mStopReason = stopReason;
        try {
            if (mStopIntent != null) {
            if (mStop != null) {
                mRecordingControllerLogger.logRecordingStopped();
                mStopIntent.send(mInteractiveBroadcastOption);
                mStop.run();
            } else {
                mRecordingControllerLogger.logRecordingStopErrorNoStopIntent();
            }
            updateState(false);
        } catch (PendingIntent.CanceledException e) {
            mRecordingControllerLogger.logRecordingStopError(e);
        } catch (Throwable e) {
            if (e instanceof PendingIntent.CanceledException) {
                mRecordingControllerLogger.logRecordingStopError(
                        (PendingIntent.CanceledException) e);
            }
        }
    }

Loading