Package the Rust mobile core and generated Kotlin API for Android (#92)
Dependency security audit / rustsec (push) Failing after 24s
Dependency security audit / rustsec (push) Failing after 24s
This commit is contained in:
1 parent
e079b82b15
commit
fcb36a0684
42 files changed
+1586
-172
No files matched your search
+95
-15
@@ -1,13 +1,13 @@
|
||||
# Native Android build
|
||||
|
||||
Architecture and issue ownership: [ADR](../docs/android/architecture.md) and
|
||||
[parity matrix](../docs/android/parity.md). This scaffold implements #89. It is
|
||||
an installable native Compose foundation; onboarding, secure storage and native
|
||||
runtime packaging are implemented by their milestone issues.
|
||||
[parity matrix](../docs/android/parity.md). The native foundation implements #89 and #92. Onboarding and secure storage
|
||||
are implemented by their milestone issues. Both variants now invoke Rust through
|
||||
the generated UniFFI API.
|
||||
|
||||
## Reproducible setup
|
||||
|
||||
Use a stable workspace Rust toolchain satisfying Cargo.toml, a JDK 25 installation
|
||||
Use Rust 1.97.1 (pinned in rust-toolchain.toml), cargo-ndk 4.1.2, a JDK 25 installation
|
||||
(Android Studio's JetBrains Runtime 25 is suitable), Android SDK Platform 37,
|
||||
build-tools 36.0.0 and NDK 30.0.16248370. The app emits JVM 17-compatible code
|
||||
and supports minSdk 26. Set JAVA_HOME and ANDROID_HOME/ANDROID_SDK_ROOT or create
|
||||
@@ -19,14 +19,14 @@ The committed Gradle 9.8.1 wrapper verifies the distribution SHA-256. Its JAR
|
||||
SHA-256 is 3b8a25775a69158b5ad2b1d17a80a88dc7b40a352a73eb27d06c612a7ce68e98,
|
||||
verified against the official Gradle version metadata. AGP 9.4.1 includes Kotlin
|
||||
support; the Kotlin JVM/Compose plugin pin upgrades its classpath consistently
|
||||
to 2.4.20. Do not additionally apply kotlin-android with built-in Kotlin enabled.
|
||||
to 2.4.21. Do not additionally apply kotlin-android with built-in Kotlin enabled.
|
||||
The version catalog is the single source for Android dependency/SDK/NDK pins.
|
||||
|
||||
From this directory:
|
||||
|
||||
```sh
|
||||
./gradlew :app:assembleDebug :app:assembleRelease :app:testDebugUnitTest :app:lintDebug ktlintCheck
|
||||
./gradlew :app:connectedDebugAndroidTest
|
||||
./gradlew auditNativePackages :core:testDebugUnitTest :app:testDebugUnitTest :app:lintDebug :app:lintRelease ktlintCheck
|
||||
./gradlew :app:connectedDebugAndroidTest :rust-bridge:connectedDebugAndroidTest
|
||||
```
|
||||
|
||||
Repeat the first command to verify configuration-cache reuse. Dependency
|
||||
@@ -50,12 +50,11 @@ source/import boundaries and subprocess paths before every Android build.
|
||||
These static checks accompany code review; they do not prove arbitrary Kotlin
|
||||
code cannot conceal a domain implementation.
|
||||
|
||||
Debug-only Loading/Empty/Ready/Locked/Error fixtures are generated from the
|
||||
storage-owned MobileShell::fixture by the Rust build tool. Debug controls select
|
||||
the fixture and native tabs; these controls and generated fake states are absent
|
||||
from release. Release displays the scaffold state and does not pretend to have
|
||||
opened/decrypted a repository. Future #92 replaces scaffold wiring with generated
|
||||
UniFFI calls; feature code continues to consume the facade.
|
||||
Debug controls invoke the storage-owned MobileShell::fixture through the native
|
||||
API for Loading/Empty/Ready/Locked/Error. A build-generated fixture inventory is
|
||||
used only as the test oracle. Release calls the same Rust Empty fixture without
|
||||
debug controls; repository initialization is owned by #90. Feature code consumes
|
||||
only the facade, including typed native recovery states.
|
||||
|
||||
## Identity, signing and update
|
||||
|
||||
@@ -64,8 +63,8 @@ Version code 1 and name 1.0.1 are deterministic initial metadata. Debug signing
|
||||
uses the standard local debug key. Release has no configured signing key and
|
||||
produces an unsigned APK; #112 configures protected upload signing. Do not add
|
||||
signing secrets or store passwords to the repository. Native symbol level FULL
|
||||
and the selected three ABIs are declared for later Rust packaging; the scaffold
|
||||
ships no native secret runtime or development network endpoint.
|
||||
and the selected three ABIs are packaged. Native runtime packaging is described
|
||||
below; no development network endpoint is included.
|
||||
|
||||
The manifest has only the exported launcher activity. Backup/cloud/device-transfer
|
||||
exclusions and cleartext denial are explicit. Feature-specific services/permissions
|
||||
@@ -87,3 +86,84 @@ app-data package as an update. After closing an issue, clean its project build
|
||||
outputs and Cargo target; preserve the emulator and shared SDK/toolchain caches.
|
||||
AGP's leaveApksInstalledAfterRun option is enabled so instrumented checks do not
|
||||
uninstall the app after running. Keep it enabled for this persistent test device.
|
||||
|
||||
## Rust packaging and integrity
|
||||
|
||||
Install the pinned build tools once:
|
||||
|
||||
```sh
|
||||
rustup toolchain install 1.97.1 --profile minimal
|
||||
rustup target add --toolchain 1.97.1 aarch64-linux-android armv7-linux-androideabi x86_64-linux-android
|
||||
cargo install cargo-ndk --version 4.1.2 --locked
|
||||
```
|
||||
|
||||
Gradle checks the actual Cargo/cargo-ndk/NDK revisions before building. Each
|
||||
variant compiles crates/android with cargo-ndk into its own generated jniLibs,
|
||||
then verifies ELF architecture, 16 KB LOAD alignment, and byte-identical UniFFI
|
||||
metadata across all three ABIs. A packaging step selects only the Android library
|
||||
and rejects accidental inclusion of the dependency Apple cdylib. The thin Android crate re-exports the existing
|
||||
UniFFI component; it duplicates no storage rules or converters. #91 owns the
|
||||
platform-neutral contract extraction. No handwritten JNI or unsafe Rust is added.
|
||||
|
||||
The workspace's UniFFI 0.32.0 CLI generates Android-mode immutable Kotlin
|
||||
records from the arm64 library, using the global defaults in uniffi.toml.
|
||||
A version-checked preparation step redacts record toString, typed/internal
|
||||
exception diagnostics and unexpected callback stack traces, mechanically renames
|
||||
Rust error message fields to rustMessage in Kotlin,
|
||||
and translates every integrity guard to a typed failure. Checksums remain enabled
|
||||
and retain every native function and expected value. UniFFI checksums are u16:
|
||||
JNA's generated Int return is normalized to its lower 16 bits before comparison;
|
||||
AArch64 may leave unrelated upper bits in the return register. Contract versions
|
||||
are compared at their full width. A failed initializer remains failed until an
|
||||
app restart/update, rather than reporting a different error on each retry.
|
||||
|
||||
NativeRuntime performs OS library/ABI preflight, loads the library and initializes
|
||||
UniFFI before entering Rust. Missing/unsupported libraries, broken APKs, contract
|
||||
or checksum mismatch, and load failures yield typed, non-secret recovery states.
|
||||
It rejects main-thread calls. The core facade schedules blocking native calls on
|
||||
Dispatchers.IO; cancellation propagates and a superseded result cannot overwrite
|
||||
newer state. Blocking fixture calls finish in Rust when a coroutine is cancelled;
|
||||
no thread is forcibly stopped. Long storage operations must use their Rust-owned
|
||||
cancellation methods when their feature is integrated.
|
||||
|
||||
No Rust-to-Kotlin platform callbacks are installed by #92. When #93 adds them,
|
||||
use generated UniFFI/JNA callback adapters only: JNA attaches a calling native
|
||||
thread to the JVM; retain the callback for the full Rust owner lifetime, release
|
||||
it after unregistering, never assume the callback runs on the Android main thread,
|
||||
and marshal UI/Activity work onto Main. Keep storage decisions in Rust and avoid
|
||||
blocking the main thread or calling back into a held Rust lock.
|
||||
|
||||
JNA 5.19.1 is packaged as its Android AAR, filtered to arm64-v8a, armeabi-v7a and
|
||||
x86_64. The release set may only be narrowed by changing the support decision in
|
||||
#88, not by silently omitting an ABI. All source/lock/config files are task inputs;
|
||||
outputs live only under build/. Debug and release compile independently, and
|
||||
unchanged builds reuse their outputs. R8 keeps generated/JNA reflection entry
|
||||
points. AGP strips release libraries and exports FULL native symbols to
|
||||
app/build/outputs/native-debug-symbols/release/native-debug-symbols.zip; retain
|
||||
that file and outputs/mapping/release/mapping.txt with the matching release.
|
||||
AAB base/lib entries let Play produce per-ABI splits.
|
||||
|
||||
The auditNativePackages gate inspects every native dependency in both APKs and
|
||||
the AAB, checks all three ABI directories and both Rust/JNA libraries, and rejects
|
||||
ELF segments below 16 KB alignment or APK native entries that are compressed or
|
||||
not ZIP-aligned to 16 KB. Follow the official [16 KB runtime validation](https://developer.android.com/guide/practices/page-sizes):
|
||||
use an actual 16 KB system image, check adb shell getconf PAGE_SIZE is 16384,
|
||||
disable page-size compatibility mode, and run both instrumented test suites.
|
||||
An ELF/ZIP audit is not a substitute for that runtime test. Milestone validation
|
||||
is emulator-only per the user instruction of 2026-10-08; physical devices are
|
||||
outside the test scope for every issue. Keep x86_64 emulator evidence separate
|
||||
from the Apple Silicon arm64 emulator run.
|
||||
|
||||
Validation recorded on 2026-10-08 for #92:
|
||||
|
||||
| Environment | Verified |
|
||||
| --- | --- |
|
||||
| API 37 arm64 emulator, 4 KB | Generated API fixture/error/redaction tests; 25 UI states; release APK and AAB split launch; update-state preservation |
|
||||
| API 37 arm64 emulator, 16 KB, compatibility disabled | Same native/UI tests, release APK/AAB launch and update-state preservation |
|
||||
| Fresh source export | Three ABI debug builds with pinned tools, locked dependencies and strict artifact verification |
|
||||
| All three ABI release outputs | ELF alignment and identical UniFFI metadata; stripped APK libraries and separate FULL Rust symbols; nine bundletool ABI split APKs audited |
|
||||
| Physical devices | Excluded from milestone testing by user instruction |
|
||||
| x86_64 runtime | System image installed; QEMU2 rejects x86_64 on this aarch64 Mac, including with acceleration disabled |
|
||||
|
||||
The outstanding x86_64 emulator check needs a compatible host; cross-compilation
|
||||
and static package checks do not establish x86_64 runtime coverage.
|
||||
+18
-15
@@ -6,8 +6,10 @@ androidx.activity:activity-compose:1.13.0=debugAndroidTestCompileClasspath,debug
|
||||
androidx.activity:activity-ktx:1.13.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.activity:activity:1.13.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.annotation:annotation-experimental:1.5.1=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.annotation:annotation-jvm:1.9.1=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.annotation:annotation:1.9.1=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.annotation:annotation-jvm:1.11.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.annotation:annotation-jvm:1.9.1=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath
|
||||
androidx.annotation:annotation:1.11.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.annotation:annotation:1.9.1=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath
|
||||
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.autofill:autofill:1.0.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
@@ -208,6 +210,7 @@ jakarta.xml.bind:jakarta.xml.bind-api:2.3.2=androidLintTool
|
||||
javax.inject:javax.inject:1=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,androidLintTool,debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,hiltAnnotationProcessorDebug,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,hiltAnnotationProcessorRelease,kspDebugKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,releaseCompileClasspath,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,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
net.java.dev.jna:jna:5.6.0=androidLintTool
|
||||
net.ltgt.gradle.incap:incap:0.2=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,hiltAnnotationProcessorDebug,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,hiltAnnotationProcessorRelease,kspDebugKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath
|
||||
net.sf.kxml:kxml2:2.3.0=androidLintTool
|
||||
@@ -228,31 +231,31 @@ 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.20=composeMappingProducerClasspath
|
||||
org.jetbrains.kotlin:compose-group-mapping:2.4.21=composeMappingProducerClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-api:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-api:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-compat:2.4.20=kotlinAbiValidationCompatClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
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
|
||||
org.jetbrains.kotlin:kotlin-build-tools-cri-impl:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-cri-impl:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-cri-impl:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-impl:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-impl:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-impl:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.2.0=ktlint,ktlintBaselineReporter,ktlintRuleset
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-runner:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-runner:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compose-compiler-plugin-embeddable:2.4.20=kotlin-extension,kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugAndroidTest,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathRelease
|
||||
org.jetbrains.kotlin:kotlin-compiler-runner:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compose-compiler-plugin-embeddable:2.4.21=kotlin-extension,kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugAndroidTest,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathRelease
|
||||
org.jetbrains.kotlin:kotlin-daemon-client:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-client:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-client:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.2.0=ktlint,ktlintBaselineReporter,ktlintRuleset
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-metadata-jvm:2.3.21=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,hiltAnnotationProcessorDebug,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,hiltAnnotationProcessorRelease,kspDebugKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath
|
||||
org.jetbrains.kotlin:kotlin-reflect:1.6.10=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,hiltAnnotationProcessorDebug,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,hiltAnnotationProcessorRelease,kotlinAbiValidationCompatClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kspDebugKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,ktlint,ktlintBaselineReporter,ktlintRuleset
|
||||
org.jetbrains.kotlin:kotlin-reflect:2.2.10=androidLintTool
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:2.2.0=ktlint,ktlintBaselineReporter,ktlintRuleset
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib-common:2.2.0=ktlintReporter
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,hiltAnnotationProcessorDebug,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,hiltAnnotationProcessorRelease,kspDebugKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,ktlintReporter
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:2.2.10=androidLintTool,unified-test-platform-gradle-work-action
|
||||
@@ -264,8 +267,8 @@ org.jetbrains.kotlin:kotlin-stdlib:2.2.21=composeMappingProducerClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.3.20=kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugAndroidTest,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathRelease,kspPluginClasspath,kspPluginClasspathNonEmbeddable
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.3.21=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,hiltAnnotationProcessorDebug,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,hiltAnnotationProcessorRelease,kspDebugKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.4.20=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-tooling-core:2.4.20=kotlinAbiValidationCompatClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
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:kotlinx-coroutines-android:1.11.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.11.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.9.0=androidLintTool,unified-test-platform-gradle-work-action
|
||||
|
||||
@@ -25,6 +25,10 @@ class ShellScreenTest {
|
||||
hasText(tab.name) and androidx.compose.ui.test.isSelectable()
|
||||
).performClick()
|
||||
val page = ShellFixtures.all.getValue(state).first { it.tab == tab }
|
||||
compose.waitUntil(timeoutMillis = 10_000) {
|
||||
compose.onAllNodes(hasText(page.stateTitle) and isHeading())
|
||||
.fetchSemanticsNodes().size == 1
|
||||
}
|
||||
compose.onNode(hasText(page.stateTitle) and isHeading()).assertIsDisplayed()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
package de.rfc1437.ironstorage
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import de.rfc1437.ironstorage.core.ShellFixtures
|
||||
import de.rfc1437.ironstorage.core.ShellRepository
|
||||
import de.rfc1437.ironstorage.core.ShellSnapshot
|
||||
import de.rfc1437.ironstorage.core.ShellState
|
||||
import de.rfc1437.ironstorage.core.ShellTab
|
||||
import javax.inject.Singleton
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
class DebugShellRepository : ShellRepository {
|
||||
private val mutableSnapshot =
|
||||
MutableStateFlow(
|
||||
ShellSnapshot(ShellState.Empty, ShellFixtures.all.getValue(ShellState.Empty))
|
||||
)
|
||||
override val snapshot: StateFlow<ShellSnapshot> = mutableSnapshot
|
||||
|
||||
override fun selectTab(tab: ShellTab) {
|
||||
mutableSnapshot.value = mutableSnapshot.value.copy(selectedTab = tab)
|
||||
}
|
||||
|
||||
fun showFixture(state: ShellState) {
|
||||
mutableSnapshot.value =
|
||||
mutableSnapshot.value.copy(state = state, pages = ShellFixtures.all.getValue(state))
|
||||
}
|
||||
}
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
object DebugShellModule {
|
||||
@Provides
|
||||
@Singleton
|
||||
fun shellRepository(): ShellRepository = DebugShellRepository()
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import de.rfc1437.ironstorage.core.NativeFixtureShellRepository
|
||||
import de.rfc1437.ironstorage.core.ShellRepository
|
||||
import de.rfc1437.ironstorage.core.ShellState
|
||||
import de.rfc1437.ironstorage.features.ShellScreen
|
||||
@@ -19,7 +20,9 @@ fun VariantContent(viewModel: ShellViewModel, repository: ShellRepository) {
|
||||
Column(Modifier.statusBarsPadding()) {
|
||||
Row(Modifier.horizontalScroll(rememberScrollState())) {
|
||||
ShellState.entries.forEach { state ->
|
||||
TextButton(onClick = { (repository as DebugShellRepository).showFixture(state) }) {
|
||||
TextButton(onClick = {
|
||||
(repository as NativeFixtureShellRepository).showFixture(state)
|
||||
}) {
|
||||
Text("Fixture: ${state.name}")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package de.rfc1437.ironstorage
|
||||
|
||||
import android.content.Context
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import de.rfc1437.ironstorage.core.NativeFixtureShellRepository
|
||||
import de.rfc1437.ironstorage.core.ShellRepository
|
||||
import javax.inject.Singleton
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
object ShellModule {
|
||||
@Provides
|
||||
@Singleton
|
||||
fun shellRepository(@ApplicationContext context: Context): ShellRepository =
|
||||
NativeFixtureShellRepository(
|
||||
context,
|
||||
CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
|
||||
)
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package de.rfc1437.ironstorage
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import de.rfc1437.ironstorage.core.ShellRepository
|
||||
import de.rfc1437.ironstorage.core.ShellSnapshot
|
||||
import de.rfc1437.ironstorage.core.ShellState
|
||||
import de.rfc1437.ironstorage.core.ShellTab
|
||||
import javax.inject.Singleton
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
class ScaffoldShellRepository : ShellRepository {
|
||||
private val mutableSnapshot = MutableStateFlow(ShellSnapshot(ShellState.Empty, emptyList()))
|
||||
override val snapshot: StateFlow<ShellSnapshot> = mutableSnapshot
|
||||
|
||||
override fun selectTab(tab: ShellTab) {
|
||||
mutableSnapshot.value = mutableSnapshot.value.copy(selectedTab = tab)
|
||||
}
|
||||
}
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
object ReleaseShellModule {
|
||||
@Provides
|
||||
@Singleton
|
||||
fun shellRepository(): ShellRepository = ScaffoldShellRepository()
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package de.rfc1437.ironstorage
|
||||
|
||||
import de.rfc1437.ironstorage.core.ShellFixtures
|
||||
import de.rfc1437.ironstorage.core.ShellState
|
||||
import de.rfc1437.ironstorage.core.ShellTab
|
||||
import org.junit.Assert.assertEquals
|
||||
@@ -7,14 +8,12 @@ import org.junit.Test
|
||||
|
||||
class DebugShellRepositoryTest {
|
||||
@Test
|
||||
fun everyFixtureHasFivePagesAndSelectionSurvivesStateChanges() {
|
||||
val repository = DebugShellRepository()
|
||||
repository.selectTab(ShellTab.Totp)
|
||||
fun fixtureInventorySupportsEveryNativeTab() {
|
||||
val selected = ShellTab.Totp
|
||||
ShellState.entries.forEach { state ->
|
||||
repository.showFixture(state)
|
||||
assertEquals(state, repository.snapshot.value.state)
|
||||
assertEquals(ShellTab.entries, repository.snapshot.value.pages.map { it.tab })
|
||||
assertEquals(ShellTab.Totp, repository.snapshot.value.selectedTab)
|
||||
val pages = ShellFixtures.all.getValue(state)
|
||||
assertEquals(ShellTab.entries, pages.map { it.tab })
|
||||
assertEquals(selected, pages.first { it.tab == selected }.tab)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,3 +62,20 @@ val checkArchitecture = tasks.register<Exec>("checkArchitecture") {
|
||||
subprojects {
|
||||
tasks.matching { it.name == "preBuild" || it.name == "check" }.configureEach { dependsOn(rootProject.tasks.named("checkArchitecture")) }
|
||||
}
|
||||
|
||||
tasks.register<Exec>("auditNativePackages") {
|
||||
dependsOn(":app:assembleDebug", ":app:assembleRelease", ":app:bundleRelease")
|
||||
workingDir = workspace
|
||||
val packages = listOf(
|
||||
layout.projectDirectory.file("app/build/outputs/apk/debug/app-debug.apk"),
|
||||
layout.projectDirectory.file("app/build/outputs/apk/release/app-release-unsigned.apk"),
|
||||
layout.projectDirectory.file("app/build/outputs/bundle/release/app-release.aab")
|
||||
)
|
||||
inputs.files(packages)
|
||||
commandLine(
|
||||
listOf(
|
||||
cargoExecutable.get(), "+${libs.versions.rust.get()}", "run", "--locked",
|
||||
"--package", "ironstorage-android-build", "--", "audit-package"
|
||||
) + packages.map { it.asFile.absolutePath }
|
||||
)
|
||||
}
|
||||
@@ -2,6 +2,8 @@
|
||||
# Manual edits can break the build and are not advised.
|
||||
# This file is expected to be part of source control.
|
||||
# To regenerate this file, run: ./gradlew :core:dependencies --write-locks
|
||||
androidx.annotation:annotation-jvm:1.11.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.annotation:annotation:1.11.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
ch.qos.logback:logback-classic:1.3.15=ktlint
|
||||
ch.qos.logback:logback-core:1.3.15=ktlint
|
||||
com.android.tools.analytics-library:protos:32.4.1=androidLintTool
|
||||
@@ -75,6 +77,7 @@ jakarta.xml.bind:jakarta.xml.bind-api:2.3.2=androidLintTool
|
||||
javax.inject:javax.inject:1=androidLintTool
|
||||
junit:junit:4.13.2=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
|
||||
net.java.dev.jna:jna:5.6.0=androidLintTool
|
||||
net.sf.kxml:kxml2:2.3.0=androidLintTool
|
||||
org.apache.commons:commons-compress:1.27.1=androidLintTool
|
||||
@@ -93,27 +96,27 @@ org.glassfish.jaxb:jaxb-runtime:2.3.2=androidLintTool
|
||||
org.glassfish.jaxb:txw2:2.3.2=androidLintTool
|
||||
org.hamcrest:hamcrest-core:1.3=debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-api:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-api:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-compat:2.4.20=kotlinAbiValidationCompatClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
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
|
||||
org.jetbrains.kotlin:kotlin-build-tools-cri-impl:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-cri-impl:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-cri-impl:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-impl:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-impl:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-impl:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.2.0=ktlint,ktlintBaselineReporter,ktlintRuleset
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-runner:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-runner:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-runner:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-client:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-client:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-client:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.2.0=ktlint,ktlintBaselineReporter,ktlintRuleset
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-reflect:1.6.10=kotlinAbiValidationCompatClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,ktlint,ktlintBaselineReporter,ktlintRuleset
|
||||
org.jetbrains.kotlin:kotlin-reflect:2.2.10=androidLintTool
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:2.2.0=ktlint,ktlintBaselineReporter,ktlintRuleset
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib-common:2.2.0=ktlintReporter
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0=ktlintReporter
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:2.2.10=androidLintTool,unified-test-platform-gradle-work-action
|
||||
@@ -122,8 +125,8 @@ org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.2.10=androidLintTool,unified-test-plat
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.2.0=ktlint,ktlintBaselineReporter,ktlintReporter,ktlintRuleset
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.2.10=androidLintTool,unified-test-platform-gradle-work-action
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.4.20=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-tooling-core:2.4.20=kotlinAbiValidationCompatClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
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:kotlinx-coroutines-android:1.11.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.11.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.9.0=androidLintTool,unified-test-platform-gradle-work-action
|
||||
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
package de.rfc1437.ironstorage.core
|
||||
|
||||
import android.content.Context
|
||||
import de.rfc1437.ironstorage.bridge.NativeBridgeException
|
||||
import de.rfc1437.ironstorage.bridge.NativeFailureKind
|
||||
import de.rfc1437.ironstorage.bridge.NativeRuntime
|
||||
import de.rfc1437.ironstorage.bridge.generated.MobileShellState
|
||||
import de.rfc1437.ironstorage.bridge.generated.MobileTab
|
||||
import java.util.concurrent.atomic.AtomicLong
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
/** #92's native fixture integration; repository initialization is owned by #90. */
|
||||
class NativeFixtureShellRepository internal constructor(
|
||||
private val scope: CoroutineScope,
|
||||
private val load: suspend (ShellState) -> ShellSnapshot
|
||||
) : ShellRepository {
|
||||
constructor(context: Context, scope: CoroutineScope) : this(scope, nativeLoader(context))
|
||||
private val mutableSnapshot = MutableStateFlow(ShellSnapshot(ShellState.Loading, emptyList()))
|
||||
override val snapshot: StateFlow<ShellSnapshot> = mutableSnapshot
|
||||
private val revision = AtomicLong()
|
||||
private var job: Job? = null
|
||||
|
||||
init {
|
||||
showFixture(ShellState.Empty)
|
||||
}
|
||||
|
||||
override fun selectTab(tab: ShellTab) {
|
||||
mutableSnapshot.update { it.copy(selectedTab = tab) }
|
||||
}
|
||||
|
||||
fun showFixture(state: ShellState) {
|
||||
val operation = revision.incrementAndGet()
|
||||
job?.cancel()
|
||||
job = scope.launch {
|
||||
val result = try {
|
||||
load(state)
|
||||
} catch (error: NativeBridgeException) {
|
||||
ShellSnapshot(ShellState.Error, emptyList(), nativeFailure = error.kind.toFacade())
|
||||
}
|
||||
if (revision.get() == operation) {
|
||||
mutableSnapshot.update { result.copy(selectedTab = it.selectedTab) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun nativeLoader(context: Context): suspend (ShellState) -> ShellSnapshot {
|
||||
val runtime = NativeRuntime(context)
|
||||
return { state ->
|
||||
withContext(Dispatchers.IO) {
|
||||
val shell = runtime.fixture(state.toNative())
|
||||
val pages = shell.pages.map { page ->
|
||||
ShellPage(page.tab.toFacade(), page.title, page.stateTitle, page.stateDetail)
|
||||
}
|
||||
val actual = shell.pages.firstOrNull()?.state
|
||||
?: throw NativeBridgeException(NativeFailureKind.RustFailure)
|
||||
ShellSnapshot(actual.toFacade(), pages)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun MobileShellState.toFacade(): ShellState = when (this) {
|
||||
MobileShellState.LOADING -> ShellState.Loading
|
||||
MobileShellState.EMPTY -> ShellState.Empty
|
||||
MobileShellState.READY -> ShellState.Ready
|
||||
MobileShellState.LOCKED -> ShellState.Locked
|
||||
MobileShellState.ERROR -> ShellState.Error
|
||||
}
|
||||
|
||||
private fun ShellState.toNative(): MobileShellState = when (this) {
|
||||
ShellState.Loading -> MobileShellState.LOADING
|
||||
ShellState.Empty -> MobileShellState.EMPTY
|
||||
ShellState.Ready -> MobileShellState.READY
|
||||
ShellState.Locked -> MobileShellState.LOCKED
|
||||
ShellState.Error -> MobileShellState.ERROR
|
||||
}
|
||||
|
||||
private fun MobileTab.toFacade(): ShellTab = when (this) {
|
||||
MobileTab.HOME -> ShellTab.Home
|
||||
MobileTab.PASSWORDS -> ShellTab.Passwords
|
||||
MobileTab.SEARCH -> ShellTab.Search
|
||||
MobileTab.TOTP -> ShellTab.Totp
|
||||
MobileTab.PREFERENCES -> ShellTab.Preferences
|
||||
}
|
||||
|
||||
private fun NativeFailureKind.toFacade(): NativeFailure = when (this) {
|
||||
NativeFailureKind.UnsupportedAbi -> NativeFailure.UnsupportedAbi
|
||||
NativeFailureKind.MissingLibrary -> NativeFailure.MissingLibrary
|
||||
NativeFailureKind.ContractMismatch -> NativeFailure.ContractMismatch
|
||||
NativeFailureKind.ChecksumMismatch -> NativeFailure.ChecksumMismatch
|
||||
NativeFailureKind.LoadFailure -> NativeFailure.LoadFailure
|
||||
NativeFailureKind.RustFailure -> NativeFailure.RustFailure
|
||||
NativeFailureKind.MainThreadCall -> NativeFailure.MainThreadCall
|
||||
}
|
||||
@@ -14,9 +14,20 @@ data class ShellPage(
|
||||
data class ShellSnapshot(
|
||||
val state: ShellState,
|
||||
val pages: List<ShellPage>,
|
||||
val selectedTab: ShellTab = ShellTab.Home
|
||||
val selectedTab: ShellTab = ShellTab.Home,
|
||||
val nativeFailure: NativeFailure? = null
|
||||
)
|
||||
|
||||
enum class NativeFailure {
|
||||
UnsupportedAbi,
|
||||
MissingLibrary,
|
||||
ContractMismatch,
|
||||
ChecksumMismatch,
|
||||
LoadFailure,
|
||||
RustFailure,
|
||||
MainThreadCall
|
||||
}
|
||||
|
||||
interface ShellRepository {
|
||||
val snapshot: StateFlow<ShellSnapshot>
|
||||
fun selectTab(tab: ShellTab)
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package de.rfc1437.ironstorage.core
|
||||
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import kotlinx.coroutines.NonCancellable
|
||||
import kotlinx.coroutines.test.runCurrent
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
|
||||
class NativeFixtureShellRepositoryTest {
|
||||
@Test
|
||||
fun cancelledNativeCompletionCannotReplaceNewerStateOrTabSelection() = runTest {
|
||||
val pending = CompletableDeferred<Unit>()
|
||||
val repository = NativeFixtureShellRepository(backgroundScope) { state ->
|
||||
if (state == ShellState.Ready) withContext(NonCancellable) { pending.await() }
|
||||
ShellSnapshot(state, listOf(ShellPage(ShellTab.Home, "Home", state.name, "Fixture")))
|
||||
}
|
||||
runCurrent()
|
||||
repository.showFixture(ShellState.Ready)
|
||||
runCurrent()
|
||||
repository.selectTab(ShellTab.Search)
|
||||
repository.showFixture(ShellState.Locked)
|
||||
runCurrent()
|
||||
pending.complete(Unit)
|
||||
runCurrent()
|
||||
assertEquals(ShellState.Locked, repository.snapshot.value.state)
|
||||
assertEquals(ShellTab.Search, repository.snapshot.value.selectedTab)
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,10 @@ androidx.activity:activity-compose:1.12.0=debugAndroidTestCompileClasspath,debug
|
||||
androidx.activity:activity-ktx:1.12.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.activity:activity:1.12.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.annotation:annotation-experimental:1.5.1=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.annotation:annotation-jvm:1.9.1=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.annotation:annotation:1.9.1=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.annotation:annotation-jvm:1.11.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.annotation:annotation-jvm:1.9.1=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath
|
||||
androidx.annotation:annotation:1.11.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.annotation:annotation:1.9.1=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath
|
||||
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.autofill:autofill:1.0.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
@@ -192,6 +194,7 @@ jakarta.xml.bind:jakarta.xml.bind-api:2.3.2=androidLintTool
|
||||
javax.inject:javax.inject:1=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,androidLintTool,debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,kspDebugKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
junit:junit:4.13.2=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
|
||||
net.java.dev.jna:jna:5.6.0=androidLintTool
|
||||
net.ltgt.gradle.incap:incap:0.2=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,kspDebugKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath
|
||||
net.sf.kxml:kxml2:2.3.0=androidLintTool
|
||||
@@ -212,29 +215,29 @@ org.glassfish.jaxb:jaxb-runtime:2.3.2=androidLintTool
|
||||
org.glassfish.jaxb:txw2:2.3.2=androidLintTool
|
||||
org.hamcrest:hamcrest-core:1.3=debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-api:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-api:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-compat:2.4.20=kotlinAbiValidationCompatClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
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
|
||||
org.jetbrains.kotlin:kotlin-build-tools-cri-impl:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-cri-impl:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-cri-impl:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-impl:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-impl:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-impl:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.2.0=ktlint,ktlintBaselineReporter,ktlintRuleset
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-runner:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-runner:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compose-compiler-plugin-embeddable:2.4.20=kotlin-extension,kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugAndroidTest,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathRelease
|
||||
org.jetbrains.kotlin:kotlin-compiler-runner:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compose-compiler-plugin-embeddable:2.4.21=kotlin-extension,kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugAndroidTest,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathRelease
|
||||
org.jetbrains.kotlin:kotlin-daemon-client:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-client:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-client:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.2.0=ktlint,ktlintBaselineReporter,ktlintRuleset
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-metadata-jvm:2.3.21=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,kspDebugKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath
|
||||
org.jetbrains.kotlin:kotlin-reflect:1.6.10=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,kotlinAbiValidationCompatClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kspDebugKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,ktlint,ktlintBaselineReporter,ktlintRuleset
|
||||
org.jetbrains.kotlin:kotlin-reflect:2.2.10=androidLintTool
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:2.2.0=ktlint,ktlintBaselineReporter,ktlintRuleset
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib-common:2.2.0=ktlintReporter
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,kspDebugKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,ktlintReporter
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:2.2.10=androidLintTool,unified-test-platform-gradle-work-action
|
||||
@@ -245,8 +248,8 @@ org.jetbrains.kotlin:kotlin-stdlib:2.2.10=androidLintTool,unified-test-platform-
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.3.20=kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugAndroidTest,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathRelease,kspPluginClasspath,kspPluginClasspathNonEmbeddable
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.3.21=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,kspDebugKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.4.20=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-tooling-core:2.4.20=kotlinAbiValidationCompatClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
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:kotlinx-coroutines-android:1.11.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.11.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.9.0=androidLintTool,unified-test-platform-gradle-work-action
|
||||
|
||||
@@ -18,6 +18,7 @@ import androidx.compose.ui.semantics.heading
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import de.rfc1437.ironstorage.core.NativeFailure
|
||||
import de.rfc1437.ironstorage.core.ShellState
|
||||
import de.rfc1437.ironstorage.core.ShellTab
|
||||
|
||||
@@ -44,12 +45,33 @@ fun ShellScreen(viewModel: ShellViewModel) {
|
||||
) {
|
||||
Text(stringResource(R.string.app_name), style = MaterialTheme.typography.headlineLarge)
|
||||
val page = snapshot.pages.firstOrNull { it.tab == snapshot.selectedTab }
|
||||
val nativeFailure = snapshot.nativeFailure
|
||||
val title = if (nativeFailure != null) {
|
||||
stringResource(R.string.native_failure_title)
|
||||
} else {
|
||||
page?.stateTitle ?: stringResource(R.string.scaffold_title)
|
||||
}
|
||||
val detail = if (nativeFailure == null) {
|
||||
page?.detail ?: stringResource(R.string.scaffold_detail)
|
||||
} else {
|
||||
stringResource(
|
||||
when (nativeFailure) {
|
||||
NativeFailure.UnsupportedAbi -> R.string.native_unsupported_device
|
||||
NativeFailure.MissingLibrary,
|
||||
NativeFailure.ContractMismatch,
|
||||
NativeFailure.ChecksumMismatch,
|
||||
NativeFailure.LoadFailure -> R.string.native_update_required
|
||||
NativeFailure.RustFailure,
|
||||
NativeFailure.MainThreadCall -> R.string.native_operation_failed
|
||||
}
|
||||
)
|
||||
}
|
||||
Text(
|
||||
page?.stateTitle ?: stringResource(R.string.scaffold_title),
|
||||
title,
|
||||
modifier = Modifier.semantics { heading() },
|
||||
style = MaterialTheme.typography.headlineSmall
|
||||
)
|
||||
Text(page?.detail ?: stringResource(R.string.scaffold_detail))
|
||||
Text(detail)
|
||||
if (snapshot.state == ShellState.Loading) CircularProgressIndicator()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,8 @@
|
||||
<string name="app_name">IronStorage</string>
|
||||
<string name="scaffold_title">No Password Store</string>
|
||||
<string name="scaffold_detail">Your password store has not been configured.</string>
|
||||
<string name="native_failure_title">IronStorage Is Unavailable</string>
|
||||
<string name="native_unsupported_device">This device is not supported by this app build.</string>
|
||||
<string name="native_update_required">The installed app components could not be loaded or do not match. Install a complete update without clearing app data.</string>
|
||||
<string name="native_operation_failed">The app could not complete this operation. Try again.</string>
|
||||
</resources>
|
||||
@@ -1,6 +1,6 @@
|
||||
[versions]
|
||||
agp = "9.4.1"
|
||||
kotlin = "2.4.20"
|
||||
kotlin = "2.4.21"
|
||||
ksp = "2.3.12"
|
||||
hilt = "2.60.1"
|
||||
compose = "2026.09.00"
|
||||
@@ -17,6 +17,10 @@ ktlint = "1.7.1"
|
||||
compileSdk = "37"
|
||||
minSdk = "26"
|
||||
ndk = "30.0.16248370"
|
||||
rust = "1.97.1"
|
||||
cargoNdk = "4.1.2"
|
||||
jna = "5.19.1"
|
||||
annotation = "1.11.0"
|
||||
|
||||
[libraries]
|
||||
compose-bom = { module = "androidx.compose:compose-bom", version.ref = "compose" }
|
||||
@@ -37,6 +41,8 @@ hilt-compiler = { module = "com.google.dagger:hilt-compiler", version.ref = "hil
|
||||
junit = { module = "junit:junit", version.ref = "junit" }
|
||||
android-test-runner = { module = "androidx.test:runner", version.ref = "androidTest" }
|
||||
android-test-espresso = { module = "androidx.test.espresso:espresso-core", version.ref = "espresso" }
|
||||
jna = { module = "net.java.dev.jna:jna", version.ref = "jna" }
|
||||
annotation = { module = "androidx.annotation:annotation", version.ref = "annotation" }
|
||||
|
||||
[plugins]
|
||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||
|
||||
@@ -63,6 +63,11 @@
|
||||
<sha256 value="f4001a709b6f7132b22a5e17c24f8b8a9b3c462a598de3b0f16cc57a4344bab6" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.annotation" name="annotation" version="1.11.0">
|
||||
<artifact name="annotation-1.11.0.module">
|
||||
<sha256 value="ac8410bea7adaabc9e71285f0627c9cb929c5addd00cfc6d0ebd421dc2da1ee0" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.annotation" name="annotation" version="1.7.0">
|
||||
<artifact name="annotation-1.7.0.module">
|
||||
<sha256 value="530708656d380605077ea8bca9ae1372fbd1af38e375f411d4e43263bd510c3c" origin="Generated by Gradle"/>
|
||||
@@ -91,6 +96,22 @@
|
||||
<sha256 value="ae1ff29a7f3965e6589acfe7f07ef39d36405d7ab278472327afd92fc6d72a3f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.annotation" name="annotation-jvm" version="1.11.0">
|
||||
<artifact name="annotation-jvm-1.11.0.jar">
|
||||
<sha256 value="a83b827cc17fd6b41c7bf5e7a2a2b40a0895b00b3e30fdfdb820b49dc7b667f3" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="annotation-jvm-1.11.0.module">
|
||||
<sha256 value="0c8a86f2a8e20120cc13544f101047f42284de1f1dd7ca26c90056901de4c2da" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.annotation" name="annotation-jvm" version="1.7.0">
|
||||
<artifact name="annotation-jvm-1.7.0.jar">
|
||||
<sha256 value="e36b8e4b8393a4adc74e3d4ab22ad5a36396f0cea2e40b5734eae14937dfd224" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="annotation-jvm-1.7.0.module">
|
||||
<sha256 value="07ce60c377ab94e47c8c902589b9776030064fd1a7e4d5a01a38d700e35e5db4" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.annotation" name="annotation-jvm" version="1.9.1">
|
||||
<artifact name="annotation-jvm-1.9.1.jar">
|
||||
<sha256 value="1e343917ebf27ba96fe4dc52b1cad7fd32b738fbc6355bb6cd5b3b305d7212d0" origin="Generated by Gradle"/>
|
||||
@@ -2180,6 +2201,14 @@
|
||||
<sha256 value="569b6977ee4603c965c1c46c3058fa6e969291b0160eb6964dd092cd89eadd94" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="net.java.dev.jna" name="jna" version="5.19.1">
|
||||
<artifact name="jna-5.19.1.aar">
|
||||
<sha256 value="b57125cb7d16253f0d65a80f7d3a4c3664effa711b8bdbb7f87fb572ce1624ed" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="jna-5.19.1.pom">
|
||||
<sha256 value="911b754a03b66af0fed2bbdfdc3a86807360dd036ad3b481ef5162c685e456bf" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="net.java.dev.jna" name="jna" version="5.6.0">
|
||||
<artifact name="jna-5.6.0.jar">
|
||||
<sha256 value="5557e235a8aa2f9766d5dc609d67948f2a8832c2d796cea9ef1d6cbe0b3b7eaf" origin="Generated by Gradle"/>
|
||||
@@ -2522,6 +2551,14 @@
|
||||
<sha256 value="6e3d3c8d2a375393d64395882ac80c9c3a44e90008801a34fd99a13cbcc96bfd" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="compose-compiler-gradle-plugin" version="2.4.21">
|
||||
<artifact name="compose-compiler-gradle-plugin-2.4.21-gradle96.jar">
|
||||
<sha256 value="17b7d35e53e23f4820e0fb9f3ad71f7ab463970d68bcd8ba7f8d71498b50395f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="compose-compiler-gradle-plugin-2.4.21.module">
|
||||
<sha256 value="e7bc61dabd4381f4a8f53c7be30bfb5cccd971af27d55b7c39b0a37b28bef24d" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="compose-group-mapping" version="2.4.20">
|
||||
<artifact name="compose-group-mapping-2.4.20.jar">
|
||||
<sha256 value="0205146299c4c02e19b62620e5a0276aaecc3ecd7711cf274e86e36e6a73f4ca" origin="Generated by Gradle"/>
|
||||
@@ -2530,6 +2567,14 @@
|
||||
<sha256 value="2fba7c50bc1933a70f6ed6d8d3b574a8e97d86912c28caa96fe7ce648a87eb48" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="compose-group-mapping" version="2.4.21">
|
||||
<artifact name="compose-group-mapping-2.4.21.jar">
|
||||
<sha256 value="45bb5caf737fb50cf96fd67f4a45aff8a75cae387333a5be80ad29523442d327" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="compose-group-mapping-2.4.21.pom">
|
||||
<sha256 value="a1c461dc79493649a9d1eee167c172dd32aa3260a48735751de30ee169cf4620" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="fus-statistics-gradle-plugin" version="2.4.20">
|
||||
<artifact name="fus-statistics-gradle-plugin-2.4.20-gradle96.jar">
|
||||
<sha256 value="0c050825d65654d0ac8f6ba9409fba824f87100df00e76300242abfe9a1b989f" origin="Generated by Gradle"/>
|
||||
@@ -2538,6 +2583,14 @@
|
||||
<sha256 value="cfe6fb1af3f7da01428ef4bf4e38e1c76637f4e108ac22f15dfe4c733df408d4" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="fus-statistics-gradle-plugin" version="2.4.21">
|
||||
<artifact name="fus-statistics-gradle-plugin-2.4.21-gradle96.jar">
|
||||
<sha256 value="44a07b9203eb2c75ceb2d33327f89b991f2d35095a96a0f1c224a012c5465367" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="fus-statistics-gradle-plugin-2.4.21.module">
|
||||
<sha256 value="3090b4e873054cdc29991ae94c92fa45afb4c145d460441d803baf6ef165bbb8" 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"/>
|
||||
@@ -2551,6 +2604,14 @@
|
||||
<sha256 value="184af9ac1aaf68d0c96875465e9d398926586d83119abbfe1be5979398b8916f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-build-statistics" version="2.4.21">
|
||||
<artifact name="kotlin-build-statistics-2.4.21.jar">
|
||||
<sha256 value="f917249997fe48d1eb1204906b4cabc8230bf32a1d9fb385e52311acaa6ebc68" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="kotlin-build-statistics-2.4.21.pom">
|
||||
<sha256 value="4ac9fe3a27069f9ad87dc36ede15fc06335663d4ae46fac09a16bb090e16038c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-build-tools-api" version="2.4.0">
|
||||
<artifact name="kotlin-build-tools-api-2.4.0.jar">
|
||||
<sha256 value="66917335497f9ab75a36c34b3d90bad2bc8dc256c34b2413ecd0c9467fcf597d" origin="Generated by Gradle"/>
|
||||
@@ -2567,6 +2628,14 @@
|
||||
<sha256 value="e8cd9ffd7d0886ba1a1795cbf4a34a06681f184aa50f25686effeefb3c1f56f5" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-build-tools-api" version="2.4.21">
|
||||
<artifact name="kotlin-build-tools-api-2.4.21.jar">
|
||||
<sha256 value="c5cd6a49bd072b529ae10809111c16a7aa0f92147e95d288354017fd65799461" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="kotlin-build-tools-api-2.4.21.pom">
|
||||
<sha256 value="4b909e42d55242520278d5397eca1edd58921fe128942eeff95a6da279c2eb27" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-build-tools-compat" version="2.4.20">
|
||||
<artifact name="kotlin-build-tools-compat-2.4.20.jar">
|
||||
<sha256 value="937d2961fc0b957a50c3d85a14fcc1bd0585f2229164136895b623691660c9b4" origin="Generated by Gradle"/>
|
||||
@@ -2575,6 +2644,14 @@
|
||||
<sha256 value="f8e9f647a00bfbc237e3ddff3891b2d4e4a947611b949281658f836def304002" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-build-tools-compat" version="2.4.21">
|
||||
<artifact name="kotlin-build-tools-compat-2.4.21.jar">
|
||||
<sha256 value="9e71ba89b6d26e46a087d4f8b64bc2f0a774282ea779fc08b26527d0a80d4fe8" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="kotlin-build-tools-compat-2.4.21.pom">
|
||||
<sha256 value="9d9b4627d5b7bb8631457061275f21524d874b865550addec4f3b029d8265817" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-build-tools-cri-impl" version="2.4.0">
|
||||
<artifact name="kotlin-build-tools-cri-impl-2.4.0.jar">
|
||||
<sha256 value="5168b866945f6ac1ffcb6d4c88cf582497249469c2e4a4eafc0bcd35b5a264a9" origin="Generated by Gradle"/>
|
||||
@@ -2591,6 +2668,14 @@
|
||||
<sha256 value="8af52efa886eed45c54d568b692e339b70ddc7c768bee9ab9c2d2f96ed8bb0e1" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-build-tools-cri-impl" version="2.4.21">
|
||||
<artifact name="kotlin-build-tools-cri-impl-2.4.21.jar">
|
||||
<sha256 value="d1849f9b98033f5333905409074ca90e6a0e17258cd0eb8befa47d795e695841" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="kotlin-build-tools-cri-impl-2.4.21.pom">
|
||||
<sha256 value="57f3c430dfec2e575bb1b64055412ace12d4ed5d9a02eb97a85dd47f53701ef1" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-build-tools-impl" version="2.4.0">
|
||||
<artifact name="kotlin-build-tools-impl-2.4.0.jar">
|
||||
<sha256 value="076c0a7f84d303f1e390774410c8678b8b584faa3f642435f93d2e4e81dabe7c" origin="Generated by Gradle"/>
|
||||
@@ -2607,6 +2692,14 @@
|
||||
<sha256 value="7a13ab2d818a5de92afa23004aa9baed99671bb48553b7098cf920fa785c3351" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-build-tools-impl" version="2.4.21">
|
||||
<artifact name="kotlin-build-tools-impl-2.4.21.jar">
|
||||
<sha256 value="3152b3e1fbaa4d48f3681734a2c0efc438359a48c8a3c5cac00d874670de1377" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="kotlin-build-tools-impl-2.4.21.pom">
|
||||
<sha256 value="6ef5cb90e2d8ea75faf9ec668d306b6be7628f11ebd41878a82cae3e17dbedfb" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-compiler-embeddable" version="2.2.0">
|
||||
<artifact name="kotlin-compiler-embeddable-2.2.0.jar">
|
||||
<sha256 value="b2f743ea5ba12f69e0f35e5d8d46069d74c8e2861087548a7e0e14a784bc4cf1" origin="Generated by Gradle"/>
|
||||
@@ -2631,6 +2724,14 @@
|
||||
<sha256 value="269d98cc4c68670c11e4aeb404e1c7c6f31b782321908d7268ba25cd236d59b2" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-compiler-embeddable" version="2.4.21">
|
||||
<artifact name="kotlin-compiler-embeddable-2.4.21.jar">
|
||||
<sha256 value="ef19419c765e7ac8404465fa026ca8fc4dbb8a822de0fc79aa53c8dce29f1d02" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="kotlin-compiler-embeddable-2.4.21.pom">
|
||||
<sha256 value="e1620d2b18319cf7495dc67697ab03ba23a7d6d9da685285884a7a8aa08ae891" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-compiler-runner" version="2.4.0">
|
||||
<artifact name="kotlin-compiler-runner-2.4.0.jar">
|
||||
<sha256 value="ad9608152740e92d94a278b4ff2ca82c4bf5ff8ef219220e3c07aeb554638cee" origin="Generated by Gradle"/>
|
||||
@@ -2647,6 +2748,14 @@
|
||||
<sha256 value="4566946280971fe8d67990ee83480af480e846590f325a40951f62657e26a40a" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-compiler-runner" version="2.4.21">
|
||||
<artifact name="kotlin-compiler-runner-2.4.21.jar">
|
||||
<sha256 value="75cd5956405697559e6925ebc5808449a2e12002d4f017275281ad3d4c0c7985" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="kotlin-compiler-runner-2.4.21.pom">
|
||||
<sha256 value="619d17c885321949eaa167af0842cad8f7aa83a4a9ca1051e5de04d11a6c0f40" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-compose-compiler-plugin-embeddable" version="2.4.20">
|
||||
<artifact name="kotlin-compose-compiler-plugin-embeddable-2.4.20.jar">
|
||||
<sha256 value="e6fc101fd0b8592911de57f96a75b09e0b6158eaccbc71ddd6ca82e05e0386a2" origin="Generated by Gradle"/>
|
||||
@@ -2655,6 +2764,14 @@
|
||||
<sha256 value="413bc7cb82d49d020e3fca2f6cb9e905954b5324a86bb941b9113dd83bd77673" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-compose-compiler-plugin-embeddable" version="2.4.21">
|
||||
<artifact name="kotlin-compose-compiler-plugin-embeddable-2.4.21.jar">
|
||||
<sha256 value="634f5c17bed5854548208f2901071f2ead5993ffad25b34fea1668ee9e314b53" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="kotlin-compose-compiler-plugin-embeddable-2.4.21.pom">
|
||||
<sha256 value="d5af6aa743ce0fa940b004a6cbd1777db0a76319e1daa1fded9b03c361aa03a3" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-daemon-client" version="2.4.0">
|
||||
<artifact name="kotlin-daemon-client-2.4.0.jar">
|
||||
<sha256 value="f546f0b3699c4984f320dd03080de05cad61064208ba8f37df0d3f8f4a7fd14a" origin="Generated by Gradle"/>
|
||||
@@ -2671,6 +2788,14 @@
|
||||
<sha256 value="37cff66ae34c924f0f738106eeb7234e7ace880f199de3362e993f4987025adc" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-daemon-client" version="2.4.21">
|
||||
<artifact name="kotlin-daemon-client-2.4.21.jar">
|
||||
<sha256 value="095903c4c4713bf91a562d226d7ba0464cf5424e76342d487deec494451ab29b" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="kotlin-daemon-client-2.4.21.pom">
|
||||
<sha256 value="c2f18065fa18f5e92eff14f34029e4f70052011070655120796adbce7167ad65" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-daemon-embeddable" version="2.2.0">
|
||||
<artifact name="kotlin-daemon-embeddable-2.2.0.jar">
|
||||
<sha256 value="a26cc8e2d8619197cc4d115bea7766e9aa8e0f1e7876ea044ee1b9f305654601" origin="Generated by Gradle"/>
|
||||
@@ -2695,6 +2820,14 @@
|
||||
<sha256 value="ca631ce7c7cc2a8ecb47d3462b429004c1cd3488437b3f739e35eafea2033bfb" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-daemon-embeddable" version="2.4.21">
|
||||
<artifact name="kotlin-daemon-embeddable-2.4.21.jar">
|
||||
<sha256 value="7b3ef24674e5bcffcadfc4e43202ea314194939ecbcdd90a4770b2f1b04e0d07" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="kotlin-daemon-embeddable-2.4.21.pom">
|
||||
<sha256 value="95236a3a7e9953545e2ff7c6dc0ea7ffeb27560000f20abe89dc53790fec3c7e" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-gradle-plugin" version="2.4.20">
|
||||
<artifact name="kotlin-gradle-plugin-2.4.20-gradle96.jar">
|
||||
<sha256 value="6f49688f2c6715d60f5dc52d4c1ada992ce4bed6053d1bd6e579c9392d7ba0ed" origin="Generated by Gradle"/>
|
||||
@@ -2703,6 +2836,14 @@
|
||||
<sha256 value="8a88cf52de5fb9c829730b0f5aec1fcd35633e697871e256230f09903c74dd43" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-gradle-plugin" version="2.4.21">
|
||||
<artifact name="kotlin-gradle-plugin-2.4.21-gradle96.jar">
|
||||
<sha256 value="d0a11912936c8801f1773a47e8fc51835a6ab568d73e4e1d188281955a7f575b" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="kotlin-gradle-plugin-2.4.21.module">
|
||||
<sha256 value="a412aecabbb40c7ed2fad5311d0114d4ca0e3a9690658ad3c4caed619e400d94" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-gradle-plugin-annotations" version="2.4.20">
|
||||
<artifact name="kotlin-gradle-plugin-annotations-2.4.20.jar">
|
||||
<sha256 value="fd400d73f635ed83875e75093c40a587840d4af399dcf6931239ba8fe469ef85" origin="Generated by Gradle"/>
|
||||
@@ -2711,6 +2852,14 @@
|
||||
<sha256 value="d903e1b1b633cdd7c85e557a4426b0c7b8584065a46fe626826a4da3790f945d" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-gradle-plugin-annotations" version="2.4.21">
|
||||
<artifact name="kotlin-gradle-plugin-annotations-2.4.21.jar">
|
||||
<sha256 value="5c386b0fa287584497b07d62af954e30d05907e6da867221124d0bb936989bbd" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="kotlin-gradle-plugin-annotations-2.4.21.pom">
|
||||
<sha256 value="b0f6b87a35d4be7ae06e554efdb261ea4bc5d59fa282c23ee28061d30805ddd6" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-gradle-plugin-api" version="2.4.20">
|
||||
<artifact name="kotlin-gradle-plugin-api-2.4.20-gradle96.jar">
|
||||
<sha256 value="fc9e18f84f1a5805532932f5293ec11121769263b396641f779e7b67fb4250a6" origin="Generated by Gradle"/>
|
||||
@@ -2719,6 +2868,14 @@
|
||||
<sha256 value="4bea3899dada541c1e482246b2573678eaedf611af7f1674ce0a17d5c3effdc0" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-gradle-plugin-api" version="2.4.21">
|
||||
<artifact name="kotlin-gradle-plugin-api-2.4.21-gradle96.jar">
|
||||
<sha256 value="43b8c73f3e4f123b1a5e4bc8e62bd9b258dfa84129e6564bebb03c5fada84d23" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="kotlin-gradle-plugin-api-2.4.21.module">
|
||||
<sha256 value="b8ae1c9ee5976145d4fd7925012e5699e2df5df7fe9613bac41d59404a58e815" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-gradle-plugin-idea" version="2.4.20">
|
||||
<artifact name="kotlin-gradle-plugin-idea-2.4.20.jar">
|
||||
<sha256 value="086734484c7edf19a620ab1a617d097c40e03bc52602e77840ea5ebd6380e514" origin="Generated by Gradle"/>
|
||||
@@ -2727,6 +2884,14 @@
|
||||
<sha256 value="7a8c8d128782b4f46b5d831c7eda2513d871d321a483a43aadbe77f97224cb64" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-gradle-plugin-idea" version="2.4.21">
|
||||
<artifact name="kotlin-gradle-plugin-idea-2.4.21.jar">
|
||||
<sha256 value="086734484c7edf19a620ab1a617d097c40e03bc52602e77840ea5ebd6380e514" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="kotlin-gradle-plugin-idea-2.4.21.module">
|
||||
<sha256 value="ddd2bb8f319a7c468ba2fb5a404b795c69e066bd5ad2d565b47b86fa2a337606" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-gradle-plugin-idea-proto" version="2.4.20">
|
||||
<artifact name="kotlin-gradle-plugin-idea-proto-2.4.20.jar">
|
||||
<sha256 value="a3a5535287930428ecbd4a326cb9d7d7c477e9f1a81e9573c3c973940c8f1477" origin="Generated by Gradle"/>
|
||||
@@ -2735,6 +2900,14 @@
|
||||
<sha256 value="d059dace6e76f36808ce94e8588a603324716d07767bc874206036794ba3bd05" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-gradle-plugin-idea-proto" version="2.4.21">
|
||||
<artifact name="kotlin-gradle-plugin-idea-proto-2.4.21.jar">
|
||||
<sha256 value="4559d92c5c1758a3e1ec5728822b059b2eb4aebef13c701ee86c7688acf164d5" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="kotlin-gradle-plugin-idea-proto-2.4.21.pom">
|
||||
<sha256 value="3c6eff2166eb46a8474b7bcccaa7d1ca5074260c866cc4bb2ba3678216a7bc15" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-gradle-plugins-bom" version="2.4.20">
|
||||
<artifact name="kotlin-gradle-plugins-bom-2.4.20.module">
|
||||
<sha256 value="6dfa7dfda619ad248e413cf313c313705db0aa0dbc410b3a8e0d922acfa82c94" origin="Generated by Gradle"/>
|
||||
@@ -2743,6 +2916,14 @@
|
||||
<sha256 value="70b071dc4074995076c97c749792ebcff69f10e636d1e2f2c68de0de023e0239" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-gradle-plugins-bom" version="2.4.21">
|
||||
<artifact name="kotlin-gradle-plugins-bom-2.4.21.module">
|
||||
<sha256 value="04f6a73a2c34217ac31599b8ed5ff24b85ebd410d32242eb27965c7b213f56c3" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="kotlin-gradle-plugins-bom-2.4.21.pom">
|
||||
<sha256 value="624c0c869b3fcf1665afec9c5c51a807be0a8c983931ebb188548ddcdb055780" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-klib-commonizer-api" version="2.4.20">
|
||||
<artifact name="kotlin-klib-commonizer-api-2.4.20.jar">
|
||||
<sha256 value="e13c80f2f96afce37d776e77ae8a2f5c4d3c72f4b0526271694b36786f27d331" origin="Generated by Gradle"/>
|
||||
@@ -2751,6 +2932,14 @@
|
||||
<sha256 value="b1edb50183d4549ad0fb449498535ab4186d491d86ad315e0187bcb9f9c7496d" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-klib-commonizer-api" version="2.4.21">
|
||||
<artifact name="kotlin-klib-commonizer-api-2.4.21.jar">
|
||||
<sha256 value="62ebe32fcf69600125b28388f0a80781276784d90e14d333bbd5080b4807220c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="kotlin-klib-commonizer-api-2.4.21.pom">
|
||||
<sha256 value="186a53ce6f218e43472808dc32cab627e19c144df2517398794bdb53d2df14a0" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-metadata-jvm" version="2.3.21">
|
||||
<artifact name="kotlin-metadata-jvm-2.3.21.jar">
|
||||
<sha256 value="00590f26a5a768777f04252c6cf93c016a3361a6bc93636df67375ad4d19557d" origin="Generated by Gradle"/>
|
||||
@@ -2767,6 +2956,14 @@
|
||||
<sha256 value="453ba071c89165cbdfc877ca733a4f38c01fc2f4894e9a259d7651f1176cd80c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-native-utils" version="2.4.21">
|
||||
<artifact name="kotlin-native-utils-2.4.21.jar">
|
||||
<sha256 value="e1858bf1fb5bbb1738c4fa0f9cfb502b911cabf313a5de4cae686d6c50d74814" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="kotlin-native-utils-2.4.21.pom">
|
||||
<sha256 value="9882156113d96f7911101a721cce2adefe2c8d9acc8844fb6397b8523538db37" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-reflect" version="1.6.10">
|
||||
<artifact name="kotlin-reflect-1.6.10.jar">
|
||||
<sha256 value="3277ac102ae17aad10a55abec75ff5696c8d109790396434b496e75087854203" origin="Generated by Gradle"/>
|
||||
@@ -2815,6 +3012,14 @@
|
||||
<sha256 value="dd0e3846b61a6d641300958cc52e4693cd7b47bd1d626505f383b2f9d23ade0e" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-script-runtime" version="2.4.21">
|
||||
<artifact name="kotlin-script-runtime-2.4.21.jar">
|
||||
<sha256 value="a658cf5902a1525a06c264a5e42b437e97a6679ddeef8ca641246f270cf6a013" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="kotlin-script-runtime-2.4.21.pom">
|
||||
<sha256 value="425d1683a903d085a1718122918242ad6ad0246c79283786697395e4d3a8c801" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-stdlib" version="2.2.0">
|
||||
<artifact name="kotlin-stdlib-2.2.0.jar">
|
||||
<sha256 value="65d12d85a3b865c160db9147851712a64b10dadd68b22eea22a95bf8a8670dca" origin="Generated by Gradle"/>
|
||||
@@ -2879,6 +3084,14 @@
|
||||
<sha256 value="afb28052ac6c3d605c0f661816ea653e073eb039682fed35bfa6cdc704c0911c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-stdlib" version="2.4.21">
|
||||
<artifact name="kotlin-stdlib-2.4.21.jar">
|
||||
<sha256 value="bd8250210584cb659847dce9cda660f8e9906e5def7fbebcea93dc6dcb6a88a3" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="kotlin-stdlib-2.4.21.module">
|
||||
<sha256 value="03b0df67c0cd74a948a45c5b03c4bbcfb31ab9b9879fb380adf7c187b6594b7f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-stdlib-common" version="2.2.0">
|
||||
<artifact name="kotlin-stdlib-common-2.2.0.module">
|
||||
<sha256 value="58fc0d664fc3a67e7e6be9fdbeaedbd212dfa3e527f744f861e792cda72c0e47" origin="Generated by Gradle"/>
|
||||
@@ -2924,6 +3137,14 @@
|
||||
<sha256 value="29dd79ed2bc1e64f6bfd5ccf0c1336c6b6c11ee2a69e0c585e3fad2f45b5325d" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-tooling-core" version="2.4.21">
|
||||
<artifact name="kotlin-tooling-core-2.4.21.jar">
|
||||
<sha256 value="5fc5db083803232857408ed5c25bcc307c703b04bdef6cb2c34ebf4db611a622" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="kotlin-tooling-core-2.4.21.pom">
|
||||
<sha256 value="b26b1cb6480001519d4650586cdc6054ea2d2d486ff332431c543eb8f76f41ce" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-util-io" version="2.4.20">
|
||||
<artifact name="kotlin-util-io-2.4.20.jar">
|
||||
<sha256 value="944edbec0f4438b40999e81872f6b05b0604abac6ed11d72c27846d19835f24c" origin="Generated by Gradle"/>
|
||||
@@ -2932,6 +3153,14 @@
|
||||
<sha256 value="840f888f360f4395c0967e17620b96d8b0cf5180efe2a214fdabd4d66677665b" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-util-io" version="2.4.21">
|
||||
<artifact name="kotlin-util-io-2.4.21.jar">
|
||||
<sha256 value="5821175f24578ca8f1ef405bc982b3668f3f40f1a5dd28bb3283dd5215a922d1" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="kotlin-util-io-2.4.21.pom">
|
||||
<sha256 value="a16f898aa8c686dc0b83d556ac4adecfcadbb6662ca547fca7802bf536d6d3d3" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-util-klib" version="2.4.20">
|
||||
<artifact name="kotlin-util-klib-2.4.20.jar">
|
||||
<sha256 value="3a58f9a82378e13ea5045266de2c09a8e5a05c44dd92131c4a83794fd3d1ceca" origin="Generated by Gradle"/>
|
||||
@@ -2940,6 +3169,14 @@
|
||||
<sha256 value="7fb051f47bbe01f318a1f434e2a7ed61a446fcc7a4d3ccb5a44c2b5105b0fd6b" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-util-klib" version="2.4.21">
|
||||
<artifact name="kotlin-util-klib-2.4.21.jar">
|
||||
<sha256 value="f01f79d54968941dfa83a525ae173be93460bb85b0bf2cc9ff06f6eb0864691e" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="kotlin-util-klib-2.4.21.pom">
|
||||
<sha256 value="97b59495de92c789c6963e4e70d5545ceccd2f0fab67d7ce72f7c5a87b948030" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-util-klib-metadata" version="2.4.20">
|
||||
<artifact name="kotlin-util-klib-metadata-2.4.20.jar">
|
||||
<sha256 value="75027fd053a594ab1ff64aa360cb1d6d13e9a7e3775583508b4811e0333823d8" origin="Generated by Gradle"/>
|
||||
@@ -2948,16 +3185,34 @@
|
||||
<sha256 value="90c5c8092955a601898c74f7dae3945fb0d041d5191d009bab41d530f8402f4f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-util-klib-metadata" version="2.4.21">
|
||||
<artifact name="kotlin-util-klib-metadata-2.4.21.jar">
|
||||
<sha256 value="a47f883b82fc3b99fe3d666498b22312628afb5cc1b9b26e8188175be2da6060" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="kotlin-util-klib-metadata-2.4.21.pom">
|
||||
<sha256 value="a0f7f315c9f60b53458cc1e034a7c55e17619ce7db51db43efb7d3cdacbb5c6c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin.jvm" name="org.jetbrains.kotlin.jvm.gradle.plugin" version="2.4.20">
|
||||
<artifact name="org.jetbrains.kotlin.jvm.gradle.plugin-2.4.20.pom">
|
||||
<sha256 value="f3b27910045c1e1e21cb48d68a7e177ea1a4a3dda467e546c15c30b9c098187c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin.jvm" name="org.jetbrains.kotlin.jvm.gradle.plugin" version="2.4.21">
|
||||
<artifact name="org.jetbrains.kotlin.jvm.gradle.plugin-2.4.21.pom">
|
||||
<sha256 value="8e08073d123182e69c07d24c6dca7b98cc53a37707a73a6af7be88e38218b42b" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin.plugin.compose" name="org.jetbrains.kotlin.plugin.compose.gradle.plugin" version="2.4.20">
|
||||
<artifact name="org.jetbrains.kotlin.plugin.compose.gradle.plugin-2.4.20.pom">
|
||||
<sha256 value="9ed1b04a99d38243a15a42b37d4dc4ba84ca77f35d77c081a7c2208d439e1220" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin.plugin.compose" name="org.jetbrains.kotlin.plugin.compose.gradle.plugin" version="2.4.21">
|
||||
<artifact name="org.jetbrains.kotlin.plugin.compose.gradle.plugin-2.4.21.pom">
|
||||
<sha256 value="ee66712b1006e971636f11554af63c56835caf315382ce23e54f59f5b8b9d4f9" 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"/>
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
# Manual edits can break the build and are not advised.
|
||||
# This file is expected to be part of source control.
|
||||
# To regenerate this file, run: ./gradlew :platform:dependencies --write-locks
|
||||
androidx.annotation:annotation-jvm:1.11.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.annotation:annotation:1.11.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
ch.qos.logback:logback-classic:1.3.15=ktlint
|
||||
ch.qos.logback:logback-core:1.3.15=ktlint
|
||||
com.android.tools.analytics-library:protos:32.4.1=androidLintTool
|
||||
@@ -75,6 +77,7 @@ jakarta.xml.bind:jakarta.xml.bind-api:2.3.2=androidLintTool
|
||||
javax.inject:javax.inject:1=androidLintTool
|
||||
junit:junit:4.13.2=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
|
||||
net.java.dev.jna:jna:5.6.0=androidLintTool
|
||||
net.sf.kxml:kxml2:2.3.0=androidLintTool
|
||||
org.apache.commons:commons-compress:1.27.1=androidLintTool
|
||||
@@ -93,27 +96,27 @@ org.glassfish.jaxb:jaxb-runtime:2.3.2=androidLintTool
|
||||
org.glassfish.jaxb:txw2:2.3.2=androidLintTool
|
||||
org.hamcrest:hamcrest-core:1.3=debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-api:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-api:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-compat:2.4.20=kotlinAbiValidationCompatClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
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
|
||||
org.jetbrains.kotlin:kotlin-build-tools-cri-impl:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-cri-impl:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-cri-impl:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-impl:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-impl:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-impl:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.2.0=ktlint,ktlintBaselineReporter,ktlintRuleset
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-runner:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-runner:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-runner:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-client:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-client:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-client:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.2.0=ktlint,ktlintBaselineReporter,ktlintRuleset
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-reflect:1.6.10=kotlinAbiValidationCompatClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,ktlint,ktlintBaselineReporter,ktlintRuleset
|
||||
org.jetbrains.kotlin:kotlin-reflect:2.2.10=androidLintTool
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:2.2.0=ktlint,ktlintBaselineReporter,ktlintRuleset
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib-common:2.2.0=ktlintReporter
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0=ktlintReporter
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:2.2.10=androidLintTool,unified-test-platform-gradle-work-action
|
||||
@@ -122,8 +125,8 @@ org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.2.10=androidLintTool,unified-test-plat
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.2.0=ktlint,ktlintBaselineReporter,ktlintReporter,ktlintRuleset
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.2.10=androidLintTool,unified-test-platform-gradle-work-action
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.4.20=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-tooling-core:2.4.20=kotlinAbiValidationCompatClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
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:kotlinx-coroutines-android:1.11.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.11.0=debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.9.0=androidLintTool,unified-test-platform-gradle-work-action
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import java.io.File
|
||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||
|
||||
plugins {
|
||||
@@ -10,6 +11,8 @@ android {
|
||||
ndkVersion = libs.versions.ndk.get()
|
||||
defaultConfig {
|
||||
minSdk = libs.versions.minSdk.get().toInt()
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
ndk { abiFilters += listOf("arm64-v8a", "armeabi-v7a", "x86_64") }
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
@@ -28,5 +31,134 @@ kotlin {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("${libs.jna.get().module}:${libs.versions.jna.get()}@aar")
|
||||
implementation(libs.annotation)
|
||||
testImplementation(libs.junit)
|
||||
androidTestImplementation(libs.android.test.runner)
|
||||
}
|
||||
|
||||
val workspace = rootProject.layout.projectDirectory.dir("..").asFile
|
||||
val cargoExecutable = providers.environmentVariable("CARGO").orElse(
|
||||
providers.environmentVariable("PATH").map { path ->
|
||||
path.split(File.pathSeparatorChar).map { File(it, "cargo") }
|
||||
.firstOrNull { it.isFile && it.canExecute() }?.absolutePath
|
||||
?: error("Cargo must be installed and in PATH")
|
||||
}
|
||||
)
|
||||
val rustVersion = libs.versions.rust.get()
|
||||
val ndkDirectory = androidComponents.sdkComponents.ndkDirectory
|
||||
val sdkDirectory = androidComponents.sdkComponents.sdkDirectory
|
||||
val rustInputs = files(
|
||||
workspace.resolve("Cargo.toml"),
|
||||
workspace.resolve("Cargo.lock"),
|
||||
rootProject.file("rust-toolchain.toml"),
|
||||
fileTree(workspace.resolve("crates")) { include("**/*.rs", "**/Cargo.toml", "**/uniffi.toml") }
|
||||
)
|
||||
val checkRustToolchain = tasks.register<Exec>("checkRustToolchain") {
|
||||
workingDir = workspace
|
||||
commandLine(
|
||||
cargoExecutable.get(), "+$rustVersion", "run", "--locked",
|
||||
"--package", "ironstorage-android-build", "--", "check-toolchain",
|
||||
cargoExecutable.get(), rustVersion, ndkDirectory.get().asFile.absolutePath,
|
||||
libs.versions.ndk.get(), libs.versions.cargoNdk.get()
|
||||
)
|
||||
}
|
||||
androidComponents.onVariants { variant ->
|
||||
val name = variant.name
|
||||
val title = name.replaceFirstChar { it.uppercaseChar() }
|
||||
val rawNative = layout.buildDirectory.dir("generated/native-raw/$name/jniLibs")
|
||||
val nativeOutput = layout.buildDirectory.dir("generated/native/$name/jniLibs")
|
||||
val rawBindings = layout.buildDirectory.dir("generated/bindings-raw/$name")
|
||||
val bindings = layout.buildDirectory.dir("generated/bindings/$name")
|
||||
val native = tasks.register<Exec>("build${title}Rust") {
|
||||
dependsOn(checkRustToolchain)
|
||||
workingDir = workspace
|
||||
inputs.files(rustInputs)
|
||||
inputs.property("rustVersion", rustVersion)
|
||||
inputs.property("cargoNdk", libs.versions.cargoNdk.get())
|
||||
inputs.property("ndkVersion", libs.versions.ndk.get())
|
||||
inputs.property("minSdk", libs.versions.minSdk.get())
|
||||
outputs.dir(rawNative)
|
||||
environment("ANDROID_NDK_HOME", ndkDirectory.get().asFile.absolutePath)
|
||||
environment("ANDROID_HOME", sdkDirectory.get().asFile.absolutePath)
|
||||
environment(
|
||||
"RUSTFLAGS",
|
||||
"-D warnings -C link-arg=-Wl,-z,max-page-size=16384 -C link-arg=-Wl,-z,common-page-size=16384"
|
||||
)
|
||||
environment("CARGO_PROFILE_RELEASE_DEBUG", "2")
|
||||
commandLine(
|
||||
listOf(
|
||||
cargoExecutable.get(), "+$rustVersion", "ndk",
|
||||
"--target", "arm64-v8a",
|
||||
"--target", "armeabi-v7a",
|
||||
"--target", "x86_64",
|
||||
"--platform", libs.versions.minSdk.get(),
|
||||
"--output-dir", rawNative.get().asFile.absolutePath,
|
||||
"build", "--locked", "--package", "ironstorage-android", "--lib"
|
||||
) +
|
||||
if (variant.buildType == "release") listOf("--release") else emptyList()
|
||||
)
|
||||
}
|
||||
val audit = tasks.register<Exec>("package${title}Rust") {
|
||||
dependsOn(native)
|
||||
workingDir = workspace
|
||||
inputs.dir(rawNative)
|
||||
inputs.files(
|
||||
fileTree(workspace.resolve("tools/android-build")) {
|
||||
include("**/*.rs", "Cargo.toml")
|
||||
}
|
||||
)
|
||||
outputs.dir(nativeOutput)
|
||||
commandLine(
|
||||
cargoExecutable.get(), "+$rustVersion", "run", "--locked",
|
||||
"--package", "ironstorage-android-build", "--", "package-native",
|
||||
rawNative.get().asFile.absolutePath, nativeOutput.get().asFile.absolutePath
|
||||
)
|
||||
}
|
||||
val generate = tasks.register<Exec>("generate${title}RustBindings") {
|
||||
dependsOn(audit)
|
||||
workingDir = workspace
|
||||
inputs.dir(nativeOutput)
|
||||
inputs.file(rootProject.file("uniffi.toml"))
|
||||
inputs.files(
|
||||
fileTree(workspace.resolve("tools/android-build")) {
|
||||
include("**/*.rs", "Cargo.toml")
|
||||
}
|
||||
)
|
||||
outputs.dir(rawBindings)
|
||||
commandLine(
|
||||
cargoExecutable.get(), "+$rustVersion", "run", "--locked",
|
||||
"--package", "ironstorage-android-build", "--bin", "ironstorage-uniffi-bindgen",
|
||||
"--", "generate", "--library",
|
||||
nativeOutput.get().file(
|
||||
"arm64-v8a/libironstorage_android.so"
|
||||
).asFile.absolutePath,
|
||||
"--language", "kotlin", "--config",
|
||||
rootProject.file(
|
||||
"uniffi.toml"
|
||||
).absolutePath,
|
||||
"--out-dir", rawBindings.get().asFile.absolutePath, "--no-format"
|
||||
)
|
||||
}
|
||||
val prepare = tasks.register<Exec>("prepare${title}RustBindings") {
|
||||
dependsOn(generate)
|
||||
workingDir = workspace
|
||||
inputs.dir(rawBindings)
|
||||
inputs.files(
|
||||
fileTree(workspace.resolve("tools/android-build")) {
|
||||
include("**/*.rs", "Cargo.toml")
|
||||
}
|
||||
)
|
||||
outputs.dir(bindings)
|
||||
commandLine(
|
||||
cargoExecutable.get(), "+$rustVersion", "run", "--locked",
|
||||
"--package", "ironstorage-android-build", "--", "prepare-bindings",
|
||||
rawBindings.get().asFile.absolutePath, bindings.get().asFile.absolutePath
|
||||
)
|
||||
}
|
||||
variant.sources.kotlin!!.addStaticSourceDirectory(bindings.get().asFile.absolutePath)
|
||||
variant.sources.jniLibs!!.addStaticSourceDirectory(nativeOutput.get().asFile.absolutePath)
|
||||
tasks.matching {
|
||||
it.name == "pre${title}Build" || it.name == "compile${title}Kotlin"
|
||||
}.configureEach { dependsOn(prepare) }
|
||||
}
|
||||
@@ -1 +1,7 @@
|
||||
# Native/generated keep rules are added with the UniFFI packaging in #92.
|
||||
-keep class com.sun.jna.** { *; }
|
||||
-keep class de.rfc1437.ironstorage.bridge.generated.** { *; }
|
||||
# JNA includes optional desktop AWT helpers that Android never invokes.
|
||||
-dontwarn java.awt.Component
|
||||
-dontwarn java.awt.GraphicsEnvironment
|
||||
-dontwarn java.awt.HeadlessException
|
||||
-dontwarn java.awt.Window
|
||||
@@ -2,6 +2,12 @@
|
||||
# Manual edits can break the build and are not advised.
|
||||
# This file is expected to be part of source control.
|
||||
# To regenerate this file, run: ./gradlew :rust-bridge:dependencies --write-locks
|
||||
androidx.annotation:annotation-jvm:1.11.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.annotation:annotation:1.11.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
androidx.test.services:storage:1.6.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath
|
||||
androidx.test:monitor:1.8.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath
|
||||
androidx.test:runner:1.7.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath
|
||||
androidx.tracing:tracing:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath
|
||||
ch.qos.logback:logback-classic:1.3.15=ktlint
|
||||
ch.qos.logback:logback-core:1.3.15=ktlint
|
||||
com.android.tools.analytics-library:protos:32.4.1=androidLintTool
|
||||
@@ -73,8 +79,9 @@ io.github.oshai:kotlin-logging:5.1.0=ktlint,ktlintBaselineReporter,ktlintReporte
|
||||
jakarta.activation:jakarta.activation-api:1.2.1=androidLintTool
|
||||
jakarta.xml.bind:jakarta.xml.bind-api:2.3.2=androidLintTool
|
||||
javax.inject:javax.inject:1=androidLintTool
|
||||
junit:junit:4.13.2=debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath
|
||||
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=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
net.java.dev.jna:jna:5.6.0=androidLintTool
|
||||
net.sf.kxml:kxml2:2.3.0=androidLintTool
|
||||
org.apache.commons:commons-compress:1.27.1=androidLintTool
|
||||
@@ -91,29 +98,29 @@ org.checkerframework:checker-qual:3.43.0=androidLintTool
|
||||
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=debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath
|
||||
org.hamcrest:hamcrest-core:1.3=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-api:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-api:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-compat:2.4.20=kotlinAbiValidationCompatClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
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
|
||||
org.jetbrains.kotlin:kotlin-build-tools-cri-impl:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-cri-impl:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-cri-impl:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-impl:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-impl:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-impl:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.2.0=ktlint,ktlintBaselineReporter,ktlintRuleset
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-runner:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-runner:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-runner:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-client:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-client:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-client:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.2.0=ktlint,ktlintBaselineReporter,ktlintRuleset
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-reflect:1.6.10=kotlinAbiValidationCompatClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,ktlint,ktlintBaselineReporter,ktlintRuleset
|
||||
org.jetbrains.kotlin:kotlin-reflect:2.2.10=androidLintTool
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:2.2.0=ktlint,ktlintBaselineReporter,ktlintRuleset
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:2.4.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:2.4.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib-common:2.2.0=ktlintReporter
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0=ktlintReporter
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:2.2.10=androidLintTool,unified-test-platform-gradle-work-action
|
||||
@@ -122,8 +129,8 @@ org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.2.10=androidLintTool,unified-test-plat
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.2.0=ktlint,ktlintBaselineReporter,ktlintReporter,ktlintRuleset
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.2.10=androidLintTool,unified-test-platform-gradle-work-action
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.4.0=kotlinAbiValidationCompatClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.4.20=debugAndroidTestCompileClasspath,debugAndroidTestLintChecksClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestLintChecksClasspath,debugUnitTestRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-tooling-core:2.4.20=kotlinAbiValidationCompatClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
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:kotlinx-coroutines-bom:1.9.0=androidLintTool,unified-test-platform-gradle-work-action
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.0=kotlinAbiValidationCompatClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,ktlint,ktlintBaselineReporter,ktlintRuleset
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.9.0=androidLintTool,unified-test-platform-gradle-work-action
|
||||
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
package de.rfc1437.ironstorage.bridge
|
||||
|
||||
import android.content.ContextWrapper
|
||||
import android.content.pm.ApplicationInfo
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import de.rfc1437.ironstorage.bridge.generated.FfiConverterString
|
||||
import de.rfc1437.ironstorage.bridge.generated.IntegrityCheckingUniffiLib
|
||||
import de.rfc1437.ironstorage.bridge.generated.InternalException
|
||||
import de.rfc1437.ironstorage.bridge.generated.MobileAuthenticationErrorKind
|
||||
import de.rfc1437.ironstorage.bridge.generated.MobileAuthenticationFfiException
|
||||
import de.rfc1437.ironstorage.bridge.generated.MobileEntryCopy
|
||||
import de.rfc1437.ironstorage.bridge.generated.MobileShellState
|
||||
import de.rfc1437.ironstorage.bridge.generated.MobileTab
|
||||
import de.rfc1437.ironstorage.bridge.generated.UniffiRustCallStatus
|
||||
import de.rfc1437.ironstorage.bridge.generated.uniffiTraitInterfaceCall
|
||||
import java.io.File
|
||||
import java.util.zip.ZipOutputStream
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertThrows
|
||||
import org.junit.Test
|
||||
|
||||
class NativeRuntimeTest {
|
||||
private val context = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
|
||||
@Test
|
||||
fun generatedBindingsCallEveryRustFixtureAndRedactDiagnostics() {
|
||||
val runtime = NativeRuntime(context)
|
||||
MobileShellState.entries.forEach { state ->
|
||||
val shell = runtime.fixture(state)
|
||||
assertEquals(MobileTab.entries, shell.pages.map { it.tab })
|
||||
assertEquals(setOf(state), shell.pages.map { it.state }.toSet())
|
||||
}
|
||||
val secret = "NativeFixtureSecretMustNeverAppearInDiagnostics"
|
||||
val copy = MobileEntryCopy(secret, 60uL)
|
||||
assertEquals(secret, copy.value)
|
||||
assertFalse(copy.toString().contains(secret))
|
||||
val error = MobileAuthenticationFfiException.Failed(
|
||||
MobileAuthenticationErrorKind.entries.first(),
|
||||
secret,
|
||||
secret
|
||||
)
|
||||
assertFalse(error.toString().contains(secret))
|
||||
assertFalse(error.message.contains(secret))
|
||||
assertFalse(InternalException(secret).toString().contains(secret))
|
||||
val status = UniffiRustCallStatus()
|
||||
uniffiTraitInterfaceCall<Unit>(status, { throw IllegalStateException(secret) }, {})
|
||||
assertEquals(
|
||||
"Native callback failed ([REDACTED])",
|
||||
FfiConverterString.lift(status.error_buf)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wrongNativeContractAndChecksumFailWithTypedRedactedErrors() {
|
||||
NativeRuntime(context).fixture(MobileShellState.EMPTY)
|
||||
val version = IntegrityCheckingUniffiLib
|
||||
.ffi_ironstorage_apple_uniffi_contract_version().toLong()
|
||||
val checksum = IntegrityCheckingUniffiLib
|
||||
.uniffi_ironstorage_apple_checksum_func_mobile_shell_fixture().toLong() and 0xffffL
|
||||
NativeBindingChecks.requireMatch(-27278, 38258, NativeFailureKind.ChecksumMismatch)
|
||||
for ((actual, kind) in listOf(
|
||||
version to NativeFailureKind.ContractMismatch,
|
||||
checksum to NativeFailureKind.ChecksumMismatch
|
||||
)) {
|
||||
val failure = assertThrows(NativeBindingMismatchException::class.java) {
|
||||
NativeBindingChecks.requireMatch(actual, actual + 1, kind)
|
||||
}
|
||||
assertEquals(kind, failure.kind)
|
||||
assertEquals("Rust bindings do not match the packaged native library", failure.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun mainThreadAndUnreadablePackagesFailWithTypedErrors() {
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync {
|
||||
val failure = assertThrows(NativeBridgeException::class.java) {
|
||||
NativeRuntime(context).fixture(MobileShellState.EMPTY)
|
||||
}
|
||||
assertEquals(NativeFailureKind.MainThreadCall, failure.kind)
|
||||
}
|
||||
val packageFile = File.createTempFile("native-corrupt-package", ".apk", context.cacheDir)
|
||||
try {
|
||||
val info = ApplicationInfo(context.applicationInfo).apply {
|
||||
sourceDir = packageFile.absolutePath
|
||||
splitSourceDirs = null
|
||||
nativeLibraryDir = File(context.cacheDir, "missing-native-fixture").absolutePath
|
||||
}
|
||||
val invalid = object : ContextWrapper(context) {
|
||||
override fun getApplicationContext() = this
|
||||
override fun getApplicationInfo() = info
|
||||
}
|
||||
val failure = assertThrows(NativeBridgeException::class.java) {
|
||||
NativeRuntime(invalid).fixture(MobileShellState.EMPTY)
|
||||
}
|
||||
assertEquals(NativeFailureKind.LoadFailure, failure.kind)
|
||||
} finally {
|
||||
packageFile.delete()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun missingLibraryAndUnsupportedAbiFailBeforeEnteringRust() {
|
||||
val abiFailure = assertThrows(NativeBridgeException::class.java) {
|
||||
NativeRuntime.supportedAbi(listOf("unsupported-fixture-abi"))
|
||||
}
|
||||
assertEquals(NativeFailureKind.UnsupportedAbi, abiFailure.kind)
|
||||
val packageFile = File.createTempFile("native-empty-package", ".apk", context.cacheDir)
|
||||
try {
|
||||
ZipOutputStream(packageFile.outputStream()).close()
|
||||
val info = ApplicationInfo(context.applicationInfo).apply {
|
||||
sourceDir = packageFile.absolutePath
|
||||
splitSourceDirs = null
|
||||
nativeLibraryDir = File(context.cacheDir, "missing-native-fixture").absolutePath
|
||||
}
|
||||
val missing = object : ContextWrapper(context) {
|
||||
override fun getApplicationContext() = this
|
||||
override fun getApplicationInfo() = info
|
||||
}
|
||||
val failure = assertThrows(NativeBridgeException::class.java) {
|
||||
NativeRuntime(missing).fixture(MobileShellState.EMPTY)
|
||||
}
|
||||
assertEquals(NativeFailureKind.MissingLibrary, failure.kind)
|
||||
} finally {
|
||||
packageFile.delete()
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package de.rfc1437.ironstorage.bridge
|
||||
|
||||
internal object NativeBindingChecks {
|
||||
fun requireMatch(actual: Long, expected: Long, kind: NativeFailureKind) {
|
||||
// UniFFI checksums are u16; JNA's Int return can include unspecified upper bits.
|
||||
val value = if (kind == NativeFailureKind.ChecksumMismatch) actual and 0xffffL else actual
|
||||
if (value != expected) throw NativeBindingMismatchException(kind)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package de.rfc1437.ironstorage.bridge
|
||||
|
||||
enum class NativeFailureKind {
|
||||
UnsupportedAbi,
|
||||
MissingLibrary,
|
||||
ContractMismatch,
|
||||
ChecksumMismatch,
|
||||
LoadFailure,
|
||||
RustFailure,
|
||||
MainThreadCall
|
||||
}
|
||||
|
||||
class NativeBindingMismatchException(val kind: NativeFailureKind) :
|
||||
LinkageError("Rust bindings do not match the packaged native library")
|
||||
|
||||
class NativeBridgeException(val kind: NativeFailureKind) :
|
||||
Exception("Native Rust runtime unavailable: $kind")
|
||||
@@ -0,0 +1,80 @@
|
||||
package de.rfc1437.ironstorage.bridge
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.os.Looper
|
||||
import de.rfc1437.ironstorage.bridge.generated.MobileShell
|
||||
import de.rfc1437.ironstorage.bridge.generated.MobileShellState
|
||||
import de.rfc1437.ironstorage.bridge.generated.mobileShellFixture
|
||||
import de.rfc1437.ironstorage.bridge.generated.uniffiEnsureInitialized
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.util.concurrent.CancellationException
|
||||
import java.util.zip.ZipFile
|
||||
|
||||
/** OS library loading only. Callers schedule all native calls off the main thread. */
|
||||
class NativeRuntime(context: Context) {
|
||||
private val applicationInfo = context.applicationContext.applicationInfo
|
||||
private val lock = Any()
|
||||
private var initialized = false
|
||||
private var initializationFailure: NativeFailureKind? = null
|
||||
|
||||
fun fixture(state: MobileShellState): MobileShell = call {
|
||||
initialize()
|
||||
mobileShellFixture(state)
|
||||
}
|
||||
|
||||
private fun initialize() = synchronized(lock) {
|
||||
initializationFailure?.let { throw NativeBridgeException(it) }
|
||||
if (!initialized) {
|
||||
val abi = supportedAbi(Build.SUPPORTED_ABIS.toList())
|
||||
val extracted = File(applicationInfo.nativeLibraryDir, LIBRARY_FILE).isFile
|
||||
val packages =
|
||||
listOf(applicationInfo.sourceDir) + applicationInfo.splitSourceDirs.orEmpty()
|
||||
val packaged = extracted || packages.any { path ->
|
||||
ZipFile(path).use { it.getEntry("lib/$abi/$LIBRARY_FILE") != null }
|
||||
}
|
||||
if (!packaged) throw NativeBridgeException(NativeFailureKind.MissingLibrary)
|
||||
System.loadLibrary(LIBRARY)
|
||||
uniffiEnsureInitialized()
|
||||
initialized = true
|
||||
}
|
||||
}
|
||||
|
||||
private fun <T> call(operation: () -> T): T {
|
||||
if (Looper.myLooper() == Looper.getMainLooper()) {
|
||||
throw NativeBridgeException(NativeFailureKind.MainThreadCall)
|
||||
}
|
||||
try {
|
||||
return operation()
|
||||
} catch (error: NativeBridgeException) {
|
||||
fail(error.kind)
|
||||
} catch (error: CancellationException) {
|
||||
throw error
|
||||
} catch (error: NativeBindingMismatchException) {
|
||||
fail(error.kind)
|
||||
} catch (_: IOException) {
|
||||
fail(NativeFailureKind.LoadFailure)
|
||||
} catch (_: LinkageError) {
|
||||
fail(NativeFailureKind.LoadFailure)
|
||||
} catch (_: Exception) {
|
||||
fail(NativeFailureKind.RustFailure)
|
||||
}
|
||||
}
|
||||
|
||||
private fun fail(kind: NativeFailureKind): Nothing {
|
||||
synchronized(lock) {
|
||||
if (!initialized) initializationFailure = kind
|
||||
}
|
||||
throw NativeBridgeException(kind)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val LIBRARY = "ironstorage_android"
|
||||
private const val LIBRARY_FILE = "libironstorage_android.so"
|
||||
|
||||
internal fun supportedAbi(deviceAbis: List<String>): String =
|
||||
deviceAbis.firstOrNull { it in setOf("arm64-v8a", "armeabi-v7a", "x86_64") }
|
||||
?: throw NativeBridgeException(NativeFailureKind.UnsupportedAbi)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
[toolchain]
|
||||
channel = "1.97.1"
|
||||
profile = "minimal"
|
||||
targets = ["aarch64-linux-android", "armv7-linux-androideabi", "x86_64-linux-android"]
|
||||
@@ -0,0 +1,6 @@
|
||||
[defaults.bindings.kotlin]
|
||||
package_name = "de.rfc1437.ironstorage.bridge.generated"
|
||||
cdylib_name = "ironstorage_android"
|
||||
android = true
|
||||
generate_immutable_records = true
|
||||
omit_checksums = false
|
||||
Reference in new issue
Block a user