Implement CameraX GPG QR transfer on Android (#106)
This commit is contained in:
1 parent
6669b77f4e
commit
d466b170ab
33 files changed
+1616
-162
No files matched your search
@@ -8,6 +8,8 @@ UniFFI API. Local-first and HTTPS onboarding is described in
|
||||
revision-checked [adaptive navigation](../docs/android/password-navigation.md);
|
||||
Home renders Rust-owned [Git activity and HTTPS synchronization](../docs/android/home-sync.md).
|
||||
Passwords and Preferences share [Rust-owned biometric authentication](../docs/android/authentication.md).
|
||||
CameraX GPG scanning and QR export are described in
|
||||
[key transfer](../docs/android/key-transfer.md).
|
||||
Remaining feature screens retain their milestone issues. The full [CI and emulator workflow](../docs/android/ci.md) documents the
|
||||
ARM-only runner/toolchain policy and artifact audits.
|
||||
|
||||
|
||||
+29
-13
@@ -16,6 +16,14 @@ androidx.arch.core:core-common:2.2.0=benchmarkCompileClasspath,benchmarkLintChec
|
||||
androidx.arch.core:core-runtime:2.2.0=benchmarkCompileClasspath,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.autofill:autofill:1.0.0=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.biometric:biometric:1.1.0=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.camera.featurecombinationquery:featurecombinationquery:1.6.2=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.camera.viewfinder:viewfinder-core:1.5.1=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.camera:camera-camera2-pipe:1.6.2=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.camera:camera-camera2:1.6.2=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.camera:camera-core:1.6.2=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.camera:camera-lifecycle:1.6.2=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.camera:camera-video:1.6.2=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.camera:camera-view:1.6.2=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.cardview:cardview:1.0.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath
|
||||
androidx.collection:collection-jvm:1.5.0=benchmarkCompileClasspath,debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,profileCompileClasspath,releaseCompileClasspath
|
||||
androidx.collection:collection-jvm:1.6.0=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
@@ -67,10 +75,12 @@ androidx.compose.ui:ui-util-android:1.12.1=benchmarkCompileClasspath,benchmarkLi
|
||||
androidx.compose.ui:ui-util:1.12.1=benchmarkCompileClasspath,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.compose.ui:ui:1.12.1=benchmarkCompileClasspath,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.compose:compose-bom:2026.09.00=benchmarkCompileClasspath,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.concurrent:concurrent-futures-ktx:1.2.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath
|
||||
androidx.concurrent:concurrent-futures-ktx:1.1.0=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.concurrent:concurrent-futures-ktx:1.2.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath
|
||||
androidx.concurrent:concurrent-futures:1.1.0=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.concurrent:concurrent-futures:1.2.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath
|
||||
androidx.coordinatorlayout:coordinatorlayout:1.1.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath
|
||||
androidx.core:core-backported-fixes:1.0.0=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.core:core-ktx:1.18.0=benchmarkCompileClasspath,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.core:core-viewtree:1.0.0=benchmarkCompileClasspath,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.core:core:1.18.0=benchmarkCompileClasspath,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
@@ -79,6 +89,7 @@ androidx.customview:customview-poolingcontainer:1.0.0=benchmarkLintChecksClasspa
|
||||
androidx.customview:customview:1.0.0=benchmarkCompileClasspath,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.drawerlayout:drawerlayout:1.0.0=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.emoji2:emoji2:1.4.0=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.exifinterface:exifinterface:1.4.2=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.fragment:fragment:1.9.1=benchmarkCompileClasspath,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.graphics:graphics-path:1.0.1=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.interpolator:interpolator:1.0.0=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
@@ -103,6 +114,9 @@ androidx.lifecycle:lifecycle-viewmodel-savedstate-android:2.11.0=benchmarkCompil
|
||||
androidx.lifecycle:lifecycle-viewmodel-savedstate:2.11.0=benchmarkCompileClasspath,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.lifecycle:lifecycle-viewmodel:2.11.0=benchmarkCompileClasspath,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.loader:loader:1.0.0=benchmarkCompileClasspath,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.media3:media3-common:1.9.0=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.media3:media3-container:1.9.0=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.media3:media3-muxer:1.9.0=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.navigation3:navigation3-runtime-android:1.2.0=benchmarkCompileClasspath,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.navigation3:navigation3-runtime:1.2.0=benchmarkCompileClasspath,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.navigation3:navigation3-ui-android:1.2.0=benchmarkCompileClasspath,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
@@ -128,6 +142,7 @@ androidx.test:monitor:1.8.0=debugAndroidTestCompileClasspath,debugAndroidTestLin
|
||||
androidx.test:rules:1.4.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath
|
||||
androidx.test:runner:1.7.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath
|
||||
androidx.tracing:tracing-android:2.0.0=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.tracing:tracing-ktx:2.0.0=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.tracing:tracing:1.1.0=debugAndroidTestCompileClasspath
|
||||
androidx.tracing:tracing:2.0.0=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.transition:transition:1.2.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath
|
||||
@@ -174,6 +189,7 @@ com.github.ajalt.clikt:clikt-jvm:5.0.3=ktlint
|
||||
com.github.ajalt.clikt:clikt:5.0.3=ktlint
|
||||
com.google.android.apps.common.testing.accessibility.framework:accessibility-test-framework:4.1.1=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath
|
||||
com.google.android.material:material:1.2.0-rc01=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath
|
||||
com.google.auto.value:auto-value-annotations:1.6.3=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
com.google.code.findbugs:jsr305:3.0.2=_agp_internal_benchmark_kspClasspath,_agp_internal_debug_kspClasspath,_agp_internal_profile_kspClasspath,_agp_internal_release_kspClasspath,androidLintTool,benchmarkCompileClasspath,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,hiltAnnotationProcessorBenchmark,hiltAnnotationProcessorDebug,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,hiltAnnotationProcessorProfile,hiltAnnotationProcessorRelease,kspBenchmarkKotlinProcessorClasspath,kspDebugKotlinProcessorClasspath,kspProfileKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,profileCompileClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
com.google.code.gson:gson:2.11.0=androidLintTool
|
||||
com.google.dagger:dagger-compiler:2.60.1=_agp_internal_benchmark_kspClasspath,_agp_internal_debug_kspClasspath,_agp_internal_profile_kspClasspath,_agp_internal_release_kspClasspath,hiltAnnotationProcessorBenchmark,hiltAnnotationProcessorDebug,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,hiltAnnotationProcessorProfile,hiltAnnotationProcessorRelease,kspBenchmarkKotlinProcessorClasspath,kspDebugKotlinProcessorClasspath,kspProfileKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath
|
||||
@@ -185,20 +201,19 @@ com.google.dagger:hilt-compiler:2.60.1=_agp_internal_benchmark_kspClasspath,_agp
|
||||
com.google.dagger:hilt-core:2.60.1=benchmarkCompileClasspath,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
com.google.devtools.ksp:symbol-processing-api:2.3.12=kotlinCompilerPluginClasspathBenchmark,kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugAndroidTest,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathProfile,kotlinCompilerPluginClasspathRelease,kspPluginClasspath,kspPluginClasspathNonEmbeddable
|
||||
com.google.devtools.ksp:symbol-processing-api:2.3.7=_agp_internal_benchmark_kspClasspath,_agp_internal_debug_kspClasspath,_agp_internal_profile_kspClasspath,_agp_internal_release_kspClasspath,hiltAnnotationProcessorBenchmark,hiltAnnotationProcessorDebug,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,hiltAnnotationProcessorProfile,hiltAnnotationProcessorRelease,kspBenchmarkKotlinProcessorClasspath,kspDebugKotlinProcessorClasspath,kspProfileKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath
|
||||
com.google.errorprone:error_prone_annotations:2.30.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath
|
||||
com.google.errorprone:error_prone_annotations:2.28.0=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
com.google.errorprone:error_prone_annotations:2.30.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath
|
||||
com.google.errorprone:error_prone_annotations:2.36.0=androidLintTool
|
||||
com.google.errorprone:error_prone_annotations:2.47.0=_agp_internal_benchmark_kspClasspath,_agp_internal_debug_kspClasspath,_agp_internal_profile_kspClasspath,_agp_internal_release_kspClasspath,hiltAnnotationProcessorBenchmark,hiltAnnotationProcessorDebug,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,hiltAnnotationProcessorProfile,hiltAnnotationProcessorRelease,kspBenchmarkKotlinProcessorClasspath,kspDebugKotlinProcessorClasspath,kspProfileKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath
|
||||
com.google.googlejavaformat:google-java-format:1.33.0=_agp_internal_benchmark_kspClasspath,_agp_internal_debug_kspClasspath,_agp_internal_profile_kspClasspath,_agp_internal_release_kspClasspath,hiltAnnotationProcessorBenchmark,hiltAnnotationProcessorDebug,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,hiltAnnotationProcessorProfile,hiltAnnotationProcessorRelease,kspBenchmarkKotlinProcessorClasspath,kspDebugKotlinProcessorClasspath,kspProfileKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath
|
||||
com.google.guava:failureaccess:1.0.1=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath
|
||||
com.google.guava:failureaccess:1.0.2=androidLintTool
|
||||
com.google.guava:failureaccess:1.0.2=androidLintTool,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
com.google.guava:failureaccess:1.0.3=_agp_internal_benchmark_kspClasspath,_agp_internal_debug_kspClasspath,_agp_internal_profile_kspClasspath,_agp_internal_release_kspClasspath,hiltAnnotationProcessorBenchmark,hiltAnnotationProcessorDebug,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,hiltAnnotationProcessorProfile,hiltAnnotationProcessorRelease,kspBenchmarkKotlinProcessorClasspath,kspDebugKotlinProcessorClasspath,kspProfileKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath
|
||||
com.google.guava:guava:31.0.1-android=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath
|
||||
com.google.guava:guava:33.3.1-android=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
com.google.guava:guava:33.4.0-jre=androidLintTool
|
||||
com.google.guava:guava:33.6.0-jre=_agp_internal_benchmark_kspClasspath,_agp_internal_debug_kspClasspath,_agp_internal_profile_kspClasspath,_agp_internal_release_kspClasspath,hiltAnnotationProcessorBenchmark,hiltAnnotationProcessorDebug,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,hiltAnnotationProcessorProfile,hiltAnnotationProcessorRelease,kspBenchmarkKotlinProcessorClasspath,kspDebugKotlinProcessorClasspath,kspProfileKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath
|
||||
com.google.guava:listenablefuture:1.0=benchmarkCompileClasspath,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=_agp_internal_benchmark_kspClasspath,_agp_internal_debug_kspClasspath,_agp_internal_profile_kspClasspath,_agp_internal_release_kspClasspath,androidLintTool,debugAndroidTestLintChecksClasspath,hiltAnnotationProcessorBenchmark,hiltAnnotationProcessorDebug,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,hiltAnnotationProcessorProfile,hiltAnnotationProcessorRelease,kspBenchmarkKotlinProcessorClasspath,kspDebugKotlinProcessorClasspath,kspProfileKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath
|
||||
com.google.j2objc:j2objc-annotations:1.3=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath
|
||||
com.google.j2objc:j2objc-annotations:3.0.0=androidLintTool
|
||||
com.google.guava:listenablefuture:1.0=benchmarkCompileClasspath,debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,profileCompileClasspath,releaseCompileClasspath
|
||||
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=_agp_internal_benchmark_kspClasspath,_agp_internal_debug_kspClasspath,_agp_internal_profile_kspClasspath,_agp_internal_release_kspClasspath,androidLintTool,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,hiltAnnotationProcessorBenchmark,hiltAnnotationProcessorDebug,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,hiltAnnotationProcessorProfile,hiltAnnotationProcessorRelease,kspBenchmarkKotlinProcessorClasspath,kspDebugKotlinProcessorClasspath,kspProfileKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
com.google.j2objc:j2objc-annotations:3.0.0=androidLintTool,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
com.google.j2objc:j2objc-annotations:3.1=_agp_internal_benchmark_kspClasspath,_agp_internal_debug_kspClasspath,_agp_internal_profile_kspClasspath,_agp_internal_release_kspClasspath,hiltAnnotationProcessorBenchmark,hiltAnnotationProcessorDebug,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,hiltAnnotationProcessorProfile,hiltAnnotationProcessorRelease,kspBenchmarkKotlinProcessorClasspath,kspDebugKotlinProcessorClasspath,kspProfileKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath
|
||||
com.google.jimfs:jimfs:1.1=androidLintTool
|
||||
com.google.protobuf:protobuf-java:3.25.5=androidLintTool,unified-test-platform-gradle-work-action
|
||||
@@ -252,15 +267,14 @@ org.bouncycastle:bcpkix-jdk18on:1.80.2=androidLintTool
|
||||
org.bouncycastle:bcprov-jdk18on:1.80.2=androidLintTool
|
||||
org.bouncycastle:bcutil-jdk18on:1.80.2=androidLintTool
|
||||
org.checkerframework:checker-compat-qual:2.5.3=_agp_internal_benchmark_kspClasspath,_agp_internal_debug_kspClasspath,_agp_internal_profile_kspClasspath,_agp_internal_release_kspClasspath,hiltAnnotationProcessorBenchmark,hiltAnnotationProcessorDebug,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,hiltAnnotationProcessorProfile,hiltAnnotationProcessorRelease,kspBenchmarkKotlinProcessorClasspath,kspDebugKotlinProcessorClasspath,kspProfileKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath
|
||||
org.checkerframework:checker-compat-qual:2.5.5=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath
|
||||
org.checkerframework:checker-qual:3.22.1=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath
|
||||
org.checkerframework:checker-qual:3.43.0=androidLintTool
|
||||
org.checkerframework:checker-qual:3.43.0=androidLintTool,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
org.ec4j.core:ec4j-core:1.1.1=ktlint,ktlintBaselineReporter,ktlintRuleset
|
||||
org.glassfish.jaxb:jaxb-runtime:2.3.2=androidLintTool
|
||||
org.glassfish.jaxb:txw2:2.3.2=androidLintTool
|
||||
org.hamcrest:hamcrest-core:1.3=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath
|
||||
org.hamcrest:hamcrest-library:1.3=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath
|
||||
org.jetbrains.kotlin:compose-group-mapping:2.4.21=composeMappingProducerClasspath
|
||||
org.jetbrains.kotlin:kotlin-bom:1.8.0=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-api:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-api:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-compat:2.4.21=kotlinAbiValidationCompatClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
@@ -298,6 +312,8 @@ org.jetbrains.kotlin:kotlin-stdlib:2.3.21=_agp_internal_benchmark_kspClasspath,_
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.4.21=benchmarkCompileClasspath,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,profileCompileClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-tooling-core:2.4.21=kotlinAbiValidationCompatClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlinx:atomicfu-jvm:0.28.0=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
org.jetbrains.kotlinx:atomicfu:0.28.0=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.11.0=benchmarkCompileClasspath,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.11.0=benchmarkCompileClasspath,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.9.0=androidLintTool,unified-test-platform-gradle-work-action
|
||||
@@ -333,4 +349,4 @@ org.ow2.asm:asm:9.9=androidLintTool
|
||||
org.ow2.asm:asm:9.9.1=composeMappingProducerClasspath
|
||||
org.slf4j:slf4j-api:2.0.7=ktlint
|
||||
rustls:rustls-platform-verifier:0.1.1=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugAndroidTestLintChecksClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,profileLintChecksClasspath,profileRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
empty=_agp_internal_debugAndroidTest_kspClasspath,_agp_internal_debugUnitTest_kspClasspath,androidApis,androidJdkImage,androidTestUtil,benchmarkAnnotationProcessorClasspath,benchmarkImplementationDependenciesMetadata,benchmarkReverseMetadataValues,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAnnotationProcessorClasspath,debugImplementationDependenciesMetadata,debugReverseMetadataValues,debugUnitTestAnnotationProcessorClasspath,debugUnitTestImplementationDependenciesMetadata,hiltCompileOnlyBenchmark,hiltCompileOnlyDebug,hiltCompileOnlyDebugAndroidTest,hiltCompileOnlyDebugUnitTest,hiltCompileOnlyProfile,hiltCompileOnlyRelease,kotlinCompilerPluginClasspath,kspDebugAndroidTestKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileReverseMetadataValues,releaseAnnotationProcessorClasspath,releaseImplementationDependenciesMetadata,releaseReverseMetadataValues
|
||||
empty=_agp_internal_debugAndroidTest_kspClasspath,_agp_internal_debugUnitTest_kspClasspath,androidApis,androidJdkImage,androidTestUtil,benchmarkAnnotationProcessorClasspath,benchmarkImplementationDependenciesMetadata,benchmarkReverseMetadataValues,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAnnotationProcessorClasspath,debugImplementationDependenciesMetadata,debugReverseMetadataValues,debugUnitTestAnnotationProcessorClasspath,debugUnitTestImplementationDependenciesMetadata,hiltCompileOnlyBenchmark,hiltCompileOnlyDebug,hiltCompileOnlyDebugAndroidTest,hiltCompileOnlyDebugUnitTest,hiltCompileOnlyProfile,hiltCompileOnlyRelease,kotlinCompilerPluginClasspath,kspDebugAndroidTestKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileImplementationDependenciesMetadata,profileReverseMetadataValues,releaseAnnotationProcessorClasspath,releaseImplementationDependenciesMetadata,releaseReverseMetadataValues
|
||||
@@ -8,11 +8,13 @@ import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.performScrollTo
|
||||
import androidx.compose.ui.test.performTextInput
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import de.rfc1437.ironstorage.core.OnboardingRepository
|
||||
import de.rfc1437.ironstorage.core.SetupKey
|
||||
import de.rfc1437.ironstorage.core.SetupStatus
|
||||
import de.rfc1437.ironstorage.features.OnboardingScreen
|
||||
import de.rfc1437.ironstorage.features.SetupFormViewModel
|
||||
import de.rfc1437.ironstorage.features.ShellViewModel
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertTrue
|
||||
@@ -32,7 +34,16 @@ class OnboardingScreenTest {
|
||||
val secrets = SetupFormViewModel()
|
||||
compose.activity.runOnUiThread {
|
||||
compose.activity.setProtectedTestContent {
|
||||
MaterialTheme { OnboardingScreen(repository, secrets) }
|
||||
MaterialTheme {
|
||||
OnboardingScreen(
|
||||
repository,
|
||||
secrets,
|
||||
SettingsScreenTest.Fixture(),
|
||||
androidx.lifecycle.ViewModelProvider(
|
||||
compose.activity
|
||||
)[de.rfc1437.ironstorage.features.ShellViewModel::class.java].authentication
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
compose.waitForIdle()
|
||||
@@ -60,6 +71,45 @@ class OnboardingScreenTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Test fun closingQrReviewReloadsPreparedOnboardingKeysWithoutCreatingAStore() {
|
||||
val original = FixtureRepository()
|
||||
val settings = SettingsScreenTest.Fixture()
|
||||
val secrets = SetupFormViewModel()
|
||||
var staged = false
|
||||
val repository = object : OnboardingRepository by original {
|
||||
override fun refresh() {
|
||||
if (staged) {
|
||||
original.setup.value = original.setup.value.copy(
|
||||
keys = listOf(
|
||||
SetupKey("SCANNED-SETUP-KEY", listOf("Scanned setup fixture"))
|
||||
),
|
||||
selectedKey = "SCANNED-SETUP-KEY"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
val model = ViewModelProvider(compose.activity)[ShellViewModel::class.java]
|
||||
val authentication = model.authentication
|
||||
compose.activity.runOnUiThread {
|
||||
compose.activity.setProtectedTestContent {
|
||||
MaterialTheme {
|
||||
OnboardingScreen(repository, secrets, settings, authentication)
|
||||
}
|
||||
}
|
||||
}
|
||||
compose.onNodeWithText("Create local store").performClick()
|
||||
compose.onNodeWithText("Import private GPG key").performScrollTo().performClick()
|
||||
compose.onNodeWithText("Scan GPG QR codes").performScrollTo().performClick()
|
||||
compose.runOnIdle { staged = true }
|
||||
compose.onNodeWithText("Done").performClick()
|
||||
compose.runOnIdle { assertEquals("SCANNED-SETUP-KEY", original.setup.value.selectedKey) }
|
||||
compose.onNodeWithText("Back to setup choices").performScrollTo().performClick()
|
||||
compose.onNodeWithText("Create local store").performClick()
|
||||
compose.onNodeWithText("SCANNED-SETUP-KEY").performScrollTo().assertIsDisplayed()
|
||||
assertTrue(!original.setup.value.configured)
|
||||
assertTrue(original.calls.isEmpty())
|
||||
}
|
||||
|
||||
private class FixtureRepository : OnboardingRepository {
|
||||
override val setup = MutableStateFlow(SetupStatus())
|
||||
val calls = mutableListOf<String>()
|
||||
|
||||
@@ -6,6 +6,8 @@ import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.test.assertHeightIsAtLeast
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
import androidx.compose.ui.test.assertIsEnabled
|
||||
import androidx.compose.ui.test.assertIsNotEnabled
|
||||
import androidx.compose.ui.test.assertTextContains
|
||||
import androidx.compose.ui.test.assertWidthIsAtLeast
|
||||
import androidx.compose.ui.test.hasText
|
||||
@@ -24,6 +26,7 @@ import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import de.rfc1437.ironstorage.core.AuthenticationRepository
|
||||
import de.rfc1437.ironstorage.core.AuthenticationState
|
||||
import de.rfc1437.ironstorage.core.CameraPreview
|
||||
import de.rfc1437.ironstorage.core.KeyTransferState
|
||||
import de.rfc1437.ironstorage.core.ProtectedPresentation
|
||||
import de.rfc1437.ironstorage.core.ProviderStatus
|
||||
@@ -31,7 +34,9 @@ import de.rfc1437.ironstorage.core.SettingsPage
|
||||
import de.rfc1437.ironstorage.core.SettingsRepository
|
||||
import de.rfc1437.ironstorage.core.SettingsState
|
||||
import de.rfc1437.ironstorage.core.TransferFrame
|
||||
import de.rfc1437.ironstorage.core.TransferKey
|
||||
import de.rfc1437.ironstorage.features.ApplicationTheme
|
||||
import de.rfc1437.ironstorage.features.R as FeatureR
|
||||
import de.rfc1437.ironstorage.features.SettingsScreen
|
||||
import de.rfc1437.ironstorage.features.SetupFormViewModel
|
||||
import de.rfc1437.ironstorage.features.ShellViewModel
|
||||
@@ -164,6 +169,69 @@ class SettingsScreenTest {
|
||||
authentication.presentation.clear()
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun privateQrActionsRequireFingerprintConfirmationAndExplicitClosing() {
|
||||
val original = ViewModelProvider(compose.activity)[ShellViewModel::class.java]
|
||||
val repository = Fixture()
|
||||
val authentication = object : AuthenticationRepository by original.authentication {
|
||||
override val presentation = ProtectedPresentation()
|
||||
}
|
||||
compose.activity.runOnUiThread {
|
||||
compose.activity.setProtectedTestContent(authentication.presentation) {
|
||||
ApplicationTheme(authentication) {
|
||||
de.rfc1437.ironstorage.features.SettingsScreen(
|
||||
repository,
|
||||
authentication,
|
||||
original.onboarding,
|
||||
ViewModelProvider(compose.activity)[SetupFormViewModel::class.java]
|
||||
) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
compose.onNodeWithTag(
|
||||
"settings-list"
|
||||
).performScrollToNode(hasText("Import or export GPG QR codes"))
|
||||
compose.onNodeWithText("Import or export GPG QR codes").performClick()
|
||||
compose.onNodeWithText("Export private key").performScrollTo().performClick()
|
||||
compose.onNodeWithText(
|
||||
"Confirm and export selected key"
|
||||
).performScrollTo().assertIsNotEnabled()
|
||||
compose.onNodeWithText(
|
||||
"I checked this fingerprint and authorize displaying its private QR codes."
|
||||
)
|
||||
.performScrollTo().performClick()
|
||||
compose.onNodeWithText(
|
||||
"Confirm and export selected key"
|
||||
).performScrollTo().assertIsEnabled().performClick()
|
||||
assertEquals(1, repository.exports)
|
||||
compose.runOnIdle {
|
||||
repository.state.value = repository.state.value.copy(
|
||||
transfer = repository.state.value.transfer.copy(
|
||||
ready = TransferKey(
|
||||
"SCANNED-FINGERPRINT",
|
||||
"Scanned fixture",
|
||||
true
|
||||
),
|
||||
received = 2u,
|
||||
total = 2u
|
||||
)
|
||||
)
|
||||
}
|
||||
compose.onNodeWithText(
|
||||
"Confirm and import reconstructed key"
|
||||
).performScrollTo().assertIsNotEnabled()
|
||||
compose.onNodeWithText("SCANNED-FINGERPRINT").performScrollTo().assertIsDisplayed()
|
||||
compose.onNodeWithText(
|
||||
"I checked this fingerprint and authorize importing its private key material."
|
||||
)
|
||||
.performScrollTo().performClick()
|
||||
compose.onNodeWithText(
|
||||
"Confirm and import reconstructed key"
|
||||
).performScrollTo().assertIsEnabled().performClick()
|
||||
assertEquals(1, repository.imports)
|
||||
compose.onNodeWithText("Done").performClick()
|
||||
assertFalse(repository.state.value.transfer.open)
|
||||
}
|
||||
internal class Fixture : SettingsRepository {
|
||||
override val state = MutableStateFlow(
|
||||
SettingsState(
|
||||
@@ -193,6 +261,8 @@ class SettingsScreenTest {
|
||||
var removals = 0
|
||||
var reloads = 0
|
||||
var choseImages = false
|
||||
var exports = 0
|
||||
var imports = 0
|
||||
override fun reload() {
|
||||
reloads += 1
|
||||
}
|
||||
@@ -211,15 +281,41 @@ class SettingsScreenTest {
|
||||
override fun openCredentials() = Unit
|
||||
override fun beginTransfer() {
|
||||
state.value =
|
||||
state.value.copy(error = null, transfer = KeyTransferState(open = true))
|
||||
state.value.copy(
|
||||
error = null,
|
||||
transfer = KeyTransferState(
|
||||
open = true,
|
||||
keys = listOf(
|
||||
TransferKey(
|
||||
"PUBLIC-FINGERPRINT",
|
||||
"Fixture GPG key",
|
||||
true
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
override fun beginSetupTransfer() {
|
||||
beginTransfer()
|
||||
state.value =
|
||||
state.value.copy(
|
||||
transfer = state.value.transfer.copy(setup = true, keys = emptyList())
|
||||
)
|
||||
}
|
||||
override fun cameraPreview(): CameraPreview? = null
|
||||
override fun exportKey(fingerprint: String, privateKey: Boolean, passphrase: String) {
|
||||
exports +=
|
||||
1
|
||||
}
|
||||
override fun exportKey(fingerprint: String, privateKey: Boolean, passphrase: String) = Unit
|
||||
override fun chooseQrImages() {
|
||||
choseImages = true
|
||||
}
|
||||
override fun addQrImages(uris: List<String>) = Unit
|
||||
override fun addQrPayload(payload: String) = Unit
|
||||
override fun importKey(passphrase: String, makeDefault: Boolean, overwrite: Boolean) = Unit
|
||||
override fun importKey(passphrase: String, makeDefault: Boolean, overwrite: Boolean) {
|
||||
imports +=
|
||||
1
|
||||
}
|
||||
override fun closeTransfer() {
|
||||
state.value = state.value.copy(transfer = KeyTransferState())
|
||||
}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" tools:node="remove" />
|
||||
<uses-feature android:name="android.hardware.camera.any" android:required="false" />
|
||||
<application
|
||||
android:name=".IronStorageApplication"
|
||||
android:allowBackup="false"
|
||||
|
||||
+25
-1
@@ -438,6 +438,7 @@ class NativeEntryViewerTest {
|
||||
keystore: MemoryKeystore
|
||||
) {
|
||||
var image = ByteArray(0)
|
||||
var cameraReceiver: ((CameraFrame) -> Unit)? = null
|
||||
val platform = object : SettingsPlatform {
|
||||
override fun autofill() = ProviderStatus(true, false, false)
|
||||
override fun credentials() =
|
||||
@@ -446,6 +447,13 @@ class NativeEntryViewerTest {
|
||||
override fun version() = "native-settings-fixture"
|
||||
override fun openAutofill() = true
|
||||
override fun openCredentials() = true
|
||||
override fun cameraPreview(
|
||||
frame: (CameraFrame) -> Unit,
|
||||
failure: () -> Unit
|
||||
): CameraPreview? {
|
||||
cameraReceiver = frame
|
||||
return null
|
||||
}
|
||||
override fun chooseQrImages() = true
|
||||
override suspend fun readQrImage(uri: String) = image.copyOf()
|
||||
}
|
||||
@@ -533,6 +541,18 @@ class NativeEntryViewerTest {
|
||||
image = output.toByteArray()
|
||||
request { settings.closeTransfer() }
|
||||
assertTrue(frame.modules.all { it.toInt() == 0 })
|
||||
assertNull(request { settings.beginTransfer() }.error)
|
||||
withContext(Dispatchers.Main.immediate) { settings.cameraPreview() }
|
||||
val luminance = ByteArray(size * size) { index ->
|
||||
if (pixels[index] == android.graphics.Color.BLACK) 0 else 255.toByte()
|
||||
}
|
||||
requireNotNull(
|
||||
cameraReceiver
|
||||
)(CameraFrame(luminance, size.toUInt(), size.toUInt(), size.toUInt(), 1u, 90u))
|
||||
withTimeout(30000) { settings.state.first { it.transfer.ready != null } }
|
||||
assertEquals(fingerprint, settings.state.value.transfer.ready!!.fingerprint)
|
||||
assertTrue(luminance.all { it.toInt() == 0 })
|
||||
request { settings.closeTransfer() }
|
||||
val qrStart = android.os.SystemClock.elapsedRealtime()
|
||||
assertNull(request { settings.addQrImages(listOf("content://public-fixture/qr")) }.error)
|
||||
val qrMs = android.os.SystemClock.elapsedRealtime() - qrStart
|
||||
@@ -559,10 +579,14 @@ class NativeEntryViewerTest {
|
||||
assertNotNull(request { settings.setDefaultKey(bob.fingerprint) }.error)
|
||||
assertEquals(fingerprint, settings.state.value.page!!.defaultKeyFingerprint)
|
||||
assertNull(request { settings.beginTransfer() }.error)
|
||||
assertNull(request { settings.exportKey(fingerprint, false, "") }.error)
|
||||
assertNull(request { settings.exportKey(fingerprint, true, passphrase) }.error)
|
||||
assertTrue(settings.state.value.transfer.exportedKey!!.privateKey)
|
||||
val privateFrames = settings.state.value.transfer.frames
|
||||
assertTrue(privateFrames.isNotEmpty())
|
||||
withContext(Dispatchers.Main.immediate) { authentication.presentation.clear() }
|
||||
assertFalse(settings.state.value.transfer.open)
|
||||
assertTrue(settings.state.value.transfer.frames.isEmpty())
|
||||
assertTrue(privateFrames.all { frame -> frame.modules.all { it.toInt() == 0 } })
|
||||
assertNull(request { settings.setDefaultKey(fingerprint) }.error)
|
||||
assertFalse(authentication.state.value.unlocked)
|
||||
assertEquals(fingerprint, settings.state.value.page!!.defaultKeyFingerprint)
|
||||
|
||||
+117
-5
@@ -2,6 +2,7 @@ package de.rfc1437.ironstorage.core
|
||||
|
||||
import de.rfc1437.ironstorage.bridge.NativeBridgeException
|
||||
import de.rfc1437.ironstorage.bridge.generated.MobileAuthenticationFfiException
|
||||
import de.rfc1437.ironstorage.bridge.generated.MobileCameraFrame
|
||||
import de.rfc1437.ironstorage.bridge.generated.MobileKeyTransfer
|
||||
import de.rfc1437.ironstorage.bridge.generated.MobileKeyTransferFfiException
|
||||
import de.rfc1437.ironstorage.bridge.generated.MobileKeyTransferImport
|
||||
@@ -10,7 +11,9 @@ import de.rfc1437.ironstorage.bridge.generated.MobileKeyTransferProgress
|
||||
import de.rfc1437.ironstorage.bridge.generated.MobilePrivateStorageFfiException
|
||||
import de.rfc1437.ironstorage.bridge.generated.MobileTotpOperation
|
||||
import de.rfc1437.ironstorage.bridge.generated.mobileKeyTransfer
|
||||
import de.rfc1437.ironstorage.bridge.generated.mobileLocalKeyTransferImporter
|
||||
import de.rfc1437.ironstorage.bridge.generated.mobileTotpOperation
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
@@ -31,10 +34,12 @@ class NativeSettingsRepository(
|
||||
private val mutable = MutableStateFlow(SettingsState())
|
||||
override val state: StateFlow<SettingsState> = mutable
|
||||
private val operation = Mutex()
|
||||
private val cameraBusy = AtomicBoolean()
|
||||
|
||||
@Volatile private var epoch = 0L
|
||||
|
||||
@Volatile private var discovery: MobileTotpOperation? = null
|
||||
private var visibility: Job? = null
|
||||
private var transfer: MobileKeyTransfer? = null
|
||||
private var importer: MobileKeyTransferImport? = null
|
||||
init {
|
||||
@@ -126,19 +131,27 @@ class NativeSettingsRepository(
|
||||
)
|
||||
}
|
||||
}
|
||||
override fun beginTransfer() = run { ticket ->
|
||||
override fun beginTransfer() = begin(false)
|
||||
override fun beginSetupTransfer() = begin(true)
|
||||
private fun begin(setup: Boolean) = run { ticket ->
|
||||
withContext(Dispatchers.IO) {
|
||||
session.storage()
|
||||
transfer = mobileKeyTransfer()
|
||||
importer = requireNotNull(transfer).importer()
|
||||
releaseTransfer()
|
||||
if (setup) {
|
||||
importer = mobileLocalKeyTransferImporter()
|
||||
} else {
|
||||
transfer = mobileKeyTransfer()
|
||||
importer = requireNotNull(transfer).importer()
|
||||
}
|
||||
}
|
||||
val keys = withContext(Dispatchers.IO) { requireNotNull(transfer).keys() }
|
||||
val keys = withContext(Dispatchers.IO) { transfer?.keys().orEmpty() }
|
||||
if (ticket ==
|
||||
epoch
|
||||
) {
|
||||
mutable.value = mutable.value.copy(
|
||||
transfer = KeyTransferState(
|
||||
open = true,
|
||||
setup = setup,
|
||||
keys = keys.map {
|
||||
TransferKey(
|
||||
it.fingerprint,
|
||||
@@ -152,6 +165,12 @@ class NativeSettingsRepository(
|
||||
}
|
||||
override fun exportKey(fingerprint: String, privateKey: Boolean, passphrase: String) =
|
||||
run { ticket ->
|
||||
visibility?.cancel()
|
||||
mutable.value.transfer.frames.forEach { it.modules.fill(0) }
|
||||
mutable.value =
|
||||
mutable.value.copy(
|
||||
transfer = mutable.value.transfer.copy(frames = emptyList(), exportedKey = null)
|
||||
)
|
||||
val result = withContext(Dispatchers.IO) {
|
||||
requireNotNull(transfer).export(
|
||||
fingerprint,
|
||||
@@ -165,11 +184,28 @@ class NativeSettingsRepository(
|
||||
mutable.value.transfer.frames.forEach { it.modules.fill(0) }
|
||||
mutable.value = mutable.value.copy(
|
||||
transfer = mutable.value.transfer.copy(
|
||||
exportedKey = TransferKey(
|
||||
result.key.fingerprint,
|
||||
result.key.title,
|
||||
result.key.kind == MobileKeyTransferKind.PRIVATE
|
||||
),
|
||||
frames = result.frames.map {
|
||||
TransferFrame(it.sequence, it.total, it.width, it.modules)
|
||||
}
|
||||
)
|
||||
)
|
||||
visibility = scope.launch {
|
||||
while (ticket == epoch) {
|
||||
kotlinx.coroutines.delay(250)
|
||||
val visible = operation.withLock {
|
||||
withContext(Dispatchers.IO) { transfer?.exportVisible() == true }
|
||||
}
|
||||
if (ticket == epoch && !visible) {
|
||||
closeTransfer()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result.frames.forEach { it.modules.fill(0) }
|
||||
}
|
||||
@@ -177,9 +213,11 @@ class NativeSettingsRepository(
|
||||
private fun progress(ticket: Long, progress: MobileKeyTransferProgress) {
|
||||
if (ticket != epoch) return
|
||||
mutable.value = mutable.value.copy(
|
||||
error = null,
|
||||
transfer = mutable.value.transfer.copy(
|
||||
received = progress.received,
|
||||
total = progress.total,
|
||||
duplicate = progress.duplicate,
|
||||
ready = progress.key?.let {
|
||||
TransferKey(
|
||||
it.fingerprint,
|
||||
@@ -190,6 +228,65 @@ class NativeSettingsRepository(
|
||||
)
|
||||
)
|
||||
}
|
||||
override fun cameraPreview(): CameraPreview? {
|
||||
val ticket = epoch
|
||||
return platform.cameraPreview({ frame ->
|
||||
if (!cameraBusy.compareAndSet(false, true)) {
|
||||
frame.pixels.fill(0)
|
||||
} else {
|
||||
scope.launch {
|
||||
try {
|
||||
operation.withLock {
|
||||
if (ticket != epoch || !mutable.value.transfer.open ||
|
||||
mutable.value.transfer.ready != null || mutable.value.busy
|
||||
) {
|
||||
return@withLock
|
||||
}
|
||||
val result = withContext(Dispatchers.IO) {
|
||||
requireNotNull(importer).addCamera(
|
||||
MobileCameraFrame(
|
||||
frame.width,
|
||||
frame.height,
|
||||
frame.rowStride,
|
||||
frame.pixelStride,
|
||||
frame.pixels
|
||||
),
|
||||
frame.rotationDegrees
|
||||
)
|
||||
}
|
||||
frame.pixels.fill(0)
|
||||
if (result != null) progress(ticket, result)
|
||||
}
|
||||
} catch (error: MobileKeyTransferFfiException.Failed) {
|
||||
if (ticket ==
|
||||
epoch
|
||||
) {
|
||||
mutable.value = mutable.value.copy(error = error.rustMessage)
|
||||
}
|
||||
} catch (_: NativeBridgeException) {
|
||||
if (ticket ==
|
||||
epoch
|
||||
) {
|
||||
mutable.value =
|
||||
mutable.value.copy(error = session.text(R.string.core_update_retry))
|
||||
}
|
||||
} finally {
|
||||
frame.pixels.fill(0)
|
||||
cameraBusy.set(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
scope.launch {
|
||||
if (ticket ==
|
||||
epoch
|
||||
) {
|
||||
mutable.value =
|
||||
mutable.value.copy(error = session.text(R.string.core_camera_unavailable))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
override fun chooseQrImages() {
|
||||
if (!platform.chooseQrImages()) {
|
||||
mutable.value =
|
||||
@@ -246,6 +343,15 @@ class NativeSettingsRepository(
|
||||
progress(ticket, withContext(Dispatchers.IO) { requireNotNull(importer).addFrame(payload) })
|
||||
}
|
||||
override fun importKey(passphrase: String, makeDefault: Boolean, overwrite: Boolean) = run {
|
||||
if (mutable.value.transfer.setup) {
|
||||
withContext(Dispatchers.IO) {
|
||||
session.storage().androidOnboarding(session.backend()).use {
|
||||
it.importScanned(requireNotNull(importer), passphrase.ifEmpty { null })
|
||||
}
|
||||
}
|
||||
closeTransfer()
|
||||
return@run
|
||||
}
|
||||
val result = withContext(Dispatchers.IO) {
|
||||
requireNotNull(importer).import(passphrase.ifEmpty { null }, makeDefault, overwrite)
|
||||
}
|
||||
@@ -264,6 +370,8 @@ class NativeSettingsRepository(
|
||||
transfer = null
|
||||
}
|
||||
override fun closeTransfer() {
|
||||
visibility?.cancel()
|
||||
visibility = null
|
||||
epoch += 1
|
||||
mutable.value.transfer.frames.forEach { it.modules.fill(0) }
|
||||
mutable.value = mutable.value.copy(transfer = KeyTransferState(), busy = false)
|
||||
@@ -295,7 +403,11 @@ class NativeSettingsRepository(
|
||||
mutable.value.copy(error = error.title + "\n" + error.detail)
|
||||
}
|
||||
} catch (error: MobileKeyTransferFfiException.Failed) {
|
||||
if (ticket == epoch) mutable.value = mutable.value.copy(error = error.message)
|
||||
if (ticket ==
|
||||
epoch
|
||||
) {
|
||||
mutable.value = mutable.value.copy(error = error.rustMessage)
|
||||
}
|
||||
} catch (_: MobilePrivateStorageFfiException) {
|
||||
if (ticket ==
|
||||
epoch
|
||||
|
||||
@@ -12,6 +12,20 @@ interface SettingsPlatform {
|
||||
fun openCredentials(): Boolean
|
||||
fun chooseQrImages(): Boolean
|
||||
suspend fun readQrImage(uri: String): ByteArray
|
||||
fun cameraPreview(frame: (CameraFrame) -> Unit, failure: () -> Unit): CameraPreview?
|
||||
}
|
||||
data class CameraFrame(
|
||||
val pixels: ByteArray,
|
||||
val width: UInt,
|
||||
val height: UInt,
|
||||
val rowStride: UInt,
|
||||
val pixelStride: UInt,
|
||||
val rotationDegrees: UInt
|
||||
) {
|
||||
override fun toString() = "CameraFrame([REDACTED])"
|
||||
}
|
||||
interface CameraPreview : AutoCloseable {
|
||||
val view: android.view.View
|
||||
}
|
||||
data class SettingsPage(
|
||||
val repositoryTitle: String,
|
||||
@@ -45,7 +59,10 @@ data class KeyTransferState(
|
||||
val frames: List<TransferFrame> = emptyList(),
|
||||
val received: UInt = 0u,
|
||||
val total: UInt = 0u,
|
||||
val ready: TransferKey? = null
|
||||
val ready: TransferKey? = null,
|
||||
val duplicate: Boolean = false,
|
||||
val setup: Boolean = false,
|
||||
val exportedKey: TransferKey? = null
|
||||
) {
|
||||
override fun toString() = "KeyTransferState([REDACTED])"
|
||||
}
|
||||
@@ -69,6 +86,8 @@ interface SettingsRepository {
|
||||
fun openAutofill()
|
||||
fun openCredentials()
|
||||
fun beginTransfer()
|
||||
fun beginSetupTransfer()
|
||||
fun cameraPreview(): CameraPreview?
|
||||
fun exportKey(fingerprint: String, privateKey: Boolean, passphrase: String)
|
||||
fun chooseQrImages()
|
||||
fun addQrImages(uris: List<String>)
|
||||
|
||||
@@ -38,4 +38,5 @@
|
||||
<string name="core_copied">Copied. The clipboard will be cleared automatically.</string>
|
||||
<string name="core_password_recovery">Unlock the device or recover the private store and refresh.</string>
|
||||
<string name="core_password_storage">Private storage is unavailable. Unlock the device and refresh.</string>
|
||||
<string name="core_camera_unavailable">The camera is unavailable. Pause scanning and retry, or choose QR images.</string>
|
||||
</resources>
|
||||
@@ -176,7 +176,31 @@
|
||||
"org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0": "Apache-2.0",
|
||||
"org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0": "Apache-2.0",
|
||||
"org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0": "Apache-2.0",
|
||||
"org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.9.0": "Apache-2.0"
|
||||
"org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.9.0": "Apache-2.0",
|
||||
"androidx.camera.featurecombinationquery:featurecombinationquery:1.6.2": "Apache-2.0",
|
||||
"androidx.camera.viewfinder:viewfinder-core:1.5.1": "Apache-2.0",
|
||||
"androidx.camera:camera-camera2-pipe:1.6.2": "Apache-2.0",
|
||||
"androidx.camera:camera-camera2:1.6.2": "Apache-2.0",
|
||||
"androidx.camera:camera-core:1.6.2": "Apache-2.0 AND BSD-3-Clause",
|
||||
"androidx.camera:camera-lifecycle:1.6.2": "Apache-2.0",
|
||||
"androidx.camera:camera-video:1.6.2": "Apache-2.0",
|
||||
"androidx.camera:camera-view:1.6.2": "Apache-2.0",
|
||||
"androidx.concurrent:concurrent-futures-ktx:1.1.0": "Apache-2.0",
|
||||
"androidx.core:core-backported-fixes:1.0.0": "Apache-2.0",
|
||||
"androidx.exifinterface:exifinterface:1.4.2": "Apache-2.0",
|
||||
"androidx.media3:media3-common:1.9.0": "Apache-2.0",
|
||||
"androidx.media3:media3-container:1.9.0": "Apache-2.0",
|
||||
"androidx.media3:media3-muxer:1.9.0": "Apache-2.0",
|
||||
"androidx.tracing:tracing-ktx:2.0.0": "Apache-2.0",
|
||||
"com.google.auto.value:auto-value-annotations:1.6.3": "Apache-2.0",
|
||||
"com.google.dagger:dagger:2.59": "Apache-2.0",
|
||||
"com.google.errorprone:error_prone_annotations:2.28.0": "Apache-2.0",
|
||||
"com.google.guava:failureaccess:1.0.2": "Apache-2.0",
|
||||
"com.google.guava:guava:33.3.1-android": "Apache-2.0",
|
||||
"com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava": "Apache-2.0",
|
||||
"com.google.j2objc:j2objc-annotations:3.0.0": "Apache-2.0",
|
||||
"org.checkerframework:checker-qual:3.43.0": "MIT",
|
||||
"org.jetbrains.kotlinx:atomicfu-jvm:0.28.0": "Apache-2.0"
|
||||
},
|
||||
"rust_licenses": [
|
||||
"(Apache-2.0 OR MIT) AND BSD-3-Clause",
|
||||
|
||||
@@ -19,6 +19,7 @@ import androidx.compose.material3.RadioButton
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
@@ -54,9 +55,17 @@ class SetupFormViewModel @Inject constructor() : ViewModel() {
|
||||
fun OnboardingScreen(
|
||||
repository: OnboardingRepository,
|
||||
secrets: SetupFormViewModel,
|
||||
settings: de.rfc1437.ironstorage.core.SettingsRepository,
|
||||
authentication: de.rfc1437.ironstorage.core.AuthenticationRepository,
|
||||
modifier: Modifier = Modifier,
|
||||
scroll: Boolean = true
|
||||
) {
|
||||
val transfer by settings.state.collectAsStateWithLifecycle()
|
||||
DisposableEffect(transfer.transfer.open) {
|
||||
val wasOpen = transfer.transfer.open
|
||||
onDispose { if (wasOpen) repository.refresh() }
|
||||
}
|
||||
if (transfer.transfer.open) KeyTransferDialog(settings, authentication)
|
||||
ProtectedInputSurface()
|
||||
val state by repository.setup.collectAsStateWithLifecycle()
|
||||
var step by rememberSaveable { mutableStateOf("choice") }
|
||||
@@ -183,6 +192,9 @@ fun OnboardingScreen(
|
||||
}
|
||||
"import" -> {
|
||||
Text(stringResource(R.string.setup_import_help))
|
||||
TextButton(onClick = settings::beginSetupTransfer) {
|
||||
Text(stringResource(R.string.qr_scan))
|
||||
}
|
||||
SecretField(
|
||||
stringResource(R.string.setup_armor),
|
||||
secrets.armor,
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
package de.rfc1437.ironstorage.features
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.provider.Settings
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clipToBounds
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.net.toUri
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.compose.LifecycleEventEffect
|
||||
import de.rfc1437.ironstorage.core.SettingsRepository
|
||||
|
||||
@Composable
|
||||
internal fun QrCameraPane(repository: SettingsRepository) {
|
||||
val context = LocalContext.current
|
||||
fun allowed() = ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) ==
|
||||
PackageManager.PERMISSION_GRANTED
|
||||
var permitted by remember { mutableStateOf(allowed()) }
|
||||
var scanning by remember { mutableStateOf(false) }
|
||||
val permission =
|
||||
rememberLauncherForActivityResult(ActivityResultContracts.RequestPermission()) {
|
||||
permitted = it
|
||||
scanning = it
|
||||
}
|
||||
LifecycleEventEffect(Lifecycle.Event.ON_RESUME) { permitted = allowed() }
|
||||
if (permitted && scanning) {
|
||||
val camera = remember(repository) { repository.cameraPreview() }
|
||||
DisposableEffect(camera) { onDispose { camera?.close() } }
|
||||
if (camera == null) {
|
||||
Text(stringResource(R.string.qr_camera_missing))
|
||||
} else {
|
||||
AndroidView(factory = {
|
||||
camera.view
|
||||
}, modifier = Modifier.fillMaxWidth().height(280.dp).clipToBounds())
|
||||
}
|
||||
TextButton(onClick = { scanning = false }) { Text(stringResource(R.string.qr_pause)) }
|
||||
} else {
|
||||
TextButton(onClick = {
|
||||
if (permitted) {
|
||||
scanning = true
|
||||
} else {
|
||||
permission.launch(Manifest.permission.CAMERA)
|
||||
}
|
||||
}) { Text(stringResource(if (permitted) R.string.qr_resume else R.string.qr_scan)) }
|
||||
if (!permitted) {
|
||||
Text(stringResource(R.string.qr_camera_denied))
|
||||
TextButton(onClick = {
|
||||
context.startActivity(
|
||||
Intent(
|
||||
Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
|
||||
"package:${context.packageName}".toUri()
|
||||
)
|
||||
)
|
||||
}) { Text(stringResource(R.string.qr_camera_settings)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun QrDisplayWindow() {
|
||||
val view = androidx.compose.ui.platform.LocalView.current
|
||||
val window = (view.parent as? androidx.compose.ui.window.DialogWindowProvider)?.window
|
||||
DisposableEffect(window, view) {
|
||||
val brightness = window?.attributes?.screenBrightness
|
||||
val keep = view.keepScreenOn
|
||||
view.keepScreenOn = true
|
||||
window?.let { it.attributes = it.attributes.apply { screenBrightness = 1f } }
|
||||
onDispose {
|
||||
view.keepScreenOn = keep
|
||||
if (brightness !=
|
||||
null
|
||||
) {
|
||||
window.attributes = window.attributes.apply { screenBrightness = brightness }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+167
-93
@@ -169,6 +169,8 @@ fun SettingsScreen(
|
||||
OnboardingScreen(
|
||||
onboarding,
|
||||
setup,
|
||||
repository,
|
||||
authentication,
|
||||
scroll = false
|
||||
)
|
||||
}
|
||||
@@ -290,7 +292,7 @@ fun SettingsScreen(
|
||||
SettingsEditDialog(repository, authentication, action) { edit = null }
|
||||
}
|
||||
}
|
||||
if (state.transfer.open) KeyTransferDialog(repository, authentication)
|
||||
if (state.transfer.open && !showSetup) KeyTransferDialog(repository, authentication)
|
||||
if (licenses) {
|
||||
val resources = LocalResources.current
|
||||
val loading = stringResource(R.string.settings_license_loading)
|
||||
@@ -422,7 +424,7 @@ private fun SettingsEditDialog(
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun KeyTransferDialog(
|
||||
internal fun KeyTransferDialog(
|
||||
repository: SettingsRepository,
|
||||
authentication: AuthenticationRepository
|
||||
) {
|
||||
@@ -436,6 +438,15 @@ private fun KeyTransferDialog(
|
||||
var frame by remember { mutableStateOf(0) }
|
||||
var passphrase by rememberProtectedInput(authentication.presentation)
|
||||
var payload by rememberProtectedInput(authentication.presentation)
|
||||
var exportConfirmed by remember(fingerprint, privateKey) { mutableStateOf(false) }
|
||||
var importConfirmed by remember(state.transfer.ready) { mutableStateOf(false) }
|
||||
var animate by remember { mutableStateOf(false) }
|
||||
LaunchedEffect(animate, state.transfer.frames) {
|
||||
while (animate && state.transfer.frames.size > 1) {
|
||||
kotlinx.coroutines.delay(1200)
|
||||
frame = (frame + 1) % state.transfer.frames.size
|
||||
}
|
||||
}
|
||||
ProtectedWindow()
|
||||
AlertDialog(
|
||||
properties = DialogProperties(
|
||||
@@ -454,91 +465,126 @@ private fun KeyTransferDialog(
|
||||
ProtectedInputSurface(authentication.presentation)
|
||||
state.error?.let { Text(it, color = MaterialTheme.colorScheme.error) }
|
||||
if (state.busy) CircularProgressIndicator()
|
||||
state.transfer.keys.forEach { key ->
|
||||
Row(
|
||||
Modifier.fillMaxWidth().selectable(
|
||||
selected = fingerprint == key.fingerprint,
|
||||
enabled = !state.busy,
|
||||
role = Role.RadioButton,
|
||||
onClick = { fingerprint = key.fingerprint }
|
||||
)
|
||||
) {
|
||||
RadioButton(selected = fingerprint == key.fingerprint, onClick = null)
|
||||
Column(Modifier.weight(1f)) {
|
||||
Text(key.title)
|
||||
Text(key.fingerprint)
|
||||
}
|
||||
}
|
||||
}
|
||||
TextButton(
|
||||
enabled =
|
||||
!state.busy &&
|
||||
state.transfer.keys.any {
|
||||
it.fingerprint == fingerprint && it.privateKey
|
||||
},
|
||||
onClick = { repository.setDefaultKey(fingerprint) }
|
||||
) { Text(stringResource(R.string.settings_default_key_select)) }
|
||||
Text(stringResource(R.string.settings_private_warning))
|
||||
SettingsToggle(stringResource(R.string.settings_private_export), privateKey) {
|
||||
privateKey =
|
||||
it
|
||||
}
|
||||
SecretField(stringResource(R.string.setup_passphrase), passphrase) {
|
||||
passphrase = it
|
||||
}
|
||||
TextButton(enabled = !state.busy && fingerprint.isNotEmpty(), onClick = {
|
||||
repository.exportKey(fingerprint, privateKey, passphrase)
|
||||
passphrase = ""
|
||||
frame =
|
||||
0
|
||||
}) { Text(stringResource(R.string.settings_export_confirm)) }
|
||||
state.transfer.frames.getOrNull(frame)?.let { qr ->
|
||||
val description =
|
||||
stringResource(
|
||||
R.string.settings_qr_frame,
|
||||
qr.sequence.toInt(),
|
||||
qr.total.toInt()
|
||||
)
|
||||
Text(description)
|
||||
Canvas(
|
||||
Modifier.fillMaxWidth().height(280.dp).semantics {
|
||||
contentDescription =
|
||||
description
|
||||
}
|
||||
) {
|
||||
drawRect(Color.White)
|
||||
val width = qr.width.toInt()
|
||||
val scale = minOf(size.width, size.height) / (width + 8)
|
||||
val x = (size.width - scale * width) / 2
|
||||
val y = (size.height - scale * width) / 2
|
||||
for (row in 0 until width) {
|
||||
for (column in 0 until width) {
|
||||
if (qr.modules[
|
||||
row *
|
||||
width +
|
||||
column
|
||||
].toInt() ==
|
||||
1
|
||||
) {
|
||||
drawRect(
|
||||
Color.Black,
|
||||
Offset(x + column * scale, y + row * scale),
|
||||
Size(scale, scale)
|
||||
)
|
||||
}
|
||||
if (!state.transfer.setup) {
|
||||
state.transfer.keys.forEach { key ->
|
||||
Row(
|
||||
Modifier.fillMaxWidth().selectable(
|
||||
selected = fingerprint == key.fingerprint,
|
||||
enabled = !state.busy,
|
||||
role = Role.RadioButton,
|
||||
onClick = { fingerprint = key.fingerprint }
|
||||
)
|
||||
) {
|
||||
RadioButton(selected = fingerprint == key.fingerprint, onClick = null)
|
||||
Column(Modifier.weight(1f)) {
|
||||
Text(key.title)
|
||||
Text(key.fingerprint)
|
||||
}
|
||||
}
|
||||
}
|
||||
FlowRow {
|
||||
TextButton(enabled = frame > 0, onClick = {
|
||||
frame -= 1
|
||||
}) { Text(stringResource(R.string.settings_previous)) }
|
||||
TextButton(enabled = frame < state.transfer.frames.lastIndex, onClick = {
|
||||
frame +=
|
||||
1
|
||||
}) { Text(stringResource(R.string.settings_next)) }
|
||||
TextButton(
|
||||
enabled =
|
||||
!state.busy &&
|
||||
state.transfer.keys.any {
|
||||
it.fingerprint == fingerprint && it.privateKey
|
||||
},
|
||||
onClick = { repository.setDefaultKey(fingerprint) }
|
||||
) { Text(stringResource(R.string.settings_default_key_select)) }
|
||||
Text(stringResource(R.string.settings_private_warning))
|
||||
SettingsToggle(stringResource(R.string.settings_private_export), privateKey) {
|
||||
privateKey =
|
||||
it
|
||||
}
|
||||
SecretField(stringResource(R.string.setup_passphrase), passphrase) {
|
||||
passphrase = it
|
||||
}
|
||||
if (privateKey) {
|
||||
SettingsToggle(
|
||||
stringResource(R.string.qr_export_private_confirm),
|
||||
exportConfirmed
|
||||
) {
|
||||
exportConfirmed =
|
||||
it
|
||||
}
|
||||
}
|
||||
TextButton(
|
||||
enabled =
|
||||
!state.busy && fingerprint.isNotEmpty() && (!privateKey || exportConfirmed),
|
||||
onClick = {
|
||||
repository.exportKey(fingerprint, privateKey, passphrase)
|
||||
passphrase = ""
|
||||
frame =
|
||||
0
|
||||
}
|
||||
) { Text(stringResource(R.string.settings_export_confirm)) }
|
||||
state.transfer.frames.getOrNull(frame)?.let { qr ->
|
||||
state.transfer.exportedKey?.let { exported ->
|
||||
Text(exported.title)
|
||||
Text(exported.fingerprint)
|
||||
}
|
||||
QrDisplayWindow()
|
||||
val description =
|
||||
stringResource(
|
||||
R.string.settings_qr_frame,
|
||||
qr.sequence.toInt(),
|
||||
qr.total.toInt()
|
||||
)
|
||||
Text(description)
|
||||
Canvas(
|
||||
Modifier.fillMaxWidth().height(280.dp).semantics {
|
||||
contentDescription =
|
||||
description
|
||||
}
|
||||
) {
|
||||
drawRect(Color.White)
|
||||
val width = qr.width.toInt()
|
||||
val scale = minOf(size.width, size.height) / (width + 8)
|
||||
val x = (size.width - scale * width) / 2
|
||||
val y = (size.height - scale * width) / 2
|
||||
for (row in 0 until width) {
|
||||
for (column in 0 until width) {
|
||||
if (qr.modules[
|
||||
row *
|
||||
width +
|
||||
column
|
||||
].toInt() ==
|
||||
1
|
||||
) {
|
||||
drawRect(
|
||||
Color.Black,
|
||||
Offset(x + column * scale, y + row * scale),
|
||||
Size(scale, scale)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
FlowRow {
|
||||
TextButton(enabled = frame > 0, onClick = {
|
||||
frame -= 1
|
||||
}) { Text(stringResource(R.string.settings_previous)) }
|
||||
TextButton(
|
||||
enabled = frame < state.transfer.frames.lastIndex,
|
||||
onClick = {
|
||||
frame +=
|
||||
1
|
||||
}
|
||||
) { Text(stringResource(R.string.settings_next)) }
|
||||
}
|
||||
}
|
||||
if (state.transfer.frames.size > 1) {
|
||||
SettingsToggle(stringResource(R.string.qr_animate), animate) {
|
||||
animate = it
|
||||
}
|
||||
}
|
||||
}
|
||||
if (state.transfer.setup) {
|
||||
SecretField(stringResource(R.string.setup_passphrase), passphrase) {
|
||||
passphrase =
|
||||
it
|
||||
}
|
||||
}
|
||||
if (state.transfer.ready == null && !state.busy) QrCameraPane(repository)
|
||||
TextButton(enabled = !state.busy, onClick = repository::chooseQrImages) {
|
||||
Text(stringResource(R.string.settings_qr_images))
|
||||
}
|
||||
@@ -564,22 +610,50 @@ private fun KeyTransferDialog(
|
||||
state.transfer.total.toInt()
|
||||
)
|
||||
)
|
||||
if (state.transfer.duplicate) Text(stringResource(R.string.qr_duplicate))
|
||||
state.transfer.ready?.let {
|
||||
Text(it.title)
|
||||
Text(it.fingerprint)
|
||||
SettingsToggle(stringResource(R.string.settings_make_default), makeDefault) {
|
||||
makeDefault =
|
||||
it
|
||||
if (!state.transfer.setup) {
|
||||
SettingsToggle(
|
||||
stringResource(R.string.settings_make_default),
|
||||
makeDefault
|
||||
) {
|
||||
makeDefault =
|
||||
it
|
||||
}
|
||||
SettingsToggle(stringResource(R.string.settings_replace_key), overwrite) {
|
||||
overwrite =
|
||||
it
|
||||
}
|
||||
}
|
||||
SettingsToggle(stringResource(R.string.settings_replace_key), overwrite) {
|
||||
overwrite =
|
||||
it
|
||||
if (it.privateKey) {
|
||||
SettingsToggle(
|
||||
stringResource(R.string.qr_import_private_confirm),
|
||||
importConfirmed
|
||||
) {
|
||||
importConfirmed =
|
||||
it
|
||||
}
|
||||
}
|
||||
TextButton(
|
||||
enabled = !state.busy && (!it.privateKey || importConfirmed),
|
||||
onClick = {
|
||||
repository.importKey(passphrase, makeDefault, overwrite)
|
||||
passphrase =
|
||||
""
|
||||
}
|
||||
) {
|
||||
Text(
|
||||
stringResource(
|
||||
if (state.transfer.setup) {
|
||||
R.string.qr_setup_import
|
||||
} else {
|
||||
R.string.settings_import_confirm
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
TextButton(enabled = !state.busy, onClick = {
|
||||
repository.importKey(passphrase, makeDefault, overwrite)
|
||||
passphrase =
|
||||
""
|
||||
}) { Text(stringResource(R.string.settings_import_confirm)) }
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -171,7 +171,13 @@ private fun ShellDestination(
|
||||
Modifier.fillMaxSize().verticalScroll(rememberScrollState()),
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
OnboardingScreen(viewModel.onboarding, setupForm, scroll = false)
|
||||
OnboardingScreen(
|
||||
viewModel.onboarding,
|
||||
setupForm,
|
||||
viewModel.settings,
|
||||
viewModel.authentication,
|
||||
scroll = false
|
||||
)
|
||||
}
|
||||
}
|
||||
ready && route == ShellRoute.Passwords -> {
|
||||
|
||||
@@ -224,4 +224,15 @@
|
||||
<item quantity="other">%1$d results</item>
|
||||
</plurals>
|
||||
<string name="settings_license_loading">Loading license…</string>
|
||||
<string name="qr_scan">Scan GPG QR codes</string>
|
||||
<string name="qr_pause">Pause camera</string>
|
||||
<string name="qr_resume">Resume camera</string>
|
||||
<string name="qr_camera_denied">Camera access is required to scan. If permission was denied, allow it in app settings or choose QR images.</string>
|
||||
<string name="qr_camera_settings">Open camera permission settings</string>
|
||||
<string name="qr_camera_missing">The camera is unavailable. Choose QR images or paste an armored key.</string>
|
||||
<string name="qr_duplicate">Duplicate frame; progress is unchanged.</string>
|
||||
<string name="qr_import_private_confirm">I checked this fingerprint and authorize importing its private key material.</string>
|
||||
<string name="qr_export_private_confirm">I checked this fingerprint and authorize displaying its private QR codes.</string>
|
||||
<string name="qr_animate">Automatically advance frames</string>
|
||||
<string name="qr_setup_import">Prepare the scanned key</string>
|
||||
</resources>
|
||||
@@ -1,4 +1,5 @@
|
||||
[versions]
|
||||
camera = "1.6.2"
|
||||
agp = "9.4.1"
|
||||
kotlin = "2.4.21"
|
||||
ksp = "2.3.12"
|
||||
@@ -28,6 +29,9 @@ biometric = "1.1.0"
|
||||
fragment = "1.9.1"
|
||||
|
||||
[libraries]
|
||||
camera-camera2 = { module = "androidx.camera:camera-camera2", version.ref = "camera" }
|
||||
camera-lifecycle = { module = "androidx.camera:camera-lifecycle", version.ref = "camera" }
|
||||
camera-view = { module = "androidx.camera:camera-view", version.ref = "camera" }
|
||||
benchmark-macro = { module = "androidx.benchmark:benchmark-macro-junit4", version.ref = "benchmark" }
|
||||
rustls-verifier = { group = "rustls", name = "rustls-platform-verifier", version.ref = "rustlsVerifier" }
|
||||
compose-bom = { module = "androidx.compose:compose-bom", version.ref = "compose" }
|
||||
|
||||
@@ -183,6 +183,11 @@
|
||||
<sha256 value="03fb659177c8618e47425925c11bc91f384703ea26c265be9b25cd79292b511c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.appcompat" name="appcompat" version="1.1.0">
|
||||
<artifact name="appcompat-1.1.0.pom">
|
||||
<sha256 value="340d617121f8ef8e02a6680c8f357aa3e542276d0c8a1cdcb6fd98984b2cb7b9" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.appcompat" name="appcompat" version="1.2.0">
|
||||
<artifact name="appcompat-1.2.0.aar">
|
||||
<sha256 value="3d2131a55a61a777322e2126e0018011efa6339e53b44153eb651b16020cca70" origin="Generated by Gradle"/>
|
||||
@@ -284,6 +289,70 @@
|
||||
<sha256 value="4999f205b2b38e31180ad58111e32d564190c2024fbfd58527e2da8bfb67ff65" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.camera" name="camera-camera2" version="1.6.2">
|
||||
<artifact name="camera-camera2-1.6.2.aar">
|
||||
<sha256 value="5a55014ed96feda81a37799faf9f96150025a4434699d55caa1cdebf2ae07e20" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="camera-camera2-1.6.2.module">
|
||||
<sha256 value="4694b995fbb4934e5e1e3cedabef426e799a510cfc179b659c4e9632f6b2fe75" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.camera" name="camera-camera2-pipe" version="1.6.2">
|
||||
<artifact name="camera-camera2-pipe-1.6.2.aar">
|
||||
<sha256 value="b357bd94fd4273ff88f453f7e712a22e100adc932324fc6b51fbe9ef9cf45515" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="camera-camera2-pipe-1.6.2.module">
|
||||
<sha256 value="5470741b0a6fe88e560e7d929097e2ec60e7406aef09b48ab900b0befa102c0f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.camera" name="camera-core" version="1.6.2">
|
||||
<artifact name="camera-core-1.6.2.aar">
|
||||
<sha256 value="ebd66f090414f4c12f23a55b5023aeee1b096da8a06c02a0b6fb3520c4ddadf6" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="camera-core-1.6.2.module">
|
||||
<sha256 value="bee75b4ef561862030702a51f692057e034ae1f600f3091b2a5e5a89856ab410" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.camera" name="camera-lifecycle" version="1.6.2">
|
||||
<artifact name="camera-lifecycle-1.6.2.aar">
|
||||
<sha256 value="b7b701a3c6838bc7c4acd1372140e889fdf9681bf833ebfc638fdbe28ed5fa32" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="camera-lifecycle-1.6.2.module">
|
||||
<sha256 value="bd7fd00cb9de0f2ce8c3400b52504cf7691590bb29a1550a71b58255e483ff47" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.camera" name="camera-video" version="1.6.2">
|
||||
<artifact name="camera-video-1.6.2.aar">
|
||||
<sha256 value="dee568da7d1ce009506a538b2916cce6f23473a835b0aeb4e8193483ff1174d0" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="camera-video-1.6.2.module">
|
||||
<sha256 value="cf1e3fb9362af9c020f1126f8c56e7578f73a96b6f670136cc756a907182733c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.camera" name="camera-view" version="1.6.2">
|
||||
<artifact name="camera-view-1.6.2.aar">
|
||||
<sha256 value="2f258b88422b925717d2d1d1714d5572e48e2194336be227b35fc60000f6e166" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="camera-view-1.6.2.module">
|
||||
<sha256 value="c84dc907bff8a46133631d1e93edcef78ac608c83abd07b51056f9cca4ae800c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.camera.featurecombinationquery" name="featurecombinationquery" version="1.6.2">
|
||||
<artifact name="featurecombinationquery-1.6.2.aar">
|
||||
<sha256 value="2321cfd29678e3128284d1622bb6b06e0fecd2c2e69140471ab00e8616e622c2" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="featurecombinationquery-1.6.2.module">
|
||||
<sha256 value="4f6edda1492eaa928cfe7516d8efd097ed2f59ee4cedf1bec2d3345a3d6137fd" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.camera.viewfinder" name="viewfinder-core" version="1.5.1">
|
||||
<artifact name="viewfinder-core-1.5.1.aar">
|
||||
<sha256 value="31179ed5509e4d6d8d667efb91a039cac897b2bfd800d4c6e0b5bed376b4fa69" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="viewfinder-core-1.5.1.module">
|
||||
<sha256 value="31407c1af39b26a59bebdcd61a39b7aa1a8b7f51c63aa61127d4f977a36d877c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.cardview" name="cardview" version="1.0.0">
|
||||
<artifact name="cardview-1.0.0.aar">
|
||||
<sha256 value="1193c04c22a3d6b5946dae9f4e8c59d6adde6a71b6bd5d87fb99d82dda1afec7" origin="Generated by Gradle"/>
|
||||
@@ -848,6 +917,14 @@
|
||||
<sha256 value="afd7094d3a07422be2e991bc87048542ae9724a5c42bd54b5cae3029c7970a1d" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.concurrent" name="concurrent-futures-ktx" version="1.1.0">
|
||||
<artifact name="concurrent-futures-ktx-1.1.0.jar">
|
||||
<sha256 value="1968bf52039e38636aa6f114cd17d7256919d1e8997417716fef9d1da1f24d85" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="concurrent-futures-ktx-1.1.0.module">
|
||||
<sha256 value="69b79724566d49140846700690b8d2165231c577e93e66726a443e8f976bbe19" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.concurrent" name="concurrent-futures-ktx" version="1.2.0">
|
||||
<artifact name="concurrent-futures-ktx-1.2.0.jar">
|
||||
<sha256 value="e1f3e17bb4358ccd6c77ca45f70635c9aba237261f19eaa4f64a0218c00e2a3e" origin="Generated by Gradle"/>
|
||||
@@ -903,6 +980,11 @@
|
||||
<sha256 value="afb5ea494dd083ed404cd51f580d218e37362f8ae326e893bee521290ed34920" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.core" name="core" version="1.7.0">
|
||||
<artifact name="core-1.7.0.module">
|
||||
<sha256 value="988f820899d5a4982e5c878ca1cd417970ace332ea2ff72f5be19b233fa0e788" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.core" name="core" version="1.8.0">
|
||||
<artifact name="core-1.8.0.module">
|
||||
<sha256 value="505f1838869611519d65ec7feb650e88856e3682e37e42a2a24b73e655a98d74" origin="Generated by Gradle"/>
|
||||
@@ -916,6 +998,14 @@
|
||||
<sha256 value="8674ade1d12962469dd2d1e6edc03b465f20d180b0840a129bc40b351e8651d1" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.core" name="core-backported-fixes" version="1.0.0">
|
||||
<artifact name="core-backported-fixes-1.0.0.aar">
|
||||
<sha256 value="874722634db5f60745ab2f64d734dd81d3ee4eb71f175263e6565dabea54713d" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="core-backported-fixes-1.0.0.module">
|
||||
<sha256 value="05aef3e2e15168190894999d4b14907c84d066837964ec900f7a2f0e4d9354ac" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.core" name="core-ktx" version="1.1.0">
|
||||
<artifact name="core-ktx-1.1.0.pom">
|
||||
<sha256 value="729d11bad16d87c6212dc9ab80e9c770d333115062136e0732164a6b1696e11c" origin="Generated by Gradle"/>
|
||||
@@ -1042,6 +1132,14 @@
|
||||
<sha256 value="92be16cccb757f807bddd92f1fca95a038a810ccca051c4149c11682478954b8" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.exifinterface" name="exifinterface" version="1.4.2">
|
||||
<artifact name="exifinterface-1.4.2.aar">
|
||||
<sha256 value="6bb2b68682a2023c55f35f941444ffea0157947b061e4fd7606ba935e2e77425" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="exifinterface-1.4.2.module">
|
||||
<sha256 value="6365165eb5aacc700a34b1650a2910ea01ebd819821b89af7689fa41274fb00b" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.fragment" name="fragment" version="1.2.5">
|
||||
<artifact name="fragment-1.2.5.pom">
|
||||
<sha256 value="df0aca46b62bb47cc662cbcee63372db6d2a2859478ee38b594fba3433fe30a5" origin="Generated by Gradle"/>
|
||||
@@ -1100,6 +1198,11 @@
|
||||
<sha256 value="2baaf7f17551765524bd1e4d2f954a2a0178a112039cf549ba8b7d4b41e66931" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.lifecycle" name="lifecycle-common" version="2.1.0">
|
||||
<artifact name="lifecycle-common-2.1.0.pom">
|
||||
<sha256 value="692c2a60437a95220c8fbb6e8943196f255f535d1a7c58714e6c46530782f276" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.lifecycle" name="lifecycle-common" version="2.10.0">
|
||||
<artifact name="lifecycle-common-2.10.0.module">
|
||||
<sha256 value="5d1247b1edfbdc9ddedcbe525c9d2629567b1c538cb7a9c620cd044a124b5c73" origin="Generated by Gradle"/>
|
||||
@@ -1170,6 +1273,11 @@
|
||||
<sha256 value="1d1837f3942b33ea30aa2301fdcea2639408a0fd6fd4368c22478fa8153aebbf" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.lifecycle" name="lifecycle-livedata" version="2.1.0">
|
||||
<artifact name="lifecycle-livedata-2.1.0.pom">
|
||||
<sha256 value="1e4c580c995e41cd18455cfb87e3e43955be9db9ec63a8fb3c7259f01b7c4e3c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.lifecycle" name="lifecycle-livedata" version="2.10.0">
|
||||
<artifact name="lifecycle-livedata-2.10.0.aar">
|
||||
<sha256 value="3e8c009fc88da1c52e4ed05a81269d5ac9bd405046f300307f5e3a17e201a6df" origin="Generated by Gradle"/>
|
||||
@@ -1186,6 +1294,11 @@
|
||||
<sha256 value="d990bc920ae43729d702d80077328e8a59781ea5a35b24c02bc47d326ae73d7d" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.lifecycle" name="lifecycle-livedata" version="2.3.1">
|
||||
<artifact name="lifecycle-livedata-2.3.1.module">
|
||||
<sha256 value="93494e78d5049dff897fde50f477e7b965e9a3de4a1ed453b5f0cbc409eb4e4c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.lifecycle" name="lifecycle-livedata" version="2.6.1">
|
||||
<artifact name="lifecycle-livedata-2.6.1.aar">
|
||||
<sha256 value="67359f609dfc2bf65da1270b23033f856064ec279f058e0a70c715f7c9003031" origin="Generated by Gradle"/>
|
||||
@@ -1194,6 +1307,11 @@
|
||||
<sha256 value="e2659e87e890b52b66f300471828b387a205e5387a392713190166f399ecf641" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.lifecycle" name="lifecycle-livedata-core" version="2.1.0">
|
||||
<artifact name="lifecycle-livedata-core-2.1.0.pom">
|
||||
<sha256 value="6839d2e68c8fee4cc3bbf04e6b291a6ae842403fcd5f8d944c27814d296deff3" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.lifecycle" name="lifecycle-livedata-core" version="2.10.0">
|
||||
<artifact name="lifecycle-livedata-core-2.10.0.aar">
|
||||
<sha256 value="12dd61a9843ccebb4547d3ebe2f6d030ca8f6988d22f8fad19c0af93b4a97e95" origin="Generated by Gradle"/>
|
||||
@@ -1215,6 +1333,11 @@
|
||||
<sha256 value="aa51621be3817d1f5d21336b0c0525fe96ae899cec656c13d8ea18a51ea32c2f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.lifecycle" name="lifecycle-livedata-core" version="2.3.1">
|
||||
<artifact name="lifecycle-livedata-core-2.3.1.module">
|
||||
<sha256 value="b1e095d550d39a7d6c815761d6dbe3fd64eb31a39dc28146e78bbf2c01ba8f41" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.lifecycle" name="lifecycle-livedata-core" version="2.6.1">
|
||||
<artifact name="lifecycle-livedata-core-2.6.1.aar">
|
||||
<sha256 value="2256780a3cff4a1e57fbb3d442557c17dc363ab8af105bcaf5261d8e2d5db949" origin="Generated by Gradle"/>
|
||||
@@ -1563,6 +1686,30 @@
|
||||
<sha256 value="c978d550808b47434aa49a63164110a50b55b0bcc6160a93a2e37d5110df8c5e" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.media3" name="media3-common" version="1.9.0">
|
||||
<artifact name="media3-common-1.9.0.aar">
|
||||
<sha256 value="714114bf8a56fe44f0f78b499ae7ea3bed52391313794c8abdc1b687700d42aa" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="media3-common-1.9.0.module">
|
||||
<sha256 value="02d42f8fd7cc53c385256f417df73a5cf30e8b7c5635ca5786148518ce711b75" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.media3" name="media3-container" version="1.9.0">
|
||||
<artifact name="media3-container-1.9.0.aar">
|
||||
<sha256 value="f73cea4fe8a2bf9eb6462bfb7a547d1aaf55395d0007eed6fadb129b56927c0d" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="media3-container-1.9.0.module">
|
||||
<sha256 value="5a5f4d796aa34a3480ea75df73892d68eba7cd4bc239c116eee3816ce973d469" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.media3" name="media3-muxer" version="1.9.0">
|
||||
<artifact name="media3-muxer-1.9.0.aar">
|
||||
<sha256 value="452b182d84cfe20d1154d999107b9aac7c218ad8ee208d35d067916a92a02031" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="media3-muxer-1.9.0.module">
|
||||
<sha256 value="e22678eed7457db37ceb4f14d96c761fa5055a114b4750892cf42b820a791428" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.navigation3" name="navigation3-runtime" version="1.2.0">
|
||||
<artifact name="navigation3-runtime-1.2.0.module">
|
||||
<sha256 value="ff14442bf489768bbd2126536921a4d007bdf2d117b2c0451be67cd58eb66a21" origin="Generated by Gradle"/>
|
||||
@@ -1989,6 +2136,19 @@
|
||||
<sha256 value="6ec8aa998df9b964424c7ab215738237a9b2cc4301da135bb9b8cdc62325fb3e" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.tracing" name="tracing-ktx" version="1.2.0">
|
||||
<artifact name="tracing-ktx-1.2.0.module">
|
||||
<sha256 value="39288b23c71a4391132aec9951f5e27f41727a2cdff69c6e4b4ece49f63e540c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.tracing" name="tracing-ktx" version="2.0.0">
|
||||
<artifact name="tracing-ktx-2.0.0.aar">
|
||||
<sha256 value="7e7cf1386841b11310138723eb9f36b5eaf6c8caec896b16f99e579d220d6a0c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="tracing-ktx-2.0.0.module">
|
||||
<sha256 value="f30609942614488befb6edaa36aa4d3b4fb1c1b7b79780630d3ca3a02b08c0a5" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.tracing" name="tracing-perfetto" version="1.0.1">
|
||||
<artifact name="tracing-perfetto-1.0.1.aar">
|
||||
<sha256 value="5387298b5bdd8f7d98315fe8720a757056ba0b9b5d9544d2e3fabc26b9ac55a6" origin="Generated by Gradle"/>
|
||||
@@ -2551,6 +2711,11 @@
|
||||
<sha256 value="05f740c6648165db00cf618dd56c200c4725e358e6d54f5853e0bec15734ea0a" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.auto" name="auto-parent" version="7">
|
||||
<artifact name="auto-parent-7.pom">
|
||||
<sha256 value="a46426fccb5d32705ad9cbbc996f786bd048cc8cbdd21db046500169f15a4356" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.auto.value" name="auto-value-annotations" version="1.6.2">
|
||||
<artifact name="auto-value-annotations-1.6.2.jar">
|
||||
<sha256 value="b48b04ddba40e8ac33bf036f06fc43995fc5084bd94bdaace807ce27d3bea3fb" origin="Generated by Gradle"/>
|
||||
@@ -2559,11 +2724,24 @@
|
||||
<sha256 value="1c76cd462fc96e7aa96dc70ce82f0d54063d6df16db35c9c7d9cc0d1a99d3fff" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.auto.value" name="auto-value-annotations" version="1.6.3">
|
||||
<artifact name="auto-value-annotations-1.6.3.jar">
|
||||
<sha256 value="0e951fee8c31f60270bc46553a8586001b7b93dbb12aec06373aa99a150392c0" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="auto-value-annotations-1.6.3.pom">
|
||||
<sha256 value="e1fc780f7ee025e662b3da72723dbe2ac8dac0a2f8920f265315c4e1be3d765c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.auto.value" name="auto-value-parent" version="1.6.2">
|
||||
<artifact name="auto-value-parent-1.6.2.pom">
|
||||
<sha256 value="27b640c82179f5cff62009c0b72033d9bc60f60e9902a66802274b7fe37fc81c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.auto.value" name="auto-value-parent" version="1.6.3">
|
||||
<artifact name="auto-value-parent-1.6.3.pom">
|
||||
<sha256 value="e59df5732b4cb34d5727181446f9ded9ce4425131a0a1062519eea196de4d8a1" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.code.findbugs" name="jsr305" version="3.0.2">
|
||||
<artifact name="jsr305-3.0.2.jar">
|
||||
<sha256 value="766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7" origin="Generated by Gradle"/>
|
||||
@@ -2601,6 +2779,14 @@
|
||||
<sha256 value="265ba959a8e13c3a06133f04b539169c1018daffd4d33f53c453ab4cb386f570" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.dagger" name="dagger" version="2.59">
|
||||
<artifact name="dagger-2.59.jar">
|
||||
<sha256 value="94d5b23812cc12fa903c9ac4a42978e7e7b2622e6b51c17f8b12037ceece43cd" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="dagger-2.59.pom">
|
||||
<sha256 value="0e47846618c7a1b7a8124fd20623a667643d73cbe0a561bb87056151aa967538" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.dagger" name="dagger" version="2.60.1">
|
||||
<artifact name="dagger-2.60.1.jar">
|
||||
<sha256 value="b012d0df527b51bfcd8953d5fcb4d022a45ebe66010d6f181ede68d1572b5cb2" origin="Generated by Gradle"/>
|
||||
@@ -2716,6 +2902,9 @@
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.errorprone" name="error_prone_annotations" version="2.18.0">
|
||||
<artifact name="error_prone_annotations-2.18.0.jar">
|
||||
<sha256 value="9e6814cb71816988a4fd1b07a993a8f21bb7058d522c162b1de849e19bea54ae" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="error_prone_annotations-2.18.0.pom">
|
||||
<sha256 value="920135797dcca5917b5a5c017642a58d340a4cd1bcd12f56f892a5663bd7bddc" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
@@ -2725,6 +2914,14 @@
|
||||
<sha256 value="4ca5a35d61235e16549ac346d1e34551cdf0fe27e84aa57e03cbeb255ea4e5da" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.errorprone" name="error_prone_annotations" version="2.28.0">
|
||||
<artifact name="error_prone_annotations-2.28.0.jar">
|
||||
<sha256 value="f3fc8a3a0a4020706a373b00e7f57c2512dd26d1f83d28c7d38768f8682b231e" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="error_prone_annotations-2.28.0.pom">
|
||||
<sha256 value="0ce909f13a568148476e5ee200f380f98c75ba08971aaf15db295eb77598ef3a" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.errorprone" name="error_prone_annotations" version="2.3.1">
|
||||
<artifact name="error_prone_annotations-2.3.1.pom">
|
||||
<sha256 value="3edce6b711ba368efe16b9b7aacb0214fbd648414cb9b965953a2e7ed89a819a" origin="Generated by Gradle"/>
|
||||
@@ -2764,6 +2961,11 @@
|
||||
<sha256 value="fa81829d049559df6927f9c9a6fd6bbd09f8b50e6d4736ae72c8300b6c3d7654" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.errorprone" name="error_prone_parent" version="2.28.0">
|
||||
<artifact name="error_prone_parent-2.28.0.pom">
|
||||
<sha256 value="accefdbb5416cef5fcd2ddc37db4f1fcb34a2193cc1a55dfe5970a131b3e7683" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.errorprone" name="error_prone_parent" version="2.3.1">
|
||||
<artifact name="error_prone_parent-2.3.1.pom">
|
||||
<sha256 value="767525d9a81129cd081968382980336327be4162b1e2251a182911daa733c123" origin="Generated by Gradle"/>
|
||||
@@ -2837,6 +3039,25 @@
|
||||
<sha256 value="13d4e2998aac652fc6d7b9eaf3e495fa2952bf98ef68a2c49aa5eaa0bbe731a9" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.guava" name="guava" version="32.0.1-android">
|
||||
<artifact name="guava-32.0.1-android.jar">
|
||||
<sha256 value="12429ff9ac33b7afd8b1a5071179757cf4d3c47f0f4099bc0384e644ecbf82dd" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="guava-32.0.1-android.pom">
|
||||
<sha256 value="cf26ce63461fb585cad25dc6932765883122643c3beec5e3269f667c73295ac4" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.guava" name="guava" version="33.3.1-android">
|
||||
<artifact name="guava-33.3.1-android.jar">
|
||||
<sha256 value="2c3e41d1b380f2044d257947a3aa82dabf3ae4b978622745254aa18b6cf89ab0" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="guava-33.3.1-android.module">
|
||||
<sha256 value="6971614ddeee003e54d2b69c6b0c94ce8a5b5eba980d16455c81df9089a7acb7" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="guava-33.3.1-jre.jar">
|
||||
<sha256 value="4bf0e2c5af8e4525c96e8fde17a4f7307f97f8478f11c4c8e35a0e3298ae4e90" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.guava" name="guava" version="33.4.0-jre">
|
||||
<artifact name="guava-33.4.0-jre.jar">
|
||||
<sha256 value="b918c98a7e44dbe94ebd9fe3e40cddaadb5a93e6a78eb6008b42df237241e538" origin="Generated by Gradle"/>
|
||||
@@ -2863,6 +3084,16 @@
|
||||
<sha256 value="30a51d34b075c9b4eb6a2da3fba6c1f5047b45225a3a03aebcefc0b7880e5735" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.guava" name="guava-parent" version="32.0.1-android">
|
||||
<artifact name="guava-parent-32.0.1-android.pom">
|
||||
<sha256 value="cddb3a941d71be5e871f39a239ba3bb8883c88c7763d8a3d2d342b09a1d5da30" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.guava" name="guava-parent" version="33.3.1-android">
|
||||
<artifact name="guava-parent-33.3.1-android.pom">
|
||||
<sha256 value="6e11986ea7250b51f847157e2dc937f32a306804dfce0007a5e81ddb9b95c579" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.guava" name="guava-parent" version="33.4.0-android">
|
||||
<artifact name="guava-parent-33.4.0-android.pom">
|
||||
<sha256 value="7220ede61026596fbc720ee4b93246fa2d14f328058532b59ef053de397c7d83" origin="Generated by Gradle"/>
|
||||
@@ -2903,6 +3134,9 @@
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.j2objc" name="j2objc-annotations" version="2.8">
|
||||
<artifact name="j2objc-annotations-2.8.jar">
|
||||
<sha256 value="f02a95fa1a5e95edb3ed859fd0fb7df709d121a35290eff8b74dce2ab7f4d6ed" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="j2objc-annotations-2.8.pom">
|
||||
<sha256 value="37f87798b18385113c918bfa9e1276fe50735ef8fa849b5800c519d54dbf11f8" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
@@ -3610,6 +3844,14 @@
|
||||
<sha256 value="66f563d8a2a1ee395a1283992fd646347f42054d071592d1f477523816e397fa" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.checkerframework" name="checker-qual" version="3.33.0">
|
||||
<artifact name="checker-qual-3.33.0.jar">
|
||||
<sha256 value="e316255bbfcd9fe50d165314b85abb2b33cb2a66a93c491db648e498a82c2de1" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="checker-qual-3.33.0.module">
|
||||
<sha256 value="e8521d75625d41272c767d262a153ac163cc505b66644a2ef705fa8949ffb4e5" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.checkerframework" name="checker-qual" version="3.43.0">
|
||||
<artifact name="checker-qual-3.43.0.jar">
|
||||
<sha256 value="3fbc2e98f05854c3df16df9abaa955b91b15b3ecac33623208ed6424640ef0f6" origin="Generated by Gradle"/>
|
||||
@@ -3768,6 +4010,11 @@
|
||||
<sha256 value="3090b4e873054cdc29991ae94c92fa45afb4c145d460441d803baf6ef165bbb8" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-bom" version="1.8.0">
|
||||
<artifact name="kotlin-bom-1.8.0.pom">
|
||||
<sha256 value="681f9878548c0a149c678092fd8b1f4cc7c5c41ba1b24397101c1073a6c76dda" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-bom" version="2.3.21">
|
||||
<artifact name="kotlin-bom-2.3.21.pom">
|
||||
<sha256 value="950704bad04c5143656cfca1d2c574f25fcad9cac33905ab22a57e9fdf7bfd88" origin="Generated by Gradle"/>
|
||||
@@ -4400,6 +4647,19 @@
|
||||
<sha256 value="ee66712b1006e971636f11554af63c56835caf315382ce23e54f59f5b8b9d4f9" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlinx" name="atomicfu" version="0.28.0">
|
||||
<artifact name="atomicfu-0.28.0.module">
|
||||
<sha256 value="535568c9291a3da7705c4b40535eacedf86b248df570ac52669c907d4bb8558b" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlinx" name="atomicfu-jvm" version="0.28.0">
|
||||
<artifact name="atomicfu-jvm-0.28.0.jar">
|
||||
<sha256 value="39576ec46b83412ff7a2909d24cccbba90400e91f9aa67b250309bc0872ecf52" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="atomicfu-jvm-0.28.0.module">
|
||||
<sha256 value="34b623af9c25ca7f2e52406f10495c46e6f410835d7a058c60ba36923d689635" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlinx" name="kotlinx-coroutines-android" version="1.11.0">
|
||||
<artifact name="kotlinx-coroutines-android-1.11.0.jar">
|
||||
<sha256 value="c2cb206d27017c7d1bf5ff179787397543d13748dbabb0d7237e1585e0b29044" origin="Generated by Gradle"/>
|
||||
|
||||
@@ -22,6 +22,14 @@ androidx.benchmark:benchmark-macro:1.5.0=benchmarkCompileClasspath,benchmarkLint
|
||||
androidx.benchmark:benchmark-traceprocessor-android:1.5.0=benchmarkCompileClasspath,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath
|
||||
androidx.benchmark:benchmark-traceprocessor:1.5.0=benchmarkCompileClasspath,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath
|
||||
androidx.biometric:biometric:1.1.0=benchmarkTestedApks,debugTestedApks
|
||||
androidx.camera.featurecombinationquery:featurecombinationquery:1.6.2=benchmarkTestedApks,debugTestedApks
|
||||
androidx.camera.viewfinder:viewfinder-core:1.5.1=benchmarkTestedApks,debugTestedApks
|
||||
androidx.camera:camera-camera2-pipe:1.6.2=benchmarkTestedApks,debugTestedApks
|
||||
androidx.camera:camera-camera2:1.6.2=benchmarkTestedApks,debugTestedApks
|
||||
androidx.camera:camera-core:1.6.2=benchmarkTestedApks,debugTestedApks
|
||||
androidx.camera:camera-lifecycle:1.6.2=benchmarkTestedApks,debugTestedApks
|
||||
androidx.camera:camera-video:1.6.2=benchmarkTestedApks,debugTestedApks
|
||||
androidx.camera:camera-view:1.6.2=benchmarkTestedApks,debugTestedApks
|
||||
androidx.collection:collection-jvm:1.6.0=benchmarkTestedApks,debugTestedApks
|
||||
androidx.collection:collection:1.0.0=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath
|
||||
androidx.collection:collection:1.6.0=benchmarkTestedApks,debugTestedApks
|
||||
@@ -64,9 +72,11 @@ androidx.compose.ui:ui-util-jvmstubs:1.12.1=benchmarkTestedApks,debugTestedApks
|
||||
androidx.compose.ui:ui-util:1.12.1=benchmarkTestedApks,debugTestedApks
|
||||
androidx.compose.ui:ui:1.12.1=benchmarkTestedApks,debugTestedApks
|
||||
androidx.compose:compose-bom:2026.09.00=benchmarkTestedApks,debugTestedApks
|
||||
androidx.concurrent:concurrent-futures-ktx:1.1.0=benchmarkTestedApks,debugTestedApks
|
||||
androidx.concurrent:concurrent-futures-ktx:1.2.0=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath
|
||||
androidx.concurrent:concurrent-futures:1.1.0=benchmarkTestedApks,debugTestedApks
|
||||
androidx.concurrent:concurrent-futures:1.2.0=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath
|
||||
androidx.core:core-backported-fixes:1.0.0=benchmarkTestedApks,debugTestedApks
|
||||
androidx.core:core-ktx:1.18.0=benchmarkTestedApks,debugTestedApks
|
||||
androidx.core:core-viewtree:1.0.0=benchmarkTestedApks,debugTestedApks
|
||||
androidx.core:core:1.18.0=benchmarkTestedApks,debugTestedApks
|
||||
@@ -74,6 +84,7 @@ androidx.core:core:1.9.0=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,
|
||||
androidx.cursoradapter:cursoradapter:1.0.0=benchmarkTestedApks,debugTestedApks
|
||||
androidx.customview:customview:1.0.0=benchmarkTestedApks,debugTestedApks
|
||||
androidx.drawerlayout:drawerlayout:1.0.0=benchmarkTestedApks,debugTestedApks
|
||||
androidx.exifinterface:exifinterface:1.4.2=benchmarkTestedApks,debugTestedApks
|
||||
androidx.fragment:fragment:1.9.1=benchmarkTestedApks,debugTestedApks
|
||||
androidx.interpolator:interpolator:1.0.0=benchmarkTestedApks,debugTestedApks
|
||||
androidx.lifecycle:lifecycle-common-jvm:2.11.0=benchmarkTestedApks,debugTestedApks
|
||||
@@ -97,6 +108,9 @@ androidx.lifecycle:lifecycle-viewmodel-savedstate-desktop:2.11.0=benchmarkTested
|
||||
androidx.lifecycle:lifecycle-viewmodel-savedstate:2.11.0=benchmarkTestedApks,debugTestedApks
|
||||
androidx.lifecycle:lifecycle-viewmodel:2.11.0=benchmarkTestedApks,debugTestedApks
|
||||
androidx.loader:loader:1.0.0=benchmarkTestedApks,debugTestedApks
|
||||
androidx.media3:media3-common:1.9.0=benchmarkTestedApks,debugTestedApks
|
||||
androidx.media3:media3-container:1.9.0=benchmarkTestedApks,debugTestedApks
|
||||
androidx.media3:media3-muxer:1.9.0=benchmarkTestedApks,debugTestedApks
|
||||
androidx.navigation3:navigation3-runtime-desktop:1.2.0=benchmarkTestedApks,debugTestedApks
|
||||
androidx.navigation3:navigation3-runtime:1.2.0=benchmarkTestedApks,debugTestedApks
|
||||
androidx.navigation3:navigation3-ui-jvmstubs:1.2.0=benchmarkTestedApks,debugTestedApks
|
||||
@@ -125,6 +139,7 @@ androidx.test:rules:1.5.0=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath
|
||||
androidx.test:runner:1.7.0=benchmarkCompileClasspath,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath
|
||||
androidx.tracing:tracing-desktop:2.0.0=benchmarkTestedApks,debugTestedApks
|
||||
androidx.tracing:tracing-ktx:1.1.0=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath
|
||||
androidx.tracing:tracing-ktx:2.0.0=benchmarkTestedApks,debugTestedApks
|
||||
androidx.tracing:tracing-perfetto-binary:1.0.1=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath
|
||||
androidx.tracing:tracing-perfetto-handshake:1.0.1=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath
|
||||
androidx.tracing:tracing-perfetto:1.0.1=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath
|
||||
@@ -169,18 +184,21 @@ com.android.tools:sdk-common:32.4.1=androidLintTool
|
||||
com.android.tools:sdklib:32.4.1=androidLintTool
|
||||
com.github.ajalt.clikt:clikt-jvm:5.0.3=ktlint
|
||||
com.github.ajalt.clikt:clikt:5.0.3=ktlint
|
||||
com.google.auto.value:auto-value-annotations:1.6.3=benchmarkTestedApks,debugTestedApks
|
||||
com.google.code.findbugs:jsr305:3.0.2=androidLintTool,benchmarkTestedApks,debugTestedApks
|
||||
com.google.code.gson:gson:2.11.0=androidLintTool
|
||||
com.google.dagger:dagger-lint-aar:2.60.1=benchmarkTestedApks,debugTestedApks
|
||||
com.google.dagger:dagger:2.60.1=benchmarkTestedApks,debugTestedApks
|
||||
com.google.dagger:hilt-android:2.60.1=benchmarkTestedApks,debugTestedApks
|
||||
com.google.dagger:hilt-core:2.60.1=benchmarkTestedApks,debugTestedApks
|
||||
com.google.errorprone:error_prone_annotations:2.28.0=benchmarkTestedApks,debugTestedApks
|
||||
com.google.errorprone:error_prone_annotations:2.36.0=androidLintTool
|
||||
com.google.guava:failureaccess:1.0.2=androidLintTool
|
||||
com.google.guava:failureaccess:1.0.2=androidLintTool,benchmarkTestedApks,debugTestedApks
|
||||
com.google.guava:guava:33.3.1-android=benchmarkTestedApks,debugTestedApks
|
||||
com.google.guava:guava:33.4.0-jre=androidLintTool
|
||||
com.google.guava:listenablefuture:1.0=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,benchmarkTestedApks,debugLintChecksClasspath,debugRuntimeClasspath,debugTestedApks
|
||||
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=androidLintTool
|
||||
com.google.j2objc:j2objc-annotations:3.0.0=androidLintTool
|
||||
com.google.guava:listenablefuture:1.0=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath
|
||||
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=androidLintTool,benchmarkTestedApks,debugTestedApks
|
||||
com.google.j2objc:j2objc-annotations:3.0.0=androidLintTool,benchmarkTestedApks,debugTestedApks
|
||||
com.google.jimfs:jimfs:1.1=androidLintTool
|
||||
com.google.protobuf:protobuf-java:3.25.5=androidLintTool,unified-test-platform-gradle-work-action
|
||||
com.pinterest.ktlint:ktlint-cli-reporter-baseline:1.7.1=ktlint,ktlintBaselineReporter
|
||||
@@ -233,11 +251,12 @@ org.apache.httpcomponents:httpmime:4.5.6=androidLintTool
|
||||
org.bouncycastle:bcpkix-jdk18on:1.80.2=androidLintTool
|
||||
org.bouncycastle:bcprov-jdk18on:1.80.2=androidLintTool
|
||||
org.bouncycastle:bcutil-jdk18on:1.80.2=androidLintTool
|
||||
org.checkerframework:checker-qual:3.43.0=androidLintTool
|
||||
org.checkerframework:checker-qual:3.43.0=androidLintTool,benchmarkTestedApks,debugTestedApks
|
||||
org.ec4j.core:ec4j-core:1.1.1=ktlint,ktlintBaselineReporter,ktlintRuleset
|
||||
org.glassfish.jaxb:jaxb-runtime:2.3.2=androidLintTool
|
||||
org.glassfish.jaxb:txw2:2.3.2=androidLintTool
|
||||
org.hamcrest:hamcrest-core:1.3=benchmarkCompileClasspath,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-bom:1.8.0=benchmarkTestedApks,debugTestedApks
|
||||
org.jetbrains.kotlin:kotlin-build-tools-api:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-api:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-compat:2.4.21=kotlinAbiValidationCompatClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
@@ -270,6 +289,8 @@ org.jetbrains.kotlin:kotlin-stdlib:2.2.10=androidLintTool,unified-test-platform-
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.4.21=benchmarkCompileClasspath,benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,benchmarkTestedApks,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugTestedApks,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-tooling-core:2.4.21=kotlinAbiValidationCompatClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlinx:atomicfu-jvm:0.28.0=benchmarkTestedApks,debugTestedApks
|
||||
org.jetbrains.kotlinx:atomicfu:0.28.0=benchmarkTestedApks,debugTestedApks
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.11.0=benchmarkTestedApks,debugTestedApks
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0=benchmarkLintChecksClasspath,benchmarkRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.11.0=benchmarkTestedApks,debugTestedApks
|
||||
|
||||
@@ -40,6 +40,9 @@ kotlin {
|
||||
|
||||
dependencies {
|
||||
implementation(project(":core"))
|
||||
implementation(libs.camera.camera2)
|
||||
implementation(libs.camera.lifecycle)
|
||||
implementation(libs.camera.view)
|
||||
implementation(libs.biometric)
|
||||
implementation(libs.fragment)
|
||||
testImplementation(libs.junit)
|
||||
|
||||
@@ -14,13 +14,23 @@ androidx.appcompat:appcompat:1.2.0=debugAndroidTestLintChecksClasspath,debugAndr
|
||||
androidx.arch.core:core-common:2.2.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.arch.core:core-runtime:2.2.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.biometric:biometric:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.camera.featurecombinationquery:featurecombinationquery:1.6.2=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.camera.viewfinder:viewfinder-core:1.5.1=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.camera:camera-camera2-pipe:1.6.2=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.camera:camera-camera2:1.6.2=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.camera:camera-core:1.6.2=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.camera:camera-lifecycle:1.6.2=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.camera:camera-video:1.6.2=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.camera:camera-view:1.6.2=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.collection:collection-jvm:1.4.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath
|
||||
androidx.collection:collection-jvm:1.6.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.collection:collection:1.4.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath
|
||||
androidx.collection:collection:1.6.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.concurrent:concurrent-futures-ktx:1.1.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.concurrent:concurrent-futures-ktx:1.2.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath
|
||||
androidx.concurrent:concurrent-futures:1.1.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.concurrent:concurrent-futures:1.2.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath
|
||||
androidx.core:core-backported-fixes:1.0.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.core:core-ktx:1.13.1=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.core:core-ktx:1.9.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath
|
||||
androidx.core:core-viewtree:1.0.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
@@ -29,6 +39,7 @@ androidx.core:core:1.9.0=debugAndroidTestCompileClasspath,debugCompileClasspath,
|
||||
androidx.cursoradapter:cursoradapter:1.0.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.customview:customview:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.drawerlayout:drawerlayout:1.0.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.exifinterface:exifinterface:1.4.2=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.fragment:fragment:1.9.1=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.interpolator:interpolator:1.0.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.lifecycle:lifecycle-common-jvm:2.10.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
@@ -46,6 +57,9 @@ androidx.lifecycle:lifecycle-viewmodel-savedstate-android:2.10.0=debugAndroidTes
|
||||
androidx.lifecycle:lifecycle-viewmodel-savedstate:2.10.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.lifecycle:lifecycle-viewmodel:2.10.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.loader:loader:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.media3:media3-common:1.9.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.media3:media3-container:1.9.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.media3:media3-muxer:1.9.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.profileinstaller:profileinstaller:1.4.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.savedstate:savedstate-android:1.4.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.savedstate:savedstate-ktx:1.4.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
@@ -56,6 +70,7 @@ androidx.test:core:1.7.0=debugAndroidTestCompileClasspath,debugAndroidTestLintCh
|
||||
androidx.test:monitor:1.8.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath
|
||||
androidx.test:runner:1.7.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath
|
||||
androidx.tracing:tracing-android:2.0.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.tracing:tracing-ktx:2.0.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.tracing:tracing:1.1.0=debugAndroidTestCompileClasspath
|
||||
androidx.tracing:tracing:2.0.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.vectordrawable:vectordrawable-animated:1.1.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
@@ -95,14 +110,21 @@ com.android.tools:sdk-common:32.4.1=androidLintTool
|
||||
com.android.tools:sdklib:32.4.1=androidLintTool
|
||||
com.github.ajalt.clikt:clikt-jvm:5.0.3=ktlint
|
||||
com.github.ajalt.clikt:clikt:5.0.3=ktlint
|
||||
com.google.code.findbugs:jsr305:3.0.2=androidLintTool
|
||||
com.google.auto.value:auto-value-annotations:1.6.3=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
com.google.code.findbugs:jsr305:3.0.2=androidLintTool,debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
com.google.code.gson:gson:2.11.0=androidLintTool
|
||||
com.google.dagger:dagger:2.59=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
com.google.errorprone:error_prone_annotations:2.18.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath
|
||||
com.google.errorprone:error_prone_annotations:2.28.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
com.google.errorprone:error_prone_annotations:2.36.0=androidLintTool
|
||||
com.google.guava:failureaccess:1.0.2=androidLintTool
|
||||
com.google.guava:failureaccess:1.0.1=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath
|
||||
com.google.guava:failureaccess:1.0.2=androidLintTool,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
com.google.guava:guava:32.0.1-android=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath
|
||||
com.google.guava:guava:33.3.1-android=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
com.google.guava:guava:33.4.0-jre=androidLintTool
|
||||
com.google.guava:listenablefuture:1.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=androidLintTool
|
||||
com.google.j2objc:j2objc-annotations:3.0.0=androidLintTool
|
||||
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=androidLintTool,debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
com.google.j2objc:j2objc-annotations:2.8=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath
|
||||
com.google.j2objc:j2objc-annotations:3.0.0=androidLintTool,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
com.google.jimfs:jimfs:1.1=androidLintTool
|
||||
com.google.protobuf:protobuf-java:3.25.5=androidLintTool,unified-test-platform-gradle-work-action
|
||||
com.pinterest.ktlint:ktlint-cli-reporter-baseline:1.7.1=ktlint,ktlintBaselineReporter
|
||||
@@ -132,8 +154,9 @@ io.github.detekt.sarif4k:sarif4k:0.6.0=ktlint,ktlintReporter
|
||||
io.github.oshai:kotlin-logging-jvm:7.0.7=ktlint,ktlintBaselineReporter,ktlintReporter,ktlintRuleset
|
||||
io.github.oshai:kotlin-logging:5.1.0=ktlint,ktlintBaselineReporter,ktlintReporter
|
||||
jakarta.activation:jakarta.activation-api:1.2.1=androidLintTool
|
||||
jakarta.inject:jakarta.inject-api:2.0.1=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
jakarta.xml.bind:jakarta.xml.bind-api:2.3.2=androidLintTool
|
||||
javax.inject:javax.inject:1=androidLintTool
|
||||
javax.inject:javax.inject:1=androidLintTool,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
junit:junit:4.13.2=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath
|
||||
net.java.dev.jna:jna-platform:5.6.0=androidLintTool
|
||||
net.java.dev.jna:jna:5.19.1=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
@@ -149,11 +172,13 @@ org.apache.httpcomponents:httpmime:4.5.6=androidLintTool
|
||||
org.bouncycastle:bcpkix-jdk18on:1.80.2=androidLintTool
|
||||
org.bouncycastle:bcprov-jdk18on:1.80.2=androidLintTool
|
||||
org.bouncycastle:bcutil-jdk18on:1.80.2=androidLintTool
|
||||
org.checkerframework:checker-qual:3.43.0=androidLintTool
|
||||
org.checkerframework:checker-qual:3.33.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath
|
||||
org.checkerframework:checker-qual:3.43.0=androidLintTool,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
org.ec4j.core:ec4j-core:1.1.1=ktlint,ktlintBaselineReporter,ktlintRuleset
|
||||
org.glassfish.jaxb:jaxb-runtime:2.3.2=androidLintTool
|
||||
org.glassfish.jaxb:txw2:2.3.2=androidLintTool
|
||||
org.hamcrest:hamcrest-core:1.3=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-bom:1.8.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-api:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-api:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-compat:2.4.21=kotlinAbiValidationCompatClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
@@ -186,6 +211,8 @@ org.jetbrains.kotlin:kotlin-stdlib:2.2.10=androidLintTool,unified-test-platform-
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.4.21=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-tooling-core:2.4.21=kotlinAbiValidationCompatClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlinx:atomicfu-jvm:0.28.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
org.jetbrains.kotlinx:atomicfu:0.28.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.11.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.11.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<application>
|
||||
<activity android:name="de.rfc1437.ironstorage.platform.KeystoreTestActivity" android:exported="false" android:theme="@android:style/Theme.Material.Light.NoActionBar" />
|
||||
</application>
|
||||
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
package de.rfc1437.ironstorage.platform
|
||||
|
||||
import android.Manifest
|
||||
import android.content.pm.PackageManager
|
||||
import androidx.test.core.app.ActivityScenario
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import java.util.concurrent.CountDownLatch
|
||||
import java.util.concurrent.TimeUnit
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
|
||||
class AndroidQrCameraTest {
|
||||
@Test fun livePreviewDeliversBoundedPlanesAndCanBeClosedAndReopened() {
|
||||
val context = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
assertEquals(
|
||||
PackageManager.PERMISSION_GRANTED,
|
||||
context.checkSelfPermission(Manifest.permission.CAMERA)
|
||||
)
|
||||
ActivityScenario.launch(KeystoreTestActivity::class.java).use { activity ->
|
||||
repeat(2) {
|
||||
val received = CountDownLatch(1)
|
||||
val failed = CountDownLatch(1)
|
||||
var camera: AndroidQrCamera? = null
|
||||
activity.onActivity { host ->
|
||||
camera = AndroidQrCamera(host, { frame ->
|
||||
try {
|
||||
assertTrue(frame.width in 1u..2048u)
|
||||
assertTrue(frame.height in 1u..2048u)
|
||||
assertTrue(frame.pixels.size <= 4 * 1024 * 1024)
|
||||
assertTrue(frame.rotationDegrees in listOf(0u, 90u, 180u, 270u))
|
||||
received.countDown()
|
||||
} finally {
|
||||
frame.pixels.fill(0)
|
||||
}
|
||||
}, { failed.countDown() })
|
||||
host.setContentView(requireNotNull(camera).view)
|
||||
assertTrue(requireNotNull(camera).view.clipToOutline)
|
||||
}
|
||||
assertTrue(
|
||||
"The emulator camera did not deliver a frame",
|
||||
received.await(15, TimeUnit.SECONDS)
|
||||
)
|
||||
assertFalse("CameraX failed to bind", failed.count == 0L)
|
||||
activity.onActivity { camera?.close() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package de.rfc1437.ironstorage.platform
|
||||
|
||||
import android.util.Size
|
||||
import androidx.camera.core.CameraSelector
|
||||
import androidx.camera.core.ImageAnalysis
|
||||
import androidx.camera.core.Preview
|
||||
import androidx.camera.core.resolutionselector.ResolutionSelector
|
||||
import androidx.camera.core.resolutionselector.ResolutionStrategy
|
||||
import androidx.camera.lifecycle.ProcessCameraProvider
|
||||
import androidx.camera.view.PreviewView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import de.rfc1437.ironstorage.core.CameraFrame
|
||||
import de.rfc1437.ironstorage.core.CameraPreview
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
internal class AndroidQrCamera(
|
||||
private val activity: FragmentActivity,
|
||||
private val frame: (CameraFrame) -> Unit,
|
||||
private val failure: () -> Unit
|
||||
) : CameraPreview {
|
||||
override val view = PreviewView(activity).apply {
|
||||
implementationMode = PreviewView.ImplementationMode.COMPATIBLE
|
||||
outlineProvider = android.view.ViewOutlineProvider.BOUNDS
|
||||
clipToOutline = true
|
||||
scaleType = PreviewView.ScaleType.FIT_CENTER
|
||||
importantForAccessibility = android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO
|
||||
}
|
||||
private val executor = Executors.newSingleThreadExecutor()
|
||||
private val preview = Preview.Builder().build()
|
||||
private val analysis = ImageAnalysis.Builder()
|
||||
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
|
||||
.setResolutionSelector(
|
||||
ResolutionSelector.Builder().setResolutionStrategy(
|
||||
ResolutionStrategy(Size(1280, 720), ResolutionStrategy.FALLBACK_RULE_CLOSEST_LOWER)
|
||||
).build()
|
||||
).build()
|
||||
private var provider: ProcessCameraProvider? = null
|
||||
|
||||
@Volatile private var active = true
|
||||
|
||||
init {
|
||||
analysis.setAnalyzer(executor) { image ->
|
||||
var bytes: ByteArray? = null
|
||||
try {
|
||||
if (active && image.width in 1..2048 && image.height in 1..2048) {
|
||||
val plane = image.planes[0]
|
||||
val source = plane.buffer.duplicate()
|
||||
if (source.remaining() <= 4 * 1024 * 1024) {
|
||||
val pixels = ByteArray(source.remaining())
|
||||
bytes = pixels
|
||||
source.get(pixels)
|
||||
if (active) {
|
||||
frame(
|
||||
CameraFrame(
|
||||
pixels,
|
||||
image.width.toUInt(),
|
||||
image.height.toUInt(),
|
||||
plane.rowStride.toUInt(),
|
||||
plane.pixelStride.toUInt(),
|
||||
image.imageInfo.rotationDegrees.toUInt()
|
||||
)
|
||||
)
|
||||
// The receiver clears transferred bytes after the native call.
|
||||
bytes = null
|
||||
}
|
||||
} else {
|
||||
failure()
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
bytes?.fill(0)
|
||||
image.close()
|
||||
}
|
||||
}
|
||||
val pending = ProcessCameraProvider.getInstance(activity)
|
||||
pending.addListener({
|
||||
if (active) {
|
||||
try {
|
||||
provider = pending.get()
|
||||
preview.setSurfaceProvider(view.surfaceProvider)
|
||||
provider!!.bindToLifecycle(
|
||||
activity,
|
||||
CameraSelector.DEFAULT_BACK_CAMERA,
|
||||
preview,
|
||||
analysis
|
||||
)
|
||||
} catch (_: java.util.concurrent.ExecutionException) {
|
||||
close()
|
||||
failure()
|
||||
} catch (_: InterruptedException) {
|
||||
Thread.currentThread().interrupt()
|
||||
close()
|
||||
failure()
|
||||
} catch (_: IllegalArgumentException) {
|
||||
close()
|
||||
failure()
|
||||
} catch (_: SecurityException) {
|
||||
close()
|
||||
failure()
|
||||
}
|
||||
}
|
||||
}, ContextCompat.getMainExecutor(activity))
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
active = false
|
||||
analysis.clearAnalyzer()
|
||||
provider?.unbind(preview, analysis)
|
||||
provider = null
|
||||
executor.shutdown()
|
||||
}
|
||||
}
|
||||
+7
@@ -40,6 +40,13 @@ class AndroidSettingsPlatform(
|
||||
host.clear()
|
||||
}
|
||||
}
|
||||
override fun cameraPreview(
|
||||
frame: (de.rfc1437.ironstorage.core.CameraFrame) -> Unit,
|
||||
failure: () -> Unit
|
||||
): de.rfc1437.ironstorage.core.CameraPreview? {
|
||||
val activity = host.get() ?: return null
|
||||
return AndroidQrCamera(activity, frame, failure)
|
||||
}
|
||||
override fun chooseQrImages(): Boolean {
|
||||
val picker = picker ?: return false
|
||||
return try {
|
||||
|
||||
Reference in new issue
Block a user