[Debug drawer][Secret Settings Manager] Investigate how to best migrate our existing preferences to DataStore + Compose
Categories
(Fenix :: Tooling, task, P2)
Tracking
(Not tracked)
People
(Reporter: 007, Assigned: 007)
References
(Blocks 1 open bug)
Details
(Whiteboard: [fxdroid][group4])
Currently, we use XML preferences, settings fragments, and a master Settings
singleton to manage our preferences. Investigate some new best practices for handling preferences in Compose and how to keep our preferences UI (roughly) in sync between debug drawer and the existing settings flow.
After this ticket:
- Have a path forward identified
- Have the first round of tickets filed
Updated•11 months ago
|
Assignee | ||
Updated•9 months ago
|
Assignee | ||
Updated•9 months ago
|
Assignee | ||
Comment 1•9 months ago
•
|
||
Secret settings audit
Setting | Type | Release flavors |
---|---|---|
Third party CA certificates | Toggle | All |
Nimbus Preview Collection | Toggle | All |
Tabs Tray to compose rewrite enable | Toggle | All |
Compose Top Sites enable | Toggle | Nightly/Debug |
Toolbar redesign | Toggle | Debug |
Translations | Toggle | Debug (flag) |
Suggest | Toggle | All |
Felt Privacy | Toggle | All |
Debug Drawer | Toggle | All |
Custom Glean server | Textfield | Nightly/Debug |
Pocket sponsored stories | Sub-navigation with multiple sub settings | Nightly/Debug |
Pocket sponsored stories
Setting | Type | Release flavors |
---|---|---|
Enable | Toggle | Nightly/Debug |
Site parameter | Textfield | Nightly/Debug |
Country parameter | Textfield | Nightly/Debug |
City parameter | Textfield | Nightly/Debug |
Assignee | ||
Comment 2•9 months ago
•
|
||
Secret Settings Migration Plan
Goals
- Have a migration/refactor path investigated for the rest of our
Settings.kt
mega singleton (megaton?). - Create the remaining design components for Settings.
- Create a reusable component for settings that have sub pages (like the Pocket parameters in Secret Settings).
- The Secret Settings UI is 100% Compose and is available within the Debug Drawer.
Plan of attack
Investigate the migration of existing preference values
- Is the migration one-and-done?
- A one-and-done migration would mean that the preferences within Fenix's SharedPreferences file are removed,
- Based on this Google Code Lab, the migration looks to be one-and-done by default, so we likely can't do a proper migration with the base API while keeping the preference usages in
Settings.kt
. (see comment below for a potential solution)
- Would the migration code need to live in the codebase until we feel confident all users have migrated?
- Would the migration code need to be 100% completed for each subset of preferences before enabling in Nightly?
- Would this have to be feature flagged to Local/Debug builds?
- What happens to the
Settings.kt
usages after a migration?
- How do we keep the XML preferences in-sync with the migrated DataStore values for the pre-existing
Settings.kt
preferences?- Would this still require writing the preference twice for legacy preferences until
Settings.kt
is removed?
- Would this still require writing the preference twice for legacy preferences until
- Should a migration helper be instantiated for each preference, or for a group of preferences?
- Individual for each solo preference but a group for something like Pocket?
- One helper per phase of migration (so one in this instance)?
DataStore stand-up
- Create a new DataStore to manage preferences that mirror feature flags.
- Add an API to observe ALL debug settings (i.e. create a data model for the use case that all or most debug preferences need to be observed on a single screen).
Preference migration
Stand-up migration code
Add the migration code shell to DebugSettingsRepository
. (see comment below)
UI Stand-up
- Create
SecretSettings
Composable for all of the preferences to live in. - Plug
SecretSettings
into the Debug Drawer. - Create any remaining design components related to settings
Switch
TextField
- Settings with sub pages for multiple parameters (Pocket)
Debug Drawer feature flag (migration path proof of concept)
- Refactor the Debug Drawer debug setting to follow the migration path.
- Add debug drawer flag toggle to the
SecretSettings
Composable. - Validate the XML and DataStore are kept in sync.
Feature flag preferences
- Create the preference within the feature flag DataStore using the EXACT key string used in the XML preference.
- Include the migration code in the read
Flow
accessor. - Include a
Settings.kt
write in the DataStore write? (In order to keep the existing XML preference working)
- Include the migration code in the read
- Add the setting to the
SecretSettings
Composable and validate it using the Debug Drawer. - Add a
@Deprecated
annotation to the preference's instance inSettings.kt
.
Debug-specific preferences
- Create the preference within the debug settings DataStore using the EXACT key string used in the XML preference.
- Include the migration code in the read
Flow
accessor. - Include a
Settings.kt
write in the DataStore write? (In order to keep the existing XML preference working)
- Include the migration code in the read
- Add the setting to the
SecretSettings
Composable and validate it using the Debug Drawer. - Add a
@Deprecated
annotation to the preference's instance inSettings.kt
.
Clean-up
- Replace the XML UI with the rewritten Compose UI.
- Remove any feature flags (if any were needed).
- (When we feel the migration has had enough time to bake) Remove the migration code from the data stores used in secret settings.
Stewardship follow-ups
- Write documentation and provide an example of how to new future secret settings going forward.
- Write-up some lessons learned and suggestions for the major
Settings.kt
clean-up and the migration of the rest of Fenix's preferences.
Links
- DebugSettingsRepository, the existing data store that manages the debug drawer secret setting.
- YoutTube video covering a code walkthrough of the debug drawer, including the DataStore preference.
- Google CodeLab
Assignee | ||
Comment 3•9 months ago
•
|
||
Potential Code Samples
Preference Migration helper WITHOUT the shared preferences clean-up from the base API
class FenixPreferencesMigration(
private val cleanUpPreferences: Boolean = false,
context: Context,
sharedPreferencesName: String,
keysToMigrate: Set<String> = mutableSetOf(),
) : DataMigration<Preferences> {
private val sharedPreferencesMigration = SharedPreferencesMigration(
context = context,
sharedPreferencesName = sharedPreferencesName,
keysToMigrate = keysToMigrate,
)
override suspend fun migrate(currentData: Preferences): Preferences {
return sharedPreferencesMigration.migrate(currentData = currentData)
}
override suspend fun shouldMigrate(currentData: Preferences): Boolean {
return sharedPreferencesMigration.shouldMigrate(currentData = currentData)
}
override suspend fun cleanUp() {
// DO NOT clean-up the SharedPreferences until all of the preferences have been migrated to
// DataStore AND their usages within [Settings] have been removed.
if (cleanUpPreferences) {
sharedPreferencesMigration.cleanUp()
}
}
}
DataStore example with migration helper
private val Context.debugSettings2: DataStore<Preferences> by preferencesDataStore(
name = "debug_settings_2",
produceMigrations = { context ->
listOf(
FenixPreferencesMigration(
cleanUpPreferences = false,
context = context,
sharedPreferencesName = Settings.FENIX_PREFERENCES,
keysToMigrate = setOf(
context.getString(R.string.pref_key_enable_debug_drawer),
),
)
)
},
)
Preference read accounting for migration
Assignee | ||
Updated•8 months ago
|
Assignee | ||
Comment 4•8 months ago
|
||
After receiving feedback, the plan is to:
- Close this ticket
- File all of the (currently projected) work task tickets under the meta, Bug 1860913
- Work on tasks as there is time, and whenever the
Settings.kt
migration tech fundamental is official prioritized.
Comment 5•7 months ago
•
|
||
For your migration questions
2. We can use telemetry to find out how many users are still being migrated daily. Once that number approaches 0, we can consider removing the migration code.
3. If we want to quickly migrate, we can first use Settings.kt to migrate everything then remove Settings.kt after the initial change for migration. Since migration takes time, I think we should first start on migration work.
Assignee | ||
Comment 6•3 months ago
|
||
I have filed the immediate work tickets that can bring us incrementally towards completing this project, and I am closing this ticket as completed.
https://bugzilla.mozilla.org/showdependencytree.cgi?id=1860913
Description
•