diff --git a/app/src/androidTest/java/network/loki/messenger/HomeActivityTests.kt b/app/src/androidTest/java/network/loki/messenger/HomeActivityTests.kt index af1d8f6d222..d39ec624e32 100644 --- a/app/src/androidTest/java/network/loki/messenger/HomeActivityTests.kt +++ b/app/src/androidTest/java/network/loki/messenger/HomeActivityTests.kt @@ -100,7 +100,7 @@ class HomeActivityTests { // PN select if (hasViewedSeed) { // has viewed seed is set to false after register activity - TextSecurePreferences.setHasViewedSeed(InstrumentationRegistry.getInstrumentation().targetContext, true) + context.prefs.setHasViewedSeed(InstrumentationRegistry.getInstrumentation().targetContext, true) } // allow notification permission PermissionGranter.allowPermissionsIfNeeded(Manifest.permission.POST_NOTIFICATIONS) @@ -149,7 +149,7 @@ class HomeActivityTests { fun testChat_withSelf() { setupLoggedInState() goToMyChat() - TextSecurePreferences.setLinkPreviewsEnabled(context, true) + context.prefs.setLinkPreviewsEnabled(context, true) sendMessage("howdy") sendMessage("test") // tests url rewriter doesn't crash @@ -161,7 +161,7 @@ class HomeActivityTests { fun testChat_displaysCorrectUrl() { setupLoggedInState() goToMyChat() - TextSecurePreferences.setLinkPreviewsEnabled(InstrumentationRegistry.getInstrumentation().targetContext, true) + context.prefs.setLinkPreviewsEnabled(InstrumentationRegistry.getInstrumentation().targetContext, true) // given the link url text val url = "https://www.ámazon.com" sendMessage(url, LinkPreview(url, "amazon", Optional.absent())) diff --git a/app/src/androidTest/java/network/loki/messenger/LibSessionTests.kt b/app/src/androidTest/java/network/loki/messenger/LibSessionTests.kt index 54470569e19..720c9731bca 100644 --- a/app/src/androidTest/java/network/loki/messenger/LibSessionTests.kt +++ b/app/src/androidTest/java/network/loki/messenger/LibSessionTests.kt @@ -27,6 +27,7 @@ import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.snode.SnodeAPI import org.session.libsession.utilities.Address import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs import org.session.libsignal.utilities.KeyHelper import org.session.libsignal.utilities.hexEncodedPublicKey import org.thoughtcrime.securesms.ApplicationContext @@ -82,18 +83,14 @@ class LibSessionTests { @Before fun setupUser() { - PreferenceManager.getDefaultSharedPreferences(InstrumentationRegistry.getInstrumentation().targetContext.applicationContext).edit { - putBoolean(TextSecurePreferences.HAS_FORCED_NEW_CONFIG, true).apply() - } val newBytes = randomSeedBytes().toByteArray() val context = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext val kp = KeyPairUtilities.generate(newBytes) KeyPairUtilities.store(context, kp.seed, kp.ed25519KeyPair, kp.x25519KeyPair) val registrationID = KeyHelper.generateRegistrationId(false) - TextSecurePreferences.setLocalRegistrationId(context, registrationID) - TextSecurePreferences.setLocalNumber(context, kp.x25519KeyPair.hexEncodedPublicKey) - TextSecurePreferences.setRestorationTime(context, 0) - TextSecurePreferences.setHasViewedSeed(context, false) + context.prefs.setLocalRegistrationId(registrationID) + context.prefs.setLocalNumber(kp.x25519KeyPair.hexEncodedPublicKey) + context.prefs.setHasViewedSeed(false) } @Test diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index d306db50b59..878e052cedf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -110,7 +110,6 @@ import dagger.hilt.EntryPoints; import dagger.hilt.android.HiltAndroidApp; import kotlin.Unit; -import kotlinx.coroutines.Job; import network.loki.messenger.BuildConfig; import network.loki.messenger.libsession_util.ConfigBase; import network.loki.messenger.libsession_util.UserProfile; @@ -152,18 +151,9 @@ public class ApplicationContext extends Application implements DefaultLifecycleO @Inject ConfigFactory configFactory; @Inject LastSentTimestampCache lastSentTimestampCache; CallMessageProcessor callMessageProcessor; - MessagingModuleConfiguration messagingModuleConfiguration; private volatile boolean isAppVisible; - @Override - public Object getSystemService(String name) { - if (MessagingModuleConfiguration.MESSAGING_MODULE_SERVICE.equals(name)) { - return messagingModuleConfiguration; - } - return super.getSystemService(name); - } - public static ApplicationContext getInstance(Context context) { return (ApplicationContext) context.getApplicationContext(); } @@ -212,20 +202,19 @@ public void onCreate() { TextSecurePreferences.setPushSuffix(BuildConfig.PUSH_KEY_SUFFIX); DatabaseModule.init(this); - MessagingModuleConfiguration.configure(this); super.onCreate(); // we need to clear the snode and onionrequest databases once on first launch // in order to apply a patch that adds a version number to the Snode objects. - if(!TextSecurePreferences.hasAppliedPatchSnodeVersion(this)) { + if(!getPrefs().getHasAppliedPatchSnodeVersion()) { ThreadUtils.queue(() -> { lokiAPIDatabase.clearSnodePool(); lokiAPIDatabase.clearOnionRequestPaths(); - TextSecurePreferences.setHasAppliedPatchSnodeVersion(this, true); + getPrefs().setHasAppliedPatchSnodeVersion(true); }); } - messagingModuleConfiguration = new MessagingModuleConfiguration( + MessagingModuleConfiguration.shared = new MessagingModuleConfiguration( this, storage, device, @@ -440,12 +429,12 @@ private void initializeBlobProvider() { @Override protected void attachBaseContext(Context base) { initializeLocaleParser(); - super.attachBaseContext(DynamicLanguageContextWrapper.updateContext(base, TextSecurePreferences.getLanguage(base))); + super.attachBaseContext(DynamicLanguageContextWrapper.updateContext(base, new TextSecurePreferences(base).getLanguage())); } private static class ProviderInitializationException extends RuntimeException { } private void setUpPollingIfNeeded() { - String userPublicKey = TextSecurePreferences.getLocalNumber(this); + String userPublicKey = textSecurePreferences.getLocalNumber(); if (userPublicKey == null) return; if (poller != null) { poller.setUserPublicKey(userPublicKey); @@ -472,15 +461,15 @@ public void retrieveUserProfile() { private void resubmitProfilePictureIfNeeded() { // Files expire on the file server after a while, so we simply re-upload the user's profile picture // at a certain interval to ensure it's always available. - String userPublicKey = TextSecurePreferences.getLocalNumber(this); + String userPublicKey = textSecurePreferences.getLocalNumber(); if (userPublicKey == null) return; long now = new Date().getTime(); - long lastProfilePictureUpload = TextSecurePreferences.getLastProfilePictureUpload(this); + long lastProfilePictureUpload = textSecurePreferences.getLastProfilePictureUpload(); if (now - lastProfilePictureUpload <= 14 * 24 * 60 * 60 * 1000) return; ThreadUtils.queue(() -> { // Don't generate a new profile key here; we do that when the user changes their profile picture Log.d("Loki-Avatar", "Uploading Avatar Started"); - String encodedProfileKey = TextSecurePreferences.getProfileKey(ApplicationContext.this); + String encodedProfileKey = textSecurePreferences.getProfileKey(); try { // Read the file into a byte array InputStream inputStream = AvatarHelper.getInputStreamFor(ApplicationContext.this, Address.fromSerialized(userPublicKey)); @@ -495,7 +484,7 @@ private void resubmitProfilePictureIfNeeded() { // Re-upload it ProfilePictureUtilities.INSTANCE.upload(profilePicture, encodedProfileKey, ApplicationContext.this).success(unit -> { // Update the last profile picture upload date - TextSecurePreferences.setLastProfilePictureUpload(ApplicationContext.this, new Date().getTime()); + textSecurePreferences.setLastProfilePictureUpload(new Date().getTime()); Log.d("Loki-Avatar", "Uploading Avatar Finished"); return Unit.INSTANCE; }); @@ -527,7 +516,7 @@ private void loadEmojiSearchIndexIfNeeded() { */ @SuppressLint("ApplySharedPref") public boolean clearAllData() { - TextSecurePreferences.clearAll(this); + getPrefs().clearAll(); getSharedPreferences(PREFERENCES_NAME, 0).edit().clear().commit(); if (!deleteDatabase(SQLCipherOpenHelper.DATABASE_NAME)) { Log.d("Loki", "Failed to delete database."); diff --git a/app/src/main/java/org/thoughtcrime/securesms/BaseActionBarActivity.java b/app/src/main/java/org/thoughtcrime/securesms/BaseActionBarActivity.java index a99fe83430a..76bd7fb2ef3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/BaseActionBarActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/BaseActionBarActivity.java @@ -1,7 +1,6 @@ package org.thoughtcrime.securesms; import static android.os.Build.VERSION.SDK_INT; -import static org.session.libsession.utilities.TextSecurePreferences.SELECTED_ACCENT_COLOR; import android.app.ActivityManager; import android.content.Context; @@ -16,6 +15,7 @@ import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AppCompatActivity; +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsession.utilities.TextSecurePreferences; import org.session.libsession.utilities.dynamiclanguage.DynamicLanguageActivityHelper; import org.session.libsession.utilities.dynamiclanguage.DynamicLanguageContextWrapper; @@ -61,7 +61,7 @@ private int getDesiredTheme() { @StyleRes @Nullable private Integer getAccentTheme() { - if (!getPreferences().hasPreference(SELECTED_ACCENT_COLOR)) return null; + if (!getPreferences().hasSelectedAccentColor()) return null; ThemeState themeState = ActivityUtilitiesKt.themeState(getPreferences()); return themeState.getAccentStyle(); } @@ -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()); String name = getResources().getString(R.string.app_name); Bitmap icon = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_foreground); int color = getResources().getColor(R.color.app_icon_background); @@ -130,7 +130,7 @@ private void initializeScreenshotSecurity(boolean isResume) { if (!isResume) { getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE); } else { - if (TextSecurePreferences.isScreenSecurityEnabled(this)) { + if (MessagingModuleConfiguration.getShared().getPrefs().isScreenSecurityEnabled()) { getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE); } else { getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE); @@ -140,6 +140,6 @@ private void initializeScreenshotSecurity(boolean isResume) { @Override protected void attachBaseContext(Context newBase) { - super.attachBaseContext(DynamicLanguageContextWrapper.updateContext(newBase, TextSecurePreferences.getLanguage(newBase))); + super.attachBaseContext(DynamicLanguageContextWrapper.updateContext(newBase, MessagingModuleConfiguration.getShared().getPrefs().getLanguage())); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/BaseActivity.java b/app/src/main/java/org/thoughtcrime/securesms/BaseActivity.java deleted file mode 100644 index d5286698cdd..00000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/BaseActivity.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.thoughtcrime.securesms; - -import android.app.ActivityManager; -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.os.Build; -import android.os.Build.VERSION; -import android.os.Build.VERSION_CODES; -import androidx.annotation.NonNull; -import androidx.fragment.app.FragmentActivity; -import android.view.KeyEvent; - -import org.session.libsession.utilities.TextSecurePreferences; -import org.session.libsession.utilities.dynamiclanguage.DynamicLanguageActivityHelper; -import org.session.libsession.utilities.dynamiclanguage.DynamicLanguageContextWrapper; - -import network.loki.messenger.R; - -public abstract class BaseActivity extends FragmentActivity { - @Override - protected void onResume() { - super.onResume(); - DynamicLanguageActivityHelper.recreateIfNotInCorrectLanguage(this, TextSecurePreferences.getLanguage(this)); - String name = getResources().getString(R.string.app_name); - Bitmap icon = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_foreground); - int color = getResources().getColor(R.color.app_icon_background); - setTaskDescription(new ActivityManager.TaskDescription(name, icon, color)); - } - - @Override - protected void attachBaseContext(Context newBase) { - super.attachBaseContext(DynamicLanguageContextWrapper.updateContext(newBase, TextSecurePreferences.getLanguage(newBase))); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/BaseActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/BaseActivity.kt new file mode 100644 index 00000000000..ecd004f5af3 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/BaseActivity.kt @@ -0,0 +1,33 @@ +package org.thoughtcrime.securesms + +import android.app.ActivityManager.TaskDescription +import android.content.Context +import android.graphics.BitmapFactory +import androidx.fragment.app.FragmentActivity +import network.loki.messenger.R +import org.session.libsession.messaging.MessagingModuleConfiguration.Companion.shared +import org.session.libsession.utilities.dynamiclanguage.DynamicLanguageActivityHelper +import org.session.libsession.utilities.dynamiclanguage.DynamicLanguageContextWrapper + +abstract class BaseActivity : FragmentActivity() { + override fun onResume() { + super.onResume() + DynamicLanguageActivityHelper.recreateIfNotInCorrectLanguage( + this, + shared.prefs.getLanguage() + ) + val name = resources.getString(R.string.app_name) + val icon = BitmapFactory.decodeResource(resources, R.drawable.ic_launcher_foreground) + val color = resources.getColor(R.color.app_icon_background) + setTaskDescription(TaskDescription(name, icon, color)) + } + + override fun attachBaseContext(newBase: Context) { + super.attachBaseContext( + DynamicLanguageContextWrapper.updateContext( + newBase, + shared.prefs.getLanguage() + ) + ) + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/DatabaseUpgradeActivity.java b/app/src/main/java/org/thoughtcrime/securesms/DatabaseUpgradeActivity.java deleted file mode 100644 index 31d146c45f9..00000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/DatabaseUpgradeActivity.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright (C) 2013 Open Whisper Systems - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.thoughtcrime.securesms; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.content.Intent; -import android.os.AsyncTask; -import android.os.Bundle; - -import org.thoughtcrime.securesms.util.Util; -import org.thoughtcrime.securesms.util.VersionTracker; - -public class DatabaseUpgradeActivity extends BaseActivity { - - @Override - public void onCreate(Bundle bundle) { - super.onCreate(bundle); - VersionTracker.updateLastSeenVersion(this); - updateNotifications(this); - startActivity((Intent)getIntent().getParcelableExtra("next_intent")); - finish(); - } - - public static boolean isUpdate(Context context) { - int currentVersionCode = Util.getCanonicalVersionCode(); - int previousVersionCode = VersionTracker.getLastSeenVersion(context); - - return previousVersionCode < currentVersionCode; - } - - @SuppressLint("StaticFieldLeak") - private void updateNotifications(final Context context) { - new AsyncTask() { - @Override - protected Void doInBackground(Void... params) { - ApplicationContext.getInstance(context).messageNotifier.updateNotification(context); - return null; - } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/DatabaseUpgradeActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/DatabaseUpgradeActivity.kt new file mode 100644 index 00000000000..5a39cd9223e --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/DatabaseUpgradeActivity.kt @@ -0,0 +1,50 @@ +/** + * Copyright (C) 2013 Open Whisper Systems + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see //www.gnu.org/licenses/>. + */ +package org.thoughtcrime.securesms + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import android.os.Parcelable +import androidx.lifecycle.lifecycleScope +import kotlinx.coroutines.launch +import org.thoughtcrime.securesms.util.Util +import org.thoughtcrime.securesms.util.VersionTracker.getLastSeenVersion +import org.thoughtcrime.securesms.util.VersionTracker.updateLastSeenVersion + +class DatabaseUpgradeActivity : BaseActivity() { + public override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + updateLastSeenVersion(this) + lifecycleScope.launch { + ApplicationContext.getInstance(this@DatabaseUpgradeActivity) + .messageNotifier.updateNotification(this@DatabaseUpgradeActivity) + } + startActivity(intent.getParcelableExtra("next_intent") as? Intent) + finish() + } + + companion object { + @JvmStatic + fun isUpdate(context: Context?): Boolean { + val currentVersionCode = Util.getCanonicalVersionCode() + val previousVersionCode = getLastSeenVersion(context!!) + + return previousVersionCode < currentVersionCode + } + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/PassphrasePromptActivity.java b/app/src/main/java/org/thoughtcrime/securesms/PassphrasePromptActivity.java index afc993df8af..8b51a52fe8c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/PassphrasePromptActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/PassphrasePromptActivity.java @@ -39,14 +39,13 @@ import androidx.core.hardware.fingerprint.FingerprintManagerCompat; import androidx.core.os.CancellationSignal; -import org.session.libsession.utilities.TextSecurePreferences; +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsignal.utilities.Log; import org.thoughtcrime.securesms.components.AnimatingToggle; import org.thoughtcrime.securesms.crypto.BiometricSecretProvider; import org.thoughtcrime.securesms.service.KeyCachingService; import org.thoughtcrime.securesms.util.AnimationCompleteListener; -import java.security.InvalidKeyException; import java.security.Signature; import network.loki.messenger.R; @@ -103,7 +102,7 @@ public void onResume() { setLockTypeVisibility(); - if (TextSecurePreferences.isScreenLockEnabled(this) && !authenticated && !failure) { + if (MessagingModuleConfiguration.getShared().getPrefs().isScreenLockEnabled() && !authenticated && !failure) { resumeScreenLock(); } @@ -114,7 +113,7 @@ public void onResume() { public void onPause() { super.onPause(); - if (TextSecurePreferences.isScreenLockEnabled(this)) { + if (MessagingModuleConfiguration.getShared().getPrefs().isScreenLockEnabled()) { pauseScreenLock(); } } @@ -176,7 +175,7 @@ private void initializeResources() { } private void setLockTypeVisibility() { - if (TextSecurePreferences.isScreenLockEnabled(this)) { + if (MessagingModuleConfiguration.getShared().getPrefs().isScreenLockEnabled()) { if (fingerprintManager.isHardwareDetected() && fingerprintManager.hasEnrolledFingerprints()) { fingerprintPrompt.setVisibility(View.VISIBLE); lockScreenButton.setVisibility(View.GONE); @@ -197,8 +196,8 @@ private void resumeScreenLock() { if (!keyguardManager.isKeyguardSecure()) { Log.w(TAG ,"Keyguard not secure..."); - TextSecurePreferences.setScreenLockEnabled(getApplicationContext(), false); - TextSecurePreferences.setScreenLockTimeout(getApplicationContext(), 0); + MessagingModuleConfiguration.getShared().getPrefs().setScreenLockEnabled(false); + MessagingModuleConfiguration.getShared().getPrefs().setScreenLockTimeout(0); handleAuthenticated(); return; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/PassphraseRequiredActionBarActivity.java b/app/src/main/java/org/thoughtcrime/securesms/PassphraseRequiredActionBarActivity.java index 1c9f4b2e57f..08efd32cb1e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/PassphraseRequiredActionBarActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/PassphraseRequiredActionBarActivity.java @@ -12,7 +12,7 @@ import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; -import org.session.libsession.utilities.TextSecurePreferences; +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsignal.utilities.Log; import org.thoughtcrime.securesms.home.HomeActivity; import org.thoughtcrime.securesms.onboarding.landing.LandingActivity; @@ -39,8 +39,8 @@ protected void onCreate(Bundle savedInstanceState) { onPreCreate(); final boolean locked = KeyCachingService.isLocked(this) && - TextSecurePreferences.isScreenLockEnabled(this) && - TextSecurePreferences.getLocalNumber(this) != null; + MessagingModuleConfiguration.getShared().getPrefs().isScreenLockEnabled() && + MessagingModuleConfiguration.getShared().getPrefs().getLocalNumber() != null; routeApplicationState(locked); super.onCreate(savedInstanceState); @@ -125,7 +125,7 @@ private Intent getIntentForState(int state) { } private int getApplicationState(boolean locked) { - if (TextSecurePreferences.getLocalNumber(this) == null) { + if (MessagingModuleConfiguration.getShared().getPrefs().getLocalNumber() == null) { return STATE_WELCOME_SCREEN; } else if (locked) { return STATE_PROMPT_PASSPHRASE; diff --git a/app/src/main/java/org/thoughtcrime/securesms/calls/WebRtcCallActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/calls/WebRtcCallActivity.kt index 2e3fdbf4d7f..300f5f3d494 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/calls/WebRtcCallActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/calls/WebRtcCallActivity.kt @@ -53,6 +53,7 @@ import org.thoughtcrime.securesms.webrtc.CallViewModel.State.CALL_RINGING import org.thoughtcrime.securesms.webrtc.Orientation import org.thoughtcrime.securesms.webrtc.audio.SignalAudioManager.AudioDevice.EARPIECE import org.thoughtcrime.securesms.webrtc.audio.SignalAudioManager.AudioDevice.SPEAKER_PHONE +import javax.inject.Inject import kotlin.math.asin @AndroidEntryPoint @@ -69,6 +70,8 @@ class WebRtcCallActivity : PassphraseRequiredActionBarActivity() { private const val CALL_DURATION_FORMAT = "HH:mm:ss" } + @Inject lateinit var prefs: TextSecurePreferences + private val viewModel by viewModels() private val glide by lazy { Glide.with(this) } private lateinit var binding: ActivityWebrtcBinding @@ -204,11 +207,10 @@ class WebRtcCallActivity : PassphraseRequiredActionBarActivity() { clipFloatingInsets() // set up the user avatar - TextSecurePreferences.getLocalNumber(this)?.let{ - val username = TextSecurePreferences.getProfileName(this) ?: truncateIdForDisplay(it) + prefs.getLocalNumber()?.let{ binding.userAvatar.apply { publicKey = it - displayName = username + displayName = prefs.getProfileName() ?: truncateIdForDisplay(it) update() } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/ComposeText.java b/app/src/main/java/org/thoughtcrime/securesms/components/ComposeText.java index 42825360c08..8595011f2bc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/ComposeText.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/ComposeText.java @@ -22,6 +22,7 @@ import androidx.core.view.inputmethod.InputConnectionCompat; import androidx.core.view.inputmethod.InputContentInfoCompat; +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.thoughtcrime.securesms.components.emoji.EmojiEditText; import org.session.libsignal.utilities.Log; import org.session.libsession.utilities.TextSecurePreferences; @@ -108,8 +109,8 @@ public void setCursorPositionChangedListener(@Nullable CursorPositionChangedList } public void setTransport() { - final boolean useSystemEmoji = TextSecurePreferences.isSystemEmojiPreferred(getContext()); - final boolean isIncognito = TextSecurePreferences.isIncognitoKeyboardEnabled(getContext()); + final boolean useSystemEmoji = MessagingModuleConfiguration.getShared().getPrefs().isSystemEmojiPreferred(); + final boolean isIncognito = MessagingModuleConfiguration.getShared().getPrefs().isIncognitoKeyboardEnabled(); int imeOptions = (getImeOptions() & ~EditorInfo.IME_MASK_ACTION) | EditorInfo.IME_ACTION_SEND; int inputType = getInputType(); @@ -132,7 +133,7 @@ public void setTransport() { public InputConnection onCreateInputConnection(EditorInfo editorInfo) { InputConnection inputConnection = super.onCreateInputConnection(editorInfo); - if(TextSecurePreferences.isEnterSendsEnabled(getContext())) { + if(MessagingModuleConfiguration.getShared().getPrefs().isEnterSendsEnabled()) { editorInfo.imeOptions &= ~EditorInfo.IME_FLAG_NO_ENTER_ACTION; } @@ -149,7 +150,7 @@ public void setMediaListener(@Nullable InputPanel.MediaListener mediaListener) { } private void initialize() { - if (TextSecurePreferences.isIncognitoKeyboardEnabled(getContext())) { + if (MessagingModuleConfiguration.getShared().getPrefs().isIncognitoKeyboardEnabled()) { setImeOptions(getImeOptions() | 16777216); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/CustomDefaultPreference.java b/app/src/main/java/org/thoughtcrime/securesms/components/CustomDefaultPreference.java deleted file mode 100644 index 178803a9f0f..00000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/components/CustomDefaultPreference.java +++ /dev/null @@ -1,259 +0,0 @@ -package org.thoughtcrime.securesms.components; - -import android.app.Dialog; -import android.content.Context; -import android.content.res.TypedArray; -import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.appcompat.app.AlertDialog; -import androidx.preference.DialogPreference; -import androidx.preference.PreferenceDialogFragmentCompat; -import android.text.Editable; -import android.text.TextUtils; -import android.text.TextWatcher; -import android.util.AttributeSet; -import org.session.libsignal.utilities.Log; -import android.view.View; -import android.widget.AdapterView; -import android.widget.Button; -import android.widget.EditText; -import android.widget.Spinner; -import android.widget.TextView; - -import network.loki.messenger.R; -import org.thoughtcrime.securesms.components.CustomDefaultPreference.CustomDefaultPreferenceDialogFragmentCompat.CustomPreferenceValidator; -import org.session.libsession.utilities.TextSecurePreferences; - -import java.net.URI; -import java.net.URISyntaxException; - - -public class CustomDefaultPreference extends DialogPreference { - - private static final String TAG = CustomDefaultPreference.class.getSimpleName(); - - private final int inputType; - private final String customPreference; - private final String customToggle; - - private CustomPreferenceValidator validator; - private String defaultValue; - - public CustomDefaultPreference(Context context, AttributeSet attrs) { - super(context, attrs); - - int[] attributeNames = new int[]{android.R.attr.inputType, R.attr.custom_pref_toggle}; - TypedArray attributes = context.obtainStyledAttributes(attrs, attributeNames); - - this.inputType = attributes.getInt(0, 0); - this.customPreference = getKey(); - this.customToggle = attributes.getString(1); - this.validator = new CustomDefaultPreferenceDialogFragmentCompat.NullValidator(); - - attributes.recycle(); - - setPersistent(false); - setDialogLayoutResource(R.layout.custom_default_preference_dialog); - } - - public CustomDefaultPreference setValidator(CustomPreferenceValidator validator) { - this.validator = validator; - return this; - } - - public CustomDefaultPreference setDefaultValue(String defaultValue) { - this.defaultValue = defaultValue; - this.setSummary(getSummary()); - return this; - } - - @Override - public String getSummary() { - if (isCustom()) { - return getContext().getString(R.string.CustomDefaultPreference_using_custom, - getPrettyPrintValue(getCustomValue())); - } else { - return getContext().getString(R.string.CustomDefaultPreference_using_default, - getPrettyPrintValue(getDefaultValue())); - } - } - - private String getPrettyPrintValue(String value) { - if (TextUtils.isEmpty(value)) return getContext().getString(R.string.CustomDefaultPreference_none); - else return value; - } - - private boolean isCustom() { - return TextSecurePreferences.getBooleanPreference(getContext(), customToggle, false); - } - - private void setCustom(boolean custom) { - TextSecurePreferences.setBooleanPreference(getContext(), customToggle, custom); - } - - private String getCustomValue() { - return TextSecurePreferences.getStringPreference(getContext(), customPreference, ""); - } - - private void setCustomValue(String value) { - TextSecurePreferences.setStringPreference(getContext(), customPreference, value); - } - - private String getDefaultValue() { - return defaultValue; - } - - - public static class CustomDefaultPreferenceDialogFragmentCompat extends PreferenceDialogFragmentCompat { - - private static final String INPUT_TYPE = "input_type"; - - private Spinner spinner; - private EditText customText; - private TextView defaultLabel; - - public static CustomDefaultPreferenceDialogFragmentCompat newInstance(String key) { - CustomDefaultPreferenceDialogFragmentCompat fragment = new CustomDefaultPreferenceDialogFragmentCompat(); - Bundle b = new Bundle(1); - b.putString(PreferenceDialogFragmentCompat.ARG_KEY, key); - fragment.setArguments(b); - return fragment; - } - - @Override - protected void onBindDialogView(@NonNull View view) { - Log.i(TAG, "onBindDialogView"); - super.onBindDialogView(view); - - CustomDefaultPreference preference = (CustomDefaultPreference)getPreference(); - - this.spinner = (Spinner) view.findViewById(R.id.default_or_custom); - this.defaultLabel = (TextView) view.findViewById(R.id.default_label); - this.customText = (EditText) view.findViewById(R.id.custom_edit); - - this.customText.setInputType(preference.inputType); - this.customText.addTextChangedListener(new TextValidator()); - this.customText.setText(preference.getCustomValue()); - this.spinner.setOnItemSelectedListener(new SelectionLister()); - this.defaultLabel.setText(preference.getPrettyPrintValue(preference.defaultValue)); - } - - - @Override - public @NonNull Dialog onCreateDialog(Bundle instanceState) { - Dialog dialog = super.onCreateDialog(instanceState); - - CustomDefaultPreference preference = (CustomDefaultPreference)getPreference(); - - if (preference.isCustom()) spinner.setSelection(1, true); - else spinner.setSelection(0, true); - - return dialog; - } - - @Override - public void onDialogClosed(boolean positiveResult) { - CustomDefaultPreference preference = (CustomDefaultPreference)getPreference(); - - if (positiveResult) { - if (spinner != null) preference.setCustom(spinner.getSelectedItemPosition() == 1); - if (customText != null) preference.setCustomValue(customText.getText().toString()); - - preference.setSummary(preference.getSummary()); - } - } - - interface CustomPreferenceValidator { - public boolean isValid(String value); - } - - private static class NullValidator implements CustomPreferenceValidator { - @Override - public boolean isValid(String value) { - return true; - } - } - - private class TextValidator implements TextWatcher { - - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) {} - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) {} - - @Override - public void afterTextChanged(Editable s) { - CustomDefaultPreference preference = (CustomDefaultPreference)getPreference(); - - if (spinner.getSelectedItemPosition() == 1) { - Button positiveButton = ((AlertDialog)getDialog()).getButton(AlertDialog.BUTTON_POSITIVE); - positiveButton.setEnabled(preference.validator.isValid(s.toString())); - } - } - } - - public static class UriValidator implements CustomPreferenceValidator { - @Override - public boolean isValid(String value) { - if (TextUtils.isEmpty(value)) return true; - - try { - new URI(value); - return true; - } catch (URISyntaxException mue) { - return false; - } - } - } - - public static class HostnameValidator implements CustomPreferenceValidator { - @Override - public boolean isValid(String value) { - if (TextUtils.isEmpty(value)) return true; - - try { - URI uri = new URI(null, value, null, null); - return true; - } catch (URISyntaxException mue) { - return false; - } - } - } - - public static class PortValidator implements CustomPreferenceValidator { - @Override - public boolean isValid(String value) { - try { - Integer.parseInt(value); - return true; - } catch (NumberFormatException e) { - return false; - } - } - } - - private class SelectionLister implements AdapterView.OnItemSelectedListener { - - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - CustomDefaultPreference preference = (CustomDefaultPreference)getPreference(); - Button positiveButton = ((AlertDialog)getDialog()).getButton(AlertDialog.BUTTON_POSITIVE); - - defaultLabel.setVisibility(position == 0 ? View.VISIBLE : View.GONE); - customText.setVisibility(position == 0 ? View.GONE : View.VISIBLE); - positiveButton.setEnabled(position == 0 || preference.validator.isValid(customText.getText().toString())); - } - - @Override - public void onNothingSelected(AdapterView parent) { - defaultLabel.setVisibility(View.VISIBLE); - customText.setVisibility(View.GONE); - } - } - - } - - - -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/ProfilePictureView.kt b/app/src/main/java/org/thoughtcrime/securesms/components/ProfilePictureView.kt index 571c778d4ad..b22f03f80df 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/ProfilePictureView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/ProfilePictureView.kt @@ -15,8 +15,9 @@ import org.session.libsession.avatars.ProfileContactPhoto import org.session.libsession.avatars.ResourceContactPhoto import org.session.libsession.messaging.contacts.Contact import org.session.libsession.utilities.Address -import org.session.libsession.utilities.AppTextSecurePreferences import org.session.libsession.utilities.GroupUtil +import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs import org.session.libsession.utilities.recipients.Recipient import org.session.libsignal.utilities.Log import org.thoughtcrime.securesms.dependencies.DatabaseComponent @@ -30,7 +31,7 @@ class ProfilePictureView @JvmOverloads constructor( private val binding = ViewProfilePictureBinding.inflate(LayoutInflater.from(context), this) private val glide: RequestManager = Glide.with(this) - private val prefs = AppTextSecurePreferences(context) + private val prefs = context.prefs private val userPublicKey = prefs.getLocalNumber() var publicKey: String? = null var displayName: String? = null diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/camera/CameraView.java b/app/src/main/java/org/thoughtcrime/securesms/components/camera/CameraView.java index 11f6c4104b0..7e067678e09 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/camera/CameraView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/camera/CameraView.java @@ -32,6 +32,8 @@ Portions Copyright (C) 2007 The Android Open Source Project import androidx.annotation.NonNull; import androidx.annotation.Nullable; import android.util.AttributeSet; + +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsignal.utilities.Log; import android.view.OrientationEventListener; import android.view.ViewGroup; @@ -81,7 +83,7 @@ public CameraView(Context context, AttributeSet attrs, int defStyle) { int camera = typedArray.getInt(R.styleable.CameraView_camera, -1); if (camera != -1) cameraId = camera; - else if (isMultiCamera()) cameraId = TextSecurePreferences.getDirectCaptureCameraId(context); + else if (isMultiCamera()) cameraId = MessagingModuleConfiguration.getShared().getPrefs().getDirectCaptureCameraId(); typedArray.recycle(); } @@ -266,7 +268,7 @@ public void flipCamera() { : CameraInfo.CAMERA_FACING_BACK; onPause(); onResume(); - TextSecurePreferences.setDirectCaptureCameraId(getContext(), cameraId); + MessagingModuleConfiguration.getShared().getPrefs().setDirectCaptureCameraId(cameraId); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiTextView.java b/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiTextView.java index 4f0072cc243..199b2278d9d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiTextView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiTextView.java @@ -1,7 +1,6 @@ package org.thoughtcrime.securesms.components.emoji; import android.content.Context; -import android.content.res.TypedArray; import android.graphics.drawable.Drawable; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -12,9 +11,10 @@ import android.util.AttributeSet; import android.util.TypedValue; import network.loki.messenger.R; + +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.thoughtcrime.securesms.components.emoji.EmojiProvider.EmojiDrawable; import org.thoughtcrime.securesms.components.emoji.parsing.EmojiParser; -import org.session.libsession.utilities.TextSecurePreferences; import org.session.libsession.utilities.Util; import org.session.libsignal.utilities.guava.Optional; @@ -171,7 +171,7 @@ private boolean unchanged(CharSequence text, CharSequence overflowText, BufferTy } private boolean useSystemEmoji() { - return TextSecurePreferences.isSystemEmojiPreferred(getContext()); + return MessagingModuleConfiguration.getShared().getPrefs().isSystemEmojiPreferred(); } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactAccessor.java b/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactAccessor.java index d560247fb93..d017c14583e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactAccessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactAccessor.java @@ -74,9 +74,9 @@ public List 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))) // { -// numberList.add(TextSecurePreferences.getLocalNumber(context)); +// numberList.add(MessagingModuleConfiguration.getShared().getPrefs().getLocalNumber(context)); // } return numberList; diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/start/home/StartConversationFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/start/home/StartConversationFragment.kt index 1934c5e5bb9..2be893ac764 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/start/home/StartConversationFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/start/home/StartConversationFragment.kt @@ -8,7 +8,9 @@ import androidx.compose.runtime.collectAsState import androidx.fragment.app.Fragment import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.MutableStateFlow +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs import org.thoughtcrime.securesms.conversation.start.StartConversationDelegate import org.thoughtcrime.securesms.conversation.start.NullStartConversationDelegate import org.thoughtcrime.securesms.ui.createThemedComposeView @@ -28,7 +30,7 @@ class StartConversationHomeFragment : Fragment() { savedInstanceState: Bundle? ): View = createThemedComposeView { StartConversationScreen( - accountId = TextSecurePreferences.getLocalNumber(requireContext())!!, + accountId = requireContext().prefs.getLocalNumber()!!, delegate = delegate.collectAsState().value ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/start/invitefriend/InviteFriendFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/start/invitefriend/InviteFriendFragment.kt index 4239a7a0675..19ffbb3dbe1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/start/invitefriend/InviteFriendFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/start/invitefriend/InviteFriendFragment.kt @@ -7,7 +7,9 @@ import android.view.ViewGroup import androidx.compose.ui.platform.LocalContext import androidx.fragment.app.Fragment import dagger.hilt.android.AndroidEntryPoint +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs import org.thoughtcrime.securesms.conversation.start.StartConversationDelegate import org.thoughtcrime.securesms.preferences.copyPublicKey import org.thoughtcrime.securesms.preferences.sendInvitationToUseSession @@ -22,7 +24,7 @@ class InviteFriendFragment : Fragment() { savedInstanceState: Bundle? ): View = createThemedComposeView { InviteFriend( - TextSecurePreferences.getLocalNumber(LocalContext.current)!!, + requireContext().prefs.getLocalNumber()!!, onBack = { delegate.onDialogBackPressed() }, onClose = { delegate.onDialogClosePressed() }, copyPublicKey = requireContext()::copyPublicKey, diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationReactionOverlay.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationReactionOverlay.kt index 9f2046334b5..cacd0216a6a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationReactionOverlay.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationReactionOverlay.kt @@ -30,9 +30,10 @@ import kotlinx.coroutines.flow.filter import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import network.loki.messenger.R +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.snode.SnodeAPI -import org.session.libsession.utilities.TextSecurePreferences.Companion.getLocalNumber import org.session.libsession.utilities.ThemeUtil +import org.session.libsession.utilities.prefs import org.thoughtcrime.securesms.components.emoji.EmojiImageView import org.thoughtcrime.securesms.components.emoji.RecentEmojiPageModel import org.thoughtcrime.securesms.components.menu.ActionItem @@ -514,7 +515,7 @@ class ConversationReactionOverlay : FrameLayout { private fun getOldEmoji(messageRecord: MessageRecord): String? = messageRecord.reactions - .filter { it.author == getLocalNumber(context) } + .filter { it.author == context.prefs.getLocalNumber() } .firstOrNull() ?.let(ReactionRecord::emoji) @@ -527,7 +528,7 @@ class ConversationReactionOverlay : FrameLayout { val openGroup = get(context).lokiThreadDatabase().getOpenGroupChat(message.threadId) val recipient = get(context).threadDatabase().getRecipientForThreadId(message.threadId) ?: return emptyList() - val userPublicKey = getLocalNumber(context)!! + val userPublicKey = context.prefs.getLocalNumber()!! // Select message items += ActionItem(R.attr.menu_select_icon, R.string.conversation_context__menu_select, { handleActionItemClicked(Action.SELECT) }, R.string.AccessibilityId_select) // Reply diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/LinkPreviewDialog.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/LinkPreviewDialog.kt index 996dd41f949..b7ea4b344ef 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/LinkPreviewDialog.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/LinkPreviewDialog.kt @@ -4,7 +4,9 @@ import android.app.Dialog import android.os.Bundle import androidx.fragment.app.DialogFragment import network.loki.messenger.R +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs import org.thoughtcrime.securesms.createSessionDialog /** Shown the first time the user inputs a URL that could generate a link preview, to @@ -19,7 +21,7 @@ class LinkPreviewDialog(private val onEnabled: () -> Unit) : DialogFragment() { } private fun enable() { - TextSecurePreferences.setLinkPreviewsEnabled(requireContext(), true) + requireContext().prefs.setLinkPreviewsEnabled(true) dismiss() onEnabled() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/input_bar/InputBar.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/input_bar/InputBar.kt index c8aacdeb6e3..69a327c537f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/input_bar/InputBar.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/input_bar/InputBar.kt @@ -18,8 +18,10 @@ import androidx.core.view.isGone import androidx.core.view.isVisible import network.loki.messenger.R import network.loki.messenger.databinding.ViewInputBarBinding +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs import org.session.libsession.utilities.recipients.Recipient import org.thoughtcrime.securesms.conversation.v2.components.LinkPreviewDraftView import org.thoughtcrime.securesms.conversation.v2.components.LinkPreviewDraftViewDelegate @@ -151,7 +153,7 @@ class InputBar @JvmOverloads constructor( // Edit text binding.inputBarEditText.setOnEditorActionListener(this) - if (TextSecurePreferences.isEnterSendsEnabled(context)) { + if (context.prefs.isEnterSendsEnabled()) { binding.inputBarEditText.imeOptions = EditorInfo.IME_ACTION_SEND binding.inputBarEditText.inputType = InputType.TYPE_TEXT_FLAG_CAP_SENTENCES } else { @@ -160,7 +162,7 @@ class InputBar @JvmOverloads constructor( binding.inputBarEditText.inputType InputType.TYPE_TEXT_FLAG_CAP_SENTENCES } - val incognitoFlag = if (TextSecurePreferences.isIncognitoKeyboardEnabled(context)) 16777216 else 0 + val incognitoFlag = if (context.prefs.isIncognitoKeyboardEnabled()) 16777216 else 0 binding.inputBarEditText.imeOptions = binding.inputBarEditText.imeOptions or incognitoFlag // Always use incognito keyboard if setting enabled binding.inputBarEditText.delegate = this } @@ -205,7 +207,7 @@ class InputBar @JvmOverloads constructor( it.delegate = this binding.inputBarAdditionalContentContainer.addView(layout) val attachments = (message as? MmsMessageRecord)?.slideDeck - val sender = if (message.isOutgoing) TextSecurePreferences.getLocalNumber(context)!! else message.individualRecipient.address.serialize() + val sender = if (message.isOutgoing) context.prefs.getLocalNumber()!! else message.individualRecipient.address.serialize() it.bind(sender, message.body, attachments, thread, true, message.isOpenGroupInvitation, message.threadId, false, glide) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationActionModeCallback.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationActionModeCallback.kt index c7862ca22ef..dbd537ba1aa 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationActionModeCallback.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationActionModeCallback.kt @@ -9,6 +9,7 @@ import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.utilities.AccountId import org.session.libsession.messaging.utilities.SodiumUtilities import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs import org.session.libsignal.utilities.IdPrefix import org.thoughtcrime.securesms.conversation.v2.ConversationAdapter import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord @@ -36,7 +37,7 @@ class ConversationActionModeCallback(private val adapter: ConversationAdapter, p val firstMessage = selectedItems.iterator().next() val openGroup = DatabaseComponent.get(context).lokiThreadDatabase().getOpenGroupChat(threadID) val thread = DatabaseComponent.get(context).threadDatabase().getRecipientForThreadId(threadID)!! - val userPublicKey = TextSecurePreferences.getLocalNumber(context)!! + val userPublicKey = context.prefs.getLocalNumber()!! val edKeyPair = MessagingModuleConfiguration.shared.getUserED25519KeyPair()!! val blindedPublicKey = openGroup?.publicKey?.let { SodiumUtilities.blindedKeyPair(it, edKeyPair)?.publicKey?.asBytes } ?.let { AccountId(IdPrefix.BLINDED, it) }?.hexString diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt index 177becd497f..13b73c1871e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt @@ -20,7 +20,7 @@ import network.loki.messenger.R import org.session.libsession.messaging.sending_receiving.MessageSender import org.session.libsession.messaging.sending_receiving.leave import org.session.libsession.utilities.GroupUtil.doubleDecodeGroupID -import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs import org.session.libsession.utilities.recipients.Recipient import org.session.libsignal.utilities.guava.Optional import org.session.libsignal.utilities.toHexString @@ -162,7 +162,7 @@ object ConversationMenuHelper { private fun call(context: Context, thread: Recipient) { - if (!TextSecurePreferences.isCallNotificationsEnabled(context)) { + if (!context.prefs.isCallNotificationsEnabled()) { context.showSessionDialog { title(R.string.ConversationActivity_call_title) text(R.string.ConversationActivity_call_prompt) @@ -271,7 +271,7 @@ object ConversationMenuHelper { val group = DatabaseComponent.get(context).groupDatabase().getGroup(thread.address.toGroupString()).orNull() val admins = group.admins - val accountID = TextSecurePreferences.getLocalNumber(context) + val accountID = context.prefs.getLocalNumber() val isCurrentUserAdmin = admins.any { it.toString() == accountID } val message = if (isCurrentUserAdmin) { "Because you are the creator of this group it will be deleted for everyone. This cannot be undone." diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/EmojiReactionsView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/EmojiReactionsView.kt index 49e4b1044f1..c58294e1066 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/EmojiReactionsView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/EmojiReactionsView.kt @@ -13,8 +13,9 @@ import androidx.core.content.ContextCompat import com.google.android.flexbox.JustifyContent import network.loki.messenger.R import network.loki.messenger.databinding.ViewEmojiReactionsBinding -import org.session.libsession.utilities.TextSecurePreferences.Companion.getLocalNumber +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.utilities.ThemeUtil +import org.session.libsession.utilities.prefs import org.thoughtcrime.securesms.components.emoji.EmojiImageView import org.thoughtcrime.securesms.components.emoji.EmojiUtil import org.thoughtcrime.securesms.conversation.v2.ViewUtil @@ -86,7 +87,7 @@ class EmojiReactionsView : ConstraintLayout, OnTouchListener { } private fun displayReactions(threshold: Int) { - val userPublicKey = getLocalNumber(context) + val userPublicKey = context.prefs.getLocalNumber() val reactions = buildSortedReactionsList(records!!, userPublicKey, threshold) binding.layoutEmojiContainer.removeAllViews() val overflowContainer = LinearLayout(context) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/QuoteView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/QuoteView.kt index 40cf4bc1e01..a1ebd778bea 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/QuoteView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/QuoteView.kt @@ -12,9 +12,11 @@ import androidx.core.view.isVisible import dagger.hilt.android.AndroidEntryPoint import network.loki.messenger.R import network.loki.messenger.databinding.ViewQuoteBinding +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.contacts.Contact import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.getColorFromAttr +import org.session.libsession.utilities.prefs import org.session.libsession.utilities.recipients.Recipient import org.thoughtcrime.securesms.conversation.v2.utilities.MentionUtilities import org.thoughtcrime.securesms.database.SessionContactDatabase @@ -71,7 +73,7 @@ class QuoteView @JvmOverloads constructor(context: Context, attrs: AttributeSet? isOriginalMissing: Boolean, glide: RequestManager) { // Author val author = contactDb.getContactWithAccountID(authorPublicKey) - val localNumber = TextSecurePreferences.getLocalNumber(context) + val localNumber = context.prefs.getLocalNumber() val quoteIsLocalUser = localNumber != null && authorPublicKey == localNumber val authorDisplayName = diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/MentionUtilities.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/MentionUtilities.kt index 4d3e48bc5b0..da1acba43d2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/MentionUtilities.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/MentionUtilities.kt @@ -12,9 +12,9 @@ import nl.komponents.kovenant.combine.Tuple2 import org.session.libsession.messaging.contacts.Contact import org.session.libsession.messaging.open_groups.OpenGroup import org.session.libsession.messaging.utilities.SodiumUtilities -import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.ThemeUtil import org.session.libsession.utilities.getColorFromAttr +import org.session.libsession.utilities.prefs import org.session.libsession.utilities.truncateIdForDisplay import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.util.RoundedBackgroundSpan @@ -51,7 +51,7 @@ object MentionUtilities { var matcher = pattern.matcher(text) val mentions = mutableListOf, String>>() var startIndex = 0 - val userPublicKey = TextSecurePreferences.getLocalNumber(context)!! + val userPublicKey = context.prefs.getLocalNumber()!! val openGroup by lazy { DatabaseComponent.get(context).storage().getOpenGroup(threadID) } // format the mention text diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/ResendMessageUtilities.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/ResendMessageUtilities.kt index c1d69879044..10604a76bdb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/ResendMessageUtilities.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/ResendMessageUtilities.kt @@ -10,6 +10,7 @@ import org.session.libsession.messaging.messages.visible.VisibleMessage import org.session.libsession.messaging.sending_receiving.MessageSender import org.session.libsession.messaging.utilities.UpdateMessageData import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs import org.session.libsession.utilities.recipients.Recipient import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.database.model.MmsMessageRecord @@ -44,7 +45,7 @@ object ResendMessageUtilities { messageRecord.linkPreviews.firstOrNull()?.let { message.linkPreview = LinkPreview.from(it) } messageRecord.quote?.quoteModel?.let { message.quote = Quote.from(it)?.apply { - if (userBlindedKey != null && publicKey == TextSecurePreferences.getLocalNumber(context)) { + if (userBlindedKey != null && publicKey == context.prefs.getLocalNumber()) { publicKey = userBlindedKey } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/crypto/AttachmentSecretProvider.java b/app/src/main/java/org/thoughtcrime/securesms/crypto/AttachmentSecretProvider.java index 0344551cab8..0c447ac0954 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/crypto/AttachmentSecretProvider.java +++ b/app/src/main/java/org/thoughtcrime/securesms/crypto/AttachmentSecretProvider.java @@ -1,11 +1,9 @@ package org.thoughtcrime.securesms.crypto; -import android.content.Context; -import android.os.Build; import androidx.annotation.NonNull; -import org.session.libsession.utilities.TextSecurePreferences; +import org.session.libsession.messaging.MessagingModuleConfiguration; import java.security.SecureRandom; @@ -19,85 +17,55 @@ public class AttachmentSecretProvider { private static AttachmentSecretProvider provider; - public static synchronized AttachmentSecretProvider getInstance(@NonNull Context context) { - if (provider == null) provider = new AttachmentSecretProvider(context.getApplicationContext()); + public static synchronized AttachmentSecretProvider getInstance() { + if (provider == null) provider = new AttachmentSecretProvider(); return provider; } - private final Context context; - private AttachmentSecret attachmentSecret; - private AttachmentSecretProvider(@NonNull Context context) { - this.context = context.getApplicationContext(); - } - public synchronized AttachmentSecret getOrCreateAttachmentSecret() { if (attachmentSecret != null) return attachmentSecret; - String unencryptedSecret = TextSecurePreferences.getAttachmentUnencryptedSecret(context); - String encryptedSecret = TextSecurePreferences.getAttachmentEncryptedSecret(context); + String unencryptedSecret = MessagingModuleConfiguration.getShared().getPrefs().getAttachmentUnencryptedSecret(); + String encryptedSecret = MessagingModuleConfiguration.getShared().getPrefs().getAttachmentEncryptedSecret(); - if (unencryptedSecret != null) attachmentSecret = getUnencryptedAttachmentSecret(context, unencryptedSecret); + if (unencryptedSecret != null) attachmentSecret = getUnencryptedAttachmentSecret(unencryptedSecret); else if (encryptedSecret != null) attachmentSecret = getEncryptedAttachmentSecret(encryptedSecret); - else attachmentSecret = createAndStoreAttachmentSecret(context); - - return attachmentSecret; - } - - public synchronized AttachmentSecret setClassicKey(@NonNull Context context, @NonNull byte[] classicCipherKey, @NonNull byte[] classicMacKey) { - AttachmentSecret currentSecret = getOrCreateAttachmentSecret(); - currentSecret.setClassicCipherKey(classicCipherKey); - currentSecret.setClassicMacKey(classicMacKey); - - storeAttachmentSecret(context, attachmentSecret); + else attachmentSecret = createAndStoreAttachmentSecret(); return attachmentSecret; } - private AttachmentSecret getUnencryptedAttachmentSecret(@NonNull Context context, @NonNull String unencryptedSecret) - { + private AttachmentSecret getUnencryptedAttachmentSecret(@NonNull String unencryptedSecret) { AttachmentSecret attachmentSecret = AttachmentSecret.fromString(unencryptedSecret); - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { - return attachmentSecret; - } else { KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(attachmentSecret.serialize().getBytes()); - TextSecurePreferences.setAttachmentEncryptedSecret(context, encryptedSecret.serialize()); - TextSecurePreferences.setAttachmentUnencryptedSecret(context, null); + MessagingModuleConfiguration.getShared().getPrefs().setAttachmentEncryptedSecret(encryptedSecret.serialize()); + MessagingModuleConfiguration.getShared().getPrefs().setAttachmentUnencryptedSecret(null); return attachmentSecret; - } } private AttachmentSecret getEncryptedAttachmentSecret(@NonNull String serializedEncryptedSecret) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { - throw new AssertionError("OS downgrade not supported. KeyStore sealed data exists on platform < M!"); - } else { - KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.SealedData.fromString(serializedEncryptedSecret); - return AttachmentSecret.fromString(new String(KeyStoreHelper.unseal(encryptedSecret))); - } + KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.SealedData.fromString(serializedEncryptedSecret); + return AttachmentSecret.fromString(new String(KeyStoreHelper.unseal(encryptedSecret))); } - private AttachmentSecret createAndStoreAttachmentSecret(@NonNull Context context) { + private AttachmentSecret createAndStoreAttachmentSecret() { SecureRandom random = new SecureRandom(); byte[] secret = new byte[32]; random.nextBytes(secret); AttachmentSecret attachmentSecret = new AttachmentSecret(null, null, secret); - storeAttachmentSecret(context, attachmentSecret); + storeAttachmentSecret(attachmentSecret); return attachmentSecret; } - private void storeAttachmentSecret(@NonNull Context context, @NonNull AttachmentSecret attachmentSecret) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + private void storeAttachmentSecret(@NonNull AttachmentSecret attachmentSecret) { KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(attachmentSecret.serialize().getBytes()); - TextSecurePreferences.setAttachmentEncryptedSecret(context, encryptedSecret.serialize()); - } else { - TextSecurePreferences.setAttachmentUnencryptedSecret(context, attachmentSecret.serialize()); - } + MessagingModuleConfiguration.getShared().getPrefs().setAttachmentEncryptedSecret(encryptedSecret.serialize()); } - } diff --git a/app/src/main/java/org/thoughtcrime/securesms/crypto/BiometricSecretProvider.kt b/app/src/main/java/org/thoughtcrime/securesms/crypto/BiometricSecretProvider.kt index ac12a69bbe5..44232ba0356 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/crypto/BiometricSecretProvider.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/crypto/BiometricSecretProvider.kt @@ -4,8 +4,10 @@ import android.content.Context import android.os.Build import android.security.keystore.KeyGenParameterSpec import android.security.keystore.KeyProperties +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.Util +import org.session.libsession.utilities.prefs import java.security.InvalidKeyException import java.security.KeyPairGenerator import java.security.KeyStore @@ -54,10 +56,10 @@ class BiometricSecretProvider { ks.load(null) if (!ks.containsAlias(BIOMETRIC_ASYM_KEY_ALIAS) || !ks.entryInstanceOf(BIOMETRIC_ASYM_KEY_ALIAS, KeyStore.PrivateKeyEntry::class.java) - || !TextSecurePreferences.getFingerprintKeyGenerated(context) + || !context.prefs.getFingerprintKeyGenerated() ) { createAsymmetricKey(context) - TextSecurePreferences.setFingerprintKeyGenerated(context) + context.prefs.setFingerprintKeyGenerated() } val signature = try { val key = ks.getKey(BIOMETRIC_ASYM_KEY_ALIAS, null) as PrivateKey @@ -67,7 +69,7 @@ class BiometricSecretProvider { } catch (e: InvalidKeyException) { ks.deleteEntry(BIOMETRIC_ASYM_KEY_ALIAS) createAsymmetricKey(context) - TextSecurePreferences.setFingerprintKeyGenerated(context) + context.prefs.setFingerprintKeyGenerated() val key = ks.getKey(BIOMETRIC_ASYM_KEY_ALIAS, null) as PrivateKey val signature = Signature.getInstance(SIGNATURE_ALGORITHM) signature.initSign(key) diff --git a/app/src/main/java/org/thoughtcrime/securesms/crypto/DatabaseSecretProvider.java b/app/src/main/java/org/thoughtcrime/securesms/crypto/DatabaseSecretProvider.java index 0ad22c3a909..c18808d3af5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/crypto/DatabaseSecretProvider.java +++ b/app/src/main/java/org/thoughtcrime/securesms/crypto/DatabaseSecretProvider.java @@ -1,10 +1,8 @@ package org.thoughtcrime.securesms.crypto; - -import android.content.Context; -import android.os.Build; import androidx.annotation.NonNull; +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsession.utilities.TextSecurePreferences; import java.io.IOException; @@ -15,63 +13,51 @@ public class DatabaseSecretProvider { @SuppressWarnings("unused") private static final String TAG = DatabaseSecretProvider.class.getSimpleName(); - private final Context context; + private final TextSecurePreferences prefs; - public DatabaseSecretProvider(@NonNull Context context) { - this.context = context.getApplicationContext(); + public DatabaseSecretProvider(@NonNull TextSecurePreferences prefs) { + this.prefs = prefs; } public DatabaseSecret getOrCreateDatabaseSecret() { - String unencryptedSecret = TextSecurePreferences.getDatabaseUnencryptedSecret(context); - String encryptedSecret = TextSecurePreferences.getDatabaseEncryptedSecret(context); + String unencryptedSecret = prefs.getDatabaseUnencryptedSecret(); + String encryptedSecret = prefs.getDatabaseEncryptedSecret(); - if (unencryptedSecret != null) return getUnencryptedDatabaseSecret(context, unencryptedSecret); + if (unencryptedSecret != null) return getUnencryptedDatabaseSecret(unencryptedSecret); else if (encryptedSecret != null) return getEncryptedDatabaseSecret(encryptedSecret); - else return createAndStoreDatabaseSecret(context); + else return createAndStoreDatabaseSecret(); } - private DatabaseSecret getUnencryptedDatabaseSecret(@NonNull Context context, @NonNull String unencryptedSecret) + private DatabaseSecret getUnencryptedDatabaseSecret(@NonNull String unencryptedSecret) { try { DatabaseSecret databaseSecret = new DatabaseSecret(unencryptedSecret); - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { - return databaseSecret; - } else { - KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(databaseSecret.asBytes()); + KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(databaseSecret.asBytes()); - TextSecurePreferences.setDatabaseEncryptedSecret(context, encryptedSecret.serialize()); - TextSecurePreferences.setDatabaseUnencryptedSecret(context, null); + prefs.setDatabaseEncryptedSecret(encryptedSecret.serialize()); + prefs.setDatabaseUnencryptedSecret(null); - return databaseSecret; - } + return databaseSecret; } catch (IOException e) { throw new AssertionError(e); } } private DatabaseSecret getEncryptedDatabaseSecret(@NonNull String serializedEncryptedSecret) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { - throw new AssertionError("OS downgrade not supported. KeyStore sealed data exists on platform < M!"); - } else { - KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.SealedData.fromString(serializedEncryptedSecret); - return new DatabaseSecret(KeyStoreHelper.unseal(encryptedSecret)); - } + KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.SealedData.fromString(serializedEncryptedSecret); + return new DatabaseSecret(KeyStoreHelper.unseal(encryptedSecret)); } - private DatabaseSecret createAndStoreDatabaseSecret(@NonNull Context context) { + private DatabaseSecret createAndStoreDatabaseSecret() { SecureRandom random = new SecureRandom(); byte[] secret = new byte[32]; random.nextBytes(secret); DatabaseSecret databaseSecret = new DatabaseSecret(secret); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(databaseSecret.asBytes()); - TextSecurePreferences.setDatabaseEncryptedSecret(context, encryptedSecret.serialize()); - } else { - TextSecurePreferences.setDatabaseUnencryptedSecret(context, databaseSecret.asString()); - } + KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(databaseSecret.asBytes()); + prefs.setDatabaseEncryptedSecret(encryptedSecret.serialize()); return databaseSecret; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java index 66d01114ef1..903432a72cd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java @@ -14,6 +14,7 @@ import net.zetetic.database.sqlcipher.SQLiteDatabase; import org.jetbrains.annotations.NotNull; +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsession.utilities.Address; import org.session.libsession.utilities.GroupRecord; import org.session.libsession.utilities.TextSecurePreferences; @@ -172,7 +173,7 @@ public Cursor getGroupsFilteredByMembers(List members) { List recipients = new LinkedList<>(); for (Address member : members) { - if (!includeSelf && Util.isOwnNumber(context, member.serialize())) + if (!includeSelf && Util.isOwnNumber(member.serialize())) continue; if (member.isContact()) { @@ -186,7 +187,7 @@ public Cursor getGroupsFilteredByMembers(List members) { public @NonNull List
getGroupMemberAddresses(String groupId, boolean includeSelf) { List
members = getCurrentMembers(groupId, false); if (!includeSelf) { - String ownNumber = TextSecurePreferences.getLocalNumber(context); + String ownNumber = MessagingModuleConfiguration.getShared().getPrefs().getLocalNumber(); if (ownNumber == null) return members; Address ownAddress = Address.fromSerialized(ownNumber); int indexOfSelf = members.indexOf(ownAddress); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/LokiAPIDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/LokiAPIDatabase.kt index f1f999242c7..adce541211d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/LokiAPIDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/LokiAPIDatabase.kt @@ -2,7 +2,9 @@ package org.thoughtcrime.securesms.database import android.content.ContentValues import android.content.Context +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs import org.session.libsignal.crypto.ecc.DjbECPrivateKey import org.session.libsignal.crypto.ecc.DjbECPublicKey import org.session.libsignal.crypto.ecc.ECKeyPair @@ -490,14 +492,10 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database( database.insertOrUpdate(openGroupPublicKeyTable, row, "${LokiAPIDatabase.server} = ?", wrap(server)) } - override fun getLastSnodePoolRefreshDate(): Date? { - val time = TextSecurePreferences.getLastSnodePoolRefreshDate(context) - if (time <= 0) { return null } - return Date(time) - } + override fun getLastSnodePoolRefreshDate(): Date? = context.prefs.getLastSnodePoolRefreshDate().takeIf { it > 0 }?.let(::Date) override fun setLastSnodePoolRefreshDate(date: Date) { - TextSecurePreferences.setLastSnodePoolRefreshDate(context, date) + context.prefs.setLastSnodePoolRefreshDate(date) } override fun getUserX25519KeyPair(): ECKeyPair { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/LokiUserDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/LokiUserDatabase.kt index 4a5468c5d44..07939e5836a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/LokiUserDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/LokiUserDatabase.kt @@ -1,8 +1,10 @@ package org.thoughtcrime.securesms.database import android.content.Context +import org.session.libsession.messaging.MessagingModuleConfiguration import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs class LokiUserDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper) { @@ -20,8 +22,8 @@ class LokiUserDatabase(context: Context, helper: SQLCipherOpenHelper) : Database } fun getDisplayName(publicKey: String): String? { - if (publicKey == TextSecurePreferences.getLocalNumber(context)) { - return TextSecurePreferences.getProfileName(context) + if (publicKey == context.prefs.getLocalNumber()) { + return context.prefs.getProfileName() } else { val database = databaseHelper.readableDatabase val result = database.get(displayNameTable, "${Companion.publicKey} = ?", arrayOf( publicKey )) { cursor -> diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MessagingDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MessagingDatabase.java index bc74496dda4..f6773dfffd9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MessagingDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MessagingDatabase.java @@ -14,7 +14,6 @@ import org.session.libsignal.crypto.IdentityKey; import org.session.libsignal.utilities.JsonUtil; import org.session.libsignal.utilities.Log; -import org.thoughtcrime.securesms.conversation.disappearingmessages.ExpiryType; import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.util.SqlUtil; diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.kt index 9d3a6c9c184..cae23a511e9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.kt @@ -25,6 +25,7 @@ import org.apache.commons.lang3.StringUtils import org.json.JSONArray import org.json.JSONException import org.json.JSONObject +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.messages.ExpirationConfiguration import org.session.libsession.messaging.messages.signal.IncomingMediaMessage import org.session.libsession.messaging.messages.signal.OutgoingGroupMediaMessage @@ -45,8 +46,8 @@ import org.session.libsession.utilities.IdentityKeyMismatch import org.session.libsession.utilities.IdentityKeyMismatchList import org.session.libsession.utilities.NetworkFailure import org.session.libsession.utilities.NetworkFailureList -import org.session.libsession.utilities.TextSecurePreferences.Companion.isReadReceiptsEnabled import org.session.libsession.utilities.Util.toIsoBytes +import org.session.libsession.utilities.prefs import org.session.libsession.utilities.recipients.Recipient import org.session.libsignal.utilities.JsonUtil import org.session.libsignal.utilities.Log @@ -1254,10 +1255,9 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa val expiry = cursor.getLong(cursor.getColumnIndexOrThrow(EXPIRY)) val status = cursor.getInt(cursor.getColumnIndexOrThrow(STATUS)) val deliveryReceiptCount = cursor.getInt(cursor.getColumnIndexOrThrow(DELIVERY_RECEIPT_COUNT)) - val readReceiptCount = if (isReadReceiptsEnabled(context)) cursor.getInt(cursor.getColumnIndexOrThrow(READ_RECEIPT_COUNT)) else 0 + val readReceiptCount = if (context.prefs.isReadReceiptsEnabled()) cursor.getInt(cursor.getColumnIndexOrThrow(READ_RECEIPT_COUNT)) else 0 val hasMention = (cursor.getInt(cursor.getColumnIndexOrThrow(HAS_MENTION)) == 1) val slideDeck = SlideDeck(context, MmsNotificationAttachment(status, messageSize)) - return NotificationMmsMessageRecord( id, recipient, recipient, dateSent, dateReceived, deliveryReceiptCount, threadId, @@ -1286,7 +1286,7 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa val unidentified = cursor.getInt(cursor.getColumnIndexOrThrow(UNIDENTIFIED)) == 1 val hasMention = cursor.getInt(cursor.getColumnIndexOrThrow(HAS_MENTION)) == 1 - if (!isReadReceiptsEnabled(context)) { + if (!context.prefs.isReadReceiptsEnabled()) { readReceiptCount = 0 } val recipient = getRecipientFor(address) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java index b737be855e2..942f7989010 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java @@ -106,7 +106,7 @@ public MmsSmsDatabase(Context context, SQLCipherOpenHelper databaseHelper) { MmsSmsDatabase.Reader reader = readerFor(cursor, getQuote); MessageRecord messageRecord; - boolean isOwnNumber = Util.isOwnNumber(context, serializedAuthor); + boolean isOwnNumber = Util.isOwnNumber(serializedAuthor); while ((messageRecord = reader.getNext()) != null) { if ((isOwnNumber && messageRecord.isOutgoing()) || @@ -122,7 +122,7 @@ public MmsSmsDatabase(Context context, SQLCipherOpenHelper databaseHelper) { public @Nullable MessageRecord getSentMessageFor(long timestamp, String serializedAuthor) { // Early exit if the author is not us - boolean isOwnNumber = Util.isOwnNumber(context, serializedAuthor); + boolean isOwnNumber = Util.isOwnNumber(serializedAuthor); if (!isOwnNumber) { Log.i(TAG, "Asked to find sent messages but provided author is not us - returning null."); return null; @@ -145,7 +145,7 @@ public MmsSmsDatabase(Context context, SQLCipherOpenHelper databaseHelper) { public MessageRecord getLastSentMessageRecordFromSender(long threadId, String serializedAuthor) { // Early exit if the author is not us - boolean isOwnNumber = Util.isOwnNumber(context, serializedAuthor); + boolean isOwnNumber = Util.isOwnNumber(serializedAuthor); if (!isOwnNumber) { Log.i(TAG, "Asked to find last sent message but provided author is not us - returning null."); return null; @@ -375,7 +375,7 @@ public int getQuotedMessagePosition(long threadId, long quoteId, @NonNull Addres try (Cursor cursor = queryTables(new String[]{ MmsSmsColumns.NORMALIZED_DATE_SENT, MmsSmsColumns.ADDRESS }, selection, order, null)) { String serializedAddress = address.serialize(); - boolean isOwnNumber = Util.isOwnNumber(context, address.serialize()); + boolean isOwnNumber = Util.isOwnNumber(address.serialize()); while (cursor != null && cursor.moveToNext()) { boolean quoteIdMatches = cursor.getLong(0) == quoteId; @@ -395,7 +395,7 @@ public int getMessagePositionInConversation(long threadId, long sentTimestamp, @ try (Cursor cursor = queryTables(new String[]{ MmsSmsColumns.NORMALIZED_DATE_SENT, MmsSmsColumns.ADDRESS }, selection, order, null)) { String serializedAddress = address.serialize(); - boolean isOwnNumber = Util.isOwnNumber(context, address.serialize()); + boolean isOwnNumber = Util.isOwnNumber(address.serialize()); while (cursor != null && cursor.moveToNext()) { boolean timestampMatches = cursor.getLong(0) == sentTimestamp; diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java index 84b94418342..b4a4f7d7d62 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java @@ -28,6 +28,7 @@ import net.zetetic.database.sqlcipher.SQLiteDatabase; import net.zetetic.database.sqlcipher.SQLiteStatement; import org.apache.commons.lang3.StringUtils; +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsession.messaging.calls.CallMessageType; import org.session.libsession.messaging.messages.signal.IncomingGroupMessage; import org.session.libsession.messaging.messages.signal.IncomingTextMessage; @@ -837,7 +838,7 @@ public SmsMessageRecord getCurrent() { boolean unidentified = cursor.getInt(cursor.getColumnIndexOrThrow(SmsDatabase.UNIDENTIFIED)) == 1; boolean hasMention = cursor.getInt(cursor.getColumnIndexOrThrow(SmsDatabase.HAS_MENTION)) == 1; - if (!TextSecurePreferences.isReadReceiptsEnabled(context)) { + if (!MessagingModuleConfiguration.getShared().getPrefs().isReadReceiptsEnabled()) { readReceiptCount = 0; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt index 3115275773c..610639679c0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -21,6 +21,7 @@ import network.loki.messenger.libsession_util.util.afterSend import org.session.libsession.avatars.AvatarHelper import org.session.libsession.database.StorageProtocol import org.session.libsession.messaging.BlindedIdMapping +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.calls.CallMessageType import org.session.libsession.messaging.contacts.Contact import org.session.libsession.messaging.jobs.AttachmentUploadJob @@ -71,6 +72,7 @@ import org.session.libsession.utilities.ProfileKeyUtil import org.session.libsession.utilities.SSKEnvironment import org.session.libsession.utilities.SSKEnvironment.ProfileManagerProtocol.Companion.NAME_PADDED_LENGTH import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.recipients.Recipient.DisappearingState import org.session.libsignal.crypto.ecc.DjbECPrivateKey @@ -175,7 +177,7 @@ open class Storage( } override fun getUserPublicKey(): String? { - return TextSecurePreferences.getLocalNumber(context) + return context.prefs.getLocalNumber() } override fun getUserX25519KeyPair(): ECKeyPair { @@ -183,9 +185,9 @@ open class Storage( } override fun getUserProfile(): Profile { - val displayName = TextSecurePreferences.getProfileName(context) + val displayName = context.prefs.getProfileName() val profileKey = ProfileKeyUtil.getProfileKey(context) - val profilePictureUrl = TextSecurePreferences.getProfilePictureURL(context) + val profilePictureUrl = context.prefs.getProfilePictureURL() return Profile(displayName, profileKey, profilePictureUrl) } @@ -210,8 +212,8 @@ open class Storage( Recipient.from(context, it, false) } ourRecipient.resolve().profileKey = newProfileKey - TextSecurePreferences.setProfileKey(context, newProfileKey?.let { Base64.encodeBytes(it) }) - TextSecurePreferences.setProfilePictureURL(context, newProfilePicture) + context.prefs.setProfileKey(newProfileKey?.let { Base64.encodeBytes(it) }) + context.prefs.setProfilePictureURL(newProfilePicture) if (newProfileKey != null) { JobQueue.shared.add(RetrieveProfileAvatarJob(newProfilePicture, ourRecipient.address)) @@ -219,10 +221,10 @@ open class Storage( } override fun getOrGenerateRegistrationID(): Int { - var registrationID = TextSecurePreferences.getLocalRegistrationId(context) + var registrationID = context.prefs.getLocalRegistrationId() if (registrationID == 0) { registrationID = KeyHelper.generateRegistrationId(false) - TextSecurePreferences.setLocalRegistrationId(context, registrationID) + context.prefs.setLocalRegistrationId(registrationID) } return registrationID } @@ -478,7 +480,7 @@ open class Storage( val profileManager = SSKEnvironment.shared.profileManager name.takeUnless { it.isEmpty() }?.truncate(NAME_PADDED_LENGTH)?.let { - TextSecurePreferences.setProfileName(context, it) + context.prefs.setProfileName(it) profileManager.setName(context, recipient, it) if (it != name) userProfile.setName(it) } @@ -487,7 +489,7 @@ open class Storage( if (userPic == UserPic.DEFAULT) { clearUserPic() } else if (userPic.key.isNotEmpty() && userPic.url.isNotEmpty() - && TextSecurePreferences.getProfilePictureURL(context) != userPic.url) { + && context.prefs.getProfilePictureURL() != userPic.url) { setUserProfilePicture(userPic.url, userPic.key) } @@ -525,11 +527,11 @@ open class Storage( val recipient = Recipient.from(context, fromSerialized(userPublicKey), false) // Clear details related to the user's profile picture - TextSecurePreferences.setProfileKey(context, null) + context.prefs.setProfileKey(null) ProfileKeyUtil.setEncodedProfileKey(context, null) recipientDatabase.setProfileAvatar(recipient, null) - TextSecurePreferences.setProfileAvatarId(context, 0) - TextSecurePreferences.setProfilePictureURL(context, null) + context.prefs.setProfileAvatarId(0) + context.prefs.setProfilePictureURL(null) Recipient.removeCached(fromSerialized(userPublicKey)) configFactory.user?.setPic(UserPic.DEFAULT) @@ -787,7 +789,7 @@ open class Storage( // message timestamp and as such we cannot use that to identify the local message. override fun markAsSentToCommunity(threadId: Long, messageID: Long) { val database = DatabaseComponent.get(context).mmsSmsDatabase() - val message = database.getLastSentMessageRecordFromSender(threadId, TextSecurePreferences.getLocalNumber(context)) + val message = database.getLastSentMessageRecordFromSender(threadId, context.prefs.getLocalNumber()) // Ensure we can find the local message.. if (message == null) { @@ -852,7 +854,7 @@ open class Storage( // modifies the message timestamp and as such we cannot use that to identify the local message. override fun markUnidentifiedInCommunity(threadId: Long, messageId: Long) { val database = DatabaseComponent.get(context).mmsSmsDatabase() - val message = database.getLastSentMessageRecordFromSender(threadId, TextSecurePreferences.getLocalNumber(context)) + val message = database.getLastSentMessageRecordFromSender(threadId, context.prefs.getLocalNumber()) // Check to ensure the message exists if (message == null) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java index f5c6da5fb9c..6b50d61aefd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java @@ -31,6 +31,7 @@ import com.annimon.stream.Stream; import net.zetetic.database.sqlcipher.SQLiteDatabase; import org.jetbrains.annotations.NotNull; +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsession.snode.SnodeAPI; import org.session.libsession.utilities.Address; import org.session.libsession.utilities.Contact; @@ -924,7 +925,7 @@ public ThreadRecord getCurrent() { Uri snippetUri = getSnippetUri(cursor); boolean pinned = cursor.getInt(cursor.getColumnIndexOrThrow(ThreadDatabase.IS_PINNED)) != 0; - if (!TextSecurePreferences.isReadReceiptsEnabled(context)) { + if (!MessagingModuleConfiguration.getShared().getPrefs().isReadReceiptsEnabled()) { readReceiptCount = 0; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java index cd1988e83ff..9cee14ca309 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java @@ -13,6 +13,7 @@ import net.zetetic.database.sqlcipher.SQLiteDatabaseHook; import net.zetetic.database.sqlcipher.SQLiteOpenHelper; +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsession.utilities.TextSecurePreferences; import org.session.libsignal.utilities.Log; import org.thoughtcrime.securesms.crypto.DatabaseSecret; @@ -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) { connection.execute("VACUUM;", null, null); - TextSecurePreferences.setLastVacuumNow(context); + MessagingModuleConfiguration.getShared().getPrefs().setLastVacuumNow(); } } }, diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/AppModule.kt b/app/src/main/java/org/thoughtcrime/securesms/dependencies/AppModule.kt index a9a72e76657..bc758ee75db 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/AppModule.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/AppModule.kt @@ -5,7 +5,6 @@ import dagger.Module import dagger.hilt.EntryPoint import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent -import org.session.libsession.utilities.AppTextSecurePreferences import org.session.libsession.utilities.TextSecurePreferences import org.thoughtcrime.securesms.repository.ConversationRepository import org.thoughtcrime.securesms.repository.DefaultConversationRepository @@ -14,8 +13,6 @@ import org.thoughtcrime.securesms.repository.DefaultConversationRepository @InstallIn(SingletonComponent::class) abstract class AppModule { - @Binds - abstract fun bindTextSecurePreferences(preferences: AppTextSecurePreferences): TextSecurePreferences @Binds abstract fun bindConversationRepository(repository: DefaultConversationRepository): ConversationRepository diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ConfigFactory.kt b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ConfigFactory.kt index 505a7939a8b..281162010cc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ConfigFactory.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ConfigFactory.kt @@ -7,9 +7,11 @@ import network.loki.messenger.libsession_util.Contacts import network.loki.messenger.libsession_util.ConversationVolatileConfig import network.loki.messenger.libsession_util.UserGroupsConfig import network.loki.messenger.libsession_util.UserProfile +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.utilities.ConfigFactoryProtocol import org.session.libsession.utilities.ConfigFactoryUpdateListener import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs import org.session.libsignal.protos.SignalServiceProtos.SharedConfigMessage import org.session.libsignal.utilities.Log import org.thoughtcrime.securesms.database.ConfigDatabase @@ -49,8 +51,6 @@ class ConfigFactory( private val userGroupsLock = Object() private var _userGroups: UserGroupsConfig? = null - private val isConfigForcedOn by lazy { TextSecurePreferences.hasForcedNewConfig(context) } - private val listeners: MutableList = mutableListOf() fun registerListener(listener: ConfigFactoryUpdateListener) { listeners += listener diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseModule.kt b/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseModule.kt index 30fb40d89a2..d2fd372b93b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseModule.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseModule.kt @@ -8,6 +8,7 @@ import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent import org.session.libsession.database.MessageDataProvider import org.session.libsession.utilities.SSKEnvironment +import org.session.libsession.utilities.TextSecurePreferences import org.thoughtcrime.securesms.attachments.DatabaseAttachmentProvider import org.thoughtcrime.securesms.crypto.AttachmentSecret import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider @@ -32,12 +33,12 @@ object DatabaseModule { @Provides @Singleton - fun provideAttachmentSecret(@ApplicationContext context: Context) = AttachmentSecretProvider.getInstance(context).orCreateAttachmentSecret + fun provideAttachmentSecret(@ApplicationContext context: Context) = AttachmentSecretProvider.getInstance().orCreateAttachmentSecret @Provides @Singleton - fun provideOpenHelper(@ApplicationContext context: Context): SQLCipherOpenHelper { - val dbSecret = DatabaseSecretProvider(context).orCreateDatabaseSecret + fun provideOpenHelper(@ApplicationContext context: Context, prefs: TextSecurePreferences): SQLCipherOpenHelper { + val dbSecret = DatabaseSecretProvider(prefs).orCreateDatabaseSecret SQLCipherOpenHelper.migrateSqlCipher3To4IfNeeded(context, dbSecret) return SQLCipherOpenHelper(context, dbSecret) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/SessionUtilModule.kt b/app/src/main/java/org/thoughtcrime/securesms/dependencies/SessionUtilModule.kt index cd4b0713382..bc8133fad5c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/SessionUtilModule.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/SessionUtilModule.kt @@ -6,8 +6,10 @@ import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.utilities.ConfigFactoryUpdateListener import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs import org.thoughtcrime.securesms.crypto.KeyPairUtilities import org.thoughtcrime.securesms.database.ConfigDatabase import javax.inject.Singleton @@ -25,7 +27,7 @@ object SessionUtilModule { @Singleton fun provideConfigFactory(@ApplicationContext context: Context, configDatabase: ConfigDatabase): ConfigFactory = ConfigFactory(context, configDatabase) { - val localUserPublicKey = TextSecurePreferences.getLocalNumber(context) + val localUserPublicKey = context.prefs.getLocalNumber() val secretKey = maybeUserEdSecretKey(context) if (localUserPublicKey == null || secretKey == null) null else secretKey to localUserPublicKey diff --git a/app/src/main/java/org/thoughtcrime/securesms/giph/ui/GiphyActivity.java b/app/src/main/java/org/thoughtcrime/securesms/giph/ui/GiphyActivity.java index dcfdb661124..c93afa01b04 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/giph/ui/GiphyActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/giph/ui/GiphyActivity.java @@ -18,6 +18,7 @@ import com.google.android.material.tabs.TabLayout; +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsession.utilities.MediaTypes; import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity; import org.session.libsignal.utilities.Log; @@ -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()); setSupportActionBar(toolbar); diff --git a/app/src/main/java/org/thoughtcrime/securesms/giph/ui/GiphyActivityToolbarTextSecurePreferencesPersistence.java b/app/src/main/java/org/thoughtcrime/securesms/giph/ui/GiphyActivityToolbarTextSecurePreferencesPersistence.java deleted file mode 100644 index 3147590d6ab..00000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/giph/ui/GiphyActivityToolbarTextSecurePreferencesPersistence.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.thoughtcrime.securesms.giph.ui; - -import android.content.Context; - -import org.session.libsession.utilities.TextSecurePreferences; - -class GiphyActivityToolbarTextSecurePreferencesPersistence implements GiphyActivityToolbar.Persistence { - - static GiphyActivityToolbar.Persistence fromContext(Context context) { - return new GiphyActivityToolbarTextSecurePreferencesPersistence(context.getApplicationContext()); - } - - private final Context context; - - private GiphyActivityToolbarTextSecurePreferencesPersistence(Context context) { - this.context = context; - } - - @Override - public boolean getGridSelected() { - return TextSecurePreferences.isGifSearchInGridLayout(context); - } - - @Override - public void setGridSelected(boolean isGridSelected) { - TextSecurePreferences.setIsGifSearchInGridLayout(context, isGridSelected); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/giph/ui/GiphyActivityToolbarTextSecurePreferencesPersistence.kt b/app/src/main/java/org/thoughtcrime/securesms/giph/ui/GiphyActivityToolbarTextSecurePreferencesPersistence.kt new file mode 100644 index 00000000000..1e3c1cff446 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/giph/ui/GiphyActivityToolbarTextSecurePreferencesPersistence.kt @@ -0,0 +1,9 @@ +package org.thoughtcrime.securesms.giph.ui + +import org.session.libsession.messaging.MessagingModuleConfiguration.Companion.shared +import org.thoughtcrime.securesms.giph.ui.GiphyActivityToolbar.Persistence + +class GiphyActivityToolbarTextSecurePreferencesPersistence: Persistence { + override fun getGridSelected(): Boolean = shared.prefs.isGifSearchInGridLayout() + override fun setGridSelected(isGridSelected: Boolean) = shared.prefs.setIsGifSearchInGridLayout(isGridSelected) +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/giph/ui/GiphyFragment.java b/app/src/main/java/org/thoughtcrime/securesms/giph/ui/GiphyFragment.java index d4b1d642dc7..7b7c11532e9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/giph/ui/GiphyFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/giph/ui/GiphyFragment.java @@ -16,11 +16,11 @@ import android.view.ViewGroup; import android.widget.TextView; +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.thoughtcrime.securesms.giph.model.GiphyImage; import org.thoughtcrime.securesms.giph.net.GiphyLoader; import org.thoughtcrime.securesms.giph.util.InfiniteScrollListener; import com.bumptech.glide.Glide; -import org.session.libsession.utilities.TextSecurePreferences; import org.session.libsession.utilities.ViewUtil; import java.util.LinkedList; @@ -57,7 +57,7 @@ public void onActivityCreated(Bundle bundle) { this.giphyAdapter = new GiphyAdapter(getActivity(), Glide.with(this), new LinkedList<>()); this.giphyAdapter.setListener(this); - setLayoutManager(TextSecurePreferences.isGifSearchInGridLayout(getContext())); + setLayoutManager(MessagingModuleConfiguration.getShared().getPrefs().isGifSearchInGridLayout()); this.recyclerView.setItemAnimator(new DefaultItemAnimator()); this.recyclerView.setAdapter(giphyAdapter); this.recyclerView.addOnScrollListener(new GiphyScrollListener()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/CreateGroupFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/groups/CreateGroupFragment.kt index acb3af8db4a..3a9288716f6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/CreateGroupFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/CreateGroupFragment.kt @@ -18,11 +18,13 @@ import network.loki.messenger.R import network.loki.messenger.databinding.FragmentCreateGroupBinding import nl.komponents.kovenant.ui.failUi import nl.komponents.kovenant.ui.successUi +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.sending_receiving.MessageSender import org.session.libsession.messaging.sending_receiving.groupSizeLimit import org.session.libsession.utilities.Address import org.session.libsession.utilities.Device import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs import org.session.libsession.utilities.recipients.Recipient import org.thoughtcrime.securesms.contacts.SelectContactsAdapter import org.thoughtcrime.securesms.conversation.start.StartConversationDelegate @@ -88,7 +90,7 @@ class CreateGroupFragment : Fragment() { if (selectedMembers.count() >= groupSizeLimit) { // Minus one because we're going to include self later return@setOnClickListener Toast.makeText(context, R.string.activity_create_closed_group_too_many_group_members_error, Toast.LENGTH_LONG).show() } - val userPublicKey = TextSecurePreferences.getLocalNumber(requireContext())!! + val userPublicKey = requireContext().prefs.getLocalNumber()!! isLoading = true binding.loaderContainer.fadeIn() MessageSender.createClosedGroup(device, name.toString(), selectedMembers + setOf( userPublicKey )).successUi { groupID -> diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/EditClosedGroupActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/groups/EditClosedGroupActivity.kt index 2d9192ac7a9..91ac7c82d0c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/EditClosedGroupActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/EditClosedGroupActivity.kt @@ -22,12 +22,14 @@ import nl.komponents.kovenant.Promise import nl.komponents.kovenant.task import nl.komponents.kovenant.ui.failUi import nl.komponents.kovenant.ui.successUi +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.sending_receiving.MessageSender import org.session.libsession.messaging.sending_receiving.groupSizeLimit import org.session.libsession.utilities.Address import org.session.libsession.utilities.GroupUtil import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.ThemeUtil +import org.session.libsession.utilities.prefs import org.session.libsession.utilities.recipients.Recipient import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.toHexString @@ -107,7 +109,7 @@ class EditClosedGroupActivity : PassphraseRequiredActionBarActivity() { groupID = intent.getStringExtra(groupIDKey)!! val groupInfo = DatabaseComponent.get(this).groupDatabase().getGroup(groupID).get() originalName = groupInfo.title - isSelfAdmin = groupInfo.admins.any{ it.serialize() == TextSecurePreferences.getLocalNumber(this) } + isSelfAdmin = groupInfo.admins.any{ it.serialize() == prefs.getLocalNumber() } name = originalName @@ -291,7 +293,7 @@ class EditClosedGroupActivity : PassphraseRequiredActionBarActivity() { return Toast.makeText(this, R.string.activity_create_closed_group_too_many_group_members_error, Toast.LENGTH_LONG).show() } - val userPublicKey = TextSecurePreferences.getLocalNumber(this)!! + val userPublicKey = prefs.getLocalNumber()!! val userAsRecipient = Recipient.from(this, Address.fromSerialized(userPublicKey), false) if (!members.contains(userAsRecipient) && !members.map { it.address.toString() }.containsAll(originalMembers.minus(userPublicKey))) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/EditClosedGroupMembersAdapter.kt b/app/src/main/java/org/thoughtcrime/securesms/groups/EditClosedGroupMembersAdapter.kt index 5127e3be724..8d5bae9c14a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/EditClosedGroupMembersAdapter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/EditClosedGroupMembersAdapter.kt @@ -3,11 +3,13 @@ package org.thoughtcrime.securesms.groups import android.content.Context import androidx.recyclerview.widget.RecyclerView import android.view.ViewGroup +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.utilities.Address import org.thoughtcrime.securesms.contacts.UserView import com.bumptech.glide.RequestManager import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs class EditClosedGroupMembersAdapter( private val context: Context, @@ -41,7 +43,7 @@ class EditClosedGroupMembersAdapter( override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) { val member = members[position] - val unlocked = admin && member != TextSecurePreferences.getLocalNumber(context) + val unlocked = admin && member != context.prefs.getLocalNumber() viewHolder.view.bind(Recipient.from( context, diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManager.java b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManager.java index d4c5acf4edb..45c478343ab 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManager.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManager.java @@ -56,7 +56,7 @@ public static long getThreadIDFromGroupID(String groupID, @NonNull Context cont final Recipient groupRecipient = Recipient.from(context, Address.fromSerialized(groupId), false); final Set
memberAddresses = new HashSet<>(); - memberAddresses.add(Address.fromSerialized(Objects.requireNonNull(TextSecurePreferences.getLocalNumber(context)))); + memberAddresses.add(Address.fromSerialized(Objects.requireNonNull(MessagingModuleConfiguration.getShared().getPrefs().getLocalNumber()))); groupDatabase.create(groupId, name, new LinkedList<>(memberAddresses), null, null, new LinkedList<>(), System.currentTimeMillis()); groupDatabase.updateProfilePicture(groupId, avatarBytes); diff --git a/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt index a971a5a1a63..38f7c07f3c8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt @@ -20,7 +20,6 @@ import androidx.recyclerview.widget.LinearLayoutManager import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.collectLatest -import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch @@ -38,6 +37,7 @@ import org.session.libsession.utilities.Address import org.session.libsession.utilities.GroupUtil import org.session.libsession.utilities.ProfilePictureModifiedEvent import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs import org.session.libsession.utilities.recipients.Recipient import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.ThreadUtils @@ -162,7 +162,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), // Set up seed reminder view lifecycleScope.launchWhenStarted { binding.seedReminderView.setThemedContent { - if (!textSecurePreferences.getHasViewedSeed()) SeedReminder { start() } + if (!textSecurePreferences.hasViewedSeed()) SeedReminder { start() } } } // Set up recycler view @@ -191,9 +191,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), // subscribe to outdated config updates, this should be removed after long enough time for device migration lifecycleScope.launch { lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { - TextSecurePreferences.events.filter { it == TextSecurePreferences.HAS_RECEIVED_LEGACY_CONFIG }.collect { - updateLegacyConfigView() - } + prefs.hasLegacyConfigFlow().collect(::updateLegacyConfigView) } } @@ -230,10 +228,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), } withContext(Dispatchers.Main) { - updateProfileButton() - TextSecurePreferences.events.filter { it == TextSecurePreferences.PROFILE_NAME_PREF }.collect { - updateProfileButton() - } + prefs.profileNameFlow().collect(::updateProfileButton) } } @@ -337,13 +332,13 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), binding.sessionToolbar.isVisible = !isShown binding.recyclerView.isVisible = !isShown binding.emptyStateContainer.isVisible = (binding.recyclerView.adapter as HomeAdapter).itemCount == 0 && binding.recyclerView.isVisible - binding.seedReminderView.isVisible = !TextSecurePreferences.getHasViewedSeed(this) && !isShown + binding.seedReminderView.isVisible = !prefs.hasViewedSeed() && !isShown binding.globalSearchRecycler.isInvisible = !isShown binding.newConversationButton.isVisible = !isShown } - private fun updateLegacyConfigView() { - binding.configOutdatedView.isVisible = textSecurePreferences.getHasLegacyConfig() + private fun updateLegacyConfigView(hasLegacyConfig: Boolean = textSecurePreferences.getHasLegacyConfig()) { + binding.configOutdatedView.isVisible = hasLegacyConfig } override fun onResume() { @@ -353,7 +348,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), IdentityKeyUtil.checkUpdate(this) binding.profileButton.recycle() // clear cached image before update tje profilePictureView binding.profileButton.update() - if (textSecurePreferences.getHasViewedSeed()) { + if (textSecurePreferences.hasViewedSeed()) { binding.seedReminderView.isVisible = false } @@ -394,9 +389,9 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), } } - private fun updateProfileButton() { + private fun updateProfileButton(profileName: String? = textSecurePreferences.getProfileName()) { binding.profileButton.publicKey = publicKey - binding.profileButton.displayName = textSecurePreferences.getProfileName() + binding.profileButton.displayName = profileName binding.profileButton.recycle() binding.profileButton.update() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/home/HomeViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/home/HomeViewModel.kt index dd6d24cd00d..ac716824806 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/HomeViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/HomeViewModel.kt @@ -16,7 +16,6 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapLatest @@ -60,11 +59,6 @@ class HomeViewModel @Inject constructor( ::Data ).stateIn(viewModelScope, SharingStarted.Eagerly, null) - private fun hasHiddenMessageRequests() = TextSecurePreferences.events - .filter { it == TextSecurePreferences.HAS_HIDDEN_MESSAGE_REQUESTS } - .map { prefs.hasHiddenMessageRequests() } - .onStart { emit(prefs.hasHiddenMessageRequests()) } - private fun observeTypingStatus(): Flow> = ApplicationContext.getInstance(context).typingStatusRepository .typingThreads @@ -74,7 +68,7 @@ class HomeViewModel @Inject constructor( private fun messageRequests() = combine( unapprovedConversationCount(), - hasHiddenMessageRequests(), + prefs.hasHiddenMessageRequestsFlow(), latestUnapprovedConversationTimestamp(), ::createMessageRequests ).flowOn(Dispatchers.IO) diff --git a/app/src/main/java/org/thoughtcrime/securesms/logging/LogSecretProvider.java b/app/src/main/java/org/thoughtcrime/securesms/logging/LogSecretProvider.java index aabd2811db0..9ffaf795b61 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/logging/LogSecretProvider.java +++ b/app/src/main/java/org/thoughtcrime/securesms/logging/LogSecretProvider.java @@ -4,6 +4,7 @@ import android.os.Build; import androidx.annotation.NonNull; +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.thoughtcrime.securesms.crypto.KeyStoreHelper; import org.session.libsignal.utilities.Base64; import org.session.libsession.utilities.TextSecurePreferences; @@ -14,8 +15,8 @@ class LogSecretProvider { static byte[] getOrCreateAttachmentSecret(@NonNull Context context) { - String unencryptedSecret = TextSecurePreferences.getLogUnencryptedSecret(context); - String encryptedSecret = TextSecurePreferences.getLogEncryptedSecret(context); + String unencryptedSecret = MessagingModuleConfiguration.getShared().getPrefs().getLogUnencryptedSecret(); + String encryptedSecret = MessagingModuleConfiguration.getShared().getPrefs().getLogEncryptedSecret(); if (unencryptedSecret != null) return parseUnencryptedSecret(unencryptedSecret); else if (encryptedSecret != null) return parseEncryptedSecret(encryptedSecret); @@ -44,12 +45,8 @@ private static byte[] createAndStoreSecret(@NonNull Context context) { byte[] secret = new byte[32]; random.nextBytes(secret); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(secret); - TextSecurePreferences.setLogEncryptedSecret(context, encryptedSecret.serialize()); - } else { - TextSecurePreferences.setLogUnencryptedSecret(context, Base64.encodeBytes(secret)); - } + KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(secret); + MessagingModuleConfiguration.getShared().getPrefs().setLogEncryptedSecret(encryptedSecret.serialize()); return secret; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/Camera1Fragment.java b/app/src/main/java/org/thoughtcrime/securesms/mediasend/Camera1Fragment.java index 3ef7090c303..60727d3246a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/Camera1Fragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/Camera1Fragment.java @@ -35,6 +35,8 @@ import com.bumptech.glide.request.transition.Transition; import network.loki.messenger.R; + +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsignal.utilities.Log; import com.bumptech.glide.Glide; import org.session.libsession.utilities.ServiceUtil; @@ -78,7 +80,7 @@ public void onCreate(@Nullable Bundle savedInstanceState) { display.getSize(displaySize); controller = (Controller) getActivity(); - camera = new Camera1Controller(TextSecurePreferences.getDirectCaptureCameraId(getContext()), displaySize.x, displaySize.y, this); + camera = new Camera1Controller(MessagingModuleConfiguration.getShared().getPrefs().getDirectCaptureCameraId(), displaySize.x, displaySize.y, this); orderEnforcer = new OrderEnforcer<>(Stage.SURFACE_AVAILABLE, Stage.CAMERA_PROPERTIES_AVAILABLE); viewModel = new ViewModelProvider(requireActivity(), new MediaSendViewModel.Factory(requireActivity().getApplication(), new MediaRepository())).get(MediaSendViewModel.class); } @@ -212,7 +214,7 @@ private void initControls() { flipButton.setVisibility(properties.getCameraCount() > 1 ? View.VISIBLE : View.GONE); flipButton.setOnClickListener(v -> { int newCameraId = camera.flip(); - TextSecurePreferences.setDirectCaptureCameraId(getContext(), newCameraId); + MessagingModuleConfiguration.getShared().getPrefs().setDirectCaptureCameraId(newCameraId); Animation animation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); animation.setDuration(200); diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaSendFragment.java b/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaSendFragment.java index 84722c24c96..9c12d819722 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaSendFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaSendFragment.java @@ -28,6 +28,7 @@ import android.widget.ImageButton; import android.widget.TextView; +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsession.utilities.MediaTypes; import org.thoughtcrime.securesms.components.ComposeText; import org.thoughtcrime.securesms.components.ControllableViewPager; @@ -50,7 +51,6 @@ import org.thoughtcrime.securesms.util.Stopwatch; import org.session.libsignal.utilities.guava.Optional; -import org.session.libsession.utilities.TextSecurePreferences; import org.session.libsession.utilities.Util; import org.session.libsession.utilities.Stub; import org.session.libsignal.utilities.ListenableFuture; @@ -215,7 +215,7 @@ public void onTextChanged(String text) { return isSend; }); - if (TextSecurePreferences.isSystemEmojiPreferred(getContext())) { + if (MessagingModuleConfiguration.getShared().getPrefs().isSystemEmojiPreferred()) { emojiToggle.setVisibility(View.GONE); } else { emojiToggle.setOnClickListener(this::onEmojiToggleClicked); @@ -511,7 +511,7 @@ private class ComposeKeyPressedListener implements View.OnKeyListener, View.OnCl public boolean onKey(View v, int keyCode, KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_DOWN) { if (keyCode == KeyEvent.KEYCODE_ENTER) { - if (TextSecurePreferences.isEnterSendsEnabled(requireContext())) { + if (MessagingModuleConfiguration.getShared().getPrefs().isEnterSendsEnabled()) { sendButton.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER)); sendButton.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER)); return true; diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/SignalGlideModule.java b/app/src/main/java/org/thoughtcrime/securesms/mms/SignalGlideModule.java index 02172b72481..9843840d3e6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mms/SignalGlideModule.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mms/SignalGlideModule.java @@ -58,7 +58,7 @@ public void applyOptions(Context context, GlideBuilder builder) { @Override public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) { - AttachmentSecret attachmentSecret = AttachmentSecretProvider.getInstance(context).getOrCreateAttachmentSecret(); + AttachmentSecret attachmentSecret = AttachmentSecretProvider.getInstance().getOrCreateAttachmentSecret(); byte[] secret = attachmentSecret.getModernKey(); registry.prepend(File.class, File.class, UnitModelLoader.Factory.getInstance()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/AbstractNotificationBuilder.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/AbstractNotificationBuilder.java index 64617eb6a1c..ac8efaddfa2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/AbstractNotificationBuilder.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/AbstractNotificationBuilder.java @@ -11,6 +11,7 @@ import androidx.annotation.Nullable; import androidx.core.app.NotificationCompat; +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsession.utilities.NotificationPrivacyPreference; import org.session.libsession.utilities.TextSecurePreferences; import org.session.libsession.utilities.Util; @@ -50,8 +51,8 @@ protected CharSequence getStyledMessage(@NonNull Recipient recipient, @Nullable } public void setAlarms(@Nullable Uri ringtone, VibrateState vibrate) { - Uri defaultRingtone = NotificationChannels.supported() ? NotificationChannels.getMessageRingtone(context) : TextSecurePreferences.getNotificationRingtone(context); - boolean defaultVibrate = NotificationChannels.supported() ? NotificationChannels.getMessageVibrate(context) : TextSecurePreferences.isNotificationVibrateEnabled(context); + Uri defaultRingtone = NotificationChannels.supported() ? NotificationChannels.getMessageRingtone(context) : MessagingModuleConfiguration.getShared().getPrefs().getNotificationRingtoneUri(); + boolean defaultVibrate = NotificationChannels.supported() ? NotificationChannels.getMessageVibrate(context) : MessagingModuleConfiguration.getShared().getPrefs().isNotificationVibrateEnabled(); if (ringtone == null && !TextUtils.isEmpty(defaultRingtone.toString())) setSound(defaultRingtone); else if (ringtone != null && !ringtone.toString().isEmpty()) setSound(ringtone); @@ -64,7 +65,7 @@ public void setAlarms(@Nullable Uri ringtone, VibrateState vibrate) { } private void setLed() { - int ledColor = TextSecurePreferences.getNotificationLedColor(context); + int ledColor = MessagingModuleConfiguration.getShared().getPrefs().getNotificationLedColor(); setLights(ledColor, 500,2000); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/BackgroundPollWorker.kt b/app/src/main/java/org/thoughtcrime/securesms/notifications/BackgroundPollWorker.kt index 63f6d07da1e..270da644cda 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/BackgroundPollWorker.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/BackgroundPollWorker.kt @@ -22,6 +22,7 @@ import org.session.libsession.messaging.sending_receiving.pollers.ClosedGroupPol import org.session.libsession.messaging.sending_receiving.pollers.OpenGroupPoller import org.session.libsession.snode.SnodeAPI import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.recover import org.thoughtcrime.securesms.dependencies.DatabaseComponent @@ -76,7 +77,7 @@ class BackgroundPollWorker(val context: Context, params: WorkerParameters) : Wor } override fun doWork(): Result { - if (TextSecurePreferences.getLocalNumber(context) == null) { + if (MessagingModuleConfiguration.shared.prefs.getLocalNumber() == null) { Log.v(TAG, "User not registered yet.") return Result.failure() } @@ -108,7 +109,7 @@ class BackgroundPollWorker(val context: Context, params: WorkerParameters) : Wor var dmsPromise: Promise = Promise.ofSuccess(Unit) if (requestTargets.contains(Targets.DMS)) { - val userPublicKey = TextSecurePreferences.getLocalNumber(context)!! + val userPublicKey = context.prefs.getLocalNumber()!! dmsPromise = SnodeAPI.getMessages(userPublicKey).bind { envelopes -> val params = envelopes.map { (envelope, serverHash) -> // FIXME: Using a job here seems like a bad idea... diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java index e80c47a9f61..2ec0efe5757 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java @@ -41,6 +41,7 @@ import com.annimon.stream.Stream; import com.goterl.lazysodium.utils.KeyPair; +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsession.messaging.open_groups.OpenGroup; import org.session.libsession.messaging.sending_receiving.notifications.MessageNotifier; import org.session.libsession.messaging.utilities.AccountId; @@ -139,7 +140,7 @@ public void notifyMessageDeliveryFailed(Context context, Recipient recipient, lo intent.putExtra(ConversationActivityV2.THREAD_ID, threadId); intent.setData((Uri.parse("custom://" + SnodeAPI.getNowWithOffset()))); - FailedNotificationBuilder builder = new FailedNotificationBuilder(context, TextSecurePreferences.getNotificationPrivacy(context), intent); + FailedNotificationBuilder builder = new FailedNotificationBuilder(context, MessagingModuleConfiguration.getShared().getPrefs().getNotificationPrivacy(), intent); ((NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE)) .notify((int)threadId, builder.build()); } @@ -147,9 +148,9 @@ public void notifyMessageDeliveryFailed(Context context, Recipient recipient, lo public void notifyMessagesPending(Context context) { - if (!TextSecurePreferences.isNotificationsEnabled(context)) { return; } + if (!MessagingModuleConfiguration.getShared().getPrefs().isNotificationsEnabled()) { return; } - PendingMessageNotificationBuilder builder = new PendingMessageNotificationBuilder(context, TextSecurePreferences.getNotificationPrivacy(context)); + PendingMessageNotificationBuilder builder = new PendingMessageNotificationBuilder(context, MessagingModuleConfiguration.getShared().getPrefs().getNotificationPrivacy()); ServiceUtil.getNotificationManager(context).notify(PENDING_MESSAGES_ID, builder.build()); } @@ -208,7 +209,7 @@ private void cancelOrphanedNotifications(@NonNull Context context, NotificationS @Override public void updateNotification(@NonNull Context context) { - if (!TextSecurePreferences.isNotificationsEnabled(context)) { + if (!MessagingModuleConfiguration.getShared().getPrefs().isNotificationsEnabled()) { return; } @@ -236,10 +237,10 @@ public void updateNotification(@NonNull Context context, long threadId, boolean if (recipient != null && !recipient.isGroupRecipient() && threads.getMessageCount(threadId) == 1 && !(recipient.isApproved() || threads.getLastSeenAndHasSent(threadId).second())) { - TextSecurePreferences.removeHasHiddenMessageRequests(context); + MessagingModuleConfiguration.getShared().getPrefs().removeHasHiddenMessageRequests(); } - if (!TextSecurePreferences.isNotificationsEnabled(context) || + if (!MessagingModuleConfiguration.getShared().getPrefs().isNotificationsEnabled() || (recipient != null && recipient.isMuted())) { return; @@ -269,7 +270,7 @@ public void updateNotification(@NonNull Context context, boolean signal, int rem try { telcoCursor = DatabaseComponent.get(context).mmsSmsDatabase().getUnread(); // TODO: add a notification specific lighter query here - if ((telcoCursor == null || telcoCursor.isAfterLast()) || TextSecurePreferences.getLocalNumber(context) == null) + if ((telcoCursor == null || telcoCursor.isAfterLast()) || MessagingModuleConfiguration.getShared().getPrefs().getLocalNumber() == null) { updateBadge(context, 0); cancelActiveNotifications(context); @@ -322,7 +323,7 @@ private void sendSingleThreadNotification(@NonNull Context context, return; } - SingleRecipientNotificationBuilder builder = new SingleRecipientNotificationBuilder(context, TextSecurePreferences.getNotificationPrivacy(context)); + SingleRecipientNotificationBuilder builder = new SingleRecipientNotificationBuilder(context, MessagingModuleConfiguration.getShared().getPrefs().getNotificationPrivacy()); List notifications = notificationState.getNotifications(); Recipient recipient = notifications.get(0).getRecipient(); int notificationId = (int) (SUMMARY_NOTIFICATION_ID + (bundled ? notifications.get(0).getThreadId() : 0)); @@ -414,7 +415,7 @@ private void sendMultipleThreadNotification(@NonNull Context context, { Log.i(TAG, "sendMultiThreadNotification() signal: " + signal); - MultipleRecipientNotificationBuilder builder = new MultipleRecipientNotificationBuilder(context, TextSecurePreferences.getNotificationPrivacy(context)); + MultipleRecipientNotificationBuilder builder = new MultipleRecipientNotificationBuilder(context, MessagingModuleConfiguration.getShared().getPrefs().getNotificationPrivacy()); List notifications = notificationState.getNotifications(); builder.setMessageCount(notificationState.getMessageCount(), notificationState.getThreadCount()); @@ -504,7 +505,7 @@ private NotificationState constructNotificationState(@NonNull Context context, threadRecipients = threadDatabase.getRecipientForThreadId(threadId); messageRequest = threadRecipients != null && !threadRecipients.isGroupRecipient() && !threadRecipients.isApproved() && !threadDatabase.getLastSeenAndHasSent(threadId).second(); - if (messageRequest && (threadDatabase.getMessageCount(threadId) > 1 || !TextSecurePreferences.hasHiddenMessageRequests(context))) { + if (messageRequest && (threadDatabase.getMessageCount(threadId) > 1 || !MessagingModuleConfiguration.getShared().getPrefs().hasHiddenMessageRequests())) { continue; } } @@ -541,7 +542,7 @@ private NotificationState constructNotificationState(@NonNull Context context, body = SpanUtil.italic(context.getString(R.string.ThreadRecord_open_group_invitation)); } - String userPublicKey = TextSecurePreferences.getLocalNumber(context); + String userPublicKey = MessagingModuleConfiguration.getShared().getPrefs().getLocalNumber(); String blindedPublicKey = cache.get(threadId); if (blindedPublicKey == null) { blindedPublicKey = generateBlindedId(threadId, context); @@ -612,7 +613,7 @@ private void updateBadge(Context context, int count) { } private void scheduleReminder(Context context, int count) { - if (count >= TextSecurePreferences.getRepeatAlertsCount(context)) { + if (count >= MessagingModuleConfiguration.getShared().getPrefs().getRepeatAlertsCount()) { return; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/MarkReadReceiver.kt b/app/src/main/java/org/thoughtcrime/securesms/notifications/MarkReadReceiver.kt index 59681c1f8a5..096b3f1464a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/MarkReadReceiver.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/MarkReadReceiver.kt @@ -6,15 +6,14 @@ import android.content.Context import android.content.Intent import android.os.AsyncTask import androidx.core.app.NotificationManagerCompat -import org.session.libsession.messaging.MessagingModuleConfiguration.Companion.shared +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.messages.control.ReadReceipt import org.session.libsession.messaging.sending_receiving.MessageSender.send import org.session.libsession.snode.SnodeAPI import org.session.libsession.snode.SnodeAPI.nowWithOffset import org.session.libsession.utilities.SSKEnvironment -import org.session.libsession.utilities.TextSecurePreferences -import org.session.libsession.utilities.TextSecurePreferences.Companion.isReadReceiptsEnabled import org.session.libsession.utilities.associateByNotNull +import org.session.libsession.utilities.prefs import org.session.libsession.utilities.recipients.Recipient import org.session.libsignal.utilities.Log import org.thoughtcrime.securesms.ApplicationContext @@ -35,7 +34,7 @@ class MarkReadReceiver : BroadcastReceiver() { val currentTime = nowWithOffset threadIds.forEach { Log.i(TAG, "Marking as read: $it") - shared.storage.markConversationAsRead(it, currentTime, true) + MessagingModuleConfiguration.shared.storage.markConversationAsRead(it, currentTime, true) } return null } @@ -102,7 +101,7 @@ class MarkReadReceiver : BroadcastReceiver() { SnodeAPI.alterTtl( messageHashes = hashes, newExpiry = nowWithOffset + expiresIn, - publicKey = TextSecurePreferences.getLocalNumber(context)!!, + publicKey = context.prefs.getLocalNumber()!!, shorten = true ) } @@ -112,7 +111,7 @@ class MarkReadReceiver : BroadcastReceiver() { context: Context, markedReadMessages: List ) { - if (!isReadReceiptsEnabled(context)) return + if (!context.prefs.isReadReceiptsEnabled()) return markedReadMessages.map { it.syncMessageId } .filter { shouldSendReadReceipt(Recipient.from(context, it.address, false)) } @@ -130,7 +129,7 @@ class MarkReadReceiver : BroadcastReceiver() { hashToMessage: Map ) { @Suppress("UNCHECKED_CAST") - val expiries = SnodeAPI.getExpiries(hashToMessage.keys.toList(), TextSecurePreferences.getLocalNumber(context)!!).get()["expiries"] as Map + val expiries = SnodeAPI.getExpiries(hashToMessage.keys.toList(), context.prefs.getLocalNumber()!!).get()["expiries"] as Map hashToMessage.forEach { (hash, info) -> expiries[hash]?.let { scheduleDeletion(context, info.expirationInfo, it - info.expirationInfo.expireStarted) } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/MultipleRecipientNotificationBuilder.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/MultipleRecipientNotificationBuilder.java index 7042a1766a0..d67971c1b86 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/MultipleRecipientNotificationBuilder.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/MultipleRecipientNotificationBuilder.java @@ -10,6 +10,7 @@ import androidx.annotation.Nullable; import androidx.core.app.NotificationCompat; +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsession.messaging.contacts.Contact; import org.session.libsession.utilities.NotificationPrivacyPreference; import org.session.libsession.utilities.TextSecurePreferences; @@ -39,7 +40,7 @@ public MultipleRecipientNotificationBuilder(Context context, NotificationPrivacy setGroupSummary(true); if (!NotificationChannels.supported()) { - setPriority(TextSecurePreferences.getNotificationPriority(context)); + setPriority(MessagingModuleConfiguration.getShared().getPrefs().getNotificationPriority()); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationChannels.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationChannels.java index 8bf1d7d8d8a..1ea2c95cb30 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationChannels.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationChannels.java @@ -20,6 +20,7 @@ import com.annimon.stream.Collectors; import com.annimon.stream.Stream; +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsession.utilities.Address; import org.session.libsession.utilities.ServiceUtil; import org.session.libsession.utilities.TextSecurePreferences; @@ -69,10 +70,10 @@ public static synchronized void create(@NonNull Context context) { NotificationManager notificationManager = ServiceUtil.getNotificationManager(context); - int oldVersion = TextSecurePreferences.getNotificationChannelVersion(context); + int oldVersion = MessagingModuleConfiguration.getShared().getPrefs().getNotificationChannelVersion(); if (oldVersion != VERSION) { onUpgrade(notificationManager, oldVersion, VERSION); - TextSecurePreferences.setNotificationChannelVersion(context, VERSION); + MessagingModuleConfiguration.getShared().getPrefs().setNotificationChannelVersion(VERSION); } onCreate(context, notificationManager); @@ -112,7 +113,7 @@ public static synchronized void restoreContactNotificationChannels(@NonNull Cont * @return The channel ID for the default messages channel. */ public static synchronized @NonNull String getMessagesChannel(@NonNull Context context) { - return getMessagesChannelId(TextSecurePreferences.getNotificationMessagesChannelVersion(context)); + return getMessagesChannelId(MessagingModuleConfiguration.getShared().getPrefs().getNotificationMessagesChannelVersion()); } /** @@ -143,7 +144,7 @@ public static boolean supported() { */ public static synchronized String createChannelFor(@NonNull Context context, @NonNull Recipient recipient) { VibrateState vibrateState = recipient.getMessageVibrate(); - boolean vibrationEnabled = vibrateState == VibrateState.DEFAULT ? TextSecurePreferences.isNotificationVibrateEnabled(context) : vibrateState == VibrateState.ENABLED; + boolean vibrationEnabled = vibrateState == VibrateState.DEFAULT ? MessagingModuleConfiguration.getShared().getPrefs().isNotificationVibrateEnabled() : vibrateState == VibrateState.ENABLED; Uri messageRingtone = recipient.getMessageRingtone() != null ? recipient.getMessageRingtone() : getMessageRingtone(context); String displayName = getChannelDisplayNameFor(context, recipient.getName(), recipient.getProfileName(), recipient.getAddress()); @@ -166,7 +167,7 @@ public static synchronized String createChannelFor(@NonNull Context context, @No String channelId = generateChannelIdFor(address); NotificationChannel channel = new NotificationChannel(channelId, displayName, NotificationManager.IMPORTANCE_HIGH); - setLedPreference(channel, TextSecurePreferences.getNotificationLedColor(context)); + setLedPreference(channel, MessagingModuleConfiguration.getShared().getPrefs().getNotificationLedColor()); channel.setGroup(CATEGORY_MESSAGES); channel.enableVibration(vibrationEnabled); @@ -434,9 +435,9 @@ private static void onCreate(@NonNull Context context, @NonNull NotificationMana NotificationChannel other = new NotificationChannel(OTHER, context.getString(R.string.NotificationChannel_other), NotificationManager.IMPORTANCE_LOW); messages.setGroup(CATEGORY_MESSAGES); - messages.enableVibration(TextSecurePreferences.isNotificationVibrateEnabled(context)); - messages.setSound(TextSecurePreferences.getNotificationRingtone(context), getRingtoneAudioAttributes()); - setLedPreference(messages, TextSecurePreferences.getNotificationLedColor(context)); + messages.enableVibration(MessagingModuleConfiguration.getShared().getPrefs().isNotificationVibrateEnabled()); + messages.setSound(MessagingModuleConfiguration.getShared().getPrefs().getNotificationRingtoneUri(), getRingtoneAudioAttributes()); + setLedPreference(messages, MessagingModuleConfiguration.getShared().getPrefs().getNotificationLedColor()); calls.setShowBadge(false); calls.setSound(null, null); @@ -528,12 +529,12 @@ private static void updateAllRecipientChannelLedColors(@NonNull Context context, @TargetApi(26) private static void updateMessageChannel(@NonNull Context context, @NonNull ChannelUpdater updater) { NotificationManager notificationManager = ServiceUtil.getNotificationManager(context); - int existingVersion = TextSecurePreferences.getNotificationMessagesChannelVersion(context); + int existingVersion = MessagingModuleConfiguration.getShared().getPrefs().getNotificationMessagesChannelVersion(); int newVersion = existingVersion + 1; Log.i(TAG, "Updating message channel from version " + existingVersion + " to " + newVersion); if (updateExistingChannel(notificationManager, getMessagesChannelId(existingVersion), getMessagesChannelId(newVersion), updater)) { - TextSecurePreferences.setNotificationMessagesChannelVersion(context, newVersion); + MessagingModuleConfiguration.getShared().getPrefs().setNotificationMessagesChannelVersion(newVersion); } else { onCreate(context, notificationManager); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/PendingMessageNotificationBuilder.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/PendingMessageNotificationBuilder.java index 935d575c569..8b533384a14 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/PendingMessageNotificationBuilder.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/PendingMessageNotificationBuilder.java @@ -7,6 +7,7 @@ import androidx.core.app.NotificationCompat; +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsession.utilities.NotificationPrivacyPreference; import org.session.libsession.utilities.TextSecurePreferences; import org.session.libsession.utilities.recipients.Recipient; @@ -34,7 +35,7 @@ public PendingMessageNotificationBuilder(Context context, NotificationPrivacyPre setAlarms(null, Recipient.VibrateState.DEFAULT); if (!NotificationChannels.supported()) { - setPriority(TextSecurePreferences.getNotificationPriority(context)); + setPriority(MessagingModuleConfiguration.getShared().getPrefs().getNotificationPriority()); } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/SingleRecipientNotificationBuilder.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/SingleRecipientNotificationBuilder.java index 6a0a8e0956e..4167ead26a1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/SingleRecipientNotificationBuilder.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/SingleRecipientNotificationBuilder.java @@ -29,6 +29,7 @@ import org.session.libsession.avatars.ContactColors; import org.session.libsession.avatars.ContactPhoto; import org.session.libsession.avatars.GeneratedContactPhoto; +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsession.messaging.contacts.Contact; import org.session.libsession.utilities.NotificationPrivacyPreference; import org.session.libsession.utilities.TextSecurePreferences; @@ -69,7 +70,7 @@ public SingleRecipientNotificationBuilder(@NonNull Context context, @NonNull Not setCategory(NotificationCompat.CATEGORY_MESSAGE); if (!NotificationChannels.supported()) { - setPriority(TextSecurePreferences.getNotificationPriority(context)); + setPriority(MessagingModuleConfiguration.getShared().getPrefs().getNotificationPriority()); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/TokenManager.kt b/app/src/main/java/org/thoughtcrime/securesms/notifications/TokenManager.kt index b3db642b812..53ee01d63b9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/TokenManager.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/TokenManager.kt @@ -1,7 +1,5 @@ package org.thoughtcrime.securesms.notifications -import android.content.Context -import dagger.hilt.android.qualifiers.ApplicationContext import org.session.libsession.utilities.TextSecurePreferences import javax.inject.Inject import javax.inject.Singleton @@ -10,7 +8,7 @@ private const val INTERVAL: Int = 12 * 60 * 60 * 1000 @Singleton class TokenManager @Inject constructor( - @ApplicationContext private val context: Context, + private val prefs: TextSecurePreferences ) { val hasValidRegistration get() = isRegistered && !isExpired val isRegistered get() = time > 0 @@ -25,8 +23,8 @@ class TokenManager @Inject constructor( } private var time - get() = TextSecurePreferences.getPushRegisterTime(context) - set(value) = TextSecurePreferences.setPushRegisterTime(context, value) + get() = prefs.getPushRegisterTime() + set(value) = prefs.setPushRegisterTime(value) private fun currentTime() = System.currentTimeMillis() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/onboarding/landing/LandingActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/onboarding/landing/LandingActivity.kt index 3be3eafcc2f..a8432b96068 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/onboarding/landing/LandingActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/onboarding/landing/LandingActivity.kt @@ -40,7 +40,7 @@ class LandingActivity: BaseActionBarActivity() { } IdentityKeyUtil.generateIdentityKeyPair(this) - TextSecurePreferences.setPasswordDisabled(this, true) + prefs.setPasswordDisabled(true) // AC: This is a temporary workaround to trick the old code that the screen is unlocked. KeyCachingService.setMasterSecret(applicationContext, Object()) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/onboarding/loadaccount/LoadAccountActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/onboarding/loadaccount/LoadAccountActivity.kt index 3c7a6f6a56c..2bc3fb7831a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/onboarding/loadaccount/LoadAccountActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/onboarding/loadaccount/LoadAccountActivity.kt @@ -30,7 +30,6 @@ class LoadAccountActivity : BaseActionBarActivity() { super.onCreate(savedInstanceState) supportActionBar?.setTitle(R.string.activity_link_load_account) prefs.setConfigurationMessageSynced(false) - prefs.setRestorationTime(System.currentTimeMillis()) prefs.setLastProfileUpdateTime(0) lifecycleScope.launch { diff --git a/app/src/main/java/org/thoughtcrime/securesms/onboarding/loading/LoadingActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/onboarding/loading/LoadingActivity.kt index 9c8a1869d4f..01ffe94d951 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/onboarding/loading/LoadingActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/onboarding/loading/LoadingActivity.kt @@ -28,8 +28,6 @@ class LoadingActivity: BaseActionBarActivity() { private val viewModel: LoadingViewModel by viewModels() private fun register(loadFailed: Boolean) { - prefs.setLastConfigurationSyncTime(System.currentTimeMillis()) - when { loadFailed -> startPickDisplayNameActivity(loadFailed = true) else -> startHomeActivity(isNewAccount = false) diff --git a/app/src/main/java/org/thoughtcrime/securesms/onboarding/loading/LoadingViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/onboarding/loading/LoadingViewModel.kt index a7871d5620e..4feced46c2b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/onboarding/loading/LoadingViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/onboarding/loading/LoadingViewModel.kt @@ -67,10 +67,8 @@ internal class LoadingViewModel @Inject constructor( viewModelScope.launch(Dispatchers.IO) { try { - TextSecurePreferences.events - .filter { it == TextSecurePreferences.CONFIGURATION_SYNCED } - .onStart { emit(TextSecurePreferences.CONFIGURATION_SYNCED) } - .filter { prefs.getConfigurationMessageSynced() } + prefs.configurationMessageSyncedFlow() + .filter { it } .timeout(TIMEOUT_TIME) .collectLatest { onSuccess() } } catch (e: Exception) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/onboarding/manager/CreateAccountManager.kt b/app/src/main/java/org/thoughtcrime/securesms/onboarding/manager/CreateAccountManager.kt index 1e0a21d571f..c80f154de36 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/onboarding/manager/CreateAccountManager.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/onboarding/manager/CreateAccountManager.kt @@ -40,6 +40,5 @@ class CreateAccountManager @Inject constructor( val registrationID = KeyHelper.generateRegistrationId(false) prefs.setLocalRegistrationId(registrationID) prefs.setLocalNumber(userHexEncodedPublicKey) - prefs.setRestorationTime(0) } } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/onboarding/manager/LoadAccountManager.kt b/app/src/main/java/org/thoughtcrime/securesms/onboarding/manager/LoadAccountManager.kt index 5a401038305..56be169b957 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/onboarding/manager/LoadAccountManager.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/onboarding/manager/LoadAccountManager.kt @@ -48,7 +48,6 @@ class LoadAccountManager @Inject constructor( prefs.apply { setLocalRegistrationId(registrationID) setLocalNumber(userHexEncodedPublicKey) - setRestorationTime(System.currentTimeMillis()) setHasViewedSeed(true) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/CallToggleListener.kt b/app/src/main/java/org/thoughtcrime/securesms/preferences/CallToggleListener.kt index ea747798c89..5fc52a5ae22 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/CallToggleListener.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/CallToggleListener.kt @@ -4,13 +4,13 @@ import android.Manifest import androidx.fragment.app.Fragment import androidx.preference.Preference import network.loki.messenger.R -import org.session.libsession.utilities.TextSecurePreferences -import org.session.libsession.utilities.TextSecurePreferences.Companion.setBooleanPreference +import org.session.libsession.messaging.MessagingModuleConfiguration +import org.session.libsession.utilities.prefs import org.thoughtcrime.securesms.permissions.Permissions import org.thoughtcrime.securesms.showSessionDialog internal class CallToggleListener( - private val context: Fragment, + private val fragment: Fragment, private val setCallback: (Boolean) -> Unit ) : Preference.OnPreferenceChangeListener { @@ -18,7 +18,7 @@ internal class CallToggleListener( if (newValue == false) return true // check if we've shown the info dialog and check for microphone permissions - context.showSessionDialog { + fragment.showSessionDialog { title(R.string.dialog_voice_video_title) text(R.string.dialog_voice_video_message) button(R.string.dialog_link_preview_enable_button_title, R.string.AccessibilityId_enable) { requestMicrophonePermission() } @@ -29,14 +29,10 @@ internal class CallToggleListener( } private fun requestMicrophonePermission() { - Permissions.with(context) + Permissions.with(fragment) .request(Manifest.permission.RECORD_AUDIO) .onAllGranted { - setBooleanPreference( - context.requireContext(), - TextSecurePreferences.CALL_NOTIFICATIONS_ENABLED, - true - ) + fragment.requireContext().prefs.setCallNotificationsEnabled(true) setCallback(true) } .onAnyDenied { setCallback(false) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/CorrectedPreferenceFragment.java b/app/src/main/java/org/thoughtcrime/securesms/preferences/CorrectedPreferenceFragment.java index 8c3e6190edc..690a8b89fe4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/CorrectedPreferenceFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/CorrectedPreferenceFragment.java @@ -13,7 +13,6 @@ import androidx.annotation.NonNull; import androidx.core.content.ContextCompat; import androidx.core.view.ViewCompat; -import androidx.fragment.app.DialogFragment; import androidx.preference.Preference; import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceFragmentCompat; @@ -22,7 +21,6 @@ import androidx.preference.PreferenceViewHolder; import androidx.recyclerview.widget.RecyclerView; -import org.thoughtcrime.securesms.components.CustomDefaultPreference; import org.thoughtcrime.securesms.conversation.v2.ViewUtil; import network.loki.messenger.R; @@ -54,22 +52,6 @@ public void onActivityCreated(Bundle savedInstanceState) { setDivider(null); } - @Override - public void onDisplayPreferenceDialog(Preference preference) { - DialogFragment dialogFragment = null; - - if (preference instanceof CustomDefaultPreference) { - dialogFragment = CustomDefaultPreference.CustomDefaultPreferenceDialogFragmentCompat.newInstance(preference.getKey()); - } - - if (dialogFragment != null) { - dialogFragment.setTargetFragment(this, 0); - dialogFragment.show(getFragmentManager(), "android.support.v7.preference.PreferenceFragment.DIALOG"); - } else { - super.onDisplayPreferenceDialog(preference); - } - } - @Override @SuppressLint("RestrictedApi") protected RecyclerView.Adapter onCreateAdapter(PreferenceScreen preferenceScreen) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/NotificationsPreferenceFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/preferences/NotificationsPreferenceFragment.kt index fa6461acc44..7458cd739fa 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/NotificationsPreferenceFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/NotificationsPreferenceFragment.kt @@ -19,7 +19,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import network.loki.messenger.R import org.session.libsession.utilities.TextSecurePreferences -import org.session.libsession.utilities.TextSecurePreferences.Companion.isNotificationsEnabled +import org.session.libsession.utilities.findPreference import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.components.SwitchPreferenceCompat import org.thoughtcrime.securesms.notifications.NotificationChannels @@ -73,7 +73,7 @@ class NotificationsPreferenceFragment : ListSummaryPreferenceFragment() { } findPreference(TextSecurePreferences.RINGTONE_PREF)!!.onPreferenceClickListener = Preference.OnPreferenceClickListener { - val current = prefs.getNotificationRingtone() + val current = prefs.getNotificationRingtoneUri() val intent = Intent(RingtoneManager.ACTION_RINGTONE_PICKER) intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true) intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, true) @@ -151,7 +151,7 @@ class NotificationsPreferenceFragment : ListSummaryPreferenceFragment() { private fun initializeRingtoneSummary(pref: Preference?) { val listener = pref!!.onPreferenceChangeListener as RingtoneSummaryListener? - val uri = prefs.getNotificationRingtone() + val uri = prefs.getNotificationRingtoneUri() listener!!.onPreferenceChange(pref, uri) } @@ -171,13 +171,4 @@ class NotificationsPreferenceFragment : ListSummaryPreferenceFragment() { return super.onPreferenceChange(preference, value) } } - - companion object { - @Suppress("unused") - private val TAG = NotificationsPreferenceFragment::class.java.simpleName - fun getSummary(context: Context): CharSequence = when (isNotificationsEnabled(context)) { - true -> R.string.ApplicationPreferencesActivity_On - false -> R.string.ApplicationPreferencesActivity_Off - }.let(context::getString) - } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/PrivacySettingsPreferenceFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/preferences/PrivacySettingsPreferenceFragment.kt index 21b12496bdc..16eb25690b7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/PrivacySettingsPreferenceFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/PrivacySettingsPreferenceFragment.kt @@ -13,9 +13,10 @@ import androidx.preference.PreferenceDataStore import dagger.hilt.android.AndroidEntryPoint import network.loki.messenger.BuildConfig import network.loki.messenger.R +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.utilities.TextSecurePreferences -import org.session.libsession.utilities.TextSecurePreferences.Companion.isPasswordDisabled -import org.session.libsession.utilities.TextSecurePreferences.Companion.setScreenLockEnabled +import org.session.libsession.utilities.findPreference +import org.session.libsession.utilities.prefs import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.components.SwitchPreferenceCompat import org.thoughtcrime.securesms.dependencies.ConfigFactory @@ -30,6 +31,7 @@ import javax.inject.Inject class PrivacySettingsPreferenceFragment : ListSummaryPreferenceFragment() { @Inject lateinit var configFactory: ConfigFactory + @Inject lateinit var prefs: TextSecurePreferences override fun onCreate(paramBundle: Bundle?) { super.onCreate(paramBundle) @@ -109,12 +111,8 @@ class PrivacySettingsPreferenceFragment : ListSummaryPreferenceFragment() { addPreferencesFromResource(R.xml.preferences_app_protection) } - override fun onResume() { - super.onResume() - } - private fun initializeVisibility() { - if (isPasswordDisabled(requireContext())) { + if (prefs.isPasswordDisabled()) { val keyguardManager = requireContext().getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager if (!keyguardManager.isKeyguardSecure) { @@ -130,10 +128,10 @@ class PrivacySettingsPreferenceFragment : ListSummaryPreferenceFragment() { private inner class ScreenLockListener : Preference.OnPreferenceChangeListener { override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean { val enabled = newValue as Boolean - setScreenLockEnabled(context!!, enabled) + requireContext().prefs.setScreenLockEnabled(enabled) val intent = Intent(context, KeyCachingService::class.java) intent.action = KeyCachingService.LOCK_TOGGLED_EVENT - context!!.startService(intent) + requireContext().startService(intent) return true } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/QRCodeActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/preferences/QRCodeActivity.kt index 9778a1c8b8c..17d831400fc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/QRCodeActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/QRCodeActivity.kt @@ -18,8 +18,10 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.asSharedFlow import network.loki.messenger.R +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.utilities.Address import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs import org.session.libsession.utilities.recipients.Recipient import org.session.libsignal.utilities.PublicKeyValidation import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity @@ -47,7 +49,7 @@ class QRCodeActivity : PassphraseRequiredActionBarActivity() { setComposeContent { Tabs( - TextSecurePreferences.getLocalNumber(this)!!, + prefs.getLocalNumber()!!, errors.asSharedFlow(), onScan = ::onScan ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/SettingsActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/preferences/SettingsActivity.kt index fc98070ca40..58a0841a557 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/SettingsActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/SettingsActivity.kt @@ -107,7 +107,7 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() { set(value) { field = value; handleDisplayNameEditActionModeChanged() } private var tempFile: File? = null - private val hexEncodedPublicKey: String get() = TextSecurePreferences.getLocalNumber(this)!! + private val hexEncodedPublicKey: String get() = prefs.getLocalNumber()!! companion object { private const val SCROLL_STATE = "SCROLL_STATE" @@ -139,7 +139,7 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() { } private fun getDisplayName(): String = - TextSecurePreferences.getProfileName(this) ?: truncateIdForDisplay(hexEncodedPublicKey) + prefs.getProfileName() ?: truncateIdForDisplay(hexEncodedPublicKey) private fun setupProfilePictureView(view: ProfilePictureView) { view.apply { @@ -256,7 +256,7 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() { Log.w(TAG, "Cannot update display name - no network connection.") } else { // if we have a network connection then attempt to update the display name - TextSecurePreferences.setProfileName(this, displayName) + prefs.setProfileName(displayName) val user = configFactory.user if (user == null) { Log.w(TAG, "Cannot update display name - missing user details from configFactory.") @@ -293,7 +293,7 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() { } val userConfig = configFactory.user - AvatarHelper.setAvatar(this, Address.fromSerialized(TextSecurePreferences.getLocalNumber(this)!!), profilePicture) + AvatarHelper.setAvatar(this, Address.fromSerialized(prefs.getLocalNumber()!!), profilePicture) prefs.setProfileAvatarId(SecureRandom().nextInt() ) ProfileKeyUtil.setEncodedProfileKey(this, encodedProfileKey) diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/Util.kt b/app/src/main/java/org/thoughtcrime/securesms/preferences/Util.kt index 1271ece02e8..58f537f7280 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/Util.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/Util.kt @@ -6,7 +6,9 @@ import android.content.Context import android.content.Intent import android.widget.Toast import network.loki.messenger.R +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs fun Context.sendInvitationToUseSession() { Intent().apply { @@ -15,7 +17,7 @@ fun Context.sendInvitationToUseSession() { Intent.EXTRA_TEXT, getString( R.string.accountIdShare, - TextSecurePreferences.getLocalNumber(this@sendInvitationToUseSession) + prefs.getLocalNumber() ) ) type = "text/plain" @@ -25,7 +27,7 @@ fun Context.sendInvitationToUseSession() { fun Context.copyPublicKey() { val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - val clip = ClipData.newPlainText("Account ID", TextSecurePreferences.getLocalNumber(this)) + val clip = ClipData.newPlainText("Account ID", prefs.getLocalNumber()) clipboard.setPrimaryClip(clip) Toast.makeText(this, R.string.copied_to_clipboard, Toast.LENGTH_SHORT).show() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/providers/BlobProvider.java b/app/src/main/java/org/thoughtcrime/securesms/providers/BlobProvider.java index 6d900a5b374..269e13cb3ba 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/providers/BlobProvider.java +++ b/app/src/main/java/org/thoughtcrime/securesms/providers/BlobProvider.java @@ -98,7 +98,7 @@ public BlobBuilder forData(@NonNull InputStream data, long fileSize) { String directory = getDirectory(storageType); File file = new File(getOrCreateCacheDirectory(context, directory), buildFileName(id)); - return ModernDecryptingPartInputStream.createFor(AttachmentSecretProvider.getInstance(context).getOrCreateAttachmentSecret(), file, 0); + return ModernDecryptingPartInputStream.createFor(AttachmentSecretProvider.getInstance().getOrCreateAttachmentSecret(), file, 0); } } else { throw new IOException("Provided URI does not match this spec. Uri: " + uri); @@ -174,7 +174,7 @@ public static boolean isAuthority(@NonNull Uri uri) { @WorkerThread private synchronized @NonNull Uri writeBlobSpecToDisk(@NonNull Context context, @NonNull BlobSpec blobSpec, @Nullable ErrorListener errorListener) throws IOException { - AttachmentSecret attachmentSecret = AttachmentSecretProvider.getInstance(context).getOrCreateAttachmentSecret(); + AttachmentSecret attachmentSecret = AttachmentSecretProvider.getInstance().getOrCreateAttachmentSecret(); String directory = getDirectory(blobSpec.getStorageType()); File outputFile = new File(getOrCreateCacheDirectory(context, directory), buildFileName(blobSpec.id)); OutputStream outputStream = ModernEncryptingPartOutputStream.createFor(attachmentSecret, outputFile, true).second; diff --git a/app/src/main/java/org/thoughtcrime/securesms/recoverypassword/RecoveryPasswordViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/recoverypassword/RecoveryPasswordViewModel.kt index 0ad207cd236..a290e7881e3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recoverypassword/RecoveryPasswordViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/recoverypassword/RecoveryPasswordViewModel.kt @@ -10,12 +10,10 @@ import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted -import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch -import org.session.libsession.utilities.AppTextSecurePreferences import org.session.libsession.utilities.TextSecurePreferences import org.session.libsignal.crypto.MnemonicCodec import org.session.libsignal.utilities.hexEncodedPrivateKey @@ -27,7 +25,7 @@ import javax.inject.Inject class RecoveryPasswordViewModel @Inject constructor( private val application: Application ): AndroidViewModel(application) { - val prefs = AppTextSecurePreferences(application) + val prefs = TextSecurePreferences(application) val seed = MutableStateFlow(null) val mnemonic = seed.filterNotNull() diff --git a/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorFragment.java b/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorFragment.java index 39b75c7a828..d2962b6d0cb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorFragment.java @@ -12,6 +12,8 @@ import android.view.ViewGroup; import network.loki.messenger.R; + +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.thoughtcrime.securesms.imageeditor.ColorableRenderer; import org.thoughtcrime.securesms.imageeditor.ImageEditorView; import org.thoughtcrime.securesms.imageeditor.Renderer; @@ -209,7 +211,7 @@ private void changeEntityColor(int selectedColor) { } private void startTextEntityEditing(@NonNull EditorElement textElement, boolean selectAll) { - imageEditorView.startTextEditing(textElement, TextSecurePreferences.isIncognitoKeyboardEnabled(requireContext()), selectAll); + imageEditorView.startTextEditing(textElement, MessagingModuleConfiguration.getShared().getPrefs().isIncognitoKeyboardEnabled(), selectAll); } protected void addText() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/search/SearchRepository.java b/app/src/main/java/org/thoughtcrime/securesms/search/SearchRepository.java index 204b63f8027..83119e090b3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/search/SearchRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/search/SearchRepository.java @@ -6,6 +6,8 @@ import android.database.MergeCursor; import androidx.annotation.NonNull; import com.annimon.stream.Stream; + +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsession.messaging.contacts.Contact; import org.session.libsession.utilities.Address; import org.session.libsession.utilities.GroupRecord; @@ -137,7 +139,7 @@ public Pair, List> queryContacts(String query) { private CursorList queryConversations(@NonNull String query, List matchingAddresses) { List numbers = contactAccessor.getNumbersForThreadSearchFilter(context, query); - String localUserNumber = TextSecurePreferences.getLocalNumber(context); + String localUserNumber = MessagingModuleConfiguration.getShared().getPrefs().getLocalNumber(); if (localUserNumber != null) { matchingAddresses.remove(localUserNumber); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/ExpiringMessageManager.kt b/app/src/main/java/org/thoughtcrime/securesms/service/ExpiringMessageManager.kt index 2f6ad7fd8b6..546c6eb931e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/ExpiringMessageManager.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/service/ExpiringMessageManager.kt @@ -3,7 +3,7 @@ package org.thoughtcrime.securesms.service import android.content.Context import network.loki.messenger.libsession_util.util.ExpiryMode import network.loki.messenger.libsession_util.util.ExpiryMode.AfterSend -import org.session.libsession.messaging.MessagingModuleConfiguration.Companion.shared +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate import org.session.libsession.messaging.messages.signal.IncomingMediaMessage import org.session.libsession.messaging.messages.signal.OutgoingExpirationUpdateMessage @@ -12,7 +12,7 @@ import org.session.libsession.utilities.Address.Companion.fromSerialized import org.session.libsession.utilities.GroupUtil.doubleEncodeGroupID import org.session.libsession.utilities.GroupUtil.getDecodedGroupIDAsData import org.session.libsession.utilities.SSKEnvironment.MessageExpirationManagerProtocol -import org.session.libsession.utilities.TextSecurePreferences.Companion.getLocalNumber +import org.session.libsession.utilities.prefs import org.session.libsession.utilities.recipients.Recipient import org.session.libsignal.messages.SignalServiceGroup import org.session.libsignal.utilities.Log @@ -87,7 +87,7 @@ class ExpiringMessageManager(context: Context) : MessageExpirationManagerProtoco val groupAddress = fromSerialized(groupID) recipient = Recipient.from(context, groupAddress, false) } - val threadId = shared.storage.getThreadId(recipient) ?: return + val threadId = MessagingModuleConfiguration.shared.storage.getThreadId(recipient) ?: return val mediaMessage = IncomingMediaMessage( address, sentTimestamp!!, -1, expiresInMillis, expireStartedAt, true, @@ -125,7 +125,7 @@ class ExpiringMessageManager(context: Context) : MessageExpirationManagerProtoco val address = fromSerialized(serializedAddress) val recipient = Recipient.from(context, address, false) - message.threadID = shared.storage.getOrCreateThreadIdFor(address) + message.threadID = MessagingModuleConfiguration.shared.storage.getOrCreateThreadIdFor(address) val timerUpdateMessage = OutgoingExpirationUpdateMessage( recipient, sentTimestamp!!, @@ -149,7 +149,7 @@ class ExpiringMessageManager(context: Context) : MessageExpirationManagerProtoco override fun insertExpirationTimerMessage(message: ExpirationTimerUpdate) { val expiryMode: ExpiryMode = message.expiryMode - val userPublicKey = getLocalNumber(context) + val userPublicKey = context.prefs.getLocalNumber() val senderPublicKey = message.sender val sentTimestamp = message.sentTimestamp ?: 0 val expireStartedAt = if ((expiryMode is AfterSend || message.isSenderSelf) && !message.isGroup) sentTimestamp else 0 diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/KeyCachingService.java b/app/src/main/java/org/thoughtcrime/securesms/service/KeyCachingService.java index f919af7ad66..e0f03c47d16 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/KeyCachingService.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/KeyCachingService.java @@ -16,6 +16,8 @@ */ package org.thoughtcrime.securesms.service; +import static org.session.libsession.utilities.TextSecurePreferencesKt.getPrefs; + import android.annotation.SuppressLint; import android.app.AlarmManager; import android.app.Notification; @@ -38,6 +40,7 @@ import org.session.libsession.utilities.ServiceUtil; import org.session.libsession.utilities.TextSecurePreferences; +import org.session.libsession.utilities.TextSecurePreferencesKt; import org.session.libsignal.utilities.Log; import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.DatabaseUpgradeActivity; @@ -68,12 +71,13 @@ public class KeyCachingService extends Service { private static final String PASSPHRASE_EXPIRED_EVENT = "org.thoughtcrime.securesms.service.action.PASSPHRASE_EXPIRED_EVENT"; public static final String CLEAR_KEY_ACTION = "org.thoughtcrime.securesms.service.action.CLEAR_KEY"; - private final IBinder binder = new KeySetBinder(); - // AC: This is a temporal drop off replacement for the refactoring time being. // This field only indicates if the app was unlocked or not (null means locked). private static Object masterSecret = null; + private final IBinder binder = new KeySetBinder(); + private final TextSecurePreferences prefs = getPrefs(this); + /** * A temporal utility method to quickly call {@link KeyCachingService#setMasterSecret(Object)} * without explicitly binding to the service. @@ -100,7 +104,9 @@ public void onServiceDisconnected(ComponentName name) { public KeyCachingService() {} public static synchronized boolean isLocked(Context context) { - boolean enabled = !TextSecurePreferences.isPasswordDisabled(context) || TextSecurePreferences.isScreenLockEnabled(context); + TextSecurePreferences prefs = ApplicationContext.getInstance(context).getPrefs(); + + boolean enabled = !prefs.isPasswordDisabled() || prefs.isScreenLockEnabled(); return getMasterSecret(context) == null && enabled; } @@ -156,7 +162,7 @@ public void onCreate() { Log.i(TAG, "onCreate()"); super.onCreate(); - if (TextSecurePreferences.isPasswordDisabled(this) && !TextSecurePreferences.isScreenLockEnabled(this)) { + if (prefs.isPasswordDisabled() && !prefs.isScreenLockEnabled()) { setMasterSecret(new Object()); } } @@ -205,22 +211,24 @@ private void handleLockToggled() { } private static void startTimeoutIfAppropriate(@NonNull Context context) { + TextSecurePreferences prefs = ApplicationContext.getInstance(context).getPrefs(); + boolean appVisible = ApplicationContext.getInstance(context).isAppVisible(); boolean secretSet = KeyCachingService.masterSecret != null; - boolean timeoutEnabled = TextSecurePreferences.isPassphraseTimeoutEnabled(context); - boolean passLockActive = timeoutEnabled && !TextSecurePreferences.isPasswordDisabled(context); + boolean timeoutEnabled = prefs.isPassphraseTimeoutEnabled(); + boolean passLockActive = timeoutEnabled && !prefs.isPasswordDisabled(); - long screenTimeout = TextSecurePreferences.getScreenLockTimeout(context); - boolean screenLockActive = screenTimeout >= 0 && TextSecurePreferences.isScreenLockEnabled(context); + long screenTimeout = prefs.getScreenLockTimeout(); + boolean screenLockActive = screenTimeout >= 0 && prefs.isScreenLockEnabled(); if (!appVisible && secretSet && (passLockActive || screenLockActive)) { - long passphraseTimeoutMinutes = TextSecurePreferences.getPassphraseTimeoutInterval(context); - long screenLockTimeoutSeconds = TextSecurePreferences.getScreenLockTimeout(context); + long passphraseTimeoutMinutes = prefs.getPassphraseTimeoutInterval(); + long screenLockTimeoutSeconds = prefs.getScreenLockTimeout(); long timeoutMillis; - if (!TextSecurePreferences.isPasswordDisabled(context)) timeoutMillis = TimeUnit.MINUTES.toMillis(passphraseTimeoutMinutes); + if (!prefs.isPasswordDisabled()) timeoutMillis = TimeUnit.MINUTES.toMillis(passphraseTimeoutMinutes); else timeoutMillis = TimeUnit.SECONDS.toMillis(screenLockTimeoutSeconds); Log.i(TAG, "Starting timeout: " + timeoutMillis); @@ -234,7 +242,7 @@ private static void startTimeoutIfAppropriate(@NonNull Context context) { } private void foregroundService() { - if (TextSecurePreferences.isPasswordDisabled(this) && !TextSecurePreferences.isScreenLockEnabled(this)) { + if (prefs.isPasswordDisabled() && !prefs.isScreenLockEnabled()) { stopForeground(true); return; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/PanicResponderListener.java b/app/src/main/java/org/thoughtcrime/securesms/service/PanicResponderListener.java index a23544d570a..77db93111de 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/PanicResponderListener.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/PanicResponderListener.java @@ -6,6 +6,8 @@ import android.os.Build; import org.session.libsession.utilities.TextSecurePreferences; +import org.session.libsession.utilities.TextSecurePreferencesKt; +import org.thoughtcrime.securesms.ApplicationContext; /** * Respond to a PanicKit trigger Intent by locking the app. PanicKit provides a @@ -18,7 +20,8 @@ public class PanicResponderListener extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { - if (intent != null && !TextSecurePreferences.isPasswordDisabled(context) && + TextSecurePreferences prefs = ApplicationContext.getInstance(context).getPrefs(); + if (intent != null && !prefs.isPasswordDisabled() && "info.guardianproject.panic.action.TRIGGER".equals(intent.getAction())) { Intent lockIntent = new Intent(context, KeyCachingService.class); diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/UpdateApkReadyListener.java b/app/src/main/java/org/thoughtcrime/securesms/service/UpdateApkReadyListener.java deleted file mode 100644 index eea6ba00f8e..00000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/service/UpdateApkReadyListener.java +++ /dev/null @@ -1,121 +0,0 @@ -package org.thoughtcrime.securesms.service; - - -import android.app.DownloadManager; -import android.app.Notification; -import android.app.PendingIntent; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.database.Cursor; -import android.net.Uri; - -import androidx.annotation.Nullable; -import androidx.core.app.NotificationCompat; - -import org.session.libsession.utilities.FileUtils; -import org.session.libsession.utilities.ServiceUtil; -import org.session.libsession.utilities.TextSecurePreferences; -import org.session.libsignal.utilities.Hex; -import org.session.libsignal.utilities.Log; -import org.thoughtcrime.securesms.notifications.NotificationChannels; -import org.thoughtcrime.securesms.util.FileProviderUtil; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.security.MessageDigest; - -import network.loki.messenger.R; - -public class UpdateApkReadyListener extends BroadcastReceiver { - - private static final String TAG = UpdateApkReadyListener.class.getSimpleName(); - - @Override - public void onReceive(Context context, Intent intent) { - Log.i(TAG, "onReceive()"); - - if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) { - long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -2); - - if (downloadId == TextSecurePreferences.getUpdateApkDownloadId(context)) { - Uri uri = getLocalUriForDownloadId(context, downloadId); - String encodedDigest = TextSecurePreferences.getUpdateApkDigest(context); - - if (uri == null) { - Log.w(TAG, "Downloaded local URI is null?"); - return; - } - - if (isMatchingDigest(context, downloadId, encodedDigest)) { - displayInstallNotification(context, uri); - } else { - Log.w(TAG, "Downloaded APK doesn't match digest..."); - } - } - } - } - - private void displayInstallNotification(Context context, Uri uri) { - Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE); - intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - intent.setData(uri); - - PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE); - - Notification notification = new NotificationCompat.Builder(context, NotificationChannels.APP_UPDATES) - .setOngoing(true) - .setContentTitle(context.getString(R.string.UpdateApkReadyListener_Signal_update)) - .setContentText(context.getString(R.string.UpdateApkReadyListener_a_new_version_of_signal_is_available_tap_to_update)) - .setSmallIcon(R.drawable.ic_notification) - .setColor(context.getResources().getColor(R.color.textsecure_primary)) - .setPriority(NotificationCompat.PRIORITY_HIGH) - .setCategory(NotificationCompat.CATEGORY_REMINDER) - .setContentIntent(pendingIntent) - .build(); - - ServiceUtil.getNotificationManager(context).notify(666, notification); - } - - private @Nullable Uri getLocalUriForDownloadId(Context context, long downloadId) { - DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); - DownloadManager.Query query = new DownloadManager.Query(); - query.setFilterById(downloadId); - - Cursor cursor = downloadManager.query(query); - - try { - if (cursor != null && cursor.moveToFirst()) { - String localUri = cursor.getString(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_LOCAL_URI)); - - if (localUri != null) { - File localFile = new File(Uri.parse(localUri).getPath()); - return FileProviderUtil.getUriFor(context, localFile); - } - } - } finally { - if (cursor != null) cursor.close(); - } - - return null; - } - - private boolean isMatchingDigest(Context context, long downloadId, String theirEncodedDigest) { - try { - if (theirEncodedDigest == null) return false; - - byte[] theirDigest = Hex.fromStringCondensed(theirEncodedDigest); - DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); - FileInputStream fin = new FileInputStream(downloadManager.openDownloadedFile(downloadId).getFileDescriptor()); - byte[] ourDigest = FileUtils.getFileDigest(fin); - - fin.close(); - - return MessageDigest.isEqual(ourDigest, theirDigest); - } catch (IOException e) { - Log.w(TAG, e); - return false; - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt b/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt index d6383ab7fcd..88718a9d483 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt @@ -2,12 +2,14 @@ package org.thoughtcrime.securesms.sskenvironment import android.content.Context import network.loki.messenger.libsession_util.util.UserPic +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.contacts.Contact import org.session.libsession.messaging.jobs.JobQueue import org.session.libsession.messaging.jobs.RetrieveProfileAvatarJob import org.session.libsession.messaging.utilities.AccountId import org.session.libsession.utilities.SSKEnvironment import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs import org.session.libsession.utilities.recipients.Recipient import org.session.libsignal.utilities.IdPrefix import org.thoughtcrime.securesms.dependencies.ConfigFactory @@ -91,7 +93,7 @@ class ProfileManager(private val context: Context, private val configFactory: Co override fun contactUpdatedInternal(contact: Contact): String? { val contactConfig = configFactory.contacts ?: return null - if (contact.accountID == TextSecurePreferences.getLocalNumber(context)) return null + if (contact.accountID == context.prefs.getLocalNumber()) return null val accountId = AccountId(contact.accountID) if (accountId.prefix != IdPrefix.STANDARD) return null // only internally store standard account IDs contactConfig.upsertContact(contact.accountID) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ReadReceiptManager.kt b/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ReadReceiptManager.kt index bdf42f0e46e..f8f58dc3c28 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ReadReceiptManager.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ReadReceiptManager.kt @@ -1,9 +1,11 @@ package org.thoughtcrime.securesms.sskenvironment import android.content.Context +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.utilities.Address import org.session.libsession.utilities.SSKEnvironment import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs import org.session.libsignal.utilities.Log import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId import org.thoughtcrime.securesms.dependencies.DatabaseComponent @@ -11,7 +13,7 @@ import org.thoughtcrime.securesms.dependencies.DatabaseComponent class ReadReceiptManager: SSKEnvironment.ReadReceiptManagerProtocol { override fun processReadReceipts(context: Context, fromRecipientId: String, sentTimestamps: List, readTimestamp: Long) { - if (TextSecurePreferences.isReadReceiptsEnabled(context)) { + if (context.prefs.isReadReceiptsEnabled()) { // Redirect message to master device conversation var address = Address.fromSerialized(fromRecipientId) diff --git a/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/TypingStatusRepository.java b/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/TypingStatusRepository.java index a18ad8211f4..6f190494cfa 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/TypingStatusRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/TypingStatusRepository.java @@ -11,6 +11,7 @@ import com.annimon.stream.Stream; import org.jetbrains.annotations.NotNull; +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsession.utilities.Address; import org.session.libsession.utilities.SSKEnvironment; import org.session.libsession.utilities.TextSecurePreferences; @@ -48,7 +49,7 @@ public TypingStatusRepository() { @Override public synchronized void didReceiveTypingStartedMessage(@NotNull Context context, long threadId, @NotNull Address author, int device) { - if (author.serialize().equals(TextSecurePreferences.getLocalNumber(context))) { + if (author.serialize().equals(MessagingModuleConfiguration.getShared().getPrefs().getLocalNumber())) { return; } @@ -77,7 +78,7 @@ public synchronized void didReceiveTypingStartedMessage(@NotNull Context context @Override public synchronized void didReceiveTypingStoppedMessage(@NotNull Context context, long threadId, @NotNull Address author, int device, boolean isReplacedByIncomingMessage) { - if (author.serialize().equals(TextSecurePreferences.getLocalNumber(context))) { + if (author.serialize().equals(MessagingModuleConfiguration.getShared().getPrefs().getLocalNumber())) { return; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/theme/Themes.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/theme/Themes.kt index 87e91e0ab0b..5dc3db922fa 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/theme/Themes.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/theme/Themes.kt @@ -14,7 +14,8 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.unit.dp -import org.session.libsession.utilities.AppTextSecurePreferences +import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs // Globally accessible composition local objects val LocalColors = compositionLocalOf { ClassicDark() } @@ -33,8 +34,7 @@ fun SessionMaterialTheme( if(selectedTheme == null) { // Some values can be set from the preferences, and if not should fallback to a default value val context = LocalContext.current - val preferences = AppTextSecurePreferences(context) - selectedTheme = preferences.getComposeTheme() + selectedTheme = context.prefs.getComposeTheme() } SessionMaterialTheme(colors = selectedTheme ?: ClassicDark()) { content() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/AttachmentUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/AttachmentUtil.java index bda23c03776..987857d83f4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/AttachmentUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/AttachmentUtil.java @@ -10,6 +10,7 @@ import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId; import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment; import org.session.libsession.utilities.ServiceUtil; @@ -79,9 +80,9 @@ private static boolean isNonDocumentType(String contentType) { } private static @NonNull Set getAllowedAutoDownloadTypes(@NonNull Context context) { - if (isConnectedWifi(context)) return TextSecurePreferences.getWifiMediaDownloadAllowed(context); - else if (isConnectedRoaming(context)) return TextSecurePreferences.getRoamingMediaDownloadAllowed(context); - else if (isConnectedMobile(context)) return TextSecurePreferences.getMobileMediaDownloadAllowed(context); + if (isConnectedWifi(context)) return MessagingModuleConfiguration.getShared().getPrefs().getWifiMediaDownloadAllowed(); + else if (isConnectedRoaming(context)) return MessagingModuleConfiguration.getShared().getPrefs().getRoamingMediaDownloadAllowed(); + else if (isConnectedMobile(context)) return MessagingModuleConfiguration.getShared().getPrefs().getMobileMediaDownloadAllowed(); else return Collections.emptySet(); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/ConfigurationMessageUtilities.kt b/app/src/main/java/org/thoughtcrime/securesms/util/ConfigurationMessageUtilities.kt index e59d3aae178..15f1b4e6d79 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/ConfigurationMessageUtilities.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/util/ConfigurationMessageUtilities.kt @@ -19,8 +19,8 @@ import org.session.libsession.messaging.messages.Destination import org.session.libsession.messaging.messages.control.ConfigurationMessage import org.session.libsession.utilities.Address import org.session.libsession.utilities.GroupUtil -import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.WindowDebouncer +import org.session.libsession.utilities.prefs import org.session.libsignal.crypto.ecc.DjbECPublicKey import org.session.libsignal.utilities.Hex import org.session.libsignal.utilities.IdPrefix @@ -54,12 +54,12 @@ object ConfigurationMessageUtilities { @JvmStatic fun syncConfigurationIfNeeded(context: Context) { - val userPublicKey = TextSecurePreferences.getLocalNumber(context) ?: return Log.w(TAG, "User Public Key is null") + val userPublicKey = context.prefs.getLocalNumber() ?: return Log.w(TAG, "User Public Key is null") scheduleConfigSync(userPublicKey) } fun forceSyncConfigurationNowIfNeeded(context: Context): Promise { - val userPublicKey = TextSecurePreferences.getLocalNumber(context) ?: return Promise.ofFail(NullPointerException("User Public Key is null")) + val userPublicKey = context.prefs.getLocalNumber() ?: return Promise.ofFail(NullPointerException("User Public Key is null")) // Schedule a new job if one doesn't already exist (only) scheduleConfigSync(userPublicKey) return Promise.ofSuccess(Unit) diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/VersionTracker.kt b/app/src/main/java/org/thoughtcrime/securesms/util/VersionTracker.kt index 222b9b7fc8c..f705140bef1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/VersionTracker.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/util/VersionTracker.kt @@ -1,16 +1,16 @@ package org.thoughtcrime.securesms.util import android.content.Context +import org.session.libsession.messaging.MessagingModuleConfiguration +import org.session.libsession.utilities.prefs import java.io.IOException import java.lang.RuntimeException -import org.session.libsession.utilities.TextSecurePreferences - object VersionTracker { @JvmStatic fun getLastSeenVersion(context: Context): Int { - var version = TextSecurePreferences.getLastVersionCode(context) + var version = context.prefs.getLastVersionCode() // Zero means the app is freshly installed = user is actually on the current version. if (version == 0) { version = updateLastSeenVersion(context) @@ -22,7 +22,7 @@ object VersionTracker { fun updateLastSeenVersion(context: Context): Int { return try { val currentVersionCode = Util.getCanonicalVersionCode() - TextSecurePreferences.setLastVersionCode(context, currentVersionCode) + context.prefs.setLastVersionCode(currentVersionCode) currentVersionCode } catch (e: IOException) { throw RuntimeException("Failed to update the last seen app version.", e) diff --git a/libsession/src/main/java/org/session/libsession/messaging/MessagingModuleConfiguration.kt b/libsession/src/main/java/org/session/libsession/messaging/MessagingModuleConfiguration.kt index e4f15b21141..823416f8cac 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/MessagingModuleConfiguration.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/MessagingModuleConfiguration.kt @@ -1,11 +1,13 @@ package org.session.libsession.messaging +import android.annotation.SuppressLint import android.content.Context import com.goterl.lazysodium.utils.KeyPair import org.session.libsession.database.MessageDataProvider import org.session.libsession.database.StorageProtocol import org.session.libsession.utilities.ConfigFactoryProtocol import org.session.libsession.utilities.Device +import org.session.libsession.utilities.prefs class MessagingModuleConfiguration( val context: Context, @@ -16,19 +18,11 @@ class MessagingModuleConfiguration( val configFactory: ConfigFactoryProtocol, val lastSentTimestampCache: LastSentTimestampCache ) { + val prefs get() = context.prefs companion object { + @SuppressLint("StaticFieldLeak") @JvmStatic - val shared: MessagingModuleConfiguration - get() = context.getSystemService(MESSAGING_MODULE_SERVICE) as MessagingModuleConfiguration - - const val MESSAGING_MODULE_SERVICE: String = "MessagingModuleConfiguration_MESSAGING_MODULE_SERVICE" - - private lateinit var context: Context - - @JvmStatic - fun configure(context: Context) { - this.context = context - } + lateinit var shared: MessagingModuleConfiguration } -} \ No newline at end of file +} diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/RetrieveProfileAvatarJob.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/RetrieveProfileAvatarJob.kt index 54efa1c80bd..6be29f2b063 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/RetrieveProfileAvatarJob.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/RetrieveProfileAvatarJob.kt @@ -5,10 +5,9 @@ import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.utilities.Data import org.session.libsession.utilities.Address import org.session.libsession.utilities.DownloadUtilities.downloadFile -import org.session.libsession.utilities.TextSecurePreferences.Companion.setProfileAvatarId -import org.session.libsession.utilities.TextSecurePreferences.Companion.setProfilePictureURL import org.session.libsession.utilities.Util.copy import org.session.libsession.utilities.Util.equals +import org.session.libsession.utilities.prefs import org.session.libsession.utilities.recipients.Recipient import org.session.libsignal.streams.ProfileCipherInputStream import org.session.libsignal.utilities.Log @@ -64,8 +63,8 @@ class RetrieveProfileAvatarJob(private val profileAvatar: String?, val recipient Log.w(TAG, "Removing profile avatar for: " + recipient.address.serialize()) if (recipient.isLocalNumber) { - setProfileAvatarId(context, SecureRandom().nextInt()) - setProfilePictureURL(context, null) + context.prefs.setProfileAvatarId(SecureRandom().nextInt()) + context.prefs.setProfilePictureURL(null) } AvatarHelper.delete(context, recipient.address) @@ -83,8 +82,8 @@ class RetrieveProfileAvatarJob(private val profileAvatar: String?, val recipient decryptDestination.renameTo(AvatarHelper.getAvatarFile(context, recipient.address)) if (recipient.isLocalNumber) { - setProfileAvatarId(context, SecureRandom().nextInt()) - setProfilePictureURL(context, profileAvatar) + context.prefs.setProfileAvatarId(SecureRandom().nextInt()) + context.prefs.setProfilePictureURL(profileAvatar) } storage.setProfileAvatar(recipient, profileAvatar) diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/TrimThreadJob.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/TrimThreadJob.kt index cc388b03766..5426f3e6af1 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/TrimThreadJob.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/TrimThreadJob.kt @@ -2,7 +2,7 @@ package org.session.libsession.messaging.jobs import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.utilities.Data -import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs class TrimThreadJob(val threadId: Long, val openGroupId: String?) : Job { override var delegate: JobDelegate? = null @@ -22,7 +22,7 @@ class TrimThreadJob(val threadId: Long, val openGroupId: String?) : Job { override suspend fun execute(dispatcherName: String) { val context = MessagingModuleConfiguration.shared.context - val trimmingEnabled = TextSecurePreferences.isThreadLengthTrimmingEnabled(context) + val trimmingEnabled = context.prefs.isThreadLengthTrimmingEnabled() val storage = MessagingModuleConfiguration.shared.storage val messageCount = storage.getMessageCount(threadId) if (trimmingEnabled && !openGroupId.isNullOrEmpty() && messageCount >= THREAD_LENGTH_TRIGGER_SIZE) { diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ConfigurationMessage.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ConfigurationMessage.kt index 7544ff9c82e..a1bbfd27abd 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ConfigurationMessage.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ConfigurationMessage.kt @@ -7,6 +7,7 @@ import org.session.libsession.utilities.Address import org.session.libsession.utilities.GroupUtil import org.session.libsession.utilities.ProfileKeyUtil import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs import org.session.libsignal.crypto.ecc.DjbECPrivateKey import org.session.libsignal.crypto.ecc.DjbECPublicKey import org.session.libsignal.crypto.ecc.ECKeyPair @@ -117,8 +118,9 @@ class ConfigurationMessage(var closedGroups: List, var openGroups: val sharedConfig = MessagingModuleConfiguration.shared val storage = sharedConfig.storage val context = sharedConfig.context - val displayName = TextSecurePreferences.getProfileName(context) ?: return null - val profilePicture = TextSecurePreferences.getProfilePictureURL(context) + val prefs = context.prefs + val displayName = prefs.getProfileName() ?: return null + val profilePicture = prefs.getProfilePictureURL() val profileKey = ProfileKeyUtil.getProfileKey(context) val groups = storage.getAllGroups(includeInactive = false) for (group in groups) { diff --git a/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupApi.kt b/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupApi.kt index e988b579f1e..c5cfe9fa630 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupApi.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupApi.kt @@ -24,6 +24,7 @@ import org.session.libsession.snode.OnionRequestAPI import org.session.libsession.snode.OnionResponse import org.session.libsession.snode.SnodeAPI import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs import org.session.libsignal.utilities.Base64.decode import org.session.libsignal.utilities.Base64.encodeBytes import org.session.libsignal.utilities.HTTP @@ -48,8 +49,7 @@ object OpenGroupApi { private val hasPerformedInitialPoll = mutableMapOf() private var hasUpdatedLastOpenDate = false private val timeSinceLastOpen by lazy { - val context = MessagingModuleConfiguration.shared.context - val lastOpenDate = TextSecurePreferences.getLastOpenTimeDate(context) + val lastOpenDate = MessagingModuleConfiguration.shared.context.prefs.getLastOpenTimeDate() val now = System.currentTimeMillis() now - lastOpenDate } @@ -701,7 +701,7 @@ object OpenGroupApi { hasPerformedInitialPoll[server] = true if (!hasUpdatedLastOpenDate) { hasUpdatedLastOpenDate = true - TextSecurePreferences.setLastOpenDate(context) + context.prefs.setLastOpenDate() } val lastInboxMessageId = storage.getLastInboxMessageId(server) val lastOutboxMessageId = storage.getLastOutboxMessageId(server) diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderClosedGroupHandler.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderClosedGroupHandler.kt index e30d58b939d..85ec3e65a49 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderClosedGroupHandler.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderClosedGroupHandler.kt @@ -16,6 +16,7 @@ import org.session.libsession.utilities.Address.Companion.fromSerialized import org.session.libsession.utilities.Device import org.session.libsession.utilities.GroupUtil import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs import org.session.libsignal.crypto.ecc.Curve import org.session.libsignal.crypto.ecc.ECKeyPair import org.session.libsignal.messages.SignalServiceGroup @@ -240,7 +241,7 @@ fun MessageSender.leave(groupPublicKey: String, notifyUser: Boolean = true): Pro ThreadUtils.queue { val context = MessagingModuleConfiguration.shared.context val storage = MessagingModuleConfiguration.shared.storage - val userPublicKey = TextSecurePreferences.getLocalNumber(context)!! + val userPublicKey = context.prefs.getLocalNumber()!! val groupID = GroupUtil.doubleEncodeGroupID(groupPublicKey) val group = storage.getGroup(groupID) ?: return@queue deferred.reject(Error.NoThread) val updatedMembers = group.members.map { it.serialize() }.toSet() - userPublicKey diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt index 7bc47931d6f..47b847aca9a 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt @@ -1,7 +1,6 @@ package org.session.libsession.messaging.sending_receiving import android.text.TextUtils -import network.loki.messenger.libsession_util.ConfigBase import network.loki.messenger.libsession_util.util.ExpiryMode import org.session.libsession.avatars.AvatarHelper import org.session.libsession.messaging.MessagingModuleConfiguration @@ -41,6 +40,7 @@ import org.session.libsession.utilities.GroupUtil.doubleEncodeGroupID import org.session.libsession.utilities.ProfileKeyUtil import org.session.libsession.utilities.SSKEnvironment import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs import org.session.libsession.utilities.recipients.Recipient import org.session.libsignal.crypto.ecc.DjbECPrivateKey import org.session.libsignal.crypto.ecc.DjbECPublicKey @@ -194,17 +194,18 @@ private fun MessageReceiver.handleDataExtractionNotification(message: DataExtrac private fun handleConfigurationMessage(message: ConfigurationMessage) { val context = MessagingModuleConfiguration.shared.context val storage = MessagingModuleConfiguration.shared.storage - if (TextSecurePreferences.getConfigurationMessageSynced(context) - && !TextSecurePreferences.shouldUpdateProfile(context, message.sentTimestamp!!)) return + val prefs = context.prefs + if (prefs.getConfigurationMessageSynced() + && !prefs.shouldUpdateProfile(message.sentTimestamp!!)) return val userPublicKey = storage.getUserPublicKey() if (userPublicKey == null || message.sender != storage.getUserPublicKey()) return - val firstTimeSync = !TextSecurePreferences.getConfigurationMessageSynced(context) + val firstTimeSync = !prefs.getConfigurationMessageSynced() - TextSecurePreferences.setConfigurationMessageSynced(context, true) - TextSecurePreferences.setLastProfileUpdateTime(context, message.sentTimestamp!!) + prefs.setConfigurationMessageSynced(true) + prefs.setLastProfileUpdateTime(message.sentTimestamp!!) - TextSecurePreferences.setHasLegacyConfig(context, true) + prefs.setHasLegacyConfig(true) if (!firstTimeSync) return val allClosedGroupPublicKeys = storage.getAllClosedGroupPublicKeys() @@ -233,11 +234,11 @@ private fun handleConfigurationMessage(message: ConfigurationMessage) { val profileManager = SSKEnvironment.shared.profileManager val recipient = Recipient.from(context, Address.fromSerialized(userPublicKey), false) if (message.displayName.isNotEmpty()) { - TextSecurePreferences.setProfileName(context, message.displayName) + prefs.setProfileName(message.displayName) profileManager.setName(context, recipient, message.displayName) } if (message.profileKey.isNotEmpty() && !message.profilePicture.isNullOrEmpty() - && TextSecurePreferences.getProfilePictureURL(context) != message.profilePicture) { + && prefs.getProfilePictureURL() != message.profilePicture) { val profileKey = Base64.encodeBytes(message.profileKey) ProfileKeyUtil.setEncodedProfileKey(context, profileKey) profileManager.setProfilePicture(context, recipient, message.profilePicture, message.profileKey) @@ -641,7 +642,7 @@ private fun MessageReceiver.handleClosedGroupEncryptionKeyPair(message: ClosedGr private fun MessageReceiver.handleClosedGroupNameChanged(message: ClosedGroupControlMessage) { val context = MessagingModuleConfiguration.shared.context val storage = MessagingModuleConfiguration.shared.storage - val userPublicKey = TextSecurePreferences.getLocalNumber(context) + val userPublicKey = context.prefs.getLocalNumber() val senderPublicKey = message.sender ?: return val kind = message.kind!! as? ClosedGroupControlMessage.Kind.NameChange ?: return val groupPublicKey = message.groupPublicKey ?: return diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/notifications/PushRegistryV1.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/notifications/PushRegistryV1.kt index 230fb2dc9c2..649869af4fa 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/notifications/PushRegistryV1.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/notifications/PushRegistryV1.kt @@ -12,6 +12,7 @@ import org.session.libsession.snode.OnionResponse import org.session.libsession.snode.Version import org.session.libsession.utilities.Device import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.prefs import org.session.libsignal.utilities.JsonUtil import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.emptyPromise @@ -29,9 +30,9 @@ object PushRegistryV1 { fun register( device: Device, - isPushEnabled: Boolean = TextSecurePreferences.isPushEnabled(context), - token: String? = TextSecurePreferences.getPushToken(context), - publicKey: String? = TextSecurePreferences.getLocalNumber(context), + isPushEnabled: Boolean = context.prefs.isPushEnabled(), + token: String? = context.prefs.getPushToken(), + publicKey: String? = context.prefs.getLocalNumber(), legacyGroupPublicKeys: Collection = MessagingModuleConfiguration.shared.storage.getAllClosedGroupPublicKeys() ): Promise<*, Exception> = when { isPushEnabled -> retryIfNeeded(maxRetryCount) { @@ -79,7 +80,7 @@ object PushRegistryV1 { fun unregister(): Promise<*, Exception> { Log.d(TAG, "unregisterV1 requested") - val token = TextSecurePreferences.getPushToken(context) ?: emptyPromise() + val token = context.prefs.getPushToken() ?: emptyPromise() return retryIfNeeded(maxRetryCount) { val parameters = mapOf("token" to token) @@ -100,7 +101,7 @@ object PushRegistryV1 { fun subscribeGroup( closedGroupPublicKey: String, - isPushEnabled: Boolean = TextSecurePreferences.isPushEnabled(context), + isPushEnabled: Boolean = context.prefs.isPushEnabled(), publicKey: String = MessagingModuleConfiguration.shared.storage.getUserPublicKey()!! ) = if (isPushEnabled) { performGroupOperation("subscribe_closed_group", closedGroupPublicKey, publicKey) @@ -108,7 +109,7 @@ object PushRegistryV1 { fun unsubscribeGroup( closedGroupPublicKey: String, - isPushEnabled: Boolean = TextSecurePreferences.isPushEnabled(context), + isPushEnabled: Boolean = context.prefs.isPushEnabled(), publicKey: String = MessagingModuleConfiguration.shared.storage.getUserPublicKey()!! ) = if (isPushEnabled) { performGroupOperation("unsubscribe_closed_group", closedGroupPublicKey, publicKey) diff --git a/libsession/src/main/java/org/session/libsession/utilities/ProfileKeyUtil.java b/libsession/src/main/java/org/session/libsession/utilities/ProfileKeyUtil.java index 4550965ae7f..7d9f438f724 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/ProfileKeyUtil.java +++ b/libsession/src/main/java/org/session/libsession/utilities/ProfileKeyUtil.java @@ -1,10 +1,13 @@ package org.session.libsession.utilities; +import static org.session.libsession.utilities.TextSecurePreferencesKt.getPrefs; + import android.content.Context; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsignal.utilities.Base64; import java.io.IOException; @@ -15,11 +18,11 @@ public class ProfileKeyUtil { public static synchronized @NonNull byte[] getProfileKey(@NonNull Context context) { try { - String encodedProfileKey = TextSecurePreferences.getProfileKey(context); + String encodedProfileKey = MessagingModuleConfiguration.getShared().getPrefs().getProfileKey(); if (encodedProfileKey == null) { encodedProfileKey = Util.getSecret(PROFILE_KEY_BYTES); - TextSecurePreferences.setProfileKey(context, encodedProfileKey); + MessagingModuleConfiguration.getShared().getPrefs().setProfileKey(encodedProfileKey); } return Base64.decode(encodedProfileKey); @@ -41,6 +44,6 @@ public class ProfileKeyUtil { } public static synchronized void setEncodedProfileKey(@NonNull Context context, @Nullable String key) { - TextSecurePreferences.setProfileKey(context, key); + MessagingModuleConfiguration.getShared().getPrefs().setProfileKey(key); } } diff --git a/libsession/src/main/java/org/session/libsession/utilities/ProfilePictureUtilities.kt b/libsession/src/main/java/org/session/libsession/utilities/ProfilePictureUtilities.kt index 38d8838c0e5..9f61dbba0d1 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/ProfilePictureUtilities.kt +++ b/libsession/src/main/java/org/session/libsession/utilities/ProfilePictureUtilities.kt @@ -4,6 +4,7 @@ import android.content.Context import nl.komponents.kovenant.Promise import nl.komponents.kovenant.deferred import okio.Buffer +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.file_server.FileServerApi import org.session.libsignal.streams.ProfileCipherOutputStream import org.session.libsignal.utilities.ProfileAvatarData @@ -35,9 +36,9 @@ object ProfilePictureUtilities { } catch (e: Exception) { deferred.reject(e) } - TextSecurePreferences.setLastProfilePictureUpload(context, Date().time) + context.prefs.setLastProfilePictureUpload(Date().time) val url = "${FileServerApi.server}/file/$id" - TextSecurePreferences.setProfilePictureURL(context, url) + context.prefs.setProfilePictureURL(url) deferred.resolve(Unit) } return deferred.promise diff --git a/libsession/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt b/libsession/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt index 4d35a89de2c..3d75566c1cd 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt +++ b/libsession/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt @@ -1,1690 +1,356 @@ package org.session.libsession.utilities import android.content.Context +import android.content.SharedPreferences +import android.content.SharedPreferences.OnSharedPreferenceChangeListener import android.hardware.Camera import android.net.Uri import android.provider.Settings import androidx.annotation.ArrayRes import androidx.annotation.StyleRes import androidx.core.app.NotificationCompat +import androidx.preference.Preference +import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceManager.getDefaultSharedPreferences import dagger.hilt.android.qualifiers.ApplicationContext -import kotlinx.coroutines.channels.BufferOverflow -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.asSharedFlow +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.callbackFlow import org.session.libsession.R -import org.session.libsession.utilities.TextSecurePreferences.Companion.AUTOPLAY_AUDIO_MESSAGES -import org.session.libsession.utilities.TextSecurePreferences.Companion.CALL_NOTIFICATIONS_ENABLED -import org.session.libsession.utilities.TextSecurePreferences.Companion.CLASSIC_DARK -import org.session.libsession.utilities.TextSecurePreferences.Companion.CLASSIC_LIGHT -import org.session.libsession.utilities.TextSecurePreferences.Companion.FOLLOW_SYSTEM_SETTINGS -import org.session.libsession.utilities.TextSecurePreferences.Companion.HIDE_PASSWORD -import org.session.libsession.utilities.TextSecurePreferences.Companion.LAST_VACUUM_TIME -import org.session.libsession.utilities.TextSecurePreferences.Companion.LEGACY_PREF_KEY_SELECTED_UI_MODE -import org.session.libsession.utilities.TextSecurePreferences.Companion.OCEAN_DARK -import org.session.libsession.utilities.TextSecurePreferences.Companion.OCEAN_LIGHT -import org.session.libsession.utilities.TextSecurePreferences.Companion.SELECTED_ACCENT_COLOR -import org.session.libsession.utilities.TextSecurePreferences.Companion.SELECTED_STYLE -import org.session.libsession.utilities.TextSecurePreferences.Companion.SHOWN_CALL_NOTIFICATION -import org.session.libsession.utilities.TextSecurePreferences.Companion.SHOWN_CALL_WARNING -import org.session.libsignal.utilities.Log -import java.io.IOException -import java.util.Arrays +import org.session.libsession.utilities.TextSecurePreferences.Companion.instance import java.util.Date import javax.inject.Inject import javax.inject.Singleton -interface TextSecurePreferences { - - fun getLastConfigurationSyncTime(): Long - fun setLastConfigurationSyncTime(value: Long) - fun getConfigurationMessageSynced(): Boolean - fun setConfigurationMessageSynced(value: Boolean) - fun isPushEnabled(): Boolean - fun setPushEnabled(value: Boolean) - fun getPushToken(): String? - fun setPushToken(value: String) - fun getPushRegisterTime(): Long - fun setPushRegisterTime(value: Long) - fun isScreenLockEnabled(): Boolean - fun setScreenLockEnabled(value: Boolean) - fun getScreenLockTimeout(): Long - fun setScreenLockTimeout(value: Long) - fun setBackupPassphrase(passphrase: String?) - fun getBackupPassphrase(): String? - fun setEncryptedBackupPassphrase(encryptedPassphrase: String?) - fun getEncryptedBackupPassphrase(): String? - fun setBackupEnabled(value: Boolean) - fun isBackupEnabled(): Boolean - fun setNextBackupTime(time: Long) - fun getNextBackupTime(): Long - fun setBackupSaveDir(dirUri: String?) - fun getBackupSaveDir(): String? - fun getNeedsSqlCipherMigration(): Boolean - fun setAttachmentEncryptedSecret(secret: String) - fun setAttachmentUnencryptedSecret(secret: String?) - fun getAttachmentEncryptedSecret(): String? - fun getAttachmentUnencryptedSecret(): String? - fun setDatabaseEncryptedSecret(secret: String) - fun setDatabaseUnencryptedSecret(secret: String?) - fun getDatabaseUnencryptedSecret(): String? - fun getDatabaseEncryptedSecret(): String? - fun isIncognitoKeyboardEnabled(): Boolean - fun isReadReceiptsEnabled(): Boolean - fun setReadReceiptsEnabled(enabled: Boolean) - fun isTypingIndicatorsEnabled(): Boolean - fun setTypingIndicatorsEnabled(enabled: Boolean) - fun isLinkPreviewsEnabled(): Boolean - fun setLinkPreviewsEnabled(enabled: Boolean) - fun hasSeenGIFMetaDataWarning(): Boolean - fun setHasSeenGIFMetaDataWarning() - fun isGifSearchInGridLayout(): Boolean - fun setIsGifSearchInGridLayout(isGrid: Boolean) - fun getProfileKey(): String? - fun setProfileKey(key: String?) - fun setProfileName(name: String?) - fun getProfileName(): String? - fun setProfileAvatarId(id: Int) - fun getProfileAvatarId(): Int - fun setProfilePictureURL(url: String?) - fun getProfilePictureURL(): String? - fun getNotificationPriority(): Int - fun getMessageBodyTextSize(): Int - fun setDirectCaptureCameraId(value: Int) - fun getDirectCaptureCameraId(): Int - fun getNotificationPrivacy(): NotificationPrivacyPreference - fun getRepeatAlertsCount(): Int - fun getLocalRegistrationId(): Int - fun setLocalRegistrationId(registrationId: Int) - fun isInThreadNotifications(): Boolean - fun isUniversalUnidentifiedAccess(): Boolean - fun getUpdateApkRefreshTime(): Long - fun setUpdateApkRefreshTime(value: Long) - fun setUpdateApkDownloadId(value: Long) - fun getUpdateApkDownloadId(): Long - fun setUpdateApkDigest(value: String?) - fun getUpdateApkDigest(): String? - fun getLocalNumber(): String? - fun getHasLegacyConfig(): Boolean - fun setHasLegacyConfig(newValue: Boolean) - fun setLocalNumber(localNumber: String) - fun removeLocalNumber() - fun isEnterSendsEnabled(): Boolean - fun isPasswordDisabled(): Boolean - fun setPasswordDisabled(disabled: Boolean) - fun isScreenSecurityEnabled(): Boolean - fun getLastVersionCode(): Int - fun setLastVersionCode(versionCode: Int) - fun isPassphraseTimeoutEnabled(): Boolean - fun getPassphraseTimeoutInterval(): Int - fun getLanguage(): String? - fun isNotificationsEnabled(): Boolean - fun getNotificationRingtone(): Uri - fun removeNotificationRingtone() - fun setNotificationRingtone(ringtone: String?) - fun setNotificationVibrateEnabled(enabled: Boolean) - fun isNotificationVibrateEnabled(): Boolean - fun getNotificationLedColor(): Int - fun isThreadLengthTrimmingEnabled(): Boolean - fun isSystemEmojiPreferred(): Boolean - fun getMobileMediaDownloadAllowed(): Set? - fun getWifiMediaDownloadAllowed(): Set? - fun getRoamingMediaDownloadAllowed(): Set? - fun getMediaDownloadAllowed(key: String, @ArrayRes defaultValuesRes: Int): Set? - fun getLogEncryptedSecret(): String? - fun setLogEncryptedSecret(base64Secret: String?) - fun getLogUnencryptedSecret(): String? - fun setLogUnencryptedSecret(base64Secret: String?) - fun getNotificationChannelVersion(): Int - fun setNotificationChannelVersion(version: Int) - fun getNotificationMessagesChannelVersion(): Int - fun setNotificationMessagesChannelVersion(version: Int) - fun getBooleanPreference(key: String?, defaultValue: Boolean): Boolean - fun setBooleanPreference(key: String?, value: Boolean) - fun getStringPreference(key: String, defaultValue: String?): String? - fun setStringPreference(key: String?, value: String?) - fun getIntegerPreference(key: String, defaultValue: Int): Int - fun setIntegerPreference(key: String, value: Int) - fun setIntegerPreferenceBlocking(key: String, value: Int): Boolean - fun getLongPreference(key: String, defaultValue: Long): Long - fun setLongPreference(key: String, value: Long) - fun removePreference(key: String) - fun getStringSetPreference(key: String, defaultValues: Set): Set? - fun getHasViewedSeed(): Boolean - fun setHasViewedSeed(hasViewedSeed: Boolean) - fun setRestorationTime(time: Long) - fun getRestorationTime(): Long - fun getLastProfilePictureUpload(): Long - fun setLastProfilePictureUpload(newValue: Long) - fun getLastSnodePoolRefreshDate(): Long - fun setLastSnodePoolRefreshDate(date: Date) - fun shouldUpdateProfile(profileUpdateTime: Long): Boolean - fun setLastProfileUpdateTime(profileUpdateTime: Long) - fun getLastOpenTimeDate(): Long - fun setLastOpenDate() - fun hasSeenLinkPreviewSuggestionDialog(): Boolean - fun setHasSeenLinkPreviewSuggestionDialog() - fun hasHiddenMessageRequests(): Boolean - fun setHasHiddenMessageRequests() - fun setShownCallWarning(): Boolean - fun setShownCallNotification(): Boolean - fun isCallNotificationsEnabled(): Boolean - fun getLastVacuum(): Long - fun setLastVacuumNow() - fun getFingerprintKeyGenerated(): Boolean - fun setFingerprintKeyGenerated() - fun getSelectedAccentColor(): String? - @StyleRes fun getAccentColorStyle(): Int? - fun setAccentColorStyle(@StyleRes newColorStyle: Int?) - fun getThemeStyle(): String - fun getFollowSystemSettings(): Boolean - fun setThemeStyle(themeStyle: String) - fun setFollowSystemSettings(followSystemSettings: Boolean) - fun autoplayAudioMessages(): Boolean - fun hasForcedNewConfig(): Boolean - fun hasPreference(key: String): Boolean - fun clearAll() - fun getHidePassword(): Boolean - fun setHidePassword(value: Boolean) - - companion object { - val TAG = TextSecurePreferences::class.simpleName - - internal val _events = MutableSharedFlow(0, 64, BufferOverflow.DROP_OLDEST) - val events get() = _events.asSharedFlow() - - @JvmStatic - var pushSuffix = "" - - const val DISABLE_PASSPHRASE_PREF = "pref_disable_passphrase" - const val LANGUAGE_PREF = "pref_language" - const val THREAD_TRIM_NOW = "pref_trim_now" - const val LAST_VERSION_CODE_PREF = "last_version_code" - const val RINGTONE_PREF = "pref_key_ringtone" - const val VIBRATE_PREF = "pref_key_vibrate" - const val NOTIFICATION_PREF = "pref_key_enable_notifications" - const val LED_COLOR_PREF = "pref_led_color" - const val LED_COLOR_PREF_PRIMARY = "pref_led_color_primary" - const val LED_BLINK_PREF = "pref_led_blink" - const val LED_BLINK_PREF_CUSTOM = "pref_led_blink_custom" - const val PASSPHRASE_TIMEOUT_INTERVAL_PREF = "pref_timeout_interval" - const val PASSPHRASE_TIMEOUT_PREF = "pref_timeout_passphrase" - const val SCREEN_SECURITY_PREF = "pref_screen_security" - const val ENTER_SENDS_PREF = "pref_enter_sends" - const val THREAD_TRIM_ENABLED = "pref_trim_threads" - const val LOCAL_NUMBER_PREF = "pref_local_number" - const val REGISTERED_GCM_PREF = "pref_gcm_registered" - const val UPDATE_APK_REFRESH_TIME_PREF = "pref_update_apk_refresh_time" - const val UPDATE_APK_DOWNLOAD_ID = "pref_update_apk_download_id" - const val UPDATE_APK_DIGEST = "pref_update_apk_digest" - const val IN_THREAD_NOTIFICATION_PREF = "pref_key_inthread_notifications" - const val IN_APP_NOTIFICATION_SOUNDS = "pref_sound_when_app_open" - const val MESSAGE_BODY_TEXT_SIZE_PREF = "pref_message_body_text_size" - const val LOCAL_REGISTRATION_ID_PREF = "pref_local_registration_id" - const val REPEAT_ALERTS_PREF = "pref_repeat_alerts" - const val NOTIFICATION_PRIVACY_PREF = "pref_notification_privacy" - const val NOTIFICATION_PRIORITY_PREF = "pref_notification_priority" - const val MEDIA_DOWNLOAD_MOBILE_PREF = "pref_media_download_mobile" - const val MEDIA_DOWNLOAD_WIFI_PREF = "pref_media_download_wifi" - const val MEDIA_DOWNLOAD_ROAMING_PREF = "pref_media_download_roaming" - const val SYSTEM_EMOJI_PREF = "pref_system_emoji" - const val DIRECT_CAPTURE_CAMERA_ID = "pref_direct_capture_camera_id" - const val PROFILE_KEY_PREF = "pref_profile_key" - const val PROFILE_NAME_PREF = "pref_profile_name" - const val PROFILE_AVATAR_ID_PREF = "pref_profile_avatar_id" - const val PROFILE_AVATAR_URL_PREF = "pref_profile_avatar_url" - const val READ_RECEIPTS_PREF = "pref_read_receipts" - const val INCOGNITO_KEYBORAD_PREF = "pref_incognito_keyboard" - const val DATABASE_ENCRYPTED_SECRET = "pref_database_encrypted_secret" - const val DATABASE_UNENCRYPTED_SECRET = "pref_database_unencrypted_secret" - const val ATTACHMENT_ENCRYPTED_SECRET = "pref_attachment_encrypted_secret" - const val ATTACHMENT_UNENCRYPTED_SECRET = "pref_attachment_unencrypted_secret" - const val NEEDS_SQLCIPHER_MIGRATION = "pref_needs_sql_cipher_migration" - const val BACKUP_ENABLED = "pref_backup_enabled_v3" - const val BACKUP_PASSPHRASE = "pref_backup_passphrase" - const val ENCRYPTED_BACKUP_PASSPHRASE = "pref_encrypted_backup_passphrase" - const val BACKUP_TIME = "pref_backup_next_time" - const val BACKUP_NOW = "pref_backup_create" - const val BACKUP_SAVE_DIR = "pref_save_dir" - const val SCREEN_LOCK = "pref_android_screen_lock" - const val SCREEN_LOCK_TIMEOUT = "pref_android_screen_lock_timeout" - const val LOG_ENCRYPTED_SECRET = "pref_log_encrypted_secret" - const val LOG_UNENCRYPTED_SECRET = "pref_log_unencrypted_secret" - const val NOTIFICATION_CHANNEL_VERSION = "pref_notification_channel_version" - const val NOTIFICATION_MESSAGES_CHANNEL_VERSION = "pref_notification_messages_channel_version" - const val UNIVERSAL_UNIDENTIFIED_ACCESS = "pref_universal_unidentified_access" - const val TYPING_INDICATORS = "pref_typing_indicators" - const val LINK_PREVIEWS = "pref_link_previews" - const val GIF_METADATA_WARNING = "has_seen_gif_metadata_warning" - const val GIF_GRID_LAYOUT = "pref_gif_grid_layout" - val IS_PUSH_ENABLED get() = "pref_is_using_fcm$pushSuffix" - val PUSH_TOKEN get() = "pref_fcm_token_2$pushSuffix" - val PUSH_REGISTER_TIME get() = "pref_last_fcm_token_upload_time_2$pushSuffix" - const val LAST_CONFIGURATION_SYNC_TIME = "pref_last_configuration_sync_time" - const val CONFIGURATION_SYNCED = "pref_configuration_synced" - const val LAST_PROFILE_UPDATE_TIME = "pref_last_profile_update_time" - const val LAST_OPEN_DATE = "pref_last_open_date" - const val HAS_HIDDEN_MESSAGE_REQUESTS = "pref_message_requests_hidden" - const val CALL_NOTIFICATIONS_ENABLED = "pref_call_notifications_enabled" - const val SHOWN_CALL_WARNING = "pref_shown_call_warning" // call warning is user-facing warning of enabling calls - const val SHOWN_CALL_NOTIFICATION = "pref_shown_call_notification" // call notification is a prompt to check privacy settings - const val LAST_VACUUM_TIME = "pref_last_vacuum_time" - const val AUTOPLAY_AUDIO_MESSAGES = "pref_autoplay_audio" - const val FINGERPRINT_KEY_GENERATED = "fingerprint_key_generated" - const val SELECTED_ACCENT_COLOR = "selected_accent_color" - - const val HAS_RECEIVED_LEGACY_CONFIG = "has_received_legacy_config" - const val HAS_FORCED_NEW_CONFIG = "has_forced_new_config" - - const val GREEN_ACCENT = "accent_green" - const val BLUE_ACCENT = "accent_blue" - const val PURPLE_ACCENT = "accent_purple" - const val PINK_ACCENT = "accent_pink" - const val RED_ACCENT = "accent_red" - const val ORANGE_ACCENT = "accent_orange" - const val YELLOW_ACCENT = "accent_yellow" - - const val SELECTED_STYLE = "pref_selected_style" // classic_dark/light, ocean_dark/light - const val FOLLOW_SYSTEM_SETTINGS = "pref_follow_system" // follow system day/night - const val HIDE_PASSWORD = "pref_hide_password" - - const val LEGACY_PREF_KEY_SELECTED_UI_MODE = "SELECTED_UI_MODE" // this will be cleared upon launching app, for users migrating to theming build - const val CLASSIC_DARK = "classic.dark" - const val CLASSIC_LIGHT = "classic.light" - const val OCEAN_DARK = "ocean.dark" - const val OCEAN_LIGHT = "ocean.light" - - const val ALLOW_MESSAGE_REQUESTS = "libsession.ALLOW_MESSAGE_REQUESTS" - - const val PATCH_SNODE_VERSION_2024_07_23 = "libsession.patch_snode_version_2024_07_23" - - @JvmStatic - fun getLastConfigurationSyncTime(context: Context): Long { - return getLongPreference(context, LAST_CONFIGURATION_SYNC_TIME, 0) - } - - @JvmStatic - fun setLastConfigurationSyncTime(context: Context, value: Long) { - setLongPreference(context, LAST_CONFIGURATION_SYNC_TIME, value) - } - - @JvmStatic - fun getConfigurationMessageSynced(context: Context): Boolean { - return getBooleanPreference(context, CONFIGURATION_SYNCED, false) - } - - @JvmStatic - fun setConfigurationMessageSynced(context: Context, value: Boolean) { - setBooleanPreference(context, CONFIGURATION_SYNCED, value) - _events.tryEmit(CONFIGURATION_SYNCED) - } - - @JvmStatic - fun isPushEnabled(context: Context): Boolean { - return getBooleanPreference(context, IS_PUSH_ENABLED, false) - } - - @JvmStatic - fun setPushEnabled(context: Context, value: Boolean) { - setBooleanPreference(context, IS_PUSH_ENABLED, value) - } - - @JvmStatic - fun getPushToken(context: Context): String? { - return getStringPreference(context, PUSH_TOKEN, "") - } - - @JvmStatic - fun setPushToken(context: Context, value: String?) { - setStringPreference(context, PUSH_TOKEN, value) - } - - fun getPushRegisterTime(context: Context): Long { - return getLongPreference(context, PUSH_REGISTER_TIME, 0) - } - - fun setPushRegisterTime(context: Context, value: Long) { - setLongPreference(context, PUSH_REGISTER_TIME, value) - } - - // endregion - @JvmStatic - fun isScreenLockEnabled(context: Context): Boolean { - return getBooleanPreference(context, SCREEN_LOCK, false) - } - - @JvmStatic - fun setScreenLockEnabled(context: Context, value: Boolean) { - setBooleanPreference(context, SCREEN_LOCK, value) - } - - @JvmStatic - fun getScreenLockTimeout(context: Context): Long { - return getLongPreference(context, SCREEN_LOCK_TIMEOUT, 0) - } - - @JvmStatic - fun setScreenLockTimeout(context: Context, value: Long) { - setLongPreference(context, SCREEN_LOCK_TIMEOUT, value) - } - - @JvmStatic - fun setBackupPassphrase(context: Context, passphrase: String?) { - setStringPreference(context, BACKUP_PASSPHRASE, passphrase) - } - - @JvmStatic - fun getBackupPassphrase(context: Context): String? { - return getStringPreference(context, BACKUP_PASSPHRASE, null) - } - - @JvmStatic - fun setEncryptedBackupPassphrase(context: Context, encryptedPassphrase: String?) { - setStringPreference(context, ENCRYPTED_BACKUP_PASSPHRASE, encryptedPassphrase) - } - - @JvmStatic - fun getEncryptedBackupPassphrase(context: Context): String? { - return getStringPreference(context, ENCRYPTED_BACKUP_PASSPHRASE, null) - } - - fun setBackupEnabled(context: Context, value: Boolean) { - setBooleanPreference(context, BACKUP_ENABLED, value) - } - - @JvmStatic - fun isBackupEnabled(context: Context): Boolean { - return getBooleanPreference(context, BACKUP_ENABLED, false) - } - - @JvmStatic - fun setNextBackupTime(context: Context, time: Long) { - setLongPreference(context, BACKUP_TIME, time) - } - - @JvmStatic - fun getNextBackupTime(context: Context): Long { - return getLongPreference(context, BACKUP_TIME, -1) - } - - fun setBackupSaveDir(context: Context, dirUri: String?) { - setStringPreference(context, BACKUP_SAVE_DIR, dirUri) - } - - fun getBackupSaveDir(context: Context): String? { - return getStringPreference(context, BACKUP_SAVE_DIR, null) - } - - @JvmStatic - fun getNeedsSqlCipherMigration(context: Context): Boolean { - return getBooleanPreference(context, NEEDS_SQLCIPHER_MIGRATION, false) - } - - @JvmStatic - fun setAttachmentEncryptedSecret(context: Context, secret: String) { - setStringPreference(context, ATTACHMENT_ENCRYPTED_SECRET, secret) - } - - @JvmStatic - fun setAttachmentUnencryptedSecret(context: Context, secret: String?) { - setStringPreference(context, ATTACHMENT_UNENCRYPTED_SECRET, secret) - } - - @JvmStatic - fun getAttachmentEncryptedSecret(context: Context): String? { - return getStringPreference(context, ATTACHMENT_ENCRYPTED_SECRET, null) - } - - @JvmStatic - fun getAttachmentUnencryptedSecret(context: Context): String? { - return getStringPreference(context, ATTACHMENT_UNENCRYPTED_SECRET, null) - } - - @JvmStatic - fun setDatabaseEncryptedSecret(context: Context, secret: String) { - setStringPreference(context, DATABASE_ENCRYPTED_SECRET, secret) - } - - @JvmStatic - fun setDatabaseUnencryptedSecret(context: Context, secret: String?) { - setStringPreference(context, DATABASE_UNENCRYPTED_SECRET, secret) - } - - @JvmStatic - fun getDatabaseUnencryptedSecret(context: Context): String? { - return getStringPreference(context, DATABASE_UNENCRYPTED_SECRET, null) - } - - @JvmStatic - fun getDatabaseEncryptedSecret(context: Context): String? { - return getStringPreference(context, DATABASE_ENCRYPTED_SECRET, null) - } - - @JvmStatic - fun isIncognitoKeyboardEnabled(context: Context): Boolean { - return getBooleanPreference(context, INCOGNITO_KEYBORAD_PREF, true) - } - - @JvmStatic - fun isReadReceiptsEnabled(context: Context): Boolean { - return getBooleanPreference(context, READ_RECEIPTS_PREF, false) - } - - fun setReadReceiptsEnabled(context: Context, enabled: Boolean) { - setBooleanPreference(context, READ_RECEIPTS_PREF, enabled) - } - - @JvmStatic - fun isTypingIndicatorsEnabled(context: Context): Boolean { - return getBooleanPreference(context, TYPING_INDICATORS, false) - } - - @JvmStatic - fun setTypingIndicatorsEnabled(context: Context, enabled: Boolean) { - setBooleanPreference(context, TYPING_INDICATORS, enabled) - } - - @JvmStatic - fun isLinkPreviewsEnabled(context: Context): Boolean { - return getBooleanPreference(context, LINK_PREVIEWS, false) - } - - @JvmStatic - fun setLinkPreviewsEnabled(context: Context, enabled: Boolean) { - setBooleanPreference(context, LINK_PREVIEWS, enabled) - } - - @JvmStatic - fun hasSeenGIFMetaDataWarning(context: Context): Boolean { - return getBooleanPreference(context, GIF_METADATA_WARNING, false) - } - - @JvmStatic - fun setHasSeenGIFMetaDataWarning(context: Context) { - setBooleanPreference(context, GIF_METADATA_WARNING, true) - } - - @JvmStatic - fun isGifSearchInGridLayout(context: Context): Boolean { - return getBooleanPreference(context, GIF_GRID_LAYOUT, false) - } - - @JvmStatic - fun setIsGifSearchInGridLayout(context: Context, isGrid: Boolean) { - setBooleanPreference(context, GIF_GRID_LAYOUT, isGrid) - } - - @JvmStatic - fun getProfileKey(context: Context): String? { - return getStringPreference(context, PROFILE_KEY_PREF, null) - } - - @JvmStatic - fun setProfileKey(context: Context, key: String?) { - setStringPreference(context, PROFILE_KEY_PREF, key) - } - - @JvmStatic - fun setProfileName(context: Context, name: String?) { - setStringPreference(context, PROFILE_NAME_PREF, name) - _events.tryEmit(PROFILE_NAME_PREF) - } - - @JvmStatic - fun getProfileName(context: Context): String? { - return getStringPreference(context, PROFILE_NAME_PREF, null) - } - - @JvmStatic - fun setProfileAvatarId(context: Context, id: Int) { - setIntegerPreference(context, PROFILE_AVATAR_ID_PREF, id) - } - - @JvmStatic - fun getProfileAvatarId(context: Context): Int { - return getIntegerPreference(context, PROFILE_AVATAR_ID_PREF, 0) - } - - fun setProfilePictureURL(context: Context, url: String?) { - setStringPreference(context, PROFILE_AVATAR_URL_PREF, url) - } - - @JvmStatic - fun getProfilePictureURL(context: Context): String? { - return getStringPreference(context, PROFILE_AVATAR_URL_PREF, null) - } - - @JvmStatic - fun getNotificationPriority(context: Context): Int { - return getStringPreference(context, NOTIFICATION_PRIORITY_PREF, NotificationCompat.PRIORITY_HIGH.toString())!!.toInt() - } - - @JvmStatic - fun getMessageBodyTextSize(context: Context): Int { - return getStringPreference(context, MESSAGE_BODY_TEXT_SIZE_PREF, "16")!!.toInt() - } - - @JvmStatic - fun setDirectCaptureCameraId(context: Context, value: Int) { - setIntegerPreference(context, DIRECT_CAPTURE_CAMERA_ID, value) - } - - @JvmStatic - fun getDirectCaptureCameraId(context: Context): Int { - return getIntegerPreference(context, DIRECT_CAPTURE_CAMERA_ID, Camera.CameraInfo.CAMERA_FACING_BACK) - } - - @JvmStatic - fun getNotificationPrivacy(context: Context): NotificationPrivacyPreference { - return NotificationPrivacyPreference(getStringPreference(context, NOTIFICATION_PRIVACY_PREF, "all")) - } - - @JvmStatic - fun getRepeatAlertsCount(context: Context): Int { - return try { - getStringPreference(context, REPEAT_ALERTS_PREF, "0")!!.toInt() - } catch (e: NumberFormatException) { - Log.w(TAG, e) - 0 - } - } - - fun getLocalRegistrationId(context: Context): Int { - return getIntegerPreference(context, LOCAL_REGISTRATION_ID_PREF, 0) - } - - fun setLocalRegistrationId(context: Context, registrationId: Int) { - setIntegerPreference(context, LOCAL_REGISTRATION_ID_PREF, registrationId) - } - - @JvmStatic - fun isInThreadNotifications(context: Context): Boolean { - return getBooleanPreference(context, IN_THREAD_NOTIFICATION_PREF, true) - } - - @JvmStatic - fun isUniversalUnidentifiedAccess(context: Context): Boolean { - return getBooleanPreference(context, UNIVERSAL_UNIDENTIFIED_ACCESS, false) - } - - @JvmStatic - fun getUpdateApkRefreshTime(context: Context): Long { - return getLongPreference(context, UPDATE_APK_REFRESH_TIME_PREF, 0L) - } - - @JvmStatic - fun setUpdateApkRefreshTime(context: Context, value: Long) { - setLongPreference(context, UPDATE_APK_REFRESH_TIME_PREF, value) - } - - @JvmStatic - fun setUpdateApkDownloadId(context: Context, value: Long) { - setLongPreference(context, UPDATE_APK_DOWNLOAD_ID, value) - } - - @JvmStatic - fun getUpdateApkDownloadId(context: Context): Long { - return getLongPreference(context, UPDATE_APK_DOWNLOAD_ID, -1) - } - - @JvmStatic - fun setUpdateApkDigest(context: Context, value: String?) { - setStringPreference(context, UPDATE_APK_DIGEST, value) - } - - @JvmStatic - fun getUpdateApkDigest(context: Context): String? { - return getStringPreference(context, UPDATE_APK_DIGEST, null) - } - - @JvmStatic - fun getLocalNumber(context: Context): String? { - return getStringPreference(context, LOCAL_NUMBER_PREF, null) - } - - @JvmStatic - fun getHasLegacyConfig(context: Context): Boolean { - return getBooleanPreference(context, HAS_RECEIVED_LEGACY_CONFIG, false) - } - - @JvmStatic - fun setHasLegacyConfig(context: Context, newValue: Boolean) { - setBooleanPreference(context, HAS_RECEIVED_LEGACY_CONFIG, newValue) - _events.tryEmit(HAS_RECEIVED_LEGACY_CONFIG) - } - - fun setLocalNumber(context: Context, localNumber: String) { - setStringPreference(context, LOCAL_NUMBER_PREF, localNumber.toLowerCase()) - } - - fun removeLocalNumber(context: Context) { - removePreference(context, LOCAL_NUMBER_PREF) - } - - @JvmStatic - fun isEnterSendsEnabled(context: Context): Boolean { - return getBooleanPreference(context, ENTER_SENDS_PREF, false) - } - - @JvmStatic - fun isPasswordDisabled(context: Context): Boolean { - return getBooleanPreference(context, DISABLE_PASSPHRASE_PREF, true) - } - - fun setPasswordDisabled(context: Context, disabled: Boolean) { - setBooleanPreference(context, DISABLE_PASSPHRASE_PREF, disabled) - } - - @JvmStatic - fun isScreenSecurityEnabled(context: Context): Boolean { - return getBooleanPreference(context, SCREEN_SECURITY_PREF, context.resources.getBoolean(R.bool.screen_security_default)) - } - - fun getLastVersionCode(context: Context): Int { - return getIntegerPreference(context, LAST_VERSION_CODE_PREF, 0) - } - - @Throws(IOException::class) - fun setLastVersionCode(context: Context, versionCode: Int) { - if (!setIntegerPreferenceBlocking(context, LAST_VERSION_CODE_PREF, versionCode)) { - throw IOException("couldn't write version code to sharedpreferences") - } - } - - @JvmStatic - fun isPassphraseTimeoutEnabled(context: Context): Boolean { - return getBooleanPreference(context, PASSPHRASE_TIMEOUT_PREF, false) - } - - @JvmStatic - fun getPassphraseTimeoutInterval(context: Context): Int { - return getIntegerPreference(context, PASSPHRASE_TIMEOUT_INTERVAL_PREF, 5 * 60) - } - - @JvmStatic - fun getLanguage(context: Context): String? { - return getStringPreference(context, LANGUAGE_PREF, "zz") - } - - @JvmStatic - fun isNotificationsEnabled(context: Context): Boolean { - return getBooleanPreference(context, NOTIFICATION_PREF, true) - } - - @JvmStatic - fun getNotificationRingtone(context: Context): Uri { - var result = getStringPreference(context, RINGTONE_PREF, Settings.System.DEFAULT_NOTIFICATION_URI.toString()) - if (result != null && result.startsWith("file:")) { - result = Settings.System.DEFAULT_NOTIFICATION_URI.toString() - } - return Uri.parse(result) - } - - @JvmStatic - fun removeNotificationRingtone(context: Context) { - removePreference(context, RINGTONE_PREF) - } - - @JvmStatic - fun setNotificationRingtone(context: Context, ringtone: String?) { - setStringPreference(context, RINGTONE_PREF, ringtone) - } - - @JvmStatic - fun setNotificationVibrateEnabled(context: Context, enabled: Boolean) { - setBooleanPreference(context, VIBRATE_PREF, enabled) - } - - @JvmStatic - fun isNotificationVibrateEnabled(context: Context): Boolean { - return getBooleanPreference(context, VIBRATE_PREF, true) - } - - @JvmStatic - fun getNotificationLedColor(context: Context): Int { - return getIntegerPreference(context, LED_COLOR_PREF_PRIMARY, ThemeUtil.getThemedColor(context, R.attr.colorAccent)) - } - - @JvmStatic - fun isThreadLengthTrimmingEnabled(context: Context): Boolean { - return getBooleanPreference(context, THREAD_TRIM_ENABLED, true) - } - - @JvmStatic - fun isSystemEmojiPreferred(context: Context): Boolean { - return getBooleanPreference(context, SYSTEM_EMOJI_PREF, false) - } - - @JvmStatic - fun getMobileMediaDownloadAllowed(context: Context): Set? { - return getMediaDownloadAllowed(context, MEDIA_DOWNLOAD_MOBILE_PREF, R.array.pref_media_download_mobile_data_default) - } - - @JvmStatic - fun getWifiMediaDownloadAllowed(context: Context): Set? { - return getMediaDownloadAllowed(context, MEDIA_DOWNLOAD_WIFI_PREF, R.array.pref_media_download_wifi_default) - } - - @JvmStatic - fun getRoamingMediaDownloadAllowed(context: Context): Set? { - return getMediaDownloadAllowed(context, MEDIA_DOWNLOAD_ROAMING_PREF, R.array.pref_media_download_roaming_default) - } - - private fun getMediaDownloadAllowed(context: Context, key: String, @ArrayRes defaultValuesRes: Int): Set? { - return getStringSetPreference(context, key, HashSet(Arrays.asList(*context.resources.getStringArray(defaultValuesRes)))) - } - - @JvmStatic - fun getLogEncryptedSecret(context: Context): String? { - return getStringPreference(context, LOG_ENCRYPTED_SECRET, null) - } - - @JvmStatic - fun setLogEncryptedSecret(context: Context, base64Secret: String?) { - setStringPreference(context, LOG_ENCRYPTED_SECRET, base64Secret) - } - - @JvmStatic - fun getLogUnencryptedSecret(context: Context): String? { - return getStringPreference(context, LOG_UNENCRYPTED_SECRET, null) - } - - @JvmStatic - fun setLogUnencryptedSecret(context: Context, base64Secret: String?) { - setStringPreference(context, LOG_UNENCRYPTED_SECRET, base64Secret) - } - - @JvmStatic - fun getNotificationChannelVersion(context: Context): Int { - return getIntegerPreference(context, NOTIFICATION_CHANNEL_VERSION, 1) - } - - @JvmStatic - fun setNotificationChannelVersion(context: Context, version: Int) { - setIntegerPreference(context, NOTIFICATION_CHANNEL_VERSION, version) - } - - @JvmStatic - fun getNotificationMessagesChannelVersion(context: Context): Int { - return getIntegerPreference(context, NOTIFICATION_MESSAGES_CHANNEL_VERSION, 1) - } - - @JvmStatic - fun setNotificationMessagesChannelVersion(context: Context, version: Int) { - setIntegerPreference(context, NOTIFICATION_MESSAGES_CHANNEL_VERSION, version) - } - - @JvmStatic - fun hasForcedNewConfig(context: Context): Boolean { - return getBooleanPreference(context, HAS_FORCED_NEW_CONFIG, false) - } - - @JvmStatic - fun getBooleanPreference(context: Context, key: String?, defaultValue: Boolean): Boolean { - return getDefaultSharedPreferences(context).getBoolean(key, defaultValue) - } - - @JvmStatic - fun setBooleanPreference(context: Context, key: String?, value: Boolean) { - getDefaultSharedPreferences(context).edit().putBoolean(key, value).apply() - } - - @JvmStatic - fun getStringPreference(context: Context, key: String, defaultValue: String?): String? { - return getDefaultSharedPreferences(context).getString(key, defaultValue) - } - - @JvmStatic - fun setStringPreference(context: Context, key: String?, value: String?) { - getDefaultSharedPreferences(context).edit().putString(key, value).apply() - } - - fun getIntegerPreference(context: Context, key: String, defaultValue: Int): Int { - return getDefaultSharedPreferences(context).getInt(key, defaultValue) - } - - private fun setIntegerPreference(context: Context, key: String, value: Int) { - getDefaultSharedPreferences(context).edit().putInt(key, value).apply() - } - - private fun setIntegerPreferenceBlocking(context: Context, key: String, value: Int): Boolean { - return getDefaultSharedPreferences(context).edit().putInt(key, value).commit() - } - - private fun getLongPreference(context: Context, key: String, defaultValue: Long): Long { - return getDefaultSharedPreferences(context).getLong(key, defaultValue) - } - - private fun setLongPreference(context: Context, key: String, value: Long) { - getDefaultSharedPreferences(context).edit().putLong(key, value).apply() - } - - private fun removePreference(context: Context, key: String) { - getDefaultSharedPreferences(context).edit().remove(key).apply() - } - - private fun getStringSetPreference(context: Context, key: String, defaultValues: Set): Set? { - val prefs = getDefaultSharedPreferences(context) - return if (prefs.contains(key)) { - prefs.getStringSet(key, emptySet()) - } else { - defaultValues - } - } - - fun getHasViewedSeed(context: Context): Boolean { - return getBooleanPreference(context, "has_viewed_seed", false) - } - - fun setHasViewedSeed(context: Context, hasViewedSeed: Boolean) { - setBooleanPreference(context, "has_viewed_seed", hasViewedSeed) - } - - fun setRestorationTime(context: Context, time: Long) { - setLongPreference(context, "restoration_time", time) - } - - fun getRestorationTime(context: Context): Long { - return getLongPreference(context, "restoration_time", 0) - } - - @JvmStatic - fun getLastProfilePictureUpload(context: Context): Long { - return getLongPreference(context, "last_profile_picture_upload", 0) - } - - @JvmStatic - fun setLastProfilePictureUpload(context: Context, newValue: Long) { - setLongPreference(context, "last_profile_picture_upload", newValue) - } - - fun getLastSnodePoolRefreshDate(context: Context?): Long { - return getLongPreference(context!!, "last_snode_pool_refresh_date", 0) - } - - fun setLastSnodePoolRefreshDate(context: Context?, date: Date) { - setLongPreference(context!!, "last_snode_pool_refresh_date", date.time) - } - - @JvmStatic - fun shouldUpdateProfile(context: Context, profileUpdateTime: Long): Boolean { - return profileUpdateTime > getLongPreference(context, LAST_PROFILE_UPDATE_TIME, 0) - } - - @JvmStatic - fun setLastProfileUpdateTime(context: Context, profileUpdateTime: Long) { - setLongPreference(context, LAST_PROFILE_UPDATE_TIME, profileUpdateTime) - } - - fun getLastOpenTimeDate(context: Context): Long { - return getLongPreference(context, LAST_OPEN_DATE, 0) - } - - fun setLastOpenDate(context: Context) { - setLongPreference(context, LAST_OPEN_DATE, System.currentTimeMillis()) - } - - fun hasSeenLinkPreviewSuggestionDialog(context: Context): Boolean { - return getBooleanPreference(context, "has_seen_link_preview_suggestion_dialog", false) - } - - fun setHasSeenLinkPreviewSuggestionDialog(context: Context) { - setBooleanPreference(context, "has_seen_link_preview_suggestion_dialog", true) - } - - @JvmStatic - fun hasHiddenMessageRequests(context: Context): Boolean { - return getBooleanPreference(context, HAS_HIDDEN_MESSAGE_REQUESTS, false) - } - - @JvmStatic - fun removeHasHiddenMessageRequests(context: Context) { - removePreference(context, HAS_HIDDEN_MESSAGE_REQUESTS) - } - - @JvmStatic - fun isCallNotificationsEnabled(context: Context): Boolean { - return getBooleanPreference(context, CALL_NOTIFICATIONS_ENABLED, false) - } - - @JvmStatic - fun setShownCallWarning(context: Context): Boolean { - val previousValue = getBooleanPreference(context, SHOWN_CALL_WARNING, false) - if (previousValue) { - return false - } - val setValue = true - setBooleanPreference(context, SHOWN_CALL_WARNING, setValue) - return previousValue != setValue - } - - @JvmStatic - fun getLastVacuumTime(context: Context): Long { - return getLongPreference(context, LAST_VACUUM_TIME, 0) - } - - @JvmStatic - fun setLastVacuumNow(context: Context) { - setLongPreference(context, LAST_VACUUM_TIME, System.currentTimeMillis()) - } - - @JvmStatic - fun getFingerprintKeyGenerated(context: Context): Boolean { - return getBooleanPreference(context, FINGERPRINT_KEY_GENERATED, false) - } - - @JvmStatic - fun setFingerprintKeyGenerated(context: Context) { - setBooleanPreference(context, FINGERPRINT_KEY_GENERATED, true) - } - - @JvmStatic - fun clearAll(context: Context) { - getDefaultSharedPreferences(context).edit().clear().commit() - } - - @JvmStatic - fun hasAppliedPatchSnodeVersion(context: Context): Boolean { - return getBooleanPreference(context, PATCH_SNODE_VERSION_2024_07_23, false) - } - - @JvmStatic - fun setHasAppliedPatchSnodeVersion(context: Context, applied: Boolean) { - setBooleanPreference(context, PATCH_SNODE_VERSION_2024_07_23, applied) - } - } -} - -@Singleton -class AppTextSecurePreferences @Inject constructor( - @ApplicationContext private val context: Context -): TextSecurePreferences { - - override fun getLastConfigurationSyncTime(): Long { - return getLongPreference(TextSecurePreferences.LAST_CONFIGURATION_SYNC_TIME, 0) - } - - override fun setLastConfigurationSyncTime(value: Long) { - setLongPreference(TextSecurePreferences.LAST_CONFIGURATION_SYNC_TIME, value) - } - - override fun getConfigurationMessageSynced(): Boolean { - return getBooleanPreference(TextSecurePreferences.CONFIGURATION_SYNCED, false) - } - - override fun setConfigurationMessageSynced(value: Boolean) { - setBooleanPreference(TextSecurePreferences.CONFIGURATION_SYNCED, value) - TextSecurePreferences._events.tryEmit(TextSecurePreferences.CONFIGURATION_SYNCED) - } - - override fun isPushEnabled(): Boolean { - return getBooleanPreference(TextSecurePreferences.IS_PUSH_ENABLED, false) - } - - override fun setPushEnabled(value: Boolean) { - setBooleanPreference(TextSecurePreferences.IS_PUSH_ENABLED, value) - } - - override fun getPushToken(): String? { - return getStringPreference(TextSecurePreferences.PUSH_TOKEN, "") - } - - override fun setPushToken(value: String) { - setStringPreference(TextSecurePreferences.PUSH_TOKEN, value) - } - - override fun getPushRegisterTime(): Long { - return getLongPreference(TextSecurePreferences.PUSH_REGISTER_TIME, 0) - } - - override fun setPushRegisterTime(value: Long) { - setLongPreference(TextSecurePreferences.PUSH_REGISTER_TIME, value) - } - - override fun isScreenLockEnabled(): Boolean { - return getBooleanPreference(TextSecurePreferences.SCREEN_LOCK, false) - } - - override fun setScreenLockEnabled(value: Boolean) { - setBooleanPreference(TextSecurePreferences.SCREEN_LOCK, value) - } - - override fun getScreenLockTimeout(): Long { - return getLongPreference(TextSecurePreferences.SCREEN_LOCK_TIMEOUT, 0) - } - - override fun setScreenLockTimeout(value: Long) { - setLongPreference(TextSecurePreferences.SCREEN_LOCK_TIMEOUT, value) - } - - override fun setBackupPassphrase(passphrase: String?) { - setStringPreference(TextSecurePreferences.BACKUP_PASSPHRASE, passphrase) - } - - override fun getBackupPassphrase(): String? { - return getStringPreference(TextSecurePreferences.BACKUP_PASSPHRASE, null) - } - - override fun setEncryptedBackupPassphrase(encryptedPassphrase: String?) { - setStringPreference(TextSecurePreferences.ENCRYPTED_BACKUP_PASSPHRASE, encryptedPassphrase) - } - - override fun getEncryptedBackupPassphrase(): String? { - return getStringPreference(TextSecurePreferences.ENCRYPTED_BACKUP_PASSPHRASE, null) - } - - override fun setBackupEnabled(value: Boolean) { - setBooleanPreference(TextSecurePreferences.BACKUP_ENABLED, value) - } - - override fun isBackupEnabled(): Boolean { - return getBooleanPreference(TextSecurePreferences.BACKUP_ENABLED, false) - } - - override fun setNextBackupTime(time: Long) { - setLongPreference(TextSecurePreferences.BACKUP_TIME, time) - } - - override fun getNextBackupTime(): Long { - return getLongPreference(TextSecurePreferences.BACKUP_TIME, -1) - } - - override fun setBackupSaveDir(dirUri: String?) { - setStringPreference(TextSecurePreferences.BACKUP_SAVE_DIR, dirUri) - } - - override fun getBackupSaveDir(): String? { - return getStringPreference(TextSecurePreferences.BACKUP_SAVE_DIR, null) - } - - override fun getNeedsSqlCipherMigration(): Boolean { - return getBooleanPreference(TextSecurePreferences.NEEDS_SQLCIPHER_MIGRATION, false) - } - - override fun setAttachmentEncryptedSecret(secret: String) { - setStringPreference(TextSecurePreferences.ATTACHMENT_ENCRYPTED_SECRET, secret) - } - - override fun setAttachmentUnencryptedSecret(secret: String?) { - setStringPreference(TextSecurePreferences.ATTACHMENT_UNENCRYPTED_SECRET, secret) - } - - override fun getAttachmentEncryptedSecret(): String? { - return getStringPreference(TextSecurePreferences.ATTACHMENT_ENCRYPTED_SECRET, null) - } - - override fun getAttachmentUnencryptedSecret(): String? { - return getStringPreference(TextSecurePreferences.ATTACHMENT_UNENCRYPTED_SECRET, null) - } - - override fun setDatabaseEncryptedSecret(secret: String) { - setStringPreference(TextSecurePreferences.DATABASE_ENCRYPTED_SECRET, secret) - } - - override fun setDatabaseUnencryptedSecret(secret: String?) { - setStringPreference(TextSecurePreferences.DATABASE_UNENCRYPTED_SECRET, secret) - } - - override fun getDatabaseUnencryptedSecret(): String? { - return getStringPreference(TextSecurePreferences.DATABASE_UNENCRYPTED_SECRET, null) - } - - override fun getDatabaseEncryptedSecret(): String? { - return getStringPreference(TextSecurePreferences.DATABASE_ENCRYPTED_SECRET, null) - } - - override fun isIncognitoKeyboardEnabled(): Boolean { - return getBooleanPreference(TextSecurePreferences.INCOGNITO_KEYBORAD_PREF, true) - } - - override fun isReadReceiptsEnabled(): Boolean { - return getBooleanPreference(TextSecurePreferences.READ_RECEIPTS_PREF, false) - } - - override fun setReadReceiptsEnabled(enabled: Boolean) { - setBooleanPreference(TextSecurePreferences.READ_RECEIPTS_PREF, enabled) - } - - override fun isTypingIndicatorsEnabled(): Boolean { - return getBooleanPreference(TextSecurePreferences.TYPING_INDICATORS, false) - } - - override fun setTypingIndicatorsEnabled(enabled: Boolean) { - setBooleanPreference(TextSecurePreferences.TYPING_INDICATORS, enabled) - } - - override fun isLinkPreviewsEnabled(): Boolean { - return getBooleanPreference(TextSecurePreferences.LINK_PREVIEWS, false) - } - - override fun setLinkPreviewsEnabled(enabled: Boolean) { - setBooleanPreference(TextSecurePreferences.LINK_PREVIEWS, enabled) - } - - override fun hasSeenGIFMetaDataWarning(): Boolean { - return getBooleanPreference(TextSecurePreferences.GIF_METADATA_WARNING, false) - } - - override fun setHasSeenGIFMetaDataWarning() { - setBooleanPreference(TextSecurePreferences.GIF_METADATA_WARNING, true) - } - - override fun isGifSearchInGridLayout(): Boolean { - return getBooleanPreference(TextSecurePreferences.GIF_GRID_LAYOUT, false) - } - - override fun setIsGifSearchInGridLayout(isGrid: Boolean) { - setBooleanPreference(TextSecurePreferences.GIF_GRID_LAYOUT, isGrid) - } - - override fun getProfileKey(): String? { - return getStringPreference(TextSecurePreferences.PROFILE_KEY_PREF, null) - } - - override fun setProfileKey(key: String?) { - setStringPreference(TextSecurePreferences.PROFILE_KEY_PREF, key) - } - - override fun setProfileName(name: String?) { - setStringPreference(TextSecurePreferences.PROFILE_NAME_PREF, name) - TextSecurePreferences._events.tryEmit(TextSecurePreferences.PROFILE_NAME_PREF) - } - - override fun getProfileName(): String? { - return getStringPreference(TextSecurePreferences.PROFILE_NAME_PREF, null) - } - - override fun setProfileAvatarId(id: Int) { - setIntegerPreference(TextSecurePreferences.PROFILE_AVATAR_ID_PREF, id) - } - - override fun getProfileAvatarId(): Int { - return getIntegerPreference(TextSecurePreferences.PROFILE_AVATAR_ID_PREF, 0) - } - - override fun setProfilePictureURL(url: String?) { - setStringPreference(TextSecurePreferences.PROFILE_AVATAR_URL_PREF, url) - } - - override fun getProfilePictureURL(): String? { - return getStringPreference(TextSecurePreferences.PROFILE_AVATAR_URL_PREF, null) - } - - override fun getNotificationPriority(): Int { - return getStringPreference( - TextSecurePreferences.NOTIFICATION_PRIORITY_PREF, NotificationCompat.PRIORITY_HIGH.toString())!!.toInt() - } - - override fun getMessageBodyTextSize(): Int { - return getStringPreference(TextSecurePreferences.MESSAGE_BODY_TEXT_SIZE_PREF, "16")!!.toInt() - } - - override fun setDirectCaptureCameraId(value: Int) { - setIntegerPreference(TextSecurePreferences.DIRECT_CAPTURE_CAMERA_ID, value) - } - - override fun getDirectCaptureCameraId(): Int { - return getIntegerPreference(TextSecurePreferences.DIRECT_CAPTURE_CAMERA_ID, Camera.CameraInfo.CAMERA_FACING_BACK) - } - - override fun getNotificationPrivacy(): NotificationPrivacyPreference { - return NotificationPrivacyPreference(getStringPreference( - TextSecurePreferences.NOTIFICATION_PRIVACY_PREF, "all")) - } - - override fun getRepeatAlertsCount(): Int { - return try { - getStringPreference(TextSecurePreferences.REPEAT_ALERTS_PREF, "0")!!.toInt() - } catch (e: NumberFormatException) { - Log.w(TextSecurePreferences.TAG, e) - 0 - } - } - - override fun getLocalRegistrationId(): Int { - return getIntegerPreference(TextSecurePreferences.LOCAL_REGISTRATION_ID_PREF, 0) - } - - override fun setLocalRegistrationId(registrationId: Int) { - setIntegerPreference(TextSecurePreferences.LOCAL_REGISTRATION_ID_PREF, registrationId) - } - - override fun isInThreadNotifications(): Boolean { - return getBooleanPreference(TextSecurePreferences.IN_THREAD_NOTIFICATION_PREF, true) - } - - override fun isUniversalUnidentifiedAccess(): Boolean { - return getBooleanPreference(TextSecurePreferences.UNIVERSAL_UNIDENTIFIED_ACCESS, false) - } - - override fun getUpdateApkRefreshTime(): Long { - return getLongPreference(TextSecurePreferences.UPDATE_APK_REFRESH_TIME_PREF, 0L) - } - - override fun setUpdateApkRefreshTime(value: Long) { - setLongPreference(TextSecurePreferences.UPDATE_APK_REFRESH_TIME_PREF, value) - } - - override fun setUpdateApkDownloadId(value: Long) { - setLongPreference(TextSecurePreferences.UPDATE_APK_DOWNLOAD_ID, value) - } - - override fun getUpdateApkDownloadId(): Long { - return getLongPreference(TextSecurePreferences.UPDATE_APK_DOWNLOAD_ID, -1) - } - - override fun setUpdateApkDigest(value: String?) { - setStringPreference(TextSecurePreferences.UPDATE_APK_DIGEST, value) - } - - override fun getUpdateApkDigest(): String? { - return getStringPreference(TextSecurePreferences.UPDATE_APK_DIGEST, null) - } - - override fun getLocalNumber(): String? { - return getStringPreference(TextSecurePreferences.LOCAL_NUMBER_PREF, null) - } - - override fun getHasLegacyConfig(): Boolean { - return getBooleanPreference(TextSecurePreferences.HAS_RECEIVED_LEGACY_CONFIG, false) - } - - override fun setHasLegacyConfig(newValue: Boolean) { - setBooleanPreference(TextSecurePreferences.HAS_RECEIVED_LEGACY_CONFIG, newValue) - TextSecurePreferences._events.tryEmit(TextSecurePreferences.HAS_RECEIVED_LEGACY_CONFIG) - } - - override fun setLocalNumber(localNumber: String) { - setStringPreference(TextSecurePreferences.LOCAL_NUMBER_PREF, localNumber.toLowerCase()) - } - - override fun removeLocalNumber() { - removePreference(TextSecurePreferences.LOCAL_NUMBER_PREF) - } - - override fun isEnterSendsEnabled(): Boolean { - return getBooleanPreference(TextSecurePreferences.ENTER_SENDS_PREF, false) - } - - override fun isPasswordDisabled(): Boolean { - return getBooleanPreference(TextSecurePreferences.DISABLE_PASSPHRASE_PREF, true) - } - - override fun setPasswordDisabled(disabled: Boolean) { - setBooleanPreference(TextSecurePreferences.DISABLE_PASSPHRASE_PREF, disabled) - } - - override fun isScreenSecurityEnabled(): Boolean { - return getBooleanPreference(TextSecurePreferences.SCREEN_SECURITY_PREF, true) - } - - override fun getLastVersionCode(): Int { - return getIntegerPreference(TextSecurePreferences.LAST_VERSION_CODE_PREF, 0) - } - - @Throws(IOException::class) - override fun setLastVersionCode(versionCode: Int) { - if (!setIntegerPreferenceBlocking(TextSecurePreferences.LAST_VERSION_CODE_PREF, versionCode)) { - throw IOException("couldn't write version code to sharedpreferences") - } - } - - override fun isPassphraseTimeoutEnabled(): Boolean { - return getBooleanPreference(TextSecurePreferences.PASSPHRASE_TIMEOUT_PREF, false) - } - - override fun getPassphraseTimeoutInterval(): Int { - return getIntegerPreference(TextSecurePreferences.PASSPHRASE_TIMEOUT_INTERVAL_PREF, 5 * 60) - } - - override fun getLanguage(): String? { - return getStringPreference(TextSecurePreferences.LANGUAGE_PREF, "zz") - } - - override fun isNotificationsEnabled(): Boolean { - return getBooleanPreference(TextSecurePreferences.NOTIFICATION_PREF, true) - } - - override fun getNotificationRingtone(): Uri { - var result = getStringPreference(TextSecurePreferences.RINGTONE_PREF, Settings.System.DEFAULT_NOTIFICATION_URI.toString()) - if (result != null && result.startsWith("file:")) { - result = Settings.System.DEFAULT_NOTIFICATION_URI.toString() - } - return Uri.parse(result) - } - - override fun removeNotificationRingtone() { - removePreference(TextSecurePreferences.RINGTONE_PREF) - } - - override fun setNotificationRingtone(ringtone: String?) { - setStringPreference(TextSecurePreferences.RINGTONE_PREF, ringtone) - } - - override fun setNotificationVibrateEnabled(enabled: Boolean) { - setBooleanPreference(TextSecurePreferences.VIBRATE_PREF, enabled) - } - - override fun isNotificationVibrateEnabled(): Boolean { - return getBooleanPreference(TextSecurePreferences.VIBRATE_PREF, true) - } - - override fun getNotificationLedColor(): Int { - return getIntegerPreference(TextSecurePreferences.LED_COLOR_PREF_PRIMARY, context.getColor(R.color.accent_green)) - } - - override fun isThreadLengthTrimmingEnabled(): Boolean { - return getBooleanPreference(TextSecurePreferences.THREAD_TRIM_ENABLED, true) - } - - override fun isSystemEmojiPreferred(): Boolean { - return getBooleanPreference(TextSecurePreferences.SYSTEM_EMOJI_PREF, false) - } - - override fun getMobileMediaDownloadAllowed(): Set? { - return getMediaDownloadAllowed(TextSecurePreferences.MEDIA_DOWNLOAD_MOBILE_PREF, R.array.pref_media_download_mobile_data_default) - } - - override fun getWifiMediaDownloadAllowed(): Set? { - return getMediaDownloadAllowed(TextSecurePreferences.MEDIA_DOWNLOAD_WIFI_PREF, R.array.pref_media_download_wifi_default) - } - - override fun getRoamingMediaDownloadAllowed(): Set? { - return getMediaDownloadAllowed(TextSecurePreferences.MEDIA_DOWNLOAD_ROAMING_PREF, R.array.pref_media_download_roaming_default) - } - - override fun getMediaDownloadAllowed(key: String, @ArrayRes defaultValuesRes: Int): Set? { - return getStringSetPreference(key, HashSet(listOf(*context.resources.getStringArray(defaultValuesRes)))) - } - - override fun getLogEncryptedSecret(): String? { - return getStringPreference(TextSecurePreferences.LOG_ENCRYPTED_SECRET, null) - } - - override fun setLogEncryptedSecret(base64Secret: String?) { - setStringPreference(TextSecurePreferences.LOG_ENCRYPTED_SECRET, base64Secret) - } - - override fun getLogUnencryptedSecret(): String? { - return getStringPreference(TextSecurePreferences.LOG_UNENCRYPTED_SECRET, null) - } - - override fun setLogUnencryptedSecret(base64Secret: String?) { - setStringPreference(TextSecurePreferences.LOG_UNENCRYPTED_SECRET, base64Secret) - } - - override fun getNotificationChannelVersion(): Int { - return getIntegerPreference(TextSecurePreferences.NOTIFICATION_CHANNEL_VERSION, 1) - } - - override fun setNotificationChannelVersion(version: Int) { - setIntegerPreference(TextSecurePreferences.NOTIFICATION_CHANNEL_VERSION, version) - } - - override fun getNotificationMessagesChannelVersion(): Int { - return getIntegerPreference(TextSecurePreferences.NOTIFICATION_MESSAGES_CHANNEL_VERSION, 1) - } - - override fun setNotificationMessagesChannelVersion(version: Int) { - setIntegerPreference(TextSecurePreferences.NOTIFICATION_MESSAGES_CHANNEL_VERSION, version) - } - - override fun hasForcedNewConfig(): Boolean = - getBooleanPreference(TextSecurePreferences.HAS_FORCED_NEW_CONFIG, false) - - override fun getBooleanPreference(key: String?, defaultValue: Boolean): Boolean { - return getDefaultSharedPreferences(context).getBoolean(key, defaultValue) - } - - override fun setBooleanPreference(key: String?, value: Boolean) { - getDefaultSharedPreferences(context).edit().putBoolean(key, value).apply() - } - - override fun getStringPreference(key: String, defaultValue: String?): String? { - return getDefaultSharedPreferences(context).getString(key, defaultValue) - } - - override fun setStringPreference(key: String?, value: String?) { - getDefaultSharedPreferences(context).edit().putString(key, value).apply() - } - - override fun getIntegerPreference(key: String, defaultValue: Int): Int { - return getDefaultSharedPreferences(context).getInt(key, defaultValue) - } - - override fun setIntegerPreference(key: String, value: Int) { - getDefaultSharedPreferences(context).edit().putInt(key, value).apply() - } - - override fun setIntegerPreferenceBlocking(key: String, value: Int): Boolean { - return getDefaultSharedPreferences(context).edit().putInt(key, value).commit() - } - - override fun getLongPreference(key: String, defaultValue: Long): Long { - return getDefaultSharedPreferences(context).getLong(key, defaultValue) - } - - override fun setLongPreference(key: String, value: Long) { - getDefaultSharedPreferences(context).edit().putLong(key, value).apply() - } - - override fun hasPreference(key: String): Boolean { - return getDefaultSharedPreferences(context).contains(key) - } +/** + * Preference definition. + */ +class Pref( + val name: String, + val default: T, + private val get: SharedPreferences.(String, T) -> T, + private val set: SharedPreferences.Editor.(String, T) -> SharedPreferences.Editor +) { + fun get(prefs: SharedPreferences) = prefs.get(name, default) + fun get(prefs: SharedPreferences, default: T) = prefs.get(name, default) + fun set(value: T?, prefs: SharedPreferences) = prefs.edit().apply { value?.let { set(name, it) } ?: run { remove(name)} }.apply() +} - override fun removePreference(key: String) { - getDefaultSharedPreferences(context).edit().remove(key).apply() - } +fun Pref(name: String, default: Boolean) = Pref(name, default, SharedPreferences::getBoolean, SharedPreferences.Editor::putBoolean) +fun Pref(name: String, default: Int) = Pref(name, default, SharedPreferences::getInt, SharedPreferences.Editor::putInt) +fun Pref(name: String, default: Long) = Pref(name, default, SharedPreferences::getLong, SharedPreferences.Editor::putLong) +fun Pref(name: String, default: String) = Pref(name, default, { _, _ -> getString(name, null) ?: default }, SharedPreferences.Editor::putStringOrRemove) +fun NullablePref(name: String, default: String?) = Pref(name, default, { _, _ -> getString(name, null) ?: default }, SharedPreferences.Editor::putStringOrRemove) +fun Pref(name: String) = Pref(name, null, SharedPreferences::getString, SharedPreferences.Editor::putStringOrRemove) +fun Pref(name: String, default: Set) = Pref(name, default, SharedPreferences::getStringSet, SharedPreferences.Editor::putStringSet) - override fun getStringSetPreference(key: String, defaultValues: Set): Set? { - val prefs = getDefaultSharedPreferences(context) - return if (prefs.contains(key)) { - prefs.getStringSet(key, emptySet()) - } else { - defaultValues - } - } +private fun SharedPreferences.Editor.putStringOrRemove(name: String, value: String?) = value?.let { putString(name, it) } ?: run { remove(name) } - override fun getHasViewedSeed(): Boolean { - return getBooleanPreference("has_viewed_seed", false) - } +operator fun SharedPreferences.get(pref: Pref): T = pref.get(this) +operator fun SharedPreferences.get(pref: Pref, default: T): T = pref.get(this, default) +operator fun SharedPreferences.set(pref: Pref, value: T?) = pref.set(value, this) - override fun setHasViewedSeed(hasViewedSeed: Boolean) { - setBooleanPreference("has_viewed_seed", hasViewedSeed) - } +val Context.prefs get() = instance ?: TextSecurePreferences(this).also { instance = it } - override fun setRestorationTime(time: Long) { - setLongPreference("restoration_time", time) - } +@Singleton +class TextSecurePreferences @Inject constructor( + @ApplicationContext private val context: Context +) { + val Context.prefs get() = TextSecurePreferences(this) - override fun getRestorationTime(): Long { - return getLongPreference("restoration_time", 0) - } + private val sharedPreferences = getDefaultSharedPreferences(context) - override fun getLastProfilePictureUpload(): Long { - return getLongPreference("last_profile_picture_upload", 0) - } + operator fun get(pref: Pref): T = sharedPreferences[pref] - override fun setLastProfilePictureUpload(newValue: Long) { - setLongPreference("last_profile_picture_upload", newValue) - } + val LED_COLOR_PREF_PRIMARY = Pref("pref_led_color_primary", ThemeUtil.getThemedColor(context, R.attr.colorAccent)) - override fun getLastSnodePoolRefreshDate(): Long { - return getLongPreference("last_snode_pool_refresh_date", 0) + fun StringSetPref(name: String, @ArrayRes defaultValuesRes: Int): Pref?> { + return Pref(name, context.resources.getStringArray(defaultValuesRes).toSet()) } - override fun setLastSnodePoolRefreshDate(date: Date) { - setLongPreference("last_snode_pool_refresh_date", date.time) - } + val MEDIA_DOWNLOAD_MOBILE_PREF = StringSetPref("pref_media_download_mobile", R.array.pref_media_download_mobile_data_default) + val MEDIA_DOWNLOAD_WIFI_PREF = StringSetPref("pref_media_download_wifi", R.array.pref_media_download_wifi_default) + val MEDIA_DOWNLOAD_ROAMING_PREF = StringSetPref("pref_media_download_roaming", R.array.pref_media_download_roaming_default) - override fun shouldUpdateProfile(profileUpdateTime: Long): Boolean { - return profileUpdateTime > getLongPreference(TextSecurePreferences.LAST_PROFILE_UPDATE_TIME, 0) - } + companion object { + val TAG = TextSecurePreferences::class.simpleName - override fun setLastProfileUpdateTime(profileUpdateTime: Long) { - setLongPreference(TextSecurePreferences.LAST_PROFILE_UPDATE_TIME, profileUpdateTime) - } + var instance: TextSecurePreferences? = null - override fun getLastOpenTimeDate(): Long { - return getLongPreference(TextSecurePreferences.LAST_OPEN_DATE, 0) - } + @JvmStatic + var pushSuffix = "" - override fun setLastOpenDate() { - setLongPreference(TextSecurePreferences.LAST_OPEN_DATE, System.currentTimeMillis()) - } + val DISABLE_PASSPHRASE_PREF = Pref("pref_disable_passphrase", true) + val LANGUAGE_PREF = Pref("pref_language", "zz") + val LAST_VERSION_CODE_PREF = Pref("last_version_code", 0) + val RINGTONE_PREF = NullablePref("pref_key_ringtone", Settings.System.DEFAULT_NOTIFICATION_URI?.toString()) + val VIBRATE_PREF = Pref("pref_key_vibrate", true) + val NOTIFICATION_PREF = Pref("pref_key_enable_notifications", true) + val PASSPHRASE_TIMEOUT_INTERVAL_PREF = Pref("pref_timeout_interval", 5 * 60) + val PASSPHRASE_TIMEOUT_PREF = Pref("pref_timeout_passphrase", false) + val SCREEN_SECURITY_PREF = Pref("pref_screen_security", true) + val ENTER_SENDS_PREF = Pref("pref_enter_sends", false) + val THREAD_TRIM_ENABLED = Pref("pref_trim_threads", true) + val LOCAL_NUMBER_PREF = Pref("pref_local_number") + val LOCAL_REGISTRATION_ID_PREF = Pref("pref_local_registration_id", 0) + val REPEAT_ALERTS_PREF = Pref("pref_repeat_alerts") + val NOTIFICATION_PRIVACY_PREF = Pref("pref_notification_privacy", "all") + val NOTIFICATION_PRIORITY_PREF = Pref("pref_notification_priority", NotificationCompat.PRIORITY_HIGH.toString()) + val SYSTEM_EMOJI_PREF = Pref("pref_system_emoji", false) + val DIRECT_CAPTURE_CAMERA_ID = Pref("pref_direct_capture_camera_id", Camera.CameraInfo.CAMERA_FACING_BACK) + val PROFILE_KEY_PREF = Pref("pref_profile_key") + val PROFILE_NAME_PREF = Pref("pref_profile_name") + val PROFILE_AVATAR_ID_PREF = Pref("pref_profile_avatar_id", 0) + val PROFILE_AVATAR_URL_PREF = Pref("pref_profile_avatar_url") + val READ_RECEIPTS_PREF = Pref("pref_read_receipts", false) + val INCOGNITO_KEYBORAD_PREF = Pref("pref_incognito_keyboard", true) + val DATABASE_ENCRYPTED_SECRET = Pref("pref_database_encrypted_secret") + val DATABASE_UNENCRYPTED_SECRET = Pref("pref_database_unencrypted_secret") + val ATTACHMENT_ENCRYPTED_SECRET = Pref("pref_attachment_encrypted_secret") + val ATTACHMENT_UNENCRYPTED_SECRET = Pref("pref_attachment_unencrypted_secret") + val SCREEN_LOCK = Pref("pref_android_screen_lock", false) + val SCREEN_LOCK_TIMEOUT = Pref("pref_android_screen_lock_timeout", 0L) + val LOG_ENCRYPTED_SECRET = Pref("pref_log_encrypted_secret") + val LOG_UNENCRYPTED_SECRET = Pref("pref_log_unencrypted_secret") + val NOTIFICATION_CHANNEL_VERSION = Pref("pref_notification_channel_version", 1) + val NOTIFICATION_MESSAGES_CHANNEL_VERSION = Pref("pref_notification_messages_channel_version", 1) + val HAS_VIEWED_SEED = Pref("has_viewed_seed", false) + val LAST_PROFILE_PICTURE_UPLOAD = Pref("last_profile_picture_upload", 0L) + val LAST_SNODE_POOL_REFRESH_DATE = Pref("last_snode_pool_refresh_date", 0L) + val TYPING_INDICATORS = Pref("pref_typing_indicators", false) + val LINK_PREVIEWS = Pref("pref_link_previews", false) + val GIF_METADATA_WARNING = Pref("has_seen_gif_metadata_warning", false) + val GIF_GRID_LAYOUT = Pref("pref_gif_grid_layout", false) + val IS_PUSH_ENABLED get() = Pref("pref_is_using_fcm$pushSuffix", false) + val PUSH_TOKEN get() = Pref("pref_fcm_token_2$pushSuffix", "") + val PUSH_REGISTER_TIME get() = Pref("pref_last_fcm_token_upload_time_2$pushSuffix", 0L) + val CONFIGURATION_SYNCED = Pref("pref_configuration_synced", false) + val LAST_PROFILE_UPDATE_TIME = Pref("pref_last_profile_update_time", 0L) + val LAST_OPEN_DATE = Pref("pref_last_open_date", 0L) + val HAS_SEEN_LINK_PREVIEW_SUGGESTION_DIALOG = Pref("has_seen_link_preview_suggestion_dialog", false) + val HAS_HIDDEN_MESSAGE_REQUESTS = Pref("pref_message_requests_hidden", false) + val CALL_NOTIFICATIONS_ENABLED = Pref("pref_call_notifications_enabled", false) + val SHOWN_CALL_NOTIFICATION = Pref("pref_shown_call_notification", false) // call notification is a prompt to check privacy settings + val LAST_VACUUM_TIME = Pref("pref_last_vacuum_time", 0L) + val AUTOPLAY_AUDIO_MESSAGES = Pref("pref_autoplay_audio", false) + val FINGERPRINT_KEY_GENERATED = Pref("fingerprint_key_generated", false) + val SELECTED_ACCENT_COLOR = Pref("selected_accent_color") + + val HAS_RECEIVED_LEGACY_CONFIG = Pref("has_received_legacy_config", false) + + val PATCH_SNODE_VERSION_2024_07_23 = Pref("libsession.patch_snode_version_2024_07_23", false) - override fun hasSeenLinkPreviewSuggestionDialog(): Boolean { - return getBooleanPreference("has_seen_link_preview_suggestion_dialog", false) - } + const val GREEN_ACCENT = "accent_green" + const val BLUE_ACCENT = "accent_blue" + const val PURPLE_ACCENT = "accent_purple" + const val PINK_ACCENT = "accent_pink" + const val RED_ACCENT = "accent_red" + const val ORANGE_ACCENT = "accent_orange" + const val YELLOW_ACCENT = "accent_yellow" - override fun setHasSeenLinkPreviewSuggestionDialog() { - setBooleanPreference("has_seen_link_preview_suggestion_dialog", true) - } + const val CLASSIC_DARK = "classic.dark" + const val CLASSIC_LIGHT = "classic.light" + const val OCEAN_DARK = "ocean.dark" + const val OCEAN_LIGHT = "ocean.light" - override fun isCallNotificationsEnabled(): Boolean { - return getBooleanPreference(CALL_NOTIFICATIONS_ENABLED, false) - } + val SELECTED_STYLE: Pref = Pref("pref_selected_style", CLASSIC_DARK) // classic_dark/light, ocean_dark/light + val FOLLOW_SYSTEM_SETTINGS = Pref("pref_follow_system", false) // follow system day/night + val HIDE_PASSWORD = Pref("pref_hide_password", false) - override fun getLastVacuum(): Long { - return getLongPreference(LAST_VACUUM_TIME, 0) - } + val LEGACY_PREF_KEY_SELECTED_UI_MODE = Pref("SELECTED_UI_MODE") // this will be cleared upon launching app, for users migrating to theming build - override fun setLastVacuumNow() { - setLongPreference(LAST_VACUUM_TIME, System.currentTimeMillis()) + const val ALLOW_MESSAGE_REQUESTS = "libsession.ALLOW_MESSAGE_REQUESTS" } - override fun setShownCallNotification(): Boolean { - val previousValue = getBooleanPreference(SHOWN_CALL_NOTIFICATION, false) - if (previousValue) return false - val setValue = true - setBooleanPreference(SHOWN_CALL_NOTIFICATION, setValue) - return previousValue != setValue - } + fun set(pref: Pref, value: T?) = sharedPreferences.set(pref, value) + fun remove(pref: Pref) = sharedPreferences.set(pref, null) + fun has(pref: Pref) = sharedPreferences.contains(pref.name) + fun flow(pref: Pref) = callbackFlow { + OnSharedPreferenceChangeListener { _, _ -> trySend(sharedPreferences[pref]) }.let { + trySend(sharedPreferences[pref]) + sharedPreferences.registerOnSharedPreferenceChangeListener(it) - /** - * Set the SHOWN_CALL_WARNING preference to `true` - * Return `true` if the value did update (it was previously unset) - */ - override fun setShownCallWarning() : Boolean { - val previousValue = getBooleanPreference(SHOWN_CALL_WARNING, false) - if (previousValue) { - return false + awaitClose { + sharedPreferences.unregisterOnSharedPreferenceChangeListener(it) + } } - val setValue = true - setBooleanPreference(SHOWN_CALL_WARNING, setValue) - return previousValue != setValue - } - - override fun hasHiddenMessageRequests(): Boolean { - return getBooleanPreference(TextSecurePreferences.HAS_HIDDEN_MESSAGE_REQUESTS, false) - } - - override fun setHasHiddenMessageRequests() { - setBooleanPreference(TextSecurePreferences.HAS_HIDDEN_MESSAGE_REQUESTS, true) } - override fun getFingerprintKeyGenerated(): Boolean { - return getBooleanPreference(TextSecurePreferences.FINGERPRINT_KEY_GENERATED, false) - } - - override fun setFingerprintKeyGenerated() { - setBooleanPreference(TextSecurePreferences.FINGERPRINT_KEY_GENERATED, true) - } - - override fun getSelectedAccentColor(): String? = - getStringPreference(SELECTED_ACCENT_COLOR, null) + fun getConfigurationMessageSynced(): Boolean = sharedPreferences[CONFIGURATION_SYNCED] + fun configurationMessageSyncedFlow() = flow(CONFIGURATION_SYNCED) + fun setConfigurationMessageSynced(value: Boolean) = set(CONFIGURATION_SYNCED, value) + fun isPushEnabled(): Boolean = sharedPreferences[IS_PUSH_ENABLED] + fun setPushEnabled(value: Boolean) = sharedPreferences.set(IS_PUSH_ENABLED, value) + fun getPushToken(): String? = sharedPreferences[PUSH_TOKEN] + fun setPushToken(value: String) = set(PUSH_TOKEN, value) + fun getPushRegisterTime(): Long = sharedPreferences[PUSH_REGISTER_TIME] + fun setPushRegisterTime(value: Long) = set(PUSH_REGISTER_TIME, value) + fun isScreenLockEnabled() = sharedPreferences[SCREEN_LOCK] + fun setScreenLockEnabled(value: Boolean) = set(SCREEN_LOCK, value) + fun getScreenLockTimeout(): Long = sharedPreferences[SCREEN_LOCK_TIMEOUT] + fun setScreenLockTimeout(value: Long) = set(SCREEN_LOCK_TIMEOUT, value) + fun setAttachmentEncryptedSecret(secret: String) = set(ATTACHMENT_ENCRYPTED_SECRET, secret) + fun setAttachmentUnencryptedSecret(secret: String?) = set(ATTACHMENT_UNENCRYPTED_SECRET, secret) + fun getAttachmentEncryptedSecret(): String? = sharedPreferences[ATTACHMENT_ENCRYPTED_SECRET] + fun getAttachmentUnencryptedSecret(): String? = sharedPreferences[ATTACHMENT_UNENCRYPTED_SECRET] + fun setDatabaseEncryptedSecret(secret: String) = set(DATABASE_ENCRYPTED_SECRET, secret) + fun setDatabaseUnencryptedSecret(secret: String?) = set(DATABASE_UNENCRYPTED_SECRET, secret) + fun getDatabaseUnencryptedSecret(): String? = sharedPreferences[DATABASE_UNENCRYPTED_SECRET] + fun getDatabaseEncryptedSecret(): String? = sharedPreferences[DATABASE_ENCRYPTED_SECRET] + fun isIncognitoKeyboardEnabled() = sharedPreferences[INCOGNITO_KEYBORAD_PREF] + fun isReadReceiptsEnabled(): Boolean = sharedPreferences[READ_RECEIPTS_PREF] + fun isTypingIndicatorsEnabled() = sharedPreferences[TYPING_INDICATORS] + fun isLinkPreviewsEnabled(): Boolean = sharedPreferences[LINK_PREVIEWS] + fun setLinkPreviewsEnabled(enabled: Boolean) = set(LINK_PREVIEWS, enabled) + fun hasSeenGIFMetaDataWarning(): Boolean = sharedPreferences[GIF_METADATA_WARNING] + fun setHasSeenGIFMetaDataWarning() = set(GIF_METADATA_WARNING, true) + fun isGifSearchInGridLayout() = sharedPreferences[GIF_GRID_LAYOUT] + fun setIsGifSearchInGridLayout(isGrid: Boolean) = set(GIF_GRID_LAYOUT, isGrid) + fun getProfileKey(): String? = sharedPreferences[PROFILE_KEY_PREF] + fun setProfileKey(key: String?) = set(PROFILE_KEY_PREF, key) + fun setProfileName(name: String?) = sharedPreferences.set(PROFILE_NAME_PREF, name) + fun getProfileName(): String? = sharedPreferences[PROFILE_NAME_PREF] + fun profileNameFlow() = flow(PROFILE_NAME_PREF) + fun setProfileAvatarId(id: Int) = set(PROFILE_AVATAR_ID_PREF, id) + fun getProfileAvatarId(): Int = sharedPreferences[PROFILE_AVATAR_ID_PREF] + fun setProfilePictureURL(url: String?) = set(PROFILE_AVATAR_URL_PREF, url) + fun getProfilePictureURL(): String? = sharedPreferences[PROFILE_AVATAR_URL_PREF] + fun getNotificationPriority(): Int = sharedPreferences[NOTIFICATION_PRIORITY_PREF]!!.toInt() + fun setDirectCaptureCameraId(value: Int) = set(DIRECT_CAPTURE_CAMERA_ID, value) + fun getDirectCaptureCameraId(): Int = sharedPreferences[DIRECT_CAPTURE_CAMERA_ID] + fun getNotificationPrivacy(): NotificationPrivacyPreference = NotificationPrivacyPreference(sharedPreferences[NOTIFICATION_PRIVACY_PREF]) + fun getRepeatAlertsCount(): Int = runCatching { sharedPreferences[REPEAT_ALERTS_PREF] }.getOrNull()?.toInt() ?: 0 + fun getLocalRegistrationId(): Int = sharedPreferences[LOCAL_REGISTRATION_ID_PREF] + fun setLocalRegistrationId(registrationId: Int) = set(LOCAL_REGISTRATION_ID_PREF, registrationId) + fun getLocalNumber(): String? = sharedPreferences[LOCAL_NUMBER_PREF] + fun getHasLegacyConfig(): Boolean = sharedPreferences[HAS_RECEIVED_LEGACY_CONFIG] + fun hasLegacyConfigFlow(): Flow = flow(HAS_RECEIVED_LEGACY_CONFIG) + fun setHasLegacyConfig(newValue: Boolean) = sharedPreferences.set(HAS_RECEIVED_LEGACY_CONFIG, newValue) + fun setLocalNumber(localNumber: String) = set(LOCAL_NUMBER_PREF, localNumber.lowercase()) + fun isEnterSendsEnabled() = sharedPreferences[ENTER_SENDS_PREF] + fun isPasswordDisabled(): Boolean = sharedPreferences[DISABLE_PASSPHRASE_PREF] + fun setPasswordDisabled(disabled: Boolean) = set(DISABLE_PASSPHRASE_PREF, disabled) + fun isScreenSecurityEnabled() = sharedPreferences[SCREEN_SECURITY_PREF] + fun getLastVersionCode(): Int = sharedPreferences[LAST_VERSION_CODE_PREF] + fun setLastVersionCode(versionCode: Int) = set(LAST_VERSION_CODE_PREF, versionCode) + fun isPassphraseTimeoutEnabled() = sharedPreferences[PASSPHRASE_TIMEOUT_PREF] + fun getPassphraseTimeoutInterval() = sharedPreferences[PASSPHRASE_TIMEOUT_INTERVAL_PREF] + fun getLanguage(): String? = sharedPreferences[LANGUAGE_PREF] + fun isNotificationsEnabled() = sharedPreferences[NOTIFICATION_PREF] + fun getNotificationRingtone(): String? = sharedPreferences[RINGTONE_PREF]?.takeUnless { it.startsWith("file:") } ?: RINGTONE_PREF.default + fun getNotificationRingtoneUri(): Uri = getNotificationRingtone().let(Uri::parse) + fun removeNotificationRingtone() = remove(RINGTONE_PREF) + fun setNotificationRingtone(ringtone: String?) = set(RINGTONE_PREF, ringtone) + fun setNotificationVibrateEnabled(enabled: Boolean) = set(VIBRATE_PREF, enabled) + fun isNotificationVibrateEnabled(): Boolean = sharedPreferences[VIBRATE_PREF] + fun getNotificationLedColor(): Int = sharedPreferences[LED_COLOR_PREF_PRIMARY] + fun isThreadLengthTrimmingEnabled() = sharedPreferences[THREAD_TRIM_ENABLED] + fun isSystemEmojiPreferred() = sharedPreferences[SYSTEM_EMOJI_PREF] + fun getMobileMediaDownloadAllowed(): Set? = sharedPreferences[MEDIA_DOWNLOAD_MOBILE_PREF] + fun getWifiMediaDownloadAllowed(): Set? = sharedPreferences[MEDIA_DOWNLOAD_WIFI_PREF] + fun getRoamingMediaDownloadAllowed(): Set? = sharedPreferences[MEDIA_DOWNLOAD_ROAMING_PREF] + fun getLogEncryptedSecret(): String? = sharedPreferences[LOG_ENCRYPTED_SECRET] + fun setLogEncryptedSecret(base64Secret: String?) = set(LOG_ENCRYPTED_SECRET, base64Secret) + fun getLogUnencryptedSecret(): String? = sharedPreferences[LOG_UNENCRYPTED_SECRET] + fun getNotificationChannelVersion(): Int = sharedPreferences[NOTIFICATION_CHANNEL_VERSION] + fun setNotificationChannelVersion(version: Int) = set(NOTIFICATION_CHANNEL_VERSION, version) + fun getNotificationMessagesChannelVersion(): Int = sharedPreferences[NOTIFICATION_MESSAGES_CHANNEL_VERSION] + fun setNotificationMessagesChannelVersion(version: Int) = set(NOTIFICATION_MESSAGES_CHANNEL_VERSION, version) + fun hasViewedSeed(): Boolean = sharedPreferences[HAS_VIEWED_SEED] + fun setHasViewedSeed(hasViewedSeed: Boolean) = set(HAS_VIEWED_SEED, hasViewedSeed) + fun getLastProfilePictureUpload(): Long = sharedPreferences[LAST_PROFILE_PICTURE_UPLOAD] + fun setLastProfilePictureUpload(newValue: Long) = set(LAST_PROFILE_PICTURE_UPLOAD, newValue) + fun getLastSnodePoolRefreshDate(): Long = sharedPreferences[LAST_SNODE_POOL_REFRESH_DATE] + fun setLastSnodePoolRefreshDate(date: Date) = set(LAST_SNODE_POOL_REFRESH_DATE, date.time) + fun shouldUpdateProfile(profileUpdateTime: Long): Boolean = profileUpdateTime > sharedPreferences[LAST_PROFILE_UPDATE_TIME] + fun setLastProfileUpdateTime(profileUpdateTime: Long) = set(LAST_PROFILE_UPDATE_TIME, profileUpdateTime) + fun getLastOpenTimeDate(): Long = sharedPreferences[LAST_OPEN_DATE] + fun setLastOpenDate() = set(LAST_OPEN_DATE, System.currentTimeMillis()) + fun hasSeenLinkPreviewSuggestionDialog(): Boolean = sharedPreferences[HAS_SEEN_LINK_PREVIEW_SUGGESTION_DIALOG] + fun setHasSeenLinkPreviewSuggestionDialog() = set(HAS_SEEN_LINK_PREVIEW_SUGGESTION_DIALOG, true) + fun isCallNotificationsEnabled(): Boolean = sharedPreferences[CALL_NOTIFICATIONS_ENABLED] + fun setCallNotificationsEnabled(enabled: Boolean) = set(CALL_NOTIFICATIONS_ENABLED, enabled) + fun getLastVacuumTime(): Long = sharedPreferences[LAST_VACUUM_TIME] + fun setLastVacuumNow() = set(LAST_VACUUM_TIME, System.currentTimeMillis()) + fun setShownCallNotification(): Boolean = when { + sharedPreferences[SHOWN_CALL_NOTIFICATION] -> false + else -> { + set(SHOWN_CALL_NOTIFICATION, true) + true + } + } + fun hasHiddenMessageRequests(): Boolean = sharedPreferences[HAS_HIDDEN_MESSAGE_REQUESTS] + fun hasHiddenMessageRequestsFlow() = flow(HAS_HIDDEN_MESSAGE_REQUESTS) + fun setHasHiddenMessageRequests() = set(HAS_HIDDEN_MESSAGE_REQUESTS, true) + fun removeHasHiddenMessageRequests() = remove(HAS_HIDDEN_MESSAGE_REQUESTS) + fun getFingerprintKeyGenerated(): Boolean = sharedPreferences[FINGERPRINT_KEY_GENERATED] + fun setFingerprintKeyGenerated() = set(FINGERPRINT_KEY_GENERATED, true) + + fun hasSelectedAccentColor() = has(SELECTED_ACCENT_COLOR) + fun getSelectedAccentColor(): String? = sharedPreferences[SELECTED_ACCENT_COLOR] + + var hasAppliedPatchSnodeVersion: Boolean + get() = sharedPreferences[PATCH_SNODE_VERSION_2024_07_23] + set(value) = set(PATCH_SNODE_VERSION_2024_07_23, value) @StyleRes - override fun getAccentColorStyle(): Int? { - return when (getSelectedAccentColor()) { - TextSecurePreferences.GREEN_ACCENT -> R.style.PrimaryGreen - TextSecurePreferences.BLUE_ACCENT -> R.style.PrimaryBlue - TextSecurePreferences.PURPLE_ACCENT -> R.style.PrimaryPurple - TextSecurePreferences.PINK_ACCENT -> R.style.PrimaryPink - TextSecurePreferences.RED_ACCENT -> R.style.PrimaryRed - TextSecurePreferences.ORANGE_ACCENT -> R.style.PrimaryOrange - TextSecurePreferences.YELLOW_ACCENT -> R.style.PrimaryYellow - else -> null - } - } - - override fun setAccentColorStyle(@StyleRes newColorStyle: Int?) { - setStringPreference( - TextSecurePreferences.SELECTED_ACCENT_COLOR, when (newColorStyle) { - R.style.PrimaryGreen -> TextSecurePreferences.GREEN_ACCENT - R.style.PrimaryBlue -> TextSecurePreferences.BLUE_ACCENT - R.style.PrimaryPurple -> TextSecurePreferences.PURPLE_ACCENT - R.style.PrimaryPink -> TextSecurePreferences.PINK_ACCENT - R.style.PrimaryRed -> TextSecurePreferences.RED_ACCENT - R.style.PrimaryOrange -> TextSecurePreferences.ORANGE_ACCENT - R.style.PrimaryYellow -> TextSecurePreferences.YELLOW_ACCENT - else -> null - } - ) + fun getAccentColorStyle(): Int? = when (getSelectedAccentColor()) { + GREEN_ACCENT -> R.style.PrimaryGreen + BLUE_ACCENT -> R.style.PrimaryBlue + PURPLE_ACCENT -> R.style.PrimaryPurple + PINK_ACCENT -> R.style.PrimaryPink + RED_ACCENT -> R.style.PrimaryRed + ORANGE_ACCENT -> R.style.PrimaryOrange + YELLOW_ACCENT -> R.style.PrimaryYellow + else -> null } - override fun getThemeStyle(): String { - val hasLegacy = getStringPreference(LEGACY_PREF_KEY_SELECTED_UI_MODE, null) - if (!hasLegacy.isNullOrEmpty()) { - migrateLegacyUiPref() - } + fun setAccentColorStyle(@StyleRes newColorStyle: Int?) = when (newColorStyle) { + R.style.PrimaryGreen -> GREEN_ACCENT + R.style.PrimaryBlue -> BLUE_ACCENT + R.style.PrimaryPurple -> PURPLE_ACCENT + R.style.PrimaryPink -> PINK_ACCENT + R.style.PrimaryRed -> RED_ACCENT + R.style.PrimaryOrange -> ORANGE_ACCENT + R.style.PrimaryYellow -> YELLOW_ACCENT + else -> null + }.let { set(SELECTED_ACCENT_COLOR, it) } - return getStringPreference(SELECTED_STYLE, CLASSIC_DARK)!! + fun getThemeStyle(): String { + migrateLegacyUiPrefIfNecessary() + return sharedPreferences[SELECTED_STYLE] } - override fun setThemeStyle(themeStyle: String) { - val safeTheme = if (themeStyle !in listOf(CLASSIC_DARK, CLASSIC_LIGHT, OCEAN_DARK, OCEAN_LIGHT)) CLASSIC_DARK else themeStyle - setStringPreference(SELECTED_STYLE, safeTheme) + fun setThemeStyle(themeStyle: String) { + sharedPreferences[SELECTED_STYLE] = if (themeStyle !in listOf(CLASSIC_DARK, CLASSIC_LIGHT, OCEAN_DARK, OCEAN_LIGHT)) CLASSIC_DARK else themeStyle } - override fun getFollowSystemSettings(): Boolean { - val hasLegacy = getStringPreference(LEGACY_PREF_KEY_SELECTED_UI_MODE, null) - if (!hasLegacy.isNullOrEmpty()) { - migrateLegacyUiPref() - } - - return getBooleanPreference(FOLLOW_SYSTEM_SETTINGS, false) + fun getFollowSystemSettings(): Boolean { + migrateLegacyUiPrefIfNecessary() + return sharedPreferences[FOLLOW_SYSTEM_SETTINGS] } - private fun migrateLegacyUiPref() { - val legacy = getStringPreference(LEGACY_PREF_KEY_SELECTED_UI_MODE, null) ?: return + private fun migrateLegacyUiPrefIfNecessary() { + val legacy = sharedPreferences[LEGACY_PREF_KEY_SELECTED_UI_MODE] ?: return val (mode, followSystem) = when (legacy) { - "DAY" -> { - CLASSIC_LIGHT to false - } - "NIGHT" -> { - CLASSIC_DARK to false - } - "SYSTEM_DEFAULT" -> { - CLASSIC_DARK to true - } - else -> { - CLASSIC_DARK to false - } + "DAY" -> CLASSIC_LIGHT to false + "NIGHT" -> CLASSIC_DARK to false + "SYSTEM_DEFAULT" -> CLASSIC_DARK to true + else -> CLASSIC_DARK to false } - if (!hasPreference(FOLLOW_SYSTEM_SETTINGS) && !hasPreference(SELECTED_STYLE)) { + if (!has(FOLLOW_SYSTEM_SETTINGS) && !has(SELECTED_STYLE)) { setThemeStyle(mode) setFollowSystemSettings(followSystem) } - removePreference(LEGACY_PREF_KEY_SELECTED_UI_MODE) - } - - override fun setFollowSystemSettings(followSystemSettings: Boolean) { - setBooleanPreference(FOLLOW_SYSTEM_SETTINGS, followSystemSettings) - } - - override fun autoplayAudioMessages(): Boolean { - return getBooleanPreference(AUTOPLAY_AUDIO_MESSAGES, false) - } - - override fun clearAll() { - getDefaultSharedPreferences(context).edit().clear().commit() + remove(LEGACY_PREF_KEY_SELECTED_UI_MODE) } - override fun getHidePassword() = getBooleanPreference(HIDE_PASSWORD, false) - - override fun setHidePassword(value: Boolean) { - setBooleanPreference(HIDE_PASSWORD, value) - } + fun setFollowSystemSettings(followSystemSettings: Boolean) = set(FOLLOW_SYSTEM_SETTINGS, followSystemSettings) + fun autoplayAudioMessages(): Boolean = sharedPreferences[AUTOPLAY_AUDIO_MESSAGES] + fun clearAll() = getDefaultSharedPreferences(context).edit().clear().commit() + fun getHidePassword() = sharedPreferences[HIDE_PASSWORD] + fun setHidePassword(value: Boolean) = set(HIDE_PASSWORD, value) } + +fun

PreferenceFragmentCompat.findPreference(pref: Pref<*>) = findPreference

(pref.name) diff --git a/libsession/src/main/java/org/session/libsession/utilities/Util.kt b/libsession/src/main/java/org/session/libsession/utilities/Util.kt index 929f53e305e..5f076ec286d 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/Util.kt +++ b/libsession/src/main/java/org/session/libsession/utilities/Util.kt @@ -11,6 +11,7 @@ import android.text.Spannable import android.text.SpannableString import android.text.TextUtils import android.text.style.StyleSpan +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.Base64 import java.io.* @@ -209,8 +210,8 @@ object Util { } @JvmStatic - fun isOwnNumber(context: Context, number: String): Boolean { - return TextSecurePreferences.getLocalNumber(context).equals(number) + fun isOwnNumber(number: String): Boolean { + return MessagingModuleConfiguration.shared.context.prefs.getLocalNumber().equals(number) } @JvmStatic diff --git a/libsession/src/main/java/org/session/libsession/utilities/recipients/Recipient.java b/libsession/src/main/java/org/session/libsession/utilities/recipients/Recipient.java index 0aef1583872..fcf353d88c9 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/recipients/Recipient.java +++ b/libsession/src/main/java/org/session/libsession/utilities/recipients/Recipient.java @@ -17,6 +17,8 @@ */ package org.session.libsession.utilities.recipients; +import static org.session.libsession.utilities.TextSecurePreferencesKt.getPrefs; + import android.content.Context; import android.graphics.drawable.Drawable; import android.net.Uri; @@ -524,7 +526,7 @@ public synchronized String toShortString() { } public synchronized @Nullable ContactPhoto getContactPhoto() { - if (isLocalNumber) return new ProfileContactPhoto(address, String.valueOf(TextSecurePreferences.getProfileAvatarId(context))); + if (isLocalNumber) return new ProfileContactPhoto(address, String.valueOf(getPrefs(MessagingModuleConfiguration.getShared().getContext()).getProfileAvatarId())); else if (isGroupRecipient() && groupAvatarId != null) return new GroupRecordContactPhoto(address, groupAvatarId); else if (systemContactPhoto != null) return new SystemContactPhoto(address, systemContactPhoto, 0); else if (profileAvatar != null) return new ProfileContactPhoto(address, profileAvatar); diff --git a/libsession/src/main/java/org/session/libsession/utilities/recipients/RecipientProvider.java b/libsession/src/main/java/org/session/libsession/utilities/recipients/RecipientProvider.java index 374956072bc..f6488e2bcfc 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/recipients/RecipientProvider.java +++ b/libsession/src/main/java/org/session/libsession/utilities/recipients/RecipientProvider.java @@ -16,6 +16,8 @@ */ package org.session.libsession.utilities.recipients; +import static org.session.libsession.utilities.TextSecurePreferencesKt.getPrefs; + import android.content.Context; import android.net.Uri; import android.text.TextUtils; @@ -80,14 +82,16 @@ boolean removeCached(@NonNull Address address) { return recipientCache.remove(address); } - private @NonNull Optional createPrefetchedRecipientDetails(@NonNull Context context, @NonNull Address address, + private @NonNull Optional createPrefetchedRecipientDetails(@NonNull Context context, + @NonNull Address address, @NonNull Optional settings, @NonNull Optional groupRecord) { if (address.isGroup() && settings.isPresent() && groupRecord.isPresent()) { return Optional.of(getGroupRecipientDetails(context, address, groupRecord, settings, true)); } else if (!address.isGroup() && settings.isPresent()) { - boolean isLocalNumber = address.serialize().equals(TextSecurePreferences.getLocalNumber(context)); + TextSecurePreferences prefs = getPrefs(context); + boolean isLocalNumber = address.serialize().equals(prefs.getLocalNumber()); return Optional.of(new RecipientDetails(null, null, !TextUtils.isEmpty(settings.get().getSystemDisplayName()), isLocalNumber, settings.get(), null)); } @@ -114,7 +118,8 @@ boolean removeCached(@NonNull Address address) { } boolean systemContact = settings.isPresent() && !TextUtils.isEmpty(settings.get().getSystemDisplayName()); - boolean isLocalNumber = address.serialize().equals(TextSecurePreferences.getLocalNumber(context)); + TextSecurePreferences prefs = getPrefs(context); + boolean isLocalNumber = address.serialize().equals(prefs.getLocalNumber()); return new RecipientDetails(null, null, systemContact, isLocalNumber, settings.orNull(), null); }