doc: Multi-Profile system documentation#20751
doc: Multi-Profile system documentation#20751criticalAY wants to merge 1 commit intoankidroid:mainfrom
Conversation
|
|
||
| | Term | What it is | Where it lives | | ||
| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---| | ||
| | **ProfileId** | Immutable string identifier. Either the literal `"default"` or `"p_" + 8 hex chars` (e.g. `p_a1b2c3d4`). Used as the folder name on disk. **Never the user's display name.** | In-memory; persisted as a key in the global registry. | |
There was a problem hiding this comment.
ProfileId isn't really just in-memory, it's also on in-disk identifier, and stored in the Global Profile Registry
| | **ProfileId** | Immutable string identifier. Either the literal `"default"` or `"p_" + 8 hex chars` (e.g. `p_a1b2c3d4`). Used as the folder name on disk. **Never the user's display name.** | In-memory; persisted as a key in the global registry. | | ||
| | **ProfileMetadata** | User-visible data about a profile: `displayName`, `version`, `createdTimestamp`. Serialized as JSON. | Value stored under the ProfileId key in the global registry. | | ||
| | **Global Profile Registry** | A single `SharedPreferences` file shared across the whole app. Contains the registered profiles (ProfileId -> metadata JSON) and the bookkeeping key `last_active_profile_id`. | `shared_prefs/profiles_prefs.xml` | | ||
| | **Profile-namespaced SharedPreferences** | The normal per-profile user settings (sync key, username, deckPath, deck options, etc.). Every pref file is prefixed with `profile_<profileId>_` by `ProfileContextWrapper`, so profiles cannot see each other's settings. | `shared_prefs/profile_<profileId>_*.xml` | |
There was a problem hiding this comment.
Every pref file
Maybe 'filename'?
|
|
||
| ## Global Profile Registry | ||
|
|
||
| Stored in `shared_prefs/profiles_prefs.xml`. Conceptually: |
There was a problem hiding this comment.
Be clear here and above: use the full path of shared_prefs/profiles_prefs.xml
| ├── p_a1b2c3d4 = {"displayName":"Alice", "version":1, "created":"2026-01-15T08:24:00Z"} | ||
| └── p_e5f6g7h8 = {"displayName":"Bob", "version":1, "created":"2026-02-03T14:10:00Z"} | ||
|
|
||
| Everything else about a profile (its files, its settings, its collection) is derived from the ProfileId key and lives elsewhere on disk. |
There was a problem hiding this comment.
Add a TODO: There is a solid rationale for moving the sync username and hkey here (from memory, upstream does this, AND it means we can show the associated AnkiWeb account on the select profile screen)
| ├── databases/ # Default profile (legacy layout) | ||
| ├── files/ # Default profile (legacy layout) | ||
| ├── cache/ # Default profile (legacy layout) | ||
| ├── p_a1b2c3d4/ # Alice's profile root (ProfileId, not display name) |
There was a problem hiding this comment.
Consider moving profiles to a /profiles/ directory so the folders don't pollute the namespace
|
|
||
| ## External storage (`/storage/emulated/0/Android/data/<pkg>/files/`) | ||
|
|
||
| This is where the actual Anki collections live (`collection.anki2`, `collection.media/`, backups). The location is controlled by `PREF_COLLECTION_PATH` (the `"deckPath"` preference) inside each profile's namespaced preferences. |
There was a problem hiding this comment.
Note that this can be any location on non-Play variants of the app
/storage/emulated/0/AnkiDroid is the default
|
|
||
| ### Profile Deletion | ||
|
|
||
| Deletion follows a **disk-first, registry-last** pattern: if the app crashes mid-way, the registry entry still points at the remaining files so the user can retry cleanup. |
There was a problem hiding this comment.
Add a warning here for security:
- If AnkiDroid is using
MANAGE_EXTERNAL_STORAGE - Then AnkiDroid could be used to delete arbitrary files on-disk
Purpose / Description
Document how mulit-profile works and how the folder structure looks like
Fixes
NA
Approach
NA
How Has This Been Tested?
NA
Learning (optional, can help others)
Always document first so that we don't mess up later
Checklist
Please, go through these checks before submitting the PR.