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

Commit 419a09af authored by Anton Potapov's avatar Anton Potapov
Browse files

Implement the new Screen Recording toolbar.

Flag: com.android.systemui.new_screen_record_toolbar
Test: manual on foldable
Bug: 428686600
Change-Id: If8400b0c43af181c835c9c62d7f174dc92826f76
parent 7d3a2f38
Loading
Loading
Loading
Loading
+8 −5
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.systemui.screencapture.common


import com.android.systemui.screencapture.common.shared.model.ScreenCaptureActivityIntentParameters
import com.android.systemui.screencapture.common.shared.model.ScreenCaptureActivityIntentParameters
import com.android.systemui.screencapture.common.ui.compose.ScreenCaptureContent
import com.android.systemui.screencapture.common.ui.compose.ScreenCaptureContent
import com.android.systemui.screencapture.ui.ScreenCaptureActivity
import dagger.BindsInstance
import dagger.BindsInstance
import dagger.Subcomponent
import dagger.Subcomponent
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineScope
@@ -32,6 +33,8 @@ import kotlinx.coroutines.CoroutineScope
@Subcomponent(modules = [CommonModule::class, FallbackModule::class])
@Subcomponent(modules = [CommonModule::class, FallbackModule::class])
interface ScreenCaptureComponent {
interface ScreenCaptureComponent {


    val screenCaptureContent: ScreenCaptureContent

    /**
    /**
     * Dagger Subcomponent Builder for [ScreenCaptureComponent].
     * Dagger Subcomponent Builder for [ScreenCaptureComponent].
     *
     *
@@ -42,12 +45,14 @@ interface ScreenCaptureComponent {
    interface Builder {
    interface Builder {


        /** The [CoroutineScope] to use coroutines limited to Screen Capture sessions. */
        /** The [CoroutineScope] to use coroutines limited to Screen Capture sessions. */
        @BindsInstance @ScreenCapture fun setScope(scope: CoroutineScope): Builder
        @BindsInstance fun setScope(@ScreenCapture scope: CoroutineScope): Builder


        /** [ScreenCaptureActivityIntentParameters] that has been used to start capture flow. */
        /** [ScreenCaptureActivityIntentParameters] that has been used to start capture flow. */
        @BindsInstance
        @BindsInstance
        @ScreenCapture
        fun setParameters(@ScreenCapture parameters: ScreenCaptureActivityIntentParameters): Builder
        fun setParameters(parameters: ScreenCaptureActivityIntentParameters): Builder

        @BindsInstance
        fun setScreenCaptureActivity(@ScreenCapture activity: ScreenCaptureActivity): Builder


        /**
        /**
         * Builds this [ScreenCaptureComponent]. Actual Subcomponent Builders should override this
         * Builds this [ScreenCaptureComponent]. Actual Subcomponent Builders should override this
@@ -55,6 +60,4 @@ interface ScreenCaptureComponent {
         */
         */
        fun build(): ScreenCaptureComponent
        fun build(): ScreenCaptureComponent
    }
    }

    val screenCaptureContent: ScreenCaptureContent
}
}
+11 −4
Original line number Original line Diff line number Diff line
@@ -16,16 +16,21 @@


package com.android.systemui.screencapture.common.ui.compose
package com.android.systemui.screencapture.common.ui.compose


import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Text
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.dp
import com.android.compose.PlatformButton
import com.android.compose.PlatformButton
import com.android.systemui.common.shared.model.Icon as IconModel
import com.android.systemui.common.shared.model.Icon as IconModel
import com.android.systemui.common.ui.compose.Icon
import com.android.systemui.common.ui.compose.Icon


private val ButtonPaddings = PaddingValues(horizontal = 16.dp, vertical = 8.dp)

/** Component for a primary button containing text and an optional leading icon. */
/** Component for a primary button containing text and an optional leading icon. */
@Composable
@Composable
fun PrimaryButton(
fun PrimaryButton(
@@ -33,12 +38,14 @@ fun PrimaryButton(
    onClick: () -> Unit,
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    modifier: Modifier = Modifier,
    icon: IconModel? = null,
    icon: IconModel? = null,
    contentPadding: PaddingValues = ButtonPaddings,
    iconPadding: Dp = 5.dp,
) {
) {
    PlatformButton(modifier = modifier, onClick = onClick) {
    PlatformButton(onClick = onClick, modifier = modifier, contentPadding = contentPadding) {
        if (icon != null) {
        if (icon != null) {
            Icon(icon = icon, modifier = Modifier.size(20.dp))
            Icon(icon = icon, modifier = Modifier.size(20.dp).align(Alignment.CenterVertically))
            Spacer(Modifier.size(5.dp))
            Spacer(Modifier.size(iconPadding))
        }
        }
        Text(text = text, maxLines = 1)
        Text(text = text, maxLines = 1, modifier = Modifier.align(Alignment.CenterVertically))
    }
    }
}
}
+7 −1
Original line number Original line Diff line number Diff line
@@ -29,6 +29,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.zIndex
import androidx.compose.ui.zIndex
import com.android.systemui.res.R
import com.android.systemui.res.R
import com.android.systemui.screencapture.common.ui.compose.PrimaryButton
import com.android.systemui.screencapture.common.ui.compose.PrimaryButton
import com.android.systemui.screencapture.common.ui.compose.loadIcon
import com.android.systemui.screencapture.record.largescreen.ui.viewmodel.PreCaptureViewModel
import com.android.systemui.screencapture.record.largescreen.ui.viewmodel.PreCaptureViewModel
import com.android.systemui.screencapture.record.largescreen.ui.viewmodel.ScreenCaptureRegion
import com.android.systemui.screencapture.record.largescreen.ui.viewmodel.ScreenCaptureRegion


@@ -58,7 +59,12 @@ fun PreCaptureUI(viewModel: PreCaptureViewModel) {
                    modifier = Modifier.fillMaxSize().wrapContentSize(Alignment.Center).zIndex(0f)
                    modifier = Modifier.fillMaxSize().wrapContentSize(Alignment.Center).zIndex(0f)
                ) {
                ) {
                    PrimaryButton(
                    PrimaryButton(
                        icon = viewModel.icons?.screenshotButton,
                        icon =
                            loadIcon(
                                viewModel = viewModel,
                                resId = R.drawable.ic_screen_capture_camera,
                                contentDescription = null,
                            ),
                        text = stringResource(R.string.screen_capture_fullscreen_screenshot_button),
                        text = stringResource(R.string.screen_capture_fullscreen_screenshot_button),
                        onClick = { viewModel.takeFullscreenScreenshot() },
                        onClick = { viewModel.takeFullscreenScreenshot() },
                    )
                    )
+11 −7
Original line number Original line Diff line number Diff line
@@ -39,9 +39,10 @@ import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.dp
import com.android.systemui.common.shared.model.Icon as IconModel
import com.android.systemui.res.R
import com.android.systemui.res.R
import com.android.systemui.screencapture.common.ui.compose.PrimaryButton
import com.android.systemui.screencapture.common.ui.compose.PrimaryButton
import com.android.systemui.screencapture.common.ui.compose.loadIcon
import com.android.systemui.screencapture.common.ui.viewmodel.DrawableLoaderViewModel


/**
/**
 * Determines which zone (corner or edge) of a box is being touched based on the press offset.
 * Determines which zone (corner or edge) of a box is being touched based on the press offset.
@@ -96,6 +97,7 @@ fun RegionBox(
    initialWidth: Dp,
    initialWidth: Dp,
    initialHeight: Dp,
    initialHeight: Dp,
    onDragEnd: (offset: Offset, width: Dp, height: Dp) -> Unit,
    onDragEnd: (offset: Offset, width: Dp, height: Dp) -> Unit,
    drawableLoaderViewModel: DrawableLoaderViewModel,
    initialOffset: Offset = Offset.Zero,
    initialOffset: Offset = Offset.Zero,
    modifier: Modifier = Modifier,
    modifier: Modifier = Modifier,
) {
) {
@@ -143,6 +145,7 @@ fun RegionBox(
                with(density) { rect.height.toDp() },
                with(density) { rect.height.toDp() },
            )
            )
        },
        },
        drawableLoaderViewModel = drawableLoaderViewModel,
        modifier = modifier,
        modifier = modifier,
    )
    )
}
}
@@ -163,13 +166,9 @@ private fun ResizableRectangle(
    onResizeDrag: (dragAmount: Offset, zone: ResizeZone, maxWidth: Float, maxHeight: Float) -> Unit,
    onResizeDrag: (dragAmount: Offset, zone: ResizeZone, maxWidth: Float, maxHeight: Float) -> Unit,
    onBoxDrag: (dragAmount: Offset, maxWidth: Float, maxHeight: Float) -> Unit,
    onBoxDrag: (dragAmount: Offset, maxWidth: Float, maxHeight: Float) -> Unit,
    onDragEnd: () -> Unit,
    onDragEnd: () -> Unit,
    drawableLoaderViewModel: DrawableLoaderViewModel,
    modifier: Modifier = Modifier,
    modifier: Modifier = Modifier,
) {
) {
    // TODO(b/422855266): Preload icons in the view model to avoid loading icons in UI thread and
    // improve performance
    val screenshotIcon =
        IconModel.Resource(res = R.drawable.ic_screen_capture_camera, contentDescription = null)

    // The width of the border stroke around the region box.
    // The width of the border stroke around the region box.
    val borderStrokeWidth = 4.dp
    val borderStrokeWidth = 4.dp
    // The touch area for detecting an edge or corner resize drag.
    // The touch area for detecting an edge or corner resize drag.
@@ -245,7 +244,12 @@ private fun ResizableRectangle(
                onClick = {
                onClick = {
                    // TODO(b/417534202): trigger a screenshot of the selected area.
                    // TODO(b/417534202): trigger a screenshot of the selected area.
                },
                },
                icon = screenshotIcon,
                icon =
                    loadIcon(
                        viewModel = drawableLoaderViewModel,
                        resId = R.drawable.ic_screen_capture_camera,
                        contentDescription = null,
                    ),
            )
            )
        }
        }
    }
    }
+4 −1
Original line number Original line Diff line number Diff line
@@ -21,6 +21,8 @@ import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.lifecycle.HydratedActivatable
import com.android.systemui.lifecycle.HydratedActivatable
import com.android.systemui.res.R
import com.android.systemui.res.R
import com.android.systemui.screencapture.common.ui.viewmodel.DrawableLoaderViewModel
import com.android.systemui.screencapture.common.ui.viewmodel.DrawableLoaderViewModelImpl
import com.android.systemui.screencapture.record.largescreen.domain.interactor.ScreenCaptureRecordLargeScreenFeaturesInteractor
import com.android.systemui.screencapture.record.largescreen.domain.interactor.ScreenCaptureRecordLargeScreenFeaturesInteractor
import com.android.systemui.screencapture.record.largescreen.domain.interactor.ScreenshotInteractor
import com.android.systemui.screencapture.record.largescreen.domain.interactor.ScreenshotInteractor
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedFactory
@@ -51,7 +53,8 @@ constructor(
    private val iconProvider: ScreenCaptureIconProvider,
    private val iconProvider: ScreenCaptureIconProvider,
    private val screenshotInteractor: ScreenshotInteractor,
    private val screenshotInteractor: ScreenshotInteractor,
    private val featuresInteractor: ScreenCaptureRecordLargeScreenFeaturesInteractor,
    private val featuresInteractor: ScreenCaptureRecordLargeScreenFeaturesInteractor,
) : HydratedActivatable() {
    private val drawableLoaderViewModelImpl: DrawableLoaderViewModelImpl,
) : HydratedActivatable(), DrawableLoaderViewModel by drawableLoaderViewModelImpl {
    private val captureTypeSource = MutableStateFlow(ScreenCaptureType.SCREENSHOT)
    private val captureTypeSource = MutableStateFlow(ScreenCaptureType.SCREENSHOT)
    private val captureRegionSource = MutableStateFlow(ScreenCaptureRegion.FULLSCREEN)
    private val captureRegionSource = MutableStateFlow(ScreenCaptureRegion.FULLSCREEN)


Loading