Prepare Android release artifacts and listing (#112)
Android ARM verification / rust (push) Failing after 49m41s
Android ARM verification / android (push) Failing after 8s
Dependency security audit / rustsec (push) Failing after 22s

Add Rust distribution auditing, pinned post-build AAB signing, complete offline third-party notices, an Android privacy policy and reviewable Play listing assets. Preserve the application ID and audit both ARM ABIs, native symbols, baseline profiles and R8 mapping.

Fix dialog focus ownership, navigation-triggered cleanup loops and stale authentication errors after first-run setup, with native and real-activity regressions.

Google Play publication is deferred by the user. Issue #112 remains open for production signing, Console declarations and actual Play install/update verification.
This commit is contained in:
hugo committed 2026-10-15 16:16:01 +02:00
1 parent b54636b7bc
commit bf83a0ba41
51 files changed
+1493 -41

No files matched your search

@@ -63,11 +63,33 @@ class NativeEntryViewerTest {
assertNotNull(page.sections)
}
try {
withContext(Dispatchers.IO) {
val setup = session.storage().androidOnboarding(session.backend())
val key = setup.generate("Viewer fixture", password).selectedKey
setup.setupLocal(requireNotNull(key), password)
withContext(Dispatchers.Main.immediate) { authentication.reload() }
withTimeout(30000) {
authentication.state.first {
!it.busy && it.failure?.kind == AuthenticationFailureKind.Configuration
}
}
val setup = NativeOnboardingRepository(
session,
scope,
NativeFixtureShellRepository(session, scope),
authentication
)
withTimeout(30000) { setup.setup.first { !it.busy } }
withContext(Dispatchers.Main.immediate) {
setup.generate("Viewer fixture", password)
}
val generated = withTimeout(30000) {
setup.setup.first { !it.busy && it.keys.isNotEmpty() }
}
withContext(Dispatchers.Main.immediate) {
setup.createLocal(generated.selectedKey, password)
}
withTimeout(30000) { setup.setup.first { !it.busy && it.configured } }
withTimeout(30000) {
authentication.state.first { !it.busy && it.failure == null }
}
assertFalse(authentication.state.value.unlocked)
repeat(12) {
coroutineScope {
val onboarding = async(Dispatchers.IO) {
@@ -14,6 +14,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@@ -21,7 +22,8 @@ import kotlinx.coroutines.withContext
class NativeOnboardingRepository(
private val session: NativePrivateSession,
private val scope: CoroutineScope,
private val shell: ShellRepository
private val shell: ShellRepository,
private val authentication: AuthenticationRepository
) : OnboardingRepository {
private val mutableSetup = MutableStateFlow(SetupStatus())
override val setup: StateFlow<SetupStatus> = mutableSetup
@@ -152,6 +154,10 @@ class NativeOnboardingRepository(
}
remote?.close()
remote = null
scope.launch {
authentication.state.first { !it.busy }
authentication.reload()
}
shell.refresh()
}
private fun updateStatus(status: MobileAndroidSetupStatus) {