From f5e6c63c3d64885636ad1cb728419c3c3af1157e Mon Sep 17 00:00:00 2001 From: Trevor McGuire Date: Mon, 16 Sep 2024 17:12:54 -0700 Subject: [PATCH] Make CaptureModeToggleButton more testable Adds test tag to CaptureModeToggleButton Adds state descriptions to ToggleButton Removes unnecessary coroutine scope from ToggleButton --- .../preview/ui/CameraControlsOverlay.kt | 22 +++++++---- .../preview/ui/PreviewScreenComponents.kt | 39 +++++++++++-------- .../feature/preview/ui/TestTags.kt | 1 + .../preview/src/main/res/values/strings.xml | 4 ++ 4 files changed, 41 insertions(+), 25 deletions(-) diff --git a/feature/preview/src/main/java/com/google/jetpackcamera/feature/preview/ui/CameraControlsOverlay.kt b/feature/preview/src/main/java/com/google/jetpackcamera/feature/preview/ui/CameraControlsOverlay.kt index 3631b360..91d817eb 100644 --- a/feature/preview/src/main/java/com/google/jetpackcamera/feature/preview/ui/CameraControlsOverlay.kt +++ b/feature/preview/src/main/java/com/google/jetpackcamera/feature/preview/ui/CameraControlsOverlay.kt @@ -15,7 +15,6 @@ */ package com.google.jetpackcamera.feature.preview.ui -import android.annotation.SuppressLint import android.content.ContentResolver import android.net.Uri import androidx.compose.foundation.layout.Arrangement @@ -47,15 +46,16 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.rememberVectorPainter import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.testTag +import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import androidx.core.util.Preconditions import com.google.jetpackcamera.feature.preview.CaptureModeToggleUiState import com.google.jetpackcamera.feature.preview.MultipleEventsCutter import com.google.jetpackcamera.feature.preview.PreviewMode import com.google.jetpackcamera.feature.preview.PreviewUiState import com.google.jetpackcamera.feature.preview.PreviewViewModel +import com.google.jetpackcamera.feature.preview.R import com.google.jetpackcamera.feature.preview.VideoRecordingState import com.google.jetpackcamera.feature.preview.quicksettings.ui.QuickSettingsIndicators import com.google.jetpackcamera.feature.preview.quicksettings.ui.ToggleQuickSettingsButton @@ -292,7 +292,8 @@ private fun ControlsBottom( CaptureModeToggleButton( uiState = previewUiState.captureModeToggleUiState, onChangeImageFormat = onChangeImageFormat, - onToggleWhenDisabled = onToggleWhenDisabled + onToggleWhenDisabled = onToggleWhenDisabled, + modifier = Modifier.testTag(CAPTURE_MODE_TOGGLE_BUTTON) ) } } @@ -390,12 +391,12 @@ private fun CaptureButton( ) } -@SuppressLint("RestrictedApi") @Composable private fun CaptureModeToggleButton( uiState: CaptureModeToggleUiState.Visible, onChangeImageFormat: (ImageOutputFormat) -> Unit, - onToggleWhenDisabled: (CaptureModeToggleUiState.DisabledReason) -> Unit + onToggleWhenDisabled: (CaptureModeToggleUiState.DisabledReason) -> Unit, + modifier: Modifier = Modifier ) { // Captures hdr image (left) when output format is UltraHdr, else captures hdr video (right). val initialState = @@ -427,10 +428,15 @@ private fun CaptureModeToggleButton( onChangeImageFormat(imageFormat) }, onToggleWhenDisabled = { - Preconditions.checkArgument(uiState is CaptureModeToggleUiState.Disabled) - onToggleWhenDisabled((uiState as CaptureModeToggleUiState.Disabled).disabledReason) + check(uiState is CaptureModeToggleUiState.Disabled) + onToggleWhenDisabled(uiState.disabledReason) }, - enabled = uiState is CaptureModeToggleUiState.Enabled + enabled = uiState is CaptureModeToggleUiState.Enabled, + leftIconDescription = + stringResource(id = R.string.capture_mode_image_capture_content_description), + rightIconDescription = + stringResource(id = R.string.capture_mode_video_recording_content_description), + modifier = modifier ) } diff --git a/feature/preview/src/main/java/com/google/jetpackcamera/feature/preview/ui/PreviewScreenComponents.kt b/feature/preview/src/main/java/com/google/jetpackcamera/feature/preview/ui/PreviewScreenComponents.kt index f5d8139b..8382af48 100644 --- a/feature/preview/src/main/java/com/google/jetpackcamera/feature/preview/ui/PreviewScreenComponents.kt +++ b/feature/preview/src/main/java/com/google/jetpackcamera/feature/preview/ui/PreviewScreenComponents.kt @@ -75,7 +75,6 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshotFlow @@ -91,6 +90,9 @@ import androidx.compose.ui.layout.layout import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.Role +import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.semantics.stateDescription import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp @@ -106,7 +108,6 @@ import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onCompletion -import kotlinx.coroutines.launch private const val TAG = "PreviewScreen" private const val BLINK_TIME = 100L @@ -583,9 +584,7 @@ enum class ToggleState { fun ToggleButton( leftIcon: Painter, rightIcon: Painter, - modifier: Modifier = Modifier - .width(64.dp) - .height(32.dp), + modifier: Modifier = Modifier, initialState: ToggleState = ToggleState.Left, onToggleStateChanged: (newState: ToggleState) -> Unit = {}, onToggleWhenDisabled: () -> Unit = {}, @@ -608,26 +607,32 @@ fun ToggleButton( }, label = "togglePosition" ) - val scope = rememberCoroutineScope() Surface( modifier = modifier .clip(shape = RoundedCornerShape(50)) .then( - Modifier.clickable { - scope.launch { - if (enabled) { - toggleState = when (toggleState) { - ToggleState.Left -> ToggleState.Right - ToggleState.Right -> ToggleState.Left - } - onToggleStateChanged(toggleState) - } else { - onToggleWhenDisabled() + Modifier.clickable( + role = Role.Switch + ) { + if (enabled) { + toggleState = when (toggleState) { + ToggleState.Left -> ToggleState.Right + ToggleState.Right -> ToggleState.Left } + onToggleStateChanged(toggleState) + } else { + onToggleWhenDisabled() } } - ), + ).semantics { + stateDescription = when (toggleState) { + ToggleState.Left -> leftIconDescription + ToggleState.Right -> rightIconDescription + } + } + .width(64.dp) + .height(32.dp), color = backgroundColor ) { Box { diff --git a/feature/preview/src/main/java/com/google/jetpackcamera/feature/preview/ui/TestTags.kt b/feature/preview/src/main/java/com/google/jetpackcamera/feature/preview/ui/TestTags.kt index 077a971f..dcea4ec6 100644 --- a/feature/preview/src/main/java/com/google/jetpackcamera/feature/preview/ui/TestTags.kt +++ b/feature/preview/src/main/java/com/google/jetpackcamera/feature/preview/ui/TestTags.kt @@ -16,6 +16,7 @@ package com.google.jetpackcamera.feature.preview.ui const val CAPTURE_BUTTON = "CaptureButton" +const val CAPTURE_MODE_TOGGLE_BUTTON = "CaptureModeToggleButton" const val FLIP_CAMERA_BUTTON = "FlipCameraButton" const val IMAGE_CAPTURE_SUCCESS_TAG = "ImageCaptureSuccessTag" const val IMAGE_CAPTURE_FAILURE_TAG = "ImageCaptureFailureTag" diff --git a/feature/preview/src/main/res/values/strings.xml b/feature/preview/src/main/res/values/strings.xml index 77d80e03..10b96b84 100644 --- a/feature/preview/src/main/res/values/strings.xml +++ b/feature/preview/src/main/res/values/strings.xml @@ -16,6 +16,10 @@ --> Camera Loading… + + Image capture mode + Video recording mode + Settings Flip Camera