Skip to content

feat: no longer implicitly set collection path when DB is used - #21343

Merged
david-allison merged 2 commits into
ankidroid:mainfrom
david-allison:collection-helper-anki-common
Jul 22, 2026
Merged

feat: no longer implicitly set collection path when DB is used#21343
david-allison merged 2 commits into
ankidroid:mainfrom
david-allison:collection-helper-anki-common

Conversation

@david-allison

@david-allison david-allison commented Jul 6, 2026

Copy link
Copy Markdown
Member

Note

Assisted-by: Claude Fable 5

Purpose / Description

  • Removes the 'create collection' responsibility of getCurrentAnkiDroidDirectory via moving storage initialization into startup/SetupStorage.kt
  • ⚠️ Accessing the collection no longer initializes it

Fixes

Approach

  • Implement storageDecision() based on whether the collection path is set
  • Add error handling to DeckPicker if storageDecision isn't set
  • Initialization is moved to AnkiDroidApp
  • ⚠️ getCurrentAnkiDroidDirectory no longer sets the collection path; throwing StorageNotConfiguredException
  • ensureOpenInner also throws

I maintained SystemStorageException for the OS-level errors if context.getExternalFilesDir returns null

How Has This Been Tested?

Unit tested

Checklist

  • You have a descriptive commit message with a short title (first line, max 50 chars).
  • You have commented your code, particularly in hard-to-understand areas
  • You have performed a self-review of your own code
  • UI changes: include screenshots of all affected screens (in particular showing any new or changed strings)
  • UI Changes: You have tested your change using the Google Accessibility Scanner

@david-allison david-allison added the Review High Priority Request for high priority review label Jul 6, 2026
@david-allison
david-allison force-pushed the collection-helper-anki-common branch from cbe4d38 to f86073c Compare July 6, 2026 06:07
@lukstbit

lukstbit commented Jul 6, 2026

Copy link
Copy Markdown
Member

Reviewers: please let me know if you want me to split this out:

Yes, please do this.

@david-allison
david-allison force-pushed the collection-helper-anki-common branch from f86073c to 33b2d1a Compare July 6, 2026 20:42
@david-allison david-allison changed the title feat: no longer implicitly set collection path when DB is used. Also move CollectionManager to :anki-common feat: no longer implicitly set collection path when DB is used Jul 6, 2026
Breaking change, this was previously done on first collection access.

Now this is set in AnkiDroidApp, and reading throws
StorageNotConfiguredException beforehand.

This contains a workaround for the OS-level bug: `SystemStorageException`
if the exception is caught, it is explicitly rethrown.

This is preparation for a full 'storage decision' screen during onboarding

* Part of 19552
* Part of 13574
* Part of 20737

Assisted-by: Claude Fable 5
The decision now mirrors whether `getCurrentAnkiDroidDirectory`
is usable or throws.

The path is set during startup (`ensureCollectionPathSet`),
so `Undecided` is only observable if startup storage initialization
failed.

This is now classified as an `InitializationError` and displayed in
the app startup flow (with a TODO for 19552 to improve this).

* Part of 19552
* Part of 13574

Assisted-by: Claude Fable 5
@david-allison
david-allison force-pushed the collection-helper-anki-common branch from 33b2d1a to 9ac0a08 Compare July 6, 2026 23:56

@BrayanDSO BrayanDSO left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the path that is being taken. It makes easier to reason with the initialization logic

Comment on lines +281 to +289
CollectionHelper.storageDecisionTestOverride
?: AnkiDroidApp.sharedPrefsOrNull()?.let { CollectionHelper.storageDecision(it) }
// test-only: in-memory test collections have no preferences and read no path
?: if (isRunningAsUnitTest) {
StorageDecision.Decided
} else {
// the app instance is unset: treat this as a bug.
throw IllegalStateException("Collection accessed before AnkiDroidApp was initialized")
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: maybe this logic should be under CollectionHelper. Maybe not. Sometimes the distinction between CollectionHelper and CollectionManager isn't clear.

@BrayanDSO BrayanDSO added Needs Second Approval Has one approval, one more approval to merge and removed Needs Review labels Jul 15, 2026

@ericli3690 ericli3690 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks fantastic!! Merge at will

* @param preferences the preferences the collection path will be read from: pass the same
* (profile) context's preferences as the [getCurrentAnkiDroidDirectory] call being gated
*
* TODO: What if a user revokes full storage?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To confirm, this TODO will not be a problem once the dedicated setup flow is created and rolled out, right? Should it be added to the issue this PR is linked to?

* Ensures [CollectionHelper.PREF_COLLECTION_PATH] is set, choosing and persisting
* [getDefaultAnkiDroidDirectory] if it is unset.
*
* This decides the storage location on the user's behalf: until a storage setup flow exists

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
* This decides the storage location on the user's behalf: until a storage setup flow exists
* This is a *temporary* function that decides the storage location on the user's behalf, and will be in place until a storage setup flow exists

As I understand it this function is a stopgap until a full storage setup flow exists. I worked with the external permissions stuff a bit a while ago but have now forgotten how it worked; it took me a while to remember / realize that this collection-path-setting method is temporary, perhaps flag that stopgap nature more explicitly in the docstring. Feel free to ignore, might just be me haha

@ericli3690 ericli3690 added Pending Merge Things with approval that are waiting future merge (e.g. targets a future release, CI wait, etc) and removed Needs Second Approval Has one approval, one more approval to merge labels Jul 22, 2026
@david-allison
david-allison added this pull request to the merge queue Jul 22, 2026
Merged via the queue into ankidroid:main with commit 89c9544 Jul 22, 2026
20 checks passed
@github-actions github-actions Bot removed Review High Priority Request for high priority review Pending Merge Things with approval that are waiting future merge (e.g. targets a future release, CI wait, etc) labels Jul 22, 2026
@github-actions github-actions Bot added this to the 2.25 release milestone Jul 22, 2026
@david-allison
david-allison deleted the collection-helper-anki-common branch August 3, 2026 08:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants