Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SES-2107] Optimise SharedPreferences #1554

Open
wants to merge 12 commits into
base: dev
Choose a base branch
from

Conversation

bemusementpark
Copy link

@bemusementpark bemusementpark commented Jul 18, 2024

  1. Remove static references to sharedPrefs that would often do some extra work retrieving or constructing a SharedPrefs object.
  2. Use a common instance of prefs which is easier on resources and mockable in tests.
  3. Create new Pref class that encapsulates a preference key, its type and default value all in one place.
  4. Utilise Flow to observe changes to shared preferences

Why add Pref? Pref is a place to put all of the important info about a preference and adds a degree of type-safety

name
default value
the type is implied by the default (or if the default is null)
Then when we get/set/observe it the type is enforced. The only way to mess it up is if the name of the pref is reused with another type, even in the past... maybe it'd be an idea to wipe all prefs we don't declare... 🤔 that'd be safer.

Why delete the static methods?

The static methods were not mockable
The static methods would create/find/fetch a new SharedPreferences for each call. slow? expensive? probably.
Why remove the interface?

The interface served no purpose as there was no alternative implementations,
the implementation was not in a separate module, it was in the same file.
Why add StateFlows to prefs?

StateFlow has a present value,
StateFlow emits changes

@bemusementpark bemusementpark changed the title Optimise SharedPreferences [SES-2107] Optimise SharedPreferences Jul 19, 2024
Copy link
Collaborator

@AL-Session AL-Session left a comment

Choose a reason for hiding this comment

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

Nice work! Maybe a couple of twiddles depending on if you agree w/ my comments or nah. Happy to approve once I've got that feedback.

@@ -97,7 +97,7 @@ protected void onCreate(Bundle savedInstanceState) {
protected void onResume() {
super.onResume();
initializeScreenshotSecurity(true);
DynamicLanguageActivityHelper.recreateIfNotInCorrectLanguage(this, TextSecurePreferences.getLanguage(this));
DynamicLanguageActivityHelper.recreateIfNotInCorrectLanguage(this, MessagingModuleConfiguration.getShared().getPrefs().getLanguage());
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is it worth putting a... what's the word, um, convenience getter (? I can't think of it - but what I'm after is syntactic sugar!) on this so we can just call MessagingModuleConfiguration.getLanguage() or something?

Same for anything else that calls MessagingModuleConfiguration.getShared().getPrefs() before it's final "give me the thing".

It looks like you have this further down where you just call context.prefs.<something> - is that the same thing?

Copy link
Author

Choose a reason for hiding this comment

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

Yeah, though ideally this is injected, I'll see if I can do that.

haha, yeah context.prefs should be the same thing, but again, if prefs is injected, that's more correct.

I'll look into it.

@@ -74,9 +74,9 @@ public List<String> getNumbersForThreadSearchFilter(Context context, String cons
}

// if (context.getString(R.string.note_to_self).toLowerCase().contains(constraint.toLowerCase()) &&
// !numberList.contains(TextSecurePreferences.getLocalNumber(context)))
// !numberList.contains(MessagingModuleConfiguration.getShared().getPrefs().getLocalNumber(context)))
Copy link
Collaborator

Choose a reason for hiding this comment

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

If we're not using this code maybe remove?

Copy link
Author

Choose a reason for hiding this comment

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

eek, find and replace fixed the commented code 🤔

I'd be tempted to delete.

@@ -125,9 +126,9 @@ public void postKey(SQLiteConnection connection) {
// if not vacuumed in a while, perform that operation
long currentTime = System.currentTimeMillis();
// 7 days
if (currentTime - TextSecurePreferences.getLastVacuumTime(context) > 604_800_000) {
if (currentTime - MessagingModuleConfiguration.getShared().getPrefs().getLastVacuumTime() > 604_800_000) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Out of curiosity, why do you reckon it might be 604,800,000... that's oddly specific, isn't it?

Ah, it's 1 week in milliseconds. Can we use something like 1.weeks.inWholeMilliseconds instead?

Copy link
Author

Choose a reason for hiding this comment

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

totally, that's 604_800_000 x thinking.

Although... I could add a courtesy Pref with an Converter to get/set Durations directly... 🤔

@@ -59,7 +60,7 @@ private void initializeToolbar() {
GiphyActivityToolbar toolbar = ViewUtil.findById(this, R.id.giphy_toolbar);
toolbar.setOnFilterChangedListener(this);
toolbar.setOnLayoutChangedListener(this);
toolbar.setPersistence(GiphyActivityToolbarTextSecurePreferencesPersistence.fromContext(this));
toolbar.setPersistence(new GiphyActivityToolbarTextSecurePreferencesPersistence());
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we make this a static class and just access it without the new?

Copy link
Author

Choose a reason for hiding this comment

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

It's more correct to instantiate, as it needs prefs. I could make this thing get injected itself... and inject its members...

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.

2 participants