diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/messages/SyncMessageProcessorTest_attachmentBackfill.kt b/app/src/androidTest/java/org/thoughtcrime/securesms/messages/SyncMessageProcessorTest_attachmentBackfill.kt index fae40ea092..613bdaf8bf 100644 --- a/app/src/androidTest/java/org/thoughtcrime/securesms/messages/SyncMessageProcessorTest_attachmentBackfill.kt +++ b/app/src/androidTest/java/org/thoughtcrime/securesms/messages/SyncMessageProcessorTest_attachmentBackfill.kt @@ -26,7 +26,6 @@ import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.testing.MessageContentFuzzer import org.thoughtcrime.securesms.testing.SignalActivityRule import org.thoughtcrime.securesms.util.MediaUtil -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.signalservice.api.push.SignalServiceAddress import org.whispersystems.signalservice.internal.push.AddressableMessage import org.whispersystems.signalservice.internal.push.AttachmentPointer @@ -54,12 +53,9 @@ class SyncMessageProcessorTest_attachmentBackfill { SignalStore.account.deviceId = 2 // Prevent AttachmentDownloadJob onAdded from async changing the attachment state. - TextSecurePreferences.getSharedPreferences(harness.application) - .edit() - .putStringSet(TextSecurePreferences.MEDIA_DOWNLOAD_WIFI_PREF, emptySet()) - .putStringSet(TextSecurePreferences.MEDIA_DOWNLOAD_MOBILE_PREF, emptySet()) - .putStringSet(TextSecurePreferences.MEDIA_DOWNLOAD_ROAMING_PREF, emptySet()) - .commit() + SignalStore.settings.wifiMediaDownloadAllowed = emptySet() + SignalStore.settings.mobileMediaDownloadAllowed = emptySet() + SignalStore.settings.roamingMediaDownloadAllowed = emptySet() } @After diff --git a/app/src/benchmarkShared/java/org/signal/benchmark/BenchmarkSetupActivity.kt b/app/src/benchmarkShared/java/org/signal/benchmark/BenchmarkSetupActivity.kt index b46f8d021f..3de850a4e0 100644 --- a/app/src/benchmarkShared/java/org/signal/benchmark/BenchmarkSetupActivity.kt +++ b/app/src/benchmarkShared/java/org/signal/benchmark/BenchmarkSetupActivity.kt @@ -26,7 +26,6 @@ import org.thoughtcrime.securesms.mms.OutgoingMessage import org.thoughtcrime.securesms.profiles.ProfileName import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.registration.util.RegistrationUtil -import org.thoughtcrime.securesms.util.TextSecurePreferences class BenchmarkSetupActivity : BaseActivity() { @@ -269,7 +268,7 @@ class BenchmarkSetupActivity : BaseActivity() { } if (enableReadReceipts) { - TextSecurePreferences.setReadReceiptsEnabled(this, true) + SignalStore.settings.isReadReceiptsEnabled = true } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/AppInitialization.java b/app/src/main/java/org/thoughtcrime/securesms/AppInitialization.java index fba212d6ab..b934e79b6e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/AppInitialization.java +++ b/app/src/main/java/org/thoughtcrime/securesms/AppInitialization.java @@ -40,8 +40,8 @@ public final class AppInitialization { PlainTextKeyValueStore.setLastVersionCode(BuildConfig.VERSION_CODE); TextSecurePreferences.setHasSeenStickerIntroTooltip(context, true); SignalStore.settings().setPassphraseDisabled(true); - TextSecurePreferences.setReadReceiptsEnabled(context, true); - TextSecurePreferences.setTypingIndicatorsEnabled(context, true); + SignalStore.settings().setReadReceiptsEnabled(true); + SignalStore.settings().setTypingIndicatorsEnabled(true); AppDependencies.getMegaphoneRepository().onFirstEverAppLaunch(); SignalStore.onFirstEverAppLaunch(); AppDependencies.getJobManager().addAll(BlessedPacks.getFirstInstallJobs()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/BackupDialog.java b/app/src/main/java/org/thoughtcrime/securesms/backup/BackupDialog.java index 038bed8ef2..9bc0bcb162 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/BackupDialog.java +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/BackupDialog.java @@ -29,7 +29,6 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.restore.restorelocalbackup.PassphraseAsYouTypeFormatter; import org.thoughtcrime.securesms.service.LocalBackupListener; import org.thoughtcrime.securesms.util.BackupUtil; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.signal.core.util.Util; import org.thoughtcrime.securesms.util.text.AfterTextChanged; @@ -74,7 +73,7 @@ public class BackupDialog { } BackupPassphrase.set(context, Util.join(password, " ")); - TextSecurePreferences.setNextBackupTime(context, 0); + SignalStore.settings().setLocalBackupNextTime(0); SignalStore.settings().setBackupEnabled(true); LocalBackupListener.schedule(context); diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupExporter.java b/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupExporter.java index 558de499cf..0da1c2f3eb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupExporter.java +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupExporter.java @@ -52,7 +52,6 @@ import org.thoughtcrime.securesms.dependencies.AppDependencies; import org.thoughtcrime.securesms.keyvalue.KeyValueDataSet; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.profiles.AvatarHelper; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import java.io.File; import java.io.FileNotFoundException; @@ -195,14 +194,6 @@ public class FullBackupExporter extends FullBackupBase { stopwatch.split("table::" + table); } - for (SharedPreference preference : TextSecurePreferences.getPreferencesToSaveToBackup(context)) { - throwIfCanceled(cancellationSignal); - EventBus.getDefault().post(new BackupEvent(BackupEvent.Type.PROGRESS, ++count, estimatedCount)); - outputStream.write(preference); - } - - stopwatch.split("prefs"); - count = exportKeyValues(outputStream, SignalStore.getKeysToIncludeInBackup(), count, estimatedCount, cancellationSignal); stopwatch.split("key_values"); @@ -248,8 +239,6 @@ public class FullBackupExporter extends FullBackupBase { count += IDENTITY_KEY_BACKUP_RECORD_COUNT; - count += TextSecurePreferences.getPreferencesToSaveToBackupCount(context); - KeyValueDataSet dataSet = KeyValueDatabase.getInstance(AppDependencies.getApplication()) .getDataSet(); for (String key : SignalStore.getKeysToIncludeInBackup()) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/processor/AccountDataArchiveProcessor.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/processor/AccountDataArchiveProcessor.kt index 93170ce29a..3d9c3288f9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/processor/AccountDataArchiveProcessor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/processor/AccountDataArchiveProcessor.kt @@ -5,7 +5,6 @@ package org.thoughtcrime.securesms.backup.v2.processor -import android.content.Context import okio.ByteString.Companion.EMPTY import okio.ByteString.Companion.toByteString import org.signal.archive.proto.AccountData @@ -44,7 +43,6 @@ import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.util.Environment import org.thoughtcrime.securesms.util.ProfileUtil -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.webrtc.CallDataMode import org.whispersystems.signalservice.api.push.UsernameLinkComponents import org.whispersystems.signalservice.api.storage.IAPSubscriptionId.AppleIAPOriginalTransactionId @@ -82,8 +80,8 @@ object AccountDataArchiveProcessor { null } - val mobileAutoDownload = TextSecurePreferences.getMobileMediaDownloadAllowed(context) - val wifiAutoDownload = TextSecurePreferences.getWifiMediaDownloadAllowed(context) + val mobileAutoDownload = SignalStore.settings.mobileMediaDownloadAllowed + val wifiAutoDownload = SignalStore.settings.wifiMediaDownloadAllowed val username = selfRecord.username?.takeIf { it.isValidUsername() } @@ -107,10 +105,10 @@ object AccountDataArchiveProcessor { }, accountSettings = AccountData.AccountSettings( storyViewReceiptsEnabled = signalStore.storyValues.viewedReceiptsEnabled, - typingIndicators = TextSecurePreferences.isTypingIndicatorsEnabled(context), - readReceipts = TextSecurePreferences.isReadReceiptsEnabled(context), - sealedSenderIndicators = TextSecurePreferences.isShowUnidentifiedDeliveryIndicatorsEnabled(context), - allowSealedSenderFromAnyone = TextSecurePreferences.isUniversalUnidentifiedAccess(context), + typingIndicators = SignalStore.settings.isTypingIndicatorsEnabled, + readReceipts = SignalStore.settings.isReadReceiptsEnabled, + sealedSenderIndicators = SignalStore.settings.isShowUnidentifiedDeliveryIndicatorsEnabled, + allowSealedSenderFromAnyone = SignalStore.settings.isUniversalUnidentifiedAccess, linkPreviews = signalStore.settingsValues.isLinkPreviewsEnabled, notDiscoverableByPhoneNumber = signalStore.phoneNumberPrivacyValues.phoneNumberDiscoverabilityMode == PhoneNumberDiscoverabilityMode.NOT_DISCOVERABLE, phoneNumberSharingMode = signalStore.phoneNumberPrivacyValues.phoneNumberSharingMode.toRemotePhoneNumberSharingMode(), @@ -160,7 +158,7 @@ object AccountDataArchiveProcessor { backupsSubscriberData = backupSubscriberRecord?.toIAPSubscriberData(), androidSpecificSettings = AccountData.AndroidSpecificSettings( useSystemEmoji = signalStore.settingsValues.isPreferSystemEmoji, - screenshotSecurity = TextSecurePreferences.isScreenSecurityEnabled(context), + screenshotSecurity = SignalStore.settings.isScreenSecurityEnabled, navigationBarSize = signalStore.settingsValues.useCompactNavigationBar.toRemoteNavigationBarSize() ).takeUnless { Environment.IS_INSTRUMENTATION && SignalStore.backup.importedEmptyAndroidSettings }, bioText = selfRecord.about ?: "", @@ -178,17 +176,16 @@ object AccountDataArchiveProcessor { SignalStore.svr.setPin(accountData.svrPin) } - val context = AppDependencies.application val settings = accountData.accountSettings if (settings != null) { - importSettings(context, settings, importState) + importSettings(settings, importState) } val androidSpecificSettings = accountData.androidSpecificSettings if (androidSpecificSettings != null) { SignalStore.settings.isPreferSystemEmoji = androidSpecificSettings.useSystemEmoji - TextSecurePreferences.setScreenSecurityEnabled(context, androidSpecificSettings.screenshotSecurity) + SignalStore.settings.isScreenSecurityEnabled = androidSpecificSettings.screenshotSecurity SignalStore.settings.useCompactNavigationBar = androidSpecificSettings.navigationBarSize.toLocalNavigationBarSize() } else if (Environment.IS_INSTRUMENTATION) { SignalStore.backup.importedEmptyAndroidSettings = true @@ -265,11 +262,11 @@ object AccountDataArchiveProcessor { Recipient.self().live().refresh() } - private fun importSettings(context: Context, settings: AccountData.AccountSettings, importState: ImportState) { - TextSecurePreferences.setReadReceiptsEnabled(context, settings.readReceipts) - TextSecurePreferences.setTypingIndicatorsEnabled(context, settings.typingIndicators) - TextSecurePreferences.setShowUnidentifiedDeliveryIndicatorsEnabled(context, settings.sealedSenderIndicators) - TextSecurePreferences.setIsUniversalUnidentifiedAccess(context, settings.allowSealedSenderFromAnyone) + private fun importSettings(settings: AccountData.AccountSettings, importState: ImportState) { + SignalStore.settings.isReadReceiptsEnabled = settings.readReceipts + SignalStore.settings.isTypingIndicatorsEnabled = settings.typingIndicators + SignalStore.settings.isShowUnidentifiedDeliveryIndicatorsEnabled = settings.sealedSenderIndicators + SignalStore.settings.isUniversalUnidentifiedAccess = settings.allowSealedSenderFromAnyone SignalStore.settings.isLinkPreviewsEnabled = settings.linkPreviews SignalStore.phoneNumberPrivacy.phoneNumberDiscoverabilityMode = if (settings.notDiscoverableByPhoneNumber) PhoneNumberDiscoverabilityMode.NOT_DISCOVERABLE else PhoneNumberDiscoverabilityMode.DISCOVERABLE SignalStore.phoneNumberPrivacy.phoneNumberSharingMode = settings.phoneNumberSharingMode.toLocalPhoneNumberMode() @@ -303,11 +300,8 @@ object AccountDataArchiveProcessor { val mobileAndWifiDownloadSet = autoDownloadSettings.toLocalAutoDownloadSet(AccountData.AutoDownloadSettings.AutoDownloadOption.WIFI_AND_CELLULAR) val wifiDownloadSet = mobileAndWifiDownloadSet + autoDownloadSettings.toLocalAutoDownloadSet(AccountData.AutoDownloadSettings.AutoDownloadOption.WIFI) - TextSecurePreferences.getSharedPreferences(context).edit().apply { - putStringSet(TextSecurePreferences.MEDIA_DOWNLOAD_MOBILE_PREF, mobileAndWifiDownloadSet) - putStringSet(TextSecurePreferences.MEDIA_DOWNLOAD_WIFI_PREF, wifiDownloadSet) - apply() - } + SignalStore.settings.mobileMediaDownloadAllowed = mobileAndWifiDownloadSet + SignalStore.settings.wifiMediaDownloadAllowed = wifiDownloadSet } val screenLockTimeoutMinutes = settings.screenLockTimeoutMinutes 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 ac44ceabee..524d152bac 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/ComposeText.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/ComposeText.java @@ -48,7 +48,6 @@ import org.thoughtcrime.securesms.database.model.Mention; import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.recipients.RecipientId; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import java.util.List; import java.util.Objects; @@ -336,7 +335,7 @@ public class ComposeText extends EmojiEditText { setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS); } - if (TextSecurePreferences.isIncognitoKeyboardEnabled(getContext())) { + if (SignalStore.settings().isIncognitoKeyboardEnabled()) { setImeOptions(getImeOptions() | 16777216); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/ContactFilterView.java b/app/src/main/java/org/thoughtcrime/securesms/components/ContactFilterView.java index 3a304f1c20..f526d74cdd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/ContactFilterView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/ContactFilterView.java @@ -20,9 +20,9 @@ import androidx.annotation.StringRes; import androidx.core.widget.TextViewCompat; import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.util.EditTextExtensionsKt; import org.signal.core.util.ServiceUtil; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.ViewUtil; /** @@ -60,7 +60,7 @@ public final class ContactFilterView extends FrameLayout { this.clearToggle = findViewById(R.id.search_clear); this.toggleContainer = findViewById(R.id.toggle_container); - EditTextExtensionsKt.setIncognitoKeyboardEnabled(searchText, TextSecurePreferences.isIncognitoKeyboardEnabled(context)); + EditTextExtensionsKt.setIncognitoKeyboardEnabled(searchText, SignalStore.settings().isIncognitoKeyboardEnabled()); this.keyboardToggle.setOnClickListener(new View.OnClickListener() { @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/TemporaryScreenshotSecurity.kt b/app/src/main/java/org/thoughtcrime/securesms/components/TemporaryScreenshotSecurity.kt index 2d807d7d47..8eee5709d5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/TemporaryScreenshotSecurity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/TemporaryScreenshotSecurity.kt @@ -14,7 +14,7 @@ import androidx.compose.runtime.DisposableEffect import androidx.fragment.app.Fragment import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.LifecycleOwner -import org.thoughtcrime.securesms.util.TextSecurePreferences +import org.thoughtcrime.securesms.keyvalue.SignalStore import java.util.WeakHashMap /** @@ -58,7 +58,7 @@ object TemporaryScreenshotSecurity { val window = activity.window val previous = activeHolds[window] ?: 0 activeHolds[window] = previous + 1 - if (previous == 0 && !TextSecurePreferences.isScreenSecurityEnabled(activity)) { + if (previous == 0 && !SignalStore.settings.isScreenSecurityEnabled) { window.addFlags(WindowManager.LayoutParams.FLAG_SECURE) } } @@ -68,7 +68,7 @@ object TemporaryScreenshotSecurity { val next = ((activeHolds[window] ?: 0) - 1).coerceAtLeast(0) if (next == 0) { activeHolds.remove(window) - if (!TextSecurePreferences.isScreenSecurityEnabled(activity)) { + if (!SignalStore.settings.isScreenSecurityEnabled) { window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE) } } else { diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiEditText.java b/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiEditText.java index 07b5ae0849..9a2de3f791 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiEditText.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiEditText.java @@ -19,7 +19,6 @@ import org.signal.emoji.EmojiProvider.EmojiDrawable; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.util.EditTextExtensionsKt; import org.signal.core.util.ServiceUtil; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.signal.core.util.Util; import java.util.HashSet; @@ -58,7 +57,7 @@ public class EmojiEditText extends AppCompatEditText { }); if (!isInEditMode()) { - EditTextExtensionsKt.setIncognitoKeyboardEnabled(this, TextSecurePreferences.isIncognitoKeyboardEnabled(context)); + EditTextExtensionsKt.setIncognitoKeyboardEnabled(this, SignalStore.settings().isIncognitoKeyboardEnabled()); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiToggle.java b/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiToggle.java index d7bf047296..3a3b19a234 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiToggle.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiToggle.java @@ -10,7 +10,8 @@ import androidx.appcompat.widget.AppCompatImageButton; import org.signal.core.util.ContextUtil; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.keyboard.KeyboardPage; -import org.thoughtcrime.securesms.util.TextSecurePreferences; +import org.thoughtcrime.securesms.keyvalue.SettingsValues; +import org.thoughtcrime.securesms.keyvalue.SignalStore; public class EmojiToggle extends AppCompatImageButton implements MediaKeyboard.MediaKeyboardListener { @@ -94,13 +95,13 @@ public class EmojiToggle extends AppCompatImageButton implements MediaKeyboard.M setStickerMode(page); switch (page) { case EMOJI: - TextSecurePreferences.setMediaKeyboardMode(getContext(), TextSecurePreferences.MediaKeyboardMode.EMOJI); + SignalStore.settings().setMediaKeyboardMode(SettingsValues.MediaKeyboardMode.EMOJI); break; case STICKER: - TextSecurePreferences.setMediaKeyboardMode(getContext(), TextSecurePreferences.MediaKeyboardMode.STICKER); + SignalStore.settings().setMediaKeyboardMode(SettingsValues.MediaKeyboardMode.STICKER); break; case GIF: - TextSecurePreferences.setMediaKeyboardMode(getContext(), TextSecurePreferences.MediaKeyboardMode.GIF); + SignalStore.settings().setMediaKeyboardMode(SettingsValues.MediaKeyboardMode.GIF); break; } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/backups/local/LocalBackupsSettingsCallback.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/backups/local/LocalBackupsSettingsCallback.kt index c32a266590..872cc9bedd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/backups/local/LocalBackupsSettingsCallback.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/backups/local/LocalBackupsSettingsCallback.kt @@ -21,7 +21,6 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.service.LocalBackupListener import org.thoughtcrime.securesms.util.BackupUtil import org.thoughtcrime.securesms.util.CommunicationActions -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.navigation.safeNavigate sealed interface LocalBackupsSettingsCallback { @@ -87,7 +86,7 @@ class DefaultLocalBackupsSettingsCallback( picker.addOnPositiveButtonClickListener { SignalStore.settings.setBackupSchedule(picker.hour, picker.minute) - TextSecurePreferences.setNextBackupTime(fragment.requireContext(), 0) + SignalStore.settings.localBackupNextTime = 0 LocalBackupListener.schedule(fragment.requireContext()) viewModel.refreshSettingsState() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/ChatsSettingsRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/ChatsSettingsRepository.kt index abb424721e..522e40f5e0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/ChatsSettingsRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/ChatsSettingsRepository.kt @@ -1,6 +1,5 @@ package org.thoughtcrime.securesms.components.settings.app.chats -import android.content.Context import org.signal.core.util.concurrent.SignalExecutors import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.dependencies.AppDependencies @@ -9,12 +8,9 @@ import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.storage.StorageSyncHelper -import org.thoughtcrime.securesms.util.TextSecurePreferences class ChatsSettingsRepository { - private val context: Context = AppDependencies.application - fun syncLinkPreviewsState() { SignalExecutors.BOUNDED.execute { val isLinkPreviewsEnabled = SignalStore.settings.isLinkPreviewsEnabled @@ -23,9 +19,9 @@ class ChatsSettingsRepository { StorageSyncHelper.scheduleSyncForDataChange() AppDependencies.jobManager.add( MultiDeviceConfigurationUpdateJob( - TextSecurePreferences.isReadReceiptsEnabled(context), - TextSecurePreferences.isTypingIndicatorsEnabled(context), - TextSecurePreferences.isShowUnidentifiedDeliveryIndicatorsEnabled(context), + SignalStore.settings.isReadReceiptsEnabled, + SignalStore.settings.isTypingIndicatorsEnabled, + SignalStore.settings.isShowUnidentifiedDeliveryIndicatorsEnabled, isLinkPreviewsEnabled ) ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/data/DataAndStorageSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/data/DataAndStorageSettingsFragment.kt index 96517bf068..b3efb6d4d9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/data/DataAndStorageSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/data/DataAndStorageSettingsFragment.kt @@ -14,7 +14,6 @@ import androidx.compose.ui.res.stringResource import androidx.fragment.app.viewModels import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.fragment.findNavController -import androidx.preference.PreferenceManager import org.signal.core.ui.compose.ComposeFragment import org.signal.core.ui.compose.DayNightPreviews import org.signal.core.ui.compose.Dialogs @@ -36,9 +35,8 @@ class DataAndStorageSettingsFragment : ComposeFragment() { private val viewModel: DataAndStorageSettingsViewModel by viewModels( factoryProducer = { - val preferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) val repository = DataAndStorageSettingsRepository() - DataAndStorageSettingsViewModel.Factory(preferences, repository) + DataAndStorageSettingsViewModel.Factory(repository) } ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/data/DataAndStorageSettingsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/data/DataAndStorageSettingsViewModel.kt index 51bec86711..b8e587f2f8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/data/DataAndStorageSettingsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/data/DataAndStorageSettingsViewModel.kt @@ -1,6 +1,5 @@ package org.thoughtcrime.securesms.components.settings.app.data -import android.content.SharedPreferences import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import kotlinx.coroutines.flow.MutableStateFlow @@ -12,11 +11,9 @@ import org.thoughtcrime.securesms.dependencies.AppDependencies import org.thoughtcrime.securesms.keyvalue.SettingsValues.ForceWebsocketMode import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.messages.IncomingMessageObserver -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.webrtc.CallDataMode class DataAndStorageSettingsViewModel( - private val sharedPreferences: SharedPreferences, private val repository: DataAndStorageSettingsRepository ) : ViewModel() { @@ -31,17 +28,17 @@ class DataAndStorageSettingsViewModel( } fun setMobileAutoDownloadValues(resultSet: Set) { - sharedPreferences.edit().putStringSet(TextSecurePreferences.MEDIA_DOWNLOAD_MOBILE_PREF, resultSet).apply() + SignalStore.settings.mobileMediaDownloadAllowed = resultSet getStateAndCopyStorageUsage() } fun setWifiAutoDownloadValues(resultSet: Set) { - sharedPreferences.edit().putStringSet(TextSecurePreferences.MEDIA_DOWNLOAD_WIFI_PREF, resultSet).apply() + SignalStore.settings.wifiMediaDownloadAllowed = resultSet getStateAndCopyStorageUsage() } fun setRoamingAutoDownloadValues(resultSet: Set) { - sharedPreferences.edit().putStringSet(TextSecurePreferences.MEDIA_DOWNLOAD_ROAMING_PREF, resultSet).apply() + SignalStore.settings.roamingMediaDownloadAllowed = resultSet getStateAndCopyStorageUsage() } @@ -88,15 +85,9 @@ class DataAndStorageSettingsViewModel( private fun getState() = DataAndStorageSettingsState( totalStorageUse = 0, - mobileAutoDownloadValues = TextSecurePreferences.getMobileMediaDownloadAllowed( - AppDependencies.application - ), - wifiAutoDownloadValues = TextSecurePreferences.getWifiMediaDownloadAllowed( - AppDependencies.application - ), - roamingAutoDownloadValues = TextSecurePreferences.getRoamingMediaDownloadAllowed( - AppDependencies.application - ), + mobileAutoDownloadValues = SignalStore.settings.mobileMediaDownloadAllowed, + wifiAutoDownloadValues = SignalStore.settings.wifiMediaDownloadAllowed, + roamingAutoDownloadValues = SignalStore.settings.roamingMediaDownloadAllowed, callDataMode = SignalStore.settings.callDataMode, isProxyEnabled = SignalStore.proxy.isProxyEnabled, sentMediaQuality = SignalStore.settings.sentMediaQuality, @@ -106,12 +97,10 @@ class DataAndStorageSettingsViewModel( ) class Factory( - private val sharedPreferences: SharedPreferences, private val repository: DataAndStorageSettingsRepository - ) : - ViewModelProvider.Factory { + ) : ViewModelProvider.Factory { override fun create(modelClass: Class): T { - return requireNotNull(modelClass.cast(DataAndStorageSettingsViewModel(sharedPreferences, repository))) + return requireNotNull(modelClass.cast(DataAndStorageSettingsViewModel(repository))) } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt index bcf919ae8f..e9e1afd83a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt @@ -80,7 +80,6 @@ import org.thoughtcrime.securesms.registration.data.QuickstartCredentialExporter import org.thoughtcrime.securesms.ringrtc.CameraFpsRanges import org.thoughtcrime.securesms.storage.StorageSyncHelper import org.thoughtcrime.securesms.util.ConversationUtil -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter import org.thoughtcrime.securesms.util.navigation.safeNavigate import org.thoughtcrime.securesms.util.setIncognitoKeyboardEnabled @@ -180,7 +179,7 @@ class InternalSettingsFragment : DSLSettingsFragment(R.string.preferences__inter searchMenuItem?.setOnActionExpandListener(object : MenuItem.OnActionExpandListener { override fun onMenuItemActionExpand(item: MenuItem): Boolean { - searchView.setIncognitoKeyboardEnabled(TextSecurePreferences.isIncognitoKeyboardEnabled(requireContext())) + searchView.setIncognitoKeyboardEnabled(SignalStore.settings.isIncognitoKeyboardEnabled) searchView.setOnQueryTextListener(queryListener) return true } @@ -1145,7 +1144,7 @@ class InternalSettingsFragment : DSLSettingsFragment(R.string.preferences__inter .setMessage("Are you sure? You'll have to re-register to use Signal again -- no promises that the process will go smoothly.") .setPositiveButton(android.R.string.ok) { _, _ -> lifecycleScope.launch { - when (AdvancedPrivacySettingsRepository(requireContext()).disablePushMessages()) { + when (AdvancedPrivacySettingsRepository().disablePushMessages()) { AdvancedPrivacySettingsRepository.DisablePushMessagesResult.SUCCESS -> { SignalStore.account.setRegistered(false) SignalStore.registration.clearRegistrationComplete() diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/NotificationsSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/NotificationsSettingsFragment.kt index 9b428e0200..1bcfcff74a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/NotificationsSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/NotificationsSettingsFragment.kt @@ -38,7 +38,6 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import androidx.navigation.fragment.findNavController -import androidx.preference.PreferenceManager import kotlinx.coroutines.launch import org.signal.core.ui.BottomSheetUtil import org.signal.core.ui.compose.ComposeFragment @@ -65,9 +64,7 @@ import org.thoughtcrime.securesms.util.viewModel class NotificationsSettingsFragment : ComposeFragment() { private val viewModel: NotificationsSettingsViewModel by viewModel { - val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) - - NotificationsSettingsViewModel.Factory(sharedPreferences).create(NotificationsSettingsViewModel::class.java) + NotificationsSettingsViewModel.Factory().create(NotificationsSettingsViewModel::class.java) } private val appSettingsRouter: AppSettingsRouter by viewModel { diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/NotificationsSettingsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/NotificationsSettingsViewModel.kt index 052aab4fde..3aeae751b2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/NotificationsSettingsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/NotificationsSettingsViewModel.kt @@ -1,8 +1,8 @@ package org.thoughtcrime.securesms.components.settings.app.notifications -import android.content.SharedPreferences import android.net.Uri import android.os.Build +import android.provider.Settings import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.viewModelScope @@ -14,7 +14,6 @@ import kotlinx.coroutines.launch import org.signal.core.util.concurrent.SignalDispatchers import org.signal.core.util.logging.Log import org.thoughtcrime.securesms.database.SignalDatabase -import org.thoughtcrime.securesms.dependencies.AppDependencies import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.notifications.DeviceSpecificNotificationConfig import org.thoughtcrime.securesms.notifications.NotificationChannels @@ -23,9 +22,8 @@ import org.thoughtcrime.securesms.preferences.widgets.NotificationPrivacyPrefere import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.RecipientForeverObserver import org.thoughtcrime.securesms.storage.StorageSyncHelper -import org.thoughtcrime.securesms.util.TextSecurePreferences -class NotificationsSettingsViewModel(private val sharedPreferences: SharedPreferences) : ViewModel(), RecipientForeverObserver { +class NotificationsSettingsViewModel : ViewModel(), RecipientForeverObserver { companion object { private val TAG = Log.tag(NotificationsSettingsViewModel::class) @@ -109,7 +107,7 @@ class NotificationsSettingsViewModel(private val sharedPreferences: SharedPrefer } fun setMessageNotificationPriority(priority: Int) { - sharedPreferences.edit().putString(TextSecurePreferences.NOTIFICATION_PRIORITY_PREF, priority.toString()).apply() + SignalStore.settings.messageNotificationPriority = priority refresh() } @@ -149,7 +147,7 @@ class NotificationsSettingsViewModel(private val sharedPreferences: SharedPrefer fun resetSettings() { Log.i(TAG, "Resetting all notifications.") // Global - setMessageNotificationsSound(TextSecurePreferences.getNotificationRingtone(AppDependencies.application)) + setMessageNotificationsSound(Settings.System.DEFAULT_NOTIFICATION_URI) SignalStore.settings.isMessageNotificationsInChatSoundsEnabled = true SignalStore.settings.messageNotificationsPrivacy = NotificationPrivacyPreference("all") SignalStore.settings.allowCallsWhileMuted = false @@ -192,7 +190,7 @@ class NotificationsSettingsViewModel(private val sharedPreferences: SharedPrefer inChatSoundsEnabled = SignalStore.settings.isMessageNotificationsInChatSoundsEnabled, repeatAlerts = SignalStore.settings.messageNotificationsRepeatAlerts, messagePrivacy = SignalStore.settings.messageNotificationsPrivacy.toString(), - priority = TextSecurePreferences.getNotificationPriority(AppDependencies.application), + priority = SignalStore.settings.messageNotificationPriority, troubleshootNotifications = if (calculateSlowNotifications) { (SlowNotificationHeuristics.isBatteryOptimizationsOn() && SlowNotificationHeuristics.isHavingDelayedNotifications()) || SlowNotificationHeuristics.getDeviceSpecificShowCondition() == DeviceSpecificNotificationConfig.ShowCondition.ALWAYS @@ -227,9 +225,9 @@ class NotificationsSettingsViewModel(private val sharedPreferences: SharedPrefer return !areNotificationsDisabledBySystem } - class Factory(private val sharedPreferences: SharedPreferences) : ViewModelProvider.Factory { + class Factory : ViewModelProvider.Factory { override fun create(modelClass: Class): T { - return requireNotNull(modelClass.cast(NotificationsSettingsViewModel(sharedPreferences))) + return requireNotNull(modelClass.cast(NotificationsSettingsViewModel())) } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/PrivacySettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/PrivacySettingsFragment.kt index 96583c0955..f6caaca082 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/PrivacySettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/PrivacySettingsFragment.kt @@ -19,7 +19,6 @@ import androidx.lifecycle.ViewModelProvider import androidx.navigation.Navigation import androidx.navigation.fragment.NavHostFragment import androidx.navigation.fragment.navArgs -import androidx.preference.PreferenceManager import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar import org.signal.core.util.ServiceUtil @@ -43,7 +42,6 @@ import org.thoughtcrime.securesms.service.KeyCachingService import org.thoughtcrime.securesms.util.CommunicationActions import org.thoughtcrime.securesms.util.ExpirationUtil import org.thoughtcrime.securesms.util.SpanUtil -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.adapter.mapping.LayoutFactory import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter import org.thoughtcrime.securesms.util.navigation.safeNavigate @@ -101,9 +99,8 @@ class PrivacySettingsFragment : DSLSettingsFragment(R.string.preferences__privac override fun bindAdapter(adapter: MappingAdapter) { adapter.registerFactory(ValueClickPreference::class.java, LayoutFactory(::ValueClickPreferenceViewHolder, R.layout.value_click_preference_item)) - val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) val repository = PrivacySettingsRepository() - val factory = PrivacySettingsViewModel.Factory(sharedPreferences, repository) + val factory = PrivacySettingsViewModel.Factory(repository) viewModel = ViewModelProvider(this, factory)[PrivacySettingsViewModel::class.java] val args: PrivacySettingsFragmentArgs by navArgs() var showPaymentLock = true @@ -279,7 +276,7 @@ class PrivacySettingsFragment : DSLSettingsFragment(R.string.preferences__privac onClick = { viewModel.setScreenSecurityEnabled(!state.screenSecurity) - if (TextSecurePreferences.isScreenSecurityEnabled(requireContext())) { + if (SignalStore.settings.isScreenSecurityEnabled) { requireActivity().window.addFlags(WindowManager.LayoutParams.FLAG_SECURE) } else { requireActivity().window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/PrivacySettingsRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/PrivacySettingsRepository.kt index 75e777a0a6..002ed32741 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/PrivacySettingsRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/PrivacySettingsRepository.kt @@ -1,6 +1,5 @@ package org.thoughtcrime.securesms.components.settings.app.privacy -import android.content.Context import org.signal.core.util.concurrent.SignalExecutors import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.dependencies.AppDependencies @@ -8,12 +7,9 @@ import org.thoughtcrime.securesms.jobs.MultiDeviceConfigurationUpdateJob import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.storage.StorageSyncHelper -import org.thoughtcrime.securesms.util.TextSecurePreferences class PrivacySettingsRepository { - private val context: Context = AppDependencies.application - fun getBlockedCount(consumer: (Int) -> Unit) { SignalExecutors.BOUNDED.execute { val recipientDatabase = SignalDatabase.recipients @@ -28,9 +24,9 @@ class PrivacySettingsRepository { StorageSyncHelper.scheduleSyncForDataChange() AppDependencies.jobManager.add( MultiDeviceConfigurationUpdateJob( - TextSecurePreferences.isReadReceiptsEnabled(context), - TextSecurePreferences.isTypingIndicatorsEnabled(context), - TextSecurePreferences.isShowUnidentifiedDeliveryIndicatorsEnabled(context), + SignalStore.settings.isReadReceiptsEnabled, + SignalStore.settings.isTypingIndicatorsEnabled, + SignalStore.settings.isShowUnidentifiedDeliveryIndicatorsEnabled, SignalStore.settings.isLinkPreviewsEnabled ) ) @@ -38,15 +34,15 @@ class PrivacySettingsRepository { } fun syncTypingIndicatorsState() { - val enabled = TextSecurePreferences.isTypingIndicatorsEnabled(context) + val enabled = SignalStore.settings.isTypingIndicatorsEnabled SignalDatabase.recipients.markNeedsSync(Recipient.self().id) StorageSyncHelper.scheduleSyncForDataChange() AppDependencies.jobManager.add( MultiDeviceConfigurationUpdateJob( - TextSecurePreferences.isReadReceiptsEnabled(context), + SignalStore.settings.isReadReceiptsEnabled, enabled, - TextSecurePreferences.isShowUnidentifiedDeliveryIndicatorsEnabled(context), + SignalStore.settings.isShowUnidentifiedDeliveryIndicatorsEnabled, SignalStore.settings.isLinkPreviewsEnabled ) ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/PrivacySettingsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/PrivacySettingsViewModel.kt index 93fad6296a..c06e74c3ca 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/PrivacySettingsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/PrivacySettingsViewModel.kt @@ -1,16 +1,12 @@ package org.thoughtcrime.securesms.components.settings.app.privacy -import android.content.SharedPreferences import androidx.lifecycle.LiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider -import org.thoughtcrime.securesms.dependencies.AppDependencies import org.thoughtcrime.securesms.keyvalue.SignalStore -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.livedata.Store class PrivacySettingsViewModel( - private val sharedPreferences: SharedPreferences, private val repository: PrivacySettingsRepository ) : ViewModel() { @@ -26,24 +22,24 @@ class PrivacySettingsViewModel( } fun setReadReceiptsEnabled(enabled: Boolean) { - sharedPreferences.edit().putBoolean(TextSecurePreferences.READ_RECEIPTS_PREF, enabled).apply() + SignalStore.settings.isReadReceiptsEnabled = enabled repository.syncReadReceiptState() refresh() } fun setTypingIndicatorsEnabled(enabled: Boolean) { - sharedPreferences.edit().putBoolean(TextSecurePreferences.TYPING_INDICATORS, enabled).apply() + SignalStore.settings.isTypingIndicatorsEnabled = enabled repository.syncTypingIndicatorsState() refresh() } fun setScreenSecurityEnabled(enabled: Boolean) { - sharedPreferences.edit().putBoolean(TextSecurePreferences.SCREEN_SECURITY_PREF, enabled).apply() + SignalStore.settings.isScreenSecurityEnabled = enabled refresh() } fun setIncognitoKeyboard(enabled: Boolean) { - sharedPreferences.edit().putBoolean(TextSecurePreferences.INCOGNITO_KEYBOARD_PREF, enabled).apply() + SignalStore.settings.isIncognitoKeyboardEnabled = enabled refresh() } @@ -70,12 +66,12 @@ class PrivacySettingsViewModel( return PrivacySettingsState( hasPhoneNumber = !SignalStore.account.isPhoneNumberless, blockedCount = 0, - readReceipts = TextSecurePreferences.isReadReceiptsEnabled(AppDependencies.application), - typingIndicators = TextSecurePreferences.isTypingIndicatorsEnabled(AppDependencies.application), + readReceipts = SignalStore.settings.isReadReceiptsEnabled, + typingIndicators = SignalStore.settings.isTypingIndicatorsEnabled, screenLock = SignalStore.settings.screenLockEnabled, screenLockActivityTimeout = SignalStore.settings.screenLockTimeout, - screenSecurity = TextSecurePreferences.isScreenSecurityEnabled(AppDependencies.application), - incognitoKeyboard = TextSecurePreferences.isIncognitoKeyboardEnabled(AppDependencies.application), + screenSecurity = SignalStore.settings.isScreenSecurityEnabled, + incognitoKeyboard = SignalStore.settings.isIncognitoKeyboardEnabled, paymentLock = SignalStore.payments.paymentLock, isObsoletePasswordEnabled = !SignalStore.settings.passphraseDisabled, isObsoletePasswordTimeoutEnabled = SignalStore.settings.passphraseTimeoutEnabled, @@ -89,11 +85,10 @@ class PrivacySettingsViewModel( } class Factory( - private val sharedPreferences: SharedPreferences, private val repository: PrivacySettingsRepository ) : ViewModelProvider.Factory { override fun create(modelClass: Class): T { - return requireNotNull(modelClass.cast(PrivacySettingsViewModel(sharedPreferences, repository))) + return requireNotNull(modelClass.cast(PrivacySettingsViewModel(repository))) } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/advanced/AdvancedPrivacySettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/advanced/AdvancedPrivacySettingsFragment.kt index fcd6f394df..39324eb293 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/advanced/AdvancedPrivacySettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/advanced/AdvancedPrivacySettingsFragment.kt @@ -32,7 +32,6 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle -import androidx.preference.PreferenceManager import kotlinx.coroutines.launch import org.signal.core.ui.compose.ComposeFragment import org.signal.core.ui.compose.DayNightPreviews @@ -53,13 +52,7 @@ import org.thoughtcrime.securesms.util.viewModel class AdvancedPrivacySettingsFragment : ComposeFragment() { private val viewModel: AdvancedPrivacySettingsViewModel by viewModel { - val repository = AdvancedPrivacySettingsRepository(requireContext()) - val preferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) - - AdvancedPrivacySettingsViewModel( - preferences, - repository - ) + AdvancedPrivacySettingsViewModel(AdvancedPrivacySettingsRepository()) } private var networkReceiver: NetworkReceiver? = null diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/advanced/AdvancedPrivacySettingsRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/advanced/AdvancedPrivacySettingsRepository.kt index d497ace556..e7e2f5b9ef 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/advanced/AdvancedPrivacySettingsRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/advanced/AdvancedPrivacySettingsRepository.kt @@ -1,6 +1,5 @@ package org.thoughtcrime.securesms.components.settings.app.privacy.advanced -import android.content.Context import com.google.android.gms.tasks.Tasks import com.google.firebase.installations.FirebaseInstallations import kotlinx.coroutines.Dispatchers @@ -16,13 +15,12 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.net.SignalNetwork import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.storage.StorageSyncHelper -import org.thoughtcrime.securesms.util.TextSecurePreferences import java.io.IOException import java.util.concurrent.ExecutionException private val TAG = Log.tag(AdvancedPrivacySettingsRepository::class.java) -class AdvancedPrivacySettingsRepository(private val context: Context) { +class AdvancedPrivacySettingsRepository { suspend fun disablePushMessages(): DisablePushMessagesResult = withContext(Dispatchers.IO) { val clearTokenError: Throwable? = when (val result = SignalNetwork.accountApi.clearFcmToken()) { @@ -61,9 +59,9 @@ class AdvancedPrivacySettingsRepository(private val context: Context) { StorageSyncHelper.scheduleSyncForDataChange() AppDependencies.jobManager.add( MultiDeviceConfigurationUpdateJob( - TextSecurePreferences.isReadReceiptsEnabled(context), - TextSecurePreferences.isTypingIndicatorsEnabled(context), - TextSecurePreferences.isShowUnidentifiedDeliveryIndicatorsEnabled(context), + SignalStore.settings.isReadReceiptsEnabled, + SignalStore.settings.isTypingIndicatorsEnabled, + SignalStore.settings.isShowUnidentifiedDeliveryIndicatorsEnabled, SignalStore.settings.isLinkPreviewsEnabled ) ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/advanced/AdvancedPrivacySettingsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/advanced/AdvancedPrivacySettingsViewModel.kt index 224d2d588b..efaffb56c4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/advanced/AdvancedPrivacySettingsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/advanced/AdvancedPrivacySettingsViewModel.kt @@ -1,6 +1,5 @@ package org.thoughtcrime.securesms.components.settings.app.privacy.advanced -import android.content.SharedPreferences import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers @@ -22,11 +21,9 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.storage.StorageSyncHelper import org.thoughtcrime.securesms.util.SignalE164Util -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.signalservice.api.websocket.WebSocketConnectionState class AdvancedPrivacySettingsViewModel( - private val sharedPreferences: SharedPreferences, private val repository: AdvancedPrivacySettingsRepository ) : ViewModel() { @@ -46,18 +43,18 @@ class AdvancedPrivacySettingsViewModel( } fun setAlwaysRelayCalls(enabled: Boolean) { - sharedPreferences.edit().putBoolean(TextSecurePreferences.ALWAYS_RELAY_CALLS_PREF, enabled).apply() + SignalStore.settings.isTurnOnly = enabled refresh() } fun setShowStatusIconForSealedSender(enabled: Boolean) { - sharedPreferences.edit().putBoolean(TextSecurePreferences.SHOW_UNIDENTIFIED_DELIVERY_INDICATORS, enabled).apply() + SignalStore.settings.isShowUnidentifiedDeliveryIndicatorsEnabled = enabled repository.syncShowSealedSenderIconState() refresh() } fun setAllowSealedSenderFromAnyone(enabled: Boolean) { - sharedPreferences.edit().putBoolean(TextSecurePreferences.UNIVERSAL_UNIDENTIFIED_ACCESS, enabled).apply() + SignalStore.settings.isUniversalUnidentifiedAccess = enabled AppDependencies.jobManager.startChain(RefreshAttributesJob()).then(RefreshOwnProfileJob()).enqueue() refresh() } @@ -97,15 +94,11 @@ class AdvancedPrivacySettingsViewModel( return AdvancedPrivacySettingsState( isPushEnabled = SignalStore.account.isRegistered, - alwaysRelayCalls = TextSecurePreferences.isTurnOnly(AppDependencies.application), + alwaysRelayCalls = SignalStore.settings.isTurnOnly, censorshipCircumventionState = censorshipCircumventionState, censorshipCircumventionEnabled = getCensorshipCircumventionEnabled(censorshipCircumventionState), - showSealedSenderStatusIcon = TextSecurePreferences.isShowUnidentifiedDeliveryIndicatorsEnabled( - AppDependencies.application - ), - allowSealedSenderFromAnyone = TextSecurePreferences.isUniversalUnidentifiedAccess( - AppDependencies.application - ), + showSealedSenderStatusIcon = SignalStore.settings.isShowUnidentifiedDeliveryIndicatorsEnabled, + allowSealedSenderFromAnyone = SignalStore.settings.isUniversalUnidentifiedAccess, showProgressSpinner = false, allowAutomaticKeyVerification = SignalStore.settings.automaticVerificationEnabled, isPrimaryDevice = SignalStore.account.isPrimaryDevice diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/v2/WebRtcCallActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/v2/WebRtcCallActivity.kt index 3dd7490e56..149b4d1556 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/v2/WebRtcCallActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/v2/WebRtcCallActivity.kt @@ -86,7 +86,6 @@ import org.thoughtcrime.securesms.service.webrtc.SignalCallManager import org.thoughtcrime.securesms.sms.MessageSender import org.thoughtcrime.securesms.util.FullscreenHelper import org.thoughtcrime.securesms.util.RemoteConfig -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.VibrateUtil import org.thoughtcrime.securesms.webrtc.CallParticipantsViewState import org.thoughtcrime.securesms.webrtc.audio.SignalAudioManager @@ -1156,7 +1155,7 @@ class WebRtcCallActivity : BaseActivity(), SafetyNumberChangeDialog.Callback, Re } private fun initializeScreenshotSecurity() { - if (TextSecurePreferences.isScreenSecurityEnabled(this)) { + if (SignalStore.settings.isScreenSecurityEnabled) { window.addFlags(WindowManager.LayoutParams.FLAG_SECURE) } else { window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt index d208541f3a..d4f124eea7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt @@ -310,6 +310,7 @@ import org.thoughtcrime.securesms.jobs.ServiceOutageDetectionJob import org.thoughtcrime.securesms.keyboard.KeyboardPage import org.thoughtcrime.securesms.keyboard.KeyboardUtil import org.thoughtcrime.securesms.keyboard.sticker.StickerSearchDialogFragment +import org.thoughtcrime.securesms.keyvalue.SettingsValues.MediaKeyboardMode import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.linkpreview.LinkPreview import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModelV2 @@ -2780,10 +2781,10 @@ class ConversationFragment : /** Which keyboard the toggle should offer, from the mode remembered across runs. */ private fun preferredKeyboardPage(): KeyboardPage { - return when (TextSecurePreferences.getMediaKeyboardMode(requireContext())) { - TextSecurePreferences.MediaKeyboardMode.EMOJI -> KeyboardPage.EMOJI - TextSecurePreferences.MediaKeyboardMode.STICKER -> KeyboardPage.STICKER - TextSecurePreferences.MediaKeyboardMode.GIF -> if (RemoteConfig.gifSearchAvailable) KeyboardPage.GIF else KeyboardPage.STICKER + return when (SignalStore.settings.mediaKeyboardMode) { + MediaKeyboardMode.EMOJI -> KeyboardPage.EMOJI + MediaKeyboardMode.STICKER -> KeyboardPage.STICKER + MediaKeyboardMode.GIF -> if (RemoteConfig.gifSearchAvailable) KeyboardPage.GIF else KeyboardPage.STICKER } } @@ -2794,7 +2795,7 @@ class ConversationFragment : inputPanel.setMediaKeyboardToggleMode(preferredKeyboardPage()) if (stickerIntro) { - TextSecurePreferences.setMediaKeyboardMode(requireContext(), TextSecurePreferences.MediaKeyboardMode.STICKER) + SignalStore.settings.mediaKeyboardMode = MediaKeyboardMode.STICKER inputPanel.setMediaKeyboardToggleMode(KeyboardPage.STICKER) conversationTooltips.displayStickerIntroductionTooltip(inputPanel.mediaKeyboardToggleAnchorView) { EventBus.getDefault().removeStickyEvent(StickerPackInstallEvent::class.java) @@ -4747,7 +4748,7 @@ class ConversationFragment : searchMenuItem!!.setOnActionExpandListener(object : MenuItem.OnActionExpandListener { override fun onMenuItemActionExpand(item: MenuItem): Boolean { - searchView.setIncognitoKeyboardEnabled(TextSecurePreferences.isIncognitoKeyboardEnabled(requireContext())) + searchView.setIncognitoKeyboardEnabled(SignalStore.settings.isIncognitoKeyboardEnabled) searchView.setOnQueryTextListener(queryListener) isSearchRequested = true searchViewModel.onSearchOpened() diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.kt index 4459658c76..1608d8733a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.kt @@ -150,7 +150,6 @@ import org.thoughtcrime.securesms.util.MediaUtil import org.thoughtcrime.securesms.util.MessageConstraintsUtil import org.thoughtcrime.securesms.util.RemoteConfig import org.thoughtcrime.securesms.util.SignalTrace -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.isStory import org.whispersystems.signalservice.internal.push.SyncMessage import java.io.Closeable @@ -7152,7 +7151,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat val messageExtraBytes = cursor.requireBlob(MESSAGE_EXTRAS) val messageExtras = messageExtraBytes?.let { MessageExtras.ADAPTER.decode(it) } - if (!TextSecurePreferences.isReadReceiptsEnabled(context)) { + if (!SignalStore.settings.isReadReceiptsEnabled) { hasReadReceipt = false if (MessageTypes.isOutgoingMessageType(box) && !storyType.isStory) { isViewed = false diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadTable.kt index 5c8f28b621..01ee31b24a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadTable.kt @@ -77,7 +77,6 @@ import org.thoughtcrime.securesms.recipients.RecipientUtil import org.thoughtcrime.securesms.storage.StorageSyncHelper import org.thoughtcrime.securesms.util.ConversationUtil import org.thoughtcrime.securesms.util.SignalTrace -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.isPoll import org.thoughtcrime.securesms.util.isScheduled import org.whispersystems.signalservice.api.storage.SignalAccountRecord @@ -2462,7 +2461,7 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa RecipientCreator.forIndividual(context, recipientSettings) } - val hasReadReceipt = TextSecurePreferences.isReadReceiptsEnabled(context) && cursor.requireBoolean(HAS_READ_RECEIPT) + val hasReadReceipt = SignalStore.settings.isReadReceiptsEnabled && cursor.requireBoolean(HAS_READ_RECEIPT) val extraString = cursor.getString(cursor.getColumnIndexOrThrow(SNIPPET_EXTRAS)) val messageExtraBytes = cursor.getBlob(cursor.getColumnIndexOrThrow(SNIPPET_MESSAGE_EXTRAS)) val messageExtras = if (messageExtraBytes != null) MessageExtras.ADAPTER.decode(messageExtraBytes) else null diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/CoreUiDependenciesProvider.kt b/app/src/main/java/org/thoughtcrime/securesms/dependencies/CoreUiDependenciesProvider.kt index 0a171491c5..bbad1fef48 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/CoreUiDependenciesProvider.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/CoreUiDependenciesProvider.kt @@ -7,7 +7,7 @@ package org.thoughtcrime.securesms.dependencies import org.signal.core.ui.CoreUiDependencies import org.thoughtcrime.securesms.BuildConfig -import org.thoughtcrime.securesms.util.TextSecurePreferences +import org.thoughtcrime.securesms.keyvalue.SignalStore object CoreUiDependenciesProvider : CoreUiDependencies.Provider { override fun providePackageId(): String { @@ -15,10 +15,10 @@ object CoreUiDependenciesProvider : CoreUiDependencies.Provider { } override fun provideIsIncognitoKeyboardEnabled(): Boolean { - return TextSecurePreferences.isIncognitoKeyboardEnabled(AppDependencies.application) + return SignalStore.settings.isIncognitoKeyboardEnabled } override fun provideIsScreenSecurityEnabled(): Boolean { - return TextSecurePreferences.isScreenSecurityEnabled(AppDependencies.application) + return SignalStore.settings.isScreenSecurityEnabled } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/v2/processing/GroupsV2StateProcessor.kt b/app/src/main/java/org/thoughtcrime/securesms/groups/v2/processing/GroupsV2StateProcessor.kt index cd01f5aa6d..da0ece5251 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/v2/processing/GroupsV2StateProcessor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/v2/processing/GroupsV2StateProcessor.kt @@ -45,7 +45,6 @@ import org.thoughtcrime.securesms.mms.OutgoingMessage import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.storage.StorageSyncHelper -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil import org.whispersystems.signalservice.api.groupsv2.GroupChangeReconstruct import org.whispersystems.signalservice.api.groupsv2.GroupHistoryPage @@ -947,7 +946,7 @@ class GroupsV2StateProcessor private constructor( } fun stopAllTypingForGroup() { - if (TextSecurePreferences.isTypingIndicatorsEnabled(AppDependencies.application)) { + if (SignalStore.settings.isTypingIndicatorsEnabled) { val threadId = SignalDatabase.threads.getThreadIdFor(SignalDatabase.recipients.getOrInsertFromGroupId(groupId)) if (threadId != null) { AppDependencies.typingStatusRepository.stopAllTypingForThread(threadId) diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/AutoDownloadEmojiConstraint.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/AutoDownloadEmojiConstraint.java index a86927598a..8adc62b3eb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/AutoDownloadEmojiConstraint.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/AutoDownloadEmojiConstraint.java @@ -7,8 +7,8 @@ import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; import org.thoughtcrime.securesms.jobmanager.Constraint; +import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.util.NetworkUtil; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import java.util.Collections; import java.util.Set; @@ -41,8 +41,8 @@ public class AutoDownloadEmojiConstraint implements Constraint { @RequiresApi(26) @Override public void applyToJobInfo(@NonNull JobInfo.Builder jobInfoBuilder) { - boolean canDownloadWhileRoaming = TextSecurePreferences.getRoamingMediaDownloadAllowed(context).contains(IMAGE_TYPE); - boolean canDownloadWhileMobile = TextSecurePreferences.getMobileMediaDownloadAllowed(context).contains(IMAGE_TYPE); + boolean canDownloadWhileRoaming = SignalStore.settings().getRoamingMediaDownloadAllowed().contains(IMAGE_TYPE); + boolean canDownloadWhileMobile = SignalStore.settings().getMobileMediaDownloadAllowed().contains(IMAGE_TYPE); if (canDownloadWhileRoaming) { jobInfoBuilder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); @@ -62,9 +62,9 @@ public class AutoDownloadEmojiConstraint implements Constraint { } private static @NonNull Set getAllowedAutoDownloadTypes(@NonNull Context context, boolean forceWifi) { - if (NetworkUtil.isConnectedWifi(context)) return forceWifi ? Collections.singleton(IMAGE_TYPE) : TextSecurePreferences.getWifiMediaDownloadAllowed(context); - else if (NetworkUtil.isConnectedRoaming(context)) return TextSecurePreferences.getRoamingMediaDownloadAllowed(context); - else if (NetworkUtil.isConnectedMobile(context)) return TextSecurePreferences.getMobileMediaDownloadAllowed(context); + if (NetworkUtil.isConnectedWifi(context)) return forceWifi ? Collections.singleton(IMAGE_TYPE) : SignalStore.settings().getWifiMediaDownloadAllowed(); + else if (NetworkUtil.isConnectedRoaming(context)) return SignalStore.settings().getRoamingMediaDownloadAllowed(); + else if (NetworkUtil.isConnectedMobile(context)) return SignalStore.settings().getMobileMediaDownloadAllowed(); else return Collections.emptySet(); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshAttributesJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshAttributesJob.java index 21cc831899..5c197d3c21 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshAttributesJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshAttributesJob.java @@ -141,7 +141,7 @@ public class RefreshAttributesJob extends BaseJob { int registrationId = SignalStore.account().getRegistrationId(); boolean fetchesMessages = !SignalStore.account().isFcmEnabled() || SignalStore.settings().getForceWebsocketMode().isEnabled(); byte[] unidentifiedAccessKey = UnidentifiedAccess.deriveAccessKeyFrom(ProfileKeyUtil.getSelfProfileKey()); - boolean universalUnidentifiedAccess = TextSecurePreferences.isUniversalUnidentifiedAccess(context); + boolean universalUnidentifiedAccess = SignalStore.settings().isUniversalUnidentifiedAccess(); String registrationLockV2 = null; int pniRegistrationId = RegistrationRepository.getPniRegistrationId(); String recoveryPassword = svrValues.getMasterKey().deriveRegistrationRecoveryPassword(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshOwnProfileJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshOwnProfileJob.kt index 80a985ec0c..85c7bc36ba 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshOwnProfileJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshOwnProfileJob.kt @@ -29,7 +29,6 @@ import org.thoughtcrime.securesms.profiles.ProfileName import org.thoughtcrime.securesms.profiles.manage.UsernameRepository import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.util.ProfileUtil -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.signalservice.api.crypto.InvalidCiphertextException import org.whispersystems.signalservice.api.crypto.ProfileCipher import org.whispersystems.signalservice.api.profiles.ProfileAndCredential @@ -213,8 +212,8 @@ class RefreshOwnProfileJob private constructor(parameters: Parameters) : BaseJob return } - if (TextSecurePreferences.isUniversalUnidentifiedAccess(context) != universalUnidentifiedAccess) { - Log.w(TAG, "The universal access flag doesn't match our local value (local: " + TextSecurePreferences.isUniversalUnidentifiedAccess(context) + ", remote: " + universalUnidentifiedAccess + ")! Refreshing attributes.") + if (SignalStore.settings.isUniversalUnidentifiedAccess != universalUnidentifiedAccess) { + Log.w(TAG, "The universal access flag doesn't match our local value (local: " + SignalStore.settings.isUniversalUnidentifiedAccess + ", remote: " + universalUnidentifiedAccess + ")! Refreshing attributes.") AppDependencies.jobManager.add(RefreshAttributesJob()) return } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/SendReadReceiptJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/SendReadReceiptJob.java index f49e53e332..7f071ad903 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/SendReadReceiptJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/SendReadReceiptJob.java @@ -19,12 +19,12 @@ import org.thoughtcrime.securesms.jobmanager.JobManager; import org.thoughtcrime.securesms.jobmanager.JsonJobData; import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; import org.thoughtcrime.securesms.jobmanager.impl.SealedSenderConstraint; +import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.net.NotPushRegisteredException; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.recipients.RecipientUtil; import org.thoughtcrime.securesms.transport.UndeliverableMessageException; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.signal.core.util.Util; import org.whispersystems.signalservice.api.SignalServiceMessageSender; import org.whispersystems.signalservice.api.crypto.ContentHint; @@ -100,7 +100,7 @@ public class SendReadReceiptJob extends BaseJob { * maximum size. */ public static void enqueue(long threadId, @NonNull RecipientId recipientId, List markedMessageInfos) { - if (!TextSecurePreferences.isReadReceiptsEnabled(AppDependencies.getApplication())) { + if (!SignalStore.settings().isReadReceiptsEnabled()) { return; } @@ -151,7 +151,7 @@ public class SendReadReceiptJob extends BaseJob { throw new NotPushRegisteredException(); } - if (!TextSecurePreferences.isReadReceiptsEnabled(context) || messageSentTimestamps.isEmpty()) return; + if (!SignalStore.settings().isReadReceiptsEnabled() || messageSentTimestamps.isEmpty()) return; if (!RecipientUtil.isMessageRequestAccepted(threadId)) { Log.w(TAG, "Refusing to send receipts to untrusted recipient"); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/SendViewedReceiptJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/SendViewedReceiptJob.java index 49004b8035..d8fd23912f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/SendViewedReceiptJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/SendViewedReceiptJob.java @@ -26,7 +26,6 @@ import org.thoughtcrime.securesms.net.NotPushRegisteredException; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.recipients.RecipientUtil; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.signal.core.util.Util; import org.whispersystems.signalservice.api.SignalServiceMessageSender; import org.whispersystems.signalservice.api.crypto.ContentHint; @@ -139,7 +138,7 @@ public class SendViewedReceiptJob extends BaseJob { @Override public void onRun() throws IOException, UntrustedIdentityException { - boolean canSendNonStoryReceipts = TextSecurePreferences.isReadReceiptsEnabled(context); + boolean canSendNonStoryReceipts = SignalStore.settings().isReadReceiptsEnabled(); boolean canSendStoryReceipts = SignalStore.story().getViewedReceiptsEnabled(); List foundMessageIds = new LinkedList<>(); @@ -158,7 +157,7 @@ public class SendViewedReceiptJob extends BaseJob { throw new NotPushRegisteredException(); } - if (storyTypes.isEmpty() && !TextSecurePreferences.isReadReceiptsEnabled(context)) { + if (storyTypes.isEmpty() && !SignalStore.settings().isReadReceiptsEnabled()) { Log.w(TAG, "Read receipts not enabled!"); return; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/TypingSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/TypingSendJob.java index 67d7ea4989..b4459ff3c5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/TypingSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/TypingSendJob.java @@ -13,11 +13,11 @@ import org.thoughtcrime.securesms.jobmanager.JsonJobData; import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; import org.thoughtcrime.securesms.jobmanager.impl.SealedSenderConstraint; +import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.messages.GroupSendUtil; import org.thoughtcrime.securesms.net.NotPushRegisteredException; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientUtil; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.signalservice.api.messages.SignalServiceTypingMessage; import org.whispersystems.signalservice.api.messages.SignalServiceTypingMessage.Action; @@ -81,7 +81,7 @@ public class TypingSendJob extends BaseJob { throw new NotPushRegisteredException(); } - if (!TextSecurePreferences.isTypingIndicatorsEnabled(context)) { + if (!SignalStore.settings().isTypingIndicatorsEnabled()) { return; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/LegacySharedPrefs.kt b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/LegacySharedPrefs.kt new file mode 100644 index 0000000000..deb14ba485 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/LegacySharedPrefs.kt @@ -0,0 +1,68 @@ +/* + * Copyright 2026 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package org.thoughtcrime.securesms.keyvalue + +import android.content.Context +import android.net.Uri +import androidx.preference.PreferenceManager + +/** + * Read-only access to the app's default [android.content.SharedPreferences] for the purpose of easing migration to [SignalStore]. + */ +object LegacySharedPrefs { + + fun contains(context: Context, key: String): Boolean { + return prefs(context).contains(key) + } + + fun getBoolean(context: Context, key: String, defaultValue: Boolean): Boolean { + return prefs(context).getBoolean(key, defaultValue) + } + + fun getInteger(context: Context, key: String, defaultValue: Int): Int { + return prefs(context).getInt(key, defaultValue) + } + + fun getLong(context: Context, key: String, defaultValue: Long): Long { + return prefs(context).getLong(key, defaultValue) + } + + fun getString(context: Context, key: String, defaultValue: String): String { + return prefs(context).getString(key, defaultValue) ?: defaultValue + } + + /** Some values were stored as strings, but some installs ended up with ints. */ + fun getIntegerFromString(context: Context, key: String, defaultValue: Int): Int { + return try { + getString(context, key, defaultValue.toString()).toInt() + } catch (e: ClassCastException) { + getInteger(context, key, defaultValue) + } catch (e: NumberFormatException) { + defaultValue + } + } + + /** Mirrors the URI fixup the old ringtone getters did. */ + fun getRingtone(context: Context, key: String, defaultValue: Uri): String { + val result = getString(context, key, defaultValue.toString()) + + return if (result.startsWith("file:")) { + defaultValue.toString() + } else { + result + } + } + + fun getStringSet(context: Context, key: String, defaultValues: Set?): Set? { + return if (prefs(context).contains(key)) { + prefs(context).getStringSet(key, emptySet()) ?: emptySet() + } else { + defaultValues + } + } + + private fun prefs(context: Context) = PreferenceManager.getDefaultSharedPreferences(context) +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SettingsValues.kt b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SettingsValues.kt index c18fb1a306..c2071f1f82 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SettingsValues.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SettingsValues.kt @@ -3,22 +3,25 @@ package org.thoughtcrime.securesms.keyvalue import android.content.Context import android.net.Uri import android.provider.Settings +import androidx.annotation.ArrayRes +import androidx.core.app.NotificationCompat import androidx.lifecycle.LiveData +import org.signal.core.util.StringStringSerializer import org.signal.core.util.logging.Log import org.signal.mediasend.SentMediaQuality import org.thoughtcrime.securesms.R -import org.thoughtcrime.securesms.dependencies.AppDependencies +import org.thoughtcrime.securesms.database.model.databaseprotos.SignalStoreList import org.thoughtcrime.securesms.preferences.widgets.NotificationPrivacyPreference +import org.thoughtcrime.securesms.util.DynamicTheme import org.thoughtcrime.securesms.util.Environment import org.thoughtcrime.securesms.util.SingleLiveEvent -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.webrtc.CallDataMode import java.util.Arrays import java.util.Random import kotlin.math.abs @Suppress("DEPRECATION") -class SettingsValues internal constructor(store: KeyValueStore, context: Context) : SignalStoreValues(store) { +class SettingsValues internal constructor(store: KeyValueStore, private val context: Context) : SignalStoreValues(store) { companion object { private val TAG = Log.tag(SettingsValues::class.java) @@ -79,6 +82,21 @@ class SettingsValues internal constructor(store: KeyValueStore, context: Context private const val SCREEN_LOCK_TIMEOUT = "settings.screen.lock.timeout" private const val AUTOMATIC_VERIFICATION_ENABLED = "settings.automatic.verification.enabled" private const val FORCE_WEBSOCKET_MODE = "settings.force.websocket.mode.2" + private const val MESSAGE_LED_BLINK_PATTERN_CUSTOM = "settings.message.led.blink.custom" + private const val MESSAGE_NOTIFICATION_PRIORITY = "settings.message.notification.priority" + private const val MEDIA_KEYBOARD_MODE = "settings.media.keyboard.mode" + private const val LOCAL_BACKUP_NEXT_TIME = "settings.backups.next.time" + private const val MEDIA_DOWNLOAD_MOBILE = "settings.media.download.mobile" + private const val MEDIA_DOWNLOAD_WIFI = "settings.media.download.wifi" + private const val MEDIA_DOWNLOAD_ROAMING = "settings.media.download.roaming" + + const val SCREEN_SECURITY_ENABLED = "settings.screen.security.enabled" + const val INCOGNITO_KEYBOARD_ENABLED = "settings.incognito.keyboard.enabled" + const val READ_RECEIPTS_ENABLED = "settings.read.receipts.enabled" + const val TYPING_INDICATORS_ENABLED = "settings.typing.indicators.enabled" + const val SHOW_UNIDENTIFIED_DELIVERY_INDICATORS = "settings.show.unidentified.delivery.indicators" + const val UNIVERSAL_UNIDENTIFIED_ACCESS = "settings.universal.unidentified.access" + const val ALWAYS_RELAY_CALLS = "settings.always.relay.calls" const val BACKUP_DEFAULT_HOUR = 2 const val BACKUP_DEFAULT_MINUTE = 0 @@ -90,6 +108,10 @@ class SettingsValues internal constructor(store: KeyValueStore, context: Context if (!store.containsKey(SCREEN_LOCK_ENABLED) && !Environment.IS_INSTRUMENTATION) { migrateFromSharedPrefsV1(context) } + + if (!store.containsKey(SCREEN_SECURITY_ENABLED) && !Environment.IS_INSTRUMENTATION) { + migrateFromSharedPrefsV2(context) + } } public override fun onFirstEverAppLaunch() { @@ -138,7 +160,17 @@ class SettingsValues internal constructor(store: KeyValueStore, context: Context PASSPHRASE_TIMEOUT_ENABLED, PASSPHRASE_TIMEOUT, SCREEN_LOCK_ENABLED, - SCREEN_LOCK_TIMEOUT + SCREEN_LOCK_TIMEOUT, + SCREEN_SECURITY_ENABLED, + INCOGNITO_KEYBOARD_ENABLED, + READ_RECEIPTS_ENABLED, + TYPING_INDICATORS_ENABLED, + SHOW_UNIDENTIFIED_DELIVERY_INDICATORS, + UNIVERSAL_UNIDENTIFIED_ACCESS, + ALWAYS_RELAY_CALLS, + MEDIA_DOWNLOAD_MOBILE, + MEDIA_DOWNLOAD_WIFI, + MEDIA_DOWNLOAD_ROAMING ) val onConfigurationSettingChanged: LiveData @@ -191,17 +223,13 @@ class SettingsValues internal constructor(store: KeyValueStore, context: Context } var theme: Theme - get() = Theme.deserialize(getString(THEME, TextSecurePreferences.getTheme(AppDependencies.application))) + get() = Theme.deserialize(getString(THEME, if (DynamicTheme.systemThemeAvailable()) "system" else "light")) set(value) { putString(THEME, value.serialize()) configurationSettingChanged.postValue(THEME) } - var messageFontSize: Int - get() = getInteger(MESSAGE_FONT_SIZE, TextSecurePreferences.getMessageBodyTextSize(AppDependencies.application)) - set(value) { - putInteger(MESSAGE_FONT_SIZE, value) - } + var messageFontSize: Int by integerValue(MESSAGE_FONT_SIZE, 16) fun getMessageQuoteFontSize(context: Context): Int { val currentMessageSize = messageFontSize @@ -220,23 +248,11 @@ class SettingsValues internal constructor(store: KeyValueStore, context: Context return possibleQuoteSizes[sizeIndex] } - var isPreferSystemEmoji: Boolean - get() = getBoolean(PREFER_SYSTEM_EMOJI, TextSecurePreferences.isSystemEmojiPreferred(AppDependencies.application)) - set(value) { - putBoolean(PREFER_SYSTEM_EMOJI, value) - } + var isPreferSystemEmoji: Boolean by booleanValue(PREFER_SYSTEM_EMOJI, false) - var isEnterKeySends: Boolean - get() = getBoolean(ENTER_KEY_SENDS, TextSecurePreferences.isEnterSendsEnabled(AppDependencies.application)) - set(value) { - putBoolean(ENTER_KEY_SENDS, value) - } + var isEnterKeySends: Boolean by booleanValue(ENTER_KEY_SENDS, false) - var isBackupEnabled: Boolean - get() = getBoolean(BACKUPS_ENABLED, TextSecurePreferences.isBackupEnabled(AppDependencies.application)) - set(value) { - putBoolean(BACKUPS_ENABLED, value) - } + var isBackupEnabled: Boolean by booleanValue(BACKUPS_ENABLED, false) val backupHour: Int get() = getInteger(BACKUPS_SCHEDULE_HOUR, BACKUP_DEFAULT_HOUR) @@ -280,27 +296,17 @@ class SettingsValues internal constructor(store: KeyValueStore, context: Context putInteger(SIGNAL_BACKUPS_SCHEDULE_MINUTE, minute) } - var isSmsDeliveryReportsEnabled: Boolean - get() = getBoolean(SMS_DELIVERY_REPORTS_ENABLED, TextSecurePreferences.isSmsDeliveryReportsEnabled(AppDependencies.application)) - set(value) { - putBoolean(SMS_DELIVERY_REPORTS_ENABLED, value) - } + var localBackupNextTime: Long by longValue(LOCAL_BACKUP_NEXT_TIME, -1) - var isWifiCallingCompatibilityModeEnabled: Boolean - get() = getBoolean(WIFI_CALLING_COMPATIBILITY_MODE_ENABLED, TextSecurePreferences.isWifiSmsEnabled(AppDependencies.application)) - set(value) { - putBoolean(WIFI_CALLING_COMPATIBILITY_MODE_ENABLED, value) - } + var isSmsDeliveryReportsEnabled: Boolean by booleanValue(SMS_DELIVERY_REPORTS_ENABLED, false) - var isMessageNotificationsEnabled: Boolean - get() = getBoolean(MESSAGE_NOTIFICATIONS_ENABLED, TextSecurePreferences.isNotificationsEnabled(AppDependencies.application)) - set(value) { - putBoolean(MESSAGE_NOTIFICATIONS_ENABLED, value) - } + var isWifiCallingCompatibilityModeEnabled: Boolean by booleanValue(WIFI_CALLING_COMPATIBILITY_MODE_ENABLED, false) + + var isMessageNotificationsEnabled: Boolean by booleanValue(MESSAGE_NOTIFICATIONS_ENABLED, true) var messageNotificationSound: Uri get() { - var result = getString(MESSAGE_NOTIFICATION_SOUND, TextSecurePreferences.getNotificationRingtone(AppDependencies.application).toString()) + var result = getString(MESSAGE_NOTIFICATION_SOUND, Settings.System.DEFAULT_NOTIFICATION_URI.toString()) if (result.startsWith("file:")) { result = Settings.System.DEFAULT_NOTIFICATION_URI.toString() @@ -312,38 +318,23 @@ class SettingsValues internal constructor(store: KeyValueStore, context: Context putString(MESSAGE_NOTIFICATION_SOUND, value.toString()) } - var isMessageVibrateEnabled: Boolean - get() = getBoolean(MESSAGE_VIBRATE_ENABLED, TextSecurePreferences.isNotificationVibrateEnabled(AppDependencies.application)) - set(value) { - putBoolean(MESSAGE_VIBRATE_ENABLED, value) - } + var isMessageVibrateEnabled: Boolean by booleanValue(MESSAGE_VIBRATE_ENABLED, true) - var messageLedColor: String - get() = getString(MESSAGE_LED_COLOR, TextSecurePreferences.getNotificationLedColor(AppDependencies.application)) - set(value) { - putString(MESSAGE_LED_COLOR, value) - } + var messageLedColor: String by stringValue(MESSAGE_LED_COLOR, "blue") - var messageLedBlinkPattern: String - get() = getString(MESSAGE_LED_BLINK_PATTERN, TextSecurePreferences.getNotificationLedPattern(AppDependencies.application)) - set(value) { - putString(MESSAGE_LED_BLINK_PATTERN, value) - } + var messageLedBlinkPattern: String by stringValue(MESSAGE_LED_BLINK_PATTERN, "500,2000") - var isMessageNotificationsInChatSoundsEnabled: Boolean - get() = getBoolean(MESSAGE_IN_CHAT_SOUNDS_ENABLED, TextSecurePreferences.isInThreadNotifications(AppDependencies.application)) - set(value) { - putBoolean(MESSAGE_IN_CHAT_SOUNDS_ENABLED, value) - } + val messageLedBlinkPatternCustom: String + get() = getString(MESSAGE_LED_BLINK_PATTERN_CUSTOM, "500,2000") - var messageNotificationsRepeatAlerts: Int - get() = getInteger(MESSAGE_REPEAT_ALERTS, TextSecurePreferences.getRepeatAlertsCount(AppDependencies.application)) - set(value) { - putInteger(MESSAGE_REPEAT_ALERTS, value) - } + var isMessageNotificationsInChatSoundsEnabled: Boolean by booleanValue(MESSAGE_IN_CHAT_SOUNDS_ENABLED, true) + + var messageNotificationsRepeatAlerts: Int by integerValue(MESSAGE_REPEAT_ALERTS, 0) + + var messageNotificationPriority: Int by integerValue(MESSAGE_NOTIFICATION_PRIORITY, NotificationCompat.PRIORITY_HIGH) var messageNotificationsPrivacy: NotificationPrivacyPreference - get() = NotificationPrivacyPreference(getString(MESSAGE_NOTIFICATION_PRIVACY, TextSecurePreferences.getNotificationPrivacy(AppDependencies.application).toString())) + get() = NotificationPrivacyPreference(getString(MESSAGE_NOTIFICATION_PRIVACY, "all")) set(value) { putString(MESSAGE_NOTIFICATION_PRIVACY, value.toString()) } @@ -377,15 +368,11 @@ class SettingsValues internal constructor(store: KeyValueStore, context: Context putBoolean(INCLUDE_MUTED_IN_BADGE_COUNT, include) } - var isCallNotificationsEnabled: Boolean - get() = getBoolean(CALL_NOTIFICATIONS_ENABLED, TextSecurePreferences.isCallNotificationsEnabled(AppDependencies.application)) - set(value) { - putBoolean(CALL_NOTIFICATIONS_ENABLED, value) - } + var isCallNotificationsEnabled: Boolean by booleanValue(CALL_NOTIFICATIONS_ENABLED, true) var callRingtone: Uri get() { - var result = getString(CALL_RINGTONE, TextSecurePreferences.getCallNotificationRingtone(AppDependencies.application).toString()) + var result = getString(CALL_RINGTONE, Settings.System.DEFAULT_RINGTONE_URI.toString()) if (result != null && result.startsWith("file:")) { result = Settings.System.DEFAULT_RINGTONE_URI.toString() @@ -397,17 +384,9 @@ class SettingsValues internal constructor(store: KeyValueStore, context: Context putString(CALL_RINGTONE, value.toString()) } - var isCallVibrateEnabled: Boolean - get() = getBoolean(CALL_VIBRATE_ENABLED, TextSecurePreferences.isCallNotificationVibrateEnabled(AppDependencies.application)) - set(value) { - putBoolean(CALL_VIBRATE_ENABLED, value) - } + var isCallVibrateEnabled: Boolean by booleanValue(CALL_VIBRATE_ENABLED, true) - var isNotifyWhenContactJoinsSignal: Boolean - get() = getBoolean(NOTIFY_WHEN_CONTACT_JOINS_SIGNAL, TextSecurePreferences.isNewContactsNotificationEnabled(AppDependencies.application)) - set(value) { - putBoolean(NOTIFY_WHEN_CONTACT_JOINS_SIGNAL, value) - } + var isNotifyWhenContactJoinsSignal: Boolean by booleanValue(NOTIFY_WHEN_CONTACT_JOINS_SIGNAL, false) var universalExpireTimer: Int by integerValue(UNIVERSAL_EXPIRE_TIMER, 0) @@ -439,6 +418,20 @@ class SettingsValues internal constructor(store: KeyValueStore, context: Context var screenLockTimeout: Long by longValue(SCREEN_LOCK_TIMEOUT, 0) + var isScreenSecurityEnabled: Boolean by booleanValue(SCREEN_SECURITY_ENABLED, false) + + var isIncognitoKeyboardEnabled: Boolean by booleanValue(INCOGNITO_KEYBOARD_ENABLED, false) + + var isReadReceiptsEnabled: Boolean by booleanValue(READ_RECEIPTS_ENABLED, false) + + var isTypingIndicatorsEnabled: Boolean by booleanValue(TYPING_INDICATORS_ENABLED, false) + + var isShowUnidentifiedDeliveryIndicatorsEnabled: Boolean by booleanValue(SHOW_UNIDENTIFIED_DELIVERY_INDICATORS, false) + + var isUniversalUnidentifiedAccess: Boolean by booleanValue(UNIVERSAL_UNIDENTIFIED_ACCESS, false) + + var isTurnOnly: Boolean by booleanValue(ALWAYS_RELAY_CALLS, false) + var automaticVerificationEnabled: Boolean get() = getBoolean(AUTOMATIC_VERIFICATION_ENABLED, true) set(value) { @@ -460,6 +453,42 @@ class SettingsValues internal constructor(store: KeyValueStore, context: Context putInteger(FORCE_WEBSOCKET_MODE, value.serialize()) } + var mediaKeyboardMode: MediaKeyboardMode + get() = MediaKeyboardMode.valueOf(getString(MEDIA_KEYBOARD_MODE, MediaKeyboardMode.EMOJI.name)) + set(value) { + putString(MEDIA_KEYBOARD_MODE, value.name) + } + + var mobileMediaDownloadAllowed: Set + get() = getMediaDownloadAllowed(MEDIA_DOWNLOAD_MOBILE, R.array.pref_media_download_mobile_data_default) + set(value) { + setMediaDownloadAllowed(MEDIA_DOWNLOAD_MOBILE, value) + } + + var wifiMediaDownloadAllowed: Set + get() = getMediaDownloadAllowed(MEDIA_DOWNLOAD_WIFI, R.array.pref_media_download_wifi_default) + set(value) { + setMediaDownloadAllowed(MEDIA_DOWNLOAD_WIFI, value) + } + + var roamingMediaDownloadAllowed: Set + get() = getMediaDownloadAllowed(MEDIA_DOWNLOAD_ROAMING, R.array.pref_media_download_roaming_default) + set(value) { + setMediaDownloadAllowed(MEDIA_DOWNLOAD_ROAMING, value) + } + + private fun getMediaDownloadAllowed(key: String, @ArrayRes defaultValuesRes: Int): Set { + if (!store.containsKey(key)) { + return context.resources.getStringArray(defaultValuesRes).toSet() + } + + return getList(key, StringStringSerializer).requireNoNulls().toSet() + } + + private fun setMediaDownloadAllowed(key: String, allowed: Set) { + putList(key, allowed.toList(), StringStringSerializer) + } + private fun getUri(key: String): Uri? { val uri = getString(key, "") @@ -473,11 +502,111 @@ class SettingsValues internal constructor(store: KeyValueStore, context: Context private fun migrateFromSharedPrefsV1(context: Context) { Log.i(TAG, "[V1] Migrating screen lock values from shared prefs.") - putBoolean(PASSPHRASE_DISABLED, TextSecurePreferences.getBooleanPreference(context, "pref_disable_passphrase", true)) - putBoolean(PASSPHRASE_TIMEOUT_ENABLED, TextSecurePreferences.getBooleanPreference(context, "pref_timeout_passphrase", false)) - putInteger(PASSPHRASE_TIMEOUT, TextSecurePreferences.getIntegerPreference(context, "pref_timeout_interval", 5 * 60)) - putBoolean(SCREEN_LOCK_ENABLED, TextSecurePreferences.getBooleanPreference(context, "pref_android_screen_lock", false)) - putLong(SCREEN_LOCK_TIMEOUT, TextSecurePreferences.getLongPreference(context, "pref_android_screen_lock_timeout", 0)) + putBoolean(PASSPHRASE_DISABLED, LegacySharedPrefs.getBoolean(context, "pref_disable_passphrase", true)) + putBoolean(PASSPHRASE_TIMEOUT_ENABLED, LegacySharedPrefs.getBoolean(context, "pref_timeout_passphrase", false)) + putInteger(PASSPHRASE_TIMEOUT, LegacySharedPrefs.getInteger(context, "pref_timeout_interval", 5 * 60)) + putBoolean(SCREEN_LOCK_ENABLED, LegacySharedPrefs.getBoolean(context, "pref_android_screen_lock", false)) + putLong(SCREEN_LOCK_TIMEOUT, LegacySharedPrefs.getLong(context, "pref_android_screen_lock_timeout", 0)) + } + + /** + * These settings used to live in shared prefs. Some of them were already mirrored into this store, but with a shared-prefs read as + * their default, so for those we only migrate the ones this store doesn't already have a value for. + */ + private fun migrateFromSharedPrefsV2(context: Context) { + Log.i(TAG, "[V2] Migrating settings from shared prefs.") + + val writer = store.beginWrite() + + if (!store.containsKey(THEME)) { + writer.putString(THEME, LegacySharedPrefs.getString(context, "pref_theme", if (DynamicTheme.systemThemeAvailable()) "system" else "light")) + } + if (!store.containsKey(MESSAGE_FONT_SIZE)) { + writer.putInteger(MESSAGE_FONT_SIZE, LegacySharedPrefs.getIntegerFromString(context, "pref_message_body_text_size", 16)) + } + if (!store.containsKey(PREFER_SYSTEM_EMOJI)) { + writer.putBoolean(PREFER_SYSTEM_EMOJI, LegacySharedPrefs.getBoolean(context, "pref_system_emoji", false)) + } + if (!store.containsKey(ENTER_KEY_SENDS)) { + writer.putBoolean(ENTER_KEY_SENDS, LegacySharedPrefs.getBoolean(context, "pref_enter_sends", false)) + } + if (!store.containsKey(BACKUPS_ENABLED)) { + writer.putBoolean(BACKUPS_ENABLED, LegacySharedPrefs.getBoolean(context, "pref_backup_enabled", false)) + } + if (!store.containsKey(SMS_DELIVERY_REPORTS_ENABLED)) { + writer.putBoolean(SMS_DELIVERY_REPORTS_ENABLED, LegacySharedPrefs.getBoolean(context, "pref_delivery_report_sms", false)) + } + if (!store.containsKey(WIFI_CALLING_COMPATIBILITY_MODE_ENABLED)) { + writer.putBoolean(WIFI_CALLING_COMPATIBILITY_MODE_ENABLED, LegacySharedPrefs.getBoolean(context, "pref_wifi_sms", false)) + } + if (!store.containsKey(MESSAGE_NOTIFICATIONS_ENABLED)) { + writer.putBoolean(MESSAGE_NOTIFICATIONS_ENABLED, LegacySharedPrefs.getBoolean(context, "pref_key_enable_notifications", true)) + } + if (!store.containsKey(MESSAGE_NOTIFICATION_SOUND)) { + writer.putString(MESSAGE_NOTIFICATION_SOUND, LegacySharedPrefs.getRingtone(context, "pref_key_ringtone", Settings.System.DEFAULT_NOTIFICATION_URI)) + } + if (!store.containsKey(MESSAGE_VIBRATE_ENABLED)) { + writer.putBoolean(MESSAGE_VIBRATE_ENABLED, LegacySharedPrefs.getBoolean(context, "pref_key_vibrate", true)) + } + if (!store.containsKey(MESSAGE_LED_COLOR)) { + writer.putString(MESSAGE_LED_COLOR, LegacySharedPrefs.getString(context, "pref_led_color", "blue")) + } + if (!store.containsKey(MESSAGE_LED_BLINK_PATTERN)) { + writer.putString(MESSAGE_LED_BLINK_PATTERN, LegacySharedPrefs.getString(context, "pref_led_blink", "500,2000")) + } + if (!store.containsKey(MESSAGE_IN_CHAT_SOUNDS_ENABLED)) { + writer.putBoolean(MESSAGE_IN_CHAT_SOUNDS_ENABLED, LegacySharedPrefs.getBoolean(context, "pref_key_inthread_notifications", true)) + } + if (!store.containsKey(MESSAGE_REPEAT_ALERTS)) { + writer.putInteger(MESSAGE_REPEAT_ALERTS, LegacySharedPrefs.getIntegerFromString(context, "pref_repeat_alerts", 0)) + } + if (!store.containsKey(MESSAGE_NOTIFICATION_PRIVACY)) { + writer.putString(MESSAGE_NOTIFICATION_PRIVACY, LegacySharedPrefs.getString(context, "pref_notification_privacy", "all")) + } + if (!store.containsKey(CALL_NOTIFICATIONS_ENABLED)) { + writer.putBoolean(CALL_NOTIFICATIONS_ENABLED, LegacySharedPrefs.getBoolean(context, "pref_call_notifications", true)) + } + if (!store.containsKey(CALL_RINGTONE)) { + writer.putString(CALL_RINGTONE, LegacySharedPrefs.getRingtone(context, "pref_call_ringtone", Settings.System.DEFAULT_RINGTONE_URI)) + } + if (!store.containsKey(CALL_VIBRATE_ENABLED)) { + val systemVibrateWhenRinging = Settings.System.getInt(context.contentResolver, Settings.System.VIBRATE_WHEN_RINGING, 1) == 1 + writer.putBoolean(CALL_VIBRATE_ENABLED, LegacySharedPrefs.getBoolean(context, "pref_call_vibrate", systemVibrateWhenRinging)) + } + if (!store.containsKey(NOTIFY_WHEN_CONTACT_JOINS_SIGNAL)) { + writer.putBoolean(NOTIFY_WHEN_CONTACT_JOINS_SIGNAL, LegacySharedPrefs.getBoolean(context, "pref_enable_new_contacts_notifications", false)) + } + + writer.putString(MESSAGE_LED_BLINK_PATTERN_CUSTOM, LegacySharedPrefs.getString(context, "pref_led_blink_custom", "500,2000")) + writer.putInteger(MESSAGE_NOTIFICATION_PRIORITY, LegacySharedPrefs.getIntegerFromString(context, "pref_notification_priority", NotificationCompat.PRIORITY_HIGH)) + writer.putString(MEDIA_KEYBOARD_MODE, LegacySharedPrefs.getString(context, "pref_media_keyboard_mode", MediaKeyboardMode.EMOJI.name)) + writer.putLong(LOCAL_BACKUP_NEXT_TIME, LegacySharedPrefs.getLong(context, "pref_backup_next_time", -1)) + writer.putBoolean(INCOGNITO_KEYBOARD_ENABLED, LegacySharedPrefs.getBoolean(context, "pref_incognito_keyboard", false)) + writer.putBoolean(READ_RECEIPTS_ENABLED, LegacySharedPrefs.getBoolean(context, "pref_read_receipts", false)) + writer.putBoolean(TYPING_INDICATORS_ENABLED, LegacySharedPrefs.getBoolean(context, "pref_typing_indicators", false)) + writer.putBoolean(SHOW_UNIDENTIFIED_DELIVERY_INDICATORS, LegacySharedPrefs.getBoolean(context, "pref_show_unidentifed_delivery_indicators", false)) + writer.putBoolean(UNIVERSAL_UNIDENTIFIED_ACCESS, LegacySharedPrefs.getBoolean(context, "pref_universal_unidentified_access", false)) + writer.putBoolean(ALWAYS_RELAY_CALLS, LegacySharedPrefs.getBoolean(context, "pref_turn_only", false)) + + // Only migrate an explicit choice -- when there was none, the getters fall back to the same resource defaults shared prefs used to. + val mediaDownloadKeys = mapOf( + "pref_media_download_mobile" to MEDIA_DOWNLOAD_MOBILE, + "pref_media_download_wifi" to MEDIA_DOWNLOAD_WIFI, + "pref_media_download_roaming" to MEDIA_DOWNLOAD_ROAMING + ) + + for ((legacyKey, key) in mediaDownloadKeys) { + val legacyValue = LegacySharedPrefs.getStringSet(context, legacyKey, null) + + if (legacyValue != null) { + writer.putBlob(key, SignalStoreList(contents = legacyValue.toList()).encode()) + } + } + + // Written last so that it acts as the marker for this migration having run. + writer.putBoolean(SCREEN_SECURITY_ENABLED, LegacySharedPrefs.getBoolean(context, "pref_screen_security", false)) + + writer.commit() } enum class CensorshipCircumventionEnabled(private val value: Int) { @@ -513,6 +642,13 @@ class SettingsValues internal constructor(store: KeyValueStore, context: Context } } + /** NEVER rename these -- they're persisted by name. */ + enum class MediaKeyboardMode { + EMOJI, + STICKER, + GIF + } + enum class Theme(private val value: String) { SYSTEM("system"), LIGHT("light"), diff --git a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionKeyPreferences.java b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionKeyPreferences.java index 87be2c74c2..7e783c0866 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionKeyPreferences.java +++ b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionKeyPreferences.java @@ -32,12 +32,12 @@ final class LogSectionKeyPreferences implements LogSection { .append("Thread Trimming : ").append(getThreadTrimmingString()).append("\n") .append("Censorship Setting : ").append(SignalStore.settings().getCensorshipCircumventionEnabled()).append("\n") .append("Network Reachable : ").append(SignalStore.misc().isServiceReachableWithoutCircumvention()).append(", last checked: ").append(SignalStore.misc().getLastCensorshipServiceReachabilityCheckTime()).append("\n") - .append("Wifi Download : ").append(Util.join(TextSecurePreferences.getWifiMediaDownloadAllowed(context), ",")).append("\n") - .append("Roaming Download : ").append(Util.join(TextSecurePreferences.getRoamingMediaDownloadAllowed(context), ",")).append("\n") - .append("Mobile Download : ").append(Util.join(TextSecurePreferences.getMobileMediaDownloadAllowed(context), ",")).append("\n") + .append("Wifi Download : ").append(Util.join(SignalStore.settings().getWifiMediaDownloadAllowed(), ",")).append("\n") + .append("Roaming Download : ").append(Util.join(SignalStore.settings().getRoamingMediaDownloadAllowed(), ",")).append("\n") + .append("Mobile Download : ").append(Util.join(SignalStore.settings().getMobileMediaDownloadAllowed(), ",")).append("\n") .append("Phone Number Sharing : ").append(SignalStore.phoneNumberPrivacy().isPhoneNumberSharingEnabled()).append(" (").append(SignalStore.phoneNumberPrivacy().getPhoneNumberSharingMode()).append(")\n") .append("Phone Number Discoverable: ").append(SignalStore.phoneNumberPrivacy().getPhoneNumberDiscoverabilityMode()).append("\n") - .append("Incognito keyboard : ").append(TextSecurePreferences.isIncognitoKeyboardEnabled(context)).append("\n"); + .append("Incognito keyboard : ").append(SignalStore.settings().isIncognitoKeyboardEnabled()).append("\n"); } private static String getThreadTrimmingString() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/text/TextStoryPostLinkEntryFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/text/TextStoryPostLinkEntryFragment.kt index 1f8dc62f4c..e94a5f4b2e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/text/TextStoryPostLinkEntryFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/text/TextStoryPostLinkEntryFragment.kt @@ -10,11 +10,11 @@ import androidx.fragment.app.viewModels import com.google.android.material.snackbar.Snackbar import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.components.KeyboardEntryDialogFragment +import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.linkpreview.LinkPreviewRepository import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModel import org.thoughtcrime.securesms.stories.StoryLinkPreviewView import org.thoughtcrime.securesms.util.LinkUtil -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.ViewUtil import org.thoughtcrime.securesms.util.activityViewModel import org.thoughtcrime.securesms.util.setIncognitoKeyboardEnabled @@ -47,7 +47,7 @@ class TextStoryPostLinkEntryFragment(private val shouldPreset: Boolean = false) val confirmButton: View = view.findViewById(R.id.confirm_button) val shareALinkGroup: Group = view.findViewById(R.id.share_a_link_group) - input.setIncognitoKeyboardEnabled(TextSecurePreferences.isIncognitoKeyboardEnabled(requireContext())) + input.setIncognitoKeyboardEnabled(SignalStore.settings.isIncognitoKeyboardEnabled) input.addTextChangedListener( afterTextChanged = { val scheme = "https://" diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/text/TextStoryPostTextEntryFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/text/TextStoryPostTextEntryFragment.kt index 1a1fedb323..e4efb514c2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/text/TextStoryPostTextEntryFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/text/TextStoryPostTextEntryFragment.kt @@ -28,13 +28,13 @@ import io.reactivex.rxjava3.kotlin.subscribeBy import org.signal.core.util.concurrent.LifecycleDisposable import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.components.KeyboardEntryDialogFragment +import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.mediasend.v2.MediaAnimations import org.thoughtcrime.securesms.scribbles.HSVColorSlider import org.thoughtcrime.securesms.scribbles.HSVColorSlider.getColor import org.thoughtcrime.securesms.scribbles.HSVColorSlider.setColor import org.thoughtcrime.securesms.scribbles.HSVColorSlider.setUpForColor import org.thoughtcrime.securesms.util.RemoteConfig -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.ViewUtil import org.thoughtcrime.securesms.util.activityViewModel import org.thoughtcrime.securesms.util.fragments.findListener @@ -121,7 +121,7 @@ class TextStoryPostTextEntryFragment : KeyboardEntryDialogFragment( viewModel.setTemporaryBody(text?.toString() ?: "") } input.setText(viewModel.getBody()) - input.setIncognitoKeyboardEnabled(TextSecurePreferences.isIncognitoKeyboardEnabled(requireContext())) + input.setIncognitoKeyboardEnabled(SignalStore.settings.isIncognitoKeyboardEnabled) } private fun presentHint() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/messagedetails/RecipientViewHolder.java b/app/src/main/java/org/thoughtcrime/securesms/messagedetails/RecipientViewHolder.java index 91c387e780..fddd49fd2c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messagedetails/RecipientViewHolder.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messagedetails/RecipientViewHolder.java @@ -13,9 +13,9 @@ import org.thoughtcrime.securesms.components.FromTextView; import org.thoughtcrime.securesms.database.AttachmentTable; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.database.model.MmsMessageRecord; +import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.mms.Slide; import org.thoughtcrime.securesms.util.DateUtils; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import java.util.List; import java.util.Locale; @@ -45,7 +45,7 @@ final class RecipientViewHolder extends RecyclerView.ViewHolder { } void bind(RecipientDeliveryStatus data) { - unidentifiedDeliveryIcon.setVisibility(TextSecurePreferences.isShowUnidentifiedDeliveryIndicatorsEnabled(itemView.getContext()) && data.isUnidentified() ? View.VISIBLE : View.GONE); + unidentifiedDeliveryIcon.setVisibility(SignalStore.settings().isShowUnidentifiedDeliveryIndicatorsEnabled() && data.isUnidentified() ? View.VISIBLE : View.GONE); fromView.setText(data.getRecipient(), data.getRecipient().getDisplayName(itemView.getContext()), null, true, true); avatar.setRecipient(data.getRecipient()); badge.setBadgeFromRecipient(data.getRecipient()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/DataMessageProcessor.kt b/app/src/main/java/org/thoughtcrime/securesms/messages/DataMessageProcessor.kt index 996bdbb245..984c2cfe27 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/DataMessageProcessor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/DataMessageProcessor.kt @@ -101,7 +101,6 @@ import org.thoughtcrime.securesms.util.MessageConstraintsUtil import org.thoughtcrime.securesms.util.RemoteConfig import org.thoughtcrime.securesms.util.SignalLocalMetrics import org.thoughtcrime.securesms.util.SignalTrace -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.hasGiftBadge import org.thoughtcrime.securesms.util.isStory import org.whispersystems.signalservice.api.crypto.EnvelopeMetadata @@ -1483,7 +1482,7 @@ object DataMessageProcessor { fun notifyTypingStoppedFromIncomingMessage(context: Context, senderRecipient: Recipient, threadRecipientId: RecipientId, device: Int) { val threadId = SignalDatabase.threads.getThreadIdIfExistsFor(threadRecipientId) - if (threadId > 0 && TextSecurePreferences.isTypingIndicatorsEnabled(context)) { + if (threadId > 0 && SignalStore.settings.isTypingIndicatorsEnabled) { debug("Typing stopped on thread $threadId due to an incoming message.") AppDependencies.typingStatusRepository.onTypingStopped(threadId, senderRecipient, device, true) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessor.kt b/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessor.kt index af4d49a6cf..c5cde71616 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessor.kt @@ -48,7 +48,6 @@ import org.thoughtcrime.securesms.util.EarlyMessageCacheEntry import org.thoughtcrime.securesms.util.RemoteConfig import org.thoughtcrime.securesms.util.SignalLocalMetrics import org.thoughtcrime.securesms.util.SignalTrace -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.signalservice.api.crypto.EnvelopeMetadata import org.whispersystems.signalservice.api.push.DistributionId import org.whispersystems.signalservice.api.push.SignalServiceAddress @@ -582,7 +581,7 @@ open class MessageContentProcessor(private val context: Context) { typingMessage: TypingMessage, senderRecipient: Recipient ) { - if (!TextSecurePreferences.isTypingIndicatorsEnabled(context)) { + if (!SignalStore.settings.isTypingIndicatorsEnabled) { return } diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/ReceiptMessageProcessor.kt b/app/src/main/java/org/thoughtcrime/securesms/messages/ReceiptMessageProcessor.kt index 84ed6473ff..6cd2fbd313 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/ReceiptMessageProcessor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/ReceiptMessageProcessor.kt @@ -12,7 +12,6 @@ import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.util.EarlyMessageCacheEntry import org.thoughtcrime.securesms.util.SignalTrace -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.signalservice.api.crypto.EnvelopeMetadata import org.whispersystems.signalservice.internal.push.Content import org.whispersystems.signalservice.internal.push.Envelope @@ -77,7 +76,7 @@ object ReceiptMessageProcessor { earlyMessageCacheEntry: EarlyMessageCacheEntry?, batchCache: BatchCache ) { - if (!TextSecurePreferences.isReadReceiptsEnabled(context)) { + if (!SignalStore.settings.isReadReceiptsEnabled) { log(envelope.clientTimestamp!!, "Ignoring read receipts for IDs: " + readReceipt.timestamp.joinToString(", ")) return } @@ -113,7 +112,7 @@ object ReceiptMessageProcessor { earlyMessageCacheEntry: EarlyMessageCacheEntry?, batchCache: BatchCache ) { - val readReceipts = TextSecurePreferences.isReadReceiptsEnabled(context) + val readReceipts = SignalStore.settings.isReadReceiptsEnabled val storyViewedReceipts = SignalStore.story.viewedReceiptsEnabled if (!readReceipts && !storyViewedReceipts) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/SyncMessageProcessor.kt b/app/src/main/java/org/thoughtcrime/securesms/messages/SyncMessageProcessor.kt index 1a7489cbb0..fc434eb601 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/SyncMessageProcessor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/SyncMessageProcessor.kt @@ -123,7 +123,6 @@ import org.thoughtcrime.securesms.util.IdentityUtil import org.thoughtcrime.securesms.util.MediaUtil import org.thoughtcrime.securesms.util.MessageConstraintsUtil import org.thoughtcrime.securesms.util.SignalE164Util -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.hasGiftBadge import org.whispersystems.signalservice.api.crypto.EnvelopeMetadata import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer @@ -993,9 +992,9 @@ object SyncMessageProcessor { Request.Type.CONFIGURATION -> { AppDependencies.jobManager.add( MultiDeviceConfigurationUpdateJob( - TextSecurePreferences.isReadReceiptsEnabled(context), - TextSecurePreferences.isTypingIndicatorsEnabled(context), - TextSecurePreferences.isShowUnidentifiedDeliveryIndicatorsEnabled(context), + SignalStore.settings.isReadReceiptsEnabled, + SignalStore.settings.isTypingIndicatorsEnabled, + SignalStore.settings.isShowUnidentifiedDeliveryIndicatorsEnabled, SignalStore.settings.isLinkPreviewsEnabled ) ) @@ -1140,15 +1139,15 @@ object SyncMessageProcessor { log(envelopeTimestamp, "Synchronize configuration message.") if (configurationMessage.readReceipts != null) { - TextSecurePreferences.setReadReceiptsEnabled(context, configurationMessage.readReceipts!!) + SignalStore.settings.isReadReceiptsEnabled = configurationMessage.readReceipts!! } if (configurationMessage.unidentifiedDeliveryIndicators != null) { - TextSecurePreferences.setShowUnidentifiedDeliveryIndicatorsEnabled(context, configurationMessage.unidentifiedDeliveryIndicators!!) + SignalStore.settings.isShowUnidentifiedDeliveryIndicatorsEnabled = configurationMessage.unidentifiedDeliveryIndicators!! } if (configurationMessage.typingIndicators != null) { - TextSecurePreferences.setTypingIndicatorsEnabled(context, configurationMessage.typingIndicators!!) + SignalStore.settings.isTypingIndicatorsEnabled = configurationMessage.typingIndicators!! } if (configurationMessage.linkPreviews != null) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/LegacyMigrationJob.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/LegacyMigrationJob.java index 6e246f18a1..ee3bff011d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/LegacyMigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/LegacyMigrationJob.java @@ -150,8 +150,8 @@ public class LegacyMigrationJob extends MigrationJob { } if (lastSeenVersion < SCREENSHOTS) { - boolean screenSecurity = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(TextSecurePreferences.SCREEN_SECURITY_PREF, true); - TextSecurePreferences.setScreenSecurityEnabled(context, screenSecurity); + boolean screenSecurity = PreferenceManager.getDefaultSharedPreferences(context).getBoolean("pref_screen_security", true); + SignalStore.settings().setScreenSecurityEnabled(screenSecurity); } if (lastSeenVersion < PERSISTENT_BLOBS) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/StoryViewedReceiptsStateMigrationJob.kt b/app/src/main/java/org/thoughtcrime/securesms/migrations/StoryViewedReceiptsStateMigrationJob.kt index 30d69b063c..811bcc79d3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/StoryViewedReceiptsStateMigrationJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/StoryViewedReceiptsStateMigrationJob.kt @@ -5,7 +5,6 @@ import org.thoughtcrime.securesms.jobmanager.Job import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.storage.StorageSyncHelper -import org.thoughtcrime.securesms.util.TextSecurePreferences /** * Added as a way to initialize the story viewed receipts setting. @@ -23,7 +22,7 @@ internal class StoryViewedReceiptsStateMigrationJob( override fun performMigration() { if (!SignalStore.story.isViewedReceiptsStateSet()) { - SignalStore.story.viewedReceiptsEnabled = TextSecurePreferences.isReadReceiptsEnabled(context) + SignalStore.story.viewedReceiptsEnabled = SignalStore.settings.isReadReceiptsEnabled if (SignalStore.account.isRegistered) { recipients.markNeedsSync(Recipient.self().id) StorageSyncHelper.scheduleSyncForDataChange() diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationBuilder.kt b/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationBuilder.kt index 62b0e052e3..59c3d45726 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationBuilder.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationBuilder.kt @@ -32,7 +32,6 @@ import org.thoughtcrime.securesms.service.KeyCachingService import org.thoughtcrime.securesms.util.AvatarUtil import org.thoughtcrime.securesms.util.BubbleUtil import org.thoughtcrime.securesms.util.ConversationUtil -import org.thoughtcrime.securesms.util.TextSecurePreferences import java.util.Optional import androidx.core.app.Person as PersonCompat import org.signal.core.ui.R as CoreUiR @@ -177,7 +176,7 @@ sealed class NotificationBuilder(protected val context: Context) { if (ledColor != "none") { var blinkPattern = SignalStore.settings.messageLedBlinkPattern if (blinkPattern == "custom") { - blinkPattern = TextSecurePreferences.getNotificationLedPatternCustom(context) + blinkPattern = SignalStore.settings.messageLedBlinkPatternCustom } val (onTime: Int, offTime: Int) = blinkPattern.parseBlinkPattern() setLights(Color.parseColor(ledColor), onTime, offTime) diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationFactory.kt b/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationFactory.kt index f39236eb98..5809a264eb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationFactory.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationFactory.kt @@ -36,7 +36,6 @@ import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.stories.my.MyStoriesActivity import org.thoughtcrime.securesms.util.BubbleUtil import org.thoughtcrime.securesms.util.ConversationUtil -import org.thoughtcrime.securesms.util.TextSecurePreferences import kotlin.time.Duration import kotlin.time.Duration.Companion.seconds import org.signal.core.ui.R as CoreUiR @@ -260,7 +259,7 @@ object NotificationFactory { setOnlyAlertOnce(!shouldAlert) setSilent(!shouldAlert) addMessages(conversation) - setPriority(TextSecurePreferences.getNotificationPriority(context)) + setPriority(SignalStore.settings.messageNotificationPriority) setLights() setAlarms(conversation.recipient) setTicker(conversation.mostRecentNotification.getStyledPrimaryText(context, true)) @@ -304,7 +303,7 @@ object NotificationFactory { addMessages(state) setOnlyAlertOnce(!hasNewNotifications) setSilent(!hasNewNotifications) - setPriority(TextSecurePreferences.getNotificationPriority(context)) + setPriority(SignalStore.settings.messageNotificationPriority) setLights() setAlarms(state.mostRecentSender) setTicker(state.mostRecentNotification?.getStyledPrimaryText(context, true)) diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/BackupsPreferenceFragment.java b/app/src/main/java/org/thoughtcrime/securesms/preferences/BackupsPreferenceFragment.java index f561c9bb1d..e4efec18e6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/BackupsPreferenceFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/BackupsPreferenceFragment.java @@ -304,7 +304,7 @@ public class BackupsPreferenceFragment extends Fragment { int minute = timePickerFragment.getMinute(); SignalStore.settings().setBackupSchedule(hour, minute); updateTimeLabel(); - TextSecurePreferences.setNextBackupTime(requireContext(), 0); + SignalStore.settings().setLocalBackupNextTime(0); LocalBackupListener.schedule(requireContext()); }); timePickerFragment.show(getChildFragmentManager(), "TIME_PICKER"); diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/data/RegistrationRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/registration/data/RegistrationRepository.kt index 13d359b7c0..aed0a66681 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/data/RegistrationRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/data/RegistrationRepository.kt @@ -422,7 +422,7 @@ object RegistrationRepository { Log.v(TAG, "registerAccount()") val api: RegistrationApi = AccountManagerFactory.getInstance().createUnauthenticated(context, registrationData.e164, SignalServiceAddress.DEFAULT_DEVICE_ID, registrationData.password).registrationApi - val universalUnidentifiedAccess: Boolean = TextSecurePreferences.isUniversalUnidentifiedAccess(context) + val universalUnidentifiedAccess: Boolean = SignalStore.settings.isUniversalUnidentifiedAccess val unidentifiedAccessKey: ByteArray = UnidentifiedAccess.deriveAccessKeyFrom(registrationData.profileKey) val masterKey: MasterKey? diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/ui/RegistrationViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/registration/ui/RegistrationViewModel.kt index b98c00f032..f1e6cafe8f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/ui/RegistrationViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/ui/RegistrationViewModel.kt @@ -85,7 +85,6 @@ import org.thoughtcrime.securesms.registration.ui.restore.StorageServiceRestore import org.thoughtcrime.securesms.registration.util.RegistrationUtil import org.thoughtcrime.securesms.registration.viewmodel.SvrAuthCredentialSet import org.thoughtcrime.securesms.util.RemoteConfig -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.dualsim.MccMncProducer import org.whispersystems.signalservice.api.SvrNoDataException import org.whispersystems.signalservice.api.messages.multidevice.RequestMessage @@ -1165,7 +1164,7 @@ class RegistrationViewModel : ViewModel() { ) if (message.readReceipts != null) { - TextSecurePreferences.setReadReceiptsEnabled(context, message.readReceipts!!) + SignalStore.settings.isReadReceiptsEnabled = message.readReceipts!! } RegistrationRepository.registerAccountLocally(context, data) diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/v2/AppRegistrationStorageController.kt b/app/src/main/java/org/thoughtcrime/securesms/registration/v2/AppRegistrationStorageController.kt index d201956ed7..1a548881f5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/v2/AppRegistrationStorageController.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/v2/AppRegistrationStorageController.kt @@ -83,6 +83,7 @@ import org.thoughtcrime.securesms.jobs.ReclaimUsernameAndLinkJob import org.thoughtcrime.securesms.jobs.RefreshOwnProfileJob import org.thoughtcrime.securesms.jobs.RotateCertificateJob import org.thoughtcrime.securesms.keyvalue.Completed +import org.thoughtcrime.securesms.keyvalue.LegacySharedPrefs import org.thoughtcrime.securesms.keyvalue.NewAccount import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues import org.thoughtcrime.securesms.keyvalue.SignalStore @@ -161,7 +162,7 @@ class AppRegistrationStorageController(private val context: Context) : StorageCo servicePassword = servicePassword, aep = aep, registrationLockEnabled = SignalStore.svr.isRegistrationLockEnabled, - unrestrictedUnidentifiedAccess = TextSecurePreferences.isUniversalUnidentifiedAccess(context), + unrestrictedUnidentifiedAccess = SignalStore.settings.isUniversalUnidentifiedAccess, aciIdentityKeyPair = aciIdentityKeyPair, pniIdentityKeyPair = pniIdentityKeyPair ) @@ -371,6 +372,8 @@ class AppRegistrationStorageController(private val context: Context) : StorageCo // Reset it so the state we read below reflects the restored values rather than stale pre-restore ones. SignalStore.onPostBackupRestore() + restoreLegacySettingsFromSharedPrefs() + // A post-registration restore clobbers parts of SignalStore.account with the backup's values -- V1 backups // carry the identity keys and AEP. Re-apply the frozen account data to heal the committed registration. val committedAccountData = inProgressData.accountData @@ -858,7 +861,7 @@ class AppRegistrationStorageController(private val context: Context) : StorageCo RotateSignedPreKeyListener.schedule(context) } - accountData.linkedDeviceData?.readReceipts?.let { TextSecurePreferences.setReadReceiptsEnabled(context, it) } + accountData.linkedDeviceData?.readReceipts?.let { SignalStore.settings.isReadReceiptsEnabled = it } } private fun getOrCreateProfileKey(aci: ACI?): ProfileKey { @@ -913,6 +916,27 @@ class AppRegistrationStorageController(private val context: Context) : StorageCo } } + /** + * Restores shared prefs from v1 backups that would otherwise get lost. + */ + private fun restoreLegacySettingsFromSharedPrefs() { + if (LegacySharedPrefs.contains(context, "pref_read_receipts")) { + SignalStore.settings.isReadReceiptsEnabled = LegacySharedPrefs.getBoolean(context, "pref_read_receipts", false) + } + + if (LegacySharedPrefs.contains(context, "pref_typing_indicators")) { + SignalStore.settings.isTypingIndicatorsEnabled = LegacySharedPrefs.getBoolean(context, "pref_typing_indicators", false) + } + + if (LegacySharedPrefs.contains(context, "pref_turn_only")) { + SignalStore.settings.isTurnOnly = LegacySharedPrefs.getBoolean(context, "pref_turn_only", false) + } + + if (LegacySharedPrefs.contains(context, "pref_incognito_keyboard")) { + SignalStore.settings.isIncognitoKeyboardEnabled = LegacySharedPrefs.getBoolean(context, "pref_incognito_keyboard", false) + } + } + private fun readRestoredLocalBackupState(includePreRegistrationKeys: Boolean = false): LocalBackupRestoreProgress.Complete { val restoredPin = SignalStore.svr.pin?.takeIf { it.isNotBlank() } val restoredProfileKey = SignalStore.account.aci 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 da9c108dd7..dcb094e430 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorFragment.java @@ -67,7 +67,6 @@ import org.thoughtcrime.securesms.scribbles.stickers.FeatureSticker; import org.thoughtcrime.securesms.util.MediaUtil; import org.thoughtcrime.securesms.util.SaveAttachmentUtil; import org.thoughtcrime.securesms.util.SystemWindowInsetsSetter; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.ViewUtil; import org.thoughtcrime.securesms.util.views.SimpleProgressDialog; @@ -361,7 +360,7 @@ public final class ImageEditorFragment extends Fragment implements ImageEditorHu TextEntryDialogFragment.Companion.show( getChildFragmentManager(), textElement, - TextSecurePreferences.isIncognitoKeyboardEnabled(requireContext()), + SignalStore.settings().isIncognitoKeyboardEnabled(), selectAll, imageEditorHud.getColorIndex() ); diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/LocalBackupListener.java b/app/src/main/java/org/thoughtcrime/securesms/service/LocalBackupListener.java index 1232f0ad9a..1397dc5f08 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/LocalBackupListener.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/LocalBackupListener.java @@ -8,7 +8,6 @@ import androidx.annotation.NonNull; import org.thoughtcrime.securesms.jobs.LocalBackupJob; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.util.JavaTimeExtensionsKt; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import java.time.LocalDateTime; import java.util.Random; @@ -25,7 +24,7 @@ public class LocalBackupListener extends PersistentAlarmManagerListener { @Override protected long getNextScheduledExecutionTime(Context context) { - return TextSecurePreferences.getNextBackupTime(context); + return SignalStore.settings().getLocalBackupNextTime(); } @Override @@ -55,7 +54,7 @@ public class LocalBackupListener extends PersistentAlarmManagerListener { long nextTime = JavaTimeExtensionsKt.toMillis(next); - TextSecurePreferences.setNextBackupTime(context, nextTime); + SignalStore.settings().setLocalBackupNextTime(nextTime); return nextTime; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/SignalCallManager.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/SignalCallManager.java index b1d893e0a6..fab9f59282 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/SignalCallManager.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/SignalCallManager.java @@ -74,7 +74,6 @@ import org.thoughtcrime.securesms.service.webrtc.links.SignalCallLinkManager; import org.thoughtcrime.securesms.service.webrtc.state.WebRtcEphemeralState; import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState; import org.thoughtcrime.securesms.util.RecipientAccessList; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.rx.RxStore; import org.thoughtcrime.securesms.webrtc.CallNotificationBuilder; import org.thoughtcrime.securesms.webrtc.audio.SignalAudioManager; @@ -1199,7 +1198,7 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall. process((s, p) -> { RemotePeer activePeer = s.getCallInfoState().getActivePeer(); if (activePeer != null && activePeer.getCallId().equals(remotePeer.getCallId())) { - return p.handleTurnServerUpdate(s, servers, TextSecurePreferences.isTurnOnly(context)); + return p.handleTurnServerUpdate(s, servers, SignalStore.settings().isTurnOnly()); } Log.w(TAG, "Ignoring received turn servers for incorrect call id. requesting_call_id: " + remotePeer.getCallId() + " current_call_id: " + (activePeer != null ? activePeer.getCallId() : "null")); diff --git a/app/src/main/java/org/thoughtcrime/securesms/storage/StorageSyncHelper.kt b/app/src/main/java/org/thoughtcrime/securesms/storage/StorageSyncHelper.kt index 0909a210bd..98b0fd5d57 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/storage/StorageSyncHelper.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/storage/StorageSyncHelper.kt @@ -34,7 +34,6 @@ import org.thoughtcrime.securesms.notifications.profiles.NotificationProfileId import org.thoughtcrime.securesms.payments.Entropy import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.Recipient.Companion.self -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.signalservice.api.push.UsernameLinkComponents import org.whispersystems.signalservice.api.storage.SignalAccountRecord import org.whispersystems.signalservice.api.storage.SignalContactRecord @@ -167,9 +166,9 @@ object StorageSyncHelper { avatarUrlPath = self.profileAvatar ?: "" noteToSelfArchived = selfRecord != null && selfRecord.syncExtras.isArchived noteToSelfMarkedUnread = selfRecord != null && selfRecord.syncExtras.isForcedUnread - typingIndicators = TextSecurePreferences.isTypingIndicatorsEnabled(context) - readReceipts = TextSecurePreferences.isReadReceiptsEnabled(context) - sealedSenderIndicators = TextSecurePreferences.isShowUnidentifiedDeliveryIndicatorsEnabled(context) + typingIndicators = SignalStore.settings.isTypingIndicatorsEnabled + readReceipts = SignalStore.settings.isReadReceiptsEnabled + sealedSenderIndicators = SignalStore.settings.isShowUnidentifiedDeliveryIndicatorsEnabled linkPreviews = SignalStore.settings.isLinkPreviewsEnabled unlistedPhoneNumber = SignalStore.phoneNumberPrivacy.phoneNumberDiscoverabilityMode == PhoneNumberDiscoverabilityMode.NOT_DISCOVERABLE phoneNumberSharingMode = StorageSyncModels.localToRemotePhoneNumberSharingMode(SignalStore.phoneNumberPrivacy.phoneNumberSharingMode) @@ -269,9 +268,9 @@ object StorageSyncHelper { fun applyAccountStorageSyncUpdates(context: Context, self: Recipient, update: StorageRecordUpdate, fetchProfile: Boolean) { SignalDatabase.recipients.applyStorageSyncAccountUpdate(update) - TextSecurePreferences.setReadReceiptsEnabled(context, update.new.proto.readReceipts) - TextSecurePreferences.setTypingIndicatorsEnabled(context, update.new.proto.typingIndicators) - TextSecurePreferences.setShowUnidentifiedDeliveryIndicatorsEnabled(context, update.new.proto.sealedSenderIndicators) + SignalStore.settings.isReadReceiptsEnabled = update.new.proto.readReceipts + SignalStore.settings.isTypingIndicatorsEnabled = update.new.proto.typingIndicators + SignalStore.settings.isShowUnidentifiedDeliveryIndicatorsEnabled = update.new.proto.sealedSenderIndicators SignalStore.settings.isLinkPreviewsEnabled = update.new.proto.linkPreviews SignalStore.phoneNumberPrivacy.phoneNumberDiscoverabilityMode = if (update.new.proto.unlistedPhoneNumber) PhoneNumberDiscoverabilityMode.NOT_DISCOVERABLE else PhoneNumberDiscoverabilityMode.DISCOVERABLE SignalStore.phoneNumberPrivacy.phoneNumberSharingMode = StorageSyncModels.remoteToLocalPhoneNumberSharingMode(update.new.proto.phoneNumberSharingMode) diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/AttachmentUtil.kt b/app/src/main/java/org/thoughtcrime/securesms/util/AttachmentUtil.kt index e00447db58..8812a4389c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/AttachmentUtil.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/util/AttachmentUtil.kt @@ -19,6 +19,7 @@ import org.thoughtcrime.securesms.database.SignalDatabase.Companion.threads import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.jobmanager.impl.NotInCallConstraint import org.thoughtcrime.securesms.jobs.MultiDeviceDeleteSyncJob.Companion.enqueueAttachmentDelete +import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.recipients.Recipient import org.whispersystems.signalservice.api.crypto.AttachmentCipherStreamUtil import org.whispersystems.signalservice.internal.crypto.PaddingInputStream @@ -167,9 +168,9 @@ object AttachmentUtil { private fun getAllowedAutoDownloadTypes(context: Context): Set { return when { - NetworkUtil.isConnectedWifi(context) -> TextSecurePreferences.getWifiMediaDownloadAllowed(context) - NetworkUtil.isConnectedRoaming(context) -> TextSecurePreferences.getRoamingMediaDownloadAllowed(context) - NetworkUtil.isConnectedMobile(context) -> TextSecurePreferences.getMobileMediaDownloadAllowed(context) + NetworkUtil.isConnectedWifi(context) -> SignalStore.settings.wifiMediaDownloadAllowed + NetworkUtil.isConnectedRoaming(context) -> SignalStore.settings.roamingMediaDownloadAllowed + NetworkUtil.isConnectedMobile(context) -> SignalStore.settings.mobileMediaDownloadAllowed else -> emptySet() } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java b/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java index 180b917b5f..908e10dc13 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java @@ -6,10 +6,7 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; -import android.net.Uri; -import android.provider.Settings; -import androidx.annotation.ArrayRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.app.NotificationCompat; @@ -17,90 +14,43 @@ import androidx.core.app.NotificationManagerCompat; import androidx.core.content.ContextCompat; import androidx.preference.PreferenceManager; -import org.greenrobot.eventbus.EventBus; import org.signal.core.util.PendingIntentFlags; import org.signal.core.util.logging.Log; import org.signal.libsignal.zkgroup.profiles.ProfileKey; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.backup.proto.SharedPreference; import org.thoughtcrime.securesms.backup.v2.BackupRepository; import org.thoughtcrime.securesms.crypto.ProfileKeyUtil; import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.AppDependencies; -import org.thoughtcrime.securesms.keyvalue.SettingsValues; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.lock.RegistrationLockReminders; import org.thoughtcrime.securesms.notifications.NotificationChannels; import org.thoughtcrime.securesms.notifications.NotificationIds; -import org.thoughtcrime.securesms.preferences.widgets.NotificationPrivacyPreference; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.registration.ui.RegistrationActivity; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - public class TextSecurePreferences { private static final String TAG = Log.tag(TextSecurePreferences.class); - public static final String THEME_PREF = "pref_theme"; - public static final String LANGUAGE_PREF = "pref_language"; public static final String ENABLE_MANUAL_MMS_PREF = "pref_enable_manual_mms"; - public static final String RINGTONE_PREF = "pref_key_ringtone"; - public static final String VIBRATE_PREF = "pref_key_vibrate"; - private static final String NOTIFICATION_PREF = "pref_key_enable_notifications"; - public static final String LED_COLOR_PREF = "pref_led_color"; - public static final String LED_BLINK_PREF = "pref_led_blink"; - private static final String LED_BLINK_PREF_CUSTOM = "pref_led_blink_custom"; - public static final String SCREEN_SECURITY_PREF = "pref_screen_security"; - private static final String ENTER_SENDS_PREF = "pref_enter_sends"; - private static final String SMS_DELIVERY_REPORT_PREF = "pref_delivery_report_sms"; private static final String PROMPTED_PUSH_REGISTRATION_PREF = "pref_prompted_push_registration"; private static final String PROMPTED_OPTIMIZE_DOZE_PREF = "pref_prompted_optimize_doze"; private static final String DIRECTORY_FRESH_TIME_PREF = "pref_directory_refresh_time"; private static final String UPDATE_APK_REFRESH_TIME_PREF = "pref_update_apk_refresh_time"; private static final String SIGNED_PREKEY_ROTATION_TIME_PREF = "pref_signed_pre_key_rotation_time"; - private static final String IN_THREAD_NOTIFICATION_PREF = "pref_key_inthread_notifications"; - private static final String SHOW_INVITE_REMINDER_PREF = "pref_show_invite_reminder"; - public static final String MESSAGE_BODY_TEXT_SIZE_PREF = "pref_message_body_text_size"; - - private static final String WIFI_SMS_PREF = "pref_wifi_sms"; - private static final String RATING_LATER_PREF = "pref_rating_later"; private static final String RATING_ENABLED_PREF = "pref_rating_enabled"; - public static final String REPEAT_ALERTS_PREF = "pref_repeat_alerts"; - public static final String NOTIFICATION_PRIVACY_PREF = "pref_notification_privacy"; - public static final String NOTIFICATION_PRIORITY_PREF = "pref_notification_priority"; - public static final String NEW_CONTACTS_NOTIFICATIONS = "pref_enable_new_contacts_notifications"; - - public static final String MEDIA_DOWNLOAD_MOBILE_PREF = "pref_media_download_mobile"; - public static final String MEDIA_DOWNLOAD_WIFI_PREF = "pref_media_download_wifi"; - public static final String MEDIA_DOWNLOAD_ROAMING_PREF = "pref_media_download_roaming"; - - public static final String SYSTEM_EMOJI_PREF = "pref_system_emoji"; private static final String MULTI_DEVICE_PROVISIONED_PREF = "pref_multi_device"; - public static final String ALWAYS_RELAY_CALLS_PREF = "pref_turn_only"; - public static final String READ_RECEIPTS_PREF = "pref_read_receipts"; - public static final String INCOGNITO_KEYBOARD_PREF = "pref_incognito_keyboard"; public static final String UNAUTHORIZED_RECEIVED = "pref_unauthorized_received"; private static final String SUCCESSFUL_DIRECTORY_PREF = "pref_successful_directory"; - public static final String CALL_NOTIFICATIONS_PREF = "pref_call_notifications"; - public static final String CALL_RINGTONE_PREF = "pref_call_ringtone"; - public static final String CALL_VIBRATE_PREF = "pref_call_vibrate"; - public static final String BACKUP = "pref_backup"; - public static final String BACKUP_ENABLED = "pref_backup_enabled"; private static final String BACKUP_PASSPHRASE = "pref_backup_passphrase"; private static final String ENCRYPTED_BACKUP_PASSPHRASE = "pref_encrypted_backup_passphrase"; - private static final String BACKUP_TIME = "pref_backup_next_time"; @Deprecated public static final String REGISTRATION_LOCK_PREF_V1 = "pref_registration_lock"; @@ -124,17 +74,13 @@ public class TextSecurePreferences { private static final String NEEDS_MESSAGE_PULL = "pref_needs_message_pull"; - public static final String UNIVERSAL_UNIDENTIFIED_ACCESS = "pref_universal_unidentified_access"; - public static final String SHOW_UNIDENTIFIED_DELIVERY_INDICATORS = "pref_show_unidentifed_delivery_indicators"; + private static final String UNIDENTIFIED_ACCESS_CERTIFICATE_ROTATION_TIME_PREF = "pref_unidentified_access_certificate_rotation_time"; private static final String UNIDENTIFIED_DELIVERY_ENABLED = "pref_unidentified_delivery_enabled"; - public static final String TYPING_INDICATORS = "pref_typing_indicators"; - public static final String LINK_PREVIEWS = "pref_link_previews"; private static final String SEEN_STICKER_INTRO_TOOLTIP = "pref_seen_sticker_intro_tooltip"; - private static final String MEDIA_KEYBOARD_MODE = "pref_media_keyboard_mode"; public static final String RECENT_STORAGE_KEY = "pref_recent_emoji2"; private static final String JOB_MANAGER_VERSION = "pref_job_manager_version"; @@ -145,101 +91,8 @@ public class TextSecurePreferences { private static final String HAS_SEEN_VIDEO_RECORDING_TOOLTIP = "camerax.fragment.has.dismissed.video.recording.tooltip"; - private static final String[] booleanPreferencesToBackup = {SCREEN_SECURITY_PREF, - INCOGNITO_KEYBOARD_PREF, - ALWAYS_RELAY_CALLS_PREF, - READ_RECEIPTS_PREF, - TYPING_INDICATORS, - SHOW_UNIDENTIFIED_DELIVERY_INDICATORS, - UNIVERSAL_UNIDENTIFIED_ACCESS, - NOTIFICATION_PREF, - VIBRATE_PREF, - IN_THREAD_NOTIFICATION_PREF, - CALL_NOTIFICATIONS_PREF, - CALL_VIBRATE_PREF, - NEW_CONTACTS_NOTIFICATIONS, - SHOW_INVITE_REMINDER_PREF, - SYSTEM_EMOJI_PREF, - ENTER_SENDS_PREF}; - - private static final String[] stringPreferencesToBackup = {LED_COLOR_PREF, - LED_BLINK_PREF, - REPEAT_ALERTS_PREF, - NOTIFICATION_PRIVACY_PREF, - THEME_PREF, - LANGUAGE_PREF, - MESSAGE_BODY_TEXT_SIZE_PREF}; - - private static final String[] stringSetPreferencesToBackup = {MEDIA_DOWNLOAD_MOBILE_PREF, - MEDIA_DOWNLOAD_WIFI_PREF, - MEDIA_DOWNLOAD_ROAMING_PREF}; - private static volatile SharedPreferences preferences = null; - public static long getPreferencesToSaveToBackupCount(@NonNull Context context) { - SharedPreferences preferences = getSharedPreferences(context); - long count = 0; - - for (String booleanPreference : booleanPreferencesToBackup) { - if (preferences.contains(booleanPreference)) { - count++; - } - } - - for (String stringPreference : stringPreferencesToBackup) { - if (preferences.contains(stringPreference)) { - count++; - } - } - - for (String stringSetPreference : stringSetPreferencesToBackup) { - if (preferences.contains(stringSetPreference)) { - count++; - } - } - - return count; - } - - public static List getPreferencesToSaveToBackup(@NonNull Context context) { - SharedPreferences preferences = getSharedPreferences(context); - List backupProtos = new ArrayList<>(); - String defaultFile = context.getPackageName() + "_preferences"; - - for (String booleanPreference : booleanPreferencesToBackup) { - if (preferences.contains(booleanPreference)) { - backupProtos.add(new SharedPreference.Builder() - .file_(defaultFile) - .key(booleanPreference) - .booleanValue(preferences.getBoolean(booleanPreference, false)) - .build()); - } - } - - for (String stringPreference : stringPreferencesToBackup) { - if (preferences.contains(stringPreference)) { - backupProtos.add(new SharedPreference.Builder() - .file_(defaultFile) - .key(stringPreference) - .value_(preferences.getString(stringPreference, null)) - .build()); - } - } - - for (String stringSetPreference : stringSetPreferencesToBackup) { - if (preferences.contains(stringSetPreference)) { - backupProtos.add(new SharedPreference.Builder() - .file_(defaultFile) - .key(stringSetPreference) - .isStringSetValue(true) - .stringSetValue(new ArrayList<>(preferences.getStringSet(stringSetPreference, Collections.emptySet()))) - .build()); - } - } - - return backupProtos; - } - public static void onPostBackupRestore(@NonNull Context context) { if (NotificationChannels.supported()) { NotificationChannels.getInstance().updateMessageVibrate(SignalStore.settings().isMessageVibrateEnabled()); @@ -313,19 +166,6 @@ public class TextSecurePreferences { return getStringPreference(context, ENCRYPTED_BACKUP_PASSPHRASE, null); } - @Deprecated - public static boolean isBackupEnabled(@NonNull Context context) { - return getBooleanPreference(context, BACKUP_ENABLED, false); - } - - public static void setNextBackupTime(@NonNull Context context, long time) { - setLongPreference(context, BACKUP_TIME, time); - } - - public static long getNextBackupTime(@NonNull Context context) { - return getLongPreference(context, BACKUP_TIME, -1); - } - public static void setHasSuccessfullyRetrievedDirectory(Context context, boolean value) { setBooleanPreference(context, SUCCESSFUL_DIRECTORY_PREF, value); } @@ -353,55 +193,6 @@ public class TextSecurePreferences { return getBooleanPreference(context, UNAUTHORIZED_RECEIVED, false); } - public static boolean isIncognitoKeyboardEnabled(Context context) { - return getBooleanPreference(context, INCOGNITO_KEYBOARD_PREF, false); - } - - public static boolean isReadReceiptsEnabled(Context context) { - return getBooleanPreference(context, READ_RECEIPTS_PREF, false); - } - - public static void setReadReceiptsEnabled(Context context, boolean enabled) { - setBooleanPreference(context, READ_RECEIPTS_PREF, enabled); - } - - public static boolean isTypingIndicatorsEnabled(Context context) { - return getBooleanPreference(context, TYPING_INDICATORS, false); - } - - public static void setTypingIndicatorsEnabled(Context context, boolean enabled) { - setBooleanPreference(context, TYPING_INDICATORS, enabled); - } - - public static int getNotificationPriority(Context context) { - try { - return Integer.parseInt(getStringPreference(context, NOTIFICATION_PRIORITY_PREF, String.valueOf(NotificationCompat.PRIORITY_HIGH))); - } catch (ClassCastException e) { - return getIntegerPreference(context, NOTIFICATION_PRIORITY_PREF, NotificationCompat.PRIORITY_HIGH); - } - } - - /** - * @deprecated Use {@link SettingsValues#getMessageFontSize()} via {@link org.thoughtcrime.securesms.keyvalue.SignalStore} instead. - */ - @Deprecated - public static int getMessageBodyTextSize(Context context) { - return Integer.parseInt(getStringPreference(context, MESSAGE_BODY_TEXT_SIZE_PREF, "16")); - } - - public static boolean isTurnOnly(Context context) { - return getBooleanPreference(context, ALWAYS_RELAY_CALLS_PREF, false); - } - - @Deprecated - public static NotificationPrivacyPreference getNotificationPrivacy(Context context) { - return new NotificationPrivacyPreference(getStringPreference(context, NOTIFICATION_PRIVACY_PREF, "all")); - } - - public static boolean isNewContactsNotificationEnabled(Context context) { - return getBooleanPreference(context, NEW_CONTACTS_NOTIFICATIONS, false); - } - public static long getRatingLaterTimestamp(Context context) { return getLongPreference(context, RATING_LATER_PREF, 0); } @@ -418,40 +209,12 @@ public class TextSecurePreferences { setBooleanPreference(context, RATING_ENABLED_PREF, enabled); } - @Deprecated - public static boolean isWifiSmsEnabled(Context context) { - return getBooleanPreference(context, WIFI_SMS_PREF, false); + public static long getUnidentifiedAccessCertificateRotationTime(Context context) { + return getLongPreference(context, UNIDENTIFIED_ACCESS_CERTIFICATE_ROTATION_TIME_PREF, 0L); } - @Deprecated - public static int getRepeatAlertsCount(Context context) { - try { - return Integer.parseInt(getStringPreference(context, REPEAT_ALERTS_PREF, "0")); - } catch (NumberFormatException e) { - Log.w(TAG, e); - return 0; - } - } - - @Deprecated - public static boolean isInThreadNotifications(Context context) { - return getBooleanPreference(context, IN_THREAD_NOTIFICATION_PREF, true); - } - - public static boolean isUniversalUnidentifiedAccess(Context context) { - return getBooleanPreference(context, UNIVERSAL_UNIDENTIFIED_ACCESS, false); - } - - public static void setIsUniversalUnidentifiedAccess(Context context, boolean enabled) { - setBooleanPreference(context, UNIVERSAL_UNIDENTIFIED_ACCESS, enabled); - } - - public static void setShowUnidentifiedDeliveryIndicatorsEnabled(Context context, boolean enabled) { - setBooleanPreference(context, SHOW_UNIDENTIFIED_DELIVERY_INDICATORS, enabled); - } - - public static boolean isShowUnidentifiedDeliveryIndicatorsEnabled(Context context) { - return getBooleanPreference(context, SHOW_UNIDENTIFIED_DELIVERY_INDICATORS, false); + public static void setUnidentifiedAccessCertificateRotationTime(Context context, long value) { + setLongPreference(context, UNIDENTIFIED_ACCESS_CERTIFICATE_ROTATION_TIME_PREF, value); } public static void setIsUnidentifiedDeliveryEnabled(Context context, boolean enabled) { @@ -482,36 +245,10 @@ public class TextSecurePreferences { setLongPreference(context, UPDATE_APK_REFRESH_TIME_PREF, value); } - @Deprecated - public static boolean isEnterSendsEnabled(Context context) { - return getBooleanPreference(context, ENTER_SENDS_PREF, false); - } - - public static void setScreenSecurityEnabled(Context context, boolean value) { - setBooleanPreference(context, SCREEN_SECURITY_PREF, value); - } - - public static boolean isScreenSecurityEnabled(Context context) { - return getBooleanPreference(context, SCREEN_SECURITY_PREF, false); - } - public static boolean isLegacyUseLocalApnsEnabled(Context context) { return getBooleanPreference(context, ENABLE_MANUAL_MMS_PREF, false); } - /** - * @deprecated Use {@link SettingsValues#getTheme()} via {@link org.thoughtcrime.securesms.keyvalue.SignalStore} instead. - */ - @Deprecated - public static String getTheme(Context context) { - return getStringPreference(context, THEME_PREF, DynamicTheme.systemThemeAvailable() ? "system" : "light"); - } - - @Deprecated - public static boolean isSmsDeliveryReportsEnabled(Context context) { - return getBooleanPreference(context, SMS_DELIVERY_REPORT_PREF, false); - } - public static boolean hasPromptedPushRegistration(Context context) { return getBooleanPreference(context, PROMPTED_PUSH_REGISTRATION_PREF, false); } @@ -528,91 +265,6 @@ public class TextSecurePreferences { return getBooleanPreference(context, PROMPTED_OPTIMIZE_DOZE_PREF, false); } - @Deprecated - public static boolean isNotificationsEnabled(Context context) { - return getBooleanPreference(context, NOTIFICATION_PREF, true); - } - - @Deprecated - public static boolean isCallNotificationsEnabled(Context context) { - return getBooleanPreference(context, CALL_NOTIFICATIONS_PREF, true); - } - - @Deprecated - public static @NonNull Uri getNotificationRingtone(Context context) { - String 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); - } - - @Deprecated - public static @NonNull Uri getCallNotificationRingtone(Context context) { - String result = getStringPreference(context, CALL_RINGTONE_PREF, Settings.System.DEFAULT_RINGTONE_URI.toString()); - - if (result != null && result.startsWith("file:")) { - result = Settings.System.DEFAULT_RINGTONE_URI.toString(); - } - - return Uri.parse(result); - } - - @Deprecated - public static boolean isNotificationVibrateEnabled(Context context) { - return getBooleanPreference(context, VIBRATE_PREF, true); - } - - @Deprecated - public static boolean isCallNotificationVibrateEnabled(Context context) { - boolean defaultValue = (Settings.System.getInt(context.getContentResolver(), Settings.System.VIBRATE_WHEN_RINGING, 1) == 1); - - return getBooleanPreference(context, CALL_VIBRATE_PREF, defaultValue); - } - - @Deprecated - public static String getNotificationLedColor(Context context) { - return getStringPreference(context, LED_COLOR_PREF, "blue"); - } - - @Deprecated - public static String getNotificationLedPattern(Context context) { - return getStringPreference(context, LED_BLINK_PREF, "500,2000"); - } - - public static String getNotificationLedPatternCustom(Context context) { - return getStringPreference(context, LED_BLINK_PREF_CUSTOM, "500,2000"); - } - - public static void setNotificationLedPatternCustom(Context context, String pattern) { - setStringPreference(context, LED_BLINK_PREF_CUSTOM, pattern); - } - - @Deprecated - public static boolean isSystemEmojiPreferred(Context context) { - return getBooleanPreference(context, SYSTEM_EMOJI_PREF, false); - } - - public static @NonNull Set getMobileMediaDownloadAllowed(Context context) { - return getMediaDownloadAllowed(context, MEDIA_DOWNLOAD_MOBILE_PREF, R.array.pref_media_download_mobile_data_default); - } - - public static @NonNull Set getWifiMediaDownloadAllowed(Context context) { - return getMediaDownloadAllowed(context, MEDIA_DOWNLOAD_WIFI_PREF, R.array.pref_media_download_wifi_default); - } - - public static @NonNull Set getRoamingMediaDownloadAllowed(Context context) { - return getMediaDownloadAllowed(context, MEDIA_DOWNLOAD_ROAMING_PREF, R.array.pref_media_download_roaming_default); - } - - private static @NonNull Set getMediaDownloadAllowed(Context context, String key, @ArrayRes int defaultValuesRes) { - return getStringSetPreference(context, - key, - new HashSet<>(Arrays.asList(context.getResources().getStringArray(defaultValuesRes)))); - } - public static void setLastOutageCheckTime(Context context, long timestamp) { setLongPreference(context, LAST_OUTAGE_CHECK_TIME, timestamp); } @@ -693,15 +345,6 @@ public class TextSecurePreferences { setBooleanPreference(context, SEEN_STICKER_INTRO_TOOLTIP, seenStickerTooltip); } - public static void setMediaKeyboardMode(Context context, MediaKeyboardMode mode) { - setStringPreference(context, MEDIA_KEYBOARD_MODE, mode.name()); - } - - public static MediaKeyboardMode getMediaKeyboardMode(Context context) { - String name = getStringPreference(context, MEDIA_KEYBOARD_MODE, MediaKeyboardMode.EMOJI.name()); - return MediaKeyboardMode.valueOf(name); - } - public static void setJobManagerVersion(Context context, int version) { setIntegerPrefrence(context, JOB_MANAGER_VERSION, version); } @@ -770,15 +413,6 @@ public class TextSecurePreferences { getSharedPreferences(context).edit().remove(key).apply(); } - private static Set getStringSetPreference(Context context, String key, Set defaultValues) { - final SharedPreferences prefs = getSharedPreferences(context); - if (prefs.contains(key)) { - return prefs.getStringSet(key, Collections.emptySet()); - } else { - return defaultValues; - } - } - private static void clearLocalCredentials(Context context) { ProfileKey newProfileKey = ProfileKeyUtil.createNew(); Recipient self = Recipient.self(); @@ -818,7 +452,4 @@ public class TextSecurePreferences { } // NEVER rename these -- they're persisted by name - public enum MediaKeyboardMode { - EMOJI, STICKER, GIF - } } diff --git a/app/src/test/java/org/thoughtcrime/securesms/notifications/MarkReadReceiverTest.kt b/app/src/test/java/org/thoughtcrime/securesms/notifications/MarkReadReceiverTest.kt index 720830a31c..ae820b5a68 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/notifications/MarkReadReceiverTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/notifications/MarkReadReceiverTest.kt @@ -3,7 +3,6 @@ package org.thoughtcrime.securesms.notifications import android.app.Application import io.mockk.every import io.mockk.mockkObject -import io.mockk.mockkStatic import io.mockk.unmockkAll import org.junit.After import org.junit.Assert @@ -23,10 +22,10 @@ import org.thoughtcrime.securesms.jobmanager.Job import org.thoughtcrime.securesms.jobmanager.JobManager import org.thoughtcrime.securesms.jobmanager.JsonJobData import org.thoughtcrime.securesms.jobs.MultiDeviceReadUpdateJob +import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.testutil.MockAppDependenciesRule -import org.thoughtcrime.securesms.util.TextSecurePreferences import java.util.LinkedList @RunWith(RobolectricTestRunner::class) @@ -46,8 +45,8 @@ class MarkReadReceiverTest { mockkObject(Recipient) every { Recipient.self() } returns Recipient() - mockkStatic(TextSecurePreferences::class) - every { TextSecurePreferences.isReadReceiptsEnabled(any()) } returns true + mockkObject(SignalStore) + every { SignalStore.settings.isReadReceiptsEnabled } returns true } @After diff --git a/app/src/test/java/org/thoughtcrime/securesms/registration/v2/AppRegistrationStorageControllerTest.kt b/app/src/test/java/org/thoughtcrime/securesms/registration/v2/AppRegistrationStorageControllerTest.kt index 70ab495b3e..b58ac55fac 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/registration/v2/AppRegistrationStorageControllerTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/registration/v2/AppRegistrationStorageControllerTest.kt @@ -213,7 +213,7 @@ class AppRegistrationStorageControllerTest { assertThat(SignalStore.account.restoredAccountEntropyPool).isFalse() assertThat(SignalStore.account.restoredAccountEntropyPoolFromPrimary).isTrue() assertThat(SignalStore.backup.mediaRootBackupKey.value).isEqualTo(mediaRootBackupKey) - assertThat(TextSecurePreferences.isReadReceiptsEnabled(context)).isTrue() + assertThat(SignalStore.settings.isReadReceiptsEnabled).isTrue() assertThat(SignalStore.svr.pin).isNull() assertThat(SignalStore.svr.hasOptedOut()).isFalse() diff --git a/app/src/test/java/org/thoughtcrime/securesms/util/AttachmentUtilTest.kt b/app/src/test/java/org/thoughtcrime/securesms/util/AttachmentUtilTest.kt index 220957a372..b6502cb364 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/util/AttachmentUtilTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/util/AttachmentUtilTest.kt @@ -25,6 +25,7 @@ import org.thoughtcrime.securesms.database.ThreadTable import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.jobmanager.impl.NotInCallConstraint import org.thoughtcrime.securesms.jobs.MultiDeviceDeleteSyncJob +import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.stickers.StickerLocator @@ -49,7 +50,7 @@ class AttachmentUtilTest { mockkStatic(NotInCallConstraint::class) mockkStatic(NetworkUtil::class) - mockkStatic(TextSecurePreferences::class) + mockkObject(SignalStore) mockkObject(MultiDeviceDeleteSyncJob.Companion) every { MultiDeviceDeleteSyncJob.enqueueAttachmentDelete(any(), any()) } just Runs @@ -57,9 +58,9 @@ class AttachmentUtilTest { every { NetworkUtil.isConnectedWifi(context) } returns true every { NetworkUtil.isConnectedRoaming(context) } returns false every { NetworkUtil.isConnectedMobile(context) } returns false - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns emptySet() - every { TextSecurePreferences.getRoamingMediaDownloadAllowed(context) } returns emptySet() - every { TextSecurePreferences.getMobileMediaDownloadAllowed(context) } returns emptySet() + every { SignalStore.settings.wifiMediaDownloadAllowed } returns emptySet() + every { SignalStore.settings.roamingMediaDownloadAllowed } returns emptySet() + every { SignalStore.settings.mobileMediaDownloadAllowed } returns emptySet() every { messageTable.getMessageRecord(any()) } returns messageRecord every { messageRecord.fromRecipient } returns fromRecipient @@ -104,7 +105,7 @@ class AttachmentUtilTest { every { toRecipient.isGroup } returns true every { toRecipient.isProfileSharing } returns true every { fromRecipient.isSystemContact } returns false - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns setOf("image") + every { SignalStore.settings.wifiMediaDownloadAllowed } returns setOf("image") assertTrue(AttachmentUtil.isAutoDownloadPermitted(context, attachment())) } @@ -125,7 +126,7 @@ class AttachmentUtilTest { @Test fun `null toRecipient falls to individual trust`() { every { threadTable.getRecipientForThreadId(any()) } returns null - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns setOf("image") + every { SignalStore.settings.wifiMediaDownloadAllowed } returns setOf("image") assertTrue(AttachmentUtil.isAutoDownloadPermitted(context, attachment())) } @@ -134,7 +135,7 @@ class AttachmentUtilTest { fun `profile sharing from recipient is trusted`() { every { fromRecipient.isSystemContact } returns false every { fromRecipient.isProfileSharing } returns true - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns setOf("image") + every { SignalStore.settings.wifiMediaDownloadAllowed } returns setOf("image") assertTrue(AttachmentUtil.isAutoDownloadPermitted(context, attachment())) } @@ -142,7 +143,7 @@ class AttachmentUtilTest { @Test fun `video gif blocked when in call`() { val attachment = attachment(videoGif = true, contentType = "video/mp4") - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns setOf("image") + every { SignalStore.settings.wifiMediaDownloadAllowed } returns setOf("image") every { NotInCallConstraint.isNotInConnectedCall() } returns false assertFalse(AttachmentUtil.isAutoDownloadPermitted(context, attachment)) @@ -151,7 +152,7 @@ class AttachmentUtilTest { @Test fun `document blocked when in call`() { val attachment = attachment(contentType = "application/pdf", fileName = "doc.pdf") - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns setOf("documents") + every { SignalStore.settings.wifiMediaDownloadAllowed } returns setOf("documents") every { NotInCallConstraint.isNotInConnectedCall() } returns false assertFalse(AttachmentUtil.isAutoDownloadPermitted(context, attachment)) } @@ -163,7 +164,7 @@ class AttachmentUtilTest { every { fromRecipient.isSystemContact } returns false every { fromRecipient.isProfileSharing } returns false every { messageRecord.isOutgoing } returns true - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns setOf("image") + every { SignalStore.settings.wifiMediaDownloadAllowed } returns setOf("image") assertTrue(AttachmentUtil.isAutoDownloadPermitted(context, attachment())) } @@ -172,7 +173,7 @@ class AttachmentUtilTest { fun `outgoing message is trusted`() { every { fromRecipient.isSystemContact } returns false every { messageRecord.isOutgoing } returns true - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns setOf("image") + every { SignalStore.settings.wifiMediaDownloadAllowed } returns setOf("image") assertTrue(AttachmentUtil.isAutoDownloadPermitted(context, attachment())) } @@ -181,7 +182,7 @@ class AttachmentUtilTest { fun `self recipient is trusted`() { every { fromRecipient.isSystemContact } returns false every { fromRecipient.isSelf } returns true - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns setOf("image") + every { SignalStore.settings.wifiMediaDownloadAllowed } returns setOf("image") assertTrue(AttachmentUtil.isAutoDownloadPermitted(context, attachment())) } @@ -190,21 +191,21 @@ class AttachmentUtilTest { fun `release notes recipient is trusted`() { every { fromRecipient.isSystemContact } returns false every { fromRecipient.isReleaseNotes } returns true - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns setOf("image") + every { SignalStore.settings.wifiMediaDownloadAllowed } returns setOf("image") assertTrue(AttachmentUtil.isAutoDownloadPermitted(context, attachment())) } @Test fun `zero size rejects`() { - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns setOf("image") + every { SignalStore.settings.wifiMediaDownloadAllowed } returns setOf("image") assertFalse(AttachmentUtil.isAutoDownloadPermitted(context, attachment(size = 0L, contentType = "image/jpeg"))) } @Test fun `ciphertext over 200MB rejects`() { val huge = attachment(size = 250L * 1024 * 1024, contentType = "image/jpeg") - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns setOf("image") + every { SignalStore.settings.wifiMediaDownloadAllowed } returns setOf("image") assertFalse(AttachmentUtil.isAutoDownloadPermitted(context, huge)) } @@ -232,7 +233,7 @@ class AttachmentUtilTest { @Test fun `large sticker requires image allowed type`() { val attachment = attachment(size = 500L * 1024, isSticker = true, contentType = "image/webp") - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns setOf("image") + every { SignalStore.settings.wifiMediaDownloadAllowed } returns setOf("image") assertTrue(AttachmentUtil.isAutoDownloadPermitted(context, attachment)) } @@ -240,7 +241,7 @@ class AttachmentUtilTest { @Test fun `large sticker blocked when in call`() { val attachment = attachment(size = 500L * 1024, isSticker = true, contentType = "image/webp") - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns setOf("image") + every { SignalStore.settings.wifiMediaDownloadAllowed } returns setOf("image") every { NotInCallConstraint.isNotInConnectedCall() } returns false assertFalse(AttachmentUtil.isAutoDownloadPermitted(context, attachment)) @@ -249,7 +250,7 @@ class AttachmentUtilTest { @Test fun `large sticker blocked when image type not allowed`() { val attachment = attachment(size = 500L * 1024, isSticker = true, contentType = "image/webp") - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns setOf("audio") + every { SignalStore.settings.wifiMediaDownloadAllowed } returns setOf("audio") assertFalse(AttachmentUtil.isAutoDownloadPermitted(context, attachment)) } @@ -263,27 +264,27 @@ class AttachmentUtilTest { @Test fun `unnamed audio without voice note flag uses audio setting`() { val attachment = attachment(size = 10L * 1024, voiceNote = false, contentType = "audio/aac", fileName = null) - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns setOf("audio") + every { SignalStore.settings.wifiMediaDownloadAllowed } returns setOf("audio") assertTrue(AttachmentUtil.isAutoDownloadPermitted(context, attachment)) - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns emptySet() + every { SignalStore.settings.wifiMediaDownloadAllowed } returns emptySet() assertFalse(AttachmentUtil.isAutoDownloadPermitted(context, attachment)) } @Test fun `named audio uses audio setting`() { val attachment = attachment(size = 10L * 1024, voiceNote = false, contentType = "audio/mpeg", fileName = "song.mp3") - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns setOf("audio") + every { SignalStore.settings.wifiMediaDownloadAllowed } returns setOf("audio") assertTrue(AttachmentUtil.isAutoDownloadPermitted(context, attachment)) - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns emptySet() + every { SignalStore.settings.wifiMediaDownloadAllowed } returns emptySet() assertFalse(AttachmentUtil.isAutoDownloadPermitted(context, attachment)) } @Test fun `large voice note requires audio allowed type`() { val attachment = attachment(size = 500L * 1024, voiceNote = true, contentType = "audio/aac", fileName = null) - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns setOf("audio") + every { SignalStore.settings.wifiMediaDownloadAllowed } returns setOf("audio") assertTrue(AttachmentUtil.isAutoDownloadPermitted(context, attachment)) } @@ -291,7 +292,7 @@ class AttachmentUtilTest { @Test fun `large voice note blocked when audio not allowed`() { val attachment = attachment(size = 500L * 1024, voiceNote = true, contentType = "audio/aac", fileName = null) - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns setOf("image") + every { SignalStore.settings.wifiMediaDownloadAllowed } returns setOf("image") assertFalse(AttachmentUtil.isAutoDownloadPermitted(context, attachment)) } @@ -299,7 +300,7 @@ class AttachmentUtilTest { @Test fun `large voice note blocked when in call`() { val attachment = attachment(size = 500L * 1024, voiceNote = true, contentType = "audio/aac", fileName = null) - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns setOf("audio") + every { SignalStore.settings.wifiMediaDownloadAllowed } returns setOf("audio") every { NotInCallConstraint.isNotInConnectedCall() } returns false assertFalse(AttachmentUtil.isAutoDownloadPermitted(context, attachment)) @@ -308,51 +309,51 @@ class AttachmentUtilTest { @Test fun `video gif requires image allowed type`() { val attachment = attachment(videoGif = true, contentType = "video/mp4") - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns setOf("image") + every { SignalStore.settings.wifiMediaDownloadAllowed } returns setOf("image") assertTrue(AttachmentUtil.isAutoDownloadPermitted(context, attachment)) - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns emptySet() + every { SignalStore.settings.wifiMediaDownloadAllowed } returns emptySet() assertFalse(AttachmentUtil.isAutoDownloadPermitted(context, attachment)) } @Test fun `image content type uses image setting`() { val attachment = attachment(contentType = "image/jpeg") - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns setOf("image") + every { SignalStore.settings.wifiMediaDownloadAllowed } returns setOf("image") assertTrue(AttachmentUtil.isAutoDownloadPermitted(context, attachment)) - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns emptySet() + every { SignalStore.settings.wifiMediaDownloadAllowed } returns emptySet() assertFalse(AttachmentUtil.isAutoDownloadPermitted(context, attachment)) } @Test fun `video content type uses video setting`() { val attachment = attachment(contentType = "video/mp4") - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns setOf("video") + every { SignalStore.settings.wifiMediaDownloadAllowed } returns setOf("video") assertTrue(AttachmentUtil.isAutoDownloadPermitted(context, attachment)) } @Test fun `document content type uses documents setting`() { val attachment = attachment(contentType = "application/pdf", fileName = "doc.pdf") - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns setOf("documents") + every { SignalStore.settings.wifiMediaDownloadAllowed } returns setOf("documents") assertTrue(AttachmentUtil.isAutoDownloadPermitted(context, attachment)) - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns emptySet() + every { SignalStore.settings.wifiMediaDownloadAllowed } returns emptySet() assertFalse(AttachmentUtil.isAutoDownloadPermitted(context, attachment)) } @Test fun `null content type falls to documents setting`() { val attachment = attachment(contentType = null, fileName = "file") - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns setOf("documents") + every { SignalStore.settings.wifiMediaDownloadAllowed } returns setOf("documents") assertTrue(AttachmentUtil.isAutoDownloadPermitted(context, attachment)) } @Test fun `in-call blocks non-sticker paths`() { every { NotInCallConstraint.isNotInConnectedCall() } returns false - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns setOf("image", "video", "audio", "documents") + every { SignalStore.settings.wifiMediaDownloadAllowed } returns setOf("image", "video", "audio", "documents") assertFalse(AttachmentUtil.isAutoDownloadPermitted(context, attachment(contentType = "image/jpeg"))) assertFalse(AttachmentUtil.isAutoDownloadPermitted(context, attachment(contentType = "application/pdf", fileName = "a.pdf"))) @@ -362,7 +363,7 @@ class AttachmentUtilTest { fun `roaming network uses roaming allowed set`() { every { NetworkUtil.isConnectedWifi(context) } returns false every { NetworkUtil.isConnectedRoaming(context) } returns true - every { TextSecurePreferences.getRoamingMediaDownloadAllowed(context) } returns setOf("image") + every { SignalStore.settings.roamingMediaDownloadAllowed } returns setOf("image") assertTrue(AttachmentUtil.isAutoDownloadPermitted(context, attachment(contentType = "image/jpeg"))) } @@ -372,7 +373,7 @@ class AttachmentUtilTest { every { NetworkUtil.isConnectedWifi(context) } returns false every { NetworkUtil.isConnectedRoaming(context) } returns false every { NetworkUtil.isConnectedMobile(context) } returns true - every { TextSecurePreferences.getMobileMediaDownloadAllowed(context) } returns setOf("image") + every { SignalStore.settings.mobileMediaDownloadAllowed } returns setOf("image") assertTrue(AttachmentUtil.isAutoDownloadPermitted(context, attachment(contentType = "image/jpeg"))) } @@ -433,20 +434,20 @@ class AttachmentUtilTest { @Test fun `restore image permitted when allowed and not in call`() { - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns setOf("image") + every { SignalStore.settings.wifiMediaDownloadAllowed } returns setOf("image") assertTrue(AttachmentUtil.isRestoreOnOpenPermitted(context, attachment(contentType = "image/jpeg"))) } @Test fun `restore image blocked when in call`() { - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns setOf("image") + every { SignalStore.settings.wifiMediaDownloadAllowed } returns setOf("image") every { NotInCallConstraint.isNotInConnectedCall() } returns false assertFalse(AttachmentUtil.isRestoreOnOpenPermitted(context, attachment(contentType = "image/jpeg"))) } @Test fun `restore image blocked when type not allowed`() { - every { TextSecurePreferences.getWifiMediaDownloadAllowed(context) } returns emptySet() + every { SignalStore.settings.wifiMediaDownloadAllowed } returns emptySet() assertFalse(AttachmentUtil.isRestoreOnOpenPermitted(context, attachment(contentType = "image/jpeg"))) } diff --git a/core/ui/src/main/java/org/signal/core/ui/CoreUiDependencies.kt b/core/ui/src/main/java/org/signal/core/ui/CoreUiDependencies.kt index 38e3b5273c..ab1a273161 100644 --- a/core/ui/src/main/java/org/signal/core/ui/CoreUiDependencies.kt +++ b/core/ui/src/main/java/org/signal/core/ui/CoreUiDependencies.kt @@ -6,6 +6,7 @@ package org.signal.core.ui import android.app.Application +import androidx.annotation.VisibleForTesting object CoreUiDependencies { @@ -21,6 +22,15 @@ object CoreUiDependencies { _provider = provider } + /** + * Replaces any existing provider, unlike [init]. Only for use in tests. + */ + @VisibleForTesting + fun testInject(application: Application, provider: Provider) { + _application = application + _provider = provider + } + val application: Application get() = _application diff --git a/core/ui/src/testFixtures/java/org/signal/core/ui/CoreUiDependenciesRule.kt b/core/ui/src/testFixtures/java/org/signal/core/ui/CoreUiDependenciesRule.kt index ddae7f75be..6eb8c32b34 100644 --- a/core/ui/src/testFixtures/java/org/signal/core/ui/CoreUiDependenciesRule.kt +++ b/core/ui/src/testFixtures/java/org/signal/core/ui/CoreUiDependenciesRule.kt @@ -17,7 +17,7 @@ class CoreUiDependenciesRule( private val isIncognitoKeyboardEnabled: Boolean = false ) : ExternalResource() { override fun before() { - CoreUiDependencies.init(application, Provider(isIncognitoKeyboardEnabled)) + CoreUiDependencies.testInject(application, Provider(isIncognitoKeyboardEnabled)) } private class Provider(