From d57b928c6f63c08aa6cdbe309b54f2f89e300555 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Tue, 22 Sep 2026 13:28:24 -0400 Subject: [PATCH] Remove TextSecurePreferences. --- ...umentationApplicationDependencyProvider.kt | 2 +- .../jobs/JobManagerPerformanceTests.kt | 4 +- .../org/signal/benchmark/setup/TestUsers.kt | 5 +- .../securesms/AppInitialization.java | 14 +- .../securesms/ApplicationContext.java | 7 +- .../ContactSelectionListFragment.java | 5 +- .../securesms/PassphraseRequiredActivity.java | 5 +- .../apkupdate/ApkUpdateRefreshListener.java | 6 +- .../securesms/backup/BackupDialog.java | 4 +- .../securesms/backup/BackupPassphrase.java | 55 --- .../securesms/backup/FullBackupExporter.java | 1 - .../securesms/backup/v2/BackupRepository.kt | 3 +- .../processor/AccountDataArchiveProcessor.kt | 2 - .../securesms/banner/banners/DozeBanner.kt | 5 +- .../banner/banners/ServiceOutageBanner.kt | 4 +- .../banner/banners/UnauthorizedBanner.kt | 3 +- .../components/CustomDefaultPreference.java | 260 ---------- .../securesms/components/RatingManager.java | 12 +- .../emoji/RecentEmojiPageModel.java | 3 + .../settings/app/AppSettingsViewModel.kt | 6 +- .../app/account/AccountSettingsRepository.kt | 4 +- .../backups/local/LocalBackupsViewModel.kt | 6 +- .../remote/RemoteBackupsSettingsViewModel.kt | 3 +- .../app/chats/ChatsSettingsViewModel.kt | 3 +- .../ConversationSettingsRepository.kt | 3 +- .../contacts/sync/ContactDiscovery.kt | 5 +- .../ui/inlinequery/InlineQueryViewModel.kt | 3 +- .../ui/inlinequery/InlineQueryViewModelV2.kt | 3 +- .../conversation/v2/ConversationFragment.kt | 13 +- .../conversation/v2/ConversationTooltips.kt | 4 +- .../conversation/v2/ConversationViewModel.kt | 3 +- .../ConversationListFragment.java | 3 +- .../SignalServiceAccountDataStoreImpl.java | 1 - .../securesms/database/ThreadTable.kt | 2 +- .../ApplicationDependencyProvider.java | 7 +- .../newdevice/NewDeviceServerTask.java | 3 +- .../securesms/jobmanager/JobManager.java | 4 +- .../jobs/ArchiveBackupIdReservationJob.kt | 3 +- .../securesms/jobs/BackupMessagesJob.kt | 3 +- .../securesms/jobs/CheckKeyTransparencyJob.kt | 5 +- .../jobs/CheckServiceReachabilityJob.kt | 6 +- .../securesms/jobs/FcmRefreshJob.java | 3 +- .../securesms/jobs/LocalBackupJob.java | 4 +- .../securesms/jobs/LocalBackupJobApi29.java | 3 +- .../jobs/MultiDeviceContactUpdateJob.java | 9 +- .../MultiDeviceProfileContentUpdateJob.java | 1 - .../MultiDeviceStickerPackOperationJob.java | 1 - .../MultiDeviceStorageSyncRequestJob.java | 1 - .../securesms/jobs/RefreshAttributesJob.java | 3 +- .../jobs/RefreshSvrCredentialsJob.kt | 5 +- .../securesms/jobs/RemoteConfigRefreshJob.kt | 3 +- .../securesms/jobs/RetrieveProfileJob.kt | 2 +- .../securesms/jobs/RotateCertificateJob.java | 3 +- .../jobs/ServiceOutageDetectionJob.java | 14 +- .../jobs/StorageAccountRestoreJob.kt | 2 +- .../securesms/jobs/StorageForcePushJob.kt | 2 +- .../securesms/jobs/StorageSyncJob.kt | 7 +- .../securesms/jobs/Svr2MirrorJob.kt | 3 +- .../emoji/EmojiKeyboardPageRepository.kt | 3 +- .../emoji/EmojiKeyboardPageViewModel.kt | 3 +- .../emoji/search/EmojiSearchRepository.kt | 3 +- .../securesms/keyvalue/AccountValues.kt | 67 ++- .../securesms/keyvalue/ApkUpdateValues.kt | 20 +- .../securesms/keyvalue/BackupValues.kt | 51 +- .../securesms/keyvalue/CertificateValues.java | 9 +- .../securesms/keyvalue/LegacySharedPrefs.kt | 4 + .../securesms/keyvalue/MiscellaneousValues.kt | 80 +++- .../securesms/keyvalue/PinValues.java | 63 ++- .../securesms/keyvalue/RegistrationValues.kt | 21 +- .../securesms/keyvalue/SettingsValues.kt | 33 ++ .../securesms/keyvalue/SignalStore.kt | 17 +- .../securesms/keyvalue/TooltipValues.java | 40 +- .../securesms/keyvalue/UiHintValues.java | 28 +- .../lock/RegistrationLockReminders.java | 16 +- .../logsubmit/LogSectionKeyPreferences.java | 3 +- .../securesms/logsubmit/LogSectionPin.java | 2 +- .../logsubmit/LogSectionSystemInfo.kt | 3 +- .../securesms/megaphone/Megaphones.java | 15 +- .../megaphone/SignalPinReminderSchedule.java | 2 +- .../messages/DataMessageProcessor.kt | 8 +- .../messages/EditMessageProcessor.kt | 2 +- .../messages/IncomingMessageObserver.kt | 7 +- .../messages/MessageContentProcessor.kt | 1 - .../messages/ReceiptMessageProcessor.kt | 9 +- .../messages/SyncMessageProcessor.kt | 8 +- .../ApplyUnknownFieldsToSelfMigrationJob.java | 2 +- .../migrations/LegacyMigrationJob.java | 3 +- .../StorageCapabilityMigrationJob.java | 1 - .../StorageServiceMigrationJob.java | 1 - .../UserNotificationMigrationJob.java | 3 +- .../net/SignalWebSocketHealthMonitor.kt | 6 +- .../notifications/NotificationChannels.java | 15 +- .../notifications/UnregisteredNotifier.kt | 61 +++ .../notifications/VitalsViewModel.kt | 3 +- .../BackupsPreferenceFragment.java | 3 +- .../CorrectedPreferenceFragment.java | 82 ---- .../ListSummaryPreferenceFragment.java | 29 -- .../profiles/manage/EditProfileViewModel.java | 3 +- .../securesms/providers/AvatarProvider.kt | 2 +- ...WithAnyEmojiBottomSheetDialogFragment.java | 4 +- .../any/ReactWithAnyEmojiViewModel.java | 3 +- .../securesms/recipients/LiveRecipient.java | 7 +- .../recipients/LiveRecipientCache.java | 17 +- .../securesms/recipients/RecipientCreator.kt | 10 +- .../bottomsheet/RecipientDialogViewModel.java | 3 +- .../data/RegistrationRepository.kt | 8 +- .../ui/restore/RemoteRestoreActivity.kt | 3 +- .../v2/AppRegistrationStorageController.kt | 35 +- .../securesms/restore/RestoreActivity.kt | 3 +- .../securesms/restore/RestoreRepository.kt | 3 +- .../RestoreLocalBackupFragment.kt | 5 +- .../service/DirectoryRefreshListener.java | 7 +- .../service/RotateSignedPreKeyListener.java | 5 +- .../storage/AccountRecordProcessor.kt | 9 +- .../securesms/storage/StorageSyncHelper.kt | 11 +- .../securesms/util/BackupUtil.java | 3 +- .../securesms/util/SupportEmailUtil.java | 7 +- .../securesms/util/TextSecurePreferences.java | 446 ------------------ app/src/main/res/values/attrs.xml | 3 - .../securesms/database/RecipientTableTest.kt | 6 +- .../securesms/jobs/StorageSyncJobTest.kt | 4 +- .../AppRegistrationStorageControllerTest.kt | 5 +- .../securesms/testutil/RecipientTestRule.kt | 7 +- 123 files changed, 658 insertions(+), 1247 deletions(-) delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/backup/BackupPassphrase.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/components/CustomDefaultPreference.java create mode 100644 app/src/main/java/org/thoughtcrime/securesms/notifications/UnregisteredNotifier.kt delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/preferences/CorrectedPreferenceFragment.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/preferences/ListSummaryPreferenceFragment.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/dependencies/InstrumentationApplicationDependencyProvider.kt b/app/src/androidTest/java/org/thoughtcrime/securesms/dependencies/InstrumentationApplicationDependencyProvider.kt index 9bbadceb6c..7aa2f9eaf8 100644 --- a/app/src/androidTest/java/org/thoughtcrime/securesms/dependencies/InstrumentationApplicationDependencyProvider.kt +++ b/app/src/androidTest/java/org/thoughtcrime/securesms/dependencies/InstrumentationApplicationDependencyProvider.kt @@ -44,7 +44,7 @@ class InstrumentationApplicationDependencyProvider(val application: Application, private var archiveService: ArchiveService = mockk(relaxed = true) init { - recipientCache = LiveRecipientCache(application) { r -> r.run() } + recipientCache = LiveRecipientCache { r -> r.run() } } override fun provideBillingApi(): BillingApi = billingApi diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/jobs/JobManagerPerformanceTests.kt b/app/src/androidTest/java/org/thoughtcrime/securesms/jobs/JobManagerPerformanceTests.kt index c868b46a35..2a951a4d53 100644 --- a/app/src/androidTest/java/org/thoughtcrime/securesms/jobs/JobManagerPerformanceTests.kt +++ b/app/src/androidTest/java/org/thoughtcrime/securesms/jobs/JobManagerPerformanceTests.kt @@ -18,7 +18,7 @@ import org.thoughtcrime.securesms.jobmanager.Job import org.thoughtcrime.securesms.jobmanager.JobManager import org.thoughtcrime.securesms.jobmanager.JobMigrator import org.thoughtcrime.securesms.jobmanager.JobTracker -import org.thoughtcrime.securesms.util.TextSecurePreferences +import org.thoughtcrime.securesms.keyvalue.SignalStore import java.util.concurrent.CountDownLatch import kotlin.random.Random @@ -90,7 +90,7 @@ class JobManagerPerformanceTests { .setConstraintFactories(JobManagerFactories.getConstraintFactories(context)) .setConstraintObservers(JobManagerFactories.getConstraintObservers(context)) .setJobStorage(FastJobStorage(getInstance(context))) - .setJobMigrator(JobMigrator(TextSecurePreferences.getJobManagerVersion(context), JobManager.CURRENT_VERSION, JobManagerFactories.getJobMigrations(context))) + .setJobMigrator(JobMigrator(SignalStore.misc.jobManagerVersion, JobManager.CURRENT_VERSION, JobManagerFactories.getJobMigrations(context))) .build() return JobManager(context, config) diff --git a/app/src/benchmarkShared/java/org/signal/benchmark/setup/TestUsers.kt b/app/src/benchmarkShared/java/org/signal/benchmark/setup/TestUsers.kt index 6d48f7f518..7f95969a90 100644 --- a/app/src/benchmarkShared/java/org/signal/benchmark/setup/TestUsers.kt +++ b/app/src/benchmarkShared/java/org/signal/benchmark/setup/TestUsers.kt @@ -34,7 +34,6 @@ import org.thoughtcrime.securesms.registration.data.LocalRegistrationMetadataUti import org.thoughtcrime.securesms.registration.data.RegistrationData import org.thoughtcrime.securesms.registration.data.RegistrationRepository import org.thoughtcrime.securesms.registration.util.RegistrationUtil -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.signalservice.api.profiles.SignalServiceProfile import org.whispersystems.signalservice.api.push.SignalServiceAddress import java.util.UUID @@ -88,8 +87,8 @@ object TestUsers { SignalStore.registration.restoreDecisionState = RestoreDecisionState.Skipped RegistrationUtil.maybeMarkRegistrationComplete() SignalDatabase.recipients.setProfileName(Recipient.self().id, ProfileName.fromParts("Tester", "McTesterson")) - TextSecurePreferences.setPromptedOptimizeDoze(application, true) - TextSecurePreferences.setRatingEnabled(application, false) + SignalStore.uiHints.setHasPromptedOptimizeDoze(true) + SignalStore.misc.ratingEnabled = false PreKeyUtil.generateAndStoreSignedPreKey(AppDependencies.protocolStore.aci(), SignalStore.account.aciPreKeys) PreKeyUtil.generateAndStoreOneTimeEcPreKeys(AppDependencies.protocolStore.aci(), SignalStore.account.aciPreKeys) diff --git a/app/src/main/java/org/thoughtcrime/securesms/AppInitialization.java b/app/src/main/java/org/thoughtcrime/securesms/AppInitialization.java index b934e79b6e..a716db6fb3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/AppInitialization.java +++ b/app/src/main/java/org/thoughtcrime/securesms/AppInitialization.java @@ -16,9 +16,9 @@ import org.thoughtcrime.securesms.keyvalue.PlainTextKeyValueStore; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.migrations.ApplicationMigrations; import org.thoughtcrime.securesms.migrations.QuoteThumbnailBackfillMigrationJob; +import org.thoughtcrime.securesms.notifications.NotificationChannels; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.stickers.BlessedPacks; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.signal.core.util.Util; /** @@ -36,9 +36,9 @@ public final class AppInitialization { Log.i(TAG, "onFirstEverAppLaunch()"); PlainTextKeyValueStore.setAppMigrationVersion(ApplicationMigrations.CURRENT_VERSION); - TextSecurePreferences.setJobManagerVersion(context, JobManager.CURRENT_VERSION); + SignalStore.misc().setJobManagerVersion(JobManager.CURRENT_VERSION); PlainTextKeyValueStore.setLastVersionCode(BuildConfig.VERSION_CODE); - TextSecurePreferences.setHasSeenStickerIntroTooltip(context, true); + SignalStore.tooltips().markStickerIntroTooltipSeen(); SignalStore.settings().setPassphraseDisabled(true); SignalStore.settings().setReadReceiptsEnabled(true); SignalStore.settings().setTypingIndicatorsEnabled(true); @@ -56,7 +56,9 @@ public final class AppInitialization { SignalStore.onboarding().clearAll(); SignalStore.settings().setPassphraseDisabled(true); SignalStore.notificationProfile().setHasSeenTooltip(true); - TextSecurePreferences.onPostBackupRestore(context); + if (NotificationChannels.supported()) { + NotificationChannels.getInstance().updateMessageVibrate(SignalStore.settings().isMessageVibrateEnabled()); + } SignalStore.settings().setPassphraseDisabled(true); AppDependencies.getJobManager().addAll(BlessedPacks.getFirstInstallJobs()); EmojiSearchIndexDownloadJob.scheduleImmediately(); @@ -82,9 +84,9 @@ public final class AppInitialization { Log.w(TAG, "onRepairFirstEverAppLaunch()"); PlainTextKeyValueStore.setAppMigrationVersion(ApplicationMigrations.CURRENT_VERSION); - TextSecurePreferences.setJobManagerVersion(context, JobManager.CURRENT_VERSION); + SignalStore.misc().setJobManagerVersion(JobManager.CURRENT_VERSION); PlainTextKeyValueStore.setLastVersionCode(BuildConfig.VERSION_CODE); - TextSecurePreferences.setHasSeenStickerIntroTooltip(context, true); + SignalStore.tooltips().markStickerIntroTooltipSeen(); SignalStore.settings().setPassphraseDisabled(true); AppDependencies.getMegaphoneRepository().onFirstEverAppLaunch(); SignalStore.onFirstEverAppLaunch(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index 57bb64e55a..115029b18d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -132,7 +132,6 @@ import org.thoughtcrime.securesms.util.RemoteConfig; import org.thoughtcrime.securesms.util.SignalLocalMetrics; import org.thoughtcrime.securesms.util.SignalUncaughtExceptionHandler; import org.thoughtcrime.securesms.util.SqlCipherLogTarget; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.VersionTracker; import org.thoughtcrime.securesms.util.dynamiclanguage.DynamicLanguageContextWrapper; import org.whispersystems.signalservice.api.websocket.SignalWebSocket; @@ -459,14 +458,14 @@ public class ApplicationContext extends Application implements AppForegroundObse } private void initializeFirstEverAppLaunch() { - if (TextSecurePreferences.getFirstInstallVersion(this) == -1) { + if (SignalStore.misc().getFirstInstallVersion() == -1) { if (!SignalDatabase.databaseFileExists(this) || VersionTracker.getDaysSinceFirstInstalled(this) < 365) { Log.i(TAG, "First ever app launch!"); AppInitialization.onFirstEverAppLaunch(this); } Log.i(TAG, "Setting first install version to " + BuildConfig.CANONICAL_VERSION_CODE); - TextSecurePreferences.setFirstInstallVersion(this, BuildConfig.CANONICAL_VERSION_CODE); + SignalStore.misc().setFirstInstallVersion(BuildConfig.CANONICAL_VERSION_CODE); } else if (!SignalStore.settings().getPassphraseDisabled() && VersionTracker.getDaysSinceFirstInstalled(this) < 90) { Log.i(TAG, "Detected a new install that doesn't have passphrases disabled -- assuming bad initialization."); AppInitialization.onRepairFirstEverAppLaunch(this); @@ -586,7 +585,7 @@ public class ApplicationContext extends Application implements AppForegroundObse } private void executePendingContactSync() { - if (TextSecurePreferences.needsFullContactSync(this)) { + if (SignalStore.misc().getNeedsFullContactSync()) { AppDependencies.getJobManager().add(new MultiDeviceContactUpdateJob(true)); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/ContactSelectionListFragment.java b/app/src/main/java/org/thoughtcrime/securesms/ContactSelectionListFragment.java index 24d40e4f0c..1f6fa643be 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ContactSelectionListFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ContactSelectionListFragment.java @@ -81,7 +81,6 @@ import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.search.SearchRepository; import org.thoughtcrime.securesms.util.CommunicationActions; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.ViewUtil; import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter; import org.thoughtcrime.securesms.util.adapter.mapping.MappingModelList; @@ -222,7 +221,7 @@ public final class ContactSelectionListFragment extends LoggingFragment { public void onStart() { super.onStart(); - if (hasContactsPermissions(requireContext()) && !TextSecurePreferences.hasSuccessfullyRetrievedDirectory(getActivity())) { + if (hasContactsPermissions(requireContext()) && !SignalStore.misc().getHasSuccessfullyRetrievedDirectory()) { handleContactPermissionGranted(); } else { requireActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); @@ -441,7 +440,7 @@ public final class ContactSelectionListFragment extends LoggingFragment { .ifNecessary() .onAllGranted(() -> { contactSearchView.setAlpha(0.5f); - if (!TextSecurePreferences.hasSuccessfullyRetrievedDirectory(getActivity())) { + if (!SignalStore.misc().getHasSuccessfullyRetrievedDirectory()) { handleContactPermissionGranted(); } else { contactSearchViewModel.refresh(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/PassphraseRequiredActivity.java b/app/src/main/java/org/thoughtcrime/securesms/PassphraseRequiredActivity.java index e95c9c615a..3c102a2a31 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/PassphraseRequiredActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/PassphraseRequiredActivity.java @@ -38,7 +38,6 @@ import org.thoughtcrime.securesms.restore.RestoreActivity; import org.thoughtcrime.securesms.service.KeyCachingService; import org.thoughtcrime.securesms.util.AppStartup; import org.thoughtcrime.securesms.util.Environment; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import java.util.Locale; @@ -175,7 +174,7 @@ public abstract class PassphraseRequiredActivity extends BaseActivity implements return STATE_PROMPT_PASSPHRASE; } else if (ApplicationMigrations.isUpdate(this) && ApplicationMigrations.isUiBlockingMigrationRunning()) { return STATE_UI_BLOCKING_UPGRADE; - } else if (!TextSecurePreferences.hasPromptedPushRegistration(this)) { + } else if (!SignalStore.registration().getHasPromptedPushRegistration()) { return STATE_WELCOME_PUSH_SCREEN; } else if (shouldResumeLinkingRegistration()) { return STATE_RESUME_LINKING_REG; @@ -251,7 +250,7 @@ public abstract class PassphraseRequiredActivity extends BaseActivity implements private Intent getUiBlockingUpgradeIntent() { return getRoutedIntent(ApplicationMigrationActivity.class, - TextSecurePreferences.hasPromptedPushRegistration(this) + SignalStore.registration().getHasPromptedPushRegistration() ? getConversationListIntent() : getPushRegistrationIntent()); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/apkupdate/ApkUpdateRefreshListener.java b/app/src/main/java/org/thoughtcrime/securesms/apkupdate/ApkUpdateRefreshListener.java index c2ad5f059d..86722b1c4b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/apkupdate/ApkUpdateRefreshListener.java +++ b/app/src/main/java/org/thoughtcrime/securesms/apkupdate/ApkUpdateRefreshListener.java @@ -12,9 +12,9 @@ import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.dependencies.AppDependencies; import org.thoughtcrime.securesms.jobs.ApkUpdateJob; +import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.service.PersistentAlarmManagerListener; import org.thoughtcrime.securesms.util.Environment; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import java.util.concurrent.TimeUnit; @@ -26,7 +26,7 @@ public class ApkUpdateRefreshListener extends PersistentAlarmManagerListener { @Override protected long getNextScheduledExecutionTime(Context context) { - return TextSecurePreferences.getUpdateApkRefreshTime(context); + return SignalStore.apkUpdate().getRefreshTime(); } @Override @@ -39,7 +39,7 @@ public class ApkUpdateRefreshListener extends PersistentAlarmManagerListener { } long newTime = System.currentTimeMillis() + INTERVAL; - TextSecurePreferences.setUpdateApkRefreshTime(context, newTime); + SignalStore.apkUpdate().setRefreshTime(newTime); return newTime; } 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 9bc0bcb162..dfff083ed1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/BackupDialog.java +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/BackupDialog.java @@ -72,7 +72,7 @@ public class BackupDialog { .takePersistableUriPermission(backupDirectoryUri, takeFlags); } - BackupPassphrase.set(context, Util.join(password, " ")); + SignalStore.backup().setV1BackupPassphrase(Util.join(password, " ")); SignalStore.settings().setLocalBackupNextTime(0); SignalStore.settings().setBackupEnabled(true); LocalBackupListener.schedule(context); @@ -177,7 +177,7 @@ public class BackupDialog { positiveButton.setOnClickListener(v -> { String passphrase = prompt.getText().toString(); - if (passphrase.equals(BackupPassphrase.get(context))) { + if (passphrase.equals(SignalStore.backup().getV1BackupPassphrase())) { Toast.makeText(context, R.string.BackupDialog_you_successfully_entered_your_backup_passphrase, Toast.LENGTH_SHORT).show(); dialog.dismiss(); } else { diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/BackupPassphrase.java b/app/src/main/java/org/thoughtcrime/securesms/backup/BackupPassphrase.java deleted file mode 100644 index af1d52a181..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/BackupPassphrase.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.thoughtcrime.securesms.backup; - -import android.content.Context; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.signal.core.util.logging.Log; -import org.signal.core.util.crypto.KeyStoreHelper; -import org.thoughtcrime.securesms.util.TextSecurePreferences; - -/** - * Allows the getting and setting of the backup passphrase, which is stored encrypted on API >= 23. - */ -public final class BackupPassphrase { - - private BackupPassphrase() { - } - - private static final String TAG = Log.tag(BackupPassphrase.class); - - public static @Nullable String get(@NonNull Context context) { - String passphrase = TextSecurePreferences.getBackupPassphrase(context); - String encryptedPassphrase = TextSecurePreferences.getEncryptedBackupPassphrase(context); - - if (passphrase == null && encryptedPassphrase == null) { - return null; - } - - if (encryptedPassphrase == null) { - Log.i(TAG, "Migrating to encrypted passphrase."); - set(context, passphrase); - encryptedPassphrase = TextSecurePreferences.getEncryptedBackupPassphrase(context); - if (encryptedPassphrase == null) throw new AssertionError("Passphrase migration failed"); - } - - KeyStoreHelper.SealedData data = KeyStoreHelper.SealedData.fromString(encryptedPassphrase); - return stripSpaces(new String(KeyStoreHelper.unseal(data))); - } - - public static void set(@NonNull Context context, @Nullable String passphrase) { - if (passphrase == null) { - TextSecurePreferences.setBackupPassphrase(context, null); - TextSecurePreferences.setEncryptedBackupPassphrase(context, null); - } else { - KeyStoreHelper.SealedData encryptedPassphrase = KeyStoreHelper.seal(passphrase.getBytes()); - TextSecurePreferences.setEncryptedBackupPassphrase(context, encryptedPassphrase.serialize()); - TextSecurePreferences.setBackupPassphrase(context, null); - } - } - - private static String stripSpaces(@Nullable String passphrase) { - return passphrase != null ? passphrase.replace(" ", "") : null; - } -} 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 0da1c2f3eb..320accf149 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupExporter.java +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupExporter.java @@ -21,7 +21,6 @@ import org.signal.core.util.Stopwatch; import org.signal.core.util.logging.Log; import org.signal.core.models.database.AttachmentId; import org.thoughtcrime.securesms.backup.proto.KeyValue; -import org.thoughtcrime.securesms.backup.proto.SharedPreference; import org.thoughtcrime.securesms.backup.proto.SqlStatement; import org.signal.core.util.crypto.AttachmentSecret; import org.signal.core.util.crypto.ClassicDecryptingPartInputStream; diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/BackupRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/BackupRepository.kt index 664990c312..6dbdd08755 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/BackupRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/BackupRepository.kt @@ -151,7 +151,6 @@ import org.thoughtcrime.securesms.service.BackupMediaRestoreService import org.thoughtcrime.securesms.service.BackupProgressService import org.thoughtcrime.securesms.storage.StorageSyncHelper import org.thoughtcrime.securesms.util.RemoteConfig -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.toMillis import org.whispersystems.signalservice.api.link.TransferArchiveResponse import org.whispersystems.signalservice.api.messages.AttachmentTransferProgress @@ -485,7 +484,7 @@ object BackupRepository { return false } - val isRegistered = SignalStore.account.isRegistered && !TextSecurePreferences.isUnauthorizedReceived(AppDependencies.application) + val isRegistered = SignalStore.account.isRegistered && !SignalStore.account.isUnauthorizedReceived if (!isRegistered) { Log.d(TAG, "[shouldDisplayCouldNotCompleteBackupSheet] Not displaying sheet for unregistered user.") return false 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 3d9c3288f9..cb38728f55 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 @@ -60,8 +60,6 @@ object AccountDataArchiveProcessor { private val TAG = Log.tag(AccountDataArchiveProcessor::class) fun export(db: SignalDatabase, signalStore: SignalStore, exportState: ExportState, emitter: BackupFrameEmitter) { - val context = AppDependencies.application - val selfId = db.recipientTable.getByAci(signalStore.accountValues.aci!!).get() val selfRecord = db.recipientTable.getRecordForSync(selfId)!! diff --git a/app/src/main/java/org/thoughtcrime/securesms/banner/banners/DozeBanner.kt b/app/src/main/java/org/thoughtcrime/securesms/banner/banners/DozeBanner.kt index 9c8c7c7d9f..a1928844b9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/banner/banners/DozeBanner.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/banner/banners/DozeBanner.kt @@ -25,12 +25,11 @@ import org.thoughtcrime.securesms.banner.ui.compose.Action import org.thoughtcrime.securesms.banner.ui.compose.DefaultBanner import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.util.PowerManagerCompat -import org.thoughtcrime.securesms.util.TextSecurePreferences class DozeBanner(private val context: Context) : Banner() { override val enabled: Boolean - get() = !SignalStore.account.fcmEnabled && !TextSecurePreferences.hasPromptedOptimizeDoze(context) && !ServiceUtil.getPowerManager(context).isIgnoringBatteryOptimizations(context.packageName) + get() = !SignalStore.account.fcmEnabled && !SignalStore.uiHints.hasPromptedOptimizeDoze() && !ServiceUtil.getPowerManager(context).isIgnoringBatteryOptimizations(context.packageName) override val dataFlow: Flow get() = flowOf(Unit) @@ -62,7 +61,7 @@ class DozeBanner(private val context: Context) : Banner() { } private fun markAsPrompted() { - TextSecurePreferences.setPromptedOptimizeDoze(context, true) + SignalStore.uiHints.setHasPromptedOptimizeDoze(true) enabledState.value = false } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/banner/banners/ServiceOutageBanner.kt b/app/src/main/java/org/thoughtcrime/securesms/banner/banners/ServiceOutageBanner.kt index 6d04cbb6d3..922d22bdbe 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/banner/banners/ServiceOutageBanner.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/banner/banners/ServiceOutageBanner.kt @@ -18,12 +18,12 @@ import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.banner.Banner import org.thoughtcrime.securesms.banner.ui.compose.DefaultBanner import org.thoughtcrime.securesms.banner.ui.compose.Importance -import org.thoughtcrime.securesms.util.TextSecurePreferences +import org.thoughtcrime.securesms.keyvalue.SignalStore class ServiceOutageBanner(val context: Context) : Banner() { override val enabled: Boolean - get() = TextSecurePreferences.getServiceOutage(context) + get() = SignalStore.misc.serviceOutage override val dataFlow: Flow = flowOf(Unit) diff --git a/app/src/main/java/org/thoughtcrime/securesms/banner/banners/UnauthorizedBanner.kt b/app/src/main/java/org/thoughtcrime/securesms/banner/banners/UnauthorizedBanner.kt index 855f303710..6add731739 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/banner/banners/UnauthorizedBanner.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/banner/banners/UnauthorizedBanner.kt @@ -27,7 +27,6 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.net.DeviceTransferBlockingInterceptor import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.registration.ui.RegistrationActivity -import org.thoughtcrime.securesms.util.TextSecurePreferences /** * A banner displayed when the client is unauthorized (deregistered). @@ -35,7 +34,7 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences class UnauthorizedBanner(val context: Context) : Banner() { override val enabled: Boolean - get() = TextSecurePreferences.isUnauthorizedReceived(context) || !SignalStore.account.isRegistered + get() = SignalStore.account.isUnauthorizedReceived || !SignalStore.account.isRegistered override val dataFlow: Flow get() = flowOf(Unit) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/CustomDefaultPreference.java b/app/src/main/java/org/thoughtcrime/securesms/components/CustomDefaultPreference.java deleted file mode 100644 index ed546c08c6..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/components/CustomDefaultPreference.java +++ /dev/null @@ -1,260 +0,0 @@ -package org.thoughtcrime.securesms.components; - -import android.app.Dialog; -import android.content.Context; -import android.content.res.TypedArray; -import android.os.Bundle; -import android.text.Editable; -import android.text.TextUtils; -import android.text.TextWatcher; -import android.util.AttributeSet; -import android.view.View; -import android.widget.AdapterView; -import android.widget.Button; -import android.widget.EditText; -import android.widget.Spinner; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AlertDialog; -import androidx.preference.DialogPreference; -import androidx.preference.PreferenceDialogFragmentCompat; - -import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.components.CustomDefaultPreference.CustomDefaultPreferenceDialogFragmentCompat.CustomPreferenceValidator; -import org.thoughtcrime.securesms.util.TextSecurePreferences; - -import java.net.URI; -import java.net.URISyntaxException; - - -public class CustomDefaultPreference extends DialogPreference { - - private static final String TAG = Log.tag(CustomDefaultPreference.class); - - private final int inputType; - private final String customPreference; - private final String customToggle; - - private CustomPreferenceValidator validator; - private String defaultValue; - - public CustomDefaultPreference(Context context, AttributeSet attrs) { - super(context, attrs); - - int[] attributeNames = new int[]{android.R.attr.inputType, R.attr.custom_pref_toggle}; - TypedArray attributes = context.obtainStyledAttributes(attrs, attributeNames); - - this.inputType = attributes.getInt(0, 0); - this.customPreference = getKey(); - this.customToggle = attributes.getString(1); - this.validator = new CustomDefaultPreferenceDialogFragmentCompat.NullValidator(); - - attributes.recycle(); - - setPersistent(false); - setDialogLayoutResource(R.layout.custom_default_preference_dialog); - } - - public CustomDefaultPreference setValidator(CustomPreferenceValidator validator) { - this.validator = validator; - return this; - } - - public CustomDefaultPreference setDefaultValue(String defaultValue) { - this.defaultValue = defaultValue; - this.setSummary(getSummary()); - return this; - } - - @Override - public String getSummary() { - if (isCustom()) { - return getContext().getString(R.string.CustomDefaultPreference_using_custom, - getPrettyPrintValue(getCustomValue())); - } else { - return getContext().getString(R.string.CustomDefaultPreference_using_default, - getPrettyPrintValue(getDefaultValue())); - } - } - - private String getPrettyPrintValue(String value) { - if (TextUtils.isEmpty(value)) return getContext().getString(R.string.CustomDefaultPreference_none); - else return value; - } - - private boolean isCustom() { - return TextSecurePreferences.getBooleanPreference(getContext(), customToggle, false); - } - - private void setCustom(boolean custom) { - TextSecurePreferences.setBooleanPreference(getContext(), customToggle, custom); - } - - private String getCustomValue() { - return TextSecurePreferences.getStringPreference(getContext(), customPreference, ""); - } - - private void setCustomValue(String value) { - TextSecurePreferences.setStringPreference(getContext(), customPreference, value); - } - - private String getDefaultValue() { - return defaultValue; - } - - - public static class CustomDefaultPreferenceDialogFragmentCompat extends PreferenceDialogFragmentCompat { - - private static final String INPUT_TYPE = "input_type"; - - private Spinner spinner; - private EditText customText; - private TextView defaultLabel; - - public static CustomDefaultPreferenceDialogFragmentCompat newInstance(String key) { - CustomDefaultPreferenceDialogFragmentCompat fragment = new CustomDefaultPreferenceDialogFragmentCompat(); - Bundle b = new Bundle(1); - b.putString(PreferenceDialogFragmentCompat.ARG_KEY, key); - fragment.setArguments(b); - return fragment; - } - - @Override - protected void onBindDialogView(@NonNull View view) { - Log.i(TAG, "onBindDialogView"); - super.onBindDialogView(view); - - CustomDefaultPreference preference = (CustomDefaultPreference)getPreference(); - - this.spinner = (Spinner) view.findViewById(R.id.default_or_custom); - this.defaultLabel = (TextView) view.findViewById(R.id.default_label); - this.customText = (EditText) view.findViewById(R.id.custom_edit); - - this.customText.setInputType(preference.inputType); - this.customText.addTextChangedListener(new TextValidator()); - this.customText.setText(preference.getCustomValue()); - this.spinner.setOnItemSelectedListener(new SelectionLister()); - this.defaultLabel.setText(preference.getPrettyPrintValue(preference.defaultValue)); - } - - - @Override - public @NonNull Dialog onCreateDialog(Bundle instanceState) { - Dialog dialog = super.onCreateDialog(instanceState); - - CustomDefaultPreference preference = (CustomDefaultPreference)getPreference(); - - if (preference.isCustom()) spinner.setSelection(1, true); - else spinner.setSelection(0, true); - - return dialog; - } - - @Override - public void onDialogClosed(boolean positiveResult) { - CustomDefaultPreference preference = (CustomDefaultPreference)getPreference(); - - if (positiveResult) { - if (spinner != null) preference.setCustom(spinner.getSelectedItemPosition() == 1); - if (customText != null) preference.setCustomValue(customText.getText().toString()); - - preference.setSummary(preference.getSummary()); - } - } - - interface CustomPreferenceValidator { - public boolean isValid(String value); - } - - private static class NullValidator implements CustomPreferenceValidator { - @Override - public boolean isValid(String value) { - return true; - } - } - - private class TextValidator implements TextWatcher { - - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) {} - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) {} - - @Override - public void afterTextChanged(Editable s) { - CustomDefaultPreference preference = (CustomDefaultPreference)getPreference(); - - if (spinner.getSelectedItemPosition() == 1) { - Button positiveButton = ((AlertDialog)getDialog()).getButton(AlertDialog.BUTTON_POSITIVE); - positiveButton.setEnabled(preference.validator.isValid(s.toString())); - } - } - } - - public static class UriValidator implements CustomPreferenceValidator { - @Override - public boolean isValid(String value) { - if (TextUtils.isEmpty(value)) return true; - - try { - new URI(value); - return true; - } catch (URISyntaxException mue) { - return false; - } - } - } - - public static class HostnameValidator implements CustomPreferenceValidator { - @Override - public boolean isValid(String value) { - if (TextUtils.isEmpty(value)) return true; - - try { - URI uri = new URI(null, value, null, null); - return true; - } catch (URISyntaxException mue) { - return false; - } - } - } - - public static class PortValidator implements CustomPreferenceValidator { - @Override - public boolean isValid(String value) { - try { - Integer.parseInt(value); - return true; - } catch (NumberFormatException e) { - return false; - } - } - } - - private class SelectionLister implements AdapterView.OnItemSelectedListener { - - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - CustomDefaultPreference preference = (CustomDefaultPreference)getPreference(); - Button positiveButton = ((AlertDialog)getDialog()).getButton(AlertDialog.BUTTON_POSITIVE); - - defaultLabel.setVisibility(position == 0 ? View.VISIBLE : View.GONE); - customText.setVisibility(position == 0 ? View.GONE : View.VISIBLE); - positiveButton.setEnabled(position == 0 || preference.validator.isValid(customText.getText().toString())); - } - - @Override - public void onNothingSelected(AdapterView parent) { - defaultLabel.setVisibility(View.VISIBLE); - customText.setVisibility(View.GONE); - } - } - - } - - - -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/RatingManager.java b/app/src/main/java/org/thoughtcrime/securesms/components/RatingManager.java index 9b3d1f3cb5..ab4e9c39d2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/RatingManager.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/RatingManager.java @@ -8,8 +8,8 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.util.PlayStoreUtil; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.VersionTracker; import java.util.concurrent.TimeUnit; @@ -22,10 +22,10 @@ public class RatingManager { private static final String TAG = Log.tag(RatingManager.class); public static void showRatingDialogIfNecessary(Context context) { - if (!TextSecurePreferences.isRatingEnabled(context) || BuildConfig.MANAGES_APP_UPDATES) return; + if (!SignalStore.misc().getRatingEnabled() || BuildConfig.MANAGES_APP_UPDATES) return; long daysSinceInstall = VersionTracker.getDaysSinceFirstInstalled(context); - long laterTimestamp = TextSecurePreferences.getRatingLaterTimestamp(context); + long laterTimestamp = SignalStore.misc().getRatingLaterTimestamp(); if (daysSinceInstall >= DAYS_SINCE_INSTALL_THRESHOLD && System.currentTimeMillis() >= laterTimestamp) @@ -41,21 +41,21 @@ public class RatingManager { .setPositiveButton(R.string.RatingManager_rate_now, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - TextSecurePreferences.setRatingEnabled(context, false); + SignalStore.misc().setRatingEnabled(false); PlayStoreUtil.openPlayStoreOrOurApkDownloadPage(context); } }) .setNegativeButton(R.string.RatingManager_no_thanks, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - TextSecurePreferences.setRatingEnabled(context, false); + SignalStore.misc().setRatingEnabled(false); } }) .setNeutralButton(R.string.RatingManager_later, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { long waitUntil = System.currentTimeMillis() + TimeUnit.DAYS.toMillis(DAYS_UNTIL_REPROMPT_THRESHOLD); - TextSecurePreferences.setRatingLaterTimestamp(context, waitUntil); + SignalStore.misc().setRatingLaterTimestamp(waitUntil); } }) .show(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/RecentEmojiPageModel.java b/app/src/main/java/org/thoughtcrime/securesms/components/emoji/RecentEmojiPageModel.java index 41eafef196..3a6654cb50 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/RecentEmojiPageModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/emoji/RecentEmojiPageModel.java @@ -32,6 +32,9 @@ public class RecentEmojiPageModel implements EmojiPageModel { private static final int EMOJI_LRU_SIZE = 50; public static final String KEY = "Recents"; + /** The shared-prefs entry this model persists its LRU into. */ + public static final String RECENT_STORAGE_KEY = "pref_recent_emoji2"; + private final SharedPreferences prefs; private final String preferenceName; private final LinkedHashSet recentlyUsed; diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/AppSettingsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/AppSettingsViewModel.kt index 3972b61270..be397caa6a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/AppSettingsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/AppSettingsViewModel.kt @@ -10,10 +10,8 @@ import org.thoughtcrime.securesms.components.settings.app.subscription.InAppDona import org.thoughtcrime.securesms.components.settings.app.subscription.RecurringInAppPaymentRepository import org.thoughtcrime.securesms.conversationlist.model.UnreadPaymentsLiveData import org.thoughtcrime.securesms.database.model.InAppPaymentSubscriberRecord -import org.thoughtcrime.securesms.dependencies.AppDependencies import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.recipients.Recipient -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.livedata.Store class AppSettingsViewModel : ViewModel() { @@ -24,7 +22,7 @@ class AppSettingsViewModel : ViewModel() { unreadPaymentsCount = 0, hasExpiredGiftBadge = SignalStore.inAppPayments.getExpiredGiftBadge() != null, allowUserToGoToDonationManagementScreen = SignalStore.inAppPayments.isLikelyASustainer() || InAppDonations.hasAtLeastOnePaymentMethodAvailable(), - userUnregistered = TextSecurePreferences.isUnauthorizedReceived(AppDependencies.application) || !SignalStore.account.isRegistered, + userUnregistered = SignalStore.account.isUnauthorizedReceived || !SignalStore.account.isRegistered, clientDeprecated = SignalStore.misc.isClientDeprecated ) ) @@ -56,7 +54,7 @@ class AppSettingsViewModel : ViewModel() { store.update { it.copy( clientDeprecated = SignalStore.misc.isClientDeprecated, - userUnregistered = TextSecurePreferences.isUnauthorizedReceived(AppDependencies.application) || !SignalStore.account.isRegistered + userUnregistered = SignalStore.account.isUnauthorizedReceived || !SignalStore.account.isRegistered ) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsRepository.kt index 6f3da90d51..c9d2e987af 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsRepository.kt @@ -12,11 +12,9 @@ import org.signal.core.util.concurrent.SignalDispatchers import org.signal.core.util.logging.Log import org.thoughtcrime.securesms.components.settings.app.account.authenticator.TotpRepository import org.thoughtcrime.securesms.components.settings.app.account.passkeys.AppPasskeysRepository -import org.thoughtcrime.securesms.dependencies.AppDependencies import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.lock.v2.PinKeyboardType import org.thoughtcrime.securesms.pin.SvrRepository -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.signalservice.api.kbs.PinHashUtil import java.io.IOException @@ -42,7 +40,7 @@ class AccountSettingsRepository { fun isRegistrationLockEnabled(): Boolean = SignalStore.svr.isRegistrationLockEnabled - fun isUserUnregistered(): Boolean = TextSecurePreferences.isUnauthorizedReceived(AppDependencies.application) + fun isUserUnregistered(): Boolean = SignalStore.account.isUnauthorizedReceived fun isClientDeprecated(): Boolean = SignalStore.misc.isClientDeprecated diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/backups/local/LocalBackupsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/backups/local/LocalBackupsViewModel.kt index 96941e1488..73d52c801d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/backups/local/LocalBackupsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/backups/local/LocalBackupsViewModel.kt @@ -17,7 +17,6 @@ import kotlinx.coroutines.withContext import org.signal.core.ui.util.StorageUtil import org.signal.core.util.logging.Log import org.thoughtcrime.securesms.R -import org.thoughtcrime.securesms.backup.BackupPassphrase import org.thoughtcrime.securesms.backup.LocalExportProgress import org.thoughtcrime.securesms.components.settings.app.backups.remote.BackupKeyCredentialManagerHandler import org.thoughtcrime.securesms.components.settings.app.backups.remote.BackupKeySaveState @@ -27,7 +26,6 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.keyvalue.protos.LocalBackupCreationProgress import org.thoughtcrime.securesms.util.BackupUtil import org.thoughtcrime.securesms.util.DateUtils -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.formatHours import java.time.LocalTime import java.util.Locale @@ -85,7 +83,7 @@ class LocalBackupsViewModel : ViewModel(), BackupKeyCredentialManagerHandler { val context = AppDependencies.application val backupTime = LocalTime.of(SignalStore.settings.backupHour, SignalStore.settings.backupMinute).formatHours(context) - val userUnregistered = TextSecurePreferences.isUnauthorizedReceived(context) || !SignalStore.account.isRegistered + val userUnregistered = SignalStore.account.isUnauthorizedReceived || !SignalStore.account.isRegistered val clientDeprecated = SignalStore.misc.isClientDeprecated val legacyLocalBackupsEnabled = SignalStore.settings.isBackupEnabled && BackupUtil.canUserAccessBackupDirectory(context) val canTurnOn = legacyLocalBackupsEnabled || (!userUnregistered && !clientDeprecated) @@ -143,7 +141,7 @@ class LocalBackupsViewModel : ViewModel(), BackupKeyCredentialManagerHandler { SignalStore.backup.newLocalBackupsDirectory = SignalStore.settings.signalBackupDirectory?.toString() - BackupPassphrase.set(context, null) + SignalStore.backup.v1BackupPassphrase = null SignalStore.settings.isBackupEnabled = false BackupUtil.deleteAllBackups() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/backups/remote/RemoteBackupsSettingsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/backups/remote/RemoteBackupsSettingsViewModel.kt index 00af4d24db..908f6ee9d1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/backups/remote/RemoteBackupsSettingsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/backups/remote/RemoteBackupsSettingsViewModel.kt @@ -50,7 +50,6 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.keyvalue.protos.ArchiveUploadProgressState import org.thoughtcrime.securesms.util.Environment import org.thoughtcrime.securesms.util.RemoteConfig -import org.thoughtcrime.securesms.util.TextSecurePreferences import kotlin.time.Duration.Companion.days import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.seconds @@ -71,7 +70,7 @@ class RemoteBackupsSettingsViewModel : ViewModel() { backupState = BackupStateObserver.getNonIOBackupState(), backupsEnabled = SignalStore.backup.areBackupsEnabled, canBackupMessagesJobRun = BackupMessagesConstraint.isMet(AppDependencies.application), - canViewBackupKey = !TextSecurePreferences.isUnauthorizedReceived(AppDependencies.application), + canViewBackupKey = !SignalStore.account.isUnauthorizedReceived, lastBackupTimestamp = SignalStore.backup.lastBackupTime, canBackUpUsingCellular = SignalStore.backup.backupWithCellular, canRestoreUsingCellular = SignalStore.backup.restoreWithCellular, diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/ChatsSettingsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/ChatsSettingsViewModel.kt index 5733b725be..69818fc0f1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/ChatsSettingsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/ChatsSettingsViewModel.kt @@ -17,7 +17,6 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.util.BackupUtil import org.thoughtcrime.securesms.util.ConversationUtil import org.thoughtcrime.securesms.util.RemoteConfig -import org.thoughtcrime.securesms.util.TextSecurePreferences class ChatsSettingsViewModel @JvmOverloads constructor( private val repository: ChatsSettingsRepository = ChatsSettingsRepository() @@ -34,7 +33,7 @@ class ChatsSettingsViewModel @JvmOverloads constructor( enterKeySends = SignalStore.settings.isEnterKeySends, localBackupsEnabled = SignalStore.settings.isBackupEnabled && BackupUtil.canUserAccessBackupDirectory(AppDependencies.application), folderCount = 0, - userUnregistered = TextSecurePreferences.isUnauthorizedReceived(AppDependencies.application) || !SignalStore.account.isRegistered, + userUnregistered = SignalStore.account.isUnauthorizedReceived || !SignalStore.account.isRegistered, clientDeprecated = SignalStore.misc.isClientDeprecated, isPlaintextExportEnabled = RemoteConfig.localPlaintextExport, chatExportState = ChatExportState.None diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsRepository.kt index eefeb8cc96..19c1bf5559 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsRepository.kt @@ -57,7 +57,6 @@ import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.recipients.RecipientUtil import org.thoughtcrime.securesms.stories.Stories import org.thoughtcrime.securesms.util.RemoteConfig -import org.thoughtcrime.securesms.util.TextSecurePreferences import java.io.IOException import kotlin.coroutines.resume @@ -74,7 +73,7 @@ class ConversationSettingsRepository( ) { fun isDeprecatedOrUnregistered(): Boolean { - return SignalStore.misc.isClientDeprecated || TextSecurePreferences.isUnauthorizedReceived(context) + return SignalStore.misc.isClientDeprecated || SignalStore.account.isUnauthorizedReceived } fun isInternalRecipientDetailsEnabled(): Boolean { diff --git a/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscovery.kt b/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscovery.kt index 5f22fa7cff..c443822e5f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscovery.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscovery.kt @@ -28,7 +28,6 @@ import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.registration.util.RegistrationUtil import org.thoughtcrime.securesms.storage.StorageSyncHelper import org.thoughtcrime.securesms.util.SignalE164Util -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.signalservice.api.push.SignalServiceAddress import java.io.IOException import java.util.Calendar @@ -192,13 +191,13 @@ object ContactDiscovery { ) stopwatch.split("contact-sync") - if (TextSecurePreferences.hasSuccessfullyRetrievedDirectory(context) && notifyOfNewUsers) { + if (SignalStore.misc.hasSuccessfullyRetrievedDirectory && notifyOfNewUsers) { val systemContacts: Set = SignalDatabase.recipients.getSystemContacts().toSet() val newlyRegisteredSystemContacts: Set = (result.registeredIds - preExistingRegisteredIds).intersect(systemContacts) notifyNewUsers(context, newlyRegisteredSystemContacts) } else { - TextSecurePreferences.setHasSuccessfullyRetrievedDirectory(context, true) + SignalStore.misc.hasSuccessfullyRetrievedDirectory = true } stopwatch.split("notify") } else { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ui/inlinequery/InlineQueryViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/ui/inlinequery/InlineQueryViewModel.kt index cdc7e97e3c..6bccdd8a0b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ui/inlinequery/InlineQueryViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ui/inlinequery/InlineQueryViewModel.kt @@ -8,7 +8,6 @@ import org.thoughtcrime.securesms.components.emoji.RecentEmojiPageModel import org.thoughtcrime.securesms.dependencies.AppDependencies import org.thoughtcrime.securesms.keyboard.emoji.search.EmojiSearchRepository import org.thoughtcrime.securesms.keyvalue.SignalStore -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.adapter.mapping.AnyMappingModel /** @@ -18,7 +17,7 @@ import org.thoughtcrime.securesms.util.adapter.mapping.AnyMappingModel */ class InlineQueryViewModel( private val emojiSearchRepository: EmojiSearchRepository = EmojiSearchRepository(AppDependencies.application), - private val recentEmojis: RecentEmojiPageModel = RecentEmojiPageModel(AppDependencies.application, TextSecurePreferences.RECENT_STORAGE_KEY) + private val recentEmojis: RecentEmojiPageModel = RecentEmojiPageModel(AppDependencies.application, RecentEmojiPageModel.RECENT_STORAGE_KEY) ) : ViewModel() { private val querySubject: PublishSubject = PublishSubject.create() diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ui/inlinequery/InlineQueryViewModelV2.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/ui/inlinequery/InlineQueryViewModelV2.kt index de299b265a..aca4840382 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ui/inlinequery/InlineQueryViewModelV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ui/inlinequery/InlineQueryViewModelV2.kt @@ -13,7 +13,6 @@ import org.thoughtcrime.securesms.conversation.v2.ConversationRecipientRepositor import org.thoughtcrime.securesms.dependencies.AppDependencies import org.thoughtcrime.securesms.keyboard.emoji.search.EmojiSearchRepository import org.thoughtcrime.securesms.keyvalue.SignalStore -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.adapter.mapping.AnyMappingModel /** @@ -24,7 +23,7 @@ class InlineQueryViewModelV2( private val recipientRepository: ConversationRecipientRepository, private val mentionsPickerRepository: MentionsPickerRepositoryV2 = MentionsPickerRepositoryV2(), private val emojiSearchRepository: EmojiSearchRepository = EmojiSearchRepository(AppDependencies.application), - private val recentEmojis: RecentEmojiPageModel = RecentEmojiPageModel(AppDependencies.application, TextSecurePreferences.RECENT_STORAGE_KEY) + private val recentEmojis: RecentEmojiPageModel = RecentEmojiPageModel(AppDependencies.application, RecentEmojiPageModel.RECENT_STORAGE_KEY) ) : ViewModel() { private val querySubject: PublishSubject = PublishSubject.create() 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 d4f124eea7..83a67f77b9 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 @@ -391,7 +391,6 @@ import org.thoughtcrime.securesms.util.PlayStoreUtil import org.thoughtcrime.securesms.util.Projection import org.thoughtcrime.securesms.util.RemoteConfig import org.thoughtcrime.securesms.util.SignalLocalMetrics -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.UriUtil import org.thoughtcrime.securesms.util.ViewUtil import org.thoughtcrime.securesms.util.atMidnight @@ -583,7 +582,7 @@ class ConversationFragment : private val colorizer = ColorizerV2() private val textDraftSaveDebouncer = Debouncer(500) private val doubleTapToEditDebouncer = DoubleClickDebouncer(200) - private val recentEmojis: RecentEmojiPageModel by lazy { RecentEmojiPageModel(AppDependencies.application, TextSecurePreferences.RECENT_STORAGE_KEY) } + private val recentEmojis: RecentEmojiPageModel by lazy { RecentEmojiPageModel(AppDependencies.application, RecentEmojiPageModel.RECENT_STORAGE_KEY) } private val nicknameEditActivityLauncher = registerForActivityResult(NicknameActivity.Contract()) {} private val handler = Handler(Looper.getMainLooper()) @@ -1793,7 +1792,7 @@ class ConversationFragment : } } - if (TextSecurePreferences.getServiceOutage(context)) { + if (SignalStore.misc.serviceOutage) { AppDependencies.jobManager.add(ServiceOutageDetectionJob()) } @@ -2789,7 +2788,7 @@ class ConversationFragment : } private fun initializeMediaKeyboard() { - val stickerIntro: Boolean = !TextSecurePreferences.hasSeenStickerIntroTooltip(requireContext()) + val stickerIntro: Boolean = !SignalStore.tooltips.hasSeenStickerIntroTooltip() inputPanel.showMediaKeyboardToggle(true) inputPanel.setMediaKeyboardToggleMode(preferredKeyboardPage()) @@ -3076,7 +3075,7 @@ class ConversationFragment : } private fun maybeShowSwipeToReplyTooltip() { - if (!TextSecurePreferences.hasSeenSwipeToReplyTooltip(requireContext())) { + if (!SignalStore.tooltips.hasSeenSwipeToReplyTooltip()) { val tooltipText = if (ViewUtil.isLtr(requireContext())) { R.string.ConversationFragment_you_can_swipe_to_the_right_reply } else { @@ -3085,7 +3084,7 @@ class ConversationFragment : snackbar(tooltipText) - TextSecurePreferences.setHasSeenSwipeToReplyTooltip(requireContext(), true) + SignalStore.tooltips.markSwipeToReplyTooltipSeen() } } @@ -5656,7 +5655,7 @@ class ConversationFragment : return } - if (!TextSecurePreferences.hasSeenStickerIntroTooltip(requireContext())) { + if (!SignalStore.tooltips.hasSeenStickerIntroTooltip()) { return } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationTooltips.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationTooltips.kt index 0e7b253ad5..a9378a2bf3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationTooltips.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationTooltips.kt @@ -8,8 +8,8 @@ import androidx.lifecycle.ViewModel import org.signal.core.util.logging.Log import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.components.TooltipPopup +import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.stickers.StickerPackInstallEvent -import org.thoughtcrime.securesms.util.TextSecurePreferences /** * Any and all tooltips that the conversation can display, and a light amount of related presentation logic. @@ -30,7 +30,7 @@ class ConversationTooltips(fragment: Fragment) { .setTextColor(ContextCompat.getColor(anchor.context, R.color.core_white)) .setText(R.string.ConversationActivity_new_say_it_with_stickers) .setOnDismissListener { - TextSecurePreferences.setHasSeenStickerIntroTooltip(anchor.context, true) + SignalStore.tooltips.markStickerIntroTooltipSeen() onDismiss() } .show(TooltipPopup.POSITION_ABOVE) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt index b2ace0427c..8860740a80 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt @@ -97,7 +97,6 @@ import org.thoughtcrime.securesms.sms.MessageSender import org.thoughtcrime.securesms.util.BubbleUtil import org.thoughtcrime.securesms.util.ConversationUtil import org.thoughtcrime.securesms.util.NetworkUtil -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.hasGiftBadge import org.thoughtcrime.securesms.util.rx.RxStore import org.thoughtcrime.securesms.wallpaper.ChatWallpaper @@ -320,7 +319,7 @@ class ConversationViewModel( messageRequestState = messageRequestRepository.getMessageRequestState(recipient, threadId), groupRecord = groupRecord.orNull(), isClientExpired = SignalStore.misc.isClientDeprecated, - isUnauthorized = TextSecurePreferences.isUnauthorizedReceived(AppDependencies.application), + isUnauthorized = SignalStore.account.isUnauthorizedReceived, threadContainsSms = !recipient.isRegistered && !recipient.isPushGroup && !recipient.isSelf && messageRequestRepository.threadContainsSms(threadId) ) }.doOnNext { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java index 65546e30fe..dce5583698 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java @@ -168,7 +168,6 @@ import org.thoughtcrime.securesms.util.RemoteConfig; import org.thoughtcrime.securesms.util.SignalLocalMetrics; import org.thoughtcrime.securesms.util.SignalProxyUtil; import org.thoughtcrime.securesms.util.SnapToTopDataObserver; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.ViewUtil; import org.thoughtcrime.securesms.util.adapter.mapping.PagingMappingAdapter; import org.thoughtcrime.securesms.verify.SelfVerificationFailureSheet; @@ -453,7 +452,7 @@ public class ConversationListFragment extends MainFragment implements Conversati if (SignalStore.account().isRegistered() && SignalStore.registration().isRegistrationComplete() && - !TextSecurePreferences.isUnauthorizedReceived(requireContext()) && + !SignalStore.account().isUnauthorizedReceived() && SignalStore.settings().getAutomaticVerificationEnabled() && SignalStore.misc().getHasKeyTransparencyFailure() && !SignalStore.misc().getHasSeenKeyTransparencyFailure()) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalServiceAccountDataStoreImpl.java b/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalServiceAccountDataStoreImpl.java index d849e1acea..562b6fe433 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalServiceAccountDataStoreImpl.java +++ b/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalServiceAccountDataStoreImpl.java @@ -16,7 +16,6 @@ import org.signal.libsignal.protocol.state.PreKeyRecord; import org.signal.libsignal.protocol.state.SessionRecord; import org.signal.libsignal.protocol.state.SignedPreKeyRecord; import org.thoughtcrime.securesms.keyvalue.SignalStore; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.signalservice.api.SignalServiceAccountDataStore; import org.whispersystems.signalservice.api.push.DistributionId; 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 01ee31b24a..b18526af29 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadTable.kt @@ -2458,7 +2458,7 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa ) } ?: Recipient.live(recipientId).get() } else { - RecipientCreator.forIndividual(context, recipientSettings) + RecipientCreator.forIndividual(recipientSettings) } val hasReadReceipt = SignalStore.settings.isReadReceiptsEnabled && cursor.requireBoolean(HAS_READ_RECEIPT) diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java index 8d231678c0..27aac5eac1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java @@ -120,7 +120,6 @@ import org.thoughtcrime.securesms.util.Environment; import org.thoughtcrime.securesms.util.FrameRateTracker; import org.thoughtcrime.securesms.util.PreKeyBatcher; import org.thoughtcrime.securesms.util.RemoteConfig; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.video.exo.GiphyMp4Cache; import org.thoughtcrime.securesms.video.exo.SimpleExoPlayerPool; import org.thoughtcrime.securesms.webrtc.audio.AudioManagerCompat; @@ -247,7 +246,7 @@ public class ApplicationDependencyProvider implements AppDependencies.Provider { @Override public @NonNull LiveRecipientCache provideRecipientCache() { - return new LiveRecipientCache(context); + return new LiveRecipientCache(); } @Override @@ -262,7 +261,7 @@ public class ApplicationDependencyProvider implements AppDependencies.Provider { .setConstraintFactories(JobManagerFactories.getConstraintFactories(context)) .setConstraintObservers(JobManagerFactories.getConstraintObservers(context)) .setJobStorage(new FastJobStorage(JobDatabase.getInstance(context))) - .setJobMigrator(new JobMigrator(TextSecurePreferences.getJobManagerVersion(context), JobManager.CURRENT_VERSION, JobManagerFactories.getJobMigrations(context))) + .setJobMigrator(new JobMigrator(SignalStore.misc().getJobManagerVersion(), JobManager.CURRENT_VERSION, JobManagerFactories.getJobMigrations(context))) .addReservedJobRunner(new FactoryJobPredicate(PushProcessMessageJob.KEY, MarkerJob.KEY)) .addReservedJobRunner(new FactoryJobPredicate(AttachmentUploadJob.KEY, AttachmentCompressionJob.KEY)) .addReservedJobRunner(new FactoryJobPredicate( @@ -421,7 +420,7 @@ public class ApplicationDependencyProvider implements AppDependencies.Provider { }; SignalWebSocket.AuthenticatedWebSocket webSocket = new SignalWebSocket.AuthenticatedWebSocket(authFactory, - () -> !SignalStore.misc().isClientDeprecated() && SignalStore.account().isRegistered() && !TextSecurePreferences.isUnauthorizedReceived(context) && !DeviceTransferBlockingInterceptor.getInstance().isBlockingNetwork() && !Environment.IS_INSTRUMENTATION, + () -> !SignalStore.misc().isClientDeprecated() && SignalStore.account().isRegistered() && !SignalStore.account().isUnauthorizedReceived() && !DeviceTransferBlockingInterceptor.getInstance().isBlockingNetwork() && !Environment.IS_INSTRUMENTATION, sleepTimer, TimeUnit.SECONDS.toMillis(30)); if (AppForegroundObserver.isForegrounded()) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceServerTask.java b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceServerTask.java index ab8e8f6d58..c6bb0ce3f3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceServerTask.java +++ b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceServerTask.java @@ -15,7 +15,6 @@ import org.signal.devicetransfer.NewDeviceRestoreStatus; import org.signal.devicetransfer.ServerTask; import org.thoughtcrime.securesms.AppInitialization; import org.thoughtcrime.securesms.backup.BackupEvent; -import org.thoughtcrime.securesms.backup.BackupPassphrase; import org.thoughtcrime.securesms.backup.FullBackupImporter; import org.thoughtcrime.securesms.crypto.AppAttachmentSecretStore; import org.thoughtcrime.securesms.database.SignalDatabase; @@ -50,7 +49,7 @@ public final class NewDeviceServerTask implements ServerTask { String passphrase = SignalStore.account().getAccountEntropyPool().getValue(); - BackupPassphrase.set(context, passphrase); + SignalStore.backup().setV1BackupPassphrase(passphrase); FullBackupImporter.importFile(context, AttachmentSecretProvider.getInstance(context, AppAttachmentSecretStore.INSTANCE).getOrCreateAttachmentSecret(), database, diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobManager.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobManager.java index 4cd17f101a..d4009e344c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobManager.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobManager.java @@ -16,8 +16,8 @@ import org.thoughtcrime.securesms.jobmanager.impl.DefaultExecutorFactory; import org.thoughtcrime.securesms.jobmanager.persistence.JobSpec; import org.thoughtcrime.securesms.jobmanager.persistence.JobStorage; import org.thoughtcrime.securesms.jobs.MinimalJobSpec; +import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.signal.core.util.Debouncer; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.signal.core.util.Util; import org.signal.core.util.concurrent.FilteredExecutor; @@ -87,7 +87,7 @@ public class JobManager implements ConstraintObserver.Notifier { jobStorage.init(); int latestVersion = configuration.getJobMigrator().migrate(jobStorage); - TextSecurePreferences.setJobManagerVersion(application, latestVersion); + SignalStore.misc().setJobManagerVersion(latestVersion); jobController.init(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/ArchiveBackupIdReservationJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/ArchiveBackupIdReservationJob.kt index 0e439607df..2d93f83862 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/ArchiveBackupIdReservationJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/ArchiveBackupIdReservationJob.kt @@ -14,7 +14,6 @@ import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.net.SignalNetwork import org.thoughtcrime.securesms.util.RemoteConfig -import org.thoughtcrime.securesms.util.TextSecurePreferences /** * Reserves backupIds for both text+media. The intention is that every registered user should be doing this, so it should happen post-registration @@ -49,7 +48,7 @@ class ArchiveBackupIdReservationJob private constructor(parameters: Parameters) return Result.success() } - if (TextSecurePreferences.isUnauthorizedReceived(context)) { + if (SignalStore.account.isUnauthorizedReceived) { Log.w(TAG, "Not authorized. Skipping.") return Result.success() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/BackupMessagesJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/BackupMessagesJob.kt index 01c0895ce6..8986bd798d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/BackupMessagesJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/BackupMessagesJob.kt @@ -56,7 +56,6 @@ import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.storage.StorageSyncHelper import org.thoughtcrime.securesms.util.MediaUtil import org.thoughtcrime.securesms.util.RemoteConfig -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.signalservice.api.messages.AttachmentTransferProgress import org.whispersystems.signalservice.api.messages.SignalServiceAttachment import org.whispersystems.signalservice.api.push.exceptions.ResumeLocationInvalidException @@ -90,7 +89,7 @@ class BackupMessagesJob private constructor( const val KEY = "BackupMessagesJob" private fun isRegistered(): Boolean { - return SignalStore.account.isRegistered && !TextSecurePreferences.isUnauthorizedReceived(AppDependencies.application) + return SignalStore.account.isRegistered && !SignalStore.account.isUnauthorizedReceived } private fun isBackupAllowed(): Boolean { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/CheckKeyTransparencyJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/CheckKeyTransparencyJob.kt index e2630839a6..d56cc5c1d1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/CheckKeyTransparencyJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/CheckKeyTransparencyJob.kt @@ -18,7 +18,6 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.net.SignalNetwork import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.util.RemoteConfig -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.signalservice.api.crypto.UnidentifiedAccess import kotlin.random.Random import kotlin.time.Duration.Companion.days @@ -93,7 +92,7 @@ class CheckKeyTransparencyJob private constructor( } else if (!SignalStore.registration.isRegistrationComplete) { Log.i(TAG, "Registration is not complete. Exiting.") false - } else if (TextSecurePreferences.isUnauthorizedReceived(AppDependencies.application)) { + } else if (SignalStore.account.isUnauthorizedReceived) { Log.i(TAG, "Account is unauthorized. Exiting.") false } else if (!SignalStore.settings.automaticVerificationEnabled) { @@ -190,7 +189,7 @@ class CheckKeyTransparencyJob private constructor( * For others, it will only show once and only be cleared on the next successful verification. */ private fun markFailure() { - if (SignalStore.account.isRegistered && !TextSecurePreferences.isUnauthorizedReceived(AppDependencies.application)) { + if (SignalStore.account.isRegistered && !SignalStore.account.isUnauthorizedReceived) { SignalStore.misc.hasKeyTransparencyFailure = true if (RemoteConfig.internalUser) { SignalStore.misc.hasSeenKeyTransparencyFailure = false diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/CheckServiceReachabilityJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/CheckServiceReachabilityJob.kt index 90ba789368..2f1f108ff9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/CheckServiceReachabilityJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/CheckServiceReachabilityJob.kt @@ -7,7 +7,6 @@ import org.thoughtcrime.securesms.jobmanager.Job import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.stories.Stories -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.signalservice.api.websocket.WebSocketConnectionState import org.whispersystems.signalservice.internal.util.StaticCredentialsProvider import org.whispersystems.signalservice.internal.websocket.OkHttpWebSocketConnection @@ -35,9 +34,8 @@ class CheckServiceReachabilityJob private constructor(params: Parameters) : Base @JvmStatic fun enqueueIfNecessary() { val isCensored = AppDependencies.signalServiceNetworkAccess.isCensored() - val context = AppDependencies.application val timeSinceLastCheck = System.currentTimeMillis() - SignalStore.misc.lastCensorshipServiceReachabilityCheckTime - if (SignalStore.account.isRegistered && !TextSecurePreferences.isUnauthorizedReceived(context) && isCensored && timeSinceLastCheck > TimeUnit.DAYS.toMillis(1)) { + if (SignalStore.account.isRegistered && !SignalStore.account.isUnauthorizedReceived && isCensored && timeSinceLastCheck > TimeUnit.DAYS.toMillis(1)) { AppDependencies.jobManager.add(CheckServiceReachabilityJob()) } } @@ -58,7 +56,7 @@ class CheckServiceReachabilityJob private constructor(params: Parameters) : Base return } - if (TextSecurePreferences.isUnauthorizedReceived(context)) { + if (SignalStore.account.isUnauthorizedReceived) { Log.w(TAG, "Unauthorized received, skipping.") SignalStore.misc.lastCensorshipServiceReachabilityCheckTime = System.currentTimeMillis() return diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/FcmRefreshJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/FcmRefreshJob.java index e24fc1b45e..081575aa44 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/FcmRefreshJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/FcmRefreshJob.java @@ -33,7 +33,6 @@ import org.thoughtcrime.securesms.messages.IncomingMessageObserver; import org.thoughtcrime.securesms.net.SignalNetwork; import org.thoughtcrime.securesms.transport.RetryLaterException; import org.signal.core.util.PlayServicesUtil; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.signalservice.api.RequestResultUtil; import org.signal.network.exceptions.NonSuccessfulResponseCodeException; @@ -73,7 +72,7 @@ public class FcmRefreshJob extends BaseJob { @Override public void onRun() throws Exception { - if (TextSecurePreferences.isUnauthorizedReceived(context)) { + if (SignalStore.account().isUnauthorizedReceived()) { Log.i(TAG, "No longer authorized. Ignoring."); return; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/LocalBackupJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/LocalBackupJob.java index 5fd59f168f..e39991a62b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/LocalBackupJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/LocalBackupJob.java @@ -19,7 +19,6 @@ import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.backup.BackupEvent; import org.thoughtcrime.securesms.backup.BackupFileIOError; -import org.thoughtcrime.securesms.backup.BackupPassphrase; import org.thoughtcrime.securesms.backup.BackupVerifier; import org.thoughtcrime.securesms.backup.FullBackupExporter; import org.thoughtcrime.securesms.crypto.AppAttachmentSecretStore; @@ -27,6 +26,7 @@ import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.AppDependencies; import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.jobmanager.JobManager; +import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.notifications.NotificationChannels; import org.thoughtcrime.securesms.service.GenericForegroundService; import org.thoughtcrime.securesms.service.NotificationController; @@ -124,7 +124,7 @@ public final class LocalBackupJob extends BaseJob { EventBus.getDefault().register(updater); notification.setIndeterminateProgress(); - String backupPassword = BackupPassphrase.get(context); + String backupPassword = SignalStore.backup().getV1BackupPassphrase(); File backupDirectory = StorageUtil.getOrCreateBackupDirectory(); String timestamp = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.US).format(new Date()); String fileName = String.format("signal-%s.backup", timestamp); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/LocalBackupJobApi29.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/LocalBackupJobApi29.java index 684619bd85..dbc6291bc1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/LocalBackupJobApi29.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/LocalBackupJobApi29.java @@ -20,7 +20,6 @@ import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.backup.BackupEvent; import org.thoughtcrime.securesms.backup.BackupFileIOError; -import org.thoughtcrime.securesms.backup.BackupPassphrase; import org.thoughtcrime.securesms.backup.BackupVerifier; import org.thoughtcrime.securesms.backup.FullBackupExporter; import org.thoughtcrime.securesms.crypto.AppAttachmentSecretStore; @@ -102,7 +101,7 @@ public final class LocalBackupJobApi29 extends BaseJob { notification.setIndeterminateProgress(); } - String backupPassword = BackupPassphrase.get(context); + String backupPassword = SignalStore.backup().getV1BackupPassphrase(); DocumentFile backupDirectory = DocumentFile.fromTreeUri(context, backupDirectoryUri); String timestamp = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.US).format(new Date()); String fileName = String.format("signal-%s.backup", timestamp); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java index 8d46c890ce..83a5b100cd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java @@ -32,7 +32,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.whispersystems.signalservice.api.SignalServiceMessageSender; import org.whispersystems.signalservice.api.crypto.AttachmentCipherStreamUtil; import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException; @@ -196,18 +195,18 @@ public class MultiDeviceContactUpdateJob extends BaseJob { throws IOException, UntrustedIdentityException, NetworkException, NoSessionException { boolean isAppVisible = AppForegroundObserver.isForegrounded(); - long timeSinceLastSync = System.currentTimeMillis() - TextSecurePreferences.getLastFullContactSyncTime(context); + long timeSinceLastSync = System.currentTimeMillis() - SignalStore.misc().getLastFullContactSyncTime(); Log.d(TAG, "Requesting a full contact sync. forced = " + forceSync + ", appVisible = " + isAppVisible + ", timeSinceLastSync = " + timeSinceLastSync + " ms"); if (!forceSync && !isAppVisible && timeSinceLastSync < FULL_SYNC_TIME) { Log.i(TAG, "App is backgrounded and the last contact sync was too soon (" + timeSinceLastSync + " ms ago). Marking that we need a sync. Skipping multi-device contact update..."); - TextSecurePreferences.setNeedsFullContactSync(context, true); + SignalStore.misc().setNeedsFullContactSync(true); return; } - TextSecurePreferences.setLastFullContactSyncTime(context, System.currentTimeMillis()); - TextSecurePreferences.setNeedsFullContactSync(context, false); + SignalStore.misc().setLastFullContactSyncTime(System.currentTimeMillis()); + SignalStore.misc().setNeedsFullContactSync(false); WriteDetails writeDetails = createTempFile(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceProfileContentUpdateJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceProfileContentUpdateJob.java index bfdab14fc9..1b2893442f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceProfileContentUpdateJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceProfileContentUpdateJob.java @@ -11,7 +11,6 @@ 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.util.TextSecurePreferences; import org.whispersystems.signalservice.api.SignalServiceMessageSender; import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage; import org.signal.network.exceptions.PushNetworkException; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceStickerPackOperationJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceStickerPackOperationJob.java index ed83e7897e..ebe2ef3e1d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceStickerPackOperationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceStickerPackOperationJob.java @@ -11,7 +11,6 @@ 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.util.TextSecurePreferences; import org.whispersystems.signalservice.api.SignalServiceMessageSender; import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage; import org.whispersystems.signalservice.api.messages.multidevice.StickerPackOperationMessage; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceStorageSyncRequestJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceStorageSyncRequestJob.java index beab6c40a7..4c35be76e6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceStorageSyncRequestJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceStorageSyncRequestJob.java @@ -11,7 +11,6 @@ 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.util.TextSecurePreferences; import org.whispersystems.signalservice.api.SignalServiceMessageSender; import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage; import org.signal.network.exceptions.PushNetworkException; 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 5c197d3c21..a44a0a2502 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshAttributesJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshAttributesJob.java @@ -20,7 +20,6 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.keyvalue.SvrValues; import org.thoughtcrime.securesms.net.SignalNetwork; import org.thoughtcrime.securesms.registration.data.RegistrationRepository; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.signalservice.api.NetworkResultUtil; import org.whispersystems.signalservice.api.RequestResultUtil; import org.whispersystems.signalservice.api.account.AccountAttributes; @@ -109,7 +108,7 @@ public class RefreshAttributesJob extends BaseJob { return; } - if (TextSecurePreferences.isUnauthorizedReceived(context)) { + if (SignalStore.account().isUnauthorizedReceived()) { Log.i(TAG, "No longer authorized. Ignoring."); return; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshSvrCredentialsJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshSvrCredentialsJob.kt index 35b58fb1a5..1342c09935 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshSvrCredentialsJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshSvrCredentialsJob.kt @@ -7,7 +7,6 @@ import org.thoughtcrime.securesms.jobmanager.Job import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.pin.SvrRepository -import org.thoughtcrime.securesms.util.TextSecurePreferences import java.io.IOException import kotlin.time.Duration import kotlin.time.Duration.Companion.days @@ -25,7 +24,7 @@ class RefreshSvrCredentialsJob private constructor(parameters: Parameters) : Bas @JvmStatic fun enqueueIfNecessary() { - if (SignalStore.svr.hasPin() && SignalStore.account.isRegistered && !TextSecurePreferences.isUnauthorizedReceived(AppDependencies.application)) { + if (SignalStore.svr.hasPin() && SignalStore.account.isRegistered && !SignalStore.account.isUnauthorizedReceived) { val lastTimestamp = SignalStore.svr.lastRefreshAuthTimestamp if (lastTimestamp + FREQUENCY.inWholeMilliseconds < System.currentTimeMillis() || lastTimestamp > System.currentTimeMillis()) { AppDependencies.jobManager.add(RefreshSvrCredentialsJob()) @@ -56,7 +55,7 @@ class RefreshSvrCredentialsJob private constructor(parameters: Parameters) : Bas return } - if (TextSecurePreferences.isUnauthorizedReceived(context)) { + if (SignalStore.account.isUnauthorizedReceived) { Log.i(TAG, "No longer authorized. Ignoring.") return } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RemoteConfigRefreshJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/RemoteConfigRefreshJob.kt index 913de3e221..f28998bb92 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RemoteConfigRefreshJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RemoteConfigRefreshJob.kt @@ -8,7 +8,6 @@ import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.net.SignalNetwork import org.thoughtcrime.securesms.util.RemoteConfig -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.signalservice.api.websocket.SignalWebSocket import kotlin.time.Duration.Companion.days @@ -45,7 +44,7 @@ class RemoteConfigRefreshJob private constructor(parameters: Parameters) : Job(p return Result.success() } - if (TextSecurePreferences.isUnauthorizedReceived(context)) { + if (SignalStore.account.isUnauthorizedReceived) { Log.i(TAG, "No longer authorized. Ignoring.") return Result.success() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileJob.kt index 644c8014ff..6927e037e9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileJob.kt @@ -101,7 +101,7 @@ class RetrieveProfileJob private constructor(parameters: Parameters, private val val recipientsToFetch = SignalDatabase .recipients .getRecordsForProfileFetch(recipientIds, debounceThreshold) - .map { RecipientCreator.forRecord(context, it) } + .map { RecipientCreator.forRecord(it) } stopwatch.split("resolve") diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RotateCertificateJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/RotateCertificateJob.java index a185d98d4b..973e0c0fe5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RotateCertificateJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RotateCertificateJob.java @@ -13,7 +13,6 @@ import org.thoughtcrime.securesms.keyvalue.CertificateType; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.net.SignalNetwork; import org.thoughtcrime.securesms.util.ExceptionHelper; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.signalservice.api.NetworkResultUtil; import java.io.IOException; @@ -60,7 +59,7 @@ public final class RotateCertificateJob extends BaseJob { return; } - if (TextSecurePreferences.isUnauthorizedReceived(context)) { + if (SignalStore.account().isUnauthorizedReceived()) { Log.i(TAG, "No longer authorized. Ignoring."); return; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/ServiceOutageDetectionJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/ServiceOutageDetectionJob.java index 4c50ecbd65..580af39f2d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/ServiceOutageDetectionJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/ServiceOutageDetectionJob.java @@ -7,8 +7,8 @@ import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; +import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.transport.RetryLaterException; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import java.net.InetAddress; import java.net.UnknownHostException; @@ -50,7 +50,7 @@ public class ServiceOutageDetectionJob extends BaseJob { public void onRun() throws RetryLaterException { Log.i(TAG, "onRun()"); - long timeSinceLastCheck = System.currentTimeMillis() - TextSecurePreferences.getLastOutageCheckTime(context); + long timeSinceLastCheck = System.currentTimeMillis() - SignalStore.misc().getLastOutageCheckTime(); if (timeSinceLastCheck < CHECK_TIME) { Log.w(TAG, "Skipping service outage check. Too soon."); return; @@ -62,16 +62,16 @@ public class ServiceOutageDetectionJob extends BaseJob { if (IP_SUCCESS.equals(address.getHostAddress())) { Log.i(TAG, "Service is available."); - TextSecurePreferences.setServiceOutage(context, false); + SignalStore.misc().setServiceOutage(false); } else if (IP_FAILURE.equals(address.getHostAddress())) { Log.w(TAG, "Service is down."); - TextSecurePreferences.setServiceOutage(context, true); + SignalStore.misc().setServiceOutage(true); } else { Log.w(TAG, "Service status check returned an unrecognized IP address. Could be a weird network state. Prompting retry."); throw new RetryLaterException(new Exception("Unrecognized service outage IP address.")); } - TextSecurePreferences.setLastOutageCheckTime(context, System.currentTimeMillis()); + SignalStore.misc().setLastOutageCheckTime(System.currentTimeMillis()); } catch (UnknownHostException e) { throw new RetryLaterException(e); } @@ -85,8 +85,8 @@ public class ServiceOutageDetectionJob extends BaseJob { @Override public void onFailure() { Log.i(TAG, "Service status check could not complete. Assuming success to avoid false positives due to bad network."); - TextSecurePreferences.setServiceOutage(context, false); - TextSecurePreferences.setLastOutageCheckTime(context, System.currentTimeMillis()); + SignalStore.misc().setServiceOutage(false); + SignalStore.misc().setLastOutageCheckTime(System.currentTimeMillis()); } public static final class Factory implements Job.Factory { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageAccountRestoreJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageAccountRestoreJob.kt index ae1ab8aae0..426e7a96f8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageAccountRestoreJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageAccountRestoreJob.kt @@ -112,7 +112,7 @@ class StorageAccountRestoreJob private constructor(parameters: Parameters) : Bas Log.i(TAG, "Applying changes locally...") SignalDatabase.writableDatabase.beginTransaction() try { - StorageSyncHelper.applyAccountStorageSyncUpdates(context, self().fresh(), accountRecord, false) + StorageSyncHelper.applyAccountStorageSyncUpdates(self().fresh(), accountRecord, false) SignalDatabase.writableDatabase.setTransactionSuccessful() } finally { SignalDatabase.writableDatabase.endTransaction() diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageForcePushJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageForcePushJob.kt index b5b1603226..918a950836 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageForcePushJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageForcePushJob.kt @@ -95,7 +95,7 @@ class StorageForcePushJob private constructor(parameters: Parameters) : BaseJob( .map { record -> StorageSyncModels.localToRemoteRecord(record, newContactStorageIds[record.id]!!.raw) } .toMutableList() - val accountRecord = StorageSyncHelper.buildAccountRecord(context, Recipient.self().fresh()) + val accountRecord = StorageSyncHelper.buildAccountRecord(Recipient.self().fresh()) val allNewStorageIds: MutableList = ArrayList(newContactStorageIds.values) inserts.add(accountRecord) diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJob.kt index 861861dacf..d8a19bbae1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJob.kt @@ -39,7 +39,6 @@ import org.thoughtcrime.securesms.storage.StorageSyncValidations import org.thoughtcrime.securesms.storage.StoryDistributionListRecordProcessor import org.thoughtcrime.securesms.transport.RetryLaterException import org.thoughtcrime.securesms.util.RemoteConfig -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException import org.whispersystems.signalservice.api.messages.multidevice.RequestMessage import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage @@ -191,7 +190,7 @@ class StorageSyncJob private constructor(parameters: Parameters, private var loc return } - if (TextSecurePreferences.isUnauthorizedReceived(context)) { + if (SignalStore.account.isUnauthorizedReceived) { Log.i(TAG, "No longer authorized. Ignoring.") return } @@ -528,7 +527,7 @@ class StorageSyncJob private constructor(parameters: Parameters, private var loc ContactRecordProcessor(identityConflictsPendingRepair).process(records.contacts, StorageSyncHelper.KEY_GENERATOR) GroupV2RecordProcessor().process(records.gv2, StorageSyncHelper.KEY_GENERATOR) NotificationProfileRecordProcessor().process(records.notificationProfileRecords, StorageSyncHelper.KEY_GENERATOR) - AccountRecordProcessor(context, freshSelf()).process(records.account, StorageSyncHelper.KEY_GENERATOR) + AccountRecordProcessor(freshSelf()).process(records.account, StorageSyncHelper.KEY_GENERATOR) StoryDistributionListRecordProcessor().process(records.storyDistributionLists, StorageSyncHelper.KEY_GENERATOR) CallLinkRecordProcessor().process(records.callLinkRecords, StorageSyncHelper.KEY_GENERATOR) ChatFolderRecordProcessor().process(records.chatFolderRecords, StorageSyncHelper.KEY_GENERATOR) @@ -575,7 +574,7 @@ class StorageSyncJob private constructor(parameters: Parameters, private var loc if (!self.storageId.contentEquals(id.raw)) { throw AssertionError("Local storage ID doesn't match self!") } - records.add(StorageSyncHelper.buildAccountRecord(context, self)) + records.add(StorageSyncHelper.buildAccountRecord(self)) } ManifestRecord.Identifier.Type.STORY_DISTRIBUTION_LIST -> { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/Svr2MirrorJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/Svr2MirrorJob.kt index 92fe50c838..658cacaac3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/Svr2MirrorJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/Svr2MirrorJob.kt @@ -14,7 +14,6 @@ import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.pin.Svr3Migration import org.thoughtcrime.securesms.pin.SvrRepository -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.signalservice.api.svr.SecureValueRecovery.BackupResponse import org.whispersystems.signalservice.api.svr.SecureValueRecovery.PinChangeSession import org.whispersystems.signalservice.api.svr.SecureValueRecoveryV2 @@ -61,7 +60,7 @@ class Svr2MirrorJob private constructor(parameters: Parameters, private var seri return Result.success() } - if (TextSecurePreferences.isUnauthorizedReceived(context)) { + if (SignalStore.account.isUnauthorizedReceived) { Log.w(TAG, "Not authorized. Skipping.") return Result.success() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/EmojiKeyboardPageRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/EmojiKeyboardPageRepository.kt index b707f453d1..a688d17741 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/EmojiKeyboardPageRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/EmojiKeyboardPageRepository.kt @@ -5,14 +5,13 @@ import org.signal.core.util.concurrent.SignalExecutors import org.signal.emoji.EmojiPageModel import org.signal.emoji.EmojiSource.Companion.latest import org.thoughtcrime.securesms.components.emoji.RecentEmojiPageModel -import org.thoughtcrime.securesms.util.TextSecurePreferences import java.util.function.Consumer class EmojiKeyboardPageRepository(private val context: Context) { fun getEmoji(consumer: Consumer>) { SignalExecutors.BOUNDED.execute { val list = mutableListOf() - list += RecentEmojiPageModel(context, TextSecurePreferences.RECENT_STORAGE_KEY) + list += RecentEmojiPageModel(context, RecentEmojiPageModel.RECENT_STORAGE_KEY) list += latest.displayPages consumer.accept(list) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/EmojiKeyboardPageViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/EmojiKeyboardPageViewModel.kt index fbde79010d..e014f67178 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/EmojiKeyboardPageViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/EmojiKeyboardPageViewModel.kt @@ -12,7 +12,6 @@ import org.thoughtcrime.securesms.components.emoji.EmojiPageViewGridAdapter.Emoj import org.thoughtcrime.securesms.components.emoji.RecentEmojiPageModel import org.thoughtcrime.securesms.dependencies.AppDependencies import org.thoughtcrime.securesms.util.DefaultValueLiveData -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.adapter.mapping.MappingModelList import org.thoughtcrime.securesms.util.livedata.LiveDataUtil @@ -68,7 +67,7 @@ class EmojiKeyboardPageViewModel(private val repository: EmojiKeyboardPageReposi companion object { fun getStartingTab(): String { - return if (RecentEmojiPageModel.hasRecents(AppDependencies.application, TextSecurePreferences.RECENT_STORAGE_KEY)) { + return if (RecentEmojiPageModel.hasRecents(AppDependencies.application, RecentEmojiPageModel.RECENT_STORAGE_KEY)) { RecentEmojiPageModel.KEY } else { EmojiCategory.PEOPLE.key diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/search/EmojiSearchRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/search/EmojiSearchRepository.kt index ff9897e87a..7a53db2799 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/search/EmojiSearchRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyboard/emoji/search/EmojiSearchRepository.kt @@ -11,7 +11,6 @@ import org.signal.emoji.EmojiSource import org.thoughtcrime.securesms.components.emoji.RecentEmojiPageModel import org.thoughtcrime.securesms.database.EmojiSearchTable import org.thoughtcrime.securesms.database.SignalDatabase -import org.thoughtcrime.securesms.util.TextSecurePreferences import java.util.function.Consumer private const val MINIMUM_QUERY_THRESHOLD = 1 @@ -36,7 +35,7 @@ class EmojiSearchRepository(private val context: Context) { fun submitQuery(query: String, includeRecents: Boolean, limit: Int = EMOJI_SEARCH_LIMIT, consumer: Consumer) { if (query.length < MINIMUM_QUERY_THRESHOLD && includeRecents) { - consumer.accept(RecentEmojiPageModel(context, TextSecurePreferences.RECENT_STORAGE_KEY)) + consumer.accept(RecentEmojiPageModel(context, RecentEmojiPageModel.RECENT_STORAGE_KEY)) } else { SignalExecutors.SERIAL.execute { val emoji: List = emojiSearchTable.query(query, limit) diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/AccountValues.kt b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/AccountValues.kt index 3e5b8abf7e..88aeec7702 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/AccountValues.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/AccountValues.kt @@ -26,9 +26,9 @@ import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.dependencies.AppDependencies import org.thoughtcrime.securesms.jobmanager.impl.RegisteredConstraint import org.thoughtcrime.securesms.jobs.PreKeysSyncJob +import org.thoughtcrime.securesms.notifications.UnregisteredNotifier import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.service.KeyCachingService -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.signalservice.api.push.ServiceIds import org.whispersystems.signalservice.api.push.SignalServiceAddress import org.whispersystems.signalservice.api.push.UsernameLinkComponents @@ -84,6 +84,7 @@ class AccountValues internal constructor(store: KeyValueStore, context: Context) private const val KEY_ACI = "account.aci" private const val KEY_PNI = "account.pni" private const val KEY_IS_REGISTERED = "account.is_registered" + private const val KEY_IS_UNAUTHORIZED_RECEIVED = "account.is_unauthorized_received" private const val KEY_ACCOUNT_REGISTERED_AT = "account.registered_at" private const val KEY_HAS_LINKED_DEVICES = "account.has_linked_devices" @@ -113,6 +114,10 @@ class AccountValues internal constructor(store: KeyValueStore, context: Context) migrateFromSharedPrefsV3(context) } + if (!store.containsKey(KEY_IS_UNAUTHORIZED_RECEIVED)) { + migrateFromSharedPrefsV4(context) + } + store.getString(KEY_PNI, null)?.let { pni -> if (!pni.startsWith("PNI:")) { store.beginWrite().putString(KEY_PNI, "PNI:$pni").commit() @@ -516,6 +521,32 @@ class AccountValues internal constructor(store: KeyValueStore, context: Context) RegisteredConstraint.Observer.notifyListeners() } + /** + * Whether the service has rejected our credentials on the authenticated websocket, i.e. we've been deregistered or unlinked remotely. + * + * This is distinct from [isRegistered], which tracks whether *we* believe this install completed registration. This flag is the service's verdict, and + * it is cleared automatically the next time we successfully authenticate. Note that setting it rotates the profile key, so it is not a free toggle. + */ + var isUnauthorizedReceived: Boolean + get() = getBoolean(KEY_IS_UNAUTHORIZED_RECEIVED, false) + set(value) { + val previous = isUnauthorizedReceived + + putBoolean(KEY_IS_UNAUTHORIZED_RECEIVED, value) + + if (previous != value) { + Recipient.self().live().refresh() + + if (value) { + UnregisteredNotifier.notify(AppDependencies.application) + rotateProfileKey() + BackupRepository.haltBackupWritesForDeregistration() + } else { + UnregisteredNotifier.cancel(AppDependencies.application) + } + } + } + /** * Milliseconds since epoch when account was registered or a negative value if not known. */ @@ -604,7 +635,14 @@ class AccountValues internal constructor(store: KeyValueStore, context: Context) private fun clearLocalCredentials() { putString(KEY_SERVICE_PASSWORD, Util.getSecret(18)) + rotateProfileKey() + } + /** + * Note that unlike [clearLocalCredentials] this leaves the service password alone, so we can still attempt to authenticate. Important for the + * [isUnauthorizedReceived] path, which needs to be able to recover on its own. + */ + private fun rotateProfileKey() { val newProfileKey = ProfileKeyUtil.createNew() val self = Recipient.self() @@ -630,15 +668,15 @@ class AccountValues internal constructor(store: KeyValueStore, context: Context) private fun migrateFromSharedPrefsV1(context: Context) { Log.i(TAG, "[V1] Migrating account values from shared prefs.") - putString(KEY_ACI, TextSecurePreferences.getStringPreference(context, "pref_local_uuid", null)) - putString(KEY_E164, TextSecurePreferences.getStringPreference(context, "pref_local_number", null)) - putString(KEY_SERVICE_PASSWORD, TextSecurePreferences.getStringPreference(context, "pref_gcm_password", null)) - putBoolean(KEY_IS_REGISTERED, TextSecurePreferences.getBooleanPreference(context, "pref_gcm_registered", false)) - putInteger(KEY_REGISTRATION_ID, TextSecurePreferences.getIntegerPreference(context, "pref_local_registration_id", 0)) - putBoolean(KEY_FCM_ENABLED, !TextSecurePreferences.getBooleanPreference(context, "pref_gcm_disabled", false)) - putString(KEY_FCM_TOKEN, TextSecurePreferences.getStringPreference(context, "pref_gcm_registration_id", null)) - putInteger(KEY_FCM_TOKEN_VERSION, TextSecurePreferences.getIntegerPreference(context, "pref_gcm_registration_id_version", 0)) - putLong(KEY_FCM_TOKEN_LAST_SET_TIME, TextSecurePreferences.getLongPreference(context, "pref_gcm_registration_id_last_set_time", 0)) + putString(KEY_ACI, LegacySharedPrefs.getStringOrNull(context, "pref_local_uuid")) + putString(KEY_E164, LegacySharedPrefs.getStringOrNull(context, "pref_local_number")) + putString(KEY_SERVICE_PASSWORD, LegacySharedPrefs.getStringOrNull(context, "pref_gcm_password")) + putBoolean(KEY_IS_REGISTERED, LegacySharedPrefs.getBoolean(context, "pref_gcm_registered", false)) + putInteger(KEY_REGISTRATION_ID, LegacySharedPrefs.getInteger(context, "pref_local_registration_id", 0)) + putBoolean(KEY_FCM_ENABLED, !LegacySharedPrefs.getBoolean(context, "pref_gcm_disabled", false)) + putString(KEY_FCM_TOKEN, LegacySharedPrefs.getStringOrNull(context, "pref_gcm_registration_id")) + putInteger(KEY_FCM_TOKEN_VERSION, LegacySharedPrefs.getInteger(context, "pref_gcm_registration_id_version", 0)) + putLong(KEY_FCM_TOKEN_LAST_SET_TIME, LegacySharedPrefs.getLong(context, "pref_gcm_registration_id_last_set_time", 0)) } /** Do not alter. If you need to migrate more stuff, create a new method. */ @@ -713,7 +751,14 @@ class AccountValues internal constructor(store: KeyValueStore, context: Context) private fun migrateFromSharedPrefsV3(context: Context) { Log.i(TAG, "[V3] Migrating account values from shared prefs.") - putBoolean(KEY_HAS_LINKED_DEVICES, TextSecurePreferences.getBooleanPreference(context, "pref_multi_device", false)) + putBoolean(KEY_HAS_LINKED_DEVICES, LegacySharedPrefs.getBoolean(context, "pref_multi_device", false)) + } + + /** Do not alter. If you need to migrate more stuff, create a new method. */ + private fun migrateFromSharedPrefsV4(context: Context) { + Log.i(TAG, "[V4] Migrating account values from shared prefs.") + + putBoolean(KEY_IS_UNAUTHORIZED_RECEIVED, LegacySharedPrefs.getBoolean(context, "pref_unauthorized_received", false)) } private fun SharedPreferences.hasStringData(key: String): Boolean { diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/ApkUpdateValues.kt b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/ApkUpdateValues.kt index 9b5a4fd7c8..d602f7c6ba 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/ApkUpdateValues.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/ApkUpdateValues.kt @@ -5,9 +5,10 @@ package org.thoughtcrime.securesms.keyvalue +import android.content.Context import org.signal.core.util.logging.Log -class ApkUpdateValues(store: KeyValueStore) : SignalStoreValues(store) { +class ApkUpdateValues(store: KeyValueStore, context: Context) : SignalStoreValues(store) { companion object { private val TAG = Log.tag(ApkUpdateValues::class.java) @@ -17,8 +18,25 @@ class ApkUpdateValues(store: KeyValueStore) : SignalStoreValues(store) { private const val LAST_SUCCESSFUL_CHECK = "apk_update.last_successful_check" private const val LAST_APK_UPLOAD_TIME = "apk_update.last_apk_upload_time" private const val PENDING_APK_UPLOAD_TIME = "apk_update.pending_apk_upload_time" + private const val REFRESH_TIME = "apk_update.refresh_time" } + init { + if (!store.containsKey(REFRESH_TIME)) { + migrateFromSharedPrefsV1(context) + } + } + + /** Do not alter. If you need to migrate more stuff, create a new method. */ + private fun migrateFromSharedPrefsV1(context: Context) { + Log.i(TAG, "[V1] Migrating apk update values from shared prefs.") + + putLong(REFRESH_TIME, LegacySharedPrefs.getLong(context, "pref_update_apk_refresh_time", 0)) + } + + /** When the next APK update check is scheduled. See [lastSuccessfulCheck] for when one last succeeded. */ + var refreshTime: Long by longValue(REFRESH_TIME, 0) + public override fun onFirstEverAppLaunch() = Unit public override fun getKeysToIncludeInBackup(): List = emptyList() diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/BackupValues.kt b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/BackupValues.kt index 0a7b6835b2..3c5201def1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/BackupValues.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/BackupValues.kt @@ -1,5 +1,6 @@ package org.thoughtcrime.securesms.keyvalue +import android.content.Context import com.fasterxml.jackson.annotation.JsonProperty import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow @@ -7,6 +8,7 @@ import okio.withLock import org.signal.core.models.backup.MediaRootBackupKey import org.signal.core.models.backup.MessageBackupKey import org.signal.core.util.LongSerializer +import org.signal.core.util.crypto.KeyStoreHelper import org.signal.core.util.logging.Log import org.signal.network.util.JsonUtil import org.thoughtcrime.securesms.backup.DeletionState @@ -29,7 +31,7 @@ import kotlin.time.Duration.Companion.days import kotlin.time.Duration.Companion.hours import kotlin.time.Duration.Companion.milliseconds -class BackupValues(store: KeyValueStore) : SignalStoreValues(store) { +class BackupValues(store: KeyValueStore, context: Context) : SignalStoreValues(store) { companion object { val TAG = Log.tag(BackupValues::class.java) private const val KEY_MESSAGE_CREDENTIALS = "backup.messageCredentials" @@ -68,6 +70,8 @@ class BackupValues(store: KeyValueStore) : SignalStoreValues(store) { private const val KEY_MESSAGE_BACKUP_INITIALIZED = "backup.messageBackupInitialized" private const val KEY_MEDIA_BACKUP_INITIALIZED = "backup.mediaBackupInitialized" private const val KEY_IMPORTED_EMPTY_ANDROID_SETTINGS = "backup.importedEmptyAndroidSettings" + private const val KEY_V1_BACKUP_PASSPHRASE = "backup.v1BackupPassphrase" + private const val KEY_V1_BACKUP_PASSPHRASE_MIGRATED = "backup.v1BackupPassphraseMigrated" const val KEY_ARCHIVE_UPLOAD_STATE = "backup.archiveUploadState" @@ -124,11 +128,56 @@ class BackupValues(store: KeyValueStore) : SignalStoreValues(store) { if (!store.containsKey(KEY_MESSAGE_BACKUP_INITIALIZED)) { migrateSplitBackupsInitialized() } + + if (!store.getBoolean(KEY_V1_BACKUP_PASSPHRASE_MIGRATED, false)) { + migrateV1BackupPassphrase(context) + } } public override fun onFirstEverAppLaunch() = Unit public override fun getKeysToIncludeInBackup(): List = emptyList() + /** + * The passphrase for legacy (v1) local backups. This store is already encrypted, so unlike the shared-prefs home it used to + * have, there's no need to seal it with the keystore by hand. + */ + var v1BackupPassphrase: String? + get() = getString(KEY_V1_BACKUP_PASSPHRASE, null)?.stripSpaces() + set(value) { + putString(KEY_V1_BACKUP_PASSPHRASE, value) + } + + /** + * Pulls the v1 backup passphrase out of shared prefs, where it lived as a hand-sealed blob because it predates this store. + * + * Do not alter. If you need to migrate more stuff, create a new method. + */ + private fun migrateV1BackupPassphrase(context: Context) { + Log.i(TAG, "[V1Passphrase] Migrating the legacy backup passphrase out of shared prefs.") + + val sealed = LegacySharedPrefs.getStringOrNull(context, "pref_encrypted_backup_passphrase") + + val passphrase = if (sealed != null) { + try { + String(KeyStoreHelper.unseal(KeyStoreHelper.SealedData.fromString(sealed))) + } catch (e: Exception) { + // Nothing we can do to recover it -- better to lose the passphrase than to fail to construct the store at all. + Log.w(TAG, "[V1Passphrase] Failed to unseal the legacy passphrase! The user will have to re-enter it.", e) + null + } + } else { + LegacySharedPrefs.getStringOrNull(context, "pref_backup_passphrase") + } + + store + .beginWrite() + .putString(KEY_V1_BACKUP_PASSPHRASE, passphrase?.stripSpaces()) + .putBoolean(KEY_V1_BACKUP_PASSPHRASE_MIGRATED, true) + .commit() + } + + private fun String.stripSpaces(): String = this.replace(" ", "") + var cachedMediaCdnPath: String? by stringValue(KEY_CDN_MEDIA_PATH, null) var lastBackupProtoSize: Long by longValue(KEY_BACKUP_LAST_PROTO_SIZE, 0L) diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/CertificateValues.java b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/CertificateValues.java index 329285fd61..019e764549 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/CertificateValues.java +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/CertificateValues.java @@ -1,12 +1,10 @@ package org.thoughtcrime.securesms.keyvalue; import android.content.Context; -import android.content.SharedPreferences; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; -import androidx.preference.PreferenceManager; import org.signal.core.util.logging.Log; @@ -81,14 +79,9 @@ public final class CertificateValues extends SignalStoreValues { private void migrateFromSharedPrefsV1(@NonNull Context context) { Log.i(TAG, "[V1] Migrating certificate values from shared prefs."); - SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context); - long legacyNextRotationTime = sharedPrefs.getLong("pref_unidentified_access_certificate_rotation_time", 0); + long legacyNextRotationTime = LegacySharedPrefs.INSTANCE.getLong(context, "pref_unidentified_access_certificate_rotation_time", 0); putLong(LAST_ROTATION_TIME, legacyNextRotationTime > 0 ? legacyNextRotationTime - LEGACY_ROTATION_INTERVAL : NEVER_ROTATED); - - sharedPrefs.edit() - .remove("pref_unidentified_access_certificate_rotation_time") - .apply(); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/LegacySharedPrefs.kt b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/LegacySharedPrefs.kt index deb14ba485..909dc74868 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/LegacySharedPrefs.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/LegacySharedPrefs.kt @@ -34,6 +34,10 @@ object LegacySharedPrefs { return prefs(context).getString(key, defaultValue) ?: defaultValue } + fun getStringOrNull(context: Context, key: String): String? { + return prefs(context).getString(key, null) + } + /** Some values were stored as strings, but some installs ended up with ints. */ fun getIntegerFromString(context: Context, key: String, defaultValue: Int): Int { return try { diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/MiscellaneousValues.kt b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/MiscellaneousValues.kt index 5aeed7f532..4c91beb219 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/MiscellaneousValues.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/MiscellaneousValues.kt @@ -1,5 +1,7 @@ package org.thoughtcrime.securesms.keyvalue +import android.content.Context +import org.signal.core.util.logging.Log import org.thoughtcrime.securesms.components.settings.app.usernamelinks.UsernameQrCodeColorScheme import org.thoughtcrime.securesms.database.model.databaseprotos.PendingChangeNumberMetadata import org.thoughtcrime.securesms.jobmanager.impl.ChangeNumberConstraintObserver @@ -7,8 +9,10 @@ import org.thoughtcrime.securesms.jobmanager.impl.SealedSenderConstraint import org.thoughtcrime.securesms.jobs.DeprecatedNotificationJob import org.thoughtcrime.securesms.keyvalue.protos.LeastActiveLinkedDevice -class MiscellaneousValues internal constructor(store: KeyValueStore) : SignalStoreValues(store) { +class MiscellaneousValues internal constructor(store: KeyValueStore, context: Context) : SignalStoreValues(store) { companion object { + private val TAG = Log.tag(MiscellaneousValues::class) + private const val LAST_PREKEY_REFRESH_TIME = "last_prekey_refresh_time" private const val MESSAGE_REQUEST_ENABLE_TIME = "message_request_enable_time" private const val LAST_PROFILE_REFRESH_TIME = "misc.last_profile_refresh_time" @@ -58,8 +62,82 @@ class MiscellaneousValues internal constructor(store: KeyValueStore) : SignalSto private const val LAST_APPLIED_PNI_CHANGE_SERVER_TIMESTAMP = "misc.last_applied_pni_change_server_timestamp" private const val LAST_MISSING_PLAY_SERVICES_FCM_VERIFICATION_TIME = "misc.last_missing_play_services_fcm_verification_time" private const val LAST_PROCESSED_SHARE_DATA_TIMESTAMP = "misc.last_processed_share_data_timestamp" + private const val DIRECTORY_REFRESH_TIME = "misc.directory_refresh_time" + private const val HAS_SUCCESSFULLY_RETRIEVED_DIRECTORY = "misc.has_successfully_retrieved_directory" + private const val LAST_FULL_CONTACT_SYNC_TIME = "misc.last_full_contact_sync_time" + private const val NEEDS_FULL_CONTACT_SYNC = "misc.needs_full_contact_sync" + private const val SERVICE_OUTAGE = "misc.service_outage" + private const val LAST_OUTAGE_CHECK_TIME = "misc.last_outage_check_time" + private const val SIGNED_PREKEY_ROTATION_TIME = "misc.signed_prekey_rotation_time" + private const val JOB_MANAGER_VERSION = "misc.job_manager_version" + private const val FIRST_INSTALL_VERSION = "misc.first_install_version" + private const val NOTIFICATION_CHANNEL_VERSION = "misc.notification_channel_version" + private const val NOTIFICATION_MESSAGES_CHANNEL_VERSION = "misc.notification_messages_channel_version" + private const val RATING_ENABLED = "misc.rating_enabled" + private const val RATING_LATER_TIMESTAMP = "misc.rating_later_timestamp" } + init { + if (!store.containsKey(FIRST_INSTALL_VERSION)) { + migrateFromSharedPrefsV1(context) + } + } + + /** Do not alter. If you need to migrate more stuff, create a new method. */ + private fun migrateFromSharedPrefsV1(context: Context) { + Log.i(TAG, "[V1] Migrating misc values from shared prefs.") + + store.beginWrite() + .putLong(DIRECTORY_REFRESH_TIME, LegacySharedPrefs.getLong(context, "pref_directory_refresh_time", 0)) + .putBoolean(HAS_SUCCESSFULLY_RETRIEVED_DIRECTORY, LegacySharedPrefs.getBoolean(context, "pref_successful_directory", false)) + .putLong(LAST_FULL_CONTACT_SYNC_TIME, LegacySharedPrefs.getLong(context, "pref_last_full_contact_sync_time", 0)) + .putBoolean(NEEDS_FULL_CONTACT_SYNC, LegacySharedPrefs.getBoolean(context, "pref_needs_full_contact_sync", false)) + .putBoolean(SERVICE_OUTAGE, LegacySharedPrefs.getBoolean(context, "pref_service_outage", false)) + .putLong(LAST_OUTAGE_CHECK_TIME, LegacySharedPrefs.getLong(context, "pref_last_outage_check_time", 0)) + .putLong(SIGNED_PREKEY_ROTATION_TIME, LegacySharedPrefs.getLong(context, "pref_signed_pre_key_rotation_time", 0)) + .putInteger(JOB_MANAGER_VERSION, LegacySharedPrefs.getInteger(context, "pref_job_manager_version", 1)) + .putInteger(NOTIFICATION_CHANNEL_VERSION, LegacySharedPrefs.getInteger(context, "pref_notification_channel_version", 1)) + .putInteger(NOTIFICATION_MESSAGES_CHANNEL_VERSION, LegacySharedPrefs.getInteger(context, "pref_notification_messages_channel_version", 1)) + .putBoolean(RATING_ENABLED, LegacySharedPrefs.getBoolean(context, "pref_rating_enabled", true)) + .putLong(RATING_LATER_TIMESTAMP, LegacySharedPrefs.getLong(context, "pref_rating_later", -1)) + // Written last so that it acts as the marker for this migration having run. + .putInteger(FIRST_INSTALL_VERSION, LegacySharedPrefs.getInteger(context, "pref_first_install_version", -1)) + .commit() + } + + /** When the next contact directory refresh is scheduled. */ + var directoryRefreshTime: Long by longValue(DIRECTORY_REFRESH_TIME, 0) + + /** Whether we've ever managed to pull down the contact directory. */ + var hasSuccessfullyRetrievedDirectory: Boolean by booleanValue(HAS_SUCCESSFULLY_RETRIEVED_DIRECTORY, false) + + var lastFullContactSyncTime: Long by longValue(LAST_FULL_CONTACT_SYNC_TIME, 0) + + var needsFullContactSync: Boolean by booleanValue(NEEDS_FULL_CONTACT_SYNC, false) + + /** Whether the service is currently reporting an outage. */ + var serviceOutage: Boolean by booleanValue(SERVICE_OUTAGE, false) + + var lastOutageCheckTime: Long by longValue(LAST_OUTAGE_CHECK_TIME, 0) + + var signedPreKeyRotationTime: Long by longValue(SIGNED_PREKEY_ROTATION_TIME, 0) + + /** The [org.thoughtcrime.securesms.jobmanager.JobManager] version the job database was last migrated to. */ + var jobManagerVersion: Int by integerValue(JOB_MANAGER_VERSION, 1) + + /** The canonical version code the app was first installed at, or -1 if we don't know. */ + var firstInstallVersion: Int by integerValue(FIRST_INSTALL_VERSION, -1) + + var notificationChannelVersion: Int by integerValue(NOTIFICATION_CHANNEL_VERSION, 1) + + var notificationMessagesChannelVersion: Int by integerValue(NOTIFICATION_MESSAGES_CHANNEL_VERSION, 1) + + /** Whether we're still allowed to ask the user to rate the app. */ + var ratingEnabled: Boolean by booleanValue(RATING_ENABLED, true) + + /** The earliest time we're allowed to ask the user to rate the app again. */ + var ratingLaterTimestamp: Long by longValue(RATING_LATER_TIMESTAMP, -1) + public override fun onFirstEverAppLaunch() { putLong(MESSAGE_REQUEST_ENABLE_TIME, 0) putBoolean(NEEDS_USERNAME_RESTORE, true) diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/PinValues.java b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/PinValues.java index ecff59e28d..65a67e1c13 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/PinValues.java +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/PinValues.java @@ -1,12 +1,13 @@ package org.thoughtcrime.securesms.keyvalue; +import android.content.Context; + import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.dependencies.AppDependencies; +import org.thoughtcrime.securesms.lock.RegistrationLockReminders; import org.thoughtcrime.securesms.lock.SignalPinReminders; import org.thoughtcrime.securesms.lock.v2.PinKeyboardType; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import java.util.Arrays; import java.util.List; @@ -22,10 +23,44 @@ public final class PinValues extends SignalStoreValues { private static final String LAST_REMINDER_TIME = "pin.last_reminder_time"; private static final String NEXT_INTERVAL = "pin.interval_index"; private static final String KEYBOARD_TYPE = "kbs.keyboard_type"; + private static final String MIGRATION_VERSION = "pin.migration_version"; public static final String PIN_REMINDERS_ENABLED = "pin.pin_reminders_enabled"; - PinValues(KeyValueStore store) { + private static final int CURRENT_MIGRATION_VERSION = 1; + + PinValues(KeyValueStore store, @NonNull Context context) { super(store); + + if (getLong(MIGRATION_VERSION, 0) < CURRENT_MIGRATION_VERSION) { + migrateFromSharedPrefsV1(context); + } + } + + /** + * Unlike the other stores, we can't use one of the migrated keys as the "has this run?" marker: both {@link #NEXT_INTERVAL} and + * {@link #LAST_SUCCESSFUL_ENTRY} are keys released versions already write, so their presence says nothing about whether this + * migration ran. Hence the explicit {@link #MIGRATION_VERSION}. + * + * These values used to be read straight out of shared prefs as the *default* for the keys above, so only migrate the ones this + * store doesn't already have a value for. + * + * Do not alter. If you need to migrate more stuff, bump {@link #CURRENT_MIGRATION_VERSION} and add a new method. + */ + private void migrateFromSharedPrefsV1(@NonNull Context context) { + Log.i(TAG, "[V1] Migrating pin values from shared prefs."); + + KeyValueStore.Writer writer = getStore().beginWrite(); + + if (!getStore().containsKey(LAST_SUCCESSFUL_ENTRY)) { + writer.putLong(LAST_SUCCESSFUL_ENTRY, LegacySharedPrefs.INSTANCE.getLong(context, "pref_registration_lock_last_reminder_time_post_kbs", 0)); + } + + if (!getStore().containsKey(NEXT_INTERVAL)) { + writer.putLong(NEXT_INTERVAL, LegacySharedPrefs.INSTANCE.getLong(context, "pref_registration_lock_next_reminder_interval", RegistrationLockReminders.INITIAL_INTERVAL)); + } + + writer.putLong(MIGRATION_VERSION, CURRENT_MIGRATION_VERSION) + .commit(); } @Override @@ -38,7 +73,7 @@ public final class PinValues extends SignalStoreValues { } public void onEntrySuccess(@NonNull String pin) { - long nextInterval = SignalPinReminders.getNextInterval(getCurrentInterval()); + long nextInterval = SignalPinReminders.getNextInterval(getNextReminderInterval()); Log.i(TAG, "onEntrySuccess() nextInterval: " + nextInterval); long now = System.currentTimeMillis(); @@ -53,7 +88,7 @@ public final class PinValues extends SignalStoreValues { } public void onEntrySuccessWithWrongGuess(@NonNull String pin) { - long nextInterval = SignalPinReminders.getPreviousInterval(getCurrentInterval()); + long nextInterval = SignalPinReminders.getPreviousInterval(getNextReminderInterval()); Log.i(TAG, "onEntrySuccessWithWrongGuess() nextInterval: " + nextInterval); long now = System.currentTimeMillis(); @@ -75,9 +110,9 @@ public final class PinValues extends SignalStoreValues { long nextInterval; if (includedFailure) { - nextInterval = SignalPinReminders.getPreviousInterval(getCurrentInterval()); + nextInterval = SignalPinReminders.getPreviousInterval(getNextReminderInterval()); } else { - nextInterval = getCurrentInterval(); + nextInterval = getNextReminderInterval(); } Log.i(TAG, "onEntrySkip(includedFailure: " + includedFailure +") nextInterval: " + nextInterval); @@ -101,12 +136,20 @@ public final class PinValues extends SignalStoreValues { .apply(); } - public long getCurrentInterval() { - return getLong(NEXT_INTERVAL, TextSecurePreferences.getRegistrationLockNextReminderInterval(AppDependencies.getApplication())); + public long getNextReminderInterval() { + return getLong(NEXT_INTERVAL, RegistrationLockReminders.INITIAL_INTERVAL); + } + + public void setNextReminderInterval(long interval) { + putLong(NEXT_INTERVAL, interval); } public long getLastSuccessfulEntryTime() { - return getLong(LAST_SUCCESSFUL_ENTRY, TextSecurePreferences.getRegistrationLockLastReminderTime(AppDependencies.getApplication())); + return getLong(LAST_SUCCESSFUL_ENTRY, 0); + } + + public void setLastSuccessfulEntryTime(long time) { + putLong(LAST_SUCCESSFUL_ENTRY, time); } public long getLastReminderTime() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/RegistrationValues.kt b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/RegistrationValues.kt index d4dbffcb48..b537fdd18b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/RegistrationValues.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/RegistrationValues.kt @@ -1,5 +1,6 @@ package org.thoughtcrime.securesms.keyvalue +import android.content.Context import androidx.annotation.CheckResult import androidx.annotation.VisibleForTesting import org.signal.core.util.logging.Log @@ -7,7 +8,7 @@ import org.thoughtcrime.securesms.database.model.databaseprotos.LocalRegistratio import org.thoughtcrime.securesms.database.model.databaseprotos.RestoreDecisionState import org.thoughtcrime.securesms.dependencies.AppDependencies -class RegistrationValues internal constructor(store: KeyValueStore) : SignalStoreValues(store) { +class RegistrationValues internal constructor(store: KeyValueStore, context: Context) : SignalStoreValues(store) { companion object { private val TAG = Log.tag(RegistrationValues::class) @@ -25,10 +26,28 @@ class RegistrationValues internal constructor(store: KeyValueStore) : SignalStor private const val RESTORING_ON_NEW_DEVICE = "registration.restoring_on_new_device" private const val IN_PROGRESS_DATA_BLOB_URI = "registration.in_progress_data_blob_uri" + private const val HAS_PROMPTED_PUSH_REGISTRATION = "registration.has_prompted_push_registration" + @VisibleForTesting const val RESTORE_DECISION_STATE = "registration.restore_decision_state.2" } + init { + if (!store.containsKey(HAS_PROMPTED_PUSH_REGISTRATION)) { + migrateFromSharedPrefsV1(context) + } + } + + /** Do not alter. If you need to migrate more stuff, create a new method. */ + private fun migrateFromSharedPrefsV1(context: Context) { + Log.i(TAG, "[V1] Migrating registration values from shared prefs.") + + putBoolean(HAS_PROMPTED_PUSH_REGISTRATION, LegacySharedPrefs.getBoolean(context, "pref_prompted_push_registration", false)) + } + + /** Whether we've already walked the user through push registration. */ + var hasPromptedPushRegistration: Boolean by booleanValue(HAS_PROMPTED_PUSH_REGISTRATION, false) + @Synchronized public override fun onFirstEverAppLaunch() { store 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 c2071f1f82..c9e44baaa4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SettingsValues.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SettingsValues.kt @@ -499,6 +499,39 @@ class SettingsValues internal constructor(store: KeyValueStore, private val cont } } + /** + * V1 backups made before these settings moved into this store carry them as shared prefs rather than key-values. The shared-prefs + * migration has already run by the time a restore happens, so the restored prefs need to be re-read afterwards or the user silently + * loses their privacy and security choices. + */ + fun restoreLegacySharedPrefsAfterBackupRestore() { + Log.i(TAG, "Restoring legacy privacy settings from shared prefs.") + + val writer = store.beginWrite() + + val booleanKeys = mapOf( + "pref_screen_security" to SCREEN_SECURITY_ENABLED, + "pref_incognito_keyboard" to INCOGNITO_KEYBOARD_ENABLED, + "pref_read_receipts" to READ_RECEIPTS_ENABLED, + "pref_typing_indicators" to TYPING_INDICATORS_ENABLED, + "pref_show_unidentifed_delivery_indicators" to SHOW_UNIDENTIFIED_DELIVERY_INDICATORS, + "pref_universal_unidentified_access" to UNIVERSAL_UNIDENTIFIED_ACCESS, + "pref_turn_only" to ALWAYS_RELAY_CALLS + ) + + for ((legacyKey, key) in booleanKeys) { + if (LegacySharedPrefs.contains(context, legacyKey)) { + writer.putBoolean(key, LegacySharedPrefs.getBoolean(context, legacyKey, false)) + } + } + + if (LegacySharedPrefs.contains(context, "pref_notification_privacy")) { + writer.putString(MESSAGE_NOTIFICATION_PRIVACY, LegacySharedPrefs.getString(context, "pref_notification_privacy", "all")) + } + + writer.commit() + } + private fun migrateFromSharedPrefsV1(context: Context) { Log.i(TAG, "[V1] Migrating screen lock values from shared prefs.") diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SignalStore.kt b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SignalStore.kt index 8cb8234a12..210825d157 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SignalStore.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SignalStore.kt @@ -12,13 +12,13 @@ class SignalStore(context: Application, private val store: KeyValueStore) { val accountValues = AccountValues(store, context) val svrValues = SvrValues(store) - val registrationValues = RegistrationValues(store) - val pinValues = PinValues(store) + val registrationValues = RegistrationValues(store, context) + val pinValues = PinValues(store, context) val remoteConfigValues = RemoteConfigValues(store) val storageServiceValues = StorageServiceValues(store) - val uiHintValues = UiHintValues(store) - val tooltipValues = TooltipValues(store) - val miscValues = MiscellaneousValues(store) + val uiHintValues = UiHintValues(store, context) + val tooltipValues = TooltipValues(store, context) + val miscValues = MiscellaneousValues(store, context) val internalValues = InternalValues(store) val emojiValues = EmojiValues(store) val settingsValues = SettingsValues(store, context) @@ -35,8 +35,8 @@ class SignalStore(context: Application, private val store: KeyValueStore) { val notificationProfileValues = NotificationProfileValues(store) val releaseChannelValues = ReleaseChannelValues(store) val storyValues = StoryValues(store) - val apkUpdateValues = ApkUpdateValues(store) - val backupValues = BackupValues(store) + val apkUpdateValues = ApkUpdateValues(store, context) + val backupValues = BackupValues(store, context) val callQualityValues = CallQualityValues(store) val labsValues = LabsValues(store) @@ -145,6 +145,7 @@ class SignalStore(context: Application, private val store: KeyValueStore) { @JvmStatic fun onPostBackupRestore() { instance!!.store.resetCache() + instance!!.settingsValues.restoreLegacySharedPrefsAfterBackupRestore() } @JvmStatic @@ -270,6 +271,8 @@ class SignalStore(context: Application, private val store: KeyValueStore) { val story: StoryValues get() = instance!!.storyValues + @JvmStatic + @get:JvmName("apkUpdate") val apkUpdate: ApkUpdateValues get() = instance!!.apkUpdateValues diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/TooltipValues.java b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/TooltipValues.java index 5a255bb378..a6ada4747f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/TooltipValues.java +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/TooltipValues.java @@ -1,12 +1,18 @@ package org.thoughtcrime.securesms.keyvalue; +import android.content.Context; + import androidx.annotation.NonNull; +import org.signal.core.util.logging.Log; + import java.util.Collections; import java.util.List; public class TooltipValues extends SignalStoreValues { + private static final String TAG = Log.tag(TooltipValues.class); + private static final int GROUP_CALLING_MAX_TOOLTIP_DISPLAY_COUNT = 3; private static final String BLUR_HUD_ICON = "tooltip.blur_hud_icon"; @@ -16,9 +22,41 @@ public class TooltipValues extends SignalStoreValues { private static final String BUBBLE_OPT_OUT = "tooltip.bubble.opt.out"; private static final String PROFILE_SETTINGS_QR_CODE = "tooltip.profile_settings_qr_code"; private static final String CALLING_SWITCH_CAMERA = "tooltip.calling.switch_camera"; + private static final String STICKER_INTRO = "tooltip.sticker_intro"; + private static final String SWIPE_TO_REPLY = "tooltip.swipe_to_reply"; - TooltipValues(@NonNull KeyValueStore store) { + TooltipValues(@NonNull KeyValueStore store, @NonNull Context context) { super(store); + + if (!store.containsKey(STICKER_INTRO)) { + migrateFromSharedPrefsV1(context); + } + } + + /** Do not alter. If you need to migrate more stuff, create a new method. */ + private void migrateFromSharedPrefsV1(@NonNull Context context) { + Log.i(TAG, "[V1] Migrating tooltip values from shared prefs."); + + getStore().beginWrite() + .putBoolean(SWIPE_TO_REPLY, LegacySharedPrefs.INSTANCE.getBoolean(context, "pref_has_seen_swipe_to_reply", false)) + .putBoolean(STICKER_INTRO, LegacySharedPrefs.INSTANCE.getBoolean(context, "pref_seen_sticker_intro_tooltip", false)) + .commit(); + } + + public boolean hasSeenStickerIntroTooltip() { + return getBoolean(STICKER_INTRO, false); + } + + public void markStickerIntroTooltipSeen() { + putBoolean(STICKER_INTRO, true); + } + + public boolean hasSeenSwipeToReplyTooltip() { + return getBoolean(SWIPE_TO_REPLY, false); + } + + public void markSwipeToReplyTooltipSeen() { + putBoolean(SWIPE_TO_REPLY, true); } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/UiHintValues.java b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/UiHintValues.java index 1474959017..35b313241e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/UiHintValues.java +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/UiHintValues.java @@ -1,12 +1,18 @@ package org.thoughtcrime.securesms.keyvalue; +import android.content.Context; + import androidx.annotation.NonNull; +import org.signal.core.util.logging.Log; + import java.util.Arrays; import java.util.List; public class UiHintValues extends SignalStoreValues { + private static final String TAG = Log.tag(UiHintValues.class); + private static final int NEVER_DISPLAY_PULL_TO_FILTER_TIP_THRESHOLD = 3; private static final int HAS_SEEN_PINNED_MESSAGE_SHEET_THRESHOLD = 3; @@ -34,9 +40,29 @@ public class UiHintValues extends SignalStoreValues { private static final String HAS_DISMISSED_MEMBER_LABEL_ABOUT_OVERRIDE_WARNING = "uihints.has_dismissed_member_label_about_override_warning"; private static final String HAS_SEEN_ADMIN_DELETE_EDUCATION_DIALOG = "uihints.has_seen_admin_delete_education_dialog"; private static final String DISMISSED_SET_UP_USERNAME_BANNER = "uihints.dismissed_set_up_username_banner"; + private static final String HAS_PROMPTED_OPTIMIZE_DOZE = "uihints.has_prompted_optimize_doze"; - UiHintValues(@NonNull KeyValueStore store) { + UiHintValues(@NonNull KeyValueStore store, @NonNull Context context) { super(store); + + if (!store.containsKey(HAS_PROMPTED_OPTIMIZE_DOZE)) { + migrateFromSharedPrefsV1(context); + } + } + + /** Do not alter. If you need to migrate more stuff, create a new method. */ + private void migrateFromSharedPrefsV1(@NonNull Context context) { + Log.i(TAG, "[V1] Migrating ui hint values from shared prefs."); + + putBoolean(HAS_PROMPTED_OPTIMIZE_DOZE, LegacySharedPrefs.INSTANCE.getBoolean(context, "pref_prompted_optimize_doze", false)); + } + + public boolean hasPromptedOptimizeDoze() { + return getBoolean(HAS_PROMPTED_OPTIMIZE_DOZE, false); + } + + public void setHasPromptedOptimizeDoze(boolean value) { + putBoolean(HAS_PROMPTED_OPTIMIZE_DOZE, value); } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/lock/RegistrationLockReminders.java b/app/src/main/java/org/thoughtcrime/securesms/lock/RegistrationLockReminders.java index 98bbbe04b4..bbdceebe8b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/lock/RegistrationLockReminders.java +++ b/app/src/main/java/org/thoughtcrime/securesms/lock/RegistrationLockReminders.java @@ -5,7 +5,7 @@ import android.content.Context; import androidx.annotation.NonNull; -import org.thoughtcrime.securesms.util.TextSecurePreferences; +import org.thoughtcrime.securesms.keyvalue.SignalStore; import java.util.NavigableSet; import java.util.TreeSet; @@ -24,26 +24,26 @@ public class RegistrationLockReminders { public static final long INITIAL_INTERVAL = INTERVALS.first(); public static boolean needsReminder(@NonNull Context context) { - long lastReminderTime = TextSecurePreferences.getRegistrationLockLastReminderTime(context); - long nextIntervalTime = TextSecurePreferences.getRegistrationLockNextReminderInterval(context); + long lastReminderTime = SignalStore.pin().getLastSuccessfulEntryTime(); + long nextIntervalTime = SignalStore.pin().getNextReminderInterval(); return System.currentTimeMillis() > lastReminderTime + nextIntervalTime; } public static void scheduleReminder(@NonNull Context context, boolean success) { if (success) { - long timeSinceLastReminder = System.currentTimeMillis() - TextSecurePreferences.getRegistrationLockLastReminderTime(context); + long timeSinceLastReminder = System.currentTimeMillis() - SignalStore.pin().getLastSuccessfulEntryTime(); Long nextReminderInterval = INTERVALS.higher(timeSinceLastReminder); if (nextReminderInterval == null) { nextReminderInterval = INTERVALS.last(); } - TextSecurePreferences.setRegistrationLockLastReminderTime(context, System.currentTimeMillis()); - TextSecurePreferences.setRegistrationLockNextReminderInterval(context, nextReminderInterval); + SignalStore.pin().setLastSuccessfulEntryTime(System.currentTimeMillis()); + SignalStore.pin().setNextReminderInterval(nextReminderInterval); } else { - long timeSinceLastReminder = TextSecurePreferences.getRegistrationLockLastReminderTime(context) + TimeUnit.MINUTES.toMillis(5); - TextSecurePreferences.setRegistrationLockLastReminderTime(context, timeSinceLastReminder); + long timeSinceLastReminder = SignalStore.pin().getLastSuccessfulEntryTime() + TimeUnit.MINUTES.toMillis(5); + SignalStore.pin().setLastSuccessfulEntryTime(timeSinceLastReminder); } } } 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 7e783c0866..43931fef81 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionKeyPreferences.java +++ b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionKeyPreferences.java @@ -7,7 +7,6 @@ import androidx.annotation.NonNull; import org.thoughtcrime.securesms.keyvalue.KeepMessagesDuration; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.signal.core.util.Util; final class LogSectionKeyPreferences implements LogSection { @@ -27,7 +26,7 @@ final class LogSectionKeyPreferences implements LogSection { .append("Media Quality : ").append(SignalStore.settings().getSentMediaQuality()).append("\n") .append("Client Deprecated : ").append(SignalStore.misc().isClientDeprecated()).append("\n") .append("Push Registered : ").append(SignalStore.account().isRegistered()).append("\n") - .append("Unauthorized Received : ").append(TextSecurePreferences.isUnauthorizedReceived(context)).append("\n") + .append("Unauthorized Received : ").append(SignalStore.account().isUnauthorizedReceived()).append("\n") .append("self.isRegistered() : ").append(SignalStore.account().getAci() == null ? "false" : Recipient.self().isRegistered()).append("\n") .append("Thread Trimming : ").append(getThreadTrimmingString()).append("\n") .append("Censorship Setting : ").append(SignalStore.settings().getCensorshipCircumventionEnabled()).append("\n") diff --git a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionPin.java b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionPin.java index 2009ba1c98..8846a33648 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionPin.java +++ b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionPin.java @@ -17,7 +17,7 @@ public class LogSectionPin implements LogSection { public @NonNull CharSequence getContent(@NonNull Context context) { return new StringBuilder().append("Last Successful Reminder Entry: ").append(SignalStore.pin().getLastSuccessfulEntryTime()).append("\n") .append("Last Reminder Time: ").append(SignalStore.pin().getLastReminderTime()).append("\n") - .append("Next Reminder Interval: ").append(SignalStore.pin().getCurrentInterval()).append("\n") + .append("Next Reminder Interval: ").append(SignalStore.pin().getNextReminderInterval()).append("\n") .append("Reglock: ").append(SignalStore.svr().isRegistrationLockEnabled()).append("\n") .append("Signal PIN: ").append(SignalStore.svr().hasPin()).append("\n") .append("Restored via AEP: ").append(SignalStore.account().restoredAccountEntropyPool()).append("\n") diff --git a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionSystemInfo.kt b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionSystemInfo.kt index b4a5705b44..553b793e84 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionSystemInfo.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionSystemInfo.kt @@ -30,7 +30,6 @@ import org.thoughtcrime.securesms.service.webrtc.AndroidTelecomUtil.telecomSuppo import org.thoughtcrime.securesms.util.AppSignatureUtil import org.thoughtcrime.securesms.util.NetworkUtil import org.thoughtcrime.securesms.util.PowerManagerCompat -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.VersionTracker.getDaysSinceFirstInstalled import java.util.Locale import kotlin.math.roundToLong @@ -71,7 +70,7 @@ class LogSectionSystemInfo : LogSection { FCM : ${SignalStore.account.fcmEnabled} Locale : ${Locale.getDefault()} Linked Devices : ${SignalStore.account.isMultiDevice} - First Version : ${TextSecurePreferences.getFirstInstallVersion(context)} + First Version : ${SignalStore.misc.firstInstallVersion} Days Installed : ${getDaysSinceFirstInstalled(context)} Last Registration : ${getTimeRegistered()} Build Variant : ${BuildConfig.BUILD_DISTRIBUTION_TYPE}${BuildConfig.BUILD_ENVIRONMENT_TYPE}${BuildConfig.BUILD_VARIANT_TYPE} diff --git a/app/src/main/java/org/thoughtcrime/securesms/megaphone/Megaphones.java b/app/src/main/java/org/thoughtcrime/securesms/megaphone/Megaphones.java index 853e4c72d8..789cab8219 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/megaphone/Megaphones.java +++ b/app/src/main/java/org/thoughtcrime/securesms/megaphone/Megaphones.java @@ -48,7 +48,6 @@ import org.thoughtcrime.securesms.util.DateUtils; import org.thoughtcrime.securesms.util.Environment; import org.thoughtcrime.securesms.util.RemoteConfig; import org.signal.core.util.ServiceUtil; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.VersionTracker; import org.thoughtcrime.securesms.util.dynamiclanguage.DynamicLanguageContextWrapper; @@ -131,7 +130,7 @@ public final class Megaphones { // Specifically putting backup reminders here, above PIN reminders put(Event.BACKUP_LOW_STORAGE_UPSELL, shouldShowBackupLowStorageUpsell(context) ? new BackupUpsellSchedule(records, TimeUnit.DAYS.toMillis(60), TimeUnit.DAYS.toMillis(120)) : NEVER); put(Event.BACKUP_MEDIA_SIZE_UPSELL, shouldShowBackupMediaSizeUpsell() ? new BackupUpsellSchedule(records, TimeUnit.DAYS.toMillis(60), TimeUnit.DAYS.toMillis(120)) : NEVER); - put(Event.BACKUP_MESSAGE_COUNT_UPSELL, shouldShowBackupMessageCountUpsell(context) ? new BackupUpsellSchedule(records, TimeUnit.DAYS.toMillis(60)) : NEVER); + put(Event.BACKUP_MESSAGE_COUNT_UPSELL, shouldShowBackupMessageCountUpsell() ? new BackupUpsellSchedule(records, TimeUnit.DAYS.toMillis(60)) : NEVER); put(Event.BACKUPS_GENERIC_UPSELL, shouldShowGenericBackupsMegaphone(context) ? new BackupUpsellSchedule(records, TimeUnit.DAYS.toMillis(60)) : NEVER); put(Event.VERIFY_BACKUP_KEY, new VerifyBackupKeyReminderSchedule()); put(Event.USE_NEW_ON_DEVICE_BACKUPS, shouldShowUseNewOnDeviceBackupsMegaphone() ? RecurringSchedule.every(TimeUnit.DAYS.toMillis(7)) : NEVER); @@ -273,7 +272,7 @@ public final class Megaphones { SignalStore.pin().onEntrySkip(includedFailure); controller.onMegaphoneSnooze(Event.PIN_REMINDER); - controller.onMegaphoneToastRequested(controller.getMegaphoneActivity().getString(SignalPinReminders.getSkipReminderString(SignalStore.pin().getCurrentInterval()))); + controller.onMegaphoneToastRequested(controller.getMegaphoneActivity().getString(SignalPinReminders.getSkipReminderString(SignalStore.pin().getNextReminderInterval()))); } @Override @@ -286,7 +285,7 @@ public final class Megaphones { } controller.onMegaphoneSnooze(Event.PIN_REMINDER); - controller.onMegaphoneToastRequested(controller.getMegaphoneActivity().getString(SignalPinReminders.getReminderString(SignalStore.pin().getCurrentInterval()))); + controller.onMegaphoneToastRequested(controller.getMegaphoneActivity().getString(SignalPinReminders.getReminderString(SignalStore.pin().getNextReminderInterval()))); } }); }) @@ -624,7 +623,7 @@ public final class Megaphones { return false; } - if (!SignalStore.account().isRegistered() || TextSecurePreferences.isUnauthorizedReceived(context) || SignalStore.account().isLinkedDevice()) { + if (!SignalStore.account().isRegistered() || SignalStore.account().isUnauthorizedReceived() || SignalStore.account().isLinkedDevice()) { return false; } @@ -667,8 +666,8 @@ public final class Megaphones { return System.currentTimeMillis() - lastSeenDonatePrompt; } - private static boolean shouldShowBackupMessageCountUpsell(@NonNull Context context) { - if (!SignalStore.account().isRegistered() || TextSecurePreferences.isUnauthorizedReceived(context) || SignalStore.account().isLinkedDevice()) { + private static boolean shouldShowBackupMessageCountUpsell() { + if (!SignalStore.account().isRegistered() || SignalStore.account().isUnauthorizedReceived() || SignalStore.account().isLinkedDevice()) { return false; } @@ -692,7 +691,7 @@ public final class Megaphones { } private static boolean shouldShowBackupLowStorageUpsell(@NonNull Context context) { - if (!SignalStore.account().isRegistered() || TextSecurePreferences.isUnauthorizedReceived(context) || SignalStore.account().isLinkedDevice() || !Environment.Backups.supportsGooglePlayBilling()) { + if (!SignalStore.account().isRegistered() || SignalStore.account().isUnauthorizedReceived() || SignalStore.account().isLinkedDevice() || !Environment.Backups.supportsGooglePlayBilling()) { return false; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/megaphone/SignalPinReminderSchedule.java b/app/src/main/java/org/thoughtcrime/securesms/megaphone/SignalPinReminderSchedule.java index c5f64fc6b3..5c4aad1d8f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/megaphone/SignalPinReminderSchedule.java +++ b/app/src/main/java/org/thoughtcrime/securesms/megaphone/SignalPinReminderSchedule.java @@ -31,7 +31,7 @@ final class SignalPinReminderSchedule implements MegaphoneSchedule { } long lastReminderTime = SignalStore.pin().getLastReminderTime(); - long interval = SignalStore.pin().getCurrentInterval(); + long interval = SignalStore.pin().getNextReminderInterval(); return currentTime - lastReminderTime >= interval; } 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 984c2cfe27..96300e59a3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/DataMessageProcessor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/DataMessageProcessor.kt @@ -860,7 +860,7 @@ object DataMessageProcessor { val giftBadge: DataMessage.GiftBadge = message.giftBadge!! check(giftBadge.receiptCredentialPresentation != null) - notifyTypingStoppedFromIncomingMessage(context, senderRecipient, threadRecipientId, metadata.sourceDeviceId) + notifyTypingStoppedFromIncomingMessage(senderRecipient, threadRecipientId, metadata.sourceDeviceId) val token = ReceiptCredentialPresentation(giftBadge.receiptCredentialPresentation!!.toByteArray()).serialize() val dbGiftBadge = GiftBadge.Builder() @@ -911,7 +911,7 @@ object DataMessageProcessor { ): InsertResult? { log(envelope.clientTimestamp!!, "Media message.") - notifyTypingStoppedFromIncomingMessage(context, senderRecipient, threadRecipient.id, metadata.sourceDeviceId) + notifyTypingStoppedFromIncomingMessage(senderRecipient, threadRecipient.id, metadata.sourceDeviceId) val insertResult: InsertResult? @@ -1018,7 +1018,7 @@ object DataMessageProcessor { handlePossibleExpirationUpdate(envelope, metadata, senderRecipient, threadRecipient, groupId, message.expireTimerDuration, message.expireTimerVersion, receivedTime) - notifyTypingStoppedFromIncomingMessage(context, senderRecipient, threadRecipient.id, metadata.sourceDeviceId) + notifyTypingStoppedFromIncomingMessage(senderRecipient, threadRecipient.id, metadata.sourceDeviceId) val textMessage = IncomingMessage( type = MessageType.NORMAL, @@ -1479,7 +1479,7 @@ object DataMessageProcessor { } } - fun notifyTypingStoppedFromIncomingMessage(context: Context, senderRecipient: Recipient, threadRecipientId: RecipientId, device: Int) { + fun notifyTypingStoppedFromIncomingMessage(senderRecipient: Recipient, threadRecipientId: RecipientId, device: Int) { val threadId = SignalDatabase.threads.getThreadIdIfExistsFor(threadRecipientId) if (threadId > 0 && SignalStore.settings.isTypingIndicatorsEnabled) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/EditMessageProcessor.kt b/app/src/main/java/org/thoughtcrime/securesms/messages/EditMessageProcessor.kt index ab1b2a1602..dd32eeb8d5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/EditMessageProcessor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/EditMessageProcessor.kt @@ -85,7 +85,7 @@ object EditMessageProcessor { return } - DataMessageProcessor.notifyTypingStoppedFromIncomingMessage(context, senderRecipient, threadRecipient.id, metadata.sourceDeviceId) + DataMessageProcessor.notifyTypingStoppedFromIncomingMessage(senderRecipient, threadRecipient.id, metadata.sourceDeviceId) targetMessage = targetMessage.withAttachments(SignalDatabase.attachments.getAttachmentsForMessage(targetMessage.id)) diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/IncomingMessageObserver.kt b/app/src/main/java/org/thoughtcrime/securesms/messages/IncomingMessageObserver.kt index 66de8a4f59..016f838c86 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/IncomingMessageObserver.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/IncomingMessageObserver.kt @@ -49,7 +49,6 @@ import org.thoughtcrime.securesms.util.AlarmSleepTimer import org.thoughtcrime.securesms.util.Environment import org.thoughtcrime.securesms.util.SignalLocalMetrics import org.thoughtcrime.securesms.util.SignalTrace -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.asChain import org.whispersystems.signalservice.api.messages.EnvelopeResponse import org.whispersystems.signalservice.api.websocket.SignalWebSocket @@ -176,7 +175,7 @@ class IncomingMessageObserver( MessageRetrievalThread().start() - val registered = SignalStore.account.isRegistered && !TextSecurePreferences.isUnauthorizedReceived(context) + val registered = SignalStore.account.isRegistered && !SignalStore.account.isUnauthorizedReceived if (registered && (!SignalStore.account.fcmEnabled || SignalStore.settings.forceWebsocketMode.isEnabled)) { SignalExecutors.UNBOUNDED.execute { if (!SafeForegroundService.start(context, ForegroundService::class.java)) { @@ -251,7 +250,7 @@ class IncomingMessageObserver( val timeIdle = if (isForeground) 0 else System.currentTimeMillis() - lastInteractionTime val registered = SignalStore.account.isRegistered - val unauthorizedReceived = TextSecurePreferences.isUnauthorizedReceived(context) + val unauthorizedReceived = SignalStore.account.isUnauthorizedReceived val fcmEnabled = SignalStore.account.fcmEnabled val hasNetwork = NetworkConstraint.isMet(context) val hasProxy = SignalStore.proxy.isProxyEnabled @@ -278,7 +277,7 @@ class IncomingMessageObserver( } private fun isConnectionAvailable(): Boolean { - return !TextSecurePreferences.isUnauthorizedReceived(context) && SignalStore.account.isRegistered && (authWebSocket.stateSnapshot == WebSocketConnectionState.CONNECTED || (authWebSocket.shouldSendKeepAlives() && NetworkConstraint.isMet(context))) + return !SignalStore.account.isUnauthorizedReceived && SignalStore.account.isRegistered && (authWebSocket.stateSnapshot == WebSocketConnectionState.CONNECTED || (authWebSocket.shouldSendKeepAlives() && NetworkConstraint.isMet(context))) } /** Conditions are evaluated outside of [connectionLock] so notifiers never block on them. We only park if nothing signaled since the version we evaluated against. */ 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 c5cde71616..292c6d17bf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessor.kt @@ -518,7 +518,6 @@ open class MessageContentProcessor(private val context: Context) { content.receiptMessage != null -> { ReceiptMessageProcessor.process( - context, senderRecipient, envelope, content, 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 6cd2fbd313..cb6053c223 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/ReceiptMessageProcessor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/ReceiptMessageProcessor.kt @@ -1,7 +1,6 @@ package org.thoughtcrime.securesms.messages import android.annotation.SuppressLint -import android.content.Context import org.signal.core.util.Stopwatch import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.dependencies.AppDependencies @@ -22,13 +21,13 @@ object ReceiptMessageProcessor { private const val VERBOSE = false - fun process(context: Context, senderRecipient: Recipient, envelope: Envelope, content: Content, metadata: EnvelopeMetadata, earlyMessageCacheEntry: EarlyMessageCacheEntry?, batchCache: BatchCache) { + fun process(senderRecipient: Recipient, envelope: Envelope, content: Content, metadata: EnvelopeMetadata, earlyMessageCacheEntry: EarlyMessageCacheEntry?, batchCache: BatchCache) { val receiptMessage = content.receiptMessage!! when (receiptMessage.type) { ReceiptMessage.Type.DELIVERY -> handleDeliveryReceipt(envelope, metadata, receiptMessage, senderRecipient.id, batchCache) - ReceiptMessage.Type.READ -> handleReadReceipt(context, senderRecipient.id, envelope, metadata, receiptMessage, earlyMessageCacheEntry, batchCache) - ReceiptMessage.Type.VIEWED -> handleViewedReceipt(context, envelope, metadata, receiptMessage, senderRecipient.id, earlyMessageCacheEntry, batchCache) + ReceiptMessage.Type.READ -> handleReadReceipt(senderRecipient.id, envelope, metadata, receiptMessage, earlyMessageCacheEntry, batchCache) + ReceiptMessage.Type.VIEWED -> handleViewedReceipt(envelope, metadata, receiptMessage, senderRecipient.id, earlyMessageCacheEntry, batchCache) else -> warn(envelope.clientTimestamp!!, "Unknown recipient message type ${receiptMessage.type}") } } @@ -68,7 +67,6 @@ object ReceiptMessageProcessor { @SuppressLint("DefaultLocale") private fun handleReadReceipt( - context: Context, senderRecipientId: RecipientId, envelope: Envelope, metadata: EnvelopeMetadata, @@ -104,7 +102,6 @@ object ReceiptMessageProcessor { } private fun handleViewedReceipt( - context: Context, envelope: Envelope, metadata: EnvelopeMetadata, viewedReceipt: ReceiptMessage, 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 fc434eb601..0150b6647c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/SyncMessageProcessor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/SyncMessageProcessor.kt @@ -174,13 +174,13 @@ object SyncMessageProcessor { when { syncMessage.sent != null -> handleSynchronizeSentMessage(context, envelope, content, metadata, syncMessage.sent!!, senderRecipient, threadRecipient, earlyMessageCacheEntry, batchCache) - syncMessage.request != null -> handleSynchronizeRequestMessage(context, syncMessage.request!!, envelope.clientTimestamp!!) + syncMessage.request != null -> handleSynchronizeRequestMessage(syncMessage.request!!, envelope.clientTimestamp!!) syncMessage.read.isNotEmpty() -> handleSynchronizeReadMessage(context, syncMessage.read, envelope.clientTimestamp!!, earlyMessageCacheEntry, batchCache) syncMessage.viewed.isNotEmpty() -> handleSynchronizeViewedMessage(context, syncMessage.viewed, envelope.clientTimestamp!!) syncMessage.viewOnceOpen != null -> handleSynchronizeViewOnceOpenMessage(context, syncMessage.viewOnceOpen!!, envelope.clientTimestamp!!, earlyMessageCacheEntry, batchCache) syncMessage.verified != null -> handleSynchronizeVerifiedMessage(context, syncMessage.verified!!) syncMessage.stickerPackOperation.isNotEmpty() -> handleSynchronizeStickerPackOperation(syncMessage.stickerPackOperation, envelope.clientTimestamp!!) - syncMessage.configuration != null -> handleSynchronizeConfigurationMessage(context, syncMessage.configuration!!, envelope.clientTimestamp!!) + syncMessage.configuration != null -> handleSynchronizeConfigurationMessage(syncMessage.configuration!!, envelope.clientTimestamp!!) syncMessage.blocked != null -> handleSynchronizeBlockedListMessage(syncMessage.blocked!!, envelope.clientTimestamp!!) syncMessage.fetchLatest?.type != null -> handleSynchronizeFetchMessage(syncMessage.fetchLatest!!.type!!, envelope.clientTimestamp!!) syncMessage.messageRequestResponse != null -> handleSynchronizeMessageRequestResponse(syncMessage.messageRequestResponse!!, envelope.clientTimestamp!!) @@ -978,7 +978,7 @@ object SyncMessageProcessor { return threadId } - private fun handleSynchronizeRequestMessage(context: Context, message: Request, envelopeTimestamp: Long) { + private fun handleSynchronizeRequestMessage(message: Request, envelopeTimestamp: Long) { if (SignalStore.account.isPrimaryDevice) { log(envelopeTimestamp, "Synchronize request message.") } else { @@ -1135,7 +1135,7 @@ object SyncMessageProcessor { } } - private fun handleSynchronizeConfigurationMessage(context: Context, configurationMessage: Configuration, envelopeTimestamp: Long) { + private fun handleSynchronizeConfigurationMessage(configurationMessage: Configuration, envelopeTimestamp: Long) { log(envelopeTimestamp, "Synchronize configuration message.") if (configurationMessage.readReceipts != null) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplyUnknownFieldsToSelfMigrationJob.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplyUnknownFieldsToSelfMigrationJob.java index b5c8074ae5..abf1271352 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplyUnknownFieldsToSelfMigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplyUnknownFieldsToSelfMigrationJob.java @@ -73,7 +73,7 @@ public class ApplyUnknownFieldsToSelfMigrationJob extends MigrationJob { SignalAccountRecord signalAccountRecord = new SignalAccountRecord(storageId, accountRecord); Log.d(TAG, "Applying potentially now known unknowns"); - StorageSyncHelper.applyAccountStorageSyncUpdates(context, self, signalAccountRecord, false); + StorageSyncHelper.applyAccountStorageSyncUpdates(self, signalAccountRecord, false); } catch (IOException e) { Log.w(TAG, e); } 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 ee3bff011d..2e18fea846 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/LegacyMigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/LegacyMigrationJob.java @@ -24,7 +24,6 @@ import org.thoughtcrime.securesms.jobs.RefreshAttributesJob; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.transport.RetryLaterException; import org.thoughtcrime.securesms.util.FileUtils; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.VersionTracker; import java.io.File; @@ -166,7 +165,7 @@ public class LegacyMigrationJob extends MigrationJob { if (lastSeenVersion < INTERNALIZE_CONTACTS) { if (SignalStore.account().isRegistered()) { - TextSecurePreferences.setHasSuccessfullyRetrievedDirectory(context, true); + SignalStore.misc().setHasSuccessfullyRetrievedDirectory(true); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/StorageCapabilityMigrationJob.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/StorageCapabilityMigrationJob.java index 62e8b5e27d..31325d36fd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/StorageCapabilityMigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/StorageCapabilityMigrationJob.java @@ -13,7 +13,6 @@ import org.thoughtcrime.securesms.jobs.RefreshAttributesJob; import org.thoughtcrime.securesms.jobs.RefreshOwnProfileJob; import org.thoughtcrime.securesms.jobs.StorageForcePushJob; import org.thoughtcrime.securesms.keyvalue.SignalStore; -import org.thoughtcrime.securesms.util.TextSecurePreferences; /** * This does a couple things: diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/StorageServiceMigrationJob.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/StorageServiceMigrationJob.java index 497ff00d3c..7c52484a13 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/StorageServiceMigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/StorageServiceMigrationJob.java @@ -13,7 +13,6 @@ import org.thoughtcrime.securesms.jobs.MultiDeviceStorageSyncRequestJob; import org.thoughtcrime.securesms.jobs.StorageSyncJob; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.util.TextSecurePreferences; /** * Just runs a storage sync. Useful if you've started syncing a new field to storage service. diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/UserNotificationMigrationJob.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/UserNotificationMigrationJob.java index 34a310bcfb..cd9a65ba6d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/UserNotificationMigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/UserNotificationMigrationJob.java @@ -26,7 +26,6 @@ import org.thoughtcrime.securesms.MainActivity; import org.thoughtcrime.securesms.notifications.NotificationChannels; import org.thoughtcrime.securesms.notifications.NotificationIds; import org.thoughtcrime.securesms.recipients.RecipientId; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import java.util.List; import java.util.Set; @@ -73,7 +72,7 @@ public class UserNotificationMigrationJob extends MigrationJob { return; } - if (TextSecurePreferences.getFirstInstallVersion(context) < 759) { + if (SignalStore.misc().getFirstInstallVersion() < 759) { Log.w(TAG, "Install is older than v5.0.8. Skipping."); return; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/net/SignalWebSocketHealthMonitor.kt b/app/src/main/java/org/thoughtcrime/securesms/net/SignalWebSocketHealthMonitor.kt index e1a2d482f3..820d82376c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/net/SignalWebSocketHealthMonitor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/net/SignalWebSocketHealthMonitor.kt @@ -17,9 +17,7 @@ import org.signal.core.util.AppForegroundObserver import org.signal.core.util.SleepTimer import org.signal.core.util.logging.Log import org.thoughtcrime.securesms.clockskew.ClockSkewDetector -import org.thoughtcrime.securesms.dependencies.AppDependencies import org.thoughtcrime.securesms.keyvalue.SignalStore -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.signalservice.api.websocket.HealthMonitor import org.whispersystems.signalservice.api.websocket.SignalWebSocket import org.whispersystems.signalservice.api.websocket.WebSocketConnectionState @@ -91,13 +89,13 @@ class SignalWebSocketHealthMonitor( } WebSocketConnectionState.CONNECTED -> { if (webSocket is SignalWebSocket.AuthenticatedWebSocket) { - TextSecurePreferences.setUnauthorizedReceived(AppDependencies.application, false) + SignalStore.account.isUnauthorizedReceived = false } failedInConnecting = false } WebSocketConnectionState.AUTHENTICATION_FAILED -> { if (webSocket is SignalWebSocket.AuthenticatedWebSocket) { - TextSecurePreferences.setUnauthorizedReceived(AppDependencies.application, true) + SignalStore.account.isUnauthorizedReceived = true } } WebSocketConnectionState.REMOTE_DEPRECATED -> { diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationChannels.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationChannels.java index 1e8c73445a..a10047d384 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationChannels.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationChannels.java @@ -37,7 +37,6 @@ import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.util.ConversationUtil; import org.signal.core.util.ServiceUtil; import org.thoughtcrime.securesms.util.RemoteConfig; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import java.util.ArrayList; import java.util.Arrays; @@ -113,10 +112,10 @@ public class NotificationChannels { NotificationManager notificationManager = ServiceUtil.getNotificationManager(context); - int oldVersion = TextSecurePreferences.getNotificationChannelVersion(context); + int oldVersion = SignalStore.misc().getNotificationChannelVersion(); if (oldVersion != VERSION) { onUpgrade(notificationManager, oldVersion, VERSION); - TextSecurePreferences.setNotificationChannelVersion(context, VERSION); + SignalStore.misc().setNotificationChannelVersion(VERSION); } onCreate(notificationManager); @@ -214,7 +213,7 @@ public class NotificationChannels { * @return The channel ID for the default messages channel. */ public synchronized @NonNull String getMessagesChannel() { - return getMessagesChannelId(TextSecurePreferences.getNotificationMessagesChannelVersion(context)); + return getMessagesChannelId(SignalStore.misc().getNotificationMessagesChannelVersion()); } /** @@ -709,7 +708,7 @@ public class NotificationChannels { if (oldVersion < Version.AUDIO_ATTRIBUTE_CHANGE) { Context context = AppDependencies.getApplication(); - int existingMessageChannelVersion = TextSecurePreferences.getNotificationMessagesChannelVersion(context); + int existingMessageChannelVersion = SignalStore.misc().getNotificationMessagesChannelVersion(); int newMessageChannelVersion = existingMessageChannelVersion + 1; String existingChannelId = "messages_" + existingMessageChannelVersion; String newChannelId = "messages_" + newMessageChannelVersion; @@ -734,7 +733,7 @@ public class NotificationChannels { notificationManager.createNotificationChannel(newChannel); - TextSecurePreferences.setNotificationMessagesChannelVersion(context, newMessageChannelVersion); + SignalStore.misc().setNotificationMessagesChannelVersion(newMessageChannelVersion); } } } @@ -803,12 +802,12 @@ public class NotificationChannels { @TargetApi(26) private void updateMessageChannel(@NonNull ChannelUpdater updater) { NotificationManager notificationManager = ServiceUtil.getNotificationManager(context); - int existingVersion = TextSecurePreferences.getNotificationMessagesChannelVersion(context); + int existingVersion = SignalStore.misc().getNotificationMessagesChannelVersion(); int newVersion = existingVersion + 1; Log.i(TAG, "Updating message channel from version " + existingVersion + " to " + newVersion); if (updateExistingChannel(notificationManager, getMessagesChannelId(existingVersion), getMessagesChannelId(newVersion), updater)) { - TextSecurePreferences.setNotificationMessagesChannelVersion(context, newVersion); + SignalStore.misc().setNotificationMessagesChannelVersion(newVersion); } else { onCreate(notificationManager); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/UnregisteredNotifier.kt b/app/src/main/java/org/thoughtcrime/securesms/notifications/UnregisteredNotifier.kt new file mode 100644 index 0000000000..281e718bd3 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/UnregisteredNotifier.kt @@ -0,0 +1,61 @@ +/* + * Copyright 2026 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package org.thoughtcrime.securesms.notifications + +import android.Manifest +import android.app.PendingIntent +import android.content.Context +import android.content.pm.PackageManager +import androidx.core.app.NotificationCompat +import androidx.core.app.NotificationManagerCompat +import androidx.core.content.ContextCompat +import org.signal.core.util.PendingIntentFlags +import org.signal.core.util.logging.Log +import org.thoughtcrime.securesms.R +import org.thoughtcrime.securesms.keyvalue.SignalStore +import org.thoughtcrime.securesms.registration.ui.RegistrationActivity + +/** + * Notification shown when the service tells us our credentials are no longer valid, prompting the user to re-register or re-link. + */ +object UnregisteredNotifier { + + private val TAG = Log.tag(UnregisteredNotifier::class) + + fun notify(context: Context) { + if (ContextCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { + Log.w(TAG, "Notification permission is not granted.") + return + } + + val registrationIntent = if (SignalStore.account.isLinkedDevice) { + RegistrationActivity.newIntentForReLinkDevice(context) + } else { + RegistrationActivity.newIntentForReRegistration(context) + } + + val reRegistrationIntent = PendingIntent.getActivity( + context, + 0, + registrationIntent, + PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentFlags.immutable() + ) + + val notification = NotificationCompat.Builder(context, NotificationChannels.getInstance().FAILURES) + .setSmallIcon(R.drawable.ic_signal_logo_large) + .setContentText(context.getString(R.string.LoggedOutNotification_you_have_been_logged_out)) + .setContentIntent(reRegistrationIntent) + .setOnlyAlertOnce(true) + .setAutoCancel(true) + .build() + + NotificationManagerCompat.from(context).notify(NotificationIds.UNREGISTERED_NOTIFICATION_ID, notification) + } + + fun cancel(context: Context) { + NotificationManagerCompat.from(context).cancel(NotificationIds.UNREGISTERED_NOTIFICATION_ID) + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/VitalsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/notifications/VitalsViewModel.kt index d6a343ebfd..1b201738ff 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/VitalsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/VitalsViewModel.kt @@ -19,7 +19,6 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.notifications.DeviceSpecificNotificationConfig.ShowCondition import org.thoughtcrime.securesms.util.ConnectivityWarning import org.thoughtcrime.securesms.util.NetworkUtil -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.signalservice.api.websocket.WebSocketConnectionState import java.util.concurrent.TimeUnit import kotlin.time.Duration.Companion.days @@ -79,7 +78,7 @@ class VitalsViewModel(private val context: Application) : AndroidViewModel(conte val timeSinceLastConnection = System.currentTimeMillis() - SignalStore.misc.lastWebSocketConnectTime val timeSinceLastConnectionWarning = System.currentTimeMillis() - SignalStore.misc.lastConnectivityWarningTime val connectedToWebSocket = AppDependencies.webSocketObserver.value == WebSocketConnectionState.CONNECTED - val isRegistered = SignalStore.account.isRegistered && !TextSecurePreferences.isUnauthorizedReceived(context) + val isRegistered = SignalStore.account.isRegistered && !SignalStore.account.isUnauthorizedReceived if (ConnectivityWarning.isEnabled && timeSinceLastConnection > ConnectivityWarning.threshold && timeSinceLastConnectionWarning > 14.days.inWholeMilliseconds && NetworkUtil.isConnected(context) && isRegistered && !connectedToWebSocket) { return@fromCallable if (ConnectivityWarning.isDebugPromptEnabled) { 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 e4efec18e6..147cee0d7c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/BackupsPreferenceFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/BackupsPreferenceFragment.java @@ -46,7 +46,6 @@ import org.thoughtcrime.securesms.service.LocalBackupListener; import org.thoughtcrime.securesms.util.BackupUtil; import org.thoughtcrime.securesms.util.Environment; import org.thoughtcrime.securesms.util.JavaTimeExtensionsKt; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import java.text.NumberFormat; import java.time.LocalTime; @@ -330,7 +329,7 @@ public class BackupsPreferenceFragment extends Fragment { } private void updateToggle() { - boolean userUnregistered = TextSecurePreferences.isUnauthorizedReceived(AppDependencies.getApplication()) || !SignalStore.account().isRegistered(); + boolean userUnregistered = SignalStore.account().isUnauthorizedReceived() || !SignalStore.account().isRegistered(); boolean clientDeprecated = SignalStore.misc().isClientDeprecated(); boolean legacyLocalBackupsEnabled = SignalStore.settings().isBackupEnabled() && BackupUtil.canUserAccessBackupDirectory(AppDependencies.getApplication()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/CorrectedPreferenceFragment.java b/app/src/main/java/org/thoughtcrime/securesms/preferences/CorrectedPreferenceFragment.java deleted file mode 100644 index 1afe896023..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/CorrectedPreferenceFragment.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.thoughtcrime.securesms.preferences; - - -import android.annotation.SuppressLint; -import android.os.Bundle; -import android.view.View; -import android.view.ViewGroup; - -import androidx.core.view.ViewCompat; -import androidx.fragment.app.DialogFragment; -import androidx.preference.Preference; -import androidx.preference.PreferenceCategory; -import androidx.preference.PreferenceFragmentCompat; -import androidx.preference.PreferenceGroupAdapter; -import androidx.preference.PreferenceScreen; -import androidx.preference.PreferenceViewHolder; -import androidx.recyclerview.widget.RecyclerView; - -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.components.CustomDefaultPreference; - -public abstract class CorrectedPreferenceFragment extends PreferenceFragmentCompat { - - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - - View lv = getView().findViewById(android.R.id.list); - if (lv != null) lv.setPadding(0, 0, 0, 0); - } - - @Override - public void onDisplayPreferenceDialog(Preference preference) { - DialogFragment dialogFragment = null; - - if (preference instanceof CustomDefaultPreference) { - dialogFragment = CustomDefaultPreference.CustomDefaultPreferenceDialogFragmentCompat.newInstance(preference.getKey()); - } - - if (dialogFragment != null) { - dialogFragment.setTargetFragment(this, 0); - dialogFragment.show(getFragmentManager(), "android.support.v7.preference.PreferenceFragment.DIALOG"); - } else { - super.onDisplayPreferenceDialog(preference); - } - } - - @Override - @SuppressLint("RestrictedApi") - protected RecyclerView.Adapter onCreateAdapter(PreferenceScreen preferenceScreen) { - return new PreferenceGroupAdapter(preferenceScreen) { - @Override - public void onBindViewHolder(PreferenceViewHolder holder, int position) { - super.onBindViewHolder(holder, position); - Preference preference = getItem(position); - if (preference instanceof PreferenceCategory) { - setZeroPaddingToLayoutChildren(holder.itemView); - } else { - View iconFrame = holder.itemView.findViewById(androidx.preference.R.id.icon_frame); - if (iconFrame != null) { - iconFrame.setVisibility(preference.getIcon() == null ? View.GONE : View.VISIBLE); - } - } - } - }; - } - - private void setZeroPaddingToLayoutChildren(View view) { - if (!(view instanceof ViewGroup)) return; - - ViewGroup viewGroup = (ViewGroup) view; - for (int i = 0; i < viewGroup.getChildCount(); i++) { - setZeroPaddingToLayoutChildren(viewGroup.getChildAt(i)); - ViewCompat.setPaddingRelative(viewGroup, 0, viewGroup.getPaddingTop(), ViewCompat.getPaddingEnd(viewGroup), viewGroup.getPaddingBottom()); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/ListSummaryPreferenceFragment.java b/app/src/main/java/org/thoughtcrime/securesms/preferences/ListSummaryPreferenceFragment.java deleted file mode 100644 index acf3657001..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/ListSummaryPreferenceFragment.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.thoughtcrime.securesms.preferences; - - -import androidx.preference.ListPreference; -import androidx.preference.Preference; - -import org.thoughtcrime.securesms.R; - -import java.util.Arrays; - -public abstract class ListSummaryPreferenceFragment extends CorrectedPreferenceFragment { - - protected class ListSummaryListener implements Preference.OnPreferenceChangeListener { - @Override - public boolean onPreferenceChange(Preference preference, Object value) { - ListPreference listPref = (ListPreference) preference; - int entryIndex = Arrays.asList(listPref.getEntryValues()).indexOf(value); - - listPref.setSummary(entryIndex >= 0 && entryIndex < listPref.getEntries().length - ? listPref.getEntries()[entryIndex] - : getString(R.string.preferences__led_color_unknown)); - return true; - } - } - - protected void initializeListSummary(ListPreference pref) { - pref.setSummary(pref.getEntry()); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/profiles/manage/EditProfileViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/profiles/manage/EditProfileViewModel.java index c9c5279abc..d0a90234c3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/profiles/manage/EditProfileViewModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/profiles/manage/EditProfileViewModel.java @@ -24,7 +24,6 @@ import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientForeverObserver; import org.thoughtcrime.securesms.util.DefaultValueLiveData; import org.thoughtcrime.securesms.util.SingleLiveEvent; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.livedata.LiveDataUtil; import org.whispersystems.signalservice.api.util.StreamDetails; @@ -107,7 +106,7 @@ class EditProfileViewModel extends ViewModel { } public boolean isRegisteredAndUpToDate() { - return !TextSecurePreferences.isUnauthorizedReceived(AppDependencies.getApplication()) && SignalStore.account().isRegistered() && !SignalStore.misc().isClientDeprecated(); + return !SignalStore.account().isUnauthorizedReceived() && SignalStore.account().isRegistered() && !SignalStore.misc().isClientDeprecated(); } public boolean isDeprecated() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/providers/AvatarProvider.kt b/app/src/main/java/org/thoughtcrime/securesms/providers/AvatarProvider.kt index 1b10ee1f62..108012dfdd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/providers/AvatarProvider.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/providers/AvatarProvider.kt @@ -117,7 +117,7 @@ class AvatarProvider : BaseContentProvider() { if (uriMatcher.match(uri) == AVATAR) { if (VERBOSE) Log.i(TAG, "Loading avatar.") try { - val recipient = getRecipientId(uri)?.let { RecipientCreator.forRecord(application, SignalDatabase.recipients.getRecord(it)) } ?: return null + val recipient = getRecipientId(uri)?.let { RecipientCreator.forRecord(SignalDatabase.recipients.getRecord(it)) } ?: return null return getParcelFileDescriptorForAvatar(recipient) } catch (ioe: IOException) { Log.w(TAG, ioe) diff --git a/app/src/main/java/org/thoughtcrime/securesms/reactions/any/ReactWithAnyEmojiBottomSheetDialogFragment.java b/app/src/main/java/org/thoughtcrime/securesms/reactions/any/ReactWithAnyEmojiBottomSheetDialogFragment.java index 7c82181b83..573b987ccb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/reactions/any/ReactWithAnyEmojiBottomSheetDialogFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/reactions/any/ReactWithAnyEmojiBottomSheetDialogFragment.java @@ -39,7 +39,7 @@ import org.thoughtcrime.securesms.keyboard.emoji.KeyboardPageSearchView; import org.thoughtcrime.securesms.reactions.ReactionsRepository; import org.thoughtcrime.securesms.reactions.edit.EditReactionsActivity; import org.thoughtcrime.securesms.util.SystemWindowInsetsSetter; -import org.thoughtcrime.securesms.util.TextSecurePreferences; +import org.thoughtcrime.securesms.components.emoji.RecentEmojiPageModel; import org.thoughtcrime.securesms.util.ViewUtil; import org.thoughtcrime.securesms.util.adapter.mapping.MappingModel; @@ -52,7 +52,7 @@ public final class ReactWithAnyEmojiBottomSheetDialogFragment extends FixedRound { public static final String REACTION_STORAGE_KEY = "reactions_recent_emoji"; - private static final String ABOUT_STORAGE_KEY = TextSecurePreferences.RECENT_STORAGE_KEY; + private static final String ABOUT_STORAGE_KEY = RecentEmojiPageModel.RECENT_STORAGE_KEY; private static final String ARG_MESSAGE_ID = "arg_message_id"; private static final String ARG_IS_MMS = "arg_is_mms"; diff --git a/app/src/main/java/org/thoughtcrime/securesms/reactions/any/ReactWithAnyEmojiViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/reactions/any/ReactWithAnyEmojiViewModel.java index f4bb78e94b..f0b9de771a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/reactions/any/ReactWithAnyEmojiViewModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/reactions/any/ReactWithAnyEmojiViewModel.java @@ -18,7 +18,6 @@ import org.thoughtcrime.securesms.keyboard.emoji.RecentsMappingModel; import org.thoughtcrime.securesms.keyboard.emoji.search.EmojiSearchRepository; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.reactions.ReactionsRepository; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.adapter.mapping.MappingModelList; import java.util.List; @@ -133,7 +132,7 @@ public final class ReactWithAnyEmojiViewModel extends ViewModel { } private static @NonNull String getStartingKey() { - if (RecentEmojiPageModel.hasRecents(AppDependencies.getApplication(), TextSecurePreferences.RECENT_STORAGE_KEY)) { + if (RecentEmojiPageModel.hasRecents(AppDependencies.getApplication(), RecentEmojiPageModel.RECENT_STORAGE_KEY)) { return RecentEmojiPageModel.KEY; } else { return EmojiCategory.PEOPLE.getKey(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/LiveRecipient.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/LiveRecipient.java index e06d0485c3..1aa64305fa 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/LiveRecipient.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/LiveRecipient.java @@ -1,6 +1,5 @@ package org.thoughtcrime.securesms.recipients; -import android.content.Context; import androidx.annotation.NonNull; import androidx.annotation.WorkerThread; @@ -30,7 +29,6 @@ public final class LiveRecipient { private static final String TAG = Log.tag(LiveRecipient.class); - private final Context context; private final LiveData observableLiveData; private final LiveData observableLiveDataResolved; private final Set observers; @@ -40,8 +38,7 @@ public final class LiveRecipient { private final BehaviorSubject subject; private final BehaviorSubject forceNotifySubject; - LiveRecipient(@NonNull Context context, @NonNull Recipient defaultRecipient) { - this.context = context.getApplicationContext(); + LiveRecipient(@NonNull Recipient defaultRecipient) { this.subject = BehaviorSubject.createDefault(defaultRecipient); this.forceNotifySubject = BehaviorSubject.createDefault(new Object()); this.recipient = new AtomicReference<>(defaultRecipient); @@ -192,7 +189,7 @@ public final class LiveRecipient { return Recipient.UNKNOWN; } - Recipient recipient = RecipientCreator.forRecord(context, record); + Recipient recipient = RecipientCreator.forRecord(record); RecipientIdCache.INSTANCE.put(recipient); return recipient; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/LiveRecipientCache.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/LiveRecipientCache.java index f715e1b1cf..1daf36f442 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/LiveRecipientCache.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/LiveRecipientCache.java @@ -1,6 +1,5 @@ package org.thoughtcrime.securesms.recipients; -import android.content.Context; import android.database.Cursor; import androidx.annotation.AnyThread; @@ -42,7 +41,6 @@ public final class LiveRecipientCache { private static final int THREAD_CACHE_WARM_MAX = 500; private static final int CONTACT_CACHE_WARM_MAX = 50; - private final Context context; private final RecipientTable recipientTable; private final Map recipients; private final LiveRecipient unknown; @@ -51,18 +49,17 @@ public final class LiveRecipientCache { private final AtomicReference localRecipientId; private final AtomicBoolean warmedUp; - public LiveRecipientCache(@NonNull Context context) { - this(context, new FilteredExecutor(SignalExecutors.newCachedBoundedExecutor("signal-recipients", ThreadUtil.PRIORITY_UI_BLOCKING_THREAD, 1, 4, 15), () -> !SignalDatabase.inTransaction())); + public LiveRecipientCache() { + this(new FilteredExecutor(SignalExecutors.newCachedBoundedExecutor("signal-recipients", ThreadUtil.PRIORITY_UI_BLOCKING_THREAD, 1, 4, 15), () -> !SignalDatabase.inTransaction())); } @VisibleForTesting - public LiveRecipientCache(@NonNull Context context, @NonNull Executor executor) { - this.context = context.getApplicationContext(); + public LiveRecipientCache(@NonNull Executor executor) { this.recipientTable = SignalDatabase.recipients(); this.recipients = new LRUCache<>(CACHE_MAX); this.warmedUp = new AtomicBoolean(false); this.localRecipientId = new AtomicReference<>(null); - this.unknown = new LiveRecipient(context, Recipient.UNKNOWN); + this.unknown = new LiveRecipient(Recipient.UNKNOWN); this.resolveExecutor = executor; } @@ -77,7 +74,7 @@ public final class LiveRecipientCache { live = recipients.get(id); if (live == null) { - live = new LiveRecipient(context, RecipientCreator.forId(id)); + live = new LiveRecipient(RecipientCreator.forId(id)); recipients.put(id, live); needsResolve = true; } else { @@ -121,7 +118,7 @@ public final class LiveRecipientCache { .getExistingRecords(cachedIds) .values() .stream() - .map(record -> RecipientCreator.forRecord(context, record)) + .map(RecipientCreator::forRecord) .collect(Collectors.toSet()); addToCache(recipients); @@ -145,7 +142,7 @@ public final class LiveRecipientCache { live = recipients.get(recipient.getId()); if (live == null) { - live = new LiveRecipient(context, recipient); + live = new LiveRecipient(recipient); recipients.put(recipient.getId(), live); needsResolve = recipient.isResolving(); } else if (live.get().isResolving() || !recipient.isResolving()) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientCreator.kt b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientCreator.kt index d90a58a340..c941ee22ea 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientCreator.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientCreator.kt @@ -1,6 +1,5 @@ package org.thoughtcrime.securesms.recipients -import android.content.Context import androidx.annotation.VisibleForTesting import androidx.annotation.WorkerThread import org.signal.core.util.Util @@ -13,7 +12,6 @@ import org.thoughtcrime.securesms.dependencies.AppDependencies import org.thoughtcrime.securesms.groups.GroupId import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.mms.PartAuthority -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.wallpaper.ChatWallpaper import org.thoughtcrime.securesms.wallpaper.UriChatWallpaper import java.util.LinkedList @@ -32,13 +30,13 @@ object RecipientCreator { } @JvmStatic - fun forIndividual(context: Context, record: RecipientRecord): Recipient { + fun forIndividual(record: RecipientRecord): Recipient { val isSelf = record.e164 != null && record.e164 == SignalStore.account.e164 || record.aci != null && record.aci == SignalStore.account.aci val isReleaseChannel = record.id == SignalStore.releaseChannel.releaseChannelRecipientId var registeredState = record.registered if (isSelf) { - registeredState = if (SignalStore.account.isRegistered && !TextSecurePreferences.isUnauthorizedReceived(context)) { + registeredState = if (SignalStore.account.isRegistered && !SignalStore.account.isUnauthorizedReceived) { RegisteredState.REGISTERED } else { RegisteredState.NOT_REGISTERED @@ -110,7 +108,7 @@ object RecipientCreator { @JvmStatic @WorkerThread - fun forRecord(context: Context, record: RecipientRecord): Recipient { + fun forRecord(record: RecipientRecord): Recipient { val recipient = if (record.groupId != null) { getGroupRecipientDetails(record) } else if (record.distributionListId != null) { @@ -118,7 +116,7 @@ object RecipientCreator { } else if (record.callLinkRoomId != null) { getCallLinkRecipientDetails(record) } else { - forIndividual(context, record) + forIndividual(record) } return recipient diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/bottomsheet/RecipientDialogViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/bottomsheet/RecipientDialogViewModel.java index 1880130914..7f176ac376 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/bottomsheet/RecipientDialogViewModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/bottomsheet/RecipientDialogViewModel.java @@ -46,7 +46,6 @@ import org.thoughtcrime.securesms.recipients.RecipientUtil; import org.thoughtcrime.securesms.stories.StoryViewerArgs; import org.thoughtcrime.securesms.stories.viewer.StoryViewerActivity; import org.thoughtcrime.securesms.util.CommunicationActions; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.livedata.LiveDataUtil; import org.thoughtcrime.securesms.verify.VerifyIdentityActivity; @@ -80,7 +79,7 @@ final class RecipientDialogViewModel extends ViewModel { this.storyViewState = new MutableLiveData<>(); this.recipientDetailsState = new MutableLiveData<>(); this.disposables = new CompositeDisposable(); - this.isDeprecatedOrUnregistered = SignalStore.misc().isClientDeprecated() || TextSecurePreferences.isUnauthorizedReceived(context); + this.isDeprecatedOrUnregistered = SignalStore.misc().isClientDeprecated() || SignalStore.account().isUnauthorizedReceived(); boolean recipientIsSelf = recipientDialogRepository.getRecipientId().equals(Recipient.self().getId()); 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 aed0a66681..15853a5660 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 @@ -9,7 +9,6 @@ import android.app.backup.BackupManager import android.content.Context import androidx.annotation.VisibleForTesting import androidx.annotation.WorkerThread -import androidx.core.app.NotificationManagerCompat import com.google.android.gms.auth.api.phone.SmsRetriever import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay @@ -52,7 +51,6 @@ import org.thoughtcrime.securesms.jobs.RotateCertificateJob import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.net.SignalNetwork -import org.thoughtcrime.securesms.notifications.NotificationIds import org.thoughtcrime.securesms.pin.Svr3Migration import org.thoughtcrime.securesms.pin.SvrRepository import org.thoughtcrime.securesms.pin.SvrWrongPinException @@ -74,7 +72,6 @@ import org.thoughtcrime.securesms.registration.fcm.PushChallengeRequest import org.thoughtcrime.securesms.registration.viewmodel.SvrAuthCredentialSet import org.thoughtcrime.securesms.service.DirectoryRefreshListener import org.thoughtcrime.securesms.service.RotateSignedPreKeyListener -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.signalservice.api.SvrNoDataException import org.whispersystems.signalservice.api.account.AccountAttributes import org.whispersystems.signalservice.api.account.DeviceAttributes @@ -237,9 +234,8 @@ object RegistrationRepository { SignalStore.account.setServicePassword(data.servicePassword) SignalStore.account.setRegistered(registered = true, isAciChanged = isAciChanged) - TextSecurePreferences.setPromptedPushRegistration(context, true) - TextSecurePreferences.setUnauthorizedReceived(context, false) - NotificationManagerCompat.from(context).cancel(NotificationIds.UNREGISTERED_NOTIFICATION_ID) + SignalStore.registration.hasPromptedPushRegistration = true + SignalStore.account.isUnauthorizedReceived = false val masterKey = if (data.masterKey != null) MasterKey(data.masterKey.toByteArray()) else null SvrRepository.onRegistrationComplete(masterKey, data.pin, hasPin, data.reglockEnabled, SignalStore.account.restoredAccountEntropyPool) diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/ui/restore/RemoteRestoreActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/registration/ui/restore/RemoteRestoreActivity.kt index d4bd0475ca..9ae5165913 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/ui/restore/RemoteRestoreActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/ui/restore/RemoteRestoreActivity.kt @@ -86,7 +86,6 @@ import org.thoughtcrime.securesms.registration.ui.shared.RegistrationScreenTitle import org.thoughtcrime.securesms.registration.util.RegistrationUtil import org.thoughtcrime.securesms.util.DateUtils import org.thoughtcrime.securesms.util.PlayStoreUtil -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.viewModel import kotlin.time.Duration @@ -160,7 +159,7 @@ class RemoteRestoreActivity : BaseActivity() { lifecycleScope.launch { lifecycle.repeatOnLifecycle(Lifecycle.State.RESUMED) { while (isActive) { - if (TextSecurePreferences.isUnauthorizedReceived(this@RemoteRestoreActivity)) { + if (SignalStore.account.isUnauthorizedReceived) { ThreadUtil.runOnMain { showUnregisteredDialog() } break } 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 1a548881f5..3b988d31da 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 @@ -9,7 +9,6 @@ import android.content.Context import android.content.Intent import android.net.Uri import androidx.annotation.VisibleForTesting -import androidx.core.app.NotificationManagerCompat import androidx.core.net.toUri import androidx.documentfile.provider.DocumentFile import com.google.common.io.CountingInputStream @@ -55,7 +54,6 @@ import org.signal.registration.screens.messagesync.LinkAndSyncProgress import org.signal.registration.screens.remotebackuprestore.RemoteBackupRestoreProgress import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.backup.BackupEvent -import org.thoughtcrime.securesms.backup.BackupPassphrase import org.thoughtcrime.securesms.backup.FullBackupImporter import org.thoughtcrime.securesms.backup.v2.BackupRepository import org.thoughtcrime.securesms.backup.v2.RemoteRestoreResult @@ -83,13 +81,11 @@ 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 import org.thoughtcrime.securesms.keyvalue.Skipped import org.thoughtcrime.securesms.keyvalue.isDecisionPending -import org.thoughtcrime.securesms.notifications.NotificationIds import org.thoughtcrime.securesms.pin.SvrRepository import org.thoughtcrime.securesms.profiles.AvatarHelper import org.thoughtcrime.securesms.profiles.manage.UsernameRepository @@ -101,7 +97,6 @@ import org.thoughtcrime.securesms.service.DirectoryRefreshListener import org.thoughtcrime.securesms.service.LocalBackupListener import org.thoughtcrime.securesms.service.RotateSignedPreKeyListener import org.thoughtcrime.securesms.util.BackupUtil -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.signalservice.api.link.TransferArchiveResponse import org.whispersystems.signalservice.api.push.UsernameLinkComponents import java.io.File @@ -372,8 +367,6 @@ 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 @@ -827,9 +820,8 @@ class AppRegistrationStorageController(private val context: Context) : StorageCo SignalStore.account.setServicePassword(accountData.servicePassword) SignalStore.account.setRegistered(registered = true, isAciChanged = isAciChanged) - TextSecurePreferences.setPromptedPushRegistration(context, true) - TextSecurePreferences.setUnauthorizedReceived(context, false) - NotificationManagerCompat.from(context).cancel(NotificationIds.UNREGISTERED_NOTIFICATION_ID) + SignalStore.registration.hasPromptedPushRegistration = true + SignalStore.account.isUnauthorizedReceived = false SvrRepository.onRegistrationComplete( masterKey = if (pin.isNotEmpty()) masterKey else null, @@ -898,7 +890,7 @@ class AppRegistrationStorageController(private val context: Context) : StorageCo */ private fun reenableLegacyLocalBackups(rootUri: Uri, passphrase: String) { try { - BackupPassphrase.set(context, passphrase) + SignalStore.backup.v1BackupPassphrase = passphrase val takeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION context.contentResolver.takePersistableUriPermission(rootUri, takeFlags) @@ -916,27 +908,6 @@ 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/restore/RestoreActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/restore/RestoreActivity.kt index 71f4e5032f..819cfc4085 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/restore/RestoreActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/restore/RestoreActivity.kt @@ -36,7 +36,6 @@ import org.thoughtcrime.securesms.registration.ui.restore.RemoteRestoreActivity import org.thoughtcrime.securesms.registration.ui.restore.local.RestoreLocalBackupActivity import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme import org.thoughtcrime.securesms.util.Environment -import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.navigation.safeNavigate /** @@ -126,7 +125,7 @@ class RestoreActivity : BaseActivity() { lifecycleScope.launch { lifecycle.repeatOnLifecycle(Lifecycle.State.RESUMED) { while (isActive) { - if (TextSecurePreferences.isUnauthorizedReceived(this@RestoreActivity)) { + if (SignalStore.account.isUnauthorizedReceived) { ThreadUtil.runOnMain { showUnregisteredDialog() } break } diff --git a/app/src/main/java/org/thoughtcrime/securesms/restore/RestoreRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/restore/RestoreRepository.kt index a10ddf7493..4a135d9b36 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/restore/RestoreRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/restore/RestoreRepository.kt @@ -12,7 +12,6 @@ import kotlinx.coroutines.withContext import org.signal.core.util.crypto.AttachmentSecretProvider import org.signal.core.util.logging.Log import org.thoughtcrime.securesms.AppInitialization -import org.thoughtcrime.securesms.backup.BackupPassphrase import org.thoughtcrime.securesms.backup.FullBackupImporter import org.thoughtcrime.securesms.crypto.AppAttachmentSecretStore import org.thoughtcrime.securesms.database.SignalDatabase @@ -49,7 +48,7 @@ object RestoreRepository { val database = SignalDatabase.backupDatabase - BackupPassphrase.set(context, passphrase) + SignalStore.backup.v1BackupPassphrase = passphrase if (!FullBackupImporter.validatePassphrase(context, backupFileUri, passphrase)) { Log.i(TAG, "Restore failed due to invalid passphrase.") diff --git a/app/src/main/java/org/thoughtcrime/securesms/restore/restorelocalbackup/RestoreLocalBackupFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/restore/restorelocalbackup/RestoreLocalBackupFragment.kt index 5ab95e5792..afa8de3ab7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/restore/restorelocalbackup/RestoreLocalBackupFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/restore/restorelocalbackup/RestoreLocalBackupFragment.kt @@ -32,7 +32,6 @@ import org.signal.core.util.bytes import org.signal.core.util.logging.Log import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.backup.BackupEvent -import org.thoughtcrime.securesms.backup.BackupPassphrase import org.thoughtcrime.securesms.components.ViewBinderDelegate import org.thoughtcrime.securesms.databinding.FragmentRestoreLocalBackupBinding import org.thoughtcrime.securesms.keyvalue.SignalStore @@ -178,12 +177,12 @@ class RestoreLocalBackupFragment : LoggingFragment(R.layout.fragment_restore_loc } catch (_: ActivityNotFoundException) { Log.w(TAG, "No external activity found") Toast.makeText(context, R.string.BackupDialog_no_file_picker_available, Toast.LENGTH_LONG).show() - BackupPassphrase.set(context, null) + SignalStore.backup.v1BackupPassphrase = null resumeRegistrationAfterLocalBackupRestore() } } .setNegativeButton(R.string.RestoreBackupFragment__not_now) { _, _ -> - BackupPassphrase.set(context, null) + SignalStore.backup.v1BackupPassphrase = null resumeRegistrationAfterLocalBackupRestore() } .setCancelable(false) diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/DirectoryRefreshListener.java b/app/src/main/java/org/thoughtcrime/securesms/service/DirectoryRefreshListener.java index a809809999..1129128ff7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/DirectoryRefreshListener.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/DirectoryRefreshListener.java @@ -7,7 +7,6 @@ import org.thoughtcrime.securesms.dependencies.AppDependencies; import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.util.RemoteConfig; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import java.util.concurrent.TimeUnit; @@ -15,7 +14,7 @@ public class DirectoryRefreshListener extends PersistentAlarmManagerListener { @Override protected long getNextScheduledExecutionTime(Context context) { - return TextSecurePreferences.getDirectoryRefreshTime(context); + return SignalStore.misc().getDirectoryRefreshTime(); } @Override @@ -31,10 +30,10 @@ public class DirectoryRefreshListener extends PersistentAlarmManagerListener { SignalStore.misc().getCdsBlockedUtil()); } else { newTime = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(RemoteConfig.cdsRefreshIntervalSeconds()); - TextSecurePreferences.setDirectoryRefreshTime(context, newTime); + SignalStore.misc().setDirectoryRefreshTime(newTime); } - TextSecurePreferences.setDirectoryRefreshTime(context, newTime); + SignalStore.misc().setDirectoryRefreshTime(newTime); return newTime; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/RotateSignedPreKeyListener.java b/app/src/main/java/org/thoughtcrime/securesms/service/RotateSignedPreKeyListener.java index 4cd7375e94..94e842378c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/RotateSignedPreKeyListener.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/RotateSignedPreKeyListener.java @@ -5,13 +5,12 @@ import android.content.Context; import org.thoughtcrime.securesms.jobs.PreKeysSyncJob; import org.thoughtcrime.securesms.keyvalue.SignalStore; -import org.thoughtcrime.securesms.util.TextSecurePreferences; public class RotateSignedPreKeyListener extends PersistentAlarmManagerListener { @Override protected long getNextScheduledExecutionTime(Context context) { - return TextSecurePreferences.getSignedPreKeyRotationTime(context); + return SignalStore.misc().getSignedPreKeyRotationTime(); } @Override @@ -21,7 +20,7 @@ public class RotateSignedPreKeyListener extends PersistentAlarmManagerListener { } long nextTime = System.currentTimeMillis() + PreKeysSyncJob.REFRESH_INTERVAL; - TextSecurePreferences.setSignedPreKeyRotationTime(context, nextTime); + SignalStore.misc().setSignedPreKeyRotationTime(nextTime); return nextTime; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/storage/AccountRecordProcessor.kt b/app/src/main/java/org/thoughtcrime/securesms/storage/AccountRecordProcessor.kt index 3374fea12f..ef0697bfe7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/storage/AccountRecordProcessor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/storage/AccountRecordProcessor.kt @@ -1,6 +1,5 @@ package org.thoughtcrime.securesms.storage -import android.content.Context import okio.ByteString import org.signal.core.util.isNotEmpty import org.signal.core.util.logging.Log @@ -23,7 +22,6 @@ import java.util.Optional * exactly one account record). */ class AccountRecordProcessor( - private val context: Context, private val self: Recipient, private val localAccountRecord: SignalAccountRecord ) : DefaultStorageRecordProcessor() { @@ -34,10 +32,9 @@ class AccountRecordProcessor( private var foundAccountRecord = false - constructor(context: Context, self: Recipient) : this( - context = context, + constructor(self: Recipient) : this( self = self, - localAccountRecord = StorageSyncHelper.buildAccountRecord(context, self).let { it.proto.account!!.toSignalAccountRecord(it.id) } + localAccountRecord = StorageSyncHelper.buildAccountRecord(self).let { it.proto.account!!.toSignalAccountRecord(it.id) } ) /** @@ -173,7 +170,7 @@ class AccountRecordProcessor( } override fun updateLocal(update: StorageRecordUpdate) { - applyAccountStorageSyncUpdates(context, self, update, true) + applyAccountStorageSyncUpdates(self, update, true) } override fun compare(lhs: SignalAccountRecord, rhs: SignalAccountRecord): Int { 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 98b0fd5d57..0cee25d7d1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/storage/StorageSyncHelper.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/storage/StorageSyncHelper.kt @@ -1,6 +1,5 @@ package org.thoughtcrime.securesms.storage -import android.content.Context import androidx.annotation.VisibleForTesting import okio.ByteString import okio.ByteString.Companion.toByteString @@ -130,7 +129,7 @@ object StorageSyncHelper { } @JvmStatic - fun buildAccountRecord(context: Context, self: Recipient): SignalStorageRecord { + fun buildAccountRecord(self: Recipient): SignalStorageRecord { var self = self var selfRecord: RecipientRecord? = SignalDatabase.recipients.getRecordForSync(self.id) val pinned: List = SignalDatabase.threads.getPinnedRecipientIds() @@ -259,13 +258,13 @@ object StorageSyncHelper { } @JvmStatic - fun applyAccountStorageSyncUpdates(context: Context, self: Recipient, updatedRecord: SignalAccountRecord, fetchProfile: Boolean) { - val localRecord = buildAccountRecord(context, self).let { it.proto.account!!.toSignalAccountRecord(it.id) } - applyAccountStorageSyncUpdates(context, self, StorageRecordUpdate(localRecord, updatedRecord), fetchProfile) + fun applyAccountStorageSyncUpdates(self: Recipient, updatedRecord: SignalAccountRecord, fetchProfile: Boolean) { + val localRecord = buildAccountRecord(self).let { it.proto.account!!.toSignalAccountRecord(it.id) } + applyAccountStorageSyncUpdates(self, StorageRecordUpdate(localRecord, updatedRecord), fetchProfile) } @JvmStatic - fun applyAccountStorageSyncUpdates(context: Context, self: Recipient, update: StorageRecordUpdate, fetchProfile: Boolean) { + fun applyAccountStorageSyncUpdates(self: Recipient, update: StorageRecordUpdate, fetchProfile: Boolean) { SignalDatabase.recipients.applyStorageSyncAccountUpdate(update) SignalStore.settings.isReadReceiptsEnabled = update.new.proto.readReceipts diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/BackupUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/BackupUtil.java index fa5a4e38b5..e730065578 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/BackupUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/BackupUtil.java @@ -18,7 +18,6 @@ import org.signal.core.util.Util; import org.signal.core.util.logging.Log; import org.signal.libsignal.protocol.util.ByteUtil; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.backup.BackupPassphrase; import org.thoughtcrime.securesms.backup.v2.local.ArchiveFileSystem; import org.signal.core.util.NoExternalStorageException; import org.signal.core.ui.util.StorageUtil; @@ -150,7 +149,7 @@ public class BackupUtil { } public static void disableBackups(@NonNull Context context) { - BackupPassphrase.set(context, null); + SignalStore.backup().setV1BackupPassphrase(null); SignalStore.settings().setBackupEnabled(false); BackupUtil.deleteAllBackups(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/SupportEmailUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/SupportEmailUtil.java index bfebbfb001..1031a2b787 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/SupportEmailUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/SupportEmailUtil.java @@ -12,7 +12,6 @@ import org.signal.core.util.Util; import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.backup.v2.MessageBackupTier; -import org.thoughtcrime.securesms.dependencies.AppDependencies; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.recipients.Recipient; @@ -85,7 +84,7 @@ public final class SupportEmailUtil { "\n" + context.getString(R.string.SupportEmailUtil_challenge_received) + " " + getChallengeReceived() + "\n" + - context.getString(R.string.SupportEmailUtil_registered) + " " + getRegistered(context) + + context.getString(R.string.SupportEmailUtil_registered) + " " + getRegistered() + "\n" + context.getString(R.string.SupportEmailUtil_backups) + " " + getBackupTier(); } @@ -117,8 +116,8 @@ public final class SupportEmailUtil { return receivedRecently ? "yes" : "no"; } - private static String getRegistered(Context context) { - boolean registered = SignalStore.account().isRegistered() && !TextSecurePreferences.isUnauthorizedReceived(context); + private static String getRegistered() { + boolean registered = SignalStore.account().isRegistered() && !SignalStore.account().isUnauthorizedReceived(); return registered ? "yes" : "no"; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java b/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java deleted file mode 100644 index e9eac9aad1..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java +++ /dev/null @@ -1,446 +0,0 @@ -package org.thoughtcrime.securesms.util; - -import android.Manifest; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.pm.PackageManager; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.app.NotificationCompat; -import androidx.core.app.NotificationManagerCompat; -import androidx.core.content.ContextCompat; -import androidx.preference.PreferenceManager; - -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.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.SignalStore; -import org.thoughtcrime.securesms.lock.RegistrationLockReminders; -import org.thoughtcrime.securesms.notifications.NotificationChannels; -import org.thoughtcrime.securesms.notifications.NotificationIds; -import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.registration.ui.RegistrationActivity; - -public class TextSecurePreferences { - - private static final String TAG = Log.tag(TextSecurePreferences.class); - - public static final String ENABLE_MANUAL_MMS_PREF = "pref_enable_manual_mms"; - - 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 RATING_LATER_PREF = "pref_rating_later"; - private static final String RATING_ENABLED_PREF = "pref_rating_enabled"; - - private static final String MULTI_DEVICE_PROVISIONED_PREF = "pref_multi_device"; - public static final String UNAUTHORIZED_RECEIVED = "pref_unauthorized_received"; - private static final String SUCCESSFUL_DIRECTORY_PREF = "pref_successful_directory"; - - public static final String BACKUP = "pref_backup"; - private static final String BACKUP_PASSPHRASE = "pref_backup_passphrase"; - private static final String ENCRYPTED_BACKUP_PASSPHRASE = "pref_encrypted_backup_passphrase"; - - @Deprecated - public static final String REGISTRATION_LOCK_PREF_V1 = "pref_registration_lock"; - @Deprecated - private static final String REGISTRATION_LOCK_PIN_PREF_V1 = "pref_registration_lock_pin"; - - private static final String REGISTRATION_LOCK_LAST_REMINDER_TIME_POST_KBS = "pref_registration_lock_last_reminder_time_post_kbs"; - private static final String REGISTRATION_LOCK_NEXT_REMINDER_INTERVAL = "pref_registration_lock_next_reminder_interval"; - - public static final String SERVICE_OUTAGE = "pref_service_outage"; - private static final String LAST_OUTAGE_CHECK_TIME = "pref_last_outage_check_time"; - - private static final String LAST_FULL_CONTACT_SYNC_TIME = "pref_last_full_contact_sync_time"; - private static final String NEEDS_FULL_CONTACT_SYNC = "pref_needs_full_contact_sync"; - - private static final String LOG_ENCRYPTED_SECRET = "pref_log_encrypted_secret"; - private static final String LOG_UNENCRYPTED_SECRET = "pref_log_unencrypted_secret"; - - private static final String NOTIFICATION_CHANNEL_VERSION = "pref_notification_channel_version"; - private static final String NOTIFICATION_MESSAGES_CHANNEL_VERSION = "pref_notification_messages_channel_version"; - - private static final String NEEDS_MESSAGE_PULL = "pref_needs_message_pull"; - - private static final String UNIDENTIFIED_DELIVERY_ENABLED = "pref_unidentified_delivery_enabled"; - - public static final String LINK_PREVIEWS = "pref_link_previews"; - - private static final String SEEN_STICKER_INTRO_TOOLTIP = "pref_seen_sticker_intro_tooltip"; - - public static final String RECENT_STORAGE_KEY = "pref_recent_emoji2"; - - private static final String JOB_MANAGER_VERSION = "pref_job_manager_version"; - - private static final String FIRST_INSTALL_VERSION = "pref_first_install_version"; - - private static final String HAS_SEEN_SWIPE_TO_REPLY = "pref_has_seen_swipe_to_reply"; - - private static final String HAS_SEEN_VIDEO_RECORDING_TOOLTIP = "camerax.fragment.has.dismissed.video.recording.tooltip"; - - private static volatile SharedPreferences preferences = null; - - public static void onPostBackupRestore(@NonNull Context context) { - if (NotificationChannels.supported()) { - NotificationChannels.getInstance().updateMessageVibrate(SignalStore.settings().isMessageVibrateEnabled()); - } - } - - public static void registerListener(@NonNull Context context, SharedPreferences.OnSharedPreferenceChangeListener listener) { - getSharedPreferences(context).registerOnSharedPreferenceChangeListener(listener); - } - - public static void unregisterListener(@NonNull Context context, SharedPreferences.OnSharedPreferenceChangeListener listener) { - getSharedPreferences(context).unregisterOnSharedPreferenceChangeListener(listener); - } - - /** - * @deprecated Use only during re-reg where user had pinV1. - */ - @Deprecated - public static void setV1RegistrationLockEnabled(@NonNull Context context, boolean value) { - //noinspection deprecation - setBooleanPreference(context, REGISTRATION_LOCK_PREF_V1, value); - } - - /** - * @deprecated Use only for migrations to the Key Backup Store registration pinV2. - */ - @Deprecated - public static @Nullable String getDeprecatedV1RegistrationLockPin(@NonNull Context context) { - //noinspection deprecation - return getStringPreference(context, REGISTRATION_LOCK_PIN_PREF_V1, null); - } - - /** - * @deprecated Use only for migrations to the Key Backup Store registration pinV2. - */ - @Deprecated - public static void setV1RegistrationLockPin(@NonNull Context context, String pin) { - //noinspection deprecation - setStringPreference(context, REGISTRATION_LOCK_PIN_PREF_V1, pin); - } - - public static long getRegistrationLockLastReminderTime(@NonNull Context context) { - return getLongPreference(context, REGISTRATION_LOCK_LAST_REMINDER_TIME_POST_KBS, 0); - } - - public static void setRegistrationLockLastReminderTime(@NonNull Context context, long time) { - setLongPreference(context, REGISTRATION_LOCK_LAST_REMINDER_TIME_POST_KBS, time); - } - - public static long getRegistrationLockNextReminderInterval(@NonNull Context context) { - return getLongPreference(context, REGISTRATION_LOCK_NEXT_REMINDER_INTERVAL, RegistrationLockReminders.INITIAL_INTERVAL); - } - - public static void setRegistrationLockNextReminderInterval(@NonNull Context context, long value) { - setLongPreference(context, REGISTRATION_LOCK_NEXT_REMINDER_INTERVAL, value); - } - - public static void setBackupPassphrase(@NonNull Context context, @Nullable String passphrase) { - setStringPreference(context, BACKUP_PASSPHRASE, passphrase); - } - - public static @Nullable String getBackupPassphrase(@NonNull Context context) { - return getStringPreference(context, BACKUP_PASSPHRASE, null); - } - - public static void setEncryptedBackupPassphrase(@NonNull Context context, @Nullable String encryptedPassphrase) { - setStringPreference(context, ENCRYPTED_BACKUP_PASSPHRASE, encryptedPassphrase); - } - - public static @Nullable String getEncryptedBackupPassphrase(@NonNull Context context) { - return getStringPreference(context, ENCRYPTED_BACKUP_PASSPHRASE, null); - } - - public static void setHasSuccessfullyRetrievedDirectory(Context context, boolean value) { - setBooleanPreference(context, SUCCESSFUL_DIRECTORY_PREF, value); - } - - public static boolean hasSuccessfullyRetrievedDirectory(Context context) { - return getBooleanPreference(context, SUCCESSFUL_DIRECTORY_PREF, false); - } - - public static void setUnauthorizedReceived(Context context, boolean value) { - boolean previous = isUnauthorizedReceived(context); - setBooleanPreference(context, UNAUTHORIZED_RECEIVED, value); - - if (previous != value) { - Recipient.self().live().refresh(); - - if (value) { - notifyUnregisteredReceived(context); - clearLocalCredentials(context); - BackupRepository.haltBackupWritesForDeregistration(); - } - } - } - - public static boolean isUnauthorizedReceived(Context context) { - return getBooleanPreference(context, UNAUTHORIZED_RECEIVED, false); - } - - public static long getRatingLaterTimestamp(Context context) { - return getLongPreference(context, RATING_LATER_PREF, 0); - } - - public static void setRatingLaterTimestamp(Context context, long timestamp) { - setLongPreference(context, RATING_LATER_PREF, timestamp); - } - - public static boolean isRatingEnabled(Context context) { - return getBooleanPreference(context, RATING_ENABLED_PREF, true); - } - - public static void setRatingEnabled(Context context, boolean enabled) { - setBooleanPreference(context, RATING_ENABLED_PREF, enabled); - } - - public static void setIsUnidentifiedDeliveryEnabled(Context context, boolean enabled) { - setBooleanPreference(context, UNIDENTIFIED_DELIVERY_ENABLED, enabled); - } - - public static long getSignedPreKeyRotationTime(Context context) { - return getLongPreference(context, SIGNED_PREKEY_ROTATION_TIME_PREF, 0L); - } - - public static void setSignedPreKeyRotationTime(Context context, long value) { - setLongPreference(context, SIGNED_PREKEY_ROTATION_TIME_PREF, value); - } - - public static long getDirectoryRefreshTime(Context context) { - return getLongPreference(context, DIRECTORY_FRESH_TIME_PREF, 0L); - } - - public static void setDirectoryRefreshTime(Context context, long value) { - setLongPreference(context, DIRECTORY_FRESH_TIME_PREF, value); - } - - public static long getUpdateApkRefreshTime(Context context) { - return getLongPreference(context, UPDATE_APK_REFRESH_TIME_PREF, 0L); - } - - public static void setUpdateApkRefreshTime(Context context, long value) { - setLongPreference(context, UPDATE_APK_REFRESH_TIME_PREF, value); - } - - public static boolean isLegacyUseLocalApnsEnabled(Context context) { - return getBooleanPreference(context, ENABLE_MANUAL_MMS_PREF, false); - } - - public static boolean hasPromptedPushRegistration(Context context) { - return getBooleanPreference(context, PROMPTED_PUSH_REGISTRATION_PREF, false); - } - - public static void setPromptedPushRegistration(Context context, boolean value) { - setBooleanPreference(context, PROMPTED_PUSH_REGISTRATION_PREF, value); - } - - public static void setPromptedOptimizeDoze(Context context, boolean value) { - setBooleanPreference(context, PROMPTED_OPTIMIZE_DOZE_PREF, value); - } - - public static boolean hasPromptedOptimizeDoze(Context context) { - return getBooleanPreference(context, PROMPTED_OPTIMIZE_DOZE_PREF, false); - } - - public static void setLastOutageCheckTime(Context context, long timestamp) { - setLongPreference(context, LAST_OUTAGE_CHECK_TIME, timestamp); - } - - public static long getLastOutageCheckTime(Context context) { - return getLongPreference(context, LAST_OUTAGE_CHECK_TIME, 0); - } - - public static void setServiceOutage(Context context, boolean isOutage) { - setBooleanPreference(context, SERVICE_OUTAGE, isOutage); - } - - public static boolean getServiceOutage(Context context) { - return getBooleanPreference(context, SERVICE_OUTAGE, false); - } - - public static long getLastFullContactSyncTime(Context context) { - return getLongPreference(context, LAST_FULL_CONTACT_SYNC_TIME, 0); - } - - public static void setLastFullContactSyncTime(Context context, long timestamp) { - setLongPreference(context, LAST_FULL_CONTACT_SYNC_TIME, timestamp); - } - - public static boolean needsFullContactSync(Context context) { - return getBooleanPreference(context, NEEDS_FULL_CONTACT_SYNC, false); - } - - public static void setNeedsFullContactSync(Context context, boolean needsSync) { - setBooleanPreference(context, NEEDS_FULL_CONTACT_SYNC, needsSync); - } - - public static void setLogEncryptedSecret(Context context, String base64Secret) { - setStringPreference(context, LOG_ENCRYPTED_SECRET, base64Secret); - } - - public static String getLogEncryptedSecret(Context context) { - return getStringPreference(context, LOG_ENCRYPTED_SECRET, null); - } - - public static void setLogUnencryptedSecret(Context context, String base64Secret) { - setStringPreference(context, LOG_UNENCRYPTED_SECRET, base64Secret); - } - - public static String getLogUnencryptedSecret(Context context) { - return getStringPreference(context, LOG_UNENCRYPTED_SECRET, null); - } - - public static int getNotificationChannelVersion(Context context) { - return getIntegerPreference(context, NOTIFICATION_CHANNEL_VERSION, 1); - } - - public static void setNotificationChannelVersion(Context context, int version) { - setIntegerPrefrence(context, NOTIFICATION_CHANNEL_VERSION, version); - } - - public static int getNotificationMessagesChannelVersion(Context context) { - return getIntegerPreference(context, NOTIFICATION_MESSAGES_CHANNEL_VERSION, 1); - } - - public static void setNotificationMessagesChannelVersion(Context context, int version) { - setIntegerPrefrence(context, NOTIFICATION_MESSAGES_CHANNEL_VERSION, version); - } - - public static boolean getNeedsMessagePull(Context context) { - return getBooleanPreference(context, NEEDS_MESSAGE_PULL, false); - } - - public static void setNeedsMessagePull(Context context, boolean needsMessagePull) { - setBooleanPreference(context, NEEDS_MESSAGE_PULL, needsMessagePull); - } - - public static boolean hasSeenStickerIntroTooltip(Context context) { - return getBooleanPreference(context, SEEN_STICKER_INTRO_TOOLTIP, false); - } - - public static void setHasSeenStickerIntroTooltip(Context context, boolean seenStickerTooltip) { - setBooleanPreference(context, SEEN_STICKER_INTRO_TOOLTIP, seenStickerTooltip); - } - - public static void setJobManagerVersion(Context context, int version) { - setIntegerPrefrence(context, JOB_MANAGER_VERSION, version); - } - - public static int getJobManagerVersion(Context contex) { - return getIntegerPreference(contex, JOB_MANAGER_VERSION, 1); - } - - public static void setFirstInstallVersion(Context context, int version) { - setIntegerPrefrence(context, FIRST_INSTALL_VERSION, version); - } - - public static int getFirstInstallVersion(Context context) { - return getIntegerPreference(context, FIRST_INSTALL_VERSION, -1); - } - - public static boolean hasSeenSwipeToReplyTooltip(Context context) { - return getBooleanPreference(context, HAS_SEEN_SWIPE_TO_REPLY, false); - } - - public static void setHasSeenSwipeToReplyTooltip(Context context, boolean value) { - setBooleanPreference(context, HAS_SEEN_SWIPE_TO_REPLY, value); - } - - public static boolean hasSeenVideoRecordingTooltip(Context context) { - return getBooleanPreference(context, HAS_SEEN_VIDEO_RECORDING_TOOLTIP, false); - } - - public static void setHasSeenVideoRecordingTooltip(Context context, boolean value) { - setBooleanPreference(context, HAS_SEEN_VIDEO_RECORDING_TOOLTIP, value); - } - - public static void setBooleanPreference(Context context, String key, boolean value) { - getSharedPreferences(context).edit().putBoolean(key, value).apply(); - } - - public static boolean getBooleanPreference(Context context, String key, boolean defaultValue) { - return getSharedPreferences(context).getBoolean(key, defaultValue); - } - - public static void setStringPreference(Context context, String key, String value) { - getSharedPreferences(context).edit().putString(key, value).apply(); - } - - public static String getStringPreference(Context context, String key, String defaultValue) { - return getSharedPreferences(context).getString(key, defaultValue); - } - - public static int getIntegerPreference(Context context, String key, int defaultValue) { - return getSharedPreferences(context).getInt(key, defaultValue); - } - - private static void setIntegerPrefrence(Context context, String key, int value) { - getSharedPreferences(context).edit().putInt(key, value).apply(); - } - - public static long getLongPreference(Context context, String key, long defaultValue) { - return getSharedPreferences(context).getLong(key, defaultValue); - } - - private static void setLongPreference(Context context, String key, long value) { - getSharedPreferences(context).edit().putLong(key, value).apply(); - } - - private static void removePreference(Context context, String key) { - getSharedPreferences(context).edit().remove(key).apply(); - } - - private static void clearLocalCredentials(Context context) { - ProfileKey newProfileKey = ProfileKeyUtil.createNew(); - Recipient self = Recipient.self(); - SignalDatabase.recipients().setProfileKey(self.getId(), newProfileKey); - - AppDependencies.getGroupsV2Authorization().clear(); - } - - public static SharedPreferences getSharedPreferences(Context context) { - if (preferences == null) { - preferences = PreferenceManager.getDefaultSharedPreferences(context); - } - return preferences; - } - - private static void notifyUnregisteredReceived(Context context) { - if (ContextCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { - Log.w(TAG, "notifyUnregisteredReceived: Notification permission is not granted."); - return; - } - - Intent registrationIntent = SignalStore.account().isLinkedDevice() ? RegistrationActivity.newIntentForReLinkDevice(context) - : RegistrationActivity.newIntentForReRegistration(context); - - PendingIntent reRegistrationIntent = PendingIntent.getActivity(context, - 0, - registrationIntent, - PendingIntent.FLAG_UPDATE_CURRENT | PendingIntentFlags.immutable()); - - final NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NotificationChannels.getInstance().FAILURES) - .setSmallIcon(R.drawable.ic_signal_logo_large) - .setContentText(context.getString(R.string.LoggedOutNotification_you_have_been_logged_out)) - .setContentIntent(reRegistrationIntent) - .setOnlyAlertOnce(true) - .setAutoCancel(true); - NotificationManagerCompat.from(context).notify(NotificationIds.UNREGISTERED_NOTIFICATION_ID, builder.build()); - } - - // NEVER rename these -- they're persisted by name -} diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index 7cf113737b..6d3a0a6fbe 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -27,9 +27,6 @@ - - - diff --git a/app/src/test/java/org/thoughtcrime/securesms/database/RecipientTableTest.kt b/app/src/test/java/org/thoughtcrime/securesms/database/RecipientTableTest.kt index 3db43cc488..2bc57fe328 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/database/RecipientTableTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/database/RecipientTableTest.kt @@ -6,7 +6,6 @@ package org.thoughtcrime.securesms.database import android.app.Application -import androidx.test.core.app.ApplicationProvider import assertk.assertThat import assertk.assertions.isEmpty import assertk.assertions.isNotEmpty @@ -391,10 +390,7 @@ class RecipientTableTest { ) } - private fun recipientFor(id: RecipientId) = RecipientCreator.forRecord( - ApplicationProvider.getApplicationContext(), - SignalDatabase.recipients.getRecord(id) - ) + private fun recipientFor(id: RecipientId) = RecipientCreator.forRecord(SignalDatabase.recipients.getRecord(id)) companion object { val ACI_A = ACI.from(UUID.fromString("aaaa0000-5a76-47fa-a98a-7e72c948a82e")) diff --git a/app/src/test/java/org/thoughtcrime/securesms/jobs/StorageSyncJobTest.kt b/app/src/test/java/org/thoughtcrime/securesms/jobs/StorageSyncJobTest.kt index b48f892269..2000ef2b1e 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/jobs/StorageSyncJobTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/jobs/StorageSyncJobTest.kt @@ -638,7 +638,7 @@ class StorageSyncJobTest { SignalDatabase.recipients.updateStorageId(recipients.self, StorageSyncHelper.generateKey()) Recipient.self().live().refresh() - val accountRecord = StorageSyncHelper.buildAccountRecord(ApplicationProvider.getApplicationContext(), Recipient.self()) + val accountRecord = StorageSyncHelper.buildAccountRecord(Recipient.self()) remoteStorage.setRemoteState(listOf(accountRecord)) val result = runJob(StorageSyncJob.forLocalChange()) @@ -764,7 +764,7 @@ class StorageSyncJobTest { /** Our account record as another device would have rewritten it: same contents, [backupTier] swapped in, under a fresh storage id so that we see it as remote-only. */ private fun accountRecordWithBackupTier(backupTier: Long?): SignalStorageRecord { - val record = StorageSyncHelper.buildAccountRecord(ApplicationProvider.getApplicationContext(), Recipient.self()) + val record = StorageSyncHelper.buildAccountRecord(Recipient.self()) return record.copy( id = StorageId.forAccount(StorageSyncHelper.generateKey()), 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 b58ac55fac..7b303c16e6 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 @@ -62,7 +62,6 @@ import org.thoughtcrime.securesms.registration.util.RegistrationUtil import org.thoughtcrime.securesms.testutil.MockAppDependenciesRule import org.thoughtcrime.securesms.testutil.SignalDatabaseRule import org.thoughtcrime.securesms.testutil.SignalStoreRule -import org.thoughtcrime.securesms.util.TextSecurePreferences import java.io.ByteArrayInputStream import java.io.File import java.io.IOException @@ -174,8 +173,8 @@ class AppRegistrationStorageControllerTest { assertThat(selfRecord.pni).isEqualTo(pni) assertThat(selfRecord.profileKey).isNotNull() - assertThat(TextSecurePreferences.hasPromptedPushRegistration(context)).isTrue() - assertThat(TextSecurePreferences.isUnauthorizedReceived(context)).isFalse() + assertThat(SignalStore.registration.hasPromptedPushRegistration).isTrue() + assertThat(SignalStore.account.isUnauthorizedReceived).isFalse() assertThat(readInProgressData().accountDataCommitted).isTrue() diff --git a/app/src/test/java/org/thoughtcrime/securesms/testutil/RecipientTestRule.kt b/app/src/test/java/org/thoughtcrime/securesms/testutil/RecipientTestRule.kt index 51616c419b..b82915ccb2 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/testutil/RecipientTestRule.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/testutil/RecipientTestRule.kt @@ -5,7 +5,6 @@ package org.thoughtcrime.securesms.testutil -import androidx.test.core.app.ApplicationProvider import io.mockk.every import io.mockk.mockkObject import io.mockk.mockkStatic @@ -59,10 +58,7 @@ class RecipientTestRule : TestRule { private val extras = object : ExternalResource() { override fun before() { mockkStatic(AppDependencies::class) - every { AppDependencies.recipientCache } returns LiveRecipientCache( - ApplicationProvider.getApplicationContext(), - Runnable::run - ) + every { AppDependencies.recipientCache } returns LiveRecipientCache(Runnable::run) mockkObject(RemoteConfig) @@ -71,6 +67,7 @@ class RecipientTestRule : TestRule { every { signalStore.account.e164 } returns selfE164 every { signalStore.account.requireE164() } returns selfE164 every { signalStore.account.isRegistered } returns true + every { signalStore.account.isUnauthorizedReceived } returns false every { signalStore.account.deviceId } returns 1 every { signalStore.account.isMultiDevice } returns false every { signalStore.account.isLinkedDevice } returns false