The platform half of chunk 2; the account-add UI is 2d, since it is a design task and the piece that needs an on-device review. A stub ContentProvider turned out to be required and was not in the plan: a sync adapter registers against a content authority, and we publish no provider since :provider was deleted. Without one there is nothing for contentAuthority to name, nothing for requestSync to address, and hasAuthorityAccess() makes every ContentResolver sync call a silent no-op at targetSdk 34+. - CredentialStore: Keystore AES/GCM, blob in its own DataStore file. security-crypto is formally deprecated and terminal. Decryption failure means re-authenticate, never a crash — including ProviderException, which is a RuntimeException and escapes the obvious catches. - CalDavAccounts + SyncAuthenticator: no password reaches AccountManager, which stores them as plain TEXT. The authenticator never returns null — a null is the protocol for "answering asynchronously", and nothing here does, so Settings would wait forever. addAccount refuses with a readable message until 2d ships the screen, rather than opening the home screen and hanging. - SyncAdapterService: enqueue and wait on the unique work *name*, not the request id — enqueueUniqueWork is async so the id is unknown when the wait starts, and under KEEP it may never exist at all. Being deduplicated is not a failure. - Account type and authority are per build variant, so debug and release do not fight over ownership. SyncContractTest guards the Kotlin/resValue pair. - The credential blob is the only thing excluded from backup: Keystore keys are non-exportable, so a restored ciphertext can never be decrypted. Known trade-off recorded in network_security_config.xml and SYNC-PLAN.md: the user CA store is trusted for all traffic, which chunk 5's cert4android should replace rather than sit beside. The instrumented tests here compile but have not been run — device work waits for an explicit go-ahead.
34 lines
1.8 KiB
XML
34 lines
1.8 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<full-backup-content>
|
|
<!--
|
|
Agendula's own task store. Room runs in WAL mode and Auto Backup copies
|
|
files without checkpointing, so the `-wal` sidecar can hold writes the
|
|
`.db` alone does not — all three go in together, and the app checkpoints
|
|
on ON_STOP so a restore is consistent either way.
|
|
|
|
Naming any <include> makes everything else excluded by default, so the
|
|
archived dmfs database (`tasks.db.imported`, kept one release as the
|
|
import's rollback path) is already left out. An explicit <exclude> for it
|
|
would be redundant *and* rejected — lint's FullBackupContent check errors
|
|
on an exclude that sits under no included path.
|
|
|
|
Settings live in DataStore, which this exclusion now also covers, so its
|
|
sharedpref file is listed back in.
|
|
-->
|
|
<include domain="database" path="agendula-tasks.db" />
|
|
<include domain="database" path="agendula-tasks.db-wal" />
|
|
<include domain="database" path="agendula-tasks.db-shm" />
|
|
<include domain="file" path="datastore/" />
|
|
<!--
|
|
The one thing that must not travel. Keystore keys are non-exportable, so
|
|
a restored ciphertext can never be decrypted again — it would surface as
|
|
an account that silently stops syncing with no way to tell why. Excluding
|
|
it means the user signs in again on a new device, which is the honest
|
|
outcome. Note this is the *only* exclusion that is right here:
|
|
docs/SYNC.md is explicit that dropping the database or all of DataStore
|
|
from backup would trade a latent bug for a live one, since Auto Backup is
|
|
Local mode's only automatic safety net.
|
|
-->
|
|
<exclude domain="file" path="datastore/agendula_credentials.preferences_pb" />
|
|
</full-backup-content>
|