diff options
5 files changed, 118 insertions, 16 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java index e93cec875429..42b35c736d42 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java @@ -191,8 +191,9 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState> @Override public boolean getDetailsViewModel(Consumer<TileDetailsViewModel> callback) { - handleClick(() -> - callback.accept(new ScreenRecordDetailsViewModel()) + handleClick(() -> executeWhenUnlockedKeyguard( + () -> callback.accept(new ScreenRecordDetailsViewModel(mController, + this::onStartRecordingClicked))) ); return true; } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/ScreenRecordDetailsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/ScreenRecordDetailsViewModel.kt index 42cb1248ccff..54e4a521c239 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/ScreenRecordDetailsViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/ScreenRecordDetailsViewModel.kt @@ -17,27 +17,45 @@ package com.android.systemui.qs.tiles.dialog import android.view.LayoutInflater +import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.heightIn import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView import com.android.systemui.plugins.qs.TileDetailsViewModel import com.android.systemui.res.R +import com.android.systemui.screenrecord.RecordingController +import com.android.systemui.screenrecord.ScreenRecordPermissionViewBinder /** The view model used for the screen record details view in the Quick Settings */ -class ScreenRecordDetailsViewModel() : TileDetailsViewModel() { +class ScreenRecordDetailsViewModel( + private val recordingController: RecordingController, + private val onStartRecordingClicked: Runnable, +) : TileDetailsViewModel() { + + private var viewBinder: ScreenRecordPermissionViewBinder = + recordingController.createScreenRecordPermissionViewBinder(onStartRecordingClicked) + @Composable override fun GetContentView() { // TODO(b/378514312): Finish implementing this function. + + if (recordingController.isScreenCaptureDisabled) { + // TODO(b/388345506): Show disabled page here. + return + } + AndroidView( - modifier = Modifier.fillMaxWidth().heightIn(max = VIEW_MAX_HEIGHT), + modifier = Modifier.fillMaxWidth().fillMaxHeight(), factory = { context -> // Inflate with the existing dialog xml layout - LayoutInflater.from(context).inflate(R.layout.screen_share_dialog, null) + val view = LayoutInflater.from(context).inflate(R.layout.screen_share_dialog, null) + viewBinder.bind(view) + + view + // TODO(b/378514473): Revamp the details view according to the spec. }, + onRelease = { viewBinder.unbind() }, ) } @@ -54,8 +72,4 @@ class ScreenRecordDetailsViewModel() : TileDetailsViewModel() { // No sub-title in this tile. return "" } - - companion object { - private val VIEW_MAX_HEIGHT: Dp = 320.dp - } } diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java index 9ee99e45ceeb..140fbf340f8b 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java @@ -70,6 +70,8 @@ public class RecordingController private final ScreenCaptureDisabledDialogDelegate mScreenCaptureDisabledDialogDelegate; private final ScreenRecordPermissionDialogDelegate.Factory mScreenRecordPermissionDialogDelegateFactory; + private final ScreenRecordPermissionViewBinder.Factory + mScreenRecordPermissionViewBinderFactory; protected static final String INTENT_UPDATE_STATE = "com.android.systemui.screenrecord.UPDATE_STATE"; @@ -118,7 +120,8 @@ public class RecordingController MediaProjectionMetricsLogger mediaProjectionMetricsLogger, ScreenCaptureDisabledDialogDelegate screenCaptureDisabledDialogDelegate, ScreenRecordPermissionDialogDelegate.Factory - screenRecordPermissionDialogDelegateFactory) { + screenRecordPermissionDialogDelegateFactory, + ScreenRecordPermissionViewBinder.Factory screenRecordPermissionViewBinderFactory) { mMainExecutor = mainExecutor; mDevicePolicyResolver = devicePolicyResolver; mBroadcastDispatcher = broadcastDispatcher; @@ -127,6 +130,7 @@ public class RecordingController mMediaProjectionMetricsLogger = mediaProjectionMetricsLogger; mScreenCaptureDisabledDialogDelegate = screenCaptureDisabledDialogDelegate; mScreenRecordPermissionDialogDelegateFactory = screenRecordPermissionDialogDelegateFactory; + mScreenRecordPermissionViewBinderFactory = screenRecordPermissionViewBinderFactory; BroadcastOptions options = BroadcastOptions.makeBasic(); options.setInteractive(true); @@ -151,8 +155,7 @@ public class RecordingController * If screen capturing is currently not allowed it will return a dialog * that warns users about it. */ public Dialog createScreenRecordDialog(@Nullable Runnable onStartRecordingClicked) { - if (mDevicePolicyResolver.get() - .isScreenCaptureCompletelyDisabled(getHostUserHandle())) { + if (isScreenCaptureDisabled()) { return mScreenCaptureDisabledDialogDelegate.createSysUIDialog(); } @@ -165,6 +168,27 @@ public class RecordingController } /** + * Create a view binder that controls the logic of views inside the screen record permission + * view. + * @param onStartRecordingClicked the callback that is run when the start button is clicked. + */ + public ScreenRecordPermissionViewBinder createScreenRecordPermissionViewBinder( + @Nullable Runnable onStartRecordingClicked + ) { + return mScreenRecordPermissionViewBinderFactory + .create(getHostUserHandle(), getHostUid(), this, + onStartRecordingClicked); + } + + /** + * Check if screen capture is currently disabled for this device and user. + */ + public boolean isScreenCaptureDisabled() { + return mDevicePolicyResolver.get() + .isScreenCaptureCompletelyDisabled(getHostUserHandle()); + } + + /** * Start counting down in preparation to start a recording * @param ms Total time in ms to wait before starting * @param interval Time in ms per countdown step diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionViewBinder.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionViewBinder.kt index 9fcb3dfc0ad3..23df1c5441bf 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionViewBinder.kt @@ -49,6 +49,9 @@ import com.android.systemui.mediaprojection.permission.ScreenShareOption import com.android.systemui.plugins.ActivityStarter import com.android.systemui.res.R import com.android.systemui.settings.UserContextProvider +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject class ScreenRecordPermissionViewBinder( private val hostUserHandle: UserHandle, @@ -68,6 +71,38 @@ class ScreenRecordPermissionViewBinder( mediaProjectionMetricsLogger, defaultSelectedMode, ) { + @AssistedInject + constructor( + @Assisted hostUserHandle: UserHandle, + @Assisted hostUid: Int, + mediaProjectionMetricsLogger: MediaProjectionMetricsLogger, + displayManager: DisplayManager, + @Assisted controller: RecordingController, + activityStarter: ActivityStarter, + userContextProvider: UserContextProvider, + @Assisted onStartRecordingClicked: Runnable?, + ) : this( + hostUserHandle, + hostUid, + mediaProjectionMetricsLogger, + defaultSelectedMode = SINGLE_APP, + displayManager, + controller, + activityStarter, + userContextProvider, + onStartRecordingClicked, + ) + + @AssistedFactory + interface Factory { + fun create( + hostUserHandle: UserHandle, + hostUid: Int, + recordingController: RecordingController, + onStartRecordingClicked: Runnable?, + ): ScreenRecordPermissionViewBinder + } + private lateinit var tapsSwitch: Switch private lateinit var audioSwitch: Switch private lateinit var tapsView: View diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java index a17f100904be..e5376d26840d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java @@ -88,8 +88,13 @@ public class RecordingControllerTest extends SysuiTestCase { private ScreenRecordPermissionDialogDelegate.Factory mScreenRecordPermissionDialogDelegateFactory; @Mock + private ScreenRecordPermissionViewBinder.Factory + mScreenRecordPermissionViewBinderFactory; + @Mock private ScreenRecordPermissionDialogDelegate mScreenRecordPermissionDialogDelegate; @Mock + private ScreenRecordPermissionViewBinder mScreenRecordPermissionViewBinder; + @Mock private SystemUIDialog mScreenRecordSystemUIDialog; private RecordingController mController; @@ -106,6 +111,8 @@ public class RecordingControllerTest extends SysuiTestCase { .thenReturn(mScreenCaptureDisabledDialog); when(mScreenRecordPermissionDialogDelegateFactory.create(any(), any(), anyInt(), any())) .thenReturn(mScreenRecordPermissionDialogDelegate); + when(mScreenRecordPermissionViewBinderFactory.create(any(), anyInt(), any(), any())) + .thenReturn(mScreenRecordPermissionViewBinder); when(mScreenRecordPermissionDialogDelegate.createDialog()) .thenReturn(mScreenRecordSystemUIDialog); mController = new RecordingController( @@ -116,7 +123,8 @@ public class RecordingControllerTest extends SysuiTestCase { new RecordingControllerLogger(logcatLogBuffer("RecordingControllerTest")), mMediaProjectionMetricsLogger, mScreenCaptureDisabledDialogDelegate, - mScreenRecordPermissionDialogDelegateFactory + mScreenRecordPermissionDialogDelegateFactory, + mScreenRecordPermissionViewBinderFactory ); mController.addCallback(mCallback); } @@ -238,6 +246,26 @@ public class RecordingControllerTest extends SysuiTestCase { } @Test + public void testCreateScreenRecordPermissionViewBinder() { + ScreenRecordPermissionViewBinder viewBinder = + mController.createScreenRecordPermissionViewBinder( + /* onStartRecordingClicked= */ null); + assertThat(viewBinder).isEqualTo(mScreenRecordPermissionViewBinder); + } + + @Test + public void testScreenCapturingAllowed_returnsFalseIsScreenCaptureDisabled() { + when(mDevicePolicyResolver.isScreenCaptureCompletelyDisabled((any()))).thenReturn(false); + assertFalse(mController.isScreenCaptureDisabled()); + } + + @Test + public void testScreenCapturingNotAllowed_returnsTrueIsScreenCaptureDisabled() { + when(mDevicePolicyResolver.isScreenCaptureCompletelyDisabled((any()))).thenReturn(true); + assertTrue(mController.isScreenCaptureDisabled()); + } + + @Test public void testScreenCapturingAllowed_logsProjectionInitiated() { when(mDevicePolicyResolver.isScreenCaptureCompletelyDisabled((any()))).thenReturn(false); |