From d4b104e13f6b1355aaa07ea071b8af5b83538315 Mon Sep 17 00:00:00 2001 From: temcguir Date: Tue, 18 Aug 2026 05:07:28 +0000 Subject: [PATCH 1/5] Update Capture Button visuals --- .gemini/styleguide.md | 6 + .../core/camera/utils/OpenGLTestUtil.kt | 1 + .../feature/preview/PreviewScreen.kt | 2 + gradle.properties | 1 + gradle/libs.versions.toml | 7 + ui/components/capture/build.gradle.kts | 15 + .../components/capture/CaptureButtonTest.kt | 189 ++++++ .../capture/CaptureButtonComponents.kt | 625 ++++++++++++------ .../capture/src/main/res/values/strings.xml | 8 + .../capture/CaptureButtonScreenshotTest.kt | 236 +++++++ ...aptureButtonBlack60ScreenshotPreview_0.png | Bin 0 -> 7341 bytes ...dImageCaptureButtonScreenshotPreview_0.png | Bin 0 -> 7465 bytes ...aptureButtonBlack60ScreenshotPreview_0.png | Bin 0 -> 7070 bytes ...andardCaptureButtonScreenshotPreview_0.png | Bin 0 -> 7347 bytes ...aptureButtonBlack60ScreenshotPreview_0.png | Bin 0 -> 6707 bytes ...eoOnlyCaptureButtonScreenshotPreview_0.png | Bin 0 -> 6778 bytes ...aptureButtonBlack60ScreenshotPreview_0.png | Bin 0 -> 7871 bytes ...eImageCaptureButtonScreenshotPreview_0.png | Bin 0 -> 7668 bytes ...aptureButtonBlack60ScreenshotPreview_0.png | Bin 0 -> 8118 bytes ...andardCaptureButtonScreenshotPreview_0.png | Bin 0 -> 7894 bytes ...aptureButtonBlack60ScreenshotPreview_0.png | Bin 0 -> 7108 bytes ...eoOnlyCaptureButtonScreenshotPreview_0.png | Bin 0 -> 6896 bytes ...kedRecordingBlack60ScreenshotPreview_0.png | Bin 0 -> 6221 bytes .../LockedRecordingScreenshotPreview_0.png | Bin 0 -> 6102 bytes ...aptureButtonBlack60ScreenshotPreview_0.png | Bin 0 -> 7859 bytes ...dImageCaptureButtonScreenshotPreview_0.png | Bin 0 -> 7654 bytes ...sedRecordingBlack60ScreenshotPreview_0.png | Bin 0 -> 10410 bytes .../PressedRecordingScreenshotPreview_0.png | Bin 0 -> 10529 bytes ...aptureButtonBlack60ScreenshotPreview_0.png | Bin 0 -> 5254 bytes ...andardCaptureButtonScreenshotPreview_0.png | Bin 0 -> 5195 bytes 30 files changed, 879 insertions(+), 211 deletions(-) create mode 100644 ui/components/capture/src/androidTest/java/com/google/jetpackcamera/ui/components/capture/CaptureButtonTest.kt create mode 100644 ui/components/capture/src/screenshotTest/kotlin/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTest.kt create mode 100644 ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/DisabledImageCaptureButtonBlack60ScreenshotPreview_0.png create mode 100644 ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/DisabledImageCaptureButtonScreenshotPreview_0.png create mode 100644 ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/DisabledStandardCaptureButtonBlack60ScreenshotPreview_0.png create mode 100644 ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/DisabledStandardCaptureButtonScreenshotPreview_0.png create mode 100644 ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/DisabledVideoOnlyCaptureButtonBlack60ScreenshotPreview_0.png create mode 100644 ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/DisabledVideoOnlyCaptureButtonScreenshotPreview_0.png create mode 100644 ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/IdleImageCaptureButtonBlack60ScreenshotPreview_0.png create mode 100644 ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/IdleImageCaptureButtonScreenshotPreview_0.png create mode 100644 ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/IdleStandardCaptureButtonBlack60ScreenshotPreview_0.png create mode 100644 ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/IdleStandardCaptureButtonScreenshotPreview_0.png create mode 100644 ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/IdleVideoOnlyCaptureButtonBlack60ScreenshotPreview_0.png create mode 100644 ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/IdleVideoOnlyCaptureButtonScreenshotPreview_0.png create mode 100644 ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/LockedRecordingBlack60ScreenshotPreview_0.png create mode 100644 ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/LockedRecordingScreenshotPreview_0.png create mode 100644 ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/PressedImageCaptureButtonBlack60ScreenshotPreview_0.png create mode 100644 ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/PressedImageCaptureButtonScreenshotPreview_0.png create mode 100644 ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/PressedRecordingBlack60ScreenshotPreview_0.png create mode 100644 ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/PressedRecordingScreenshotPreview_0.png create mode 100644 ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/PressedStandardCaptureButtonBlack60ScreenshotPreview_0.png create mode 100644 ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/PressedStandardCaptureButtonScreenshotPreview_0.png diff --git a/.gemini/styleguide.md b/.gemini/styleguide.md index e2bf5e9ae4..53fbaa70cc 100644 --- a/.gemini/styleguide.md +++ b/.gemini/styleguide.md @@ -25,6 +25,7 @@ When reviewing a pull request, focus on the following key areas: * **Remove Unused Imports:** Check for and remove any unused import statements to maintain code cleanliness. * Look for potential null-safety issues, improper error handling, or resource leaks. * **Promote Reusability (DRY Principle):** Identify duplicated or highly similar blocks of code. If a pattern of logic is repeated—even with minor variations—suggest extracting it into a reusable function, composable, or helper class. + * **Avoid Magic Numbers:** Avoid scattering literal dimension values or scales directly in the layout code. Instead, group them into a `private object Tokens` at the top of the file if file-scoped, or in a separate `Dimensions.kt` or `Tokens.kt` file if shared across features. Use semantic naming (e.g., `SmallPadding`) rather than value-based naming (e.g., `Dp16`). 3. **Performance and Efficiency** * Scan for inefficient operations, especially within Composable functions (e.g., expensive calculations, improper state management leading to excessive recompositions). @@ -94,6 +95,11 @@ When reviewing a pull request, focus on the following key areas: * **Apply Proper Semantics:** When building custom UI components from the ground up (e.g., a custom button made of an `Icon` and a `Text`), apply the correct semantics to ensure they are accessible. * Use `semantics { role = Role.Button }` (or `Role.Checkbox`, etc.) to define the component's logical purpose for screen readers. * For components made of multiple parts that should be read as a single, coherent unit, use `semantics { mergeDescendants = true }`. This prevents screen readers from announcing inner elements (like an icon and its text label) as separate, unrelated items. + * **Explicit Focusability:** When building custom components that handle input manually via low-level gestures (e.g., using `pointerInput` or `detectTapGestures`) rather than `Modifier.clickable()`, they may not automatically become focusable. In such cases, explicitly add `Modifier.focusable()` to ensure they are reachable via keyboard navigation and analyzed by automated accessibility checks. + * **Content vs State Descriptions:** + * Use `contentDescription` to describe the **identity** or **action** of the component (e.g., "Capture Photo", "Start Video Recording"). + * Use `stateDescription` to describe the **current state** of the component (e.g., "Locked", "Selected"). + * **Avoid Redundancy:** Do not include state information or control type in `contentDescription` (e.g., avoid "Locked Video Button" or "Shutter Button"). Let the system announce role and state automatically. ## Rules for Providing Feedback * **Be Constructive:** Frame feedback as suggestions, not commands. Explain the reasoning ("why") behind each comment. diff --git a/core/camera/src/androidTest/java/com/google/jetpackcamera/core/camera/utils/OpenGLTestUtil.kt b/core/camera/src/androidTest/java/com/google/jetpackcamera/core/camera/utils/OpenGLTestUtil.kt index 3553b4c7ef..30dc5e822e 100644 --- a/core/camera/src/androidTest/java/com/google/jetpackcamera/core/camera/utils/OpenGLTestUtil.kt +++ b/core/camera/src/androidTest/java/com/google/jetpackcamera/core/camera/utils/OpenGLTestUtil.kt @@ -48,6 +48,7 @@ import kotlinx.coroutines.withContext * * This is useful for tests that require a valid surface provider but do not need to display the output. */ +@android.annotation.SuppressLint("Recycle") suspend fun SurfaceRequest.provideUpdatingSurface() { var isReleased = false val executor = Executors.newFixedThreadPool(1) diff --git a/feature/preview/src/main/java/com/google/jetpackcamera/feature/preview/PreviewScreen.kt b/feature/preview/src/main/java/com/google/jetpackcamera/feature/preview/PreviewScreen.kt index eff65479a2..b6c371d214 100644 --- a/feature/preview/src/main/java/com/google/jetpackcamera/feature/preview/PreviewScreen.kt +++ b/feature/preview/src/main/java/com/google/jetpackcamera/feature/preview/PreviewScreen.kt @@ -419,6 +419,7 @@ private fun ContentScreen( ) { @Composable { modifier: Modifier -> PreviewDisplay( + modifier = modifier, previewDisplayUiState = previewDisplayState.value, onFlipCamera = onFlipCamera, onTapToFocus = onTapToFocusLambda, @@ -453,6 +454,7 @@ private fun ContentScreen( action() } CaptureButton( + modifier = modifier, captureButtonUiState = captureButtonState.value, isQuickSettingsOpen = (quickSettingsUiState as? QuickSettingsUiState.Available) ?.quickSettingsIsOpen ?: false, diff --git a/gradle.properties b/gradle.properties index 23a6f2b562..e2cc2f8eea 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,5 +44,6 @@ android.experimental.testOptions.managedDevices.maxConcurrentDevices=1 android.experimental.testOptions.managedDevices.setupTimeoutMinutes=180 # Ensure we can run managed devices on servers that don't support hardware rendering android.testoptions.manageddevices.emulator.gpu=swiftshader_indirect +android.experimental.enableScreenshotTest=true # Enabled parallel sync for Gradle 9.4+ org.gradle.tooling.parallel=true diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 04676d579a..456e43eaa8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,9 @@ accompanist = "0.37.3" # See https://developer.android.com/jetpack/androidx/releases/compose-kotlin kotlinPlugin = "2.2.0" androidGradlePlugin = "9.3.1" +composeScreenshot = "0.0.1-alpha14" +accessibilityTestFramework = "4.1.1" androidxActivityCompose = "1.10.1" androidxAppCompat = "1.7.1" @@ -66,6 +68,7 @@ androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidx androidx-datastore-preferences = { module = "androidx.datastore:datastore-preferences", version.ref = "androidxDatastore" } androidx-espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "androidxTestEspresso" } +androidx-espresso-accessibility = { module = "androidx.test.espresso:espresso-accessibility", version.ref = "androidxTestEspresso" } androidx-graphics-core = { module = "androidx.graphics:graphics-core", version.ref = "androidxGraphicsCore" } androidx-junit = { module = "androidx.test.ext:junit", version.ref = "androidxTestJunit" } androidx-lifecycle-livedata = { module = "androidx.lifecycle:lifecycle-livedata-ktx", version.ref = "androidxLifecycle" } @@ -88,8 +91,11 @@ camera-video = { module = "androidx.camera:camera-video", version.ref = "android camera-compose = { module = "androidx.camera:camera-compose", version.ref = "androidxCamera" } compose-bom = { module = "androidx.compose:compose-bom", version.ref = "composeBom" } compose-junit = { module = "androidx.compose.ui:ui-test-junit4" } +compose-accessibility = { module = "androidx.compose.ui:ui-test-junit4-accessibility" } +accessibility-test-framework = { module = "com.google.android.apps.common.testing.accessibility.framework:accessibility-test-framework", version.ref = "accessibilityTestFramework" } compose-material3 = { module = "androidx.compose.material3:material3", version.ref = "composeMaterial" } compose-test-manifest = { module = "androidx.compose.ui:ui-test-manifest" } +screenshot-validation-api = { module = "com.android.tools.screenshot:screenshot-validation-api", version.ref = "composeScreenshot" } compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling" } compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview" } dagger-hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt" } @@ -124,4 +130,5 @@ dagger-hilt-android = { id = "com.google.dagger.hilt.android", version.ref = "hi kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlinPlugin" } kotlin-kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlinPlugin" } +compose-screenshot = { id = "com.android.compose.screenshot", version.ref = "composeScreenshot" } android-legacy-kapt = { id = "com.android.legacy-kapt", version.ref = "androidGradlePlugin" } diff --git a/ui/components/capture/build.gradle.kts b/ui/components/capture/build.gradle.kts index bfb1aa21c0..cc1d04d9d8 100644 --- a/ui/components/capture/build.gradle.kts +++ b/ui/components/capture/build.gradle.kts @@ -18,12 +18,15 @@ plugins { alias(libs.plugins.android.library) alias(libs.plugins.android.legacy.kapt) alias(libs.plugins.compose.compiler) + alias(libs.plugins.compose.screenshot) } android { namespace = "com.google.jetpackcamera.ui.components.capture" compileSdk = libs.versions.compileSdk.get().toInt() + experimentalProperties["android.experimental.enableScreenshotTest"] = true + defaultConfig { minSdk = libs.versions.minSdk.get().toInt() testOptions.targetSdk = libs.versions.targetSdk.get().toInt() @@ -92,6 +95,8 @@ dependencies { // noinspection TestManifestGradleConfiguration: required for release build unit tests testImplementation(libs.compose.test.manifest) testImplementation(libs.compose.junit) + screenshotTestImplementation(libs.screenshot.validation.api) + screenshotTestImplementation(libs.compose.ui.tooling) // Testing testImplementation(libs.junit) @@ -102,6 +107,9 @@ dependencies { testImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.espresso.core) + androidTestImplementation(libs.androidx.espresso.accessibility) + androidTestImplementation(libs.compose.accessibility) + androidTestImplementation(libs.accessibility.test.framework) implementation(project(":ui:uistate")) implementation(project(":ui:uistate:capture")) @@ -121,3 +129,10 @@ dependencies { kapt { correctErrorTypes = true } +configurations.all { + resolutionStrategy { + // Exclude protobuf-lite to prevent DuplicateClassException conflicts with protobuf-javalite + // that is brought in by androidx.datastore, since the accessibility-test-framework brings in protobuf-lite. + exclude(group = "com.google.protobuf", module = "protobuf-lite") + } +} diff --git a/ui/components/capture/src/androidTest/java/com/google/jetpackcamera/ui/components/capture/CaptureButtonTest.kt b/ui/components/capture/src/androidTest/java/com/google/jetpackcamera/ui/components/capture/CaptureButtonTest.kt new file mode 100644 index 0000000000..8665479065 --- /dev/null +++ b/ui/components/capture/src/androidTest/java/com/google/jetpackcamera/ui/components/capture/CaptureButtonTest.kt @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2026 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.jetpackcamera.ui.components.capture + +import androidx.activity.ComponentActivity +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag +import androidx.compose.ui.semantics.Role +import androidx.compose.ui.semantics.SemanticsProperties +import androidx.compose.ui.test.SemanticsMatcher +import androidx.compose.ui.test.assert +import androidx.compose.ui.test.assertContentDescriptionEquals +import androidx.compose.ui.test.isNotEnabled +import androidx.compose.ui.test.junit4.accessibility.enableAccessibilityChecks +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onNodeWithTag +import androidx.compose.ui.test.onRoot +import androidx.compose.ui.test.tryPerformAccessibilityChecks +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResult.AccessibilityCheckResultType +import com.google.android.apps.common.testing.accessibility.framework.integrations.espresso.AccessibilityValidator +import com.google.jetpackcamera.model.CaptureMode +import com.google.jetpackcamera.ui.uistate.capture.CaptureButtonUiState +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class CaptureButtonTest { + @get:Rule + val composeTestRule = createAndroidComposeRule() + + @Before + fun setUp() { + composeTestRule.enableAccessibilityChecks( + AccessibilityValidator().setRunChecksFromRootView(true).also { + it.setThrowExceptionFor(AccessibilityCheckResultType.ERROR) + } + ) + } + + @Test + fun captureButton_standard_exists() { + composeTestRule.setContent { + CaptureButton( + modifier = Modifier.testTag("CaptureButtonTestTag"), + onImageCapture = {}, + onStartRecording = {}, + onStopRecording = {}, + onLockVideoRecording = {}, + onIncrementZoom = {}, + captureButtonUiState = CaptureButtonUiState.Enabled.Idle(CaptureMode.STANDARD) + ) + } + + composeTestRule.onNodeWithTag("CaptureButtonTestTag").assertExists() + composeTestRule.onNodeWithTag( + "CaptureButtonTestTag" + ).assertContentDescriptionEquals("Capture Photo") + composeTestRule.onNodeWithTag("CaptureButtonTestTag", useUnmergedTree = true) + .assert(SemanticsMatcher.expectValue(SemanticsProperties.Role, Role.Button)) + composeTestRule.onRoot().tryPerformAccessibilityChecks() + } + + @Test + fun captureButton_imageOnly_exists() { + composeTestRule.setContent { + CaptureButton( + modifier = Modifier.testTag("CaptureButtonImageOnly"), + onImageCapture = {}, + onStartRecording = {}, + onStopRecording = {}, + onLockVideoRecording = {}, + onIncrementZoom = {}, + captureButtonUiState = CaptureButtonUiState.Enabled.Idle(CaptureMode.IMAGE_ONLY) + ) + } + composeTestRule.onRoot().tryPerformAccessibilityChecks() + composeTestRule.onNodeWithTag("CaptureButtonImageOnly").assertExists() + composeTestRule.onNodeWithTag( + "CaptureButtonImageOnly" + ).assertContentDescriptionEquals("Capture Photo") + composeTestRule.onNodeWithTag("CaptureButtonImageOnly", useUnmergedTree = true) + .assert(SemanticsMatcher.expectValue(SemanticsProperties.Role, Role.Button)) + } + + @Test + fun captureButton_videoOnly_exists() { + composeTestRule.setContent { + CaptureButton( + modifier = Modifier.testTag("CaptureButtonVideoOnly"), + onImageCapture = {}, + onStartRecording = {}, + onStopRecording = {}, + onLockVideoRecording = {}, + onIncrementZoom = {}, + captureButtonUiState = CaptureButtonUiState.Enabled.Idle(CaptureMode.VIDEO_ONLY) + ) + } + composeTestRule.onRoot().tryPerformAccessibilityChecks() + composeTestRule.onNodeWithTag("CaptureButtonVideoOnly").assertExists() + composeTestRule.onNodeWithTag( + "CaptureButtonVideoOnly" + ).assertContentDescriptionEquals("Start Video Recording") + composeTestRule.onNodeWithTag("CaptureButtonVideoOnly", useUnmergedTree = true) + .assert(SemanticsMatcher.expectValue(SemanticsProperties.Role, Role.Button)) + } + + @Test + fun captureButton_lockedRecording_exists() { + composeTestRule.setContent { + CaptureButton( + modifier = Modifier.testTag("CaptureButtonLocked"), + onImageCapture = {}, + onStartRecording = {}, + onStopRecording = {}, + onLockVideoRecording = {}, + onIncrementZoom = {}, + captureButtonUiState = CaptureButtonUiState.Enabled.Recording.LockedRecording + ) + } + composeTestRule.onRoot().tryPerformAccessibilityChecks() + composeTestRule.onNodeWithTag("CaptureButtonLocked").assertExists() + composeTestRule.onNodeWithTag( + "CaptureButtonLocked" + ).assertContentDescriptionEquals("Stop Video Recording") + composeTestRule.onNodeWithTag("CaptureButtonLocked", useUnmergedTree = true) + .assert(SemanticsMatcher.expectValue(SemanticsProperties.Role, Role.Button)) + } + + @Test + fun captureButton_pressedRecording_exists() { + composeTestRule.setContent { + CaptureButton( + modifier = Modifier.testTag("CaptureButtonPressedRecording"), + onImageCapture = {}, + onStartRecording = {}, + onStopRecording = {}, + onLockVideoRecording = {}, + onIncrementZoom = {}, + captureButtonUiState = CaptureButtonUiState.Enabled.Recording.PressedRecording + ) + } + composeTestRule.onRoot().tryPerformAccessibilityChecks() + composeTestRule.onNodeWithTag("CaptureButtonPressedRecording").assertExists() + composeTestRule.onNodeWithTag( + "CaptureButtonPressedRecording" + ).assertContentDescriptionEquals("Recording Video") + composeTestRule.onNodeWithTag("CaptureButtonPressedRecording", useUnmergedTree = true) + .assert(SemanticsMatcher.expectValue(SemanticsProperties.Role, Role.Button)) + } + + @Test + fun captureButton_disabled_exists() { + composeTestRule.setContent { + CaptureButton( + modifier = Modifier.testTag("CaptureButtonDisabled"), + onImageCapture = {}, + onStartRecording = {}, + onStopRecording = {}, + onLockVideoRecording = {}, + onIncrementZoom = {}, + captureButtonUiState = CaptureButtonUiState.Enabled.Idle( + CaptureMode.STANDARD, + isEnabled = false + ) + ) + } + composeTestRule.onRoot().tryPerformAccessibilityChecks() + composeTestRule.onNodeWithTag("CaptureButtonDisabled").assertExists() + composeTestRule.onNodeWithTag( + "CaptureButtonDisabled" + ).assert(androidx.compose.ui.test.isNotEnabled()) + } +} diff --git a/ui/components/capture/src/main/java/com/google/jetpackcamera/ui/components/capture/CaptureButtonComponents.kt b/ui/components/capture/src/main/java/com/google/jetpackcamera/ui/components/capture/CaptureButtonComponents.kt index 88ce0c69f3..692c4115bb 100644 --- a/ui/components/capture/src/main/java/com/google/jetpackcamera/ui/components/capture/CaptureButtonComponents.kt +++ b/ui/components/capture/src/main/java/com/google/jetpackcamera/ui/components/capture/CaptureButtonComponents.kt @@ -15,26 +15,28 @@ */ package com.google.jetpackcamera.ui.components.capture -import android.util.Log import android.view.KeyEvent import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.EnterTransition import androidx.compose.animation.ExitTransition +import androidx.compose.animation.animateColor import androidx.compose.animation.animateColorAsState import androidx.compose.animation.core.FastOutSlowInEasing +import androidx.compose.animation.core.animateDp import androidx.compose.animation.core.animateDpAsState import androidx.compose.animation.core.snap import androidx.compose.animation.core.tween +import androidx.compose.animation.core.updateTransition import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.animation.scaleIn import androidx.compose.foundation.Canvas import androidx.compose.foundation.background import androidx.compose.foundation.border -import androidx.compose.foundation.clickable +import androidx.compose.foundation.focusable import androidx.compose.foundation.gestures.detectDragGesturesAfterLongPress import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.interaction.PressInteraction +import androidx.compose.foundation.interaction.collectIsPressedAsState import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.offset @@ -42,12 +44,17 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Icon import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.darkColorScheme import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.State +import androidx.compose.runtime.compositionLocalOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableStateOf @@ -62,27 +69,50 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.geometry.CornerRadius import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Rect -import androidx.compose.ui.geometry.Size +import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.platform.LocalView import androidx.compose.ui.platform.LocalViewConfiguration import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.Role +import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.disabled +import androidx.compose.ui.semantics.role import androidx.compose.ui.semantics.semantics import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.dp import androidx.core.view.ViewCompat import com.google.jetpackcamera.model.CaptureMode import com.google.jetpackcamera.ui.uistate.capture.CaptureButtonUiState +import kotlin.math.roundToInt import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.launch private const val TAG = "CaptureButton" -private const val DEFAULT_CAPTURE_BUTTON_SIZE = 80f +private const val DEFAULT_CAPTURE_BUTTON_SIZE = 76f + +private const val IDLE_IMAGE_CAPTURE_SCALE = 0.86f +private const val IDLE_VIDEO_CAPTURE_SCALE = 0.64f +private const val PRESSED_IMAGE_CAPTURE_SCALE = 0.93f +private const val LOCKED_RECORDING_NUCLEUS_SCALE = 0.51f +private const val MORPH_INTERMEDIATE_SCALE = 0.58f +private const val BORDER_WIDTH = 3f +private const val ANIMATION_DURATION_SIZE = 250 +private const val ANIMATION_DURATION_COLOR = 150 +private const val ANIMATION_DURATION_NUCLEUS_RELEASE = 100 +private const val ANIMATION_DURATION_DISABLED = 500 +private const val ANIMATION_DURATION_NUCLEUS_PRESSED = 50 +private const val ALPHA_DISABLED_NUCLEUS = 0.6f +private const val ALPHA_WHITE_20 = 0.2f +private const val ALPHA_BLACK_60 = 0.6f + +private val LOCKED_CORNER_RADIUS = 8.dp // scales against the size of the capture button private const val LOCK_SWITCH_PRESSED_NUCLEUS_SCALE = .5f @@ -193,7 +223,8 @@ internal fun CaptureButton( onLockVideoRecording: (Boolean) -> Unit, onIncrementZoom: (Float) -> Unit, captureButtonUiState: CaptureButtonUiState, - captureButtonSize: Float = DEFAULT_CAPTURE_BUTTON_SIZE + captureButtonSize: Float = DEFAULT_CAPTURE_BUTTON_SIZE, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() } ) { val currentUiState = rememberUpdatedState(captureButtonUiState) val firstKeyPressed = remember { mutableStateOf(null) } @@ -202,6 +233,9 @@ internal fun CaptureButton( val scope = rememberCoroutineScope() val longPressTimeout = LocalViewConfiguration.current.longPressTimeoutMillis + // To handle press interactions from key events + var currentPressInteraction by remember { mutableStateOf(null) } + LaunchedEffect(captureButtonUiState) { if (captureButtonUiState is CaptureButtonUiState.Enabled.Idle) { onLockVideoRecording(false) @@ -220,7 +254,6 @@ internal fun CaptureButton( CaptureMode.STANDARD, CaptureMode.VIDEO_ONLY -> { isLongPressing.value = true - Log.d(TAG, "Starting recording") onStartRecording() } @@ -238,6 +271,16 @@ internal fun CaptureButton( if (!captureButtonUiState.isEnabled) return if (firstKeyPressed.value == null) { firstKeyPressed.value = captureSource + + // Emit press interaction for key events to trigger UI feedback + if (captureSource != CaptureSource.CAPTURE_BUTTON) { + val press = PressInteraction.Press(Offset.Zero) + currentPressInteraction = press + scope.launch { + interactionSource.emit(press) + } + } + longPressJob = scope.launch { delay(longPressTimeout) onLongPress() @@ -248,6 +291,18 @@ internal fun CaptureButton( fun onKeyUp(captureSource: CaptureSource, isLocked: Boolean = false) { // releasing while pressed recording if (firstKeyPressed.value == captureSource) { + // Emit release interaction for key events + if (captureSource != CaptureSource.CAPTURE_BUTTON) { + val interactionToRelease = currentPressInteraction + currentPressInteraction = null + if (interactionToRelease != null) { + scope.launch { + delay(50) // Ensure visible press state for fast taps + interactionSource.emit(PressInteraction.Release(interactionToRelease)) + } + } + } + if (isLongPressing.value) { if (!isLocked && ( @@ -257,7 +312,6 @@ internal fun CaptureButton( CaptureButtonUiState.Enabled.Recording.Starting ) ) { - Log.d(TAG, "Stopping recording") onStopRecording() } } @@ -270,7 +324,6 @@ internal fun CaptureButton( CaptureMode.VIDEO_ONLY -> { onLockVideoRecording(true) - Log.d(TAG, "Starting recording") onStartRecording() } } @@ -300,7 +353,8 @@ internal fun CaptureButton( onLockVideoRecording = onLockVideoRecording, onDragZoom = onIncrementZoom, captureButtonUiState = captureButtonUiState, - captureButtonSize = captureButtonSize + captureButtonSize = captureButtonSize, + interactionSource = interactionSource ) } @@ -344,9 +398,13 @@ private fun CaptureButton( onLockVideoRecording: (Boolean) -> Unit, captureButtonUiState: CaptureButtonUiState, useLockSwitch: Boolean = true, - captureButtonSize: Float = DEFAULT_CAPTURE_BUTTON_SIZE + captureButtonSize: Float = DEFAULT_CAPTURE_BUTTON_SIZE, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() } ) { - // todo: explore MutableInteractionSource + val initialPressed = LocalInitialPressedState.current + var isCaptureButtonPressed by remember(initialPressed) { + mutableStateOf(initialPressed) + } var isTapping by remember { mutableStateOf(false) } @@ -365,18 +423,32 @@ private fun CaptureButton( ) val disableAnimations = LocalDisableAnimations.current - + val isPressedInteraction by interactionSource.collectIsPressedAsState() val animatedColor by animateColorAsState( - targetValue = if (isVisuallyDisabled) { - LocalContentColor.current.copy(alpha = 0.38f) - } else { - LocalContentColor.current + targetValue = when { + isVisuallyDisabled -> { + if (currentUiState.value.let { + it is CaptureButtonUiState.Enabled.Idle && + it.captureMode == CaptureMode.STANDARD + } + ) { + LocalContentColor.current.copy(alpha = 0.2f) + } else { + Color.Transparent + } + } + currentUiState.value.let { + it is CaptureButtonUiState.Enabled.Idle && + it.captureMode == CaptureMode.STANDARD + } -> LocalContentColor.current + else -> Color.Transparent }, animationSpec = if (disableAnimations) { snap() } else { tween( - durationMillis = if (isVisuallyDisabled) 1000 else 300 + durationMillis = + if (isVisuallyDisabled) ANIMATION_DURATION_DISABLED else ANIMATION_DURATION_COLOR ) }, label = "Capture Button Color" @@ -421,19 +493,25 @@ private fun CaptureButton( onLongPress = {}, onPress = { isTapping = true + val press = PressInteraction.Press(it) + interactionSource.emit(press) + isCaptureButtonPressed = true // Manually set pressed state try { onPress() awaitRelease() } finally { isTapping = false + isCaptureButtonPressed = false // Manually unset pressed state + interactionSource.emit(PressInteraction.Release(press)) } if (shouldBeLocked()) { onLockVideoRecording(true) onRelease(true) + } else { + onRelease(false) } switchPosition = LOCK_SWITCH_POSITION_OFF - onRelease(false) } ) } @@ -481,6 +559,12 @@ private fun CaptureButton( } else { Modifier } + val capturePhotoDesc = stringResource(R.string.capture_button_capture_photo) + val startVideoDesc = stringResource(R.string.capture_button_start_video_recording) + val recordingVideoDesc = stringResource(R.string.capture_button_recording_video) + val stopVideoDesc = stringResource(R.string.capture_button_stop_video_recording) + val unavailableDesc = stringResource(R.string.capture_button_unavailable) + CaptureButtonRing( modifier = modifier .onSizeChanged { @@ -488,10 +572,23 @@ private fun CaptureButton( Rect(0f, 0f, it.width.toFloat(), it.height.toFloat()) } .semantics { + role = Role.Button if (!captureButtonUiState.isEnabled) { disabled() } + contentDescription = when (val uiState = captureButtonUiState) { + is CaptureButtonUiState.Enabled.Idle -> when (uiState.captureMode) { + CaptureMode.STANDARD -> capturePhotoDesc + CaptureMode.IMAGE_ONLY -> capturePhotoDesc + CaptureMode.VIDEO_ONLY -> startVideoDesc + } + CaptureButtonUiState.Enabled.Recording.PressedRecording -> recordingVideoDesc + CaptureButtonUiState.Enabled.Recording.LockedRecording -> stopVideoDesc + CaptureButtonUiState.Unavailable -> unavailableDesc + CaptureButtonUiState.Enabled.Recording.Starting -> startVideoDesc + } } + .focusable() .then(gestureModifier), captureButtonSize = captureButtonSize, color = animatedColor @@ -501,29 +598,55 @@ private fun CaptureButton( captureButtonUiState = captureButtonUiState, captureButtonSize = captureButtonSize, switchWidth = switchWidth.dp, - switchPosition = switchPosition, + switchPositionProvider = { switchPosition }, onToggleSwitchPosition = { toggleSwitchPosition() }, - shouldBeLocked = { shouldBeLocked() } + shouldBeLocked = { shouldBeLocked() }, + isVisuallyDisabled = isVisuallyDisabled, + isTapping = isCaptureButtonPressed || isPressedInteraction ) } else { CaptureButtonNucleus( captureButtonUiState = captureButtonUiState, - isTapping = isTapping, - captureButtonSize = captureButtonSize + isTapping = isCaptureButtonPressed || isPressedInteraction, + captureButtonSize = captureButtonSize, + isVisuallyDisabled = isVisuallyDisabled ) } } } +/** + * CompositionLocal to provide the initial pressed state of the capture button. + * This is primarily used for previews and screenshot tests to force the pressed state. + */ +internal val LocalInitialPressedState = compositionLocalOf { false } + @Composable -private fun CaptureButtonRing( +internal fun CaptureButtonRing( modifier: Modifier = Modifier, captureButtonSize: Float, color: Color, - borderWidth: Float = 4f, + borderWidth: Float = BORDER_WIDTH, contents: (@Composable () -> Unit)? = null ) { + val backgroundStyle = LocalCameraControlBackgroundStyle.current + val targetBackgroundColor = when (backgroundStyle) { + CameraControlBackgroundStyle.WHITE_20 -> Color.White.copy(alpha = ALPHA_WHITE_20) + CameraControlBackgroundStyle.BLACK_60 -> Color.Black.copy(alpha = ALPHA_BLACK_60) + } + val backgroundColor by animateColorAsState( + targetValue = targetBackgroundColor, + animationSpec = androidx.compose.animation.core.tween( + durationMillis = ANIMATION_DURATION_COLOR + ), + label = "backgroundColor" + ) Box(modifier = modifier, contentAlignment = Alignment.Center) { + Box( + modifier = Modifier + .size(captureButtonSize.dp) + .background(backgroundColor, CircleShape) + ) contents?.invoke() // todo(): use a canvas instead of a box. // the sizing gets funny so the scales need to be completely readjusted @@ -546,13 +669,16 @@ private fun LockSwitchCaptureButtonNucleus( captureButtonUiState: CaptureButtonUiState, captureButtonSize: Float, switchWidth: Dp, - switchPosition: Float, + switchPositionProvider: () -> Float, onToggleSwitchPosition: () -> Unit, - shouldBeLocked: () -> Boolean + shouldBeLocked: () -> Boolean, + isVisuallyDisabled: Boolean = false, + isTapping: Boolean ) { val pressedNucleusSize = (captureButtonSize * LOCK_SWITCH_PRESSED_NUCLEUS_SCALE).dp val switchHeight = (pressedNucleusSize * LOCK_SWITCH_HEIGHT_SCALE) val disableAnimations = LocalDisableAnimations.current + val lockVideoRecordingDesc = stringResource(R.string.capture_button_lock_video_recording) Box( modifier = modifier @@ -563,7 +689,7 @@ private fun LockSwitchCaptureButtonNucleus( Box( contentAlignment = Alignment.CenterStart, modifier = Modifier - .width(switchWidth) + .width(switchWidth + 4.dp) .height(switchHeight) .offset(x = -(switchWidth - pressedNucleusSize) / 2) ) { @@ -593,11 +719,20 @@ private fun LockSwitchCaptureButtonNucleus( // is behind lock icon but in front of the switch background CaptureButtonNucleus( - offsetX = (-(switchWidth - pressedNucleusSize) * switchPosition), + modifier = Modifier.offset { + IntOffset( + x = ( + -(switchWidth - pressedNucleusSize).toPx() * + switchPositionProvider() + ).roundToInt(), + y = 0 + ) + }, captureButtonSize = captureButtonSize, captureButtonUiState = captureButtonUiState, pressedVideoCaptureScale = LOCK_SWITCH_PRESSED_NUCLEUS_SCALE, - isTapping = false + isTapping = isTapping, + isVisuallyDisabled = isVisuallyDisabled ) // locked icon, matches cylinder offset @@ -607,52 +742,64 @@ private fun LockSwitchCaptureButtonNucleus( enter = if (disableAnimations) EnterTransition.None else fadeIn(), exit = ExitTransition.None ) { - Icon( + Box( modifier = Modifier - .size(switchHeight * .75f) .align(Alignment.CenterStart) .padding(start = 8.dp) .offset(x = -(switchWidth - pressedNucleusSize)) - .clickable( - indication = null, - interactionSource = remember { MutableInteractionSource() } - ) { - onToggleSwitchPosition() + .size(32.dp) + .semantics { + contentDescription = lockVideoRecordingDesc + role = Role.Button + } + .pointerInput(Unit) { + detectTapGestures { + onToggleSwitchPosition() + } + } + ) { + Icon( + modifier = Modifier.size(switchHeight * .75f).align(Alignment.Center), + tint = Color.White, + painter = if (shouldBeLocked()) { + painterResource(R.drawable.ic_lock) + } else { + painterResource(R.drawable.ic_lock_open) }, - tint = Color.White, - painter = if (shouldBeLocked()) { - painterResource(R.drawable.ic_lock) - } else { - painterResource(R.drawable.ic_lock_open) - }, - contentDescription = null - ) + contentDescription = null + ) + } } } } +private enum class NucleusState { + Disabled, + Idle, + Pressed +} + /** * The animated center of the capture button. It serves as a visual indicator of the current capture and recording states. * * @param captureButtonSize diameter of the capture button ring that this is scaled to - * @param isPressed true if the capture button is physically pressed on - * @param offsetX the offset of this component. 0 by default + * @param isTapping true if the capture button is physically pressed on * @param idleImageCaptureScale the scale factor for the idle size of the image-only nucleus. Must be between 0 and 1. * @param idleVideoCaptureScale the scale factor for the idle size of the video-only nucleus. Must be between 0 and 1. * @param pressedVideoCaptureScale the scale factor for the pressed size of the video-only nucleus. Must be between 0 and 1. */ @Composable -private fun CaptureButtonNucleus( +internal fun CaptureButtonNucleus( modifier: Modifier = Modifier, captureButtonUiState: CaptureButtonUiState, isTapping: Boolean, captureButtonSize: Float, - offsetX: Dp = 0.dp, recordingColor: Color = Color.Red, imageCaptureModeColor: Color = Color.White, - idleImageCaptureScale: Float = .7f, - idleVideoCaptureScale: Float = .35f, - pressedVideoCaptureScale: Float = .7f + idleImageCaptureScale: Float = IDLE_IMAGE_CAPTURE_SCALE, + idleVideoCaptureScale: Float = IDLE_VIDEO_CAPTURE_SCALE, + pressedVideoCaptureScale: Float = IDLE_IMAGE_CAPTURE_SCALE, + isVisuallyDisabled: Boolean = false ) { require(idleImageCaptureScale in 0f..1f) { "value must be between 0 and 1 to remain within the bounds of the capture button" @@ -668,10 +815,11 @@ private fun CaptureButtonNucleus( val disableAnimations = LocalDisableAnimations.current // smoothly animate between the size changes of the capture button center - val centerShapeSize by animateDpAsState( + val standardShapeSize by animateDpAsState( targetValue = when (val uiState = currentUiState.value) { - // inner circle fills white ring when locked - CaptureButtonUiState.Enabled.Recording.LockedRecording -> captureButtonSize.dp + // inner circle becomes a square when locked + CaptureButtonUiState.Enabled.Recording.LockedRecording -> + (captureButtonSize * LOCKED_RECORDING_NUCLEUS_SCALE).dp CaptureButtonUiState.Enabled.Recording.Starting, CaptureButtonUiState.Enabled.Recording.PressedRecording -> @@ -690,34 +838,116 @@ private fun CaptureButtonNucleus( animationSpec = if (disableAnimations) { snap() } else { - tween(durationMillis = 500, easing = FastOutSlowInEasing) + tween(durationMillis = ANIMATION_DURATION_SIZE, easing = FastOutSlowInEasing) } ) + val pressTransition = updateTransition( + targetState = isTapping && + currentUiState.value.let { + it is CaptureButtonUiState.Enabled.Idle && + ( + it.captureMode == CaptureMode.IMAGE_ONLY || + it.captureMode == CaptureMode.STANDARD + ) + }, + label = "Press Size Transition" + ) + + val centerShapeSize by pressTransition.animateDp( + transitionSpec = { + if (targetState) { + snap() + } else { + tween(durationMillis = ANIMATION_DURATION_NUCLEUS_RELEASE) + } + }, + label = "Nucleus Size" + ) { isPressedImage -> + if (isPressedImage) { + (captureButtonSize * PRESSED_IMAGE_CAPTURE_SCALE).dp + } else { + standardShapeSize + } + } + + val sizeFinal = (captureButtonSize * LOCKED_RECORDING_NUCLEUS_SCALE).dp + val sizeInter = (captureButtonSize * MORPH_INTERMEDIATE_SCALE).dp + val isLocked = currentUiState.value is CaptureButtonUiState.Enabled.Recording.LockedRecording + val cornerRadius = if (isLocked) { + if (centerShapeSize <= sizeInter) { + val fraction = (centerShapeSize - sizeFinal) / (sizeInter - sizeFinal) + val coercedFraction = fraction.coerceIn(0f, 1f) + LOCKED_CORNER_RADIUS + (centerShapeSize / 2 - LOCKED_CORNER_RADIUS) * coercedFraction + } else { + centerShapeSize / 2 + } + } else { + centerShapeSize / 2 + } + // used to fade between red/white in the center of the capture button - val animatedColor by animateColorAsState( - targetValue = when (val uiState = currentUiState.value) { - is CaptureButtonUiState.Enabled.Idle -> when (uiState.captureMode) { - CaptureMode.STANDARD -> imageCaptureModeColor - CaptureMode.IMAGE_ONLY -> imageCaptureModeColor - CaptureMode.VIDEO_ONLY -> recordingColor + val isPressableImageMode = currentUiState.value.let { + it is CaptureButtonUiState.Enabled.Idle && + (it.captureMode == CaptureMode.IMAGE_ONLY || it.captureMode == CaptureMode.STANDARD) + } + val nucleusState = when { + isVisuallyDisabled -> NucleusState.Disabled + isTapping && isPressableImageMode -> NucleusState.Pressed + else -> NucleusState.Idle + } + + val transition = + updateTransition(targetState = nucleusState, label = "Nucleus Color Transition") + val animatedColor by transition.animateColor( + label = "Nucleus Color", + transitionSpec = { + if (disableAnimations) { + snap() + } else { + when { + NucleusState.Disabled isTransitioningTo NucleusState.Idle -> tween( + durationMillis = ANIMATION_DURATION_COLOR + ) + NucleusState.Idle isTransitioningTo NucleusState.Disabled -> tween( + durationMillis = ANIMATION_DURATION_DISABLED + ) + NucleusState.Pressed isTransitioningTo NucleusState.Idle -> tween( + durationMillis = ANIMATION_DURATION_NUCLEUS_PRESSED + ) + else -> snap() + } } + } + ) { state -> + when (state) { + NucleusState.Disabled -> Color.Black.copy(alpha = ALPHA_DISABLED_NUCLEUS) + NucleusState.Pressed -> imageCaptureModeColor + NucleusState.Idle -> { + when (val uiState = currentUiState.value) { + is CaptureButtonUiState.Enabled.Idle -> when (uiState.captureMode) { + CaptureMode.STANDARD -> imageCaptureModeColor + CaptureMode.IMAGE_ONLY -> imageCaptureModeColor + CaptureMode.VIDEO_ONLY -> + if (isTapping) recordingColor else imageCaptureModeColor + } - is CaptureButtonUiState.Enabled.Recording -> recordingColor - is CaptureButtonUiState.Unavailable -> Color.Transparent - }, - animationSpec = if (disableAnimations) snap() else tween(durationMillis = 500) - ) + is CaptureButtonUiState.Enabled.Recording -> recordingColor + is CaptureButtonUiState.Unavailable -> Color.Transparent + } + } + } + } // this box contains and centers everything - Box(modifier = modifier.offset(x = offsetX), contentAlignment = Alignment.Center) { + Box(modifier = modifier, contentAlignment = Alignment.Center) { // this box is the inner circle Box(modifier = Modifier) { Box( contentAlignment = Alignment.Center, modifier = Modifier .size(centerShapeSize) - .clip(CircleShape) + .clip(RoundedCornerShape(cornerRadius)) .alpha( if (isTapping && currentUiState.value == @@ -731,25 +961,38 @@ private fun CaptureButtonNucleus( .background(animatedColor) ) {} } - // central "square" stop icon - val isVisible = currentUiState.value is - CaptureButtonUiState.Enabled.Recording.LockedRecording - AnimatedVisibility( - visible = isVisible, - enter = if (disableAnimations) { - EnterTransition.None - } else { - scaleIn(initialScale = .5f) + fadeIn() - }, - exit = if (disableAnimations) ExitTransition.None else fadeOut() + } +} + +@Composable +internal fun PreviewCaptureButton( + captureButtonUiState: CaptureButtonUiState, + modifier: Modifier = Modifier, + contentAlignment: Alignment = Alignment.CenterEnd, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() } +) { + MaterialTheme(colorScheme = darkColorScheme()) { + CompositionLocalProvider( + LocalContentColor provides Color.White ) { - val smallBoxSize = (captureButtonSize / 5f).dp - Canvas(modifier = Modifier) { - drawRoundRect( - color = Color.White, - topLeft = Offset(-smallBoxSize.toPx() / 2f, -smallBoxSize.toPx() / 2f), - size = Size(smallBoxSize.toPx(), smallBoxSize.toPx()), - cornerRadius = CornerRadius(smallBoxSize.toPx() * .15f) + Box( + modifier = modifier + .background( + Brush.verticalGradient( + colors = listOf(Color.Gray, Color.DarkGray) + ) + ), + contentAlignment = contentAlignment + ) { + CaptureButton( + modifier = Modifier, + onImageCapture = {}, + onStartRecording = {}, + onStopRecording = {}, + onLockVideoRecording = {}, + onIncrementZoom = {}, + captureButtonUiState = captureButtonUiState, + interactionSource = interactionSource ) } } @@ -758,177 +1001,124 @@ private fun CaptureButtonNucleus( @Preview @Composable -private fun CaptureButtonUnavailablePreview() { - CaptureButton( - onImageCapture = {}, - onStartRecording = {}, - onStopRecording = {}, - onLockVideoRecording = {}, - onIncrementZoom = {}, +internal fun CaptureButtonUnavailablePreview() { + PreviewCaptureButton( captureButtonUiState = CaptureButtonUiState.Unavailable ) } @Preview @Composable -private fun IdleStandardCaptureButtonPreview() { - CaptureButtonRing(captureButtonSize = DEFAULT_CAPTURE_BUTTON_SIZE, color = Color.White) { - CaptureButtonNucleus( - captureButtonUiState = CaptureButtonUiState.Enabled.Idle(CaptureMode.STANDARD), - isTapping = false, - captureButtonSize = DEFAULT_CAPTURE_BUTTON_SIZE - ) - } -} - -@Preview -@Composable -private fun IdleImageCaptureButtonPreview() { - CaptureButtonRing(captureButtonSize = DEFAULT_CAPTURE_BUTTON_SIZE, color = Color.White) { - CaptureButtonNucleus( - captureButtonUiState = CaptureButtonUiState.Enabled.Idle(CaptureMode.IMAGE_ONLY), - isTapping = false, - captureButtonSize = DEFAULT_CAPTURE_BUTTON_SIZE - ) - } -} - -@Preview -@Composable -private fun IdleVideoOnlyCaptureButtonPreview() { - CaptureButtonRing(captureButtonSize = DEFAULT_CAPTURE_BUTTON_SIZE, color = Color.White) { - CaptureButtonNucleus( - captureButtonUiState = CaptureButtonUiState.Enabled.Idle(CaptureMode.VIDEO_ONLY), - isTapping = false, - captureButtonSize = DEFAULT_CAPTURE_BUTTON_SIZE - ) - } +internal fun IdleStandardCaptureButtonPreview() { + PreviewCaptureButton( + captureButtonUiState = CaptureButtonUiState.Enabled.Idle(CaptureMode.STANDARD) + ) } @Preview @Composable -private fun IdleStandardCaptureButtonDisabledPreview() { - CaptureButtonRing(captureButtonSize = DEFAULT_CAPTURE_BUTTON_SIZE, color = Color.Gray) { - CaptureButtonNucleus( - captureButtonUiState = CaptureButtonUiState.Enabled.Idle( - CaptureMode.STANDARD, - isEnabled = false - ), - isTapping = false, - captureButtonSize = DEFAULT_CAPTURE_BUTTON_SIZE - ) - } +internal fun IdleImageCaptureButtonPreview() { + PreviewCaptureButton( + captureButtonUiState = CaptureButtonUiState.Enabled.Idle(CaptureMode.IMAGE_ONLY) + ) } @Preview @Composable -private fun IdleImageCaptureButtonDisabledPreview() { - CaptureButtonRing(captureButtonSize = DEFAULT_CAPTURE_BUTTON_SIZE, color = Color.Gray) { - CaptureButtonNucleus( - captureButtonUiState = CaptureButtonUiState.Enabled.Idle( - CaptureMode.IMAGE_ONLY, - isEnabled = false - ), - isTapping = false, - captureButtonSize = DEFAULT_CAPTURE_BUTTON_SIZE - ) - } +internal fun IdleVideoOnlyCaptureButtonPreview() { + PreviewCaptureButton( + captureButtonUiState = CaptureButtonUiState.Enabled.Idle(CaptureMode.VIDEO_ONLY) + ) } @Preview @Composable -private fun IdleVideoOnlyCaptureButtonDisabledPreview() { - CaptureButtonRing(captureButtonSize = DEFAULT_CAPTURE_BUTTON_SIZE, color = Color.Gray) { - CaptureButtonNucleus( - captureButtonUiState = CaptureButtonUiState.Enabled.Idle( - CaptureMode.VIDEO_ONLY, - isEnabled = false - ), - isTapping = false, - captureButtonSize = DEFAULT_CAPTURE_BUTTON_SIZE +internal fun IdleStandardCaptureButtonDisabledPreview() { + PreviewCaptureButton( + captureButtonUiState = CaptureButtonUiState.Enabled.Idle( + CaptureMode.STANDARD, + isEnabled = false ) - } + ) } @Preview @Composable -private fun PressedImageCaptureButtonPreview() { - CaptureButtonRing(captureButtonSize = DEFAULT_CAPTURE_BUTTON_SIZE, color = Color.White) { - CaptureButtonNucleus( - captureButtonUiState = CaptureButtonUiState.Enabled.Idle(CaptureMode.IMAGE_ONLY), - isTapping = true, - captureButtonSize = DEFAULT_CAPTURE_BUTTON_SIZE +internal fun IdleImageCaptureButtonDisabledPreview() { + PreviewCaptureButton( + captureButtonUiState = CaptureButtonUiState.Enabled.Idle( + CaptureMode.IMAGE_ONLY, + isEnabled = false ) - } + ) } @Preview @Composable -private fun IdleRecordingCaptureButtonPreview() { - CaptureButtonRing(captureButtonSize = DEFAULT_CAPTURE_BUTTON_SIZE, color = Color.White) { - CaptureButtonNucleus( - captureButtonUiState = CaptureButtonUiState.Enabled.Idle(CaptureMode.VIDEO_ONLY), - isTapping = false, - captureButtonSize = DEFAULT_CAPTURE_BUTTON_SIZE +internal fun IdleVideoOnlyCaptureButtonDisabledPreview() { + PreviewCaptureButton( + captureButtonUiState = CaptureButtonUiState.Enabled.Idle( + CaptureMode.VIDEO_ONLY, + isEnabled = false ) - } + ) } @Preview @Composable -private fun SimpleNucleusPressedRecordingPreview() { - CaptureButtonRing(captureButtonSize = DEFAULT_CAPTURE_BUTTON_SIZE, color = Color.White) { - CaptureButtonNucleus( - captureButtonUiState = CaptureButtonUiState.Enabled.Recording.PressedRecording, - isTapping = true, - captureButtonSize = DEFAULT_CAPTURE_BUTTON_SIZE +internal fun PressedImageCaptureButtonPreview() { + CompositionLocalProvider(LocalInitialPressedState provides true) { + PreviewCaptureButton( + captureButtonUiState = CaptureButtonUiState.Enabled.Idle(CaptureMode.IMAGE_ONLY) ) } } @Preview @Composable -private fun LockedRecordingPreview() { - CaptureButtonRing(captureButtonSize = DEFAULT_CAPTURE_BUTTON_SIZE, color = Color.White) { - CaptureButtonNucleus( - captureButtonUiState = CaptureButtonUiState.Enabled.Recording.LockedRecording, - isTapping = false, - captureButtonSize = DEFAULT_CAPTURE_BUTTON_SIZE - ) - } +internal fun LockSwitchUnlockedPressedRecordingPreview() { + // box is here to account for the offset lock switch + PreviewCaptureButton( + captureButtonUiState = CaptureButtonUiState.Enabled.Recording.PressedRecording, + modifier = Modifier.width(150.dp), + contentAlignment = Alignment.CenterEnd + ) } @Preview @Composable -private fun LockSwitchUnlockedPressedRecordingPreview() { - // box is here to account for the offset lock switch - Box(modifier = Modifier.width(150.dp), contentAlignment = Alignment.CenterEnd) { - CaptureButtonRing(captureButtonSize = DEFAULT_CAPTURE_BUTTON_SIZE, color = Color.White) { - LockSwitchCaptureButtonNucleus( - captureButtonSize = DEFAULT_CAPTURE_BUTTON_SIZE, - captureButtonUiState = CaptureButtonUiState.Enabled.Recording.PressedRecording, - switchWidth = (DEFAULT_CAPTURE_BUTTON_SIZE * LOCK_SWITCH_WIDTH_SCALE).dp, - switchPosition = 0f, - onToggleSwitchPosition = {}, - shouldBeLocked = { false } - ) - } - } +internal fun LockedRecordingPreview() { + PreviewCaptureButton( + captureButtonUiState = CaptureButtonUiState.Enabled.Recording.LockedRecording + ) } @Preview @Composable -private fun LockSwitchLockedAtThresholdPressedRecordingPreview() { +internal fun LockSwitchLockedAtThresholdPressedRecordingPreview() { // box is here to account for the offset lock switch - Box(modifier = Modifier.width(150.dp), contentAlignment = Alignment.CenterEnd) { - CaptureButtonRing(captureButtonSize = DEFAULT_CAPTURE_BUTTON_SIZE, color = Color.White) { + Box( + modifier = Modifier + .width(150.dp) + .background( + Brush.verticalGradient( + colors = listOf(Color.Gray, Color.DarkGray) + ) + ), + contentAlignment = Alignment.CenterEnd + ) { + CaptureButtonRing( + captureButtonSize = DEFAULT_CAPTURE_BUTTON_SIZE, + color = Color.Transparent + ) { LockSwitchCaptureButtonNucleus( captureButtonSize = DEFAULT_CAPTURE_BUTTON_SIZE, captureButtonUiState = CaptureButtonUiState.Enabled.Recording.PressedRecording, switchWidth = (DEFAULT_CAPTURE_BUTTON_SIZE * LOCK_SWITCH_WIDTH_SCALE).dp, - switchPosition = MINIMUM_LOCK_THRESHOLD, + switchPositionProvider = { MINIMUM_LOCK_THRESHOLD }, onToggleSwitchPosition = {}, - shouldBeLocked = { true } + shouldBeLocked = { true }, + isTapping = false ) } } @@ -936,17 +1126,30 @@ private fun LockSwitchLockedAtThresholdPressedRecordingPreview() { @Preview @Composable -private fun LockSwitchLockedPressedRecordingPreview() { +internal fun LockSwitchLockedPressedRecordingPreview() { // box is here to account for the offset lock switch - Box(modifier = Modifier.width(150.dp), contentAlignment = Alignment.CenterEnd) { - CaptureButtonRing(captureButtonSize = DEFAULT_CAPTURE_BUTTON_SIZE, color = Color.White) { + Box( + modifier = Modifier + .width(150.dp) + .background( + Brush.verticalGradient( + colors = listOf(Color.Gray, Color.DarkGray) + ) + ), + contentAlignment = Alignment.CenterEnd + ) { + CaptureButtonRing( + captureButtonSize = DEFAULT_CAPTURE_BUTTON_SIZE, + color = Color.Transparent + ) { LockSwitchCaptureButtonNucleus( captureButtonSize = DEFAULT_CAPTURE_BUTTON_SIZE, captureButtonUiState = CaptureButtonUiState.Enabled.Recording.PressedRecording, switchWidth = (DEFAULT_CAPTURE_BUTTON_SIZE * LOCK_SWITCH_WIDTH_SCALE).dp, - switchPosition = 1f, + switchPositionProvider = { 1f }, onToggleSwitchPosition = {}, - shouldBeLocked = { true } + shouldBeLocked = { true }, + isTapping = false ) } } diff --git a/ui/components/capture/src/main/res/values/strings.xml b/ui/components/capture/src/main/res/values/strings.xml index f73e4d3e4a..2d025b9216 100644 --- a/ui/components/capture/src/main/res/values/strings.xml +++ b/ui/components/capture/src/main/res/values/strings.xml @@ -127,4 +127,12 @@ View recently saved media + + + Capture Photo + Start Video Recording + Recording Video + Stop Video Recording + Lock Video Recording + Capture Button Unavailable \ No newline at end of file diff --git a/ui/components/capture/src/screenshotTest/kotlin/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTest.kt b/ui/components/capture/src/screenshotTest/kotlin/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTest.kt new file mode 100644 index 0000000000..76e5f11c63 --- /dev/null +++ b/ui/components/capture/src/screenshotTest/kotlin/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTest.kt @@ -0,0 +1,236 @@ +/* + * Copyright (C) 2026 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.jetpackcamera.ui.components.capture + +import androidx.compose.foundation.layout.width +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.android.tools.screenshot.PreviewTest +import com.google.jetpackcamera.model.CaptureMode +import com.google.jetpackcamera.ui.uistate.capture.CaptureButtonUiState + +// --- Standard Mode --- + +@PreviewTest +@Preview +@Composable +fun IdleStandardCaptureButtonScreenshotPreview() { + IdleStandardCaptureButtonPreview() +} + +@PreviewTest +@Preview +@Composable +fun IdleStandardCaptureButtonBlack60ScreenshotPreview() { + CompositionLocalProvider( + LocalCameraControlBackgroundStyle provides CameraControlBackgroundStyle.BLACK_60 + ) { + IdleStandardCaptureButtonPreview() + } +} + +@PreviewTest +@Preview +@Composable +fun DisabledStandardCaptureButtonScreenshotPreview() { + IdleStandardCaptureButtonDisabledPreview() +} + +@PreviewTest +@Preview +@Composable +fun DisabledStandardCaptureButtonBlack60ScreenshotPreview() { + CompositionLocalProvider( + LocalCameraControlBackgroundStyle provides CameraControlBackgroundStyle.BLACK_60 + ) { + IdleStandardCaptureButtonDisabledPreview() + } +} + +@PreviewTest +@Preview +@Composable +fun PressedStandardCaptureButtonScreenshotPreview() { + CompositionLocalProvider(LocalInitialPressedState provides true) { + PreviewCaptureButton( + captureButtonUiState = CaptureButtonUiState.Enabled.Idle(CaptureMode.STANDARD) + ) + } +} + +@PreviewTest +@Preview +@Composable +fun PressedStandardCaptureButtonBlack60ScreenshotPreview() { + CompositionLocalProvider( + LocalCameraControlBackgroundStyle provides CameraControlBackgroundStyle.BLACK_60, + LocalInitialPressedState provides true + ) { + PreviewCaptureButton( + captureButtonUiState = CaptureButtonUiState.Enabled.Idle(CaptureMode.STANDARD) + ) + } +} + +// --- Image Only Mode --- + +@PreviewTest +@Preview +@Composable +fun IdleImageCaptureButtonScreenshotPreview() { + IdleImageCaptureButtonPreview() +} + +@PreviewTest +@Preview +@Composable +fun IdleImageCaptureButtonBlack60ScreenshotPreview() { + CompositionLocalProvider( + LocalCameraControlBackgroundStyle provides CameraControlBackgroundStyle.BLACK_60 + ) { + IdleImageCaptureButtonPreview() + } +} + +@PreviewTest +@Preview +@Composable +fun DisabledImageCaptureButtonScreenshotPreview() { + IdleImageCaptureButtonDisabledPreview() +} + +@PreviewTest +@Preview +@Composable +fun DisabledImageCaptureButtonBlack60ScreenshotPreview() { + CompositionLocalProvider( + LocalCameraControlBackgroundStyle provides CameraControlBackgroundStyle.BLACK_60 + ) { + IdleImageCaptureButtonDisabledPreview() + } +} + +@PreviewTest +@Preview +@Composable +fun PressedImageCaptureButtonScreenshotPreview() { + CompositionLocalProvider(LocalInitialPressedState provides true) { + PreviewCaptureButton( + captureButtonUiState = CaptureButtonUiState.Enabled.Idle(CaptureMode.IMAGE_ONLY) + ) + } +} + +@PreviewTest +@Preview +@Composable +fun PressedImageCaptureButtonBlack60ScreenshotPreview() { + CompositionLocalProvider( + LocalCameraControlBackgroundStyle provides CameraControlBackgroundStyle.BLACK_60, + LocalInitialPressedState provides true + ) { + PreviewCaptureButton( + captureButtonUiState = CaptureButtonUiState.Enabled.Idle(CaptureMode.IMAGE_ONLY) + ) + } +} + +// --- Video Only Mode --- + +@PreviewTest +@Preview +@Composable +fun IdleVideoOnlyCaptureButtonScreenshotPreview() { + IdleVideoOnlyCaptureButtonPreview() +} + +@PreviewTest +@Preview +@Composable +fun IdleVideoOnlyCaptureButtonBlack60ScreenshotPreview() { + CompositionLocalProvider( + LocalCameraControlBackgroundStyle provides CameraControlBackgroundStyle.BLACK_60 + ) { + IdleVideoOnlyCaptureButtonPreview() + } +} + +@PreviewTest +@Preview +@Composable +fun DisabledVideoOnlyCaptureButtonScreenshotPreview() { + IdleVideoOnlyCaptureButtonDisabledPreview() +} + +@PreviewTest +@Preview +@Composable +fun DisabledVideoOnlyCaptureButtonBlack60ScreenshotPreview() { + CompositionLocalProvider( + LocalCameraControlBackgroundStyle provides CameraControlBackgroundStyle.BLACK_60 + ) { + IdleVideoOnlyCaptureButtonDisabledPreview() + } +} + +// --- Recording States --- + +@PreviewTest +@Preview +@Composable +fun PressedRecordingScreenshotPreview() { + PreviewCaptureButton( + modifier = Modifier.width(150.dp), + captureButtonUiState = CaptureButtonUiState.Enabled.Recording.PressedRecording + ) +} + +@PreviewTest +@Preview +@Composable +fun LockedRecordingScreenshotPreview() { + LockedRecordingPreview() +} + +@PreviewTest +@Preview +@Composable +fun PressedRecordingBlack60ScreenshotPreview() { + CompositionLocalProvider( + LocalCameraControlBackgroundStyle provides CameraControlBackgroundStyle.BLACK_60 + ) { + PreviewCaptureButton( + modifier = Modifier.width(150.dp), + captureButtonUiState = CaptureButtonUiState.Enabled.Recording.PressedRecording + ) + } +} + +@PreviewTest +@Preview +@Composable +fun LockedRecordingBlack60ScreenshotPreview() { + CompositionLocalProvider( + LocalCameraControlBackgroundStyle provides CameraControlBackgroundStyle.BLACK_60 + ) { + PreviewCaptureButton( + captureButtonUiState = CaptureButtonUiState.Enabled.Recording.LockedRecording + ) + } +} diff --git a/ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/DisabledImageCaptureButtonBlack60ScreenshotPreview_0.png b/ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/DisabledImageCaptureButtonBlack60ScreenshotPreview_0.png new file mode 100644 index 0000000000000000000000000000000000000000..7748076b73abfa175f35744c5905d78eb47c6c14 GIT binary patch literal 7341 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 literal 0 HcmV?d00001 diff --git a/ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/DisabledImageCaptureButtonScreenshotPreview_0.png b/ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/DisabledImageCaptureButtonScreenshotPreview_0.png new file mode 100644 index 0000000000000000000000000000000000000000..b4e34ecc88b6e152228b0becb2a097486b6fe493 GIT binary patch literal 7465 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 xWhpF-_$cI54 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 literal 0 HcmV?d00001 diff --git a/ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/DisabledVideoOnlyCaptureButtonBlack60ScreenshotPreview_0.png b/ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/DisabledVideoOnlyCaptureButtonBlack60ScreenshotPreview_0.png new file mode 100644 index 0000000000000000000000000000000000000000..bf4741c3b6bfaf147cea5ef4d0bafe489fd54c49 GIT binary patch literal 6707 zcmYLOc|4SB*iJ;UMu;)tAZ5?aSW-e^D7%rh8tY`=je`(bLfI!p_K|(x86=D?V;Q@# z8*3V5`CjLI-*^6*-~8Tp-uJoh=f0oozOHK`^`IJb*Ep_Sx^#)|v8LLyOP9!)fbZY0 zQUafRONg0Em)MUVtEn3JSP)SwX+PDO!#v5bWa)OyI^{j`5&SC|_vCLz)5)!DHsDB& z#FB{A?9}NiUU@~ZgT)+!b!%?}&q8B|Dzj0Q^Ar8^Kie(fDKY%{!Ik5L37}r_4xRBzdyf;2h08G8&!^Dl;f{vx2795PXCZ1 z2KIuWCyoRFN$-2Eo& zj&OBrnDy!L!9iOnRfqS|=F))5Ip_Xi<22HLB^uL16;;x(_*t&X$~|}+d(TCfles&$ zdt*E=DlZM;jGqlUZ)y%YM+R<=m$`J6z3NZXdz)h#8)Hi_IX_&CQ|FwTto*|3>eT+3 zpFBk)mXkWD?rybA+dcP9%-<$<0h|y6bIXc(T=?nHO6CT>=Ji+vJ-BeJ7&dn2TlE9s zx720x*u<`WXEP91(<2W*KgktzQr7Ics9sylp}UW28!QmF^50+XKhDcUI$%bKJI->v zkr>n#LpOYC@%Uil09OnHbuL6R*l5r$<_y^FdIjyBe2T@e)3==LX$7tg=lG4}>cq6W zSkT(|9_=kL!eVM9j|`>|wjD$QOw=0tNeN%Kv7oI;JNOCW{q1Z%f{SC<8{#YD!G|U6 z5o=~~0=l1m?Z)vuKu5}#jRnXt>vlHz$xJ~Tm!#5HOc)Q=M~gyRr|HMqQzhZ;)8hSc z_{fScylXRSXPCpjz&T%LifIu9Y2=WwfJH&b_m|Fkk5I9g)SGf2m#wQ1*CAfqvINcj zn_zf7kd0d6N%hV;;?m-BMlgV>$0DX7)31-se*mqK&7+*B{asp~>njz>|5R|x z12R5S?^)!2cd?Sn4g2g$AythItZbe(d~H-vJny*+9O^m$>zV8HKser_S6X7*`RP-6 zA^{W0tO_b*t~s9=jQ7~~I8QEJXLSrKOv&)-&}thDU++A%{N%}p4JwW8{G{a1@s}It z+$g)9n&*g@p8^wf<$&DT;e4xMdmRPwmccNa*15g3&8(>@LG?H`O6wg+CN)1nl-Stf ziL$c+%rnkF-{6RLNh=;H)I|yoMRefD_@nirl64VSHATD})<;#+PUGOGx*%oTxLr|9 zvZNqWH#>v2`J#k|=co)wA)&hc^8|37K?^P!E7mVw@Yy{+7`-iMBr}GZ{xFF}&P-L? zbVh}X*YA409t%93tdpM7bv*t3ar_om^H+!Sj_)C~bFTT1*kX2ps-MvGc1C<<&nEyz z5(8=w0>fD%qcD)us^%mHK#m8)V0ig`+roz7f}4Cc*>p*HK8u!d)%!gHnLppLiWIK& zryBlS{vCY(9gqdx11wSXZ*KE^>eigW&=sn$3QF7m-Z`99`;q*kF=l9pYKT? znx1H%Dmhcc?EWlWFL?oEB(t-WY#AQrD7EHnHBtWZpgoLcW1<2cLI1fSG{x?4;)EW_ z){;0|Jex=NSz0PjLHJ`Zn3~k(Y59%V$6}2uyxm|>x#+Wk^5(drB78XQOf*Tc4f$=5 zUO0dx;BF}-)K(bux?M^m44X6u_}=+xTJcI}oxQua-Fp$T_xuR!$C=Ys9#h!ObjC=HVrM_-E)mB5ef6_F=$!pV7&{op7>TgVmbLH&1< z#y3}&Ql4z;4RQ|<@|Cr+7C2&Km_$Zqv&FSaTft0Q8FoBLm%F>}b(MWUx_%$p!&;BR z9|K37za7J!U~+ALWq_f^vTEl^m~9OFPEPBeaKpSDy|UZ~q*$gCDu!Ec{EyPUbDB2# zxYllb3B$3glEKqFnAvP4w7`Fs$vB^xm3cbbVls{0jp9P2d#+9KGnpr)z$hS|RQ>3eDE)3Z zRWsu!bmJXvG0|79aZ5E3Z$#ZbGeaNSWfkT=EGqqQUqozqO7w`7F+0^vc3dY* z?|qT%S(Bg=DQb4lvaz8BIq=rcK7qh_9dYQjXk1au>e&tA)wDb_!%ZyVL7y#L!VGyl zVO^8`QcB6<6z0ePjzs3;&750Y<{xN2_-a`$T*MrAb8COqyVn`epa`Y|hxAF5mr zcz;%0<*kr_Jhx{oz^~P%zM4W^)rs2D8rrJyab|o?=ZK_?FAVGmr&Gn-uFcx`&&FaD z&>Np0mtNIH7v`g+-qZBQJxVdo@*4;iv`AjEVV|C9^mXSY!&&kC#Zr;T>XzkO-jyT* zJ6@lu2LKAXbG4dsmSf6~@I`{99Ju`eA!Ui1(+Mo}-!M1{gY&XMBqW$Zz$L!LrkPa^ zpe@3Cq5gFKcU^`g956YDP~&g6bSKV$SsW4OLG7iM$mm??#l==O(3dJnwfq`=LZ1ze z$@UyQH#vwezo;{`NSQ`~q!q%Fd2r95GFHdr{LwzVN5y-~{NZ`h>0ta$?C=)D9izz_ z#PlSykCw~h#gW;49&Es<4L)#vFN%9`6dc3Wy zJ7hSCx4P7hND&vp_jq+B6TWw`nDv)2x}joJMR0yQ%Z;|bMzb~I+QSX~&(BU72M^gg z5?)enq`z)vf3qs{T1!;Ag;iLO+>8wefU8d7_2XS^-yD2$B7eDiZ^Z5Bu`HZqhXU#TO}|g z%MpzBQ5+6ddVzNeCPCmxeqgAKT`j!gBd+^s^#fVmXaH;uxD<0-s4OKAbk2axhFSh4l!R4I(5nXeA3=hdW`oD21Y_5{N4-_nw1q6a&JS2J^;v1_ z9cJ|Lfq#BWuXiNSfg=rTW%%AFrQEYsf9L}>eQ(?E?~s3`m_f^c;g;f65N@+ST^7`) ztrH-p8@BS{Q9z3Ber6iPdrN8^69sgl%0dL?y$NEn=yL}O328;+>@4>mZ_FLf^xXlL z4J(hO^6xQMoqlc7YHu8(-(Jb?%&(VB=T* zj!h;2W|VauY>Yje6K<21TyUEtmp2A~4WAtJE4%-QVXUbmWB{Th^>=|aBKTVW-E_H3 z43qZ9F~7382+0K1n1Yjz2nN~9DNLWP8pg{L|DGzk^~?>RLF!E=I}kWulJEeF-6j3@ z&*|6t?5PxCIewZwGfn=W1DiI0uW>Z0nUbe4Ss-&RyHApd4Lwu(`sSZ?I~Ay$Ov)R) zh=pt-W;ZUw+x8ffFJ3^fICww&3}hz83iKYj4T7Z3U@^IAa%H)a+^xhh<46UFLZc<^y2efHL?o%<=3qpNO$Ovr*JgC_EPt?b(2L>RsfKkC?6> zt>_4uosJiOR0nx~H-IH+MAU%cZs2mlMXVj{k3G;P(AoOXl*!{99e)&p}>Yb(gql|A7c{U%QOjQp!Bs;(ea<8C7GsECz;Sl zRqdB~P}HRH3q)_tKULiORdTTmR`X)VGfCbaRALD~;5tzV*GE%gvjP`sDqobdZF@}< z-MSz$O{PsJ^wpE5&z|Apc_xR48=aR~dhr$3J$nuh=&YWYR2cq$A8fGyUt{ksc7w>Y zdqS?za9no(5upY8FZuP!Do5*%geG9L@dE8_lK`|g2=~`hp!rFYz}^D~1Ax`G^Is#n zAab1oYa)~-O<#s!?)jc6_q+Z@@lK!`Hguov4&KjwfkT_peUX3p5Nk+v*V?ZU7s=A+ z#n(4Caz7VCWsZ-i3N~_huz|T|sAyRJ%6oJCdI%d;gRlvg0FaH@e&*!XR9(eW0VAi* z@JIBVa*QEx>R0lG|A7Gj7Wv;SnmA<8rWQ%)VC|T=L_kdxAL;h@Bnp5$Z90vHB29Md z`g4K-m`bgU!rrBE)BYxXUQp+=yU^da=`QKh zm~kbY2yRu{F>onQQ3JqwS8T&aeYZ}ew|rc(4%e7h4TxKZpAq~(8x>((nL_NT)qh?8 zq<;$lcxSR(pdkRkJpp(uwI1EWDbYDN0Mu{fNND*3xjcVO+V)Rzs?`wB;J)#VaFJyiwY2f+L?vO?=Q+BP0!|G8b%6czi@(KUmjRwqBiWABZ* z15)Jg-&MDSCkNwAB0g3~w;IjOi?ZY-vJv$59m0tC8rk)>zgR{P6Qxe37O_Vl3S8P! zDlJQHB3nj`okj6Dvj9|Ty)6qE4D>s!ULlUxxrBPy{+r{SYROw*qrjy3vHLLV-xP-*;)mr{n*o+BAv@J7bk91Jd{f)w) zUIT3}YhEgUU|s0vMN4K!9F+yJ!;d#jRx63hunzt76jlu|$Vh;ZM_9qaBAVr#jdm4e z=Jpaf?Pr9`0H_MzDjr$WOo{pyGi_qOGM&fa<0vlHw!JXUtE`)SR8IL$kzx3p`&msy zEFba?70s08*c{BZE1I2-2V&17kS5?L&flE5Rg5p3g>J}1R4~n%nRjk}<%xY~0^go# zqH9{QdZ>{AqOBJ-E&m!%;pif=HL&nCA~_hw#TMN8j*ZH>XvY0>l%=9MV;7l2}?L#@~VkMja{)HgO!^Ks4aN2}T=Q0xxRGR9)x`g&z_uHj0Zo@-0J zzXnt}&Sb+9RHW=pqQdi7QkTw^pw#@cBTiYL@ummR<@A}TE_DaASK%g zs1(|&G~ucaL|n-UCm*tE=FEoZmu|c-aYw}=Vic>@K2*N$FMJAf02D02LH6~`l$(7)f#rpmpw-&AuWBW78T zdLj&HcS_?cURJ`GUw|pe>ZH+~bB#Br7Wi{H;2SQarw19?K!;I_^XetO0KXYfyDM^S z<%m06-s>+rBhL&WmQY0}0>W2TuqQI)M^D$Wd#i08?^WmGKrt zD3v`;c$rG3V}aOVBb}0FNo9$~=jmL4_Z8W7S9UOWy@~=*-otY_y?$n?Leb=vM>6-i zp|nz>@*%f}F766;vDABiSdfIhC#+ePnFm7G*sTJVJ{tR7D>lfqT}q+qRV6(pK}7eeV~AEL*<%Y;c7ZDUHnZUEE^k7^9_m2ui7jBj(J3X_ z0rZ#B=bLJxxggsA!IwR5Pz|&yC4z1?c)Q(up<#_A!t#%!us&X9Yn|=UTOlVL^0h}4 ze75dR3Z=py(+xu@UHd|3d$tiBsSzPKpColplR`Q;pIkhWOE3rJXvms4^tFa==4qdm zNMd6O0y}Xz8FWL%mUVZ@Vj4w{-^`8~*fBk0I8V-O8(4tvRUDA2=$7B@{J1e{sq#E& z_`;TX$o~g@uD3T=lz2-@Ml&eq7;qY3R^@58XI*b!uFUasBp)5h*62{j3v1E8KlC}> z!V!BX=|D149yrzuN2uKIV4eF?x3B47!g`U8L0_$Hb_}ZzhyJ5^xdC#H1^O7^Dgaf} z5d5+`%x5U;5uGbwG~I{T*}ZR`TmXcmjQd<`aA|p36vkDZy#F(JR3Ee(OE~Agsv_yy zMYEl~3nj3#jCncLDsi%+E}RI)Yx;H5^+Y&;`W%&6$MzKfv)`wsXrE&bapk|!uMoy#aQP`SM&a)ysj`nkDS@XtfPQ@Zfn-k0khNAHc z9xn{}qTqtRFecf#`anCX<9j^az_j0{&5a^+haf@8Joi0>35(UVy*Yh=vgJ7Pf>Z;i zngk_vuf#=1zZs+DZbjUy&&(Uhp_K=JcumqEL4cf2N;7VWDL;FvaCCp``~2DIAJCC! zm#(fxR+~pqfO1}k`Fg%482^uW^f*5{6;wc2VkO#J0K-~*MeWMQcnD`1<8}ClG>sZD zK#47Aa|)mIh6V{*bW`_98RCd}@l($ZX8x{Uym zQcBmWlqrLMM6n39TV-CGO}$ym+(9(ADcT%(iw1_&`?YDIs|o3&Ce+KhN~N z?jbm}@Inx&2wM~FnhJ;w?mnzb>@0JQ4vn1+Oa~Bgfk16bNvr5a-Rj7f$~5!5G-<8@ z5R+m7#?6wm&*Qp#;-W@g$xJ2L2Jf<1d}*EIOIEw_x>1;e@%gOD%*cIbn0_=C}qZbH3t)>r6}~ oG_!Mn0N(~2>0N(R`4JZvnW<4~?^|Qw&!9_>A3@c=J+KP-A3W7@-2eap literal 0 HcmV?d00001 diff --git a/ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/DisabledVideoOnlyCaptureButtonScreenshotPreview_0.png b/ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/DisabledVideoOnlyCaptureButtonScreenshotPreview_0.png new file mode 100644 index 0000000000000000000000000000000000000000..716fe005e813f9ef133737c370568982f71b7bc8 GIT binary patch literal 6778 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 Wb2D~=oq>N!M2{Zms8^_22K^6eZ!L@f literal 0 HcmV?d00001 diff --git a/ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/IdleImageCaptureButtonBlack60ScreenshotPreview_0.png b/ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/IdleImageCaptureButtonBlack60ScreenshotPreview_0.png new file mode 100644 index 0000000000000000000000000000000000000000..2cf1bf5a3cad04ff308564fee30eb918fd0bdeba GIT binary patch literal 7871 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 L>v5UltKk0!!#3Ew literal 0 HcmV?d00001 diff --git a/ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/IdleImageCaptureButtonScreenshotPreview_0.png b/ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/IdleImageCaptureButtonScreenshotPreview_0.png new file mode 100644 index 0000000000000000000000000000000000000000..352406ae733877346de9a73917d5cda87e1823d3 GIT binary patch literal 7668 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 w!4e{e<6vmnxzXZ6eQJBkd3catnlvLwb5VHnA- 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 kU6lOo=C1b#_!WL>_o=ieX45n#K+I0=6(Wwqs#o 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 literal 0 HcmV?d00001 diff --git a/ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/PressedImageCaptureButtonBlack60ScreenshotPreview_0.png b/ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/PressedImageCaptureButtonBlack60ScreenshotPreview_0.png new file mode 100644 index 0000000000000000000000000000000000000000..704e42c1c200c87abc56e6e87367bd9e79ea0b66 GIT binary patch literal 7859 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 literal 0 HcmV?d00001 diff --git a/ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/PressedImageCaptureButtonScreenshotPreview_0.png b/ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/PressedImageCaptureButtonScreenshotPreview_0.png new file mode 100644 index 0000000000000000000000000000000000000000..f8ec851aab9c1b3731a9ba2e4e9b6f98adb69bcd GIT binary patch literal 7654 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ý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 F{6Ck^C+q+K literal 0 HcmV?d00001 diff --git a/ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/PressedRecordingScreenshotPreview_0.png b/ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/PressedRecordingScreenshotPreview_0.png new file mode 100644 index 0000000000000000000000000000000000000000..13785ff2f8008c3df2256bce662e5637536014d2 GIT binary patch literal 10529 zcmYLvcR1T!*nh`UYE@fGP&}%L(TWjTv#1q*L1P&Hcwk6mikjy+=6*4Bzydo?yi z?WT5O)c$?-eXsZT&$-C;J?Gr#-uLIe!!^|vsmK}0uU)%FrL6Q)``WeZ5y0O)w@HBY zFtwoL+BNVm<(D$L?@YHc$ZDD4sXHIEj7AC!XL#cGa~nd|UN_(i+`FThJ%lF=mfu)@-TFL>i$Sfh zk7F*@rDg4jRUaxn2~bk?~=^8A;gv_s@Wx0W63 z>F=(E*I)y%>YozZtbgj1^dgrZQvqBCyLONI*vj0z3hTBi$XIx&HFwkSs`FDBKnsE3NeS2(< z^mVto5IIK}5#-A%oYqU!KhRf`$pORG7pX_+?ts8HMjX#Msv1iW!_bHv0`GS+7+}~KgivD2tT1dd=0EE`QXa3DIsJurZ zp077Az1ph$*=g2BL>CSxCa%_`UgM-v-eaO;w`$L9$^tId(F8|)jG1`U-Zk-b#TV|a z=sM>ynR@jg(ZnH%3Crq`V23H#!mT6SdE4=cu`%#%K1QVRL5iZUU@kXOgf6Nh%042O zL2KR_;FwyJ?6za*8WQ`1{uS2Ap-&DS`;yqvv(D1*v+(;!Zo3qQr>spU3l_V#FSoUV4iI6KA1^g$Sln-$ksf`8cY){BJz0@ljsm=JVn6rA+ay_c&oqgzodfV0VUf(w6#MW$~HA|$dwNF@QJ(^yw5f> zxrDd&d`NXqFdeB=TORfjw`h{+50|FU1TrBOS z8Hlf-pqBb%>Ca*(_+MlSJjA@4k|_~;k5`R?yd>Qf@qjR`K@;z^^SX;8*?4Jl^o&4Y zu;+|Yv!{+k&s3TR38>g-8?q;!TJ+oAlfkn}9;*}`7i3q8mzMMDl|csSCxUf5G*6=P zQ@OXoIH%KIHx$1vf$OrM9{WC4Q2W#UNa#~nriLQ4<}Fe6c3sao8sR79tB7k&7;5j- zUSm+AsdI=swd}P`jgdgukNeB^ID^3@B;&TBH*o_A(8nB<&TCxyKf>=}f362V&zQNa8T6U7cjd#|^5j!WlT&qZG+VPd-ApzDfVuw9%4Pt%X6X^t{#h9#g*U-+uqxCar4Gu%rIZ z(g)}rzJg*+bo>%)nQzzcQk$4A=j$-1QXpd$x0NMhBBv5V z35-pdx1;wln#%9Y$e8q=xcVy{^OW$^SG&pGCN z+R5-VJMR=v##k?1PTJ!X3;0?6-k~|e1Dp;e4f}nXJSn>gXmN*%Ic*>6c@?Zb;-@~3 zOxNaT-pYlnFJr7&z#ODOPL6v zUftfOZ(6@BYd#t(FZbhqmeP}G`&j@#@#&SDFOM)3O8#Mv!9g|a>Ht(qz!Nov)TE&l zG3cC#qru6sj)t1QcImCNi|n9>ZqD>)2x+f%@lpS>^My$&)=YKj|9oBw(JDmb*bG7o zQVf6N+|!Pehh5}k?g};m9@Gf^+$#{ zy|Vr!usx7r&@d>9O2J3Dg*+-aQD^$LVe*q#di;+SVpu*g#?8$9(_v9szTv=mHh6>; z^=%G#E*~DxJx-8!#8xS?d%<4pKerq#6I|l4t!*lqT2l)6e%B0 zk@@s}oNfkEAySD|^3b3=!FRo}Zn()~3bKwOnE4hli+h4Bqwb-n^52HMZ09L)R00f2 zYPBYb(k8Gtk`Y=W^Tf4fEi8Umn|TZjxnE3IFI{j3cx3cN#WjlCy>Da0pPC4Imbv*6 znhXh99FS^~ew`J9aP3)!_*=1y#C0TgEiF)%B>|pAJa#qb!&z0A9GkBR;lfXmaRnC8 zt}}a`f_&<9PosvNShCK(QaaYeh!}dI z63s&l>=^}WECy2ci@&tY34AYUb$ulKrFY{7C_#7zWM*xMM`Gi5DKet&y5n(}gTt*j zc17<`wKaarObbf>#I%KcNlY@rZ~9?Ba^+N4&8xFmIMQI+Kzu!Uo&ae> zzoSj6sLy5Q#bqo}1}$Iq!~Nn|E6U+Fuki~CKGSWUF=F5D7B@<_E=1P@CdrSG3e720NcbxF7x zT=-YD2ZiS=zxb{>JwkA15PUpW5%N;Uz;SniIE4J_$G6uOTvvv-S)_0HvF?L)@^koh ziR#hVl#$|Pp2F#(0+{BvUlx8j^S2C|k)P1D9CM;Kj=fM%OY;s!*4qEs4c+Ljm@UJH zmU|X>W-c5T6=d(GuJ$L3tI=X#sIAvcn#N=2cfv1&(l{P0+yUmT$f5f?$h6{O4_vnxdI!iw*F5zOr^&`0<} z&%ej`CHU=qK&ZCtWB60Id`}O1JJ6gL{0@2qx6WK)ab>rtkmt+Yg)PqrO5K!+7MT?$ zLgg9F(Ui%n$}trY@LK=MR)9owejG zv&b%FJLCwVN0?#dH1NG#S;Dt6P)rqTx0!Fe}5qHoW#~_qW>bco}mVU6E zpNumby*iWCp-f_Yv|!(1#il3VO*hW`;y?36)l;$_if@ zl(txQ#QnM(ln87&e6{#B<%cIQi3C&ZQ(X)h`OOqTYnZOsC%r%CXHL#;sv6HBndK(^ zyqs!+lgUO<-YSb)0q{+D{^fB2AmDonZDyQUE#czrgGq#_kn$?hn?k7OXlH?c0h^f; z$%UZdDZ4Si>hFkJyUF@yKpoFytW*Bv+#BS`ca=fzNiQhbG1+!-S>H$#re*y}zgyvd zj>OL%?6=;eepc~Z^Ie4vK7`)%O*Hibzq?BDR2knayMAd-iL^pjXI!JcI4^92UKfpM z#H|NO6$82Z)PRlqqbxEJoF?kO#bWtzPSRua%@Cw!0!aTUg62`#0tet~4q4u&Te`w7 zcL!MX47kO1A3azz6;?6k@XTq@u)&^iW6eNHT~sI)(}Woq z+j&)*?r(UX%pYObA1+M(IbFEKo;m*xFZm)NRhts+GXSTfW9v3bvy=X;=K|DG4Dr^l zLI@+wW z6|RhBIcj)F)EN~B{0=$s8=O#n} zIsWMAG; zQ|{}zhVeal#278DRO?+idrmmlT3~Kt<7|o}rNrgL7cr6ocam~Rr&EyAFUQ%>gTSXs z2A$DS)rk-E1!5_le$Cd!WCcerHTxVDw497r?Y#YSJSF%0dLjt zlu>d&~Ve}xpcmf)8J$5iLY5XKEC0r1#+U? zlp?Bje@z&2oy?Z;$fIIbU{ZG84+u^)suAyd-*z#>N1^brGYKRH9v&r4(d7o1cX80X z;}NNX=lgLpX)>;W=~3D7>Cs??+%Oa$<_m&j+~c=c+Zqu2PV@A&|n@*LPl zYZ{Fw>1mqrQX19nTMV`C2eO)b=oXChNp?Xtm??Al-@*KNiL>1f93oGdT5>;T-K@U<8h(9~GY!`1j$zHZ!z?zIqQn5BQ7gkw+h%zT zeQ}J!WPe4rUhA$*aQ!n7%hqM*gpepL1&LM>&D3vQ0Jl3@WqP^5O+rAj8s^XCy*+E8_%0^pU_* zm{)f)gV4MGIJ#;Im@LkIHO{YslCvUN!$%bw&>S8;^K7lTE}>4lgXP z%(B4?EU!e$hzZain#bd>=9jKW1j1ww36NIOktAIFx=FTCU!zq}ogV~(w3VXF& zaeuGRJnVTWCZXd}eCf7jt%SC)mGx5gz9K7N0M_hjU@4JGZCEs`O6X!&8yL<#YD0-@hFoiRzv5+&k}Bm;dqr_%${}L8(fZ z7h_!Z9kxuxZBy)mkCEyuP%sawPPlcwrT}OE1mN^(5wPoz;JByFt5GU=9ln?K>y@|D zLucj#I&{D&p9!RE7ej?HvS>1(&^;Az0k1ZzV@B_+0D6h5;zI!AuI0)=`*IS`M$xfcCp)bdwF|hqF|UN9$hn z9A1vokeElv&K$zNmf{s-ZgyDKtTFM>(&7N6G!J(c>C?^BfLQh1wR~i4r`0Ep6(xT= z?`3;3yKte0^=NQjkg9Qg;wwz>XdeF`4H$3)w3-kveN1zu0cPzP!gF`0o4jh4W2B0> z!F{2r(;y{7fEGvRpG|&$I#~O@xZ{ANWnvu&bbyRHK0d*@%dO1rc*R^fc>*_*1 zueDU$6@Z3J6hV32*XXY)+l&=yQH3(`=tqMVuk>7WAZx*_A*b5=z~Rbmqzc(a18&21 zASEtSzf{cPe}(iwGIqa@w*sJ}tumeJ)H>Fp+s(kr=5?<(oqH{|59 zXZ3~ow3d_tW&vq|0nd4yBFtpXyT(R^(YgAr6cSPV1>Z)>>ONlxzv7T%ibmU}W2A`t z_?<1n@ff}ksPRS;{Q@NX`Ch5X#LXG%sgf27C#Y)ydhn@TPWtdF5i7S}GAIxKACVZa zR@xxRpr%mwB1>bK?X;kc>YU>fwyuG`*K0A>-3NiWjs_DlXyrmMz|HyH<6(bOtjXwp z{jl$lm#;JMqXDa#lKaFvIZWeW^SECGA=}@gcj+5d0TT~paWeK7#XK!-B=?D+gE0r=!q+74&_sLPz{Hqxk_?w>r+`|J03Z?SW#s0q5y8H;n- zo55_Sv`?R!R}0SumjeZ)E9yJF+SKkXJ)Lh#fBg~*Si;Q`fN=2TCXKjP&duZd<|6_8 zG2)s4xf7&cSyCKnBbn2rPJyt^31lMc4wI;^eSDXdrCIMsj%cnE*>-*}5tOFh1IhJt zx5zkm?JF9j9ImX|adnzDdXZ${=8jL6r4`I)5iOLi%lNuz_eYonVqb=a$)GQiOC!@* zltzVX2{81g7?-PUn<;Bt_Mh3@Rx8c%7Y~JWW^PV;`)#2|%lUz5yxacBpHD~x8e!8z zuRIf{;nOUfXtS^Hr}eR-*T+{#EESQkvOzG-Qfwp|%Ih({?m6ox<9ZfaP)k~V&>2p{ zTtk(3urVoanz9~ay$aNb9KzM42@D9--nZzS+O*uqF$alP%Pp~5%yj5LE(QOXkv!?2 za~V<$1#%MIYoD?SoirXbYhddFz~F%cImA-u_P+dIEEd)X7@Ps(?~*NqKs)`CAZ))C z?<&~mzjXQGvSu{8X{9FWZv93jll3GQC>5y0#4yFR@&Er)bV2_2&>^^7sNJXBs5egf z9v-P)`YDclBLnQdBU~Q=q&1ByE8+7-TM#Le5I*?-Vq_D4U#B=_(mm%YaLYSP8~1rf z3#(6A{SXBmAB3dQxB3Y1^)US8|+-V#QOF>XfsPb+7jgnGbS5XFGu{LC-HgVro zqR>ZrR!{!c}-wVI5W2Yia$meNU}gs1CBwoG)D6~5vu_c0>= z=)}fd@P9*3jQWaBO)MwUeDOs+f5MqdT~lGSSf7CSYU{hDUwMN-g+rit7&Hese#-_! z+1|n$gA;_t#T5RmlSGQgji+q7R>%Li9|3cY;%we+rx-duDcILB7>!a+9&=EsU`AD1 zdc$_6-uAHJbEU^5QpMw-(<6y-uW&~wT^-Foh>@)w2zxDLp4LaE9^;QBz!e`PjwkOG|T%eX_BZAU3yNwY}x>y^{x~Scsw8Nbr zE$pOMI9H~J2~VZ`NgDd}%#20s;?IdkzDS!86J$y)O+-G2@ik&#)c3wA z|4$>A!Oer^?jJxk_OOPEfkph^^P$PV3GK=Kej|CI8axs;4%e6eUUhy(98PnKTVHn@ zh`DZGUga`gzh2NXKD5QM$msH^dh+S#nSVx<)7RfhbsaE<43kToKSc^|X^ZLEPZkE9 zexpYuuxvWz{&#x#r6ptDXQz2B=LMljc0?;r;rSXP)9kPqudihH!$eWDHtBM$L-aJ3 z%)XXQ&IxgnJ`8m3?*7`|7O~0gq=?_iuj=Yy-tlj-jO}CkA!7EQTeDu7!6HyV?8ZLA zyGX?wdrn*1u>Z3RDq4N~S6kb~o!=&a%l-gUl;o0aa=p*(6LBz1M+5{SQVeI)Vf6=URmYGDD`&Egvy zB-GIj+!1ce4_5)i^ATegBNK9>%mu|qdp}caP~m+aDxhXqY8Ldt!Po)$;OyTbw0g;d zkC*$l{x)m0N_kWd6rkrFy!Je8QbLbczPjQi`Blwwd3yq zBF>R1?eACaA96p9F@!3=F9>t;Q6q6&*-ueDs zm)Vfm2H&_+0@qLFAT34)aaXGb@1L#v+bt)h`-?|ST)v;Fs9{Tzm!A&jkH#*jFZeGs zj-Pwq6so{fb&+UP_7jUofKsHYZ7Bc*$i3`3N0b7$4Qfkqw685_G=ufei<2X+taLx3 z$qvl_-Trs{@ciND{Yw^?mnUfhVmgjBJGP3y_zA(jiBem0Ubp^s@Q#$dCo4YrbhfpJvYXiy_&$|r zq?36WTwah}L|(?xAsdK$mr$AQ`TidFg)EzZWf!GT%r%-%H#~=e_cK6Bkm1c}o=#M_ zQ_D97+w|{dvW#K(bi_Mjf7SFbCUmWK?<+!PXV8VhqXw4fbix^D=oBrjNaZa2y?q3u z#JfrX7NnHtt7XU%0D827;-S2apIp2I{B40wW>H!Z$6-ofRgbf5%my?fH^?HYv9U2~ zdL=cs>!KShw3n8e)RpnU{A3@$*6WUYX&HkL%3(&FsHnO$D`;7R9?0t`OhhI?Dv>hW zt8KY1V~?uW3?G0&Ub;p52~$dc;DezKUyk9yduA^Rv-}zy{)Mse531Np3okr1{#yAu z1+F{c`cdjW5T9hdXjp=+6cx;6VIWEXMi3ChNKV~TQ|0S`l#-v{$4Ogow1I%`yl&># zkYl@mdn98|4W4PD(K!Fge@KUG3sRNQHsfYD*qn}Vq87ji$-k8=%(|HR-{^ zT;KRXgaM0K+|LAT+Z%m{yAmb3j5ZH)h-kl5y)*Wtzs+y^%`RHd!0oQcd>QVG7p(Dg zbmupNBy5H=O^!JW_>3ulevEV{izqEE3^{_I8z09EYG<~ef$Y73|C>4qQ)L7mHElyD z^n5<6Za^@i&#~yxG{EIdB49AOl>uV*UkRy$qU`ich=Uu(4Lz>zrT)(#4=DGOd=a)d z@=YHxfCnfu6R>j73~4b3#+#&f%F>dwS>!?~1&&_Y2Qvx`lAnpK)sxZQ0p;KxX7+Gh zu9dzFY^%zdX@QacTSqkz5g5c6CM<|K->qb~Pk;xlJ$?ll$dX=ght0Oj)Y)PniT(?4 z9UV=pw+=tBDeXbh#%uOwW$k2gaAOg|)S95( z%2Z&oAr;Z88fpo$o!IAN{6aUX-?8v|e!(pfz}$1dRe|Az^#984fngfE8H<&bgBr_=vb~zScs%d|nE8QvV#J)pot?y+OG+qs2zH7NNcr;T)kzD)=}Lw+4F$$l!|-{DC!H!&zn#HV2rONZ_%c|EdFY zID2=(2%O=}7L$~Nlc;+B0@TD-TtSX5X(+WuhS>PAY3<2*F$`O*)e{8F=)eSGs;t2I z!uL2{e_bCCk6R#(ngg&hP57s3T<@SAy*(!^y|Vm4-p`ez7f{62_);H}YL?U-fKFR# zE&b=yUjtq7)sIj%c>eM4+)cvTdk&SPu_$@yoz+a-0C?w%!&O@GcOdA`qftH?;y)zu zP^PGk$ogbTqN8UE^l3DZ-sXazQs$U^b~FsagBM$y^PX$X>to&u)6$kH6<2jJigpR> zk2tbXP)40cJL$wXWicK}sXJzulo*w%_E{)dPbBD`>ulePaZ5bXIA{f$DG|A~BwIfu zHm=KQp9OU%3a0DKi(;G~ONb_4Q90q!9!$2@_TtR@TQ)FawbmNRDm`DXQF5LK@R4@4 z)r{=!OgjJ;5#MaplM=AtbCq_>2Q}hX<7)HYY8M5?BEsf+WaX9*JB^X$_2=WS-2H{O zeH}RJfd84T%6VUjDQ+X@b@f0#KxD ziLcH{kilvqlCR>6!|DG}9@ZPrl@_f>sezX?7BA0fDu>xBD@20KujZg;3sui77|85{ zVN%5PVbMudQ^j#tAkswSx|7WEh1`R=m5CYCpp(BU5E{5wwfVuJ)U5NdIRFp8h}sZX zG8Tj@rtaw^m2{?yPyVOuN;t9G)Nmvx2L_kmbq}rUjFN8Wj835K%KDxQ)+UC@_ikkW zF8qu4T|JCo;lL@-V2)W>BOy#m(%N{!qAE{Ca8CB>;l}GjaY936~#VU2HB| zukeSuJFJT}dkn{Ab8~ZRHT^`bc6J64$CRrPIV#1}I90a?>_K+b76KA8r>Ttr=3ibh zw8;m&xV!9XgjyrZwvn^9@5kMy2_v)5kRb?*B**SXH;^F9ZwsjhH?>@FDq05_BrQQ80ip#s0RUnK!QS>~N5 z0f1Uf2_^l+``LO5)-N27z)xKipENG#)>r1|%ECWU9qvTpW4C@NxFr43E{L46P?DY5>{61b#!zrDHtUj)zc)Lkj6D;hK7c!S3iD^ z7>%G4X-O+CD43C~H*X~=$IL62qx+e4jE#Q=Dd3tI0|n25$ueTvGbg?tynIQdPAynl z?Kom_us&vM@8Hl4zQF>UQCJ&zRwv@NaQ$LpPoS??MiO@B_&G4JqJFpsi_+_)%rfyh zNfvQa_3^14X$+_r@jEE0_1a8L9=1^|?G$Q;Ax78l(hdevt$VY~#cmK>G%xySG6 zVhw~{CLI@g(_Hq6i`2WYR|Yuip4U20h`Mczi--(2WR#Tj6q(fjriR0xo)Ir={pYdr z1lhb&>W&ZD$W0dYQ10Q}6mgw-^*KL(n!E}(W#;DKBgf2TUhaSor^R=*PSkrP)q8Dr z9uZ#|QW(-7vYo|8Rv*KJPvZ1hGFp@gBirm6sXvDy5sZ?^MKVR$ir7l4QViSEGjd74 zKx5_?xU7bT$AP(-85z<&Ns&FpHV=&!4vrMM!_+?yeFKIisyVu*v z+}yI*S@N7O!HvAykSe#h4Whmh3#Pkkf67Ai<1oqQgXIm(_t>dVha@J{-?vCGF)`d7 zq!F+&n7tuc*~>-sG(okodT=K`HL<~MG2*@S&0A>4cpjtMMk(%W68_GMC>dC`C9D5f z9zNJ^&~ln|@A}PfADnkE<0h#&t0P8*a>{*Ni=F@p7nz8T+6ElPg2^;7{e=S$T_$7s zNFKlVk!m6J14<31N3IPKo*XbqsC8Sk$hz0eCsjY8BEx5SmjD=a2BOOjh(qcw9+IBa*UB z&r)dZn5!qM^F~2Ud9XbykZI}kKN(icvz-sSu-|RZz>eS-29~HRP7>d9O;Pv3(N9OT zw4CyMMPJbdt4fu{a{Q+HC0CZB&$81hL2y?T0ur)uIDWeZxrxYPMSq-1Jn|zSASG{5 zfsTf|NEoQINMJn$iPHjf{MDxoCp4s=z#N zI(5GMsw-Vp6(fTtnIM(yjJHL4E-P3$67ShQf` zb>rjX-1ytUMKXMfWgN2t%4G794Bf9eMrGepbnsO!{iIC;SeR4pWa{%-`O9};n6a5l ziV#3hno_3oQF!P}tt|OAUDUTcKSFVFF@_G(&Pg3Jn5$MkBSa?gMe&1>@~VuO31E*# zM_FDCCPP!kSh*$_O}++YiRHm=Zid_4qm%>q-`AtVB`w^ z6n*}zbmwrChn*@ObrKHTv|iFHeebtUwq)x4pvEHTbX#F$(>1%30L&#m;Zt@Y>8cra zzN}Nnn-BZ7j(G}L$QHy`$n-~0!BKRV=dK>}*W}hg#5a|0a~qhoHQA)WI`E7^ zbcYa5p7qa29MMhq!RC}pTM)k;nzDt`uG-y`1dxz6ou7Z)XD zfdTE2FMzk4mR7V7Zw2QaLG(>T#b|fZ!>&MRGZ#9VK(Pc+1v>MHQ;2KIS}u0lXrfYoCN91vv>zS&=pA-4u8JlR97pCNYN_ zCg<^{Jusd)m=g1AM&;ZR=QL4|f;APOfsL1!cl{`4{U965GMp$G)VQVqG~{Mye@|pL z{EmIqDDPg8VHF@ew#@wmkP_>P=hg5#XDQh1Jdg@h3#2i{{;x0l#-`r-H01x5~o|TNHh-g`?xbw0Bt#3V)EO+-%KPLt)r$Ez9tDs z(fS>%l`Vvkv{5NdH3rPy#Vj*Q_!}HB0_owzq!b3bav{A~mZBkxGRkWJHX}f34jfK= ztdU>JKYV_)yJ&p@0Y>wSiz~rLfSVYtWoeo9@39D^aVhv4G~jse?@Knn{T1DjARt&c zF)69|DDxZGCTyd66o8rA?t&Vax@I4kVh!1iKnI7yf5WR?rmDcwFA=HJ_+)kXOZ;U$vv9ZpaQ#keP?>V`^Yge10B{1i;_2lx8N_{`OUI;$ z`&Ip$P+Gu2f{>{o=t`r4o@)mG@{td}YyEGP2-C#iD!F42K=YdeAQ~J#j~Xb`4!Hms zCyDl*b0_dRML``8Q6vH?`o3S4YP%#pXlm#1cEW18{>A}Fdnj& zoDahFAPJ8|0^Z%BaIPYs%r=rIefd7S3;*I4dQu!N<0kz!#gXW8_Z3kfJ>`<}c2QwB zWY}YGr$s=n02Q*dS6P#IYY)KYQ{ACd^6>C8F-f`HEUz{!I*+35&#lT+U>)_FjkJdl zp7S?1X#ed;hvAY+a6d|3Jt;j1fp?Zd)iMozraaCwy5fCI2PZsK{p$A zDL`!it-C`4)P^N)$N$#`uF9jSpo_0-`apxl?2mAz#kaR5;}k0j^79oBxPWKU!({Uf zeYq!WAF8JU#|pYUPonP0S~U?(!$U}J;1=ZTb`^em==$9hP2@>shcr?>V^k946$C|R zw9^j+maqN}`(83<(S@7O@C1DOO$FBxcjzz0OX ziCB!iRL+fwdb}=rzv*;GWu(_N+mM+kJ^Truijf^l66L7>vuGBFp}E7&DboW1AUfA& zs!?e%L|C$l+4UR4V{gp^At3q{1$q4Tmk|uJs~jsUE3OIhj^*|1*LtT8dRq%gE|_o7 zv3f6;ktqO0HM%PMqsazLg0DpIkDMZGdQA)Ag z5y51`H<4gJmMrfNo8n_innkpW<(CxIL!D?gksMcpo)0?)1~$@>0?9U=v7CCz^%kI? z6oesoJIjD(CA3Qa@H4;eP*;8GcE(9oM!fIKd`)9x$F^z}kV0e>43Et1+$Pk&@S4_Q ziq))EtDP|1aM* ztvrnES-`$7vc{2J^%E1G6kxw2;a>yqMH+(WqFIn<0_ppqA$exiR#r#`dchCqFwa*S z|HU495k1#zU#6?Us?iUAJ5M!sZw|FT^8B?EiqfmI2U(j9PY!&HjgL3lUd8qbxZ zF#X{Gb(RcRT-FTOBPJ27fQUIhf?f}VJrHC!4)5s)_|9yAzK>Cbv_IJ2-=_=Xm&lsK z>#=D4YJNei25Kao5r89VV{kG+&hp!nJ@Z{=MWRM5rl_L0LPJA~yx(Vna1?T|HgX?- zCm5MiS2r5kn*YFiyA4r$(?dnf>Mkv<53df*Tdm5=L(7v)O1Ye`pilYp zG6t8-jaE9?GzUZUPFX{{@+)>jQGpzt5-GGFR(Q+-2I|ma^VT=4;Z6C+uGsGgQ2jc# zNty0zI(B&PN`E8gZD@v0t-XYjTU`gXH2coK@%Q+bfs_qTIi`?e%P%UbnCW7N_DWtn zM)+66DlOlp2Plc#G&2c1An-05EGKCo-bXNqKd>YYu6X3V#e~h&ww`xJ)vRlv-tQ+ za-(dGJX~hw_RWG3+CZ@Fp8gh6>>ccKQU<@acIFhxApZ06v|04xos8u~xvd5lg&7Pa za!udN!hJX#&c7h_JzXH%u4tYh+W~)kwl`=TtTq*Khp(lgqN1HZ93i_XPf0I2bl2t2 z5Qs8(Wy12&9*ZOB>F?#HIrf;C=|fW-8~#pBffdW&^dlMZDZxp^@)$1NaVu* zj<7W-W-(ZxZy;#=-Iree{_^bG57iY(-4fd*%^*H`9*6AVF|N6pq#_1{-&&7S_|nql z`YPZ*u#TO{OMl243bPP*X-9=+B53!XlcoCaC?T6|eh;`_VOLL%a=niE&KPuRe!RbG z8xC`{0VyZnVedOke`E1gOe?7HPPwWHEtdE2q@Bq`Bj2_JHV3`7!HbZY4fWd@ z^?YDgoet&DQ4$gkFZt(IpiRKBv--Dy`A#^^A(QOs$!60yerOnX@z*Pb(I~pvrgwlW zr?j+B5R?%gfFbJg_Q3DJagtW{;GyI2WqqCZ{#ZsPT!XQFYJE%D&uX}`T2=& zJRTR6vBv3rx{a>|lEhS22J<3Es+?$rwUt9aHc14xHYV-$H5RR=78~#Y{bKLk8(~FaNvlQrhg|x_y^r@6%DYi(|8C23sg8f4& zm0n)JUcZ7GsL_`bEbjN)|8T(CccSsE|thoSO+338Yi5RA#MX|PS;7!6Ft2|)1b4DjELUb;o;#8 z+k=Th4g}jf;=Y0xs(ZQlr#|Kr)yaxXK`35>*Ge`U~N3YX{fH zs(b0gJl`L#pzZBLSxFw~&{wWc)W=KKyUxm=m#f5a|Ghwn_ex*59E;6Ok;@rf5bv(! WMG%)7&4KrefRda#szk=@<^KVJ)*M;@ literal 0 HcmV?d00001 diff --git a/ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/PressedStandardCaptureButtonScreenshotPreview_0.png b/ui/components/capture/src/screenshotTestStableDebug/reference/com/google/jetpackcamera/ui/components/capture/CaptureButtonScreenshotTestKt/PressedStandardCaptureButtonScreenshotPreview_0.png new file mode 100644 index 0000000000000000000000000000000000000000..bb61aff4a5345a1274b0111f759b389fbe1229be GIT binary patch literal 5195 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 literal 0 HcmV?d00001 From 4fe64fe801a187f6c3e5618e328867c950b48f23 Mon Sep 17 00:00:00 2001 From: temcguir Date: Wed, 16 Sep 2026 19:48:27 +0000 Subject: [PATCH 2/5] Use tryEmit instead of emit inside finally block in CaptureButton --- .../ui/components/capture/CaptureButtonComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/components/capture/src/main/java/com/google/jetpackcamera/ui/components/capture/CaptureButtonComponents.kt b/ui/components/capture/src/main/java/com/google/jetpackcamera/ui/components/capture/CaptureButtonComponents.kt index 692c4115bb..7b0d839f5d 100644 --- a/ui/components/capture/src/main/java/com/google/jetpackcamera/ui/components/capture/CaptureButtonComponents.kt +++ b/ui/components/capture/src/main/java/com/google/jetpackcamera/ui/components/capture/CaptureButtonComponents.kt @@ -502,7 +502,7 @@ private fun CaptureButton( } finally { isTapping = false isCaptureButtonPressed = false // Manually unset pressed state - interactionSource.emit(PressInteraction.Release(press)) + interactionSource.tryEmit(PressInteraction.Release(press)) } if (shouldBeLocked()) { onLockVideoRecording(true) From 82970d898e0ec99eb6423c8a1b1401b354f0034b Mon Sep 17 00:00:00 2001 From: temcguir Date: Wed, 16 Sep 2026 22:39:48 +0000 Subject: [PATCH 3/5] Add translator descriptions for capture button accessibility strings --- ui/components/capture/src/main/res/values/strings.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ui/components/capture/src/main/res/values/strings.xml b/ui/components/capture/src/main/res/values/strings.xml index 587e7c752e..fd0a666708 100644 --- a/ui/components/capture/src/main/res/values/strings.xml +++ b/ui/components/capture/src/main/res/values/strings.xml @@ -107,11 +107,17 @@ View recently saved media + Capture Photo + Start Video Recording + Recording Video + Stop Video Recording + Lock Video Recording + Capture Button Unavailable Camera viewfinder From d4506908ad961c69675cea51827617739117faca Mon Sep 17 00:00:00 2001 From: temcguir Date: Tue, 22 Sep 2026 00:54:51 +0000 Subject: [PATCH 4/5] Add click semantics actions to CaptureButton and refine accessibility tests --- .../components/capture/CaptureButtonTest.kt | 91 ++++++++++++------- .../capture/CaptureButtonComponents.kt | 24 +++++ .../capture/src/main/res/values/strings.xml | 2 +- 3 files changed, 85 insertions(+), 32 deletions(-) diff --git a/ui/components/capture/src/androidTest/java/com/google/jetpackcamera/ui/components/capture/CaptureButtonTest.kt b/ui/components/capture/src/androidTest/java/com/google/jetpackcamera/ui/components/capture/CaptureButtonTest.kt index 8665479065..eff9974d8e 100644 --- a/ui/components/capture/src/androidTest/java/com/google/jetpackcamera/ui/components/capture/CaptureButtonTest.kt +++ b/ui/components/capture/src/androidTest/java/com/google/jetpackcamera/ui/components/capture/CaptureButtonTest.kt @@ -19,6 +19,7 @@ import androidx.activity.ComponentActivity import androidx.compose.ui.Modifier import androidx.compose.ui.platform.testTag import androidx.compose.ui.semantics.Role +import androidx.compose.ui.semantics.SemanticsActions import androidx.compose.ui.semantics.SemanticsProperties import androidx.compose.ui.test.SemanticsMatcher import androidx.compose.ui.test.assert @@ -28,10 +29,12 @@ import androidx.compose.ui.test.junit4.accessibility.enableAccessibilityChecks import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.onRoot +import androidx.compose.ui.test.performSemanticsAction import androidx.compose.ui.test.tryPerformAccessibilityChecks import androidx.test.ext.junit.runners.AndroidJUnit4 import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResult.AccessibilityCheckResultType import com.google.android.apps.common.testing.accessibility.framework.integrations.espresso.AccessibilityValidator +import com.google.common.truth.Truth.assertThat import com.google.jetpackcamera.model.CaptureMode import com.google.jetpackcamera.ui.uistate.capture.CaptureButtonUiState import org.junit.Before @@ -55,33 +58,46 @@ class CaptureButtonTest { @Test fun captureButton_standard_exists() { + var imageCaptured = false + var recordingStarted = false + var recordingLocked = false composeTestRule.setContent { CaptureButton( - modifier = Modifier.testTag("CaptureButtonTestTag"), - onImageCapture = {}, - onStartRecording = {}, + modifier = Modifier.testTag(CAPTURE_BUTTON), + onImageCapture = { imageCaptured = true }, + onStartRecording = { recordingStarted = true }, onStopRecording = {}, - onLockVideoRecording = {}, + onLockVideoRecording = { recordingLocked = it }, onIncrementZoom = {}, captureButtonUiState = CaptureButtonUiState.Enabled.Idle(CaptureMode.STANDARD) ) } - composeTestRule.onNodeWithTag("CaptureButtonTestTag").assertExists() + composeTestRule.onNodeWithTag(CAPTURE_BUTTON).assertExists() composeTestRule.onNodeWithTag( - "CaptureButtonTestTag" + CAPTURE_BUTTON ).assertContentDescriptionEquals("Capture Photo") - composeTestRule.onNodeWithTag("CaptureButtonTestTag", useUnmergedTree = true) + composeTestRule.onNodeWithTag(CAPTURE_BUTTON, useUnmergedTree = true) .assert(SemanticsMatcher.expectValue(SemanticsProperties.Role, Role.Button)) composeTestRule.onRoot().tryPerformAccessibilityChecks() + + composeTestRule.onNodeWithTag(CAPTURE_BUTTON) + .performSemanticsAction(SemanticsActions.OnClick) + assertThat(imageCaptured).isTrue() + + composeTestRule.onNodeWithTag(CAPTURE_BUTTON) + .performSemanticsAction(SemanticsActions.OnLongClick) + assertThat(recordingLocked).isTrue() + assertThat(recordingStarted).isTrue() } @Test fun captureButton_imageOnly_exists() { + var imageCaptured = false composeTestRule.setContent { CaptureButton( - modifier = Modifier.testTag("CaptureButtonImageOnly"), - onImageCapture = {}, + modifier = Modifier.testTag(CAPTURE_BUTTON), + onImageCapture = { imageCaptured = true }, onStartRecording = {}, onStopRecording = {}, onLockVideoRecording = {}, @@ -90,63 +106,76 @@ class CaptureButtonTest { ) } composeTestRule.onRoot().tryPerformAccessibilityChecks() - composeTestRule.onNodeWithTag("CaptureButtonImageOnly").assertExists() + composeTestRule.onNodeWithTag(CAPTURE_BUTTON).assertExists() composeTestRule.onNodeWithTag( - "CaptureButtonImageOnly" + CAPTURE_BUTTON ).assertContentDescriptionEquals("Capture Photo") - composeTestRule.onNodeWithTag("CaptureButtonImageOnly", useUnmergedTree = true) + composeTestRule.onNodeWithTag(CAPTURE_BUTTON, useUnmergedTree = true) .assert(SemanticsMatcher.expectValue(SemanticsProperties.Role, Role.Button)) + composeTestRule.onNodeWithTag(CAPTURE_BUTTON) + .performSemanticsAction(SemanticsActions.OnClick) + assertThat(imageCaptured).isTrue() } @Test fun captureButton_videoOnly_exists() { + var recordingStarted = false + var recordingLocked = false composeTestRule.setContent { CaptureButton( - modifier = Modifier.testTag("CaptureButtonVideoOnly"), + modifier = Modifier.testTag(CAPTURE_BUTTON), onImageCapture = {}, - onStartRecording = {}, + onStartRecording = { recordingStarted = true }, onStopRecording = {}, - onLockVideoRecording = {}, + onLockVideoRecording = { recordingLocked = it }, onIncrementZoom = {}, captureButtonUiState = CaptureButtonUiState.Enabled.Idle(CaptureMode.VIDEO_ONLY) ) } composeTestRule.onRoot().tryPerformAccessibilityChecks() - composeTestRule.onNodeWithTag("CaptureButtonVideoOnly").assertExists() + composeTestRule.onNodeWithTag(CAPTURE_BUTTON).assertExists() composeTestRule.onNodeWithTag( - "CaptureButtonVideoOnly" + CAPTURE_BUTTON ).assertContentDescriptionEquals("Start Video Recording") - composeTestRule.onNodeWithTag("CaptureButtonVideoOnly", useUnmergedTree = true) + composeTestRule.onNodeWithTag(CAPTURE_BUTTON, useUnmergedTree = true) .assert(SemanticsMatcher.expectValue(SemanticsProperties.Role, Role.Button)) + composeTestRule.onNodeWithTag(CAPTURE_BUTTON) + .performSemanticsAction(SemanticsActions.OnClick) + assertThat(recordingLocked).isTrue() + assertThat(recordingStarted).isTrue() } @Test fun captureButton_lockedRecording_exists() { + var recordingStopped = false composeTestRule.setContent { CaptureButton( - modifier = Modifier.testTag("CaptureButtonLocked"), + modifier = Modifier.testTag(CAPTURE_BUTTON), onImageCapture = {}, onStartRecording = {}, - onStopRecording = {}, + onStopRecording = { recordingStopped = true }, onLockVideoRecording = {}, onIncrementZoom = {}, captureButtonUiState = CaptureButtonUiState.Enabled.Recording.LockedRecording ) } composeTestRule.onRoot().tryPerformAccessibilityChecks() - composeTestRule.onNodeWithTag("CaptureButtonLocked").assertExists() + composeTestRule.onNodeWithTag(CAPTURE_BUTTON).assertExists() composeTestRule.onNodeWithTag( - "CaptureButtonLocked" + CAPTURE_BUTTON ).assertContentDescriptionEquals("Stop Video Recording") - composeTestRule.onNodeWithTag("CaptureButtonLocked", useUnmergedTree = true) + composeTestRule.onNodeWithTag(CAPTURE_BUTTON, useUnmergedTree = true) .assert(SemanticsMatcher.expectValue(SemanticsProperties.Role, Role.Button)) + composeTestRule.onNodeWithTag(CAPTURE_BUTTON) + .performSemanticsAction(SemanticsActions.OnClick) + assertThat(recordingStopped).isTrue() } @Test fun captureButton_pressedRecording_exists() { composeTestRule.setContent { CaptureButton( - modifier = Modifier.testTag("CaptureButtonPressedRecording"), + modifier = Modifier.testTag(CAPTURE_BUTTON), onImageCapture = {}, onStartRecording = {}, onStopRecording = {}, @@ -156,11 +185,11 @@ class CaptureButtonTest { ) } composeTestRule.onRoot().tryPerformAccessibilityChecks() - composeTestRule.onNodeWithTag("CaptureButtonPressedRecording").assertExists() + composeTestRule.onNodeWithTag(CAPTURE_BUTTON).assertExists() composeTestRule.onNodeWithTag( - "CaptureButtonPressedRecording" + CAPTURE_BUTTON ).assertContentDescriptionEquals("Recording Video") - composeTestRule.onNodeWithTag("CaptureButtonPressedRecording", useUnmergedTree = true) + composeTestRule.onNodeWithTag(CAPTURE_BUTTON, useUnmergedTree = true) .assert(SemanticsMatcher.expectValue(SemanticsProperties.Role, Role.Button)) } @@ -168,7 +197,7 @@ class CaptureButtonTest { fun captureButton_disabled_exists() { composeTestRule.setContent { CaptureButton( - modifier = Modifier.testTag("CaptureButtonDisabled"), + modifier = Modifier.testTag(CAPTURE_BUTTON), onImageCapture = {}, onStartRecording = {}, onStopRecording = {}, @@ -181,9 +210,9 @@ class CaptureButtonTest { ) } composeTestRule.onRoot().tryPerformAccessibilityChecks() - composeTestRule.onNodeWithTag("CaptureButtonDisabled").assertExists() + composeTestRule.onNodeWithTag(CAPTURE_BUTTON).assertExists() composeTestRule.onNodeWithTag( - "CaptureButtonDisabled" - ).assert(androidx.compose.ui.test.isNotEnabled()) + CAPTURE_BUTTON + ).assert(isNotEnabled()) } } diff --git a/ui/components/capture/src/main/java/com/google/jetpackcamera/ui/components/capture/CaptureButtonComponents.kt b/ui/components/capture/src/main/java/com/google/jetpackcamera/ui/components/capture/CaptureButtonComponents.kt index 7b0d839f5d..a41ca5df00 100644 --- a/ui/components/capture/src/main/java/com/google/jetpackcamera/ui/components/capture/CaptureButtonComponents.kt +++ b/ui/components/capture/src/main/java/com/google/jetpackcamera/ui/components/capture/CaptureButtonComponents.kt @@ -80,6 +80,8 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.Role import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.disabled +import androidx.compose.ui.semantics.onClick +import androidx.compose.ui.semantics.onLongClick import androidx.compose.ui.semantics.role import androidx.compose.ui.semantics.semantics import androidx.compose.ui.tooling.preview.Preview @@ -350,6 +352,7 @@ internal fun CaptureButton( modifier = modifier, onPress = { onPress(CaptureSource.CAPTURE_BUTTON) }, onRelease = { onKeyUp(CaptureSource.CAPTURE_BUTTON, it) }, + onStartRecording = onStartRecording, onLockVideoRecording = onLockVideoRecording, onDragZoom = onIncrementZoom, captureButtonUiState = captureButtonUiState, @@ -397,6 +400,7 @@ private fun CaptureButton( onDragZoom: (Float) -> Unit, onLockVideoRecording: (Boolean) -> Unit, captureButtonUiState: CaptureButtonUiState, + onStartRecording: () -> Unit = {}, useLockSwitch: Boolean = true, captureButtonSize: Float = DEFAULT_CAPTURE_BUTTON_SIZE, interactionSource: MutableInteractionSource = remember { MutableInteractionSource() } @@ -575,6 +579,21 @@ private fun CaptureButton( role = Role.Button if (!captureButtonUiState.isEnabled) { disabled() + } else { + onClick { + onPress() + onRelease(false) + true + } + if (captureButtonUiState is CaptureButtonUiState.Enabled.Idle && + captureButtonUiState.captureMode == CaptureMode.STANDARD + ) { + onLongClick(label = startVideoDesc) { + onLockVideoRecording(true) + onStartRecording() + true + } + } } contentDescription = when (val uiState = captureButtonUiState) { is CaptureButtonUiState.Enabled.Idle -> when (uiState.captureMode) { @@ -751,7 +770,12 @@ private fun LockSwitchCaptureButtonNucleus( .semantics { contentDescription = lockVideoRecordingDesc role = Role.Button + onClick { + onToggleSwitchPosition() + true + } } + .focusable() .pointerInput(Unit) { detectTapGestures { onToggleSwitchPosition() diff --git a/ui/components/capture/src/main/res/values/strings.xml b/ui/components/capture/src/main/res/values/strings.xml index fd0a666708..9731e5a6ec 100644 --- a/ui/components/capture/src/main/res/values/strings.xml +++ b/ui/components/capture/src/main/res/values/strings.xml @@ -118,7 +118,7 @@ Lock Video Recording - Capture Button Unavailable + Capture Camera viewfinder From 708519f2a4b3e59b3e3edd9d7cdb37d4eb061a54 Mon Sep 17 00:00:00 2001 From: temcguir Date: Tue, 22 Sep 2026 02:09:56 +0000 Subject: [PATCH 5/5] Fade out capture button nucleus on release in standard capture mode --- .../capture/CaptureButtonComponents.kt | 136 +++++++++++------- 1 file changed, 81 insertions(+), 55 deletions(-) diff --git a/ui/components/capture/src/main/java/com/google/jetpackcamera/ui/components/capture/CaptureButtonComponents.kt b/ui/components/capture/src/main/java/com/google/jetpackcamera/ui/components/capture/CaptureButtonComponents.kt index a41ca5df00..9dc18431fd 100644 --- a/ui/components/capture/src/main/java/com/google/jetpackcamera/ui/components/capture/CaptureButtonComponents.kt +++ b/ui/components/capture/src/main/java/com/google/jetpackcamera/ui/components/capture/CaptureButtonComponents.kt @@ -23,7 +23,7 @@ import androidx.compose.animation.animateColor import androidx.compose.animation.animateColorAsState import androidx.compose.animation.core.FastOutSlowInEasing import androidx.compose.animation.core.animateDp -import androidx.compose.animation.core.animateDpAsState +import androidx.compose.animation.core.keyframes import androidx.compose.animation.core.snap import androidx.compose.animation.core.tween import androidx.compose.animation.core.updateTransition @@ -107,7 +107,7 @@ private const val MORPH_INTERMEDIATE_SCALE = 0.58f private const val BORDER_WIDTH = 3f private const val ANIMATION_DURATION_SIZE = 250 private const val ANIMATION_DURATION_COLOR = 150 -private const val ANIMATION_DURATION_NUCLEUS_RELEASE = 100 +private const val ANIMATION_DURATION_NUCLEUS_RELEASE = 50 private const val ANIMATION_DURATION_DISABLED = 500 private const val ANIMATION_DURATION_NUCLEUS_PRESSED = 50 private const val ALPHA_DISABLED_NUCLEUS = 0.6f @@ -803,6 +803,16 @@ private enum class NucleusState { Pressed } +private enum class NucleusSizeState { + Unavailable, + IdleStandard, + IdleImageOnly, + IdleVideoOnly, + PressedImage, + RecordingPressed, + RecordingLocked +} + /** * The animated center of the capture button. It serves as a visual indicator of the current capture and recording states. * @@ -838,77 +848,85 @@ internal fun CaptureButtonNucleus( val currentUiState = rememberUpdatedState(captureButtonUiState) val disableAnimations = LocalDisableAnimations.current - // smoothly animate between the size changes of the capture button center - val standardShapeSize by animateDpAsState( - targetValue = when (val uiState = currentUiState.value) { - // inner circle becomes a square when locked - CaptureButtonUiState.Enabled.Recording.LockedRecording -> - (captureButtonSize * LOCKED_RECORDING_NUCLEUS_SCALE).dp - - CaptureButtonUiState.Enabled.Recording.Starting, - CaptureButtonUiState.Enabled.Recording.PressedRecording -> - (captureButtonSize * pressedVideoCaptureScale).dp - - CaptureButtonUiState.Unavailable -> 0.dp - is CaptureButtonUiState.Enabled.Idle -> when (uiState.captureMode) { - // no inner circle will be visible on STANDARD - CaptureMode.STANDARD -> 0.dp - // large white circle will be visible on IMAGE_ONLY - CaptureMode.IMAGE_ONLY -> (captureButtonSize * idleImageCaptureScale).dp - // small red circle will be visible on VIDEO_ONLY - CaptureMode.VIDEO_ONLY -> (captureButtonSize * idleVideoCaptureScale).dp - } - }, - animationSpec = if (disableAnimations) { - snap() - } else { - tween(durationMillis = ANIMATION_DURATION_SIZE, easing = FastOutSlowInEasing) + val nucleusSizeState = when (val uiState = currentUiState.value) { + CaptureButtonUiState.Enabled.Recording.LockedRecording -> NucleusSizeState.RecordingLocked + CaptureButtonUiState.Enabled.Recording.Starting, + CaptureButtonUiState.Enabled.Recording.PressedRecording -> NucleusSizeState.RecordingPressed + CaptureButtonUiState.Unavailable -> NucleusSizeState.Unavailable + is CaptureButtonUiState.Enabled.Idle -> when (uiState.captureMode) { + CaptureMode.STANDARD -> + if (isTapping) NucleusSizeState.PressedImage else NucleusSizeState.IdleStandard + CaptureMode.IMAGE_ONLY -> + if (isTapping) NucleusSizeState.PressedImage else NucleusSizeState.IdleImageOnly + CaptureMode.VIDEO_ONLY -> NucleusSizeState.IdleVideoOnly } - ) + } - val pressTransition = updateTransition( - targetState = isTapping && - currentUiState.value.let { - it is CaptureButtonUiState.Enabled.Idle && - ( - it.captureMode == CaptureMode.IMAGE_ONLY || - it.captureMode == CaptureMode.STANDARD - ) - }, - label = "Press Size Transition" + val sizeTransition = updateTransition( + targetState = nucleusSizeState, + label = "Nucleus Size Transition" ) - val centerShapeSize by pressTransition.animateDp( + val rawCenterShapeSize by sizeTransition.animateDp( transitionSpec = { - if (targetState) { + if (disableAnimations || targetState == NucleusSizeState.PressedImage) { snap() - } else { + } else if ( + NucleusSizeState.PressedImage isTransitioningTo NucleusSizeState.IdleImageOnly + ) { tween(durationMillis = ANIMATION_DURATION_NUCLEUS_RELEASE) + } else if ( + NucleusSizeState.PressedImage isTransitioningTo NucleusSizeState.IdleStandard + ) { + keyframes { + durationMillis = ANIMATION_DURATION_NUCLEUS_RELEASE + (captureButtonSize * PRESSED_IMAGE_CAPTURE_SCALE).dp at + ANIMATION_DURATION_NUCLEUS_RELEASE + } + } else { + tween(durationMillis = ANIMATION_DURATION_SIZE, easing = FastOutSlowInEasing) } }, label = "Nucleus Size" - ) { isPressedImage -> - if (isPressedImage) { - (captureButtonSize * PRESSED_IMAGE_CAPTURE_SCALE).dp - } else { - standardShapeSize + ) { state -> + when (state) { + // inner circle becomes a square when locked + NucleusSizeState.RecordingLocked -> + (captureButtonSize * LOCKED_RECORDING_NUCLEUS_SCALE).dp + NucleusSizeState.RecordingPressed -> + (captureButtonSize * pressedVideoCaptureScale).dp + // no inner circle will be visible on Unavailable or idle STANDARD + NucleusSizeState.Unavailable, + NucleusSizeState.IdleStandard -> 0.dp + // large white circle will be visible on IMAGE_ONLY + NucleusSizeState.IdleImageOnly -> + (captureButtonSize * idleImageCaptureScale).dp + // small red circle will be visible on VIDEO_ONLY + NucleusSizeState.IdleVideoOnly -> + (captureButtonSize * idleVideoCaptureScale).dp + NucleusSizeState.PressedImage -> + (captureButtonSize * PRESSED_IMAGE_CAPTURE_SCALE).dp } } + val centerShapeSize = rawCenterShapeSize.coerceAtLeast(0.dp) val sizeFinal = (captureButtonSize * LOCKED_RECORDING_NUCLEUS_SCALE).dp val sizeInter = (captureButtonSize * MORPH_INTERMEDIATE_SCALE).dp val isLocked = currentUiState.value is CaptureButtonUiState.Enabled.Recording.LockedRecording - val cornerRadius = if (isLocked) { - if (centerShapeSize <= sizeInter) { - val fraction = (centerShapeSize - sizeFinal) / (sizeInter - sizeFinal) - val coercedFraction = fraction.coerceIn(0f, 1f) - LOCKED_CORNER_RADIUS + (centerShapeSize / 2 - LOCKED_CORNER_RADIUS) * coercedFraction + val cornerRadius = ( + if (isLocked) { + if (centerShapeSize <= sizeInter) { + val fraction = (centerShapeSize - sizeFinal) / (sizeInter - sizeFinal) + val coercedFraction = fraction.coerceIn(0f, 1f) + LOCKED_CORNER_RADIUS + + (centerShapeSize / 2 - LOCKED_CORNER_RADIUS) * coercedFraction + } else { + centerShapeSize / 2 + } } else { centerShapeSize / 2 } - } else { - centerShapeSize / 2 - } + ).coerceAtLeast(0.dp) // used to fade between red/white in the center of the capture button val isPressableImageMode = currentUiState.value.let { @@ -950,7 +968,15 @@ internal fun CaptureButtonNucleus( NucleusState.Idle -> { when (val uiState = currentUiState.value) { is CaptureButtonUiState.Enabled.Idle -> when (uiState.captureMode) { - CaptureMode.STANDARD -> imageCaptureModeColor + CaptureMode.STANDARD -> + if ( + sizeTransition.currentState == NucleusSizeState.RecordingPressed || + sizeTransition.currentState == NucleusSizeState.RecordingLocked + ) { + imageCaptureModeColor + } else { + imageCaptureModeColor.copy(alpha = 0f) + } CaptureMode.IMAGE_ONLY -> imageCaptureModeColor CaptureMode.VIDEO_ONLY -> if (isTapping) recordingColor else imageCaptureModeColor