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

Commit 268c7d64 authored by Jerry Liu's avatar Jerry Liu Committed by Android (Google) Code Review
Browse files

Merge "Desktop screenshots: Add a default region box" into main

parents 611088cd de60c8fa
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -121,6 +121,7 @@ fun PreCaptureUI(viewModel: PreCaptureViewModel) {
                        contentDescription = null,
                    )
                RegionBox(
                    initialRect = viewModel.regionBox,
                    buttonText =
                        stringResource(
                            id =
+19 −3
Original line number Diff line number Diff line
@@ -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)

@@ -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,
@@ -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)

+12 −0
Original line number Diff line number Diff line
@@ -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
@@ -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,
@@ -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?,
+18 −14
Original line number Diff line number Diff line
@@ -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
@@ -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

@@ -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
@@ -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 {
@@ -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)

@@ -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)
        }
}
+2 −0
Original line number Diff line number Diff line
@@ -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
@@ -35,6 +36,7 @@ val Kosmos.preCaptureViewModelFactory by Fixture {
                displayId = displayId,
                applicationContext = applicationContext,
                backgroundScope = backgroundScope,
                windowManager = windowManager,
                iconProvider = screenCaptureIconProviderKosmos,
                screenshotInteractor = screenshotInteractor,
                featuresInteractor = largeScreenCaptureFeaturesInteractor,