Loading packages/SystemUI/src/com/android/systemui/screencapture/record/largescreen/ui/compose/PreCaptureUI.kt +1 −0 Original line number Diff line number Diff line Loading @@ -121,6 +121,7 @@ fun PreCaptureUI(viewModel: PreCaptureViewModel) { contentDescription = null, ) RegionBox( initialRect = viewModel.regionBox, buttonText = stringResource( id = Loading packages/SystemUI/src/com/android/systemui/screencapture/record/largescreen/ui/compose/RegionBox.kt +19 −3 Original line number Diff line number Diff line Loading @@ -163,9 +163,24 @@ private fun getResizeZone( * * @param minSizePx The minimum size of the box in pixels. * @param density The density of the screen. Used for the conversions between pixels and Dp. * @param initialRect The initial rectangle of the box. */ class RegionBoxState(private val minSizePx: Float, private val density: Density) { var rect by mutableStateOf<Rect?>(null) class RegionBoxState( private val minSizePx: Float, private val density: Density, initialRect: IntRect? = null, ) { var rect by mutableStateOf<Rect?>( initialRect?.let { Rect( left = it.left.toFloat(), top = it.top.toFloat(), right = it.right.toFloat(), bottom = it.bottom.toFloat(), ) } ) var dragMode by mutableStateOf(DragMode.NONE) Loading Loading @@ -368,6 +383,7 @@ class RegionBoxState(private val minSizePx: Float, private val density: Density) */ @Composable fun RegionBox( initialRect: IntRect?, buttonText: String, buttonIcon: Icon?, onRegionSelected: (rect: IntRect) -> Unit, Loading @@ -381,7 +397,7 @@ fun RegionBox( val minSize = 48.dp val minSizePx = remember(density) { with(density) { minSize.toPx() } } val state = remember { RegionBoxState(minSizePx, density) } val state = remember { RegionBoxState(minSizePx, density, initialRect) } val scrimColor = ScreenCaptureColors.scrimColor val pointerIcon = rememberPointerIcon(state) Loading packages/SystemUI/src/com/android/systemui/screencapture/record/largescreen/ui/viewmodel/PreCaptureViewModel.kt +12 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.systemui.screencapture.record.largescreen.ui.viewmodel import android.content.Context import android.graphics.Rect import android.view.WindowManager import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.lifecycle.HydratedActivatable Loading Loading @@ -52,6 +53,7 @@ constructor( @Assisted private val displayId: Int, @Application private val applicationContext: Context, @Background private val backgroundScope: CoroutineScope, private val windowManager: WindowManager, private val iconProvider: ScreenCaptureIconProvider, private val screenshotInteractor: ScreenshotInteractor, private val featuresInteractor: LargeScreenCaptureFeaturesInteractor, Loading Loading @@ -252,9 +254,19 @@ constructor( coroutineScope { launch { iconProvider.collectIcons() } launch { screenCaptureRecordParametersViewModel.activate() } launch { initializeRegionBox() } } } private fun initializeRegionBox() { if (regionBoxSource.value != null) { return } val bounds = windowManager.currentWindowMetrics.bounds regionBoxSource.value = Rect(bounds).apply { inset(bounds.width() / 4, bounds.height() / 4) } } private fun generateCaptureTypeButtonViewModels( selectedType: ScreenCaptureType, icons: ScreenCaptureIcons?, Loading packages/SystemUI/tests/src/com/android/systemui/screencapture/record/largescreen/ui/viewmodel/PreCaptureViewModelTest.kt +18 −14 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ import android.graphics.Rect import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import android.view.WindowManager import android.view.WindowMetrics import android.view.windowManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.util.ScreenshotRequest Loading Loading @@ -68,6 +70,8 @@ class PreCaptureViewModelTest : SysuiTestCase() { @Mock private lateinit var mockScreenRecordingServiceInteractor: ScreenRecordingServiceInteractor @Mock private lateinit var mockBitmap: Bitmap @Mock private lateinit var mockWindowMetrics: WindowMetrics private val screenBounds = Rect(0, 0, 100, 100) private val displayId = 1234 private lateinit var viewModel: PreCaptureViewModel Loading @@ -83,6 +87,8 @@ class PreCaptureViewModelTest : SysuiTestCase() { @Before fun setUp() { MockitoAnnotations.openMocks(this) whenever(kosmos.windowManager.currentWindowMetrics).thenReturn(mockWindowMetrics) whenever(mockWindowMetrics.bounds).thenReturn(screenBounds) } @Test Loading @@ -93,6 +99,18 @@ class PreCaptureViewModelTest : SysuiTestCase() { assertThat(viewModel.isShowingUi).isTrue() } @Test fun onActivated_initializesRegionBox() = kosmos.runTest { setupViewModel() val bounds = Rect(0, 0, 100, 100) val expectedRegionBox = Rect(bounds) expectedRegionBox.inset(bounds.width() / 4, bounds.height() / 4) // For a 100x100 screen, the expected inset rect is (25, 25, 75, 75). assertThat(viewModel.regionBox).isEqualTo(expectedRegionBox) } @Test fun captureType_defaultsToScreenshot() = kosmos.runTest { Loading Loading @@ -217,9 +235,6 @@ class PreCaptureViewModelTest : SysuiTestCase() { kosmos.runTest { setupViewModel() // State is initially null. assertThat(viewModel.regionBox).isNull() val regionBox = Rect(0, 0, 100, 100) viewModel.updateRegionBoxBounds(regionBox) Loading Loading @@ -436,15 +451,4 @@ class PreCaptureViewModelTest : SysuiTestCase() { assertThat(viewModel.toolbarOpacity).isEqualTo(0.15f) } @Test fun updateToolbarOpacityForRegionBox_notInteracting_noRegion_opacityIsOne() = kosmos.runTest { setupViewModel() viewModel.updateToolbarBounds(Rect(0, 0, 100, 100)) viewModel.updateToolbarOpacityForRegionBox(isInteracting = false) assertThat(viewModel.toolbarOpacity).isEqualTo(1f) } } packages/SystemUI/tests/utils/src/com/android/systemui/screencapture/record/largescreen/ui/viewmodel/PreCaptureViewModelKosmos.kt +2 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.systemui.screencapture.record.largescreen.ui.viewmodel import android.content.applicationContext import android.view.windowManager import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture import com.android.systemui.kosmos.backgroundScope Loading @@ -35,6 +36,7 @@ val Kosmos.preCaptureViewModelFactory by Fixture { displayId = displayId, applicationContext = applicationContext, backgroundScope = backgroundScope, windowManager = windowManager, iconProvider = screenCaptureIconProviderKosmos, screenshotInteractor = screenshotInteractor, featuresInteractor = largeScreenCaptureFeaturesInteractor, Loading Loading
packages/SystemUI/src/com/android/systemui/screencapture/record/largescreen/ui/compose/PreCaptureUI.kt +1 −0 Original line number Diff line number Diff line Loading @@ -121,6 +121,7 @@ fun PreCaptureUI(viewModel: PreCaptureViewModel) { contentDescription = null, ) RegionBox( initialRect = viewModel.regionBox, buttonText = stringResource( id = Loading
packages/SystemUI/src/com/android/systemui/screencapture/record/largescreen/ui/compose/RegionBox.kt +19 −3 Original line number Diff line number Diff line Loading @@ -163,9 +163,24 @@ private fun getResizeZone( * * @param minSizePx The minimum size of the box in pixels. * @param density The density of the screen. Used for the conversions between pixels and Dp. * @param initialRect The initial rectangle of the box. */ class RegionBoxState(private val minSizePx: Float, private val density: Density) { var rect by mutableStateOf<Rect?>(null) class RegionBoxState( private val minSizePx: Float, private val density: Density, initialRect: IntRect? = null, ) { var rect by mutableStateOf<Rect?>( initialRect?.let { Rect( left = it.left.toFloat(), top = it.top.toFloat(), right = it.right.toFloat(), bottom = it.bottom.toFloat(), ) } ) var dragMode by mutableStateOf(DragMode.NONE) Loading Loading @@ -368,6 +383,7 @@ class RegionBoxState(private val minSizePx: Float, private val density: Density) */ @Composable fun RegionBox( initialRect: IntRect?, buttonText: String, buttonIcon: Icon?, onRegionSelected: (rect: IntRect) -> Unit, Loading @@ -381,7 +397,7 @@ fun RegionBox( val minSize = 48.dp val minSizePx = remember(density) { with(density) { minSize.toPx() } } val state = remember { RegionBoxState(minSizePx, density) } val state = remember { RegionBoxState(minSizePx, density, initialRect) } val scrimColor = ScreenCaptureColors.scrimColor val pointerIcon = rememberPointerIcon(state) Loading
packages/SystemUI/src/com/android/systemui/screencapture/record/largescreen/ui/viewmodel/PreCaptureViewModel.kt +12 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.systemui.screencapture.record.largescreen.ui.viewmodel import android.content.Context import android.graphics.Rect import android.view.WindowManager import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.lifecycle.HydratedActivatable Loading Loading @@ -52,6 +53,7 @@ constructor( @Assisted private val displayId: Int, @Application private val applicationContext: Context, @Background private val backgroundScope: CoroutineScope, private val windowManager: WindowManager, private val iconProvider: ScreenCaptureIconProvider, private val screenshotInteractor: ScreenshotInteractor, private val featuresInteractor: LargeScreenCaptureFeaturesInteractor, Loading Loading @@ -252,9 +254,19 @@ constructor( coroutineScope { launch { iconProvider.collectIcons() } launch { screenCaptureRecordParametersViewModel.activate() } launch { initializeRegionBox() } } } private fun initializeRegionBox() { if (regionBoxSource.value != null) { return } val bounds = windowManager.currentWindowMetrics.bounds regionBoxSource.value = Rect(bounds).apply { inset(bounds.width() / 4, bounds.height() / 4) } } private fun generateCaptureTypeButtonViewModels( selectedType: ScreenCaptureType, icons: ScreenCaptureIcons?, Loading
packages/SystemUI/tests/src/com/android/systemui/screencapture/record/largescreen/ui/viewmodel/PreCaptureViewModelTest.kt +18 −14 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ import android.graphics.Rect import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import android.view.WindowManager import android.view.WindowMetrics import android.view.windowManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.util.ScreenshotRequest Loading Loading @@ -68,6 +70,8 @@ class PreCaptureViewModelTest : SysuiTestCase() { @Mock private lateinit var mockScreenRecordingServiceInteractor: ScreenRecordingServiceInteractor @Mock private lateinit var mockBitmap: Bitmap @Mock private lateinit var mockWindowMetrics: WindowMetrics private val screenBounds = Rect(0, 0, 100, 100) private val displayId = 1234 private lateinit var viewModel: PreCaptureViewModel Loading @@ -83,6 +87,8 @@ class PreCaptureViewModelTest : SysuiTestCase() { @Before fun setUp() { MockitoAnnotations.openMocks(this) whenever(kosmos.windowManager.currentWindowMetrics).thenReturn(mockWindowMetrics) whenever(mockWindowMetrics.bounds).thenReturn(screenBounds) } @Test Loading @@ -93,6 +99,18 @@ class PreCaptureViewModelTest : SysuiTestCase() { assertThat(viewModel.isShowingUi).isTrue() } @Test fun onActivated_initializesRegionBox() = kosmos.runTest { setupViewModel() val bounds = Rect(0, 0, 100, 100) val expectedRegionBox = Rect(bounds) expectedRegionBox.inset(bounds.width() / 4, bounds.height() / 4) // For a 100x100 screen, the expected inset rect is (25, 25, 75, 75). assertThat(viewModel.regionBox).isEqualTo(expectedRegionBox) } @Test fun captureType_defaultsToScreenshot() = kosmos.runTest { Loading Loading @@ -217,9 +235,6 @@ class PreCaptureViewModelTest : SysuiTestCase() { kosmos.runTest { setupViewModel() // State is initially null. assertThat(viewModel.regionBox).isNull() val regionBox = Rect(0, 0, 100, 100) viewModel.updateRegionBoxBounds(regionBox) Loading Loading @@ -436,15 +451,4 @@ class PreCaptureViewModelTest : SysuiTestCase() { assertThat(viewModel.toolbarOpacity).isEqualTo(0.15f) } @Test fun updateToolbarOpacityForRegionBox_notInteracting_noRegion_opacityIsOne() = kosmos.runTest { setupViewModel() viewModel.updateToolbarBounds(Rect(0, 0, 100, 100)) viewModel.updateToolbarOpacityForRegionBox(isInteracting = false) assertThat(viewModel.toolbarOpacity).isEqualTo(1f) } }
packages/SystemUI/tests/utils/src/com/android/systemui/screencapture/record/largescreen/ui/viewmodel/PreCaptureViewModelKosmos.kt +2 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.systemui.screencapture.record.largescreen.ui.viewmodel import android.content.applicationContext import android.view.windowManager import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture import com.android.systemui.kosmos.backgroundScope Loading @@ -35,6 +36,7 @@ val Kosmos.preCaptureViewModelFactory by Fixture { displayId = displayId, applicationContext = applicationContext, backgroundScope = backgroundScope, windowManager = windowManager, iconProvider = screenCaptureIconProviderKosmos, screenshotInteractor = screenshotInteractor, featuresInteractor = largeScreenCaptureFeaturesInteractor, Loading