summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Andre Le <leandre@google.com> 2025-01-08 22:40:12 +0000
committer Andre Le <leandre@google.com> 2025-01-14 21:54:18 +0000
commit016dce89e5774bfe8a8a54ed5cec154346d6db1c (patch)
treea2ff70ca86104fe75b3d72759359258fde272675
parentc84a0332517e30fc9fd364e4b7a3fa94faa4a2cd (diff)
QSDetailedView: Add view binder to ScreenRecordDetailsViewModel
Add an instance of ScreenRecordPermissionViewBinder and RecordingController to ScreenRecordDetailsViewModel to control the logic within the UI of screen record details view. With CL, we can complete the full flow of start screen recording with any configurations within the screen record details view. Bug: b/378514312 Flag: com.android.systemui.qs_tile_detailed_view Test: ScreenRecordTileTest, ScreenRecordPermissionDialogDelegateTest Test: Click on screen record tile in the QS -> can start do screen recording within the details view. Change-Id: Ifc64cfed4243e885694c0e99edc5f7ab898ce464
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/ScreenRecordDetailsViewModel.kt34
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java30
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionViewBinder.kt35
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java30
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);