diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/KbsValues.java b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/KbsValues.java index 75c8953a56..ca5ebb295c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/KbsValues.java +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/KbsValues.java @@ -12,7 +12,7 @@ import org.whispersystems.signalservice.internal.contacts.entities.TokenResponse import java.io.IOException; import java.security.SecureRandom; -public final class KbsValues { +public final class KbsValues extends SignalStoreValues { public static final String V2_LOCK_ENABLED = "kbs.v2_lock_enabled"; private static final String MASTER_KEY = "kbs.registration_lock_master_key"; @@ -21,10 +21,12 @@ public final class KbsValues { private static final String LOCK_LOCAL_PIN_HASH = "kbs.registration_lock_local_pin_hash"; private static final String LAST_CREATE_FAILED_TIMESTAMP = "kbs.last_create_failed_timestamp"; - private final KeyValueStore store; - KbsValues(KeyValueStore store) { - this.store = store; + super(store); + } + + @Override + void onFirstEverAppLaunch() { } /** @@ -33,13 +35,13 @@ public final class KbsValues { * Should only be called by {@link org.thoughtcrime.securesms.pin.PinState} */ public void clearRegistrationLockAndPin() { - store.beginWrite() - .remove(V2_LOCK_ENABLED) - .remove(TOKEN_RESPONSE) - .remove(LOCK_LOCAL_PIN_HASH) - .remove(PIN) - .remove(LAST_CREATE_FAILED_TIMESTAMP) - .commit(); + getStore().beginWrite() + .remove(V2_LOCK_ENABLED) + .remove(TOKEN_RESPONSE) + .remove(LOCK_LOCAL_PIN_HASH) + .remove(PIN) + .remove(LAST_CREATE_FAILED_TIMESTAMP) + .commit(); } /** Should only be set by {@link org.thoughtcrime.securesms.pin.PinState}. */ @@ -52,43 +54,43 @@ public final class KbsValues { throw new AssertionError(e); } - store.beginWrite() - .putString(TOKEN_RESPONSE, tokenResponse) - .putBlob(MASTER_KEY, masterKey.serialize()) - .putString(LOCK_LOCAL_PIN_HASH, PinHashing.localPinHash(pin)) - .putString(PIN, pin) - .putLong(LAST_CREATE_FAILED_TIMESTAMP, -1) - .commit(); + getStore().beginWrite() + .putString(TOKEN_RESPONSE, tokenResponse) + .putBlob(MASTER_KEY, masterKey.serialize()) + .putString(LOCK_LOCAL_PIN_HASH, PinHashing.localPinHash(pin)) + .putString(PIN, pin) + .putLong(LAST_CREATE_FAILED_TIMESTAMP, -1) + .commit(); } synchronized void setPinIfNotPresent(@NonNull String pin) { - if (store.getString(PIN, null) == null) { - store.beginWrite().putString(PIN, pin).commit(); + if (getStore().getString(PIN, null) == null) { + getStore().beginWrite().putString(PIN, pin).commit(); } } /** Should only be set by {@link org.thoughtcrime.securesms.pin.PinState}. */ public synchronized void setV2RegistrationLockEnabled(boolean enabled) { - store.beginWrite().putBoolean(V2_LOCK_ENABLED, enabled).apply(); + putBoolean(V2_LOCK_ENABLED, enabled); } /** * Whether or not registration lock V2 is enabled. */ public synchronized boolean isV2RegistrationLockEnabled() { - return store.getBoolean(V2_LOCK_ENABLED, false); + return getBoolean(V2_LOCK_ENABLED, false); } /** Should only be set by {@link org.thoughtcrime.securesms.pin.PinState}. */ public synchronized void onPinCreateFailure() { - store.beginWrite().putLong(LAST_CREATE_FAILED_TIMESTAMP, System.currentTimeMillis()).apply(); + putLong(LAST_CREATE_FAILED_TIMESTAMP, System.currentTimeMillis()); } /** * Whether or not the last time the user attempted to create a PIN, it failed. */ public synchronized boolean lastPinCreateFailed() { - return store.getLong(LAST_CREATE_FAILED_TIMESTAMP, -1) > 0; + return getLong(LAST_CREATE_FAILED_TIMESTAMP, -1) > 0; } /** @@ -98,13 +100,13 @@ public final class KbsValues { * If you only want a key when it's backed up, use {@link #getPinBackedMasterKey()}. */ public synchronized @NonNull MasterKey getOrCreateMasterKey() { - byte[] blob = store.getBlob(MASTER_KEY, null); + byte[] blob = getStore().getBlob(MASTER_KEY, null); if (blob == null) { - store.beginWrite() - .putBlob(MASTER_KEY, MasterKey.createNew(new SecureRandom()).serialize()) - .commit(); - blob = store.getBlob(MASTER_KEY, null); + getStore().beginWrite() + .putBlob(MASTER_KEY, MasterKey.createNew(new SecureRandom()).serialize()) + .commit(); + blob = getBlob(MASTER_KEY, null); } return new MasterKey(blob); @@ -119,7 +121,7 @@ public final class KbsValues { } private synchronized @Nullable MasterKey getMasterKey() { - byte[] blob = store.getBlob(MASTER_KEY, null); + byte[] blob = getBlob(MASTER_KEY, null); return blob != null ? new MasterKey(blob) : null; } @@ -133,7 +135,7 @@ public final class KbsValues { } public synchronized @Nullable String getLocalPinHash() { - return store.getString(LOCK_LOCAL_PIN_HASH, null); + return getString(LOCK_LOCAL_PIN_HASH, null); } public synchronized boolean hasPin() { @@ -141,7 +143,7 @@ public final class KbsValues { } public synchronized @Nullable TokenResponse getRegistrationLockTokenResponse() { - String token = store.getString(TOKEN_RESPONSE, null); + String token = getStore().getString(TOKEN_RESPONSE, null); if (token == null) return null; diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/PinValues.java b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/PinValues.java index c3932aa644..c6e22997a2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/PinValues.java +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/PinValues.java @@ -12,7 +12,7 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences; /** * Specifically handles just the UI/UX state around PINs. For actual keys, see {@link KbsValues}. */ -public final class PinValues { +public final class PinValues extends SignalStoreValues { private static final String TAG = Log.tag(PinValues.class); @@ -22,20 +22,22 @@ public final class PinValues { private static final String PIN_STATE = "pin.pin_state"; public static final String PIN_REMINDERS_ENABLED = "pin.pin_reminders_enabled"; - private final KeyValueStore store; - PinValues(KeyValueStore store) { - this.store = store; + super(store); + } + + @Override + void onFirstEverAppLaunch() { } public void onEntrySuccess(@NonNull String pin) { long nextInterval = SignalPinReminders.getNextInterval(getCurrentInterval()); Log.i(TAG, "onEntrySuccess() nextInterval: " + nextInterval); - store.beginWrite() - .putLong(LAST_SUCCESSFUL_ENTRY, System.currentTimeMillis()) - .putLong(NEXT_INTERVAL, nextInterval) - .apply(); + getStore().beginWrite() + .putLong(LAST_SUCCESSFUL_ENTRY, System.currentTimeMillis()) + .putLong(NEXT_INTERVAL, nextInterval) + .apply(); SignalStore.kbsValues().setPinIfNotPresent(pin); } @@ -44,10 +46,10 @@ public final class PinValues { long nextInterval = SignalPinReminders.getPreviousInterval(getCurrentInterval()); Log.i(TAG, "onEntrySuccessWithWrongGuess() nextInterval: " + nextInterval); - store.beginWrite() - .putLong(LAST_SUCCESSFUL_ENTRY, System.currentTimeMillis()) - .putLong(NEXT_INTERVAL, nextInterval) - .apply(); + getStore().beginWrite() + .putLong(LAST_SUCCESSFUL_ENTRY, System.currentTimeMillis()) + .putLong(NEXT_INTERVAL, nextInterval) + .apply(); SignalStore.kbsValues().setPinIfNotPresent(pin); } @@ -56,61 +58,55 @@ public final class PinValues { long nextInterval = SignalPinReminders.getPreviousInterval(getCurrentInterval()); Log.i(TAG, "onEntrySkipWithWrongGuess() nextInterval: " + nextInterval); - store.beginWrite() - .putLong(NEXT_INTERVAL, nextInterval) - .apply(); + putLong(NEXT_INTERVAL, nextInterval); } public void resetPinReminders() { long nextInterval = SignalPinReminders.INITIAL_INTERVAL; Log.i(TAG, "resetPinReminders() nextInterval: " + nextInterval, new Throwable()); - store.beginWrite() - .putLong(NEXT_INTERVAL, nextInterval) - .putLong(LAST_SUCCESSFUL_ENTRY, System.currentTimeMillis()) - .apply(); + getStore().beginWrite() + .putLong(NEXT_INTERVAL, nextInterval) + .putLong(LAST_SUCCESSFUL_ENTRY, System.currentTimeMillis()) + .apply(); } public long getCurrentInterval() { - return store.getLong(NEXT_INTERVAL, TextSecurePreferences.getRegistrationLockNextReminderInterval(ApplicationDependencies.getApplication())); + return getLong(NEXT_INTERVAL, TextSecurePreferences.getRegistrationLockNextReminderInterval(ApplicationDependencies.getApplication())); } public long getLastSuccessfulEntryTime() { - return store.getLong(LAST_SUCCESSFUL_ENTRY, TextSecurePreferences.getRegistrationLockLastReminderTime(ApplicationDependencies.getApplication())); + return getLong(LAST_SUCCESSFUL_ENTRY, TextSecurePreferences.getRegistrationLockLastReminderTime(ApplicationDependencies.getApplication())); } public void setKeyboardType(@NonNull PinKeyboardType keyboardType) { - store.beginWrite() - .putString(KEYBOARD_TYPE, keyboardType.getCode()) - .commit(); + putString(KEYBOARD_TYPE, keyboardType.getCode()); } public void setPinRemindersEnabled(boolean enabled) { - store.beginWrite().putBoolean(PIN_REMINDERS_ENABLED, enabled).apply(); + putBoolean(PIN_REMINDERS_ENABLED, enabled); } public boolean arePinRemindersEnabled() { - return store.getBoolean(PIN_REMINDERS_ENABLED, true); + return getBoolean(PIN_REMINDERS_ENABLED, true); } public @NonNull PinKeyboardType getKeyboardType() { - return PinKeyboardType.fromCode(store.getString(KEYBOARD_TYPE, null)); + return PinKeyboardType.fromCode(getStore().getString(KEYBOARD_TYPE, null)); } public void setNextReminderIntervalToAtMost(long maxInterval) { - if (store.getLong(NEXT_INTERVAL, 0) > maxInterval) { - store.beginWrite() - .putLong(NEXT_INTERVAL, maxInterval) - .apply(); + if (getStore().getLong(NEXT_INTERVAL, 0) > maxInterval) { + putLong(NEXT_INTERVAL, maxInterval); } } /** Should only be set by {@link org.thoughtcrime.securesms.pin.PinState} */ public void setPinState(@NonNull String pinState) { - store.beginWrite().putString(PIN_STATE, pinState).commit(); + getStore().beginWrite().putString(PIN_STATE, pinState).commit(); } public @Nullable String getPinState() { - return store.getString(PIN_STATE, null); + return getString(PIN_STATE, null); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/RegistrationValues.java b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/RegistrationValues.java index 72db1774f6..6028046235 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/RegistrationValues.java +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/RegistrationValues.java @@ -3,22 +3,20 @@ package org.thoughtcrime.securesms.keyvalue; import androidx.annotation.CheckResult; import androidx.annotation.NonNull; -public final class RegistrationValues { +public final class RegistrationValues extends SignalStoreValues { private static final String REGISTRATION_COMPLETE = "registration.complete"; private static final String PIN_REQUIRED = "registration.pin_required"; - private final KeyValueStore store; - RegistrationValues(@NonNull KeyValueStore store) { - this.store = store; + super(store); } public synchronized void onFirstEverAppLaunch() { - store.beginWrite() - .putBoolean(REGISTRATION_COMPLETE, false) - .putBoolean(PIN_REQUIRED, true) - .commit(); + getStore().beginWrite() + .putBoolean(REGISTRATION_COMPLETE, false) + .putBoolean(PIN_REQUIRED, true) + .commit(); } public synchronized void clearRegistrationComplete() { @@ -26,18 +24,18 @@ public final class RegistrationValues { } public synchronized void setRegistrationComplete() { - store.beginWrite() - .putBoolean(REGISTRATION_COMPLETE, true) - .commit(); + getStore().beginWrite() + .putBoolean(REGISTRATION_COMPLETE, true) + .commit(); } @CheckResult public synchronized boolean pinWasRequiredAtRegistration() { - return store.getBoolean(PIN_REQUIRED, false); + return getStore().getBoolean(PIN_REQUIRED, false); } @CheckResult public synchronized boolean isRegistrationComplete() { - return store.getBoolean(REGISTRATION_COMPLETE, true); + return getStore().getBoolean(REGISTRATION_COMPLETE, true); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/RemoteConfigValues.java b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/RemoteConfigValues.java index 5da9d45964..1f96c73ea6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/RemoteConfigValues.java +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/RemoteConfigValues.java @@ -1,8 +1,10 @@ package org.thoughtcrime.securesms.keyvalue; +import androidx.annotation.NonNull; + import org.thoughtcrime.securesms.logging.Log; -public final class RemoteConfigValues { +public final class RemoteConfigValues extends SignalStoreValues { private static final String TAG = Log.tag(RemoteConfigValues.class); @@ -10,33 +12,35 @@ public final class RemoteConfigValues { private static final String PENDING_CONFIG = "pending_remote_config"; private static final String LAST_FETCH_TIME = "remote_config_last_fetch_time"; - private final KeyValueStore store; + RemoteConfigValues(@NonNull KeyValueStore store) { + super(store); + } - RemoteConfigValues(KeyValueStore store) { - this.store = store; + @Override + void onFirstEverAppLaunch() { } public String getCurrentConfig() { - return store.getString(CURRENT_CONFIG, null); + return getString(CURRENT_CONFIG, null); } public void setCurrentConfig(String value) { - store.beginWrite().putString(CURRENT_CONFIG, value).apply(); + putString(CURRENT_CONFIG, value); } public String getPendingConfig() { - return store.getString(PENDING_CONFIG, getCurrentConfig()); + return getString(PENDING_CONFIG, getCurrentConfig()); } public void setPendingConfig(String value) { - store.beginWrite().putString(PENDING_CONFIG, value).apply(); + putString(PENDING_CONFIG, value); } public long getLastFetchTime() { - return store.getLong(LAST_FETCH_TIME, 0); + return getLong(LAST_FETCH_TIME, 0); } public void setLastFetchTime(long time) { - store.beginWrite().putLong(LAST_FETCH_TIME, time).apply(); + putLong(LAST_FETCH_TIME, time); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SignalStore.java b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SignalStore.java index e48f72d058..bd8460f7ff 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SignalStore.java +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SignalStore.java @@ -15,7 +15,27 @@ public final class SignalStore { private static final String LAST_PREKEY_REFRESH_TIME = "last_prekey_refresh_time"; private static final String MESSAGE_REQUEST_ENABLE_TIME = "message_request_enable_time"; - private SignalStore() {} + private static final SignalStore INSTANCE = new SignalStore(); + + private final KeyValueStore store; + private final KbsValues kbsValues; + private final RegistrationValues registrationValues; + private final PinValues pinValues; + private final RemoteConfigValues remoteConfigValues; + private final StorageServiceValues storageServiceValues; + private final UiHints uiHints; + private final TooltipValues tooltipValues; + + private SignalStore() { + this.store = ApplicationDependencies.getKeyValueStore(); + this.kbsValues = new KbsValues(store); + this.registrationValues = new RegistrationValues(store); + this.pinValues = new PinValues(store); + this.remoteConfigValues = new RemoteConfigValues(store); + this.storageServiceValues = new StorageServiceValues(store); + this.uiHints = new UiHints(store); + this.tooltipValues = new TooltipValues(store); + } public static void onFirstEverAppLaunch() { registrationValues().onFirstEverAppLaunch(); @@ -24,31 +44,31 @@ public final class SignalStore { } public static @NonNull KbsValues kbsValues() { - return new KbsValues(getStore()); + return INSTANCE.kbsValues; } public static @NonNull RegistrationValues registrationValues() { - return new RegistrationValues(getStore()); + return INSTANCE.registrationValues; } public static @NonNull PinValues pinValues() { - return new PinValues(getStore()); + return INSTANCE.pinValues; } public static @NonNull RemoteConfigValues remoteConfigValues() { - return new RemoteConfigValues(getStore()); + return INSTANCE.remoteConfigValues; } public static @NonNull StorageServiceValues storageServiceValues() { - return new StorageServiceValues(getStore()); + return INSTANCE.storageServiceValues; } public static @NonNull UiHints uiHints() { - return new UiHints(getStore()); + return INSTANCE.uiHints; } public static @NonNull TooltipValues tooltips() { - return new TooltipValues(getStore()); + return INSTANCE.tooltipValues; } public static @NonNull GroupsV2AuthorizationSignalStoreCache groupsV2AuthorizationCache() { @@ -84,7 +104,7 @@ public final class SignalStore { } private static @NonNull KeyValueStore getStore() { - return ApplicationDependencies.getKeyValueStore(); + return INSTANCE.store; } private static void putBlob(@NonNull String key, byte[] value) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SignalStoreValues.java b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SignalStoreValues.java new file mode 100644 index 0000000000..02557064ce --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SignalStoreValues.java @@ -0,0 +1,66 @@ +package org.thoughtcrime.securesms.keyvalue; + +import androidx.annotation.NonNull; + +abstract class SignalStoreValues { + + private final KeyValueStore store; + + SignalStoreValues(@NonNull KeyValueStore store) { + this.store = store; + } + + @NonNull KeyValueStore getStore() { + return store; + } + + abstract void onFirstEverAppLaunch(); + + String getString(String key, String defaultValue) { + return store.getString(key, defaultValue); + } + + int getInteger(String key, int defaultValue) { + return store.getInteger(key, defaultValue); + } + + long getLong(String key, long defaultValue) { + return store.getLong(key, defaultValue); + } + + boolean getBoolean(String key, boolean defaultValue) { + return store.getBoolean(key, defaultValue); + } + + float getFloat(String key, float defaultValue) { + return store.getFloat(key, defaultValue); + } + + byte[] getBlob(String key, byte[] defaultValue) { + return store.getBlob(key, defaultValue); + } + + void putBlob(@NonNull String key, byte[] value) { + store.beginWrite().putBlob(key, value).apply(); + } + + void putBoolean(@NonNull String key, boolean value) { + store.beginWrite().putBoolean(key, value).apply(); + } + + void putFloat(@NonNull String key, float value) { + store.beginWrite().putFloat(key, value).apply(); + } + + void putInteger(@NonNull String key, int value) { + store.beginWrite().putInteger(key, value).apply(); + } + + void putLong(@NonNull String key, long value) { + store.beginWrite().putLong(key, value).apply(); + } + + void putString(@NonNull String key, String value) { + store.beginWrite().putString(key, value).apply(); + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/StorageServiceValues.java b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/StorageServiceValues.java index 1c48457dea..31fe8eaaf6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/StorageServiceValues.java +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/StorageServiceValues.java @@ -8,15 +8,17 @@ import org.whispersystems.signalservice.api.storage.StorageKey; import java.security.SecureRandom; -public class StorageServiceValues { +public class StorageServiceValues extends SignalStoreValues { private static final String LAST_SYNC_TIME = "storage.last_sync_time"; private static final String NEEDS_ACCOUNT_RESTORE = "storage.needs_account_restore"; - private final KeyValueStore store; - StorageServiceValues(@NonNull KeyValueStore store) { - this.store = store; + super(store); + } + + @Override + void onFirstEverAppLaunch() { } public synchronized StorageKey getOrCreateStorageKey() { @@ -24,18 +26,18 @@ public class StorageServiceValues { } public long getLastSyncTime() { - return store.getLong(LAST_SYNC_TIME, 0); + return getLong(LAST_SYNC_TIME, 0); } public void onSyncCompleted() { - store.beginWrite().putLong(LAST_SYNC_TIME, System.currentTimeMillis()).apply(); + putLong(LAST_SYNC_TIME, System.currentTimeMillis()); } public boolean needsAccountRestore() { - return store.getBoolean(NEEDS_ACCOUNT_RESTORE, false); + return getBoolean(NEEDS_ACCOUNT_RESTORE, false); } public void setNeedsAccountRestore(boolean value) { - store.beginWrite().putBoolean(NEEDS_ACCOUNT_RESTORE, value).apply(); + putBoolean(NEEDS_ACCOUNT_RESTORE, value); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/TooltipValues.java b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/TooltipValues.java index 0fb8741f18..d496416a0e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/TooltipValues.java +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/TooltipValues.java @@ -4,24 +4,23 @@ import androidx.annotation.NonNull; import org.whispersystems.signalservice.api.storage.StorageKey; -public class TooltipValues { +public class TooltipValues extends SignalStoreValues { private static final String BLUR_HUD_ICON = "tooltip.blur_hud_icon"; - private final KeyValueStore store; - TooltipValues(@NonNull KeyValueStore store) { - this.store = store; + super(store); } + @Override public void onFirstEverAppLaunch() { } public boolean hasSeenBlurHudIconTooltip() { - return store.getBoolean(BLUR_HUD_ICON, false); + return getBoolean(BLUR_HUD_ICON, false); } public void markBlurHudIconTooltipSeen() { - store.beginWrite().putBoolean(BLUR_HUD_ICON, true).apply(); + putBoolean(BLUR_HUD_ICON, true); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/UiHints.java b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/UiHints.java index 3a4ad72526..ab4414c166 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/UiHints.java +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/UiHints.java @@ -1,24 +1,25 @@ package org.thoughtcrime.securesms.keyvalue; -public class UiHints { +import androidx.annotation.NonNull; + +public class UiHints extends SignalStoreValues { private static final String HAS_SEEN_GROUP_SETTINGS_MENU_TOAST = "uihints.has_seen_group_settings_menu_toast"; - private final KeyValueStore store; - - UiHints(KeyValueStore store) { - this.store = store; + UiHints(@NonNull KeyValueStore store) { + super(store); } + @Override void onFirstEverAppLaunch() { markHasSeenGroupSettingsMenuToast(); } public void markHasSeenGroupSettingsMenuToast() { - store.beginWrite().putBoolean(HAS_SEEN_GROUP_SETTINGS_MENU_TOAST, true).apply(); + putBoolean(HAS_SEEN_GROUP_SETTINGS_MENU_TOAST, true); } public boolean hasSeenGroupSettingsMenuToast() { - return store.getBoolean(HAS_SEEN_GROUP_SETTINGS_MENU_TOAST, false); + return getBoolean(HAS_SEEN_GROUP_SETTINGS_MENU_TOAST, false); } }