diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/database/RecipientDatabaseTest.kt b/app/src/androidTest/java/org/thoughtcrime/securesms/database/RecipientDatabaseTest.kt index 9e0361beed..0470d22e5a 100644 --- a/app/src/androidTest/java/org/thoughtcrime/securesms/database/RecipientDatabaseTest.kt +++ b/app/src/androidTest/java/org/thoughtcrime/securesms/database/RecipientDatabaseTest.kt @@ -1,8 +1,6 @@ package org.thoughtcrime.securesms.database -import android.app.Application import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.platform.app.InstrumentationRegistry import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertNotEquals @@ -24,7 +22,7 @@ class RecipientDatabaseTest { @Before fun setup() { - recipientDatabase = DatabaseFactory.getRecipientDatabase(context) + recipientDatabase = SignalDatabase.recipients ensureDbEmpty() } @@ -347,11 +345,8 @@ class RecipientDatabaseTest { recipientDatabase.getAndPossiblyMerge(null, null, true) } - private val context: Application - get() = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext as Application - private fun ensureDbEmpty() { - DatabaseFactory.getInstance(context).rawDatabase.rawQuery("SELECT COUNT(*) FROM ${RecipientDatabase.TABLE_NAME}", null).use { cursor -> + SignalDatabase.rawDatabase.rawQuery("SELECT COUNT(*) FROM ${RecipientDatabase.TABLE_NAME}", null).use { cursor -> assertTrue(cursor.moveToFirst()) assertEquals(0, cursor.getLong(0)) } diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/database/RecipientDatabaseTest_merges.kt b/app/src/androidTest/java/org/thoughtcrime/securesms/database/RecipientDatabaseTest_merges.kt index c3c7f53a29..a154b7697e 100644 --- a/app/src/androidTest/java/org/thoughtcrime/securesms/database/RecipientDatabaseTest_merges.kt +++ b/app/src/androidTest/java/org/thoughtcrime/securesms/database/RecipientDatabaseTest_merges.kt @@ -3,7 +3,6 @@ package org.thoughtcrime.securesms.database import android.app.Application import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry -import net.zetetic.database.sqlcipher.SQLiteDatabase import org.junit.Assert.assertEquals import org.junit.Assert.assertNotEquals import org.junit.Assert.assertNotNull @@ -49,16 +48,16 @@ class RecipientDatabaseTest_merges { @Before fun setup() { - recipientDatabase = DatabaseFactory.getRecipientDatabase(context) - identityDatabase = DatabaseFactory.getIdentityDatabase(context) - groupReceiptDatabase = DatabaseFactory.getGroupReceiptDatabase(context) - groupDatabase = DatabaseFactory.getGroupDatabase(context) - threadDatabase = DatabaseFactory.getThreadDatabase(context) - smsDatabase = DatabaseFactory.getSmsDatabase(context) - mmsDatabase = DatabaseFactory.getMmsDatabase(context) - sessionDatabase = DatabaseFactory.getSessionDatabase(context) - mentionDatabase = DatabaseFactory.getMentionDatabase(context) - reactionDatabase = DatabaseFactory.getReactionDatabase(context) + recipientDatabase = SignalDatabase.recipients + identityDatabase = SignalDatabase.identities + groupReceiptDatabase = SignalDatabase.groupReceipts + groupDatabase = SignalDatabase.groups + threadDatabase = SignalDatabase.threads + smsDatabase = SignalDatabase.sms + mmsDatabase = SignalDatabase.mms + sessionDatabase = SignalDatabase.sessions + mentionDatabase = SignalDatabase.mentions + reactionDatabase = SignalDatabase.reactions ensureDbEmpty() } @@ -178,7 +177,7 @@ class RecipientDatabaseTest_merges { get() = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext as Application private fun ensureDbEmpty() { - DatabaseFactory.getInstance(context).rawDatabase.rawQuery("SELECT COUNT(*) FROM ${RecipientDatabase.TABLE_NAME}", null).use { cursor -> + SignalDatabase.rawDatabase.rawQuery("SELECT COUNT(*) FROM ${RecipientDatabase.TABLE_NAME}", null).use { cursor -> assertTrue(cursor.moveToFirst()) assertEquals(0, cursor.getLong(0)) } @@ -212,8 +211,7 @@ class RecipientDatabaseTest_merges { } private fun getMention(messageId: Long): MentionModel { - val db: SQLiteDatabase = DatabaseFactory.getInstance(context).rawDatabase - db.rawQuery("SELECT * FROM ${MentionDatabase.TABLE_NAME}").use { cursor -> + SignalDatabase.rawDatabase.rawQuery("SELECT * FROM ${MentionDatabase.TABLE_NAME} WHERE ${MentionDatabase.MESSAGE_ID} = $messageId").use { cursor -> cursor.moveToFirst() return MentionModel( recipientId = RecipientId.from(CursorUtil.requireLong(cursor, MentionDatabase.RECIPIENT_ID)), diff --git a/app/src/flipper/java/org/thoughtcrime/securesms/database/FlipperSqlCipherAdapter.java b/app/src/flipper/java/org/thoughtcrime/securesms/database/FlipperSqlCipherAdapter.java index df7819053a..c110705eee 100644 --- a/app/src/flipper/java/org/thoughtcrime/securesms/database/FlipperSqlCipherAdapter.java +++ b/app/src/flipper/java/org/thoughtcrime/securesms/database/FlipperSqlCipherAdapter.java @@ -16,7 +16,6 @@ import net.zetetic.database.sqlcipher.SQLiteDatabase; import net.zetetic.database.sqlcipher.SQLiteStatement; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.util.Hex; import java.lang.reflect.Field; @@ -43,14 +42,11 @@ public class FlipperSqlCipherAdapter extends DatabaseDriver getDatabases() { try { - Field databaseHelperField = DatabaseFactory.class.getDeclaredField("databaseHelper"); - databaseHelperField.setAccessible(true); - - SignalDatabase mainOpenHelper = Objects.requireNonNull((SQLCipherOpenHelper) databaseHelperField.get(DatabaseFactory.getInstance(getContext()))); - SignalDatabase keyValueOpenHelper = KeyValueDatabase.getInstance((Application) getContext()); - SignalDatabase megaphoneOpenHelper = MegaphoneDatabase.getInstance((Application) getContext()); - SignalDatabase jobManagerOpenHelper = JobDatabase.getInstance((Application) getContext()); - SignalDatabase metricsOpenHelper = LocalMetricsDatabase.getInstance((Application) getContext()); + SignalDatabaseOpenHelper mainOpenHelper = Objects.requireNonNull(SignalDatabase.getInstance()); + SignalDatabaseOpenHelper keyValueOpenHelper = KeyValueDatabase.getInstance((Application) getContext()); + SignalDatabaseOpenHelper megaphoneOpenHelper = MegaphoneDatabase.getInstance((Application) getContext()); + SignalDatabaseOpenHelper jobManagerOpenHelper = JobDatabase.getInstance((Application) getContext()); + SignalDatabaseOpenHelper metricsOpenHelper = LocalMetricsDatabase.getInstance((Application) getContext()); return Arrays.asList(new Descriptor(mainOpenHelper), new Descriptor(keyValueOpenHelper), @@ -253,9 +249,9 @@ public class FlipperSqlCipherAdapter extends DatabaseDriver SqlCipherLibraryLoader.load()) + .addBlocking("sqlcipher-init", () -> { + SqlCipherLibraryLoader.load(); + SignalDatabase.init(this, + DatabaseSecretProvider.getOrCreateDatabaseSecret(this), + AttachmentSecretProvider.getInstance(this).getOrCreateAttachmentSecret()); + }) .addBlocking("logging", () -> { initializeLogging(); Log.i(TAG, "onCreate()"); @@ -176,7 +182,7 @@ public class ApplicationContext extends MultiDexApplication implements AppForegr .addPostRender(() -> SignalStore.settings().setDefaultSms(Util.isDefaultSmsProvider(this))) .addPostRender(() -> DownloadLatestEmojiDataJob.scheduleIfNecessary(this)) .addPostRender(EmojiSearchIndexDownloadJob::scheduleIfNecessary) - .addPostRender(() -> DatabaseFactory.getMessageLogDatabase(this).trimOldMessages(System.currentTimeMillis(), FeatureFlags.retryRespondMaxAge())) + .addPostRender(() -> SignalDatabase.messageLog().trimOldMessages(System.currentTimeMillis(), FeatureFlags.retryRespondMaxAge())) .execute(); Log.d(TAG, "onCreate() took " + (System.currentTimeMillis() - startTime) + " ms"); @@ -284,7 +290,7 @@ public class ApplicationContext extends MultiDexApplication implements AppForegr private void initializeFirstEverAppLaunch() { if (TextSecurePreferences.getFirstInstallVersion(this) == -1) { - if (!SQLCipherOpenHelper.databaseFileExists(this) || VersionTracker.getDaysSinceFirstInstalled(this) < 365) { + if (!SignalDatabase.databaseFileExists(this) || VersionTracker.getDaysSinceFirstInstalled(this) < 365) { Log.i(TAG, "First ever app launch!"); AppInitialization.onFirstEverAppLaunch(this); } @@ -389,7 +395,7 @@ public class ApplicationContext extends MultiDexApplication implements AppForegr @WorkerThread private void initializeCleanup() { - int deleted = DatabaseFactory.getAttachmentDatabase(this).deleteAbandonedPreuploadedAttachments(); + int deleted = SignalDatabase.attachments().deleteAbandonedPreuploadedAttachments(); Log.i(TAG, "Deleted " + deleted + " abandoned attachments."); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/BlockUnblockDialog.java b/app/src/main/java/org/thoughtcrime/securesms/BlockUnblockDialog.java index 2cd48df70e..b090c8d39e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/BlockUnblockDialog.java +++ b/app/src/main/java/org/thoughtcrime/securesms/BlockUnblockDialog.java @@ -11,7 +11,7 @@ import androidx.lifecycle.Lifecycle; import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.util.concurrent.SimpleTask; @@ -65,7 +65,7 @@ public final class BlockUnblockDialog { Resources resources = context.getResources(); if (recipient.isGroup()) { - if (DatabaseFactory.getGroupDatabase(context).isActive(recipient.requireGroupId())) { + if (SignalDatabase.groups().isActive(recipient.requireGroupId())) { builder.setTitle(resources.getString(R.string.BlockUnblockDialog_block_and_leave_s, recipient.getDisplayName(context))); builder.setMessage(R.string.BlockUnblockDialog_you_will_no_longer_receive_messages_or_updates); builder.setPositiveButton(R.string.BlockUnblockDialog_block_and_leave, ((dialog, which) -> onBlock.run())); @@ -104,7 +104,7 @@ public final class BlockUnblockDialog { Resources resources = context.getResources(); if (recipient.isGroup()) { - if (DatabaseFactory.getGroupDatabase(context).isActive(recipient.requireGroupId())) { + if (SignalDatabase.groups().isActive(recipient.requireGroupId())) { builder.setTitle(resources.getString(R.string.BlockUnblockDialog_unblock_s, recipient.getDisplayName(context))); builder.setMessage(R.string.BlockUnblockDialog_group_members_will_be_able_to_add_you); builder.setPositiveButton(R.string.RecipientPreferenceActivity_unblock, ((dialog, which) -> onUnblock.run())); diff --git a/app/src/main/java/org/thoughtcrime/securesms/InviteActivity.java b/app/src/main/java/org/thoughtcrime/securesms/InviteActivity.java index 99ff3dae3a..eea6cae2c9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/InviteActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/InviteActivity.java @@ -24,7 +24,7 @@ import org.thoughtcrime.securesms.components.ContactFilterView; import org.thoughtcrime.securesms.components.ContactFilterView.OnFilterChangedListener; import org.thoughtcrime.securesms.contacts.ContactsCursorLoader.DisplayMode; import org.thoughtcrime.securesms.contacts.SelectedContact; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.groups.SelectionLimits; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; @@ -255,7 +255,7 @@ public class InviteActivity extends PassphraseRequiredActivity implements Contac MessageSender.send(context, new OutgoingTextMessage(recipient, message, subscriptionId), -1L, true, null, null); if (recipient.getContactUri() != null) { - DatabaseFactory.getRecipientDatabase(context).setHasSentInvite(recipient.getId()); + SignalDatabase.recipients().setHasSentInvite(recipient.getId()); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/NewConversationActivity.java b/app/src/main/java/org/thoughtcrime/securesms/NewConversationActivity.java index 36fb5c69c8..b8596db3a5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/NewConversationActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/NewConversationActivity.java @@ -26,13 +26,12 @@ import androidx.appcompat.app.AlertDialog; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.contacts.sync.DirectoryHelper; import org.thoughtcrime.securesms.conversation.ConversationIntents; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.groups.ui.creategroup.CreateGroupActivity; import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.concurrent.SimpleTask; import org.thoughtcrime.securesms.util.views.SimpleProgressDialog; import org.whispersystems.libsignal.util.guava.Optional; @@ -104,7 +103,7 @@ public class NewConversationActivity extends ContactSelectionActivity } private void launch(Recipient recipient) { - long existingThread = DatabaseFactory.getThreadDatabase(this).getThreadIdIfExistsFor(recipient.getId()); + long existingThread = SignalDatabase.threads().getThreadIdIfExistsFor(recipient.getId()); Intent intent = ConversationIntents.createBuilder(this, recipient.getId(), existingThread) .withDraftText(getIntent().getStringExtra(Intent.EXTRA_TEXT)) .withDataUri(getIntent().getData()) diff --git a/app/src/main/java/org/thoughtcrime/securesms/SmsSendtoActivity.java b/app/src/main/java/org/thoughtcrime/securesms/SmsSendtoActivity.java index 8068fa0251..b472b3a49d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/SmsSendtoActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/SmsSendtoActivity.java @@ -12,7 +12,7 @@ import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.conversation.ConversationIntents; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.util.Rfc5724Uri; @@ -48,7 +48,7 @@ public class SmsSendtoActivity extends Activity { Toast.makeText(this, R.string.ConversationActivity_specify_recipient, Toast.LENGTH_LONG).show(); } else { Recipient recipient = Recipient.external(this, destination.getDestination()); - long threadId = DatabaseFactory.getThreadDatabase(this).getThreadIdIfExistsFor(recipient.getId()); + long threadId = SignalDatabase.threads().getThreadIdIfExistsFor(recipient.getId()); nextIntent = ConversationIntents.createBuilder(this, recipient.getId(), threadId) .withDraftText(destination.getBody()) diff --git a/app/src/main/java/org/thoughtcrime/securesms/audio/AudioWaveForm.java b/app/src/main/java/org/thoughtcrime/securesms/audio/AudioWaveForm.java index b36618da0b..d06c08ed02 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/audio/AudioWaveForm.java +++ b/app/src/main/java/org/thoughtcrime/securesms/audio/AudioWaveForm.java @@ -22,7 +22,7 @@ import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.attachments.DatabaseAttachment; import org.thoughtcrime.securesms.database.AttachmentDatabase; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.databaseprotos.AudioWaveFormData; import org.thoughtcrime.securesms.media.DecryptableUriMediaInput; import org.thoughtcrime.securesms.media.MediaInput; @@ -100,7 +100,7 @@ public final class AudioWaveForm { if (attachment instanceof DatabaseAttachment) { try { - AttachmentDatabase attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context); + AttachmentDatabase attachmentDatabase = SignalDatabase.attachments(); DatabaseAttachment dbAttachment = (DatabaseAttachment) attachment; long startTime = System.currentTimeMillis(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/avatar/AvatarBundler.kt b/app/src/main/java/org/thoughtcrime/securesms/avatar/AvatarBundler.kt index f72784247e..786e2d70b0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/avatar/AvatarBundler.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/avatar/AvatarBundler.kt @@ -1,7 +1,6 @@ package org.thoughtcrime.securesms.avatar import android.os.Bundle -import java.lang.IllegalStateException /** * Utility class which encapsulates reading and writing Avatar objects to and from Bundles. diff --git a/app/src/main/java/org/thoughtcrime/securesms/avatar/AvatarPickerStorage.kt b/app/src/main/java/org/thoughtcrime/securesms/avatar/AvatarPickerStorage.kt index d3e498fec1..aa65b6f217 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/avatar/AvatarPickerStorage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/avatar/AvatarPickerStorage.kt @@ -3,7 +3,7 @@ package org.thoughtcrime.securesms.avatar import android.content.Context import android.net.Uri import android.webkit.MimeTypeMap -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.mediasend.Media import org.thoughtcrime.securesms.mms.PartAuthority import org.thoughtcrime.securesms.util.MediaUtil @@ -33,7 +33,7 @@ object AvatarPickerStorage { @JvmStatic fun cleanOrphans(context: Context) { val avatarFiles = FileStorage.getAllFiles(context, DIRECTORY, FILENAME_BASE) - val database = DatabaseFactory.getAvatarPickerDatabase(context) + val database = SignalDatabase.avatarPicker val photoAvatars = database .getAllAvatars() .filterIsInstance() diff --git a/app/src/main/java/org/thoughtcrime/securesms/avatar/photo/PhotoEditorFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/avatar/photo/PhotoEditorFragment.kt index 756ea000fa..cd3365102b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/avatar/photo/PhotoEditorFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/avatar/photo/PhotoEditorFragment.kt @@ -11,7 +11,7 @@ import org.signal.core.util.concurrent.SignalExecutors import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.avatar.AvatarBundler import org.thoughtcrime.securesms.avatar.AvatarPickerStorage -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.providers.BlobProvider import org.thoughtcrime.securesms.scribbles.ImageEditorFragment @@ -44,7 +44,7 @@ class PhotoEditorFragment : Fragment(R.layout.avatar_photo_editor_fragment), Ima val inputStream = BlobProvider.getInstance().getStream(applicationContext, editedImageUri) val onDiskUri = AvatarPickerStorage.save(applicationContext, inputStream) val photo = AvatarBundler.extractPhoto(args.photoAvatar) - val database = DatabaseFactory.getAvatarPickerDatabase(applicationContext) + val database = SignalDatabase.avatarPicker val newPhoto = photo.copy(uri = onDiskUri, size = size) database.update(newPhoto) diff --git a/app/src/main/java/org/thoughtcrime/securesms/avatar/picker/AvatarPickerRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/avatar/picker/AvatarPickerRepository.kt index 3b26c5cc75..821651af12 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/avatar/picker/AvatarPickerRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/avatar/picker/AvatarPickerRepository.kt @@ -14,7 +14,7 @@ import org.thoughtcrime.securesms.avatar.AvatarPickerStorage import org.thoughtcrime.securesms.avatar.AvatarRenderer import org.thoughtcrime.securesms.avatar.Avatars import org.thoughtcrime.securesms.conversation.colors.AvatarColor -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.groups.GroupId import org.thoughtcrime.securesms.mediasend.Media import org.thoughtcrime.securesms.profiles.AvatarHelper @@ -70,11 +70,11 @@ class AvatarPickerRepository(context: Context) { } fun getPersistedAvatarsForSelf(): Single> = Single.fromCallable { - DatabaseFactory.getAvatarPickerDatabase(applicationContext).getAvatarsForSelf() + SignalDatabase.avatarPicker.getAvatarsForSelf() } fun getPersistedAvatarsForGroup(groupId: GroupId): Single> = Single.fromCallable { - DatabaseFactory.getAvatarPickerDatabase(applicationContext).getAvatarsForGroup(groupId) + SignalDatabase.avatarPicker.getAvatarsForGroup(groupId) } fun getDefaultAvatarsForSelf(): Single> = Single.fromCallable { @@ -97,7 +97,7 @@ class AvatarPickerRepository(context: Context) { fun persistAvatarForSelf(avatar: Avatar, onPersisted: (Avatar) -> Unit) { SignalExecutors.BOUNDED.execute { - val avatarDatabase = DatabaseFactory.getAvatarPickerDatabase(applicationContext) + val avatarDatabase = SignalDatabase.avatarPicker val savedAvatar = avatarDatabase.saveAvatarForSelf(avatar) avatarDatabase.markUsage(savedAvatar) onPersisted(savedAvatar) @@ -106,7 +106,7 @@ class AvatarPickerRepository(context: Context) { fun persistAvatarForGroup(avatar: Avatar, groupId: GroupId, onPersisted: (Avatar) -> Unit) { SignalExecutors.BOUNDED.execute { - val avatarDatabase = DatabaseFactory.getAvatarPickerDatabase(applicationContext) + val avatarDatabase = SignalDatabase.avatarPicker val savedAvatar = avatarDatabase.saveAvatarForGroup(avatar, groupId) avatarDatabase.markUsage(savedAvatar) onPersisted(savedAvatar) @@ -180,7 +180,7 @@ class AvatarPickerRepository(context: Context) { fun delete(avatar: Avatar, onDelete: () -> Unit) { SignalExecutors.BOUNDED.execute { if (avatar.databaseId is Avatar.DatabaseId.Saved) { - val avatarDatabase = DatabaseFactory.getAvatarPickerDatabase(applicationContext) + val avatarDatabase = SignalDatabase.avatarPicker avatarDatabase.deleteAvatar(avatar) } onDelete() 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 a7fec0f3e4..a928f40c6d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupExporter.java +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupExporter.java @@ -43,7 +43,6 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.keyvalue.KeyValueDataSet; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.profiles.AvatarHelper; -import org.thoughtcrime.securesms.service.PendingRetryReceiptManager; import org.thoughtcrime.securesms.util.SetUtil; import org.thoughtcrime.securesms.util.Stopwatch; import org.thoughtcrime.securesms.util.TextSecurePreferences; diff --git a/app/src/main/java/org/thoughtcrime/securesms/badges/BadgeRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/badges/BadgeRepository.kt index d8814f9310..258ed47786 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/badges/BadgeRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/badges/BadgeRepository.kt @@ -4,8 +4,8 @@ import android.content.Context import io.reactivex.rxjava3.core.Completable import io.reactivex.rxjava3.schedulers.Schedulers import org.thoughtcrime.securesms.badges.models.Badge -import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.RecipientDatabase +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.storage.StorageSyncHelper @@ -19,7 +19,7 @@ class BadgeRepository(context: Context) { displayBadgesOnProfile: Boolean, selfBadges: List = Recipient.self().badges ): Completable = Completable.fromAction { - val recipientDatabase: RecipientDatabase = DatabaseFactory.getRecipientDatabase(context) + val recipientDatabase: RecipientDatabase = SignalDatabase.recipients val badges = selfBadges.map { it.copy(visible = displayBadgesOnProfile) } ProfileUtil.uploadProfileWithBadges(context, badges) @@ -35,7 +35,7 @@ class BadgeRepository(context: Context) { val reOrderedBadges = listOf(featuredBadge.copy(visible = true)) + (badges.filterNot { it.id == featuredBadge.id }) ProfileUtil.uploadProfileWithBadges(context, reOrderedBadges) - val recipientDatabase: RecipientDatabase = DatabaseFactory.getRecipientDatabase(context) + val recipientDatabase: RecipientDatabase = SignalDatabase.recipients recipientDatabase.setBadges(Recipient.self().id, reOrderedBadges) }.subscribeOn(Schedulers.io()) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/blocked/BlockedUsersRepository.java b/app/src/main/java/org/thoughtcrime/securesms/blocked/BlockedUsersRepository.java index f41ccc959f..ac892702bd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/blocked/BlockedUsersRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/blocked/BlockedUsersRepository.java @@ -7,8 +7,8 @@ import androidx.core.util.Consumer; import org.signal.core.util.concurrent.SignalExecutors; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.RecipientDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.groups.GroupChangeBusyException; import org.thoughtcrime.securesms.groups.GroupChangeFailedException; import org.thoughtcrime.securesms.recipients.Recipient; @@ -32,7 +32,7 @@ class BlockedUsersRepository { void getBlocked(@NonNull Consumer> blockedUsers) { SignalExecutors.BOUNDED.execute(() -> { - RecipientDatabase db = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase db = SignalDatabase.recipients(); try (RecipientDatabase.RecipientReader reader = db.readerForBlocked(db.getBlocked())) { int count = reader.getCount(); if (count == 0) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/ConversationItemFooter.java b/app/src/main/java/org/thoughtcrime/securesms/components/ConversationItemFooter.java index 3a795389c2..34fc3bacaa 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/ConversationItemFooter.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/ConversationItemFooter.java @@ -28,7 +28,7 @@ import com.airbnb.lottie.model.KeyPath; import org.signal.core.util.concurrent.SignalExecutors; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.animation.AnimationCompleteListener; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.database.model.MmsMessageRecord; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; @@ -360,8 +360,11 @@ public class ConversationItemFooter extends ConstraintLayout { long id = messageRecord.getId(); boolean mms = messageRecord.isMms(); - if (mms) DatabaseFactory.getMmsDatabase(getContext()).markExpireStarted(id); - else DatabaseFactory.getSmsDatabase(getContext()).markExpireStarted(id); + if (mms) { + SignalDatabase.mms().markExpireStarted(id); + } else { + SignalDatabase.mms().markExpireStarted(id); + } expirationManager.scheduleDeletion(id, mms, messageRecord.getExpiresIn()); }); diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/identity/UntrustedSendDialog.java b/app/src/main/java/org/thoughtcrime/securesms/components/identity/UntrustedSendDialog.java index 9c44f69fd9..6042be2075 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/identity/UntrustedSendDialog.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/identity/UntrustedSendDialog.java @@ -10,8 +10,6 @@ import androidx.appcompat.app.AlertDialog; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.crypto.ReentrantSessionLock; import org.thoughtcrime.securesms.crypto.storage.TextSecureIdentityKeyStore; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.IdentityDatabase; import org.thoughtcrime.securesms.database.model.IdentityRecord; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.util.concurrent.SimpleTask; diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/identity/UnverifiedSendDialog.java b/app/src/main/java/org/thoughtcrime/securesms/components/identity/UnverifiedSendDialog.java index f19978a4aa..e7669d5f9a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/identity/UnverifiedSendDialog.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/identity/UnverifiedSendDialog.java @@ -9,7 +9,6 @@ import androidx.appcompat.app.AlertDialog; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.crypto.ReentrantSessionLock; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.IdentityDatabase; import org.thoughtcrime.securesms.database.model.IdentityRecord; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberRepository.kt index a651645351..8186f05934 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberRepository.kt @@ -5,7 +5,7 @@ import androidx.annotation.WorkerThread import io.reactivex.rxjava3.core.Single import io.reactivex.rxjava3.schedulers.Schedulers import org.signal.core.util.logging.Log -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.dependencies.ApplicationDependencies import org.thoughtcrime.securesms.keyvalue.CertificateType import org.thoughtcrime.securesms.keyvalue.SignalStore @@ -59,7 +59,7 @@ class ChangeNumberRepository(private val context: Context) { @WorkerThread fun changeLocalNumber(e164: String): Single { - DatabaseFactory.getRecipientDatabase(context).updateSelfPhone(e164) + SignalDatabase.recipients.updateSelfPhone(e164) SignalStore.account().setE164(e164) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/ChatsSettingsRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/ChatsSettingsRepository.kt index e7ee1444d6..641c5ab5ae 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/ChatsSettingsRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/ChatsSettingsRepository.kt @@ -2,7 +2,7 @@ package org.thoughtcrime.securesms.components.settings.app.chats import android.content.Context import org.signal.core.util.concurrent.SignalExecutors -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.dependencies.ApplicationDependencies import org.thoughtcrime.securesms.jobs.MultiDeviceConfigurationUpdateJob import org.thoughtcrime.securesms.keyvalue.SignalStore @@ -19,7 +19,7 @@ class ChatsSettingsRepository { SignalExecutors.BOUNDED.execute { val isLinkPreviewsEnabled = SignalStore.settings().isLinkPreviewsEnabled - DatabaseFactory.getRecipientDatabase(context).markNeedsSync(Recipient.self().id) + SignalDatabase.recipients.markNeedsSync(Recipient.self().id) StorageSyncHelper.scheduleSyncForDataChange() ApplicationDependencies.getJobManager().add( MultiDeviceConfigurationUpdateJob( diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/data/DataAndStorageSettingsRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/data/DataAndStorageSettingsRepository.kt index 7b43c46d74..c24ee21d84 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/data/DataAndStorageSettingsRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/data/DataAndStorageSettingsRepository.kt @@ -2,7 +2,7 @@ package org.thoughtcrime.securesms.components.settings.app.data import android.content.Context import org.signal.core.util.concurrent.SignalExecutors -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.dependencies.ApplicationDependencies class DataAndStorageSettingsRepository { @@ -11,7 +11,7 @@ class DataAndStorageSettingsRepository { fun getTotalStorageUse(consumer: (Long) -> Unit) { SignalExecutors.BOUNDED.execute { - val breakdown = DatabaseFactory.getMediaDatabase(context).storageBreakdown + val breakdown = SignalDatabase.media.storageBreakdown consumer(listOf(breakdown.audioSize, breakdown.documentSize, breakdown.photoSize, breakdown.videoSize).sum()) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt index 10e32b29a1..9478e974e0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt @@ -15,8 +15,8 @@ import org.thoughtcrime.securesms.components.settings.DSLSettingsAdapter import org.thoughtcrime.securesms.components.settings.DSLSettingsFragment import org.thoughtcrime.securesms.components.settings.DSLSettingsText import org.thoughtcrime.securesms.components.settings.configure -import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.LocalMetricsDatabase +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.dependencies.ApplicationDependencies import org.thoughtcrime.securesms.jobs.DownloadLatestEmojiDataJob import org.thoughtcrime.securesms.jobs.RefreshAttributesJob @@ -399,13 +399,13 @@ class InternalSettingsFragment : DSLSettingsFragment(R.string.preferences__inter } private fun clearAllSenderKeyState() { - DatabaseFactory.getSenderKeyDatabase(requireContext()).deleteAll() - DatabaseFactory.getSenderKeySharedDatabase(requireContext()).deleteAll() + SignalDatabase.senderKeys.deleteAll() + SignalDatabase.senderKeyShared.deleteAll() Toast.makeText(context, "Deleted all sender key state.", Toast.LENGTH_SHORT).show() } private fun clearAllSenderKeySharedState() { - DatabaseFactory.getSenderKeySharedDatabase(requireContext()).deleteAll() + SignalDatabase.senderKeyShared.deleteAll() Toast.makeText(context, "Deleted all sender key shared state.", Toast.LENGTH_SHORT).show() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/PrivacySettingsRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/PrivacySettingsRepository.kt index 00ffed8ed0..01ad530bee 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/PrivacySettingsRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/PrivacySettingsRepository.kt @@ -2,7 +2,7 @@ package org.thoughtcrime.securesms.components.settings.app.privacy import android.content.Context import org.signal.core.util.concurrent.SignalExecutors -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.dependencies.ApplicationDependencies import org.thoughtcrime.securesms.jobs.MultiDeviceConfigurationUpdateJob import org.thoughtcrime.securesms.keyvalue.SignalStore @@ -16,7 +16,7 @@ class PrivacySettingsRepository { fun getBlockedCount(consumer: (Int) -> Unit) { SignalExecutors.BOUNDED.execute { - val recipientDatabase = DatabaseFactory.getRecipientDatabase(context) + val recipientDatabase = SignalDatabase.recipients consumer(recipientDatabase.blocked.count) } @@ -24,7 +24,7 @@ class PrivacySettingsRepository { fun syncReadReceiptState() { SignalExecutors.BOUNDED.execute { - DatabaseFactory.getRecipientDatabase(context).markNeedsSync(Recipient.self().id) + SignalDatabase.recipients.markNeedsSync(Recipient.self().id) StorageSyncHelper.scheduleSyncForDataChange() ApplicationDependencies.getJobManager().add( MultiDeviceConfigurationUpdateJob( @@ -40,7 +40,7 @@ class PrivacySettingsRepository { fun syncTypingIndicatorsState() { val enabled = TextSecurePreferences.isTypingIndicatorsEnabled(context) - DatabaseFactory.getRecipientDatabase(context).markNeedsSync(Recipient.self().id) + SignalDatabase.recipients.markNeedsSync(Recipient.self().id) StorageSyncHelper.scheduleSyncForDataChange() ApplicationDependencies.getJobManager().add( MultiDeviceConfigurationUpdateJob( diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/advanced/AdvancedPrivacySettingsRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/advanced/AdvancedPrivacySettingsRepository.kt index 6f8fe8c341..e991a8f476 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/advanced/AdvancedPrivacySettingsRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/advanced/AdvancedPrivacySettingsRepository.kt @@ -5,7 +5,7 @@ import com.google.android.gms.tasks.Tasks import com.google.firebase.installations.FirebaseInstallations import org.signal.core.util.concurrent.SignalExecutors import org.signal.core.util.logging.Log -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.dependencies.ApplicationDependencies import org.thoughtcrime.securesms.jobs.MultiDeviceConfigurationUpdateJob import org.thoughtcrime.securesms.keyvalue.SignalStore @@ -51,7 +51,7 @@ class AdvancedPrivacySettingsRepository(private val context: Context) { fun syncShowSealedSenderIconState() { SignalExecutors.BOUNDED.execute { - DatabaseFactory.getRecipientDatabase(context).markNeedsSync(Recipient.self().id) + SignalDatabase.recipients.markNeedsSync(Recipient.self().id) StorageSyncHelper.scheduleSyncForDataChange() ApplicationDependencies.getJobManager().add( MultiDeviceConfigurationUpdateJob( diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/expire/ExpireTimerSettingsRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/expire/ExpireTimerSettingsRepository.kt index b9a27f284e..a4b017143d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/expire/ExpireTimerSettingsRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/expire/ExpireTimerSettingsRepository.kt @@ -4,7 +4,7 @@ import android.content.Context import androidx.annotation.WorkerThread import org.signal.core.util.concurrent.SignalExecutors import org.signal.core.util.logging.Log -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.database.ThreadDatabase import org.thoughtcrime.securesms.groups.GroupChangeException import org.thoughtcrime.securesms.groups.GroupManager @@ -36,7 +36,7 @@ class ExpireTimerSettingsRepository(val context: Context) { consumer.invoke(Result.failure(e)) } } else { - DatabaseFactory.getRecipientDatabase(context).setExpireMessages(recipientId, newExpirationTime) + SignalDatabase.recipients.setExpireMessages(recipientId, newExpirationTime) val outgoingMessage = OutgoingExpirationUpdateMessage(Recipient.resolved(recipientId), System.currentTimeMillis(), newExpirationTime * 1000L) MessageSender.send(context, outgoingMessage, getThreadId(recipientId), false, null, null) consumer.invoke(Result.success(newExpirationTime)) @@ -46,7 +46,7 @@ class ExpireTimerSettingsRepository(val context: Context) { @WorkerThread private fun getThreadId(recipientId: RecipientId): Long { - val threadDatabase: ThreadDatabase = DatabaseFactory.getThreadDatabase(context) + val threadDatabase: ThreadDatabase = SignalDatabase.threads val recipient: Recipient = Recipient.resolved(recipientId) return threadDatabase.getOrCreateThreadIdFor(recipient) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/DonationPaymentRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/DonationPaymentRepository.kt index 5dadc7abfb..6152f51ee6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/DonationPaymentRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/DonationPaymentRepository.kt @@ -13,7 +13,7 @@ import org.signal.donations.GooglePayApi import org.signal.donations.GooglePayPaymentSource import org.signal.donations.StripeApi import org.thoughtcrime.securesms.R -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.dependencies.ApplicationDependencies import org.thoughtcrime.securesms.jobmanager.JobTracker import org.thoughtcrime.securesms.jobs.BoostReceiptRequestResponseJob @@ -65,7 +65,7 @@ class DonationPaymentRepository(activity: Activity) : StripeApi.PaymentIntentFet } private fun scheduleSyncForAccountRecordChangeSync() { - DatabaseFactory.getRecipientDatabase(application).markNeedsSync(Recipient.self().id) + SignalDatabase.recipients.markNeedsSync(Recipient.self().id) StorageSyncHelper.scheduleSyncForDataChange() } 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 3b554d3e5a..fc7aec918f 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 @@ -9,9 +9,9 @@ import org.signal.core.util.logging.Log import org.signal.storageservice.protos.groups.local.DecryptedGroup import org.signal.storageservice.protos.groups.local.DecryptedPendingMember import org.thoughtcrime.securesms.contacts.sync.DirectoryHelper -import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.GroupDatabase import org.thoughtcrime.securesms.database.MediaDatabase +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.database.model.IdentityRecord import org.thoughtcrime.securesms.dependencies.ApplicationDependencies import org.thoughtcrime.securesms.groups.GroupId @@ -40,27 +40,27 @@ class ConversationSettingsRepository( return if (threadId <= 0) { Optional.absent() } else { - Optional.of(DatabaseFactory.getMediaDatabase(context).getGalleryMediaForThread(threadId, MediaDatabase.Sorting.Newest)) + Optional.of(SignalDatabase.media.getGalleryMediaForThread(threadId, MediaDatabase.Sorting.Newest)) } } fun getThreadId(recipientId: RecipientId, consumer: (Long) -> Unit) { SignalExecutors.BOUNDED.execute { - consumer(DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(recipientId)) + consumer(SignalDatabase.threads.getThreadIdIfExistsFor(recipientId)) } } fun getThreadId(groupId: GroupId, consumer: (Long) -> Unit) { SignalExecutors.BOUNDED.execute { val recipientId = Recipient.externalGroupExact(context, groupId).id - consumer(DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(recipientId)) + consumer(SignalDatabase.threads.getThreadIdIfExistsFor(recipientId)) } } fun isInternalRecipientDetailsEnabled(): Boolean = SignalStore.internalValues().recipientDetails() fun hasGroups(consumer: (Boolean) -> Unit) { - SignalExecutors.BOUNDED.execute { consumer(DatabaseFactory.getGroupDatabase(context).activeGroupCount > 0) } + SignalExecutors.BOUNDED.execute { consumer(SignalDatabase.groups.activeGroupCount > 0) } } fun getIdentity(recipientId: RecipientId, consumer: (IdentityRecord?) -> Unit) { @@ -72,8 +72,8 @@ class ConversationSettingsRepository( fun getGroupsInCommon(recipientId: RecipientId, consumer: (List) -> Unit) { SignalExecutors.BOUNDED.execute { consumer( - DatabaseFactory - .getGroupDatabase(context) + SignalDatabase + .groups .getPushGroupsContainingMember(recipientId) .asSequence() .filter { it.members.contains(Recipient.self().id) } @@ -87,7 +87,7 @@ class ConversationSettingsRepository( fun getGroupMembership(recipientId: RecipientId, consumer: (List) -> Unit) { SignalExecutors.BOUNDED.execute { - val groupDatabase = DatabaseFactory.getGroupDatabase(context) + val groupDatabase = SignalDatabase.groups val groupRecords = groupDatabase.getPushGroupsContainingMember(recipientId) val groupRecipients = ArrayList(groupRecords.size) for (groupRecord in groupRecords) { @@ -109,13 +109,13 @@ class ConversationSettingsRepository( fun setMuteUntil(recipientId: RecipientId, until: Long) { SignalExecutors.BOUNDED.execute { - DatabaseFactory.getRecipientDatabase(context).setMuted(recipientId, until) + SignalDatabase.recipients.setMuted(recipientId, until) } } fun getGroupCapacity(groupId: GroupId, consumer: (GroupCapacityResult) -> Unit) { SignalExecutors.BOUNDED.execute { - val groupRecord: GroupDatabase.GroupRecord = DatabaseFactory.getGroupDatabase(context).getGroup(groupId).get() + val groupRecord: GroupDatabase.GroupRecord = SignalDatabase.groups.getGroup(groupId).get() consumer( if (groupRecord.isV2Group) { val decryptedGroup: DecryptedGroup = groupRecord.requireV2GroupProperties().decryptedGroup @@ -138,7 +138,7 @@ class ConversationSettingsRepository( fun addMembers(groupId: GroupId, selected: List, consumer: (GroupAddMembersResult) -> Unit) { SignalExecutors.BOUNDED.execute { - val record: GroupDatabase.GroupRecord = DatabaseFactory.getGroupDatabase(context).getGroup(groupId).get() + val record: GroupDatabase.GroupRecord = SignalDatabase.groups.getGroup(groupId).get() if (record.isAnnouncementGroup) { val needsResolve = selected @@ -171,7 +171,7 @@ class ConversationSettingsRepository( fun setMuteUntil(groupId: GroupId, until: Long) { SignalExecutors.BOUNDED.execute { val recipientId = Recipient.externalGroupExact(context, groupId).id - DatabaseFactory.getRecipientDatabase(context).setMuted(recipientId, until) + SignalDatabase.recipients.setMuted(recipientId, until) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/InternalConversationSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/InternalConversationSettingsFragment.kt index d72aad4cec..7594e8456d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/InternalConversationSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/InternalConversationSettingsFragment.kt @@ -1,6 +1,5 @@ package org.thoughtcrime.securesms.components.settings.conversation -import android.content.Context import android.graphics.Color import android.text.TextUtils import android.widget.Toast @@ -15,8 +14,7 @@ import org.thoughtcrime.securesms.components.settings.DSLSettingsAdapter import org.thoughtcrime.securesms.components.settings.DSLSettingsFragment import org.thoughtcrime.securesms.components.settings.DSLSettingsText import org.thoughtcrime.securesms.components.settings.configure -import org.thoughtcrime.securesms.database.DatabaseFactory -import org.thoughtcrime.securesms.dependencies.ApplicationDependencies +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.groups.GroupId import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.recipients.Recipient @@ -134,7 +132,7 @@ class InternalConversationSettingsFragment : DSLSettingsFragment( MaterialAlertDialogBuilder(requireContext()) .setTitle("Are you sure?") .setNegativeButton(android.R.string.cancel) { d, _ -> d.dismiss() } - .setPositiveButton(android.R.string.ok) { _, _ -> DatabaseFactory.getRecipientDatabase(requireContext()).setProfileSharing(recipient.id, false) } + .setPositiveButton(android.R.string.ok) { _, _ -> SignalDatabase.recipients.setProfileSharing(recipient.id, false) } .show() } ) @@ -148,10 +146,10 @@ class InternalConversationSettingsFragment : DSLSettingsFragment( .setNegativeButton(android.R.string.cancel) { d, _ -> d.dismiss() } .setPositiveButton(android.R.string.ok) { _, _ -> if (recipient.hasAci()) { - DatabaseFactory.getSessionDatabase(context).deleteAllFor(recipient.requireAci().toString()) + SignalDatabase.sessions.deleteAllFor(recipient.requireAci().toString()) } if (recipient.hasE164()) { - DatabaseFactory.getSessionDatabase(context).deleteAllFor(recipient.requireE164()) + SignalDatabase.sessions.deleteAllFor(recipient.requireE164()) } } .show() @@ -230,9 +228,8 @@ class InternalConversationSettingsFragment : DSLSettingsFragment( liveRecipient.observeForever(this) SignalExecutors.BOUNDED.execute { - val context: Context = ApplicationDependencies.getApplication() - val threadId: Long? = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipientId) - val groupId: GroupId? = DatabaseFactory.getGroupDatabase(context).getGroup(recipientId).transform { it.id }.orNull() + val threadId: Long? = SignalDatabase.threads.getThreadIdFor(recipientId) + val groupId: GroupId? = SignalDatabase.groups.getGroup(recipientId).transform { it.id }.orNull() store.update { state -> state.copy(threadId = threadId, groupId = groupId) } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/sounds/SoundsAndNotificationsSettingsRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/sounds/SoundsAndNotificationsSettingsRepository.kt index 58d133b19e..4cb4a80735 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/sounds/SoundsAndNotificationsSettingsRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/sounds/SoundsAndNotificationsSettingsRepository.kt @@ -2,8 +2,8 @@ package org.thoughtcrime.securesms.components.settings.conversation.sounds import android.content.Context import org.signal.core.util.concurrent.SignalExecutors -import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.RecipientDatabase +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.notifications.NotificationChannels import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.RecipientId @@ -12,13 +12,13 @@ class SoundsAndNotificationsSettingsRepository(private val context: Context) { fun setMuteUntil(recipientId: RecipientId, muteUntil: Long) { SignalExecutors.BOUNDED.execute { - DatabaseFactory.getRecipientDatabase(context).setMuted(recipientId, muteUntil) + SignalDatabase.recipients.setMuted(recipientId, muteUntil) } } fun setMentionSetting(recipientId: RecipientId, mentionSetting: RecipientDatabase.MentionSetting) { SignalExecutors.BOUNDED.execute { - DatabaseFactory.getRecipientDatabase(context).setMentionSetting(recipientId, mentionSetting) + SignalDatabase.recipients.setMentionSetting(recipientId, mentionSetting) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/sounds/custom/CustomNotificationsSettingsRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/sounds/custom/CustomNotificationsSettingsRepository.kt index b9beb8cb87..a65a237e38 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/sounds/custom/CustomNotificationsSettingsRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/sounds/custom/CustomNotificationsSettingsRepository.kt @@ -4,8 +4,8 @@ import android.content.Context import android.net.Uri import androidx.annotation.WorkerThread import org.signal.core.util.concurrent.SignalExecutors -import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.RecipientDatabase +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.notifications.NotificationChannels import org.thoughtcrime.securesms.recipients.Recipient @@ -20,7 +20,7 @@ class CustomNotificationsSettingsRepository(context: Context) { fun initialize(recipientId: RecipientId, onInitializationComplete: () -> Unit) { executor.execute { val recipient = Recipient.resolved(recipientId) - val database = DatabaseFactory.getRecipientDatabase(context) + val database = SignalDatabase.recipients if (NotificationChannels.supported() && recipient.notificationChannel != null) { database.setMessageRingtone(recipient.id, NotificationChannels.getMessageRingtone(context, recipient)) @@ -47,14 +47,14 @@ class CustomNotificationsSettingsRepository(context: Context) { executor.execute { val recipient: Recipient = Recipient.resolved(recipientId) - DatabaseFactory.getRecipientDatabase(context).setMessageVibrate(recipient.id, vibrateState) + SignalDatabase.recipients.setMessageVibrate(recipient.id, vibrateState) NotificationChannels.updateMessageVibrate(context, recipient, vibrateState) } } fun setCallingVibrate(recipientId: RecipientId, vibrateState: RecipientDatabase.VibrateState) { executor.execute { - DatabaseFactory.getRecipientDatabase(context).setCallVibrate(recipientId, vibrateState) + SignalDatabase.recipients.setCallVibrate(recipientId, vibrateState) } } @@ -64,7 +64,7 @@ class CustomNotificationsSettingsRepository(context: Context) { val defaultValue = SignalStore.settings().messageNotificationSound val newValue: Uri? = if (defaultValue == sound) null else sound ?: Uri.EMPTY - DatabaseFactory.getRecipientDatabase(context).setMessageRingtone(recipient.id, newValue) + SignalDatabase.recipients.setMessageRingtone(recipient.id, newValue) NotificationChannels.updateMessageRingtone(context, recipient, newValue) } } @@ -74,7 +74,7 @@ class CustomNotificationsSettingsRepository(context: Context) { val defaultValue = SignalStore.settings().callRingtone val newValue: Uri? = if (defaultValue == sound) null else sound ?: Uri.EMPTY - DatabaseFactory.getRecipientDatabase(context).setCallRingtone(recipientId, newValue) + SignalDatabase.recipients.setCallRingtone(recipientId, newValue) } } @@ -82,13 +82,13 @@ class CustomNotificationsSettingsRepository(context: Context) { private fun createCustomNotificationChannel(recipientId: RecipientId) { val recipient: Recipient = Recipient.resolved(recipientId) val channelId = NotificationChannels.createChannelFor(context, recipient) - DatabaseFactory.getRecipientDatabase(context).setNotificationChannel(recipient.id, channelId) + SignalDatabase.recipients.setNotificationChannel(recipient.id, channelId) } @WorkerThread private fun deleteCustomNotificationChannel(recipientId: RecipientId) { val recipient: Recipient = Recipient.resolved(recipientId) - DatabaseFactory.getRecipientDatabase(context).setNotificationChannel(recipient.id, null) + SignalDatabase.recipients.setNotificationChannel(recipient.id, null) NotificationChannels.deleteChannelFor(context, recipient) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/voice/VoiceNoteMediaItemFactory.java b/app/src/main/java/org/thoughtcrime/securesms/components/voice/VoiceNoteMediaItemFactory.java index 4139c1d1cc..93fe8b15ed 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/voice/VoiceNoteMediaItemFactory.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/voice/VoiceNoteMediaItemFactory.java @@ -14,7 +14,7 @@ import com.google.android.exoplayer2.MediaMetadata; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.database.model.MmsMessageRecord; import org.thoughtcrime.securesms.keyvalue.SignalStore; @@ -52,7 +52,7 @@ class VoiceNoteMediaItemFactory { @NonNull Uri draftUri) { - Recipient threadRecipient = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(threadId); + Recipient threadRecipient = SignalDatabase.threads().getRecipientForThreadId(threadId); if (threadRecipient == null) { threadRecipient = Recipient.UNKNOWN; } @@ -80,11 +80,11 @@ class VoiceNoteMediaItemFactory { @Nullable static MediaItem buildMediaItem(@NonNull Context context, @NonNull MessageRecord messageRecord) { - int startingPosition = DatabaseFactory.getMmsSmsDatabase(context) + int startingPosition = SignalDatabase.mmsSms() .getMessagePositionInConversation(messageRecord.getThreadId(), messageRecord.getDateReceived()); - Recipient threadRecipient = Objects.requireNonNull(DatabaseFactory.getThreadDatabase(context) + Recipient threadRecipient = Objects.requireNonNull(SignalDatabase.threads() .getRecipientForThreadId(messageRecord.getThreadId())); Recipient sender = messageRecord.isOutgoing() ? Recipient.self() : messageRecord.getIndividualRecipient(); Recipient avatarRecipient = threadRecipient.isGroup() ? threadRecipient : sender; diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/voice/VoiceNotePlaybackPreparer.java b/app/src/main/java/org/thoughtcrime/securesms/components/voice/VoiceNotePlaybackPreparer.java index 38dec621f9..3d45dc3953 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/voice/VoiceNotePlaybackPreparer.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/voice/VoiceNotePlaybackPreparer.java @@ -23,8 +23,8 @@ import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector; import org.signal.core.util.ThreadUtil; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.NoSuchMessageException; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.util.MessageRecordUtil; import org.thoughtcrime.securesms.util.Util; @@ -240,8 +240,8 @@ final class VoiceNotePlaybackPreparer implements MediaSessionConnector.PlaybackP private @NonNull List loadMediaItemsForSinglePlayback(long messageId) { try { - MessageRecord messageRecord = DatabaseFactory.getMmsDatabase(context) - .getMessageRecord(messageId); + MessageRecord messageRecord = SignalDatabase.mms() + .getMessageRecord(messageId); if (!MessageRecordUtil.hasAudio(messageRecord)) { Log.w(TAG, "Message does not contain audio."); @@ -268,7 +268,7 @@ final class VoiceNotePlaybackPreparer implements MediaSessionConnector.PlaybackP @WorkerThread private @NonNull List loadMediaItemsForConsecutivePlayback(long messageId) { try { - List recordsAfter = DatabaseFactory.getMmsSmsDatabase(context) + List recordsAfter = SignalDatabase.mmsSms() .getMessagesAfterVoiceNoteInclusive(messageId, LIMIT); return buildFilteredMessageRecordList(recordsAfter).stream() diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/voice/VoiceNotePlaybackService.java b/app/src/main/java/org/thoughtcrime/securesms/components/voice/VoiceNotePlaybackService.java index f6fccfd3cc..b74e9185c9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/voice/VoiceNotePlaybackService.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/voice/VoiceNotePlaybackService.java @@ -29,8 +29,8 @@ import com.google.android.exoplayer2.ui.PlayerNotificationManager; import org.signal.core.util.concurrent.SignalExecutors; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessageDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.MessageId; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobs.MultiDeviceViewedUpdateJob; @@ -241,7 +241,7 @@ public class VoiceNotePlaybackService extends MediaBrowserServiceCompat { } long messageId = extras.getLong(VoiceNoteMediaItemFactory.EXTRA_MESSAGE_ID); RecipientId recipientId = RecipientId.from(extras.getString(VoiceNoteMediaItemFactory.EXTRA_INDIVIDUAL_RECIPIENT_ID)); - MessageDatabase messageDatabase = DatabaseFactory.getMmsDatabase(this); + MessageDatabase messageDatabase = SignalDatabase.mms(); MessageDatabase.MarkedMessageInfo markedMessageInfo = messageDatabase.setIncomingMessageViewed(messageId); diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/WebRtcCallRepository.java b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/WebRtcCallRepository.java index 23ac9d94c8..ebeaf8ef34 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/WebRtcCallRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/WebRtcCallRepository.java @@ -7,8 +7,8 @@ import androidx.annotation.WorkerThread; import androidx.core.util.Consumer; import org.signal.core.util.concurrent.SignalExecutors; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.identity.IdentityRecordList; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.recipients.Recipient; @@ -30,7 +30,7 @@ class WebRtcCallRepository { List recipients; if (recipient.isGroup()) { - recipients = DatabaseFactory.getGroupDatabase(context).getGroupMembers(recipient.requireGroupId(), GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF); + recipients = SignalDatabase.groups().getGroupMembers(recipient.requireGroupId(), GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF); } else { recipients = Collections.singletonList(recipient); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactAccessor.java b/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactAccessor.java index 0d1e54ba03..62a77800ce 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactAccessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactAccessor.java @@ -26,39 +26,18 @@ import android.os.Parcelable; import android.provider.ContactsContract; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract.Contacts; -import android.provider.ContactsContract.PhoneLookup; import android.telephony.PhoneNumberUtils; import android.text.TextUtils; -import androidx.annotation.NonNull; - -import com.annimon.stream.Stream; - -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.contactshare.Contact; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.GroupDatabase; -import org.thoughtcrime.securesms.database.RecipientDatabase; import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter; -import org.thoughtcrime.securesms.profiles.ProfileName; -import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.recipients.RecipientId; -import org.thoughtcrime.securesms.util.CursorUtil; import org.thoughtcrime.securesms.util.SqlUtil; -import org.thoughtcrime.securesms.util.TextSecurePreferences; -import org.thoughtcrime.securesms.util.Util; import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; -import java.util.Map; import java.util.Set; -import static org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord; - /** * This class was originally a layer of indirection between * ContactAccessorNewApi and ContactAccessorOldApi, which corresponded diff --git a/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactRepository.java b/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactRepository.java index 792e998c0d..9d663c7c1b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactRepository.java @@ -11,8 +11,8 @@ import androidx.annotation.NonNull; import androidx.annotation.WorkerThread; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.RecipientDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.util.CursorUtil; @@ -102,7 +102,7 @@ public class ContactRepository { }}; public ContactRepository(@NonNull Context context) { - this.recipientDatabase = DatabaseFactory.getRecipientDatabase(context); + this.recipientDatabase = SignalDatabase.recipients(); this.noteToSelfTitle = context.getString(R.string.note_to_self); this.context = context.getApplicationContext(); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactsCursorLoader.java b/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactsCursorLoader.java index 78e69f5820..8d8b302893 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactsCursorLoader.java +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactsCursorLoader.java @@ -24,8 +24,8 @@ import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.database.model.ThreadRecord; import org.thoughtcrime.securesms.phonenumbers.NumberUtil; @@ -181,7 +181,7 @@ public class ContactsCursorLoader extends AbstractContactsCursorLoader { } private Cursor getRecentConversationsCursor(boolean groupsOnly) { - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(getContext()); + ThreadDatabase threadDatabase = SignalDatabase.threads(); MatrixCursor recentConversations = ContactsCursorRows.createMatrixCursor(RECENT_CONVERSATION_MAX); try (Cursor rawConversations = threadDatabase.getRecentConversationList(RECENT_CONVERSATION_MAX, flagSet(mode, DisplayMode.FLAG_INACTIVE_GROUPS), groupsOnly, hideGroupsV1(mode), !smsEnabled(mode))) { @@ -210,7 +210,7 @@ public class ContactsCursorLoader extends AbstractContactsCursorLoader { private Cursor getGroupsCursor() { MatrixCursor groupContacts = ContactsCursorRows.createMatrixCursor(); - try (GroupDatabase.Reader reader = DatabaseFactory.getGroupDatabase(getContext()).getGroupsFilteredByTitle(getFilter(), flagSet(mode, DisplayMode.FLAG_INACTIVE_GROUPS), hideGroupsV1(mode), !smsEnabled(mode))) { + try (GroupDatabase.Reader reader = SignalDatabase.groups().getGroupsFilteredByTitle(getFilter(), flagSet(mode, DisplayMode.FLAG_INACTIVE_GROUPS), hideGroupsV1(mode), !smsEnabled(mode))) { GroupDatabase.GroupRecord groupRecord; while ((groupRecord = reader.getNext()) != null) { groupContacts.addRow(ContactsCursorRows.forGroup(groupRecord)); diff --git a/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactsSyncAdapter.java b/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactsSyncAdapter.java index 2f7e643d2e..8c67be3bb3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactsSyncAdapter.java +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactsSyncAdapter.java @@ -7,23 +7,20 @@ import android.content.Context; import android.content.SyncResult; import android.os.Bundle; -import androidx.annotation.NonNull; import com.annimon.stream.Stream; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.contacts.sync.DirectoryHelper; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.util.SetUtil; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import java.io.IOException; import java.util.List; -import java.util.Map; import java.util.Set; public class ContactsSyncAdapter extends AbstractThreadedSyncAdapter { @@ -51,7 +48,7 @@ public class ContactsSyncAdapter extends AbstractThreadedSyncAdapter { } Set allSystemNumbers = ContactAccessor.getInstance().getAllContactsWithNumbers(context); - Set knownSystemNumbers = DatabaseFactory.getRecipientDatabase(context).getAllPhoneNumbers(); + Set knownSystemNumbers = SignalDatabase.recipients().getAllPhoneNumbers(); Set unknownSystemNumbers = SetUtil.difference(allSystemNumbers, knownSystemNumbers); if (unknownSystemNumbers.size() > FULL_SYNC_THRESHOLD) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/contacts/TurnOffContactJoinedNotificationsActivity.java b/app/src/main/java/org/thoughtcrime/securesms/contacts/TurnOffContactJoinedNotificationsActivity.java index 37f4017cf3..d4c369fb9e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contacts/TurnOffContactJoinedNotificationsActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/TurnOffContactJoinedNotificationsActivity.java @@ -9,13 +9,12 @@ import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessageDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.notifications.MarkReadReceiver; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.concurrent.SimpleTask; import java.util.List; @@ -53,7 +52,7 @@ public class TurnOffContactJoinedNotificationsActivity extends AppCompatActivity private void handlePositiveAction(@NonNull DialogInterface dialog) { SimpleTask.run(getLifecycle(), () -> { - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(this); + ThreadDatabase threadDatabase = SignalDatabase.threads(); List marked = threadDatabase.setRead(getIntent().getLongExtra(EXTRA_THREAD_ID, -1), false); MarkReadReceiver.process(this, marked); diff --git a/app/src/main/java/org/thoughtcrime/securesms/contacts/avatars/GroupRecordContactPhoto.java b/app/src/main/java/org/thoughtcrime/securesms/contacts/avatars/GroupRecordContactPhoto.java index 53369eb9e6..a02f665819 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contacts/avatars/GroupRecordContactPhoto.java +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/avatars/GroupRecordContactPhoto.java @@ -8,8 +8,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import org.signal.core.util.Conversions; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.profiles.AvatarHelper; import org.whispersystems.libsignal.util.guava.Optional; @@ -30,7 +30,7 @@ public final class GroupRecordContactPhoto implements ContactPhoto { @Override public InputStream openInputStream(Context context) throws IOException { - GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); + GroupDatabase groupDatabase = SignalDatabase.groups(); Optional groupRecord = groupDatabase.getGroup(groupId); if (!groupRecord.isPresent() || !AvatarHelper.hasAvatar(context, groupRecord.get().getRecipientId())) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/DirectoryHelper.java b/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/DirectoryHelper.java index 3cc60dd48c..afcbdba89a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/DirectoryHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/DirectoryHelper.java @@ -24,11 +24,11 @@ import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.contacts.ContactAccessor; import org.thoughtcrime.securesms.contacts.ContactsDatabase; import org.thoughtcrime.securesms.crypto.SessionUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessageDatabase.InsertResult; import org.thoughtcrime.securesms.database.RecipientDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase.BulkOperationsHandle; import org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.whispersystems.signalservice.api.push.ACI; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob; @@ -98,7 +98,7 @@ public class DirectoryHelper { return; } - RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase recipientDatabase = SignalDatabase.recipients(); Set databaseNumbers = sanitizeNumbers(recipientDatabase.getAllPhoneNumbers()); Set systemNumbers = sanitizeNumbers(ContactAccessor.getInstance().getAllContactsWithNumbers(context)); @@ -109,7 +109,7 @@ public class DirectoryHelper { @WorkerThread public static void refreshDirectoryFor(@NonNull Context context, @NonNull List recipients, boolean notifyOfNewUsers) throws IOException { - RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase recipientDatabase = SignalDatabase.recipients(); for (Recipient recipient : recipients) { if (recipient.hasAci() && !recipient.hasE164()) { @@ -132,7 +132,7 @@ public class DirectoryHelper { @WorkerThread public static RegisteredState refreshDirectoryFor(@NonNull Context context, @NonNull Recipient recipient, boolean notifyOfNewUsers) throws IOException { Stopwatch stopwatch = new Stopwatch("single"); - RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase recipientDatabase = SignalDatabase.recipients(); RegisteredState originalRegisteredState = recipient.resolve().getRegistered(); RegisteredState newRegisteredState; @@ -221,7 +221,7 @@ public class DirectoryHelper { @WorkerThread private static void refreshNumbers(@NonNull Context context, @NonNull Set databaseNumbers, @NonNull Set systemNumbers, boolean notifyOfNewUsers, boolean removeSystemContactEntryForMissing) throws IOException { - RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase recipientDatabase = SignalDatabase.recipients(); Set allNumbers = SetUtil.union(databaseNumbers, systemNumbers); if (allNumbers.isEmpty()) { @@ -325,7 +325,7 @@ public class DirectoryHelper { } try { - ContactsDatabase contactsDatabase = DatabaseFactory.getContactsDatabase(context); + ContactsDatabase contactsDatabase = SignalDatabase.contacts(); List activeAddresses = Stream.of(activeIds) .map(Recipient::resolved) .filter(Recipient::hasE164) @@ -342,7 +342,7 @@ public class DirectoryHelper { } private static void syncRecipientInfoWithSystemContacts(@NonNull Context context, @NonNull Map rewrites) { - RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase recipientDatabase = SignalDatabase.recipients(); BulkOperationsHandle handle = recipientDatabase.beginBulkSystemContactUpdate(); try (Cursor cursor = ContactAccessor.getInstance().getAllSystemContacts(context)) { @@ -406,7 +406,7 @@ public class DirectoryHelper { } if (NotificationChannels.supported()) { - try (RecipientDatabase.RecipientReader recipients = DatabaseFactory.getRecipientDatabase(context).getRecipientsWithNotificationChannels()) { + try (RecipientDatabase.RecipientReader recipients = SignalDatabase.recipients().getRecipientsWithNotificationChannels()) { Recipient recipient; while ((recipient = recipients.getNext()) != null) { NotificationChannels.updateContactChannelName(context, recipient); @@ -480,7 +480,7 @@ public class DirectoryHelper { recipient.hasAUserSetDisplayName(context)) { IncomingJoinedMessage message = new IncomingJoinedMessage(recipient.getId()); - Optional insertResult = DatabaseFactory.getSmsDatabase(context).insertMessageInbox(message); + Optional insertResult = SignalDatabase.sms().insertMessageInbox(message); if (insertResult.isPresent()) { int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY); @@ -549,9 +549,9 @@ public class DirectoryHelper { } private static boolean hasCommunicatedWith(@NonNull Context context, @NonNull Recipient recipient) { - return DatabaseFactory.getThreadDatabase(context).hasThread(recipient.getId()) || - (recipient.hasAci() && DatabaseFactory.getSessionDatabase(context).hasSessionFor(recipient.requireAci().toString())) || - (recipient.hasE164() && DatabaseFactory.getSessionDatabase(context).hasSessionFor(recipient.requireE164())); + return SignalDatabase.threads().hasThread(recipient.getId()) || + (recipient.hasAci() && SignalDatabase.sessions().hasSessionFor(recipient.requireAci().toString())) || + (recipient.hasE164() && SignalDatabase.sessions().hasSessionFor(recipient.requireE164())); } static class DirectoryResult { diff --git a/app/src/main/java/org/thoughtcrime/securesms/contactshare/ContactShareEditActivity.java b/app/src/main/java/org/thoughtcrime/securesms/contactshare/ContactShareEditActivity.java index 2b677e427a..6731aa7890 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contactshare/ContactShareEditActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/contactshare/ContactShareEditActivity.java @@ -17,7 +17,7 @@ import androidx.recyclerview.widget.RecyclerView; import org.thoughtcrime.securesms.PassphraseRequiredActivity; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.mms.GlideApp; import org.thoughtcrime.securesms.util.DynamicLanguage; import org.thoughtcrime.securesms.util.DynamicTheme; @@ -78,8 +78,8 @@ public class ContactShareEditActivity extends PassphraseRequiredActivity impleme contactList.setAdapter(contactAdapter); SharedContactRepository contactRepository = new SharedContactRepository(this, - AsyncTask.THREAD_POOL_EXECUTOR, - DatabaseFactory.getContactsDatabase(this)); + AsyncTask.THREAD_POOL_EXECUTOR, + SignalDatabase.contacts()); viewModel = ViewModelProviders.of(this, new Factory(contactUris, contactRepository)).get(ContactShareEditViewModel.class); viewModel.getContacts().observe(this, contacts -> { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java index fb67b0fbe4..9adc00f7ff 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java @@ -152,7 +152,6 @@ import org.thoughtcrime.securesms.conversation.ui.groupcall.GroupCallViewModel; import org.thoughtcrime.securesms.conversation.ui.mentions.MentionsPickerViewModel; import org.thoughtcrime.securesms.crypto.ReentrantSessionLock; import org.thoughtcrime.securesms.crypto.SecurityEvent; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.DraftDatabase; import org.thoughtcrime.securesms.database.DraftDatabase.Draft; import org.thoughtcrime.securesms.database.DraftDatabase.Drafts; @@ -163,6 +162,7 @@ import org.thoughtcrime.securesms.database.MentionUtil.UpdatedBodyAndMentions; import org.thoughtcrime.securesms.database.MmsSmsColumns.Types; import org.thoughtcrime.securesms.database.RecipientDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.database.identity.IdentityRecordList; import org.thoughtcrime.securesms.database.model.IdentityRecord; @@ -1195,8 +1195,7 @@ public class ConversationActivity extends PassphraseRequiredActivity new AsyncTask() { @Override protected Void doInBackground(Void... params) { - DatabaseFactory.getRecipientDatabase(ConversationActivity.this) - .setMuted(recipient.getId(), until); + SignalDatabase.recipients().setMuted(recipient.getId(), until); return null; } @@ -1222,9 +1221,7 @@ public class ConversationActivity extends PassphraseRequiredActivity new AsyncTask() { @Override protected Void doInBackground(Void... params) { - DatabaseFactory.getRecipientDatabase(ConversationActivity.this) - .setMuted(recipient.getId(), 0); - + SignalDatabase.recipients().setMuted(recipient.getId(), 0); return null; } }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); @@ -1358,8 +1355,7 @@ public class ConversationActivity extends PassphraseRequiredActivity new AsyncTask() { @Override protected Void doInBackground(Void... params) { - DatabaseFactory.getThreadDatabase(ConversationActivity.this) - .setDistributionType(threadId, ThreadDatabase.DistributionTypes.BROADCAST); + SignalDatabase.threads().setDistributionType(threadId, ThreadDatabase.DistributionTypes.BROADCAST); return null; } }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); @@ -1374,8 +1370,7 @@ public class ConversationActivity extends PassphraseRequiredActivity new AsyncTask() { @Override protected Void doInBackground(Void... params) { - DatabaseFactory.getThreadDatabase(ConversationActivity.this) - .setDistributionType(threadId, ThreadDatabase.DistributionTypes.CONVERSATION); + SignalDatabase.threads().setDistributionType(threadId, ThreadDatabase.DistributionTypes.CONVERSATION); return null; } }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); @@ -1692,7 +1687,7 @@ public class ConversationActivity extends PassphraseRequiredActivity @Override protected Pair doInBackground(Void... params) { Context context = ConversationActivity.this; - DraftDatabase draftDatabase = DatabaseFactory.getDraftDatabase(context); + DraftDatabase draftDatabase = SignalDatabase.drafts(); Drafts results = draftDatabase.getDrafts(threadId); Draft mentionsDraft = results.getDraftOfType(Draft.MENTION); Spannable updatedText = null; @@ -1925,8 +1920,7 @@ public class ConversationActivity extends PassphraseRequiredActivity List recipients; if (params[0].isGroup()) { - recipients = DatabaseFactory.getGroupDatabase(ConversationActivity.this) - .getGroupMembers(params[0].requireGroupId(), GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF); + recipients = SignalDatabase.groups().getGroupMembers(params[0].requireGroupId(), GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF); } else { recipients = Collections.singletonList(params[0]); } @@ -2456,7 +2450,7 @@ public class ConversationActivity extends PassphraseRequiredActivity } if (this.threadId == -1) { - SimpleTask.run(() -> DatabaseFactory.getThreadDatabase(this).getThreadIdIfExistsFor(recipient.getId()), threadId -> { + SimpleTask.run(() -> SignalDatabase.threads().getThreadIdIfExistsFor(recipient.getId()), threadId -> { if (this.threadId != threadId) { Log.d(TAG, "Thread id changed via recipient change"); this.threadId = threadId; @@ -2636,8 +2630,8 @@ public class ConversationActivity extends PassphraseRequiredActivity } } - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(ConversationActivity.this); - DraftDatabase draftDatabase = DatabaseFactory.getDraftDatabase(ConversationActivity.this); + ThreadDatabase threadDatabase = SignalDatabase.threads(); + DraftDatabase draftDatabase = SignalDatabase.drafts(); long threadId = params[0]; if (drafts.size() > 0) { @@ -2732,7 +2726,7 @@ public class ConversationActivity extends PassphraseRequiredActivity private boolean isActiveGroup() { if (!isGroupConversation()) return false; - Optional record = DatabaseFactory.getGroupDatabase(this).getGroup(getRecipient().getId()); + Optional record = SignalDatabase.groups().getGroup(getRecipient().getId()); return record.isPresent() && record.get().isActive(); } @@ -2779,7 +2773,7 @@ public class ConversationActivity extends PassphraseRequiredActivity new AsyncTask() { @Override protected Void doInBackground(Long... params) { - DatabaseFactory.getThreadDatabase(ConversationActivity.this).setLastSeen(params[0]); + SignalDatabase.threads().setLastSeen(params[0]); return null; } }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, threadId); @@ -2885,7 +2879,7 @@ public class ConversationActivity extends PassphraseRequiredActivity SimpleTask.run(() -> { long resultId = MessageSender.sendPushWithPreUploadedMedia(this, secureMessage, result.getPreUploadResults(), thread, null); - int deleted = DatabaseFactory.getAttachmentDatabase(this).deleteAbandonedPreuploadedAttachments(); + int deleted = SignalDatabase.attachments().deleteAbandonedPreuploadedAttachments(); Log.i(TAG, "Deleted " + deleted + " abandoned attachments."); return resultId; @@ -3083,7 +3077,7 @@ public class ConversationActivity extends PassphraseRequiredActivity new AsyncTask() { @Override protected Void doInBackground(Void... params) { - RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(ConversationActivity.this); + RecipientDatabase recipientDatabase = SignalDatabase.recipients(); recipientDatabase.setDefaultSubscriptionId(recipient.getId(), transportOption.getSimSubscriptionId().or(-1)); @@ -3258,7 +3252,7 @@ public class ConversationActivity extends PassphraseRequiredActivity sendSticker(new StickerLocator(stickerRecord.getPackId(), stickerRecord.getPackKey(), stickerRecord.getStickerId(), stickerRecord.getEmoji()), stickerRecord.getContentType(), stickerRecord.getUri(), stickerRecord.getSize(), clearCompose); SignalExecutors.BOUNDED.execute(() -> - DatabaseFactory.getStickerDatabase(getApplicationContext()) + SignalDatabase.stickers() .updateStickerLastUsedTime(stickerRecord.getRowId(), System.currentTimeMillis()) ); } @@ -3688,8 +3682,7 @@ public class ConversationActivity extends PassphraseRequiredActivity SimpleTask.run(() -> { //noinspection CodeBlock2Expr - return DatabaseFactory.getMmsSmsDatabase(this) - .checkMessageExists(reactionDelegate.getMessageRecord()); + return SignalDatabase.mmsSms().checkMessageExists(reactionDelegate.getMessageRecord()); }, messageExists -> { if (!messageExists) { reactionDelegate.hide(); @@ -3956,7 +3949,7 @@ public class ConversationActivity extends PassphraseRequiredActivity Context context = getApplicationContext(); - MessageRecord messageRecord = DatabaseFactory.getMmsSmsDatabase(context).getMessageFor(quoteId.getId(), quoteId.getAuthor()); + MessageRecord messageRecord = SignalDatabase.mmsSms().getMessageFor(quoteId.getId(), quoteId.getAuthor()); if (messageRecord == null) { return null; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationBannerView.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationBannerView.java index 9f01e19baa..b667c7d00b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationBannerView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationBannerView.java @@ -17,7 +17,7 @@ import org.thoughtcrime.securesms.components.AvatarImageView; import org.thoughtcrime.securesms.components.emoji.EmojiTextView; import org.thoughtcrime.securesms.contacts.avatars.FallbackContactPhoto; import org.thoughtcrime.securesms.contacts.avatars.ResourceContactPhoto; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.mms.GlideRequests; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.util.LongClickMovementMethod; @@ -70,8 +70,7 @@ public class ConversationBannerView extends ConstraintLayout { if (recipient != null && recipient.shouldBlurAvatar() && recipient.getContactPhoto() != null) { tapToView.setVisibility(VISIBLE); tapToView.setOnClickListener(v -> { - SignalExecutors.BOUNDED.execute(() -> DatabaseFactory.getRecipientDatabase(getContext().getApplicationContext()) - .manuallyShowAvatar(recipient.getId())); + SignalExecutors.BOUNDED.execute(() -> SignalDatabase.recipients().manuallyShowAvatar(recipient.getId())); }); } else { tapToView.setVisibility(GONE); diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationDataSource.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationDataSource.java index a612ab98a8..4fb285a605 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationDataSource.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationDataSource.java @@ -12,9 +12,9 @@ import org.signal.paging.PagedDataSource; import org.thoughtcrime.securesms.attachments.DatabaseAttachment; import org.thoughtcrime.securesms.conversation.ConversationData.MessageRequestData; import org.thoughtcrime.securesms.conversation.ConversationMessage.ConversationMessageFactory; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessageDatabase; import org.thoughtcrime.securesms.database.MmsSmsDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.InMemoryMessageRecord; import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord; import org.thoughtcrime.securesms.database.model.Mention; @@ -57,7 +57,7 @@ class ConversationDataSource implements PagedDataSource load(int start, int length, @NonNull CancellationSignal cancellationSignal) { Stopwatch stopwatch = new Stopwatch("load(" + start + ", " + length + "), thread " + threadId); - MmsSmsDatabase db = DatabaseFactory.getMmsSmsDatabase(context); + MmsSmsDatabase db = SignalDatabase.mmsSms(); List records = new ArrayList<>(length); MentionHelper mentionHelper = new MentionHelper(); AttachmentHelper attachmentHelper = new AttachmentHelper(); @@ -123,7 +123,7 @@ class ConversationDataSource implements PagedDataSource mentions; if (messageId.isMms()) { - mentions = DatabaseFactory.getMentionDatabase(context).getMentionsForMessage(messageId.getId()); + mentions = SignalDatabase.mentions().getMentionsForMessage(messageId.getId()); } else { mentions = Collections.emptyList(); } stopwatch.split("mentions"); - List reactions = DatabaseFactory.getReactionDatabase(context).getReactions(messageId); + List reactions = SignalDatabase.reactions().getReactions(messageId); record = ReactionHelper.recordWithReactions(record, reactions); stopwatch.split("reactions"); if (messageId.isMms()) { - List attachments = DatabaseFactory.getAttachmentDatabase(context).getAttachmentsForMessage(messageId.getId()); + List attachments = SignalDatabase.attachments().getAttachmentsForMessage(messageId.getId()); if (attachments.size() > 0) { record = ((MediaMmsMessageRecord) record).withAttachments(context, attachments); } @@ -179,7 +179,7 @@ class ConversationDataSource implements PagedDataSource getMentions(long id) { @@ -199,7 +199,7 @@ class ConversationDataSource implements PagedDataSource buildUpdatedModels(@NonNull Context context, @NonNull List records) { @@ -229,7 +229,7 @@ class ConversationDataSource implements PagedDataSource buildUpdatedModels(@NonNull Context context, @NonNull List records) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java index 03f8e30b4a..19259eb69a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java @@ -94,9 +94,9 @@ import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectFor import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragmentArgs; import org.thoughtcrime.securesms.conversation.ui.error.EnableCallNotificationSettingsDialog; import org.thoughtcrime.securesms.conversation.ui.error.SafetyNumberChangeDialog; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessageDatabase; import org.thoughtcrime.securesms.database.MmsDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.SmsDatabase; import org.thoughtcrime.securesms.database.model.InMemoryMessageRecord; import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord; @@ -439,7 +439,7 @@ public class ConversationFragment extends LoggingFragment implements Multiselect } else { lastVisibleMessageTimestamp = 0; } - SignalExecutors.BOUNDED.submit(() -> DatabaseFactory.getThreadDatabase(requireContext()).setLastScrolled(threadId, lastVisibleMessageTimestamp)); + SignalExecutors.BOUNDED.submit(() -> SignalDatabase.threads().setLastScrolled(threadId, lastVisibleMessageTimestamp)); } @Override @@ -860,9 +860,9 @@ public class ConversationFragment extends LoggingFragment implements Multiselect boolean threadDeleted; if (messageRecord.isMms()) { - threadDeleted = DatabaseFactory.getMmsDatabase(context).deleteMessage(messageRecord.getId()); + threadDeleted = SignalDatabase.mms().deleteMessage(messageRecord.getId()); } else { - threadDeleted = DatabaseFactory.getSmsDatabase(context).deleteMessage(messageRecord.getId()); + threadDeleted = SignalDatabase.sms().deleteMessage(messageRecord.getId()); } if (threadDeleted) { @@ -1076,8 +1076,7 @@ public class ConversationFragment extends LoggingFragment implements Multiselect @SuppressWarnings("CodeBlock2Expr") public void jumpToMessage(@NonNull RecipientId author, long timestamp, @Nullable Runnable onMessageNotFound) { SimpleTask.run(getLifecycle(), () -> { - return DatabaseFactory.getMmsSmsDatabase(getContext()) - .getMessagePositionInConversation(threadId, timestamp, author); + return SignalDatabase.mmsSms().getMessagePositionInConversation(threadId, timestamp, author); }, p -> moveToPosition(p + (isTypingIndicatorShowing() ? 1 : 0), onMessageNotFound)); } @@ -1142,8 +1141,7 @@ public class ConversationFragment extends LoggingFragment implements Multiselect private void scrollToNextMention() { SimpleTask.run(getViewLifecycleOwner().getLifecycle(), () -> { - MessageDatabase mmsDatabase = DatabaseFactory.getMmsDatabase(ApplicationDependencies.getApplication()); - return mmsDatabase.getOldestUnreadMentionDetails(threadId); + return SignalDatabase.mms().getOldestUnreadMentionDetails(threadId); }, (pair) -> { if (pair != null) { jumpToMessage(pair.first(), pair.second(), () -> {}); @@ -1366,10 +1364,9 @@ public class ConversationFragment extends LoggingFragment implements Multiselect } SimpleTask.run(getLifecycle(), () -> { - return DatabaseFactory.getMmsSmsDatabase(getContext()) - .getQuotedMessagePosition(threadId, - messageRecord.getQuote().getId(), - messageRecord.getQuote().getAuthor()); + return SignalDatabase.mmsSms().getQuotedMessagePosition(threadId, + messageRecord.getQuote().getId(), + messageRecord.getQuote().getAuthor()); }, p -> moveToPosition(p + (isTypingIndicatorShowing() ? 1 : 0), () -> { Toast.makeText(getContext(), R.string.ConversationFragment_quoted_message_no_longer_available, Toast.LENGTH_SHORT).show(); })); @@ -1419,7 +1416,7 @@ public class ConversationFragment extends LoggingFragment implements Multiselect .withMimeType(thumbnailSlide.getContentType()) .createForSingleSessionOnDisk(requireContext()); - DatabaseFactory.getAttachmentDatabase(requireContext()).deleteAttachmentFilesForViewOnceMessage(messageRecord.getId()); + SignalDatabase.attachments().deleteAttachmentFilesForViewOnceMessage(messageRecord.getId()); ApplicationDependencies.getViewOnceMessageManager().scheduleIfNecessary(); @@ -1435,7 +1432,7 @@ public class ConversationFragment extends LoggingFragment implements Multiselect } else { Log.w(TAG, "Failed to open view-once photo. Showing a toast and deleting the attachments for the message just in case."); Toast.makeText(requireContext(), R.string.ConversationFragment_failed_to_open_message, Toast.LENGTH_SHORT).show(); - SignalExecutors.BOUNDED.execute(() -> DatabaseFactory.getAttachmentDatabase(requireContext()).deleteAttachmentFilesForViewOnceMessage(messageRecord.getId())); + SignalExecutors.BOUNDED.execute(() -> SignalDatabase.attachments().deleteAttachmentFilesForViewOnceMessage(messageRecord.getId())); } }); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationGroupViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationGroupViewModel.java index 061c2afe30..7dd279259a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationGroupViewModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationGroupViewModel.java @@ -15,9 +15,9 @@ import androidx.lifecycle.ViewModelProvider; import com.annimon.stream.Stream; import org.signal.core.util.concurrent.SignalExecutors; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupChangeBusyException; import org.thoughtcrime.securesms.groups.GroupChangeFailedException; @@ -81,7 +81,7 @@ final class ConversationGroupViewModel extends ViewModel { void onSuggestedMembersBannerDismissed(@NonNull GroupId groupId, @NonNull List suggestions) { SignalExecutors.BOUNDED.execute(() -> { if (groupId.isV2()) { - DatabaseFactory.getGroupDatabase(ApplicationDependencies.getApplication()).removeUnmigratedV1Members(groupId.requireV2(), suggestions); + SignalDatabase.groups().removeUnmigratedV1Members(groupId.requireV2(), suggestions); liveRecipient.postValue(liveRecipient.getValue()); } }); @@ -118,7 +118,7 @@ final class ConversationGroupViewModel extends ViewModel { private static @Nullable GroupRecord getGroupRecordForRecipient(@Nullable Recipient recipient) { if (recipient != null && recipient.isGroup()) { Application context = ApplicationDependencies.getApplication(); - GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); + GroupDatabase groupDatabase = SignalDatabase.groups(); return groupDatabase.getGroup(recipient.getId()).orNull(); } else { return null; @@ -198,9 +198,9 @@ final class ConversationGroupViewModel extends ViewModel { firstTimeInviteFriendsTriggered = true; - SimpleTask.run(() -> DatabaseFactory.getGroupDatabase(ApplicationDependencies.getApplication()) - .requireGroup(groupId) - .getMembers().equals(Collections.singletonList(Recipient.self().getId())), + SimpleTask.run(() -> SignalDatabase.groups() + .requireGroup(groupId) + .getMembers().equals(Collections.singletonList(Recipient.self().getId())), justSelf -> { if (justSelf) { inviteFriends(supportFragmentManager, groupId); diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java index 7c44d671af..3b5a7bbae0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java @@ -88,8 +88,8 @@ import org.thoughtcrime.securesms.conversation.colors.Colorizer; import org.thoughtcrime.securesms.conversation.mutiselect.MultiselectCollection; import org.thoughtcrime.securesms.conversation.mutiselect.MultiselectPart; import org.thoughtcrime.securesms.database.AttachmentDatabase; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessageDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.database.model.MmsMessageRecord; @@ -2108,8 +2108,8 @@ public final class ConversationItem extends RelativeLayout implements BindableCo if (message > -1) builder.setMessage(message); builder.setPositiveButton(R.string.yes, (dialogInterface, i) -> { - MessageDatabase db = messageRecord.isMms() ? DatabaseFactory.getMmsDatabase(context) - : DatabaseFactory.getSmsDatabase(context); + MessageDatabase db = messageRecord.isMms() ? SignalDatabase.mms() + : SignalDatabase.sms(); db.markAsInsecure(messageRecord.getId()); db.markAsOutbox(messageRecord.getId()); @@ -2127,9 +2127,9 @@ public final class ConversationItem extends RelativeLayout implements BindableCo builder.setNegativeButton(R.string.no, (dialogInterface, i) -> { if (messageRecord.isMms()) { - DatabaseFactory.getMmsDatabase(context).markAsSentFailed(messageRecord.getId()); + SignalDatabase.mms().markAsSentFailed(messageRecord.getId()); } else { - DatabaseFactory.getSmsDatabase(context).markAsSentFailed(messageRecord.getId()); + SignalDatabase.sms().markAsSentFailed(messageRecord.getId()); } }); builder.show(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationMessage.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationMessage.java index 52c9723c84..e8b31014fa 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationMessage.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationMessage.java @@ -12,8 +12,8 @@ import org.signal.core.util.Conversions; import org.thoughtcrime.securesms.components.mention.MentionAnnotation; import org.thoughtcrime.securesms.conversation.mutiselect.Multiselect; import org.thoughtcrime.securesms.conversation.mutiselect.MultiselectCollection; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MentionUtil; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.Mention; import org.thoughtcrime.securesms.database.model.MessageRecord; @@ -149,7 +149,7 @@ public class ConversationMessage { @WorkerThread public static @NonNull ConversationMessage createWithUnresolvedData(@NonNull Context context, @NonNull MessageRecord messageRecord, @NonNull CharSequence body) { if (messageRecord.isMms()) { - List mentions = DatabaseFactory.getMentionDatabase(context).getMentionsForMessage(messageRecord.getId()); + List mentions = SignalDatabase.mentions().getMentionsForMessage(messageRecord.getId()); if (!mentions.isEmpty()) { MentionUtil.UpdatedBodyAndMentions updated = MentionUtil.updateBodyAndMentionsWithDisplayNames(context, body, mentions); return new ConversationMessage(messageRecord, updated.getBody(), updated.getMentions()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationRepository.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationRepository.java index 819ac353ed..a16e50e83d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationRepository.java @@ -9,8 +9,8 @@ import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import org.signal.core.util.concurrent.SignalExecutors; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.keyvalue.SignalStore; @@ -46,7 +46,7 @@ class ConversationRepository { @WorkerThread boolean canShowAsBubble(long threadId) { if (Build.VERSION.SDK_INT >= ConversationUtil.CONVERSATION_SUPPORT_VERSION) { - Recipient recipient = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(threadId); + Recipient recipient = SignalDatabase.threads().getRecipientForThreadId(threadId); return recipient != null && BubbleUtil.canBubble(context, recipient.getId(), threadId); } else { @@ -55,8 +55,8 @@ class ConversationRepository { } private @NonNull ConversationData getConversationDataInternal(long threadId, @NonNull Recipient conversationRecipient, int jumpToPosition) { - ThreadDatabase.ConversationMetadata metadata = DatabaseFactory.getThreadDatabase(context).getConversationMetadata(threadId); - int threadSize = DatabaseFactory.getMmsSmsDatabase(context).getConversationCount(threadId); + ThreadDatabase.ConversationMetadata metadata = SignalDatabase.threads().getConversationMetadata(threadId); + int threadSize = SignalDatabase.mmsSms().getConversationCount(threadId); long lastSeen = metadata.getLastSeen(); boolean hasSent = metadata.hasSent(); int lastSeenPosition = 0; @@ -67,7 +67,7 @@ class ConversationRepository { boolean showUniversalExpireTimerUpdate = false; if (lastSeen > 0) { - lastSeenPosition = DatabaseFactory.getMmsSmsDatabase(context).getMessagePositionOnOrAfterTimestamp(threadId, lastSeen); + lastSeenPosition = SignalDatabase.mmsSms().getMessagePositionOnOrAfterTimestamp(threadId, lastSeen); } if (lastSeenPosition <= 0) { @@ -75,14 +75,14 @@ class ConversationRepository { } if (lastSeen == 0 && lastScrolled > 0) { - lastScrolledPosition = DatabaseFactory.getMmsSmsDatabase(context).getMessagePositionOnOrAfterTimestamp(threadId, lastScrolled); + lastScrolledPosition = SignalDatabase.mmsSms().getMessagePositionOnOrAfterTimestamp(threadId, lastScrolled); } if (!isMessageRequestAccepted) { boolean isGroup = false; boolean recipientIsKnownOrHasGroupsInCommon = false; if (conversationRecipient.isGroup()) { - Optional group = DatabaseFactory.getGroupDatabase(context).getGroup(conversationRecipient.getId()); + Optional group = SignalDatabase.groups().getGroup(conversationRecipient.getId()); if (group.isPresent()) { List recipients = Recipient.resolvedList(group.get().getMembers()); for (Recipient recipient : recipients) { @@ -103,7 +103,7 @@ class ConversationRepository { conversationRecipient.getExpiresInSeconds() == 0 && !conversationRecipient.isGroup() && conversationRecipient.isRegistered() && - (threadId == -1 || !DatabaseFactory.getMmsSmsDatabase(context).hasMeaningfulMessage(threadId))) + (threadId == -1 || !SignalDatabase.mmsSms().hasMeaningfulMessage(threadId))) { showUniversalExpireTimerUpdate = true; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/MarkReadHelper.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/MarkReadHelper.java index 49b6b76e91..2b8fb6b4d1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/MarkReadHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/MarkReadHelper.java @@ -8,8 +8,8 @@ import androidx.lifecycle.LifecycleOwner; import org.signal.core.util.concurrent.SignalExecutors; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessageDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.notifications.MarkReadReceiver; @@ -46,7 +46,7 @@ class MarkReadHelper { debouncer.publish(() -> { EXECUTOR.execute(() -> { - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); + ThreadDatabase threadDatabase = SignalDatabase.threads(); List infos = threadDatabase.setReadSince(threadId, false, timestamp); Log.d(TAG, "Marking " + infos.size() + " messages as read."); diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/MessageCountsViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/MessageCountsViewModel.java index 0c95be112e..b02b1969e1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/MessageCountsViewModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/MessageCountsViewModel.java @@ -10,8 +10,8 @@ import androidx.lifecycle.Transformations; import androidx.lifecycle.ViewModel; import org.signal.core.util.concurrent.SignalExecutors; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.DatabaseObserver; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.ThreadRecord; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.util.concurrent.SerialMonoLifoExecutor; @@ -80,12 +80,12 @@ public class MessageCountsViewModel extends ViewModel { } private int getUnreadCount(@NonNull Context context, long threadId) { - ThreadRecord threadRecord = DatabaseFactory.getThreadDatabase(context).getThreadRecord(threadId); + ThreadRecord threadRecord = SignalDatabase.threads().getThreadRecord(threadId); return threadRecord != null ? threadRecord.getUnreadCount() : 0; } private int getUnreadMentionsCount(@NonNull Context context, long threadId) { - return DatabaseFactory.getMmsDatabase(context).getUnreadMentionCount(threadId); + return SignalDatabase.mms().getUnreadMentionCount(threadId); } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ShowAdminsBottomSheetDialog.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ShowAdminsBottomSheetDialog.java index f1b464a34b..b7674943f8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ShowAdminsBottomSheetDialog.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ShowAdminsBottomSheetDialog.java @@ -15,8 +15,8 @@ import androidx.fragment.app.FragmentManager; import com.google.android.material.bottomsheet.BottomSheetDialogFragment; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.groups.ParcelableGroupId; import org.thoughtcrime.securesms.groups.ui.GroupMemberListView; @@ -93,9 +93,9 @@ public final class ShowAdminsBottomSheetDialog extends BottomSheetDialogFragment @WorkerThread private static @NonNull List getAdmins(@NonNull Context context, @NonNull GroupId groupId) { - return DatabaseFactory.getGroupDatabase(context) - .getGroup(groupId) - .transform(GroupDatabase.GroupRecord::getAdmins) - .or(Collections.emptyList()); + return SignalDatabase.groups() + .getGroup(groupId) + .transform(GroupDatabase.GroupRecord::getAdmins) + .or(Collections.emptyList()); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/colors/ui/ChatColorSelectionRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/colors/ui/ChatColorSelectionRepository.kt index b2f20ab7dd..6c0864462e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/colors/ui/ChatColorSelectionRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/colors/ui/ChatColorSelectionRepository.kt @@ -4,7 +4,7 @@ import android.content.Context import org.signal.core.util.concurrent.SignalExecutors import org.thoughtcrime.securesms.conversation.colors.ChatColors import org.thoughtcrime.securesms.conversation.colors.ChatColorsPalette -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.RecipientId @@ -21,19 +21,19 @@ sealed class ChatColorSelectionRepository(context: Context) { fun duplicate(chatColors: ChatColors) { SignalExecutors.BOUNDED.execute { val duplicate = chatColors.withId(ChatColors.Id.NotSet) - DatabaseFactory.getChatColorsDatabase(context).saveChatColors(duplicate) + SignalDatabase.chatColors.saveChatColors(duplicate) } } fun getUsageCount(chatColorsId: ChatColors.Id, consumer: (Int) -> Unit) { SignalExecutors.BOUNDED.execute { - consumer(DatabaseFactory.getRecipientDatabase(context).getColorUsageCount(chatColorsId)) + consumer(SignalDatabase.recipients.getColorUsageCount(chatColorsId)) } } fun delete(chatColors: ChatColors, onDeleted: () -> Unit) { SignalExecutors.BOUNDED.execute { - DatabaseFactory.getChatColorsDatabase(context).deleteChatColors(chatColors) + SignalDatabase.chatColors.deleteChatColors(chatColors) onDeleted() } } @@ -84,7 +84,7 @@ sealed class ChatColorSelectionRepository(context: Context) { override fun save(chatColors: ChatColors, onSaved: () -> Unit) { SignalExecutors.BOUNDED.execute { - val recipientDatabase = DatabaseFactory.getRecipientDatabase(context) + val recipientDatabase = SignalDatabase.recipients recipientDatabase.setColor(recipientId, chatColors) onSaved() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/colors/ui/ChatColorsOptionsLiveData.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/colors/ui/ChatColorsOptionsLiveData.kt index e314faa10f..8ac4434281 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/colors/ui/ChatColorsOptionsLiveData.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/colors/ui/ChatColorsOptionsLiveData.kt @@ -5,14 +5,14 @@ import org.signal.core.util.concurrent.SignalExecutors import org.thoughtcrime.securesms.conversation.colors.ChatColors import org.thoughtcrime.securesms.conversation.colors.ChatColorsPalette import org.thoughtcrime.securesms.database.ChatColorsDatabase -import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.DatabaseObserver +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.dependencies.ApplicationDependencies import org.thoughtcrime.securesms.util.concurrent.SerialMonoLifoExecutor import java.util.concurrent.Executor class ChatColorsOptionsLiveData : LiveData>() { - private val chatColorsDatabase: ChatColorsDatabase = DatabaseFactory.getChatColorsDatabase(ApplicationDependencies.getApplication()) + private val chatColorsDatabase: ChatColorsDatabase = SignalDatabase.chatColors private val observer: DatabaseObserver.Observer = DatabaseObserver.Observer { refreshChatColors() } private val executor: Executor = SerialMonoLifoExecutor(SignalExecutors.BOUNDED) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/colors/ui/custom/CustomChatColorCreatorRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/colors/ui/custom/CustomChatColorCreatorRepository.kt index e54b8a4aff..9932932acd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/colors/ui/custom/CustomChatColorCreatorRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/colors/ui/custom/CustomChatColorCreatorRepository.kt @@ -3,7 +3,7 @@ package org.thoughtcrime.securesms.conversation.colors.ui.custom import android.content.Context import org.signal.core.util.concurrent.SignalExecutors import org.thoughtcrime.securesms.conversation.colors.ChatColors -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.RecipientId @@ -12,9 +12,7 @@ import org.thoughtcrime.securesms.wallpaper.ChatWallpaper class CustomChatColorCreatorRepository(private val context: Context) { fun loadColors(chatColorsId: ChatColors.Id, consumer: (ChatColors) -> Unit) { SignalExecutors.BOUNDED.execute { - val chatColorsDatabase = DatabaseFactory.getChatColorsDatabase(context) - val chatColors = chatColorsDatabase.getById(chatColorsId) - + val chatColors = SignalDatabase.chatColors.getById(chatColorsId) consumer(chatColors) } } @@ -32,16 +30,14 @@ class CustomChatColorCreatorRepository(private val context: Context) { fun setChatColors(chatColors: ChatColors, consumer: (ChatColors) -> Unit) { SignalExecutors.BOUNDED.execute { - val chatColorsDatabase = DatabaseFactory.getChatColorsDatabase(context) - val savedColors = chatColorsDatabase.saveChatColors(chatColors) - + val savedColors = SignalDatabase.chatColors.saveChatColors(chatColors) consumer(savedColors) } } fun getUsageCount(chatColorsId: ChatColors.Id, consumer: (Int) -> Unit) { SignalExecutors.BOUNDED.execute { - val recipientsDatabase = DatabaseFactory.getRecipientDatabase(context) + val recipientsDatabase = SignalDatabase.recipients consumer(recipientsDatabase.getColorUsageCount(chatColorsId)) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/mutiselect/forward/MultiselectForwardRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/mutiselect/forward/MultiselectForwardRepository.kt index 9d26f7cb52..571b71ca98 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/mutiselect/forward/MultiselectForwardRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/mutiselect/forward/MultiselectForwardRepository.kt @@ -4,7 +4,7 @@ import android.content.Context import androidx.core.util.Consumer import io.reactivex.rxjava3.core.Single import org.signal.core.util.concurrent.SignalExecutors -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.database.ThreadDatabase import org.thoughtcrime.securesms.database.identity.IdentityRecordList import org.thoughtcrime.securesms.database.model.IdentityRecord @@ -44,7 +44,7 @@ class MultiselectForwardRepository(context: Context) { return Single.fromCallable { val recipient = Recipient.resolved(recipientId.get()) if (recipient.isPushV2Group) { - val record = DatabaseFactory.getGroupDatabase(context).getGroup(recipient.requireGroupId()) + val record = SignalDatabase.groups.getGroup(recipient.requireGroupId()) !(record.isPresent && record.get().isAnnouncementGroup && !record.get().isAdmin(Recipient.self())) } else { true @@ -59,7 +59,7 @@ class MultiselectForwardRepository(context: Context) { resultHandlers: MultiselectForwardResultHandlers ) { SignalExecutors.BOUNDED.execute { - val threadDatabase: ThreadDatabase = DatabaseFactory.getThreadDatabase(context) + val threadDatabase: ThreadDatabase = SignalDatabase.threads val sharedContactsAndThreads: Set = shareContacts .asSequence() diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ui/error/SafetyNumberChangeRepository.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ui/error/SafetyNumberChangeRepository.java index 7fdf2eb9cb..4be9b25c46 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ui/error/SafetyNumberChangeRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ui/error/SafetyNumberChangeRepository.java @@ -15,8 +15,8 @@ import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.crypto.SessionUtil; import org.thoughtcrime.securesms.crypto.ReentrantSessionLock; import org.thoughtcrime.securesms.crypto.storage.TextSecureIdentityKeyStore; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.IdentityDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.IdentityRecord; import org.thoughtcrime.securesms.database.MessageDatabase; import org.thoughtcrime.securesms.database.MmsSmsDatabase; @@ -82,9 +82,9 @@ final class SafetyNumberChangeRepository { try { switch (messageType) { case MmsSmsDatabase.SMS_TRANSPORT: - return DatabaseFactory.getSmsDatabase(context).getMessageRecord(messageId); + return SignalDatabase.sms().getMessageRecord(messageId); case MmsSmsDatabase.MMS_TRANSPORT: - return DatabaseFactory.getMmsDatabase(context).getMessageRecord(messageId); + return SignalDatabase.mms().getMessageRecord(messageId); default: throw new AssertionError("no valid message type specified"); } @@ -136,7 +136,7 @@ final class SafetyNumberChangeRepository { Log.i(TAG, "Archiving sessions explicitly as they appear to be out of sync."); SessionUtil.archiveSession(changedRecipient.getRecipient().getId(), SignalServiceAddress.DEFAULT_DEVICE_ID); SessionUtil.archiveSiblingSessions(mismatchAddress); - DatabaseFactory.getSenderKeySharedDatabase(context).deleteAllFor(changedRecipient.getRecipient().getId()); + SignalDatabase.senderKeyShared().deleteAllFor(changedRecipient.getRecipient().getId()); } } } @@ -151,8 +151,8 @@ final class SafetyNumberChangeRepository { @WorkerThread private void processOutgoingMessageRecord(@NonNull List changedRecipients, @NonNull MessageRecord messageRecord) { Log.d(TAG, "processOutgoingMessageRecord"); - MessageDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context); - MessageDatabase mmsDatabase = DatabaseFactory.getMmsDatabase(context); + MessageDatabase smsDatabase = SignalDatabase.sms(); + MessageDatabase mmsDatabase = SignalDatabase.mms(); for (ChangedRecipient changedRecipient : changedRecipients) { RecipientId id = changedRecipient.getRecipient().getId(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ui/mentions/MentionsPickerRepository.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ui/mentions/MentionsPickerRepository.java index 4d8adad1e9..2f0aa32671 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ui/mentions/MentionsPickerRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ui/mentions/MentionsPickerRepository.java @@ -8,9 +8,9 @@ import androidx.annotation.WorkerThread; import com.annimon.stream.Stream; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; @@ -23,8 +23,8 @@ final class MentionsPickerRepository { private final GroupDatabase groupDatabase; MentionsPickerRepository(@NonNull Context context) { - recipientDatabase = DatabaseFactory.getRecipientDatabase(context); - groupDatabase = DatabaseFactory.getGroupDatabase(context); + recipientDatabase = SignalDatabase.recipients(); + groupDatabase = SignalDatabase.groups(); } @WorkerThread diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListArchiveFragment.java b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListArchiveFragment.java index 8a84638011..2b8f7f17ec 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListArchiveFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListArchiveFragment.java @@ -36,7 +36,7 @@ import com.google.android.material.snackbar.Snackbar; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.components.registration.PulsingFloatingActionButton; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.util.task.SnackbarAsyncTask; import org.thoughtcrime.securesms.util.views.Stub; @@ -112,13 +112,13 @@ public class ConversationListArchiveFragment extends ConversationListFragment im @Override @WorkerThread protected void archiveThreads(Set threadIds) { - DatabaseFactory.getThreadDatabase(getActivity()).setArchived(threadIds, false); + SignalDatabase.threads().setArchived(threadIds, false); } @Override @WorkerThread protected void reverseArchiveThreads(Set threadIds) { - DatabaseFactory.getThreadDatabase(getActivity()).setArchived(threadIds, true); + SignalDatabase.threads().setArchived(threadIds, true); } @SuppressLint("StaticFieldLeak") @@ -137,12 +137,12 @@ public class ConversationListArchiveFragment extends ConversationListFragment im { @Override protected void executeAction(@Nullable Long parameter) { - DatabaseFactory.getThreadDatabase(getActivity()).unarchiveConversation(threadId); + SignalDatabase.threads().unarchiveConversation(threadId); } @Override protected void reverseAction(@Nullable Long parameter) { - DatabaseFactory.getThreadDatabase(getActivity()).archiveConversation(threadId); + SignalDatabase.threads().archiveConversation(threadId); } }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, threadId); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListDataSource.java b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListDataSource.java index d93f241348..cc832f0c33 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListDataSource.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListDataSource.java @@ -13,7 +13,7 @@ import org.signal.core.util.logging.Log; import org.signal.paging.PagedDataSource; import org.thoughtcrime.securesms.conversationlist.model.Conversation; import org.thoughtcrime.securesms.conversationlist.model.ConversationReader; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.database.model.ThreadRecord; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; @@ -31,7 +31,7 @@ abstract class ConversationListDataSource implements PagedDataSource { - return DatabaseFactory.getThreadDatabase(getContext()).getThreadIdIfExistsFor(contact.getId()); + return SignalDatabase.threads().getThreadIdIfExistsFor(contact.getId()); }, threadId -> { hideKeyboard(); getNavigator().goToConversation(contact.getId(), @@ -460,7 +460,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode @Override public void onMessageClicked(@NonNull MessageResult message) { SimpleTask.run(getViewLifecycleOwner().getLifecycle(), () -> { - int startingPosition = DatabaseFactory.getMmsSmsDatabase(getContext()).getMessagePositionInConversation(message.getThreadId(), message.getReceivedTimestampMs()); + int startingPosition = SignalDatabase.mmsSms().getMessagePositionInConversation(message.getThreadId(), message.getReceivedTimestampMs()); return Math.max(0, startingPosition); }, startingPosition -> { hideKeyboard(); @@ -798,7 +798,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode Context context = requireContext(); SignalExecutors.BOUNDED.execute(() -> { - List messageIds = DatabaseFactory.getThreadDatabase(context).setAllThreadsRead(); + List messageIds = SignalDatabase.threads().setAllThreadsRead(); ApplicationDependencies.getMessageNotifier().updateNotification(context); MarkReadReceiver.process(context, messageIds); @@ -809,7 +809,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode Context context = requireContext(); SimpleTask.run(getViewLifecycleOwner().getLifecycle(), () -> { - List messageIds = DatabaseFactory.getThreadDatabase(context).setRead(ids, false); + List messageIds = SignalDatabase.threads().setRead(ids, false); ApplicationDependencies.getMessageNotifier().updateNotification(context); MarkReadReceiver.process(context, messageIds); @@ -824,7 +824,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode Context context = requireContext(); SimpleTask.run(getViewLifecycleOwner().getLifecycle(), () -> { - DatabaseFactory.getThreadDatabase(context).setForcedUnread(ids); + SignalDatabase.threads().setForcedUnread(ids); StorageSyncHelper.scheduleSyncForDataChange(); return null; }, none -> { @@ -902,7 +902,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode @Override protected Void doInBackground(Void... params) { - DatabaseFactory.getThreadDatabase(getActivity()).deleteConversations(selectedConversations); + SignalDatabase.threads().deleteConversations(selectedConversations); ApplicationDependencies.getMessageNotifier().updateNotification(requireActivity()); return null; } @@ -937,7 +937,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode } SimpleTask.run(SignalExecutors.BOUNDED, () -> { - ThreadDatabase db = DatabaseFactory.getThreadDatabase(ApplicationDependencies.getApplication()); + ThreadDatabase db = SignalDatabase.threads(); db.pinConversations(toPin); @@ -949,7 +949,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode private void handleUnpin(@NonNull Collection ids) { SimpleTask.run(SignalExecutors.BOUNDED, () -> { - ThreadDatabase db = DatabaseFactory.getThreadDatabase(ApplicationDependencies.getApplication()); + ThreadDatabase db = SignalDatabase.threads(); db.unpinConversations(ids); @@ -978,7 +978,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode .filter(r -> r.getMuteUntil() != until) .map(Recipient::getId) .collect(Collectors.toList()); - DatabaseFactory.getRecipientDatabase(requireContext()).setMuted(recipientIds, until); + SignalDatabase.recipients().setMuted(recipientIds, until); return null; }, unused -> { endActionModeIfActive(); @@ -1264,12 +1264,12 @@ public class ConversationListFragment extends MainFragment implements ActionMode @WorkerThread protected void archiveThreads(Set threadIds) { - DatabaseFactory.getThreadDatabase(getActivity()).setArchived(threadIds, true); + SignalDatabase.threads().setArchived(threadIds, true); } @WorkerThread protected void reverseArchiveThreads(Set threadIds) { - DatabaseFactory.getThreadDatabase(getActivity()).setArchived(threadIds, false); + SignalDatabase.threads().setArchived(threadIds, false); } @SuppressLint("StaticFieldLeak") @@ -1285,7 +1285,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode Snackbar.LENGTH_LONG, false) { - private final ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(getActivity()); + private final ThreadDatabase threadDatabase = SignalDatabase.threads(); private List pinnedThreadIds; diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListViewModel.java index 6de35eed46..6607976c3c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListViewModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListViewModel.java @@ -17,8 +17,8 @@ import org.signal.paging.PagingController; import org.thoughtcrime.securesms.conversationlist.model.Conversation; import org.thoughtcrime.securesms.conversationlist.model.UnreadPayments; import org.thoughtcrime.securesms.conversationlist.model.UnreadPaymentsLiveData; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.DatabaseObserver; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.megaphone.Megaphone; import org.thoughtcrime.securesms.megaphone.MegaphoneRepository; @@ -88,12 +88,12 @@ class ConversationListViewModel extends ViewModel { }; this.hasNoConversations = LiveDataUtil.mapAsync(pagedData.getData(), conversations -> { - pinnedCount = DatabaseFactory.getThreadDatabase(application).getPinnedConversationListCount(); + pinnedCount = SignalDatabase.threads().getPinnedConversationListCount(); if (conversations.size() > 0) { return false; } else { - return DatabaseFactory.getThreadDatabase(application).getArchivedConversationListCount() == 0; + return SignalDatabase.threads().getArchivedConversationListCount() == 0; } }); diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/model/UnreadPaymentsLiveData.java b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/model/UnreadPaymentsLiveData.java index 1e4bb9dd2f..cab89f491d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/model/UnreadPaymentsLiveData.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/model/UnreadPaymentsLiveData.java @@ -5,9 +5,9 @@ import androidx.annotation.WorkerThread; import androidx.lifecycle.LiveData; import org.signal.core.util.concurrent.SignalExecutors; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.DatabaseObserver; import org.thoughtcrime.securesms.database.PaymentDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.util.concurrent.SerialMonoLifoExecutor; @@ -28,7 +28,7 @@ public final class UnreadPaymentsLiveData extends LiveData { - DatabaseFactory.getInstance(context).getRawDatabase().setTransactionSuccessful(); - DatabaseFactory.getInstance(context).getRawDatabase().endTransaction(); + SignalDatabase.getRawDatabase().setTransactionSuccessful(); + SignalDatabase.getRawDatabase().endTransaction(); }; } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalSenderKeyStore.java b/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalSenderKeyStore.java index 8eb79e554d..2f82d4c680 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalSenderKeyStore.java +++ b/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalSenderKeyStore.java @@ -4,7 +4,7 @@ import android.content.Context; import androidx.annotation.NonNull; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.whispersystems.signalservice.api.SignalServiceSenderKeyStore; import org.whispersystems.signalservice.api.push.DistributionId; import org.thoughtcrime.securesms.recipients.RecipientId; @@ -34,35 +34,35 @@ public final class SignalSenderKeyStore implements SignalServiceSenderKeyStore { @Override public void storeSenderKey(@NonNull SignalProtocolAddress sender, @NonNull UUID distributionId, @NonNull SenderKeyRecord record) { synchronized (LOCK) { - DatabaseFactory.getSenderKeyDatabase(context).store(sender, DistributionId.from(distributionId), record); + SignalDatabase.senderKeys().store(sender, DistributionId.from(distributionId), record); } } @Override public @Nullable SenderKeyRecord loadSenderKey(@NonNull SignalProtocolAddress sender, @NonNull UUID distributionId) { synchronized (LOCK) { - return DatabaseFactory.getSenderKeyDatabase(context).load(sender, DistributionId.from(distributionId)); + return SignalDatabase.senderKeys().load(sender, DistributionId.from(distributionId)); } } @Override public Set getSenderKeySharedWith(DistributionId distributionId) { synchronized (LOCK) { - return DatabaseFactory.getSenderKeySharedDatabase(context).getSharedWith(distributionId); + return SignalDatabase.senderKeyShared().getSharedWith(distributionId); } } @Override public void markSenderKeySharedWith(DistributionId distributionId, Collection addresses) { synchronized (LOCK) { - DatabaseFactory.getSenderKeySharedDatabase(context).markAsShared(distributionId, addresses); + SignalDatabase.senderKeyShared().markAsShared(distributionId, addresses); } } @Override public void clearSenderKeySharedWith(Collection addresses) { synchronized (LOCK) { - DatabaseFactory.getSenderKeySharedDatabase(context).deleteAllFor(addresses); + SignalDatabase.senderKeyShared().deleteAllFor(addresses); } } @@ -71,7 +71,7 @@ public final class SignalSenderKeyStore implements SignalServiceSenderKeyStore { */ public void deleteAllFor(@NonNull String addressName, @NonNull DistributionId distributionId) { synchronized (LOCK) { - DatabaseFactory.getSenderKeyDatabase(context).deleteAllFor(addressName, distributionId); + SignalDatabase.senderKeys().deleteAllFor(addressName, distributionId); } } @@ -80,7 +80,7 @@ public final class SignalSenderKeyStore implements SignalServiceSenderKeyStore { */ public void deleteAll() { synchronized (LOCK) { - DatabaseFactory.getSenderKeyDatabase(context).deleteAll(); + SignalDatabase.senderKeys().deleteAll(); } } } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/TextSecureIdentityKeyStore.java b/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/TextSecureIdentityKeyStore.java index 8d61c58a5e..3147dd0fc9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/TextSecureIdentityKeyStore.java +++ b/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/TextSecureIdentityKeyStore.java @@ -8,9 +8,9 @@ import androidx.annotation.Nullable; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.crypto.IdentityKeyUtil; import org.thoughtcrime.securesms.crypto.SessionUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.IdentityDatabase; import org.thoughtcrime.securesms.database.IdentityDatabase.VerifiedStatus; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.identity.IdentityRecordList; import org.thoughtcrime.securesms.database.model.IdentityRecord; import org.thoughtcrime.securesms.database.model.IdentityStoreRecord; @@ -43,7 +43,7 @@ public class TextSecureIdentityKeyStore implements IdentityKeyStore { private final Cache cache; public TextSecureIdentityKeyStore(Context context) { - this(context, DatabaseFactory.getIdentityDatabase(context)); + this(context, SignalDatabase.identities()); } TextSecureIdentityKeyStore(@NonNull Context context, @NonNull IdentityDatabase identityDatabase) { @@ -92,7 +92,7 @@ public class TextSecureIdentityKeyStore implements IdentityKeyStore { cache.save(address.getName(), recipientId, identityKey, verifiedStatus, false, System.currentTimeMillis(), nonBlockingApproval); IdentityUtil.markIdentityUpdate(context, recipientId); SessionUtil.archiveSiblingSessions(address); - DatabaseFactory.getSenderKeySharedDatabase(context).deleteAllFor(recipientId); + SignalDatabase.senderKeyShared().deleteAllFor(recipientId); return SaveResult.UPDATE; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/TextSecurePreKeyStore.java b/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/TextSecurePreKeyStore.java index b184f23816..ecbe2fe11b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/TextSecurePreKeyStore.java +++ b/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/TextSecurePreKeyStore.java @@ -5,7 +5,7 @@ import android.content.Context; import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.whispersystems.libsignal.InvalidKeyIdException; import org.whispersystems.libsignal.state.PreKeyRecord; import org.whispersystems.libsignal.state.PreKeyStore; @@ -31,7 +31,7 @@ public class TextSecurePreKeyStore implements PreKeyStore, SignedPreKeyStore { @Override public PreKeyRecord loadPreKey(int preKeyId) throws InvalidKeyIdException { synchronized (LOCK) { - PreKeyRecord preKeyRecord = DatabaseFactory.getPreKeyDatabase(context).getPreKey(preKeyId); + PreKeyRecord preKeyRecord = SignalDatabase.preKeys().getPreKey(preKeyId); if (preKeyRecord == null) throw new InvalidKeyIdException("No such key: " + preKeyId); else return preKeyRecord; @@ -41,7 +41,7 @@ public class TextSecurePreKeyStore implements PreKeyStore, SignedPreKeyStore { @Override public SignedPreKeyRecord loadSignedPreKey(int signedPreKeyId) throws InvalidKeyIdException { synchronized (LOCK) { - SignedPreKeyRecord signedPreKeyRecord = DatabaseFactory.getSignedPreKeyDatabase(context).getSignedPreKey(signedPreKeyId); + SignedPreKeyRecord signedPreKeyRecord = SignalDatabase.signedPreKeys().getSignedPreKey(signedPreKeyId); if (signedPreKeyRecord == null) throw new InvalidKeyIdException("No such signed prekey: " + signedPreKeyId); else return signedPreKeyRecord; @@ -51,41 +51,41 @@ public class TextSecurePreKeyStore implements PreKeyStore, SignedPreKeyStore { @Override public List loadSignedPreKeys() { synchronized (LOCK) { - return DatabaseFactory.getSignedPreKeyDatabase(context).getAllSignedPreKeys(); + return SignalDatabase.signedPreKeys().getAllSignedPreKeys(); } } @Override public void storePreKey(int preKeyId, PreKeyRecord record) { synchronized (LOCK) { - DatabaseFactory.getPreKeyDatabase(context).insertPreKey(preKeyId, record); + SignalDatabase.preKeys().insertPreKey(preKeyId, record); } } @Override public void storeSignedPreKey(int signedPreKeyId, SignedPreKeyRecord record) { synchronized (LOCK) { - DatabaseFactory.getSignedPreKeyDatabase(context).insertSignedPreKey(signedPreKeyId, record); + SignalDatabase.signedPreKeys().insertSignedPreKey(signedPreKeyId, record); } } @Override public boolean containsPreKey(int preKeyId) { - return DatabaseFactory.getPreKeyDatabase(context).getPreKey(preKeyId) != null; + return SignalDatabase.preKeys().getPreKey(preKeyId) != null; } @Override public boolean containsSignedPreKey(int signedPreKeyId) { - return DatabaseFactory.getSignedPreKeyDatabase(context).getSignedPreKey(signedPreKeyId) != null; + return SignalDatabase.signedPreKeys().getSignedPreKey(signedPreKeyId) != null; } @Override public void removePreKey(int preKeyId) { - DatabaseFactory.getPreKeyDatabase(context).removePreKey(preKeyId); + SignalDatabase.preKeys().removePreKey(preKeyId); } @Override public void removeSignedPreKey(int signedPreKeyId) { - DatabaseFactory.getSignedPreKeyDatabase(context).removeSignedPreKey(signedPreKeyId); + SignalDatabase.signedPreKeys().removeSignedPreKey(signedPreKeyId); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/TextSecureSessionStore.java b/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/TextSecureSessionStore.java index 2c265513d5..ad1e1ab805 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/TextSecureSessionStore.java +++ b/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/TextSecureSessionStore.java @@ -6,8 +6,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.SessionDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.whispersystems.libsignal.NoSessionException; @@ -36,7 +36,7 @@ public class TextSecureSessionStore implements SignalServiceSessionStore { @Override public SessionRecord loadSession(@NonNull SignalProtocolAddress address) { synchronized (LOCK) { - SessionRecord sessionRecord = DatabaseFactory.getSessionDatabase(context).load(address); + SessionRecord sessionRecord = SignalDatabase.sessions().load(address); if (sessionRecord == null) { Log.w(TAG, "No existing session information found for " + address); @@ -50,7 +50,7 @@ public class TextSecureSessionStore implements SignalServiceSessionStore { @Override public List loadExistingSessions(List addresses) throws NoSessionException { synchronized (LOCK) { - List sessionRecords = DatabaseFactory.getSessionDatabase(context).load(addresses); + List sessionRecords = SignalDatabase.sessions().load(addresses); if (sessionRecords.size() != addresses.size()) { String message = "Mismatch! Asked for " + addresses.size() + " sessions, but only found " + sessionRecords.size() + "!"; @@ -69,14 +69,14 @@ public class TextSecureSessionStore implements SignalServiceSessionStore { @Override public void storeSession(@NonNull SignalProtocolAddress address, @NonNull SessionRecord record) { synchronized (LOCK) { - DatabaseFactory.getSessionDatabase(context).store(address, record); + SignalDatabase.sessions().store(address, record); } } @Override public boolean containsSession(SignalProtocolAddress address) { synchronized (LOCK) { - SessionRecord sessionRecord = DatabaseFactory.getSessionDatabase(context).load(address); + SessionRecord sessionRecord = SignalDatabase.sessions().load(address); return sessionRecord != null && sessionRecord.hasSenderChain() && @@ -88,7 +88,7 @@ public class TextSecureSessionStore implements SignalServiceSessionStore { public void deleteSession(SignalProtocolAddress address) { synchronized (LOCK) { Log.w(TAG, "Deleting session for " + address); - DatabaseFactory.getSessionDatabase(context).delete(address); + SignalDatabase.sessions().delete(address); } } @@ -96,36 +96,36 @@ public class TextSecureSessionStore implements SignalServiceSessionStore { public void deleteAllSessions(String name) { synchronized (LOCK) { Log.w(TAG, "Deleting all sessions for " + name); - DatabaseFactory.getSessionDatabase(context).deleteAllFor(name); + SignalDatabase.sessions().deleteAllFor(name); } } @Override public List getSubDeviceSessions(String name) { synchronized (LOCK) { - return DatabaseFactory.getSessionDatabase(context).getSubDevices(name); + return SignalDatabase.sessions().getSubDevices(name); } } @Override public Set getAllAddressesWithActiveSessions(List addressNames) { synchronized (LOCK) { - return DatabaseFactory.getSessionDatabase(context) - .getAllFor(addressNames) - .stream() - .filter(row -> isActive(row.getRecord())) - .map(row -> new SignalProtocolAddress(row.getAddress(), row.getDeviceId())) - .collect(Collectors.toSet()); + return SignalDatabase.sessions() + .getAllFor(addressNames) + .stream() + .filter(row -> isActive(row.getRecord())) + .map(row -> new SignalProtocolAddress(row.getAddress(), row.getDeviceId())) + .collect(Collectors.toSet()); } } @Override public void archiveSession(SignalProtocolAddress address) { synchronized (LOCK) { - SessionRecord session = DatabaseFactory.getSessionDatabase(context).load(address); + SessionRecord session = SignalDatabase.sessions().load(address); if (session != null) { session.archiveCurrentState(); - DatabaseFactory.getSessionDatabase(context).store(address, session); + SignalDatabase.sessions().store(address, session); } } } @@ -146,7 +146,7 @@ public class TextSecureSessionStore implements SignalServiceSessionStore { public void archiveSiblingSessions(@NonNull SignalProtocolAddress address) { synchronized (LOCK) { - List sessions = DatabaseFactory.getSessionDatabase(context).getAllFor(address.getName()); + List sessions = SignalDatabase.sessions().getAllFor(address.getName()); for (SessionDatabase.SessionRow row : sessions) { if (row.getDeviceId() != address.getDeviceId()) { @@ -159,7 +159,7 @@ public class TextSecureSessionStore implements SignalServiceSessionStore { public void archiveAllSessions() { synchronized (LOCK) { - List sessions = DatabaseFactory.getSessionDatabase(context).getAll(); + List sessions = SignalDatabase.sessions().getAll(); for (SessionDatabase.SessionRow row : sessions) { row.getRecord().archiveCurrentState(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentDatabase.java index 03dbd44676..b21796dfc9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentDatabase.java @@ -47,7 +47,6 @@ import org.thoughtcrime.securesms.crypto.AttachmentSecret; import org.thoughtcrime.securesms.crypto.ClassicDecryptingPartInputStream; import org.thoughtcrime.securesms.crypto.ModernDecryptingPartInputStream; import org.thoughtcrime.securesms.crypto.ModernEncryptingPartOutputStream; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.database.model.databaseprotos.AudioWaveFormData; import org.thoughtcrime.securesms.mms.MediaStream; import org.thoughtcrime.securesms.mms.MmsException; @@ -196,7 +195,7 @@ public class AttachmentDatabase extends Database { private final AttachmentSecret attachmentSecret; - public AttachmentDatabase(Context context, SQLCipherOpenHelper databaseHelper, AttachmentSecret attachmentSecret) { + public AttachmentDatabase(Context context, SignalDatabase databaseHelper, AttachmentSecret attachmentSecret) { super(context, databaseHelper); this.attachmentSecret = attachmentSecret; } @@ -227,7 +226,7 @@ public class AttachmentDatabase extends Database { values.put(TRANSFER_STATE, TRANSFER_PROGRESS_FAILED); database.update(TABLE_NAME, values, PART_ID_WHERE, attachmentId.toStrings()); - notifyConversationListeners(DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(mmsId)); + notifyConversationListeners(SignalDatabase.mms().getThreadIdForMessage(mmsId)); } public @Nullable DatabaseAttachment getAttachment(@NonNull AttachmentId attachmentId) @@ -425,7 +424,7 @@ public class AttachmentDatabase extends Database { database.update(TABLE_NAME, values, MMS_ID + " = ?", new String[] {mmsId + ""}); notifyAttachmentListeners(); - long threadId = DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(mmsId); + long threadId = SignalDatabase.mms().getThreadIdForMessage(mmsId); if (threadId > 0) { notifyConversationListeners(threadId); } @@ -487,7 +486,7 @@ public class AttachmentDatabase extends Database { } } - filesInDb.addAll(DatabaseFactory.getStickerDatabase(context).getAllStickerFiles()); + filesInDb.addAll(SignalDatabase.stickers().getAllStickerFiles()); Set onDiskButNotInDatabase = SetUtil.difference(filesOnDisk, filesInDb); @@ -618,8 +617,8 @@ public class AttachmentDatabase extends Database { //noinspection ResultOfMethodCallIgnored dataInfo.file.delete(); } else { - long threadId = DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(mmsId); - DatabaseFactory.getThreadDatabase(context).updateSnippetUriSilently(threadId, PartAuthority.getAttachmentDataUri(attachmentId)); + long threadId = SignalDatabase.mms().getThreadIdForMessage(mmsId); + SignalDatabase.threads().updateSnippetUriSilently(threadId, PartAuthority.getAttachmentDataUri(attachmentId)); notifyConversationListeners(threadId); notifyConversationListListeners(); @@ -938,7 +937,7 @@ public class AttachmentDatabase extends Database { values.put(TRANSFER_STATE, TRANSFER_PROGRESS_DONE); database.update(TABLE_NAME, values, PART_ID_WHERE, ((DatabaseAttachment)attachment).getAttachmentId().toStrings()); - notifyConversationListeners(DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(messageId)); + notifyConversationListeners(SignalDatabase.mms().getThreadIdForMessage(messageId)); } public void setTransferState(long messageId, @NonNull Attachment attachment, int transferState) { @@ -955,7 +954,7 @@ public class AttachmentDatabase extends Database { values.put(TRANSFER_STATE, transferState); database.update(TABLE_NAME, values, PART_ID_WHERE, attachmentId.toStrings()); - notifyConversationListeners(DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(messageId)); + notifyConversationListeners(SignalDatabase.mms().getThreadIdForMessage(messageId)); } /** diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/ChatColorsDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/ChatColorsDatabase.kt index 7047743847..b79b811a67 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/ChatColorsDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/ChatColorsDatabase.kt @@ -4,14 +4,13 @@ import android.content.ContentValues import android.content.Context import android.database.Cursor import org.thoughtcrime.securesms.conversation.colors.ChatColors -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper import org.thoughtcrime.securesms.database.model.databaseprotos.ChatColor import org.thoughtcrime.securesms.dependencies.ApplicationDependencies import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.util.CursorUtil import org.thoughtcrime.securesms.util.SqlUtil -class ChatColorsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Database(context, databaseHelper) { +class ChatColorsDatabase(context: Context, databaseHelper: SignalDatabase) : Database(context, databaseHelper) { companion object { private const val TABLE_NAME = "chat_colors" @@ -103,8 +102,7 @@ class ChatColorsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) SignalStore.chatColorsValues().chatColors = chatColors } - val recipientDatabase = DatabaseFactory.getRecipientDatabase(context) - recipientDatabase.onUpdatedChatColors(chatColors) + SignalDatabase.recipients.onUpdatedChatColors(chatColors) notifyListeners() return chatColors @@ -122,8 +120,7 @@ class ChatColorsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) SignalStore.chatColorsValues().chatColors = null } - val recipientDatabase = DatabaseFactory.getRecipientDatabase(context) - recipientDatabase.onDeletedChatColors(chatColors) + SignalDatabase.recipients.onDeletedChatColors(chatColors) notifyListeners() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/Database.java b/app/src/main/java/org/thoughtcrime/securesms/database/Database.java index f0220f4813..7d0ca7c92d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Database.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Database.java @@ -17,12 +17,7 @@ package org.thoughtcrime.securesms.database; import android.content.Context; -import android.database.ContentObserver; -import android.database.Cursor; -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import java.util.Set; @@ -32,10 +27,10 @@ public abstract class Database { protected static final String ID_WHERE = "_id = ?"; protected static final String[] COUNT = new String[] { "COUNT(*)" }; - protected SQLCipherOpenHelper databaseHelper; - protected final Context context; + protected SignalDatabase databaseHelper; + protected final Context context; - public Database(Context context, SQLCipherOpenHelper databaseHelper) { + public Database(Context context, SignalDatabase databaseHelper) { this.context = context; this.databaseHelper = databaseHelper; } @@ -76,7 +71,7 @@ public abstract class Database { ApplicationDependencies.getDatabaseObserver().notifyAttachmentObservers(); } - public void reset(SQLCipherOpenHelper databaseHelper) { + public void reset(SignalDatabase databaseHelper) { this.databaseHelper = databaseHelper; } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseFactory.java b/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseFactory.java deleted file mode 100644 index beb857edbc..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseFactory.java +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright (C) 2018 Open Whisper Systems - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.thoughtcrime.securesms.database; - -import android.content.Context; - -import androidx.annotation.NonNull; - -import net.zetetic.database.sqlcipher.SQLiteDatabase; - -import org.thoughtcrime.securesms.contacts.ContactsDatabase; -import org.thoughtcrime.securesms.crypto.AttachmentSecret; -import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider; -import org.thoughtcrime.securesms.crypto.DatabaseSecret; -import org.thoughtcrime.securesms.crypto.DatabaseSecretProvider; -import org.thoughtcrime.securesms.crypto.MasterSecret; -import org.thoughtcrime.securesms.database.helpers.ClassicOpenHelper; -import org.thoughtcrime.securesms.database.helpers.SQLCipherMigrationHelper; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; -import org.thoughtcrime.securesms.database.model.AvatarPickerDatabase; -import org.thoughtcrime.securesms.migrations.LegacyMigrationJob; -import org.thoughtcrime.securesms.util.SqlUtil; -import org.thoughtcrime.securesms.util.TextSecurePreferences; - -import java.io.Closeable; -import java.io.IOException; - -public class DatabaseFactory { - - private static final Object lock = new Object(); - - private static volatile DatabaseFactory instance; - - private final SQLCipherOpenHelper databaseHelper; - private final SmsDatabase sms; - private final MmsDatabase mms; - private final AttachmentDatabase attachments; - private final MediaDatabase media; - private final ThreadDatabase thread; - private final MmsSmsDatabase mmsSmsDatabase; - private final IdentityDatabase identityDatabase; - private final DraftDatabase draftDatabase; - private final PushDatabase pushDatabase; - private final GroupDatabase groupDatabase; - private final RecipientDatabase recipientDatabase; - private final ContactsDatabase contactsDatabase; - private final GroupReceiptDatabase groupReceiptDatabase; - private final OneTimePreKeyDatabase preKeyDatabase; - private final SignedPreKeyDatabase signedPreKeyDatabase; - private final SessionDatabase sessionDatabase; - private final SenderKeyDatabase senderKeyDatabase; - private final SenderKeySharedDatabase senderKeySharedDatabase; - private final PendingRetryReceiptDatabase pendingRetryReceiptDatabase; - private final SearchDatabase searchDatabase; - private final StickerDatabase stickerDatabase; - private final UnknownStorageIdDatabase storageIdDatabase; - private final RemappedRecordsDatabase remappedRecordsDatabase; - private final MentionDatabase mentionDatabase; - private final PaymentDatabase paymentDatabase; - private final ChatColorsDatabase chatColorsDatabase; - private final EmojiSearchDatabase emojiSearchDatabase; - private final MessageSendLogDatabase messageSendLogDatabase; - private final AvatarPickerDatabase avatarPickerDatabase; - private final GroupCallRingDatabase groupCallRingDatabase; - private final ReactionDatabase reactionDatabase; - - public static DatabaseFactory getInstance(Context context) { - if (instance == null) { - synchronized (lock) { - if (instance == null) { - instance = new DatabaseFactory(context.getApplicationContext()); - } - } - } - return instance; - } - - public static MmsSmsDatabase getMmsSmsDatabase(Context context) { - return getInstance(context).mmsSmsDatabase; - } - - public static ThreadDatabase getThreadDatabase(Context context) { - return getInstance(context).thread; - } - - public static MessageDatabase getSmsDatabase(Context context) { - return getInstance(context).sms; - } - - public static MessageDatabase getMmsDatabase(Context context) { - return getInstance(context).mms; - } - - public static AttachmentDatabase getAttachmentDatabase(Context context) { - return getInstance(context).attachments; - } - - public static MediaDatabase getMediaDatabase(Context context) { - return getInstance(context).media; - } - - public static IdentityDatabase getIdentityDatabase(Context context) { - return getInstance(context).identityDatabase; - } - - public static DraftDatabase getDraftDatabase(Context context) { - return getInstance(context).draftDatabase; - } - - /** - * @deprecated You probably shouldn't be using this anymore. It used to store encrypted envelopes, - * but now it's skipped over in favor of other mechanisms. It's only accessible to - * support old migrations and stuff. - */ - @Deprecated - public static PushDatabase getPushDatabase(Context context) { - return getInstance(context).pushDatabase; - } - - public static GroupDatabase getGroupDatabase(Context context) { - return getInstance(context).groupDatabase; - } - - public static RecipientDatabase getRecipientDatabase(Context context) { - return getInstance(context).recipientDatabase; - } - - public static ContactsDatabase getContactsDatabase(Context context) { - return getInstance(context).contactsDatabase; - } - - public static GroupReceiptDatabase getGroupReceiptDatabase(Context context) { - return getInstance(context).groupReceiptDatabase; - } - - public static OneTimePreKeyDatabase getPreKeyDatabase(Context context) { - return getInstance(context).preKeyDatabase; - } - - public static SignedPreKeyDatabase getSignedPreKeyDatabase(Context context) { - return getInstance(context).signedPreKeyDatabase; - } - - public static SessionDatabase getSessionDatabase(Context context) { - return getInstance(context).sessionDatabase; - } - - public static SenderKeyDatabase getSenderKeyDatabase(Context context) { - return getInstance(context).senderKeyDatabase; - } - - public static SenderKeySharedDatabase getSenderKeySharedDatabase(Context context) { - return getInstance(context).senderKeySharedDatabase; - } - - public static PendingRetryReceiptDatabase getPendingRetryReceiptDatabase(Context context) { - return getInstance(context).pendingRetryReceiptDatabase; - } - - public static SearchDatabase getSearchDatabase(Context context) { - return getInstance(context).searchDatabase; - } - - public static StickerDatabase getStickerDatabase(Context context) { - return getInstance(context).stickerDatabase; - } - - public static UnknownStorageIdDatabase getUnknownStorageIdDatabase(Context context) { - return getInstance(context).storageIdDatabase; - } - - public static RemappedRecordsDatabase getRemappedRecordsDatabase(Context context) { - return getInstance(context).remappedRecordsDatabase; - } - - public static MentionDatabase getMentionDatabase(Context context) { - return getInstance(context).mentionDatabase; - } - - public static PaymentDatabase getPaymentDatabase(Context context) { - return getInstance(context).paymentDatabase; - } - - public static ChatColorsDatabase getChatColorsDatabase(Context context) { - return getInstance(context).chatColorsDatabase; - } - - public static EmojiSearchDatabase getEmojiSearchDatabase(Context context) { - return getInstance(context).emojiSearchDatabase; - } - - public static MessageSendLogDatabase getMessageLogDatabase(Context context) { - return getInstance(context).messageSendLogDatabase; - } - - public static AvatarPickerDatabase getAvatarPickerDatabase(Context context) { - return getInstance(context).avatarPickerDatabase; - } - - public static GroupCallRingDatabase getGroupCallRingDatabase(Context context) { - return getInstance(context).groupCallRingDatabase; - } - - public static ReactionDatabase getReactionDatabase(Context context) { - return getInstance(context).reactionDatabase; - } - - public static net.zetetic.database.sqlcipher.SQLiteDatabase getBackupDatabase(Context context) { - return getInstance(context).databaseHelper.getRawReadableDatabase(); - } - - public static void upgradeRestored(Context context, SQLiteDatabase database){ - synchronized (lock) { - getInstance(context).databaseHelper.onUpgrade(database, database.getVersion(), -1); - getInstance(context).databaseHelper.markCurrent(database); - getInstance(context).sms.deleteAbandonedMessages(); - getInstance(context).mms.deleteAbandonedMessages(); - getInstance(context).mms.trimEntriesForExpiredMessages(); - getInstance(context).getRawDatabase().execSQL("DROP TABLE IF EXISTS key_value"); - getInstance(context).getRawDatabase().execSQL("DROP TABLE IF EXISTS megaphone"); - getInstance(context).getRawDatabase().execSQL("DROP TABLE IF EXISTS job_spec"); - getInstance(context).getRawDatabase().execSQL("DROP TABLE IF EXISTS constraint_spec"); - getInstance(context).getRawDatabase().execSQL("DROP TABLE IF EXISTS dependency_spec"); - } - } - - public static boolean inTransaction(Context context) { - return getInstance(context).databaseHelper.getSignalWritableDatabase().inTransaction(); - } - - private DatabaseFactory(@NonNull Context context) { - SqlCipherLibraryLoader.load(); - - DatabaseSecret databaseSecret = DatabaseSecretProvider.getOrCreateDatabaseSecret(context); - AttachmentSecret attachmentSecret = AttachmentSecretProvider.getInstance(context).getOrCreateAttachmentSecret(); - - this.databaseHelper = new SQLCipherOpenHelper(context, databaseSecret); - this.sms = new SmsDatabase(context, databaseHelper); - this.mms = new MmsDatabase(context, databaseHelper); - this.attachments = new AttachmentDatabase(context, databaseHelper, attachmentSecret); - this.media = new MediaDatabase(context, databaseHelper); - this.thread = new ThreadDatabase(context, databaseHelper); - this.mmsSmsDatabase = new MmsSmsDatabase(context, databaseHelper); - this.identityDatabase = new IdentityDatabase(context, databaseHelper); - this.draftDatabase = new DraftDatabase(context, databaseHelper); - this.pushDatabase = new PushDatabase(context, databaseHelper); - this.groupDatabase = new GroupDatabase(context, databaseHelper); - this.recipientDatabase = new RecipientDatabase(context, databaseHelper); - this.groupReceiptDatabase = new GroupReceiptDatabase(context, databaseHelper); - this.contactsDatabase = new ContactsDatabase(context); - this.preKeyDatabase = new OneTimePreKeyDatabase(context, databaseHelper); - this.signedPreKeyDatabase = new SignedPreKeyDatabase(context, databaseHelper); - this.sessionDatabase = new SessionDatabase(context, databaseHelper); - this.senderKeyDatabase = new SenderKeyDatabase(context, databaseHelper); - this.senderKeySharedDatabase = new SenderKeySharedDatabase(context, databaseHelper); - this.pendingRetryReceiptDatabase = new PendingRetryReceiptDatabase(context, databaseHelper); - this.searchDatabase = new SearchDatabase(context, databaseHelper); - this.stickerDatabase = new StickerDatabase(context, databaseHelper, attachmentSecret); - this.storageIdDatabase = new UnknownStorageIdDatabase(context, databaseHelper); - this.remappedRecordsDatabase = new RemappedRecordsDatabase(context, databaseHelper); - this.mentionDatabase = new MentionDatabase(context, databaseHelper); - this.paymentDatabase = new PaymentDatabase(context, databaseHelper); - this.chatColorsDatabase = new ChatColorsDatabase(context, databaseHelper); - this.emojiSearchDatabase = new EmojiSearchDatabase(context, databaseHelper); - this.messageSendLogDatabase = new MessageSendLogDatabase(context, databaseHelper); - this.avatarPickerDatabase = new AvatarPickerDatabase(context, databaseHelper); - this.groupCallRingDatabase = new GroupCallRingDatabase(context, databaseHelper); - this.reactionDatabase = new ReactionDatabase(context, databaseHelper); - } - - public void onApplicationLevelUpgrade(@NonNull Context context, @NonNull MasterSecret masterSecret, - int fromVersion, LegacyMigrationJob.DatabaseUpgradeListener listener) - { - databaseHelper.getSignalWritableDatabase(); - - ClassicOpenHelper legacyOpenHelper = null; - - if (fromVersion < LegacyMigrationJob.ASYMMETRIC_MASTER_SECRET_FIX_VERSION) { - legacyOpenHelper = new ClassicOpenHelper(context); - legacyOpenHelper.onApplicationLevelUpgrade(context, masterSecret, fromVersion, listener); - } - - if (fromVersion < LegacyMigrationJob.SQLCIPHER && TextSecurePreferences.getNeedsSqlCipherMigration(context)) { - if (legacyOpenHelper == null) { - legacyOpenHelper = new ClassicOpenHelper(context); - } - - SQLCipherMigrationHelper.migrateCiphertext(context, masterSecret, - legacyOpenHelper.getWritableDatabase(), - databaseHelper.getRawWritableDatabase(), - listener); - } - } - - public void triggerDatabaseAccess() { - databaseHelper.getSignalWritableDatabase(); - } - - public net.zetetic.database.sqlcipher.SQLiteDatabase getRawDatabase() { - return databaseHelper.getRawWritableDatabase(); - } - - public boolean hasTable(String table) { - return SqlUtil.tableExists(databaseHelper.getRawReadableDatabase(), table); - } - - public @NonNull Transaction transaction() { - getRawDatabase().beginTransaction(); - return () -> { - getRawDatabase().setTransactionSuccessful(); - getRawDatabase().endTransaction(); - }; - } - - public interface Transaction extends Closeable { - @Override - void close(); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/DraftDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/DraftDatabase.java index c378bb0171..33bda2293a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/DraftDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/DraftDatabase.java @@ -10,7 +10,6 @@ import androidx.annotation.Nullable; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.util.CursorUtil; import org.thoughtcrime.securesms.util.SqlUtil; @@ -35,7 +34,7 @@ public class DraftDatabase extends Database { "CREATE INDEX IF NOT EXISTS draft_thread_index ON " + TABLE_NAME + " (" + THREAD_ID + ");", }; - public DraftDatabase(Context context, SQLCipherOpenHelper databaseHelper) { + public DraftDatabase(Context context, SignalDatabase databaseHelper) { super(context, databaseHelper); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/EmojiSearchDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/EmojiSearchDatabase.java index 554f0d3de5..02c53588cc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/EmojiSearchDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/EmojiSearchDatabase.java @@ -7,7 +7,6 @@ import android.text.TextUtils; import androidx.annotation.NonNull; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.database.model.EmojiSearchData; import org.thoughtcrime.securesms.util.CursorUtil; import org.thoughtcrime.securesms.util.FtsUtil; @@ -28,7 +27,7 @@ public class EmojiSearchDatabase extends Database { public static final String CREATE_TABLE = "CREATE VIRTUAL TABLE " + TABLE_NAME + " USING fts5(" + LABEL + ", " + EMOJI + " UNINDEXED)"; - public EmojiSearchDatabase(@NonNull Context context, @NonNull SQLCipherOpenHelper databaseHelper) { + public EmojiSearchDatabase(@NonNull Context context, @NonNull SignalDatabase databaseHelper) { super(context, databaseHelper); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/GroupCallRingDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/GroupCallRingDatabase.kt index 10e08ef507..c3ddfee72d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/GroupCallRingDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/GroupCallRingDatabase.kt @@ -3,7 +3,6 @@ package org.thoughtcrime.securesms.database import android.content.ContentValues import android.content.Context import org.signal.ringrtc.CallManager -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper import org.thoughtcrime.securesms.util.CursorUtil import org.thoughtcrime.securesms.util.SqlUtil import java.util.concurrent.TimeUnit @@ -11,7 +10,7 @@ import java.util.concurrent.TimeUnit /** * Track state of Group Call ring cancellations. */ -class GroupCallRingDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Database(context, databaseHelper) { +class GroupCallRingDatabase(context: Context, databaseHelper: SignalDatabase) : Database(context, databaseHelper) { companion object { private val VALID_RING_DURATION = TimeUnit.MINUTES.toMillis(30) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java index 9b7b54908b..121d62df19 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java @@ -22,7 +22,6 @@ import org.signal.storageservice.protos.groups.local.EnabledState; import org.signal.zkgroup.InvalidInputException; import org.signal.zkgroup.groups.GroupMasterKey; import org.thoughtcrime.securesms.crypto.SenderKeyUtil; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.v2.processing.GroupsV2StateProcessor; import org.thoughtcrime.securesms.jobs.RequestGroupV2InfoJob; @@ -124,7 +123,7 @@ private static final String[] GROUP_PROJECTION = { static final List TYPED_GROUP_PROJECTION = Stream.of(GROUP_PROJECTION).map(columnName -> TABLE_NAME + "." + columnName).toList(); - public GroupDatabase(Context context, SQLCipherOpenHelper databaseHelper) { + public GroupDatabase(Context context, SignalDatabase databaseHelper) { super(context, databaseHelper); } @@ -145,11 +144,11 @@ private static final String[] GROUP_PROJECTION = { if (cursor != null && cursor.moveToNext()) { Optional groupRecord = getGroup(cursor); - if (groupRecord.isPresent() && RemappedRecords.getInstance().areAnyRemapped(context, groupRecord.get().getMembers())) { - String remaps = RemappedRecords.getInstance().buildRemapDescription(context, groupRecord.get().getMembers()); + if (groupRecord.isPresent() && RemappedRecords.getInstance().areAnyRemapped(groupRecord.get().getMembers())) { + String remaps = RemappedRecords.getInstance().buildRemapDescription(groupRecord.get().getMembers()); Log.w(TAG, "Found a group with remapped recipients in it's membership list! Updating the list. GroupId: " + groupId + ", Remaps: " + remaps, true); - Collection remapped = RemappedRecords.getInstance().remap(context, groupRecord.get().getMembers()); + Collection remapped = RemappedRecords.getInstance().remap(groupRecord.get().getMembers()); ContentValues values = new ContentValues(); values.put(MEMBERS, RecipientId.toSerializedList(remapped)); @@ -540,7 +539,7 @@ private static final String[] GROUP_PROJECTION = { @Nullable GroupMasterKey groupMasterKey, @Nullable DecryptedGroup groupState) { - RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase recipientDatabase = SignalDatabase.recipients(); RecipientId groupRecipientId = recipientDatabase.getOrInsertFromGroupId(groupId); List members = new ArrayList<>(new HashSet<>(memberCollection)); @@ -628,7 +627,7 @@ private static final String[] GROUP_PROJECTION = { GROUP_ID + " = ?", new String[] {groupId.toString()}); - RecipientId groupRecipient = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupId); + RecipientId groupRecipient = SignalDatabase.recipients().getOrInsertFromGroupId(groupId); Recipient.live(groupRecipient).refresh(); notifyConversationListListeners(); @@ -674,13 +673,13 @@ private static final String[] GROUP_PROJECTION = { throw new AssertionError(); } - DatabaseFactory.getRecipientDatabase(context).updateGroupId(groupIdV1, groupIdV2); + SignalDatabase.recipients().updateGroupId(groupIdV1, groupIdV2); update(groupMasterKey, decryptedGroup); - DatabaseFactory.getSmsDatabase(context).insertGroupV1MigrationEvents(record.getRecipientId(), - threadId, - new GroupMigrationMembershipChange(pendingMembers, droppedMembers)); + SignalDatabase.sms().insertGroupV1MigrationEvents(record.getRecipientId(), + threadId, + new GroupMigrationMembershipChange(pendingMembers, droppedMembers)); db.setTransactionSuccessful(); } finally { @@ -695,7 +694,7 @@ private static final String[] GROUP_PROJECTION = { } public void update(@NonNull GroupId.V2 groupId, @NonNull DecryptedGroup decryptedGroup) { - RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase recipientDatabase = SignalDatabase.recipients(); RecipientId groupRecipientId = recipientDatabase.getOrInsertFromGroupId(groupId); Optional existingGroup = getGroup(groupId); String title = decryptedGroup.getTitle(); @@ -775,7 +774,7 @@ private static final String[] GROUP_PROJECTION = { databaseHelper.getSignalWritableDatabase().update(TABLE_NAME, contentValues, GROUP_ID + " = ?", new String[] {groupId.toString()}); - RecipientId groupRecipient = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupId); + RecipientId groupRecipient = SignalDatabase.recipients().getOrInsertFromGroupId(groupId); Recipient.live(groupRecipient).refresh(); } @@ -789,7 +788,7 @@ private static final String[] GROUP_PROJECTION = { databaseHelper.getSignalWritableDatabase().update(TABLE_NAME, contentValues, GROUP_ID + " = ?", new String[] {groupId.toString()}); - RecipientId groupRecipient = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupId); + RecipientId groupRecipient = SignalDatabase.recipients().getOrInsertFromGroupId(groupId); Recipient.live(groupRecipient).refresh(); } @@ -803,7 +802,7 @@ private static final String[] GROUP_PROJECTION = { databaseHelper.getSignalWritableDatabase().update(TABLE_NAME, contents, GROUP_ID + " = ?", new String[] {groupId.toString()}); - RecipientId groupRecipient = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupId); + RecipientId groupRecipient = SignalDatabase.recipients().getOrInsertFromGroupId(groupId); Recipient.live(groupRecipient).refresh(); } @@ -817,7 +816,7 @@ private static final String[] GROUP_PROJECTION = { databaseHelper.getSignalWritableDatabase().update(TABLE_NAME, contents, GROUP_ID + " = ?", new String[] {groupId.toString()}); - RecipientId groupRecipient = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupId); + RecipientId groupRecipient = SignalDatabase.recipients().getOrInsertFromGroupId(groupId); Recipient.live(groupRecipient).refresh(); } @@ -899,7 +898,7 @@ private static final String[] GROUP_PROJECTION = { List uuids = DecryptedGroupUtil.membersToUuidList(decryptedGroup.getMembersList()); List ids = uuidsToRecipientIds(uuids); - if (RemappedRecords.getInstance().areAnyRemapped(context, ids)) { + if (RemappedRecords.getInstance().areAnyRemapped(ids)) { throw new IllegalStateException("Remapped records in group membership!"); } else { return ids; diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/GroupReceiptDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/GroupReceiptDatabase.java index 84179954c6..991e88d897 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/GroupReceiptDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/GroupReceiptDatabase.java @@ -7,7 +7,6 @@ import android.database.Cursor; import androidx.annotation.NonNull; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.util.SqlUtil; import org.whispersystems.libsignal.util.Pair; @@ -16,7 +15,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; import java.util.List; -import java.util.stream.Collectors; import javax.annotation.Nullable; @@ -44,7 +42,7 @@ public class GroupReceiptDatabase extends Database { "CREATE INDEX IF NOT EXISTS group_receipt_mms_id_index ON " + TABLE_NAME + " (" + MMS_ID + ");", }; - public GroupReceiptDatabase(Context context, SQLCipherOpenHelper databaseHelper) { + public GroupReceiptDatabase(Context context, SignalDatabase databaseHelper) { super(context, databaseHelper); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/IdentityDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/IdentityDatabase.java index 6f872999e1..ba4e02d6f7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/IdentityDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/IdentityDatabase.java @@ -25,7 +25,6 @@ import androidx.annotation.Nullable; import org.greenrobot.eventbus.EventBus; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.database.model.IdentityRecord; import org.thoughtcrime.securesms.database.model.IdentityStoreRecord; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; @@ -86,7 +85,7 @@ public class IdentityDatabase extends Database { } } - IdentityDatabase(Context context, SQLCipherOpenHelper databaseHelper) { + IdentityDatabase(Context context, SignalDatabase databaseHelper) { super(context, databaseHelper); } @@ -110,7 +109,7 @@ public class IdentityDatabase extends Database { timestamp, nonblockingApproval); } else if (UuidUtil.isUuid(addressName)) { - if (DatabaseFactory.getRecipientDatabase(context).containsPhoneOrUuid(addressName)) { + if (SignalDatabase.recipients().containsPhoneOrUuid(addressName)) { Recipient recipient = Recipient.external(context, addressName); if (recipient.hasE164() && !UuidUtil.isUuid(recipient.requireE164())) { @@ -141,7 +140,7 @@ public class IdentityDatabase extends Database { boolean nonBlockingApproval) { saveIdentityInternal(addressName, recipientId, identityKey, verifiedStatus, firstUse, timestamp, nonBlockingApproval); - DatabaseFactory.getRecipientDatabase(context).markNeedsSync(recipientId); + SignalDatabase.recipients().markNeedsSync(recipientId); } public void setApproval(@NonNull String addressName, @NonNull RecipientId recipientId, boolean nonBlockingApproval) { @@ -152,7 +151,7 @@ public class IdentityDatabase extends Database { database.update(TABLE_NAME, contentValues, ADDRESS + " = ?", SqlUtil.buildArgs(addressName)); - DatabaseFactory.getRecipientDatabase(context).markNeedsSync(recipientId); + SignalDatabase.recipients().markNeedsSync(recipientId); } public void setVerified(@NonNull String addressName, @NonNull RecipientId recipientId, IdentityKey identityKey, VerifiedStatus verifiedStatus) { @@ -169,7 +168,7 @@ public class IdentityDatabase extends Database { if (updated > 0) { Optional record = getIdentityRecord(addressName); if (record.isPresent()) EventBus.getDefault().post(record.get()); - DatabaseFactory.getRecipientDatabase(context).markNeedsSync(recipientId); + SignalDatabase.recipients().markNeedsSync(recipientId); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/JobDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/JobDatabase.java index f62975816b..e75ae895df 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/JobDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/JobDatabase.java @@ -2,14 +2,12 @@ package org.thoughtcrime.securesms.database; import android.app.Application; import android.content.ContentValues; -import android.content.Context; import android.database.Cursor; import androidx.annotation.NonNull; import com.annimon.stream.Stream; -import net.zetetic.database.sqlcipher.SQLiteDatabaseHook; import net.zetetic.database.sqlcipher.SQLiteOpenHelper; import net.zetetic.database.sqlcipher.SQLiteDatabase; @@ -26,7 +24,7 @@ import org.thoughtcrime.securesms.util.CursorUtil; import java.util.LinkedList; import java.util.List; -public class JobDatabase extends SQLiteOpenHelper implements SignalDatabase { +public class JobDatabase extends SQLiteOpenHelper implements SignalDatabaseOpenHelper { private static final String TAG = Log.tag(JobDatabase.class); @@ -117,19 +115,19 @@ public class JobDatabase extends SQLiteOpenHelper implements SignalDatabase { db.execSQL(Constraints.CREATE_TABLE); db.execSQL(Dependencies.CREATE_TABLE); - if (DatabaseFactory.getInstance(application).hasTable("job_spec")) { + if (SignalDatabase.hasTable("job_spec")) { Log.i(TAG, "Found old job_spec table. Migrating data."); - migrateJobSpecsFromPreviousDatabase(DatabaseFactory.getInstance(application).getRawDatabase(), db); + migrateJobSpecsFromPreviousDatabase(SignalDatabase.getRawDatabase(), db); } - if (DatabaseFactory.getInstance(application).hasTable("constraint_spec")) { + if (SignalDatabase.hasTable("constraint_spec")) { Log.i(TAG, "Found old constraint_spec table. Migrating data."); - migrateConstraintSpecsFromPreviousDatabase(DatabaseFactory.getInstance(application).getRawDatabase(), db); + migrateConstraintSpecsFromPreviousDatabase(SignalDatabase.getRawDatabase(), db); } - if (DatabaseFactory.getInstance(application).hasTable("dependency_spec")) { + if (SignalDatabase.hasTable("dependency_spec")) { Log.i(TAG, "Found old dependency_spec table. Migrating data."); - migrateDependencySpecsFromPreviousDatabase(DatabaseFactory.getInstance(application).getRawDatabase(), db); + migrateDependencySpecsFromPreviousDatabase(SignalDatabase.getRawDatabase(), db); } } @@ -375,9 +373,9 @@ public class JobDatabase extends SQLiteOpenHelper implements SignalDatabase { } private void dropTableIfPresent(@NonNull String table) { - if (DatabaseFactory.getInstance(application).hasTable(table)) { + if (SignalDatabase.hasTable(table)) { Log.i(TAG, "Dropping original " + table + " table from the main database."); - DatabaseFactory.getInstance(application).getRawDatabase().execSQL("DROP TABLE " + table); + SignalDatabase.getRawDatabase().execSQL("DROP TABLE " + table); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/KeyValueDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/KeyValueDatabase.java index d60be1ee89..e4fc82e92b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/KeyValueDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/KeyValueDatabase.java @@ -26,7 +26,7 @@ import java.util.Map; * This is it's own separate physical database, so it cannot do joins or queries with any other * tables. */ -public class KeyValueDatabase extends SQLiteOpenHelper implements SignalDatabase, KeyValuePersistentStorage { +public class KeyValueDatabase extends SQLiteOpenHelper implements SignalDatabaseOpenHelper, KeyValuePersistentStorage { private static final String TAG = Log.tag(KeyValueDatabase.class); @@ -72,9 +72,9 @@ public class KeyValueDatabase extends SQLiteOpenHelper implements SignalDatabase db.execSQL(CREATE_TABLE); - if (DatabaseFactory.getInstance(application).hasTable("key_value")) { + if (SignalDatabase.hasTable("key_value")) { Log.i(TAG, "Found old key_value table. Migrating data."); - migrateDataFromPreviousDatabase(DatabaseFactory.getInstance(application).getRawDatabase(), db); + migrateDataFromPreviousDatabase(SignalDatabase.getRawDatabase(), db); } } @@ -91,9 +91,9 @@ public class KeyValueDatabase extends SQLiteOpenHelper implements SignalDatabase db.setForeignKeyConstraintsEnabled(true); SignalExecutors.BOUNDED.execute(() -> { - if (DatabaseFactory.getInstance(application).hasTable("key_value")) { + if (SignalDatabase.hasTable("key_value")) { Log.i(TAG, "Dropping original key_value table from the main database."); - DatabaseFactory.getInstance(application).getRawDatabase().execSQL("DROP TABLE key_value"); + SignalDatabase.getRawDatabase().execSQL("DROP TABLE key_value"); } }); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/LocalMetricsDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/LocalMetricsDatabase.kt index d223c76328..99eace5768 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/LocalMetricsDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/LocalMetricsDatabase.kt @@ -36,7 +36,7 @@ class LocalMetricsDatabase private constructor( SqlCipherDeletingErrorHandler(DATABASE_NAME), SqlCipherDatabaseHook() ), - SignalDatabase { + SignalDatabaseOpenHelper { companion object { private val TAG = Log.tag(LocalMetricsDatabase::class.java) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/LogDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/LogDatabase.kt index 88b2cb52a6..399547aef0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/LogDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/LogDatabase.kt @@ -38,7 +38,7 @@ class LogDatabase private constructor( SqlCipherDeletingErrorHandler(DATABASE_NAME), SqlCipherDatabaseHook() ), - SignalDatabase { + SignalDatabaseOpenHelper { companion object { private val TAG = Log.tag(LogDatabase::class.java) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MediaDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MediaDatabase.java index 41ac2392f0..8404d9d5cc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MediaDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MediaDatabase.java @@ -1,15 +1,12 @@ package org.thoughtcrime.securesms.database; import android.content.Context; -import android.database.ContentObserver; import android.database.Cursor; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import org.thoughtcrime.securesms.attachments.DatabaseAttachment; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; -import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.util.MediaUtil; @@ -85,7 +82,7 @@ public class MediaDatabase extends Database { AttachmentDatabase.CONTENT_TYPE + " NOT LIKE 'audio/%' AND " + AttachmentDatabase.CONTENT_TYPE + " NOT LIKE 'text/x-signal-plain'"); - MediaDatabase(Context context, SQLCipherOpenHelper databaseHelper) { + MediaDatabase(Context context, SignalDatabase databaseHelper) { super(context, databaseHelper); } @@ -191,7 +188,7 @@ public class MediaDatabase extends Database { } public static MediaRecord from(@NonNull Context context, @NonNull Cursor cursor) { - AttachmentDatabase attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context); + AttachmentDatabase attachmentDatabase = SignalDatabase.attachments(); List attachments = attachmentDatabase.getAttachments(cursor); RecipientId recipientId = RecipientId.from(cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.RECIPIENT_ID))); long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.THREAD_ID)); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MegaphoneDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MegaphoneDatabase.java index 1a3c240003..aa22865114 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MegaphoneDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MegaphoneDatabase.java @@ -26,7 +26,7 @@ import java.util.Set; /** * IMPORTANT: Writes should only be made through {@link org.thoughtcrime.securesms.megaphone.MegaphoneRepository}. */ -public class MegaphoneDatabase extends SQLiteOpenHelper implements SignalDatabase { +public class MegaphoneDatabase extends SQLiteOpenHelper implements SignalDatabaseOpenHelper { private static final String TAG = Log.tag(MegaphoneDatabase.class); @@ -76,9 +76,9 @@ public class MegaphoneDatabase extends SQLiteOpenHelper implements SignalDatabas db.execSQL(CREATE_TABLE); - if (DatabaseFactory.getInstance(application).hasTable("megaphone")) { + if (SignalDatabase.hasTable("megaphone")) { Log.i(TAG, "Found old megaphone table. Migrating data."); - migrateDataFromPreviousDatabase(DatabaseFactory.getInstance(application).getRawDatabase(), db); + migrateDataFromPreviousDatabase(SignalDatabase.getRawDatabase(), db); } } @@ -95,9 +95,9 @@ public class MegaphoneDatabase extends SQLiteOpenHelper implements SignalDatabas db.setForeignKeyConstraintsEnabled(true); SignalExecutors.BOUNDED.execute(() -> { - if (DatabaseFactory.getInstance(application).hasTable("megaphone")) { + if (SignalDatabase.hasTable("megaphone")) { Log.i(TAG, "Dropping original megaphone table from the main database."); - DatabaseFactory.getInstance(application).getRawDatabase().execSQL("DROP TABLE megaphone"); + SignalDatabase.getRawDatabase().execSQL("DROP TABLE megaphone"); } }); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MentionDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MentionDatabase.java index 8b0f9fbf32..c0d71bc1e1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MentionDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MentionDatabase.java @@ -10,7 +10,6 @@ import androidx.annotation.Nullable; import com.annimon.stream.Stream; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.database.model.Mention; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.util.CursorUtil; @@ -28,7 +27,7 @@ public class MentionDatabase extends Database { private static final String ID = "_id"; static final String THREAD_ID = "thread_id"; - private static final String MESSAGE_ID = "message_id"; + static final String MESSAGE_ID = "message_id"; static final String RECIPIENT_ID = "recipient_id"; private static final String RANGE_START = "range_start"; private static final String RANGE_LENGTH = "range_length"; @@ -45,7 +44,7 @@ public class MentionDatabase extends Database { "CREATE INDEX IF NOT EXISTS mention_recipient_id_thread_id_index ON " + TABLE_NAME + " (" + RECIPIENT_ID + ", " + THREAD_ID + ");" }; - public MentionDatabase(@NonNull Context context, @NonNull SQLCipherOpenHelper databaseHelper) { + public MentionDatabase(@NonNull Context context, @NonNull SignalDatabase databaseHelper) { super(context, databaseHelper); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MentionUtil.java b/app/src/main/java/org/thoughtcrime/securesms/database/MentionUtil.java index 6af572dced..08338fdd84 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MentionUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MentionUtil.java @@ -42,7 +42,7 @@ public final class MentionUtil { @WorkerThread public static @NonNull CharSequence updateBodyWithDisplayNames(@NonNull Context context, @NonNull MessageRecord messageRecord, @NonNull CharSequence body) { if (messageRecord.isMms()) { - List mentions = DatabaseFactory.getMentionDatabase(context).getMentionsForMessage(messageRecord.getId()); + List mentions = SignalDatabase.mentions().getMentionsForMessage(messageRecord.getId()); CharSequence updated = updateBodyAndMentionsWithDisplayNames(context, body, mentions).getBody(); if (updated != null) { return updated; diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MessageDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MessageDatabase.java index 1ac30b66e8..6fc3edd28d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MessageDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MessageDatabase.java @@ -8,9 +8,7 @@ import android.text.TextUtils; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.annimon.stream.Stream; import com.google.android.mms.pdu_alt.NotificationInd; -import com.google.protobuf.InvalidProtocolBufferException; import net.zetetic.database.sqlcipher.SQLiteStatement; @@ -19,12 +17,9 @@ import org.thoughtcrime.securesms.database.documents.Document; import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch; import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatchSet; import org.thoughtcrime.securesms.database.documents.NetworkFailure; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.database.model.MessageId; import org.thoughtcrime.securesms.database.model.MessageRecord; -import org.thoughtcrime.securesms.database.model.ReactionRecord; import org.thoughtcrime.securesms.database.model.SmsMessageRecord; -import org.thoughtcrime.securesms.database.model.databaseprotos.ReactionList; import org.thoughtcrime.securesms.groups.GroupMigrationMembershipChange; import org.thoughtcrime.securesms.insights.InsightsConstants; import org.thoughtcrime.securesms.mms.IncomingMediaMessage; @@ -47,7 +42,6 @@ import java.io.Closeable; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Locale; @@ -63,7 +57,7 @@ public abstract class MessageDatabase extends Database implements MmsSmsColumns protected static final String THREAD_ID_WHERE = THREAD_ID + " = ?"; protected static final String[] THREAD_ID_PROJECTION = new String[] { THREAD_ID }; - public MessageDatabase(Context context, SQLCipherOpenHelper databaseHelper) { + public MessageDatabase(Context context, SignalDatabase databaseHelper) { super(context, databaseHelper); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MessageSendLogDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/MessageSendLogDatabase.kt index 993e01ea63..37a492e4e7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MessageSendLogDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MessageSendLogDatabase.kt @@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.database import android.content.ContentValues import android.content.Context -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper import org.thoughtcrime.securesms.database.model.MessageId import org.thoughtcrime.securesms.database.model.MessageLogEntry import org.thoughtcrime.securesms.recipients.Recipient @@ -44,7 +43,7 @@ import org.whispersystems.signalservice.internal.push.SignalServiceProtos * - We *don't* really need to optimize for retrieval, since that happens very infrequently. In particular, we don't want to slow down inserts in order to * improve retrieval time. That means we shouldn't be adding indexes that optimize for retrieval. */ -class MessageSendLogDatabase constructor(context: Context?, databaseHelper: SQLCipherOpenHelper?) : Database(context, databaseHelper) { +class MessageSendLogDatabase constructor(context: Context?, databaseHelper: SignalDatabase?) : Database(context, databaseHelper) { companion object { @JvmField diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java index a061a392f6..f0762350f4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java @@ -44,14 +44,12 @@ import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch; import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatchSet; import org.thoughtcrime.securesms.database.documents.NetworkFailure; import org.thoughtcrime.securesms.database.documents.NetworkFailureSet; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord; import org.thoughtcrime.securesms.database.model.Mention; import org.thoughtcrime.securesms.database.model.MessageId; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.database.model.NotificationMmsMessageRecord; import org.thoughtcrime.securesms.database.model.Quote; -import org.thoughtcrime.securesms.database.model.ReactionRecord; import org.thoughtcrime.securesms.database.model.SmsMessageRecord; import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; @@ -233,7 +231,7 @@ public class MmsDatabase extends MessageDatabase { private final EarlyReceiptCache earlyDeliveryReceiptCache = new EarlyReceiptCache("MmsDelivery"); - public MmsDatabase(Context context, SQLCipherOpenHelper databaseHelper) { + public MmsDatabase(Context context, SignalDatabase databaseHelper) { super(context, databaseHelper); } @@ -637,7 +635,7 @@ public class MmsDatabase extends MessageDatabase { ID + " = ?", SqlUtil.buildArgs(updatedTimestamp, id)); - DatabaseFactory.getGroupReceiptDatabase(context).update(ourRecipientId, id, status, timestamp); + SignalDatabase.groupReceipts().update(ourRecipientId, id, status, timestamp); threadUpdates.add(new ThreadUpdate(threadId, !isFirstIncrement)); } @@ -674,12 +672,12 @@ public class MmsDatabase extends MessageDatabase { private long getThreadIdFor(@NonNull IncomingMediaMessage retrieved) { if (retrieved.getGroupId() != null) { - RecipientId groupRecipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromPossiblyMigratedGroupId(retrieved.getGroupId()); + RecipientId groupRecipientId = SignalDatabase.recipients().getOrInsertFromPossiblyMigratedGroupId(retrieved.getGroupId()); Recipient groupRecipients = Recipient.resolved(groupRecipientId); - return DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(groupRecipients); + return SignalDatabase.threads().getOrCreateThreadIdFor(groupRecipients); } else { Recipient sender = Recipient.resolved(retrieved.getFrom()); - return DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(sender); + return SignalDatabase.threads().getOrCreateThreadIdFor(sender); } } @@ -688,7 +686,7 @@ public class MmsDatabase extends MessageDatabase { ? Util.toIsoString(notification.getFrom().getTextString()) : ""; Recipient recipient = Recipient.external(context, fromString); - return DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient); + return SignalDatabase.threads().getOrCreateThreadIdFor(recipient); } private Cursor rawQuery(@NonNull String where, @Nullable String[] arguments) { @@ -753,7 +751,7 @@ public class MmsDatabase extends MessageDatabase { " WHERE " + ID + " = ?", new String[] { id + "" }); if (threadId.isPresent()) { - DatabaseFactory.getThreadDatabase(context).updateSnippetTypeSilently(threadId.get()); + SignalDatabase.threads().updateSnippetTypeSilently(threadId.get()); } db.setTransactionSuccessful(); } finally { @@ -849,12 +847,12 @@ public class MmsDatabase extends MessageDatabase { values.putNull(SHARED_CONTACTS); db.update(TABLE_NAME, values, ID_WHERE, new String[] { String.valueOf(messageId) }); - deletedAttachments = DatabaseFactory.getAttachmentDatabase(context).deleteAttachmentsForMessage(messageId); - DatabaseFactory.getMentionDatabase(context).deleteMentionsForMessage(messageId); - DatabaseFactory.getMessageLogDatabase(context).deleteAllRelatedToMessage(messageId, true); + deletedAttachments = SignalDatabase.attachments().deleteAttachmentsForMessage(messageId); + SignalDatabase.mentions().deleteMentionsForMessage(messageId); + SignalDatabase.messageLog().deleteAllRelatedToMessage(messageId, true); threadId = getThreadIdForMessage(messageId); - DatabaseFactory.getThreadDatabase(context).update(threadId, false); + SignalDatabase.threads().update(threadId, false); db.setTransactionSuccessful(); } finally { db.endTransaction(); @@ -927,7 +925,7 @@ public class MmsDatabase extends MessageDatabase { db.endTransaction(); } - DatabaseFactory.getThreadDatabase(context).update(threadId, false); + SignalDatabase.threads().update(threadId, false); notifyConversationListeners(threadId); } @@ -1034,8 +1032,8 @@ public class MmsDatabase extends MessageDatabase { database.update(TABLE_NAME, values, ID_WHERE, new String[]{String.valueOf(id)}); - DatabaseFactory.getThreadDatabase(context).updateReadState(threadId); - DatabaseFactory.getThreadDatabase(context).setLastSeen(threadId); + SignalDatabase.threads().updateReadState(threadId); + SignalDatabase.threads().setLastSeen(threadId); notifyConversationListeners(threadId); Long latest = threadToLatestRead.get(threadId); @@ -1096,16 +1094,16 @@ public class MmsDatabase extends MessageDatabase { try (Cursor cursor = database.query(AttachmentDatabase.TABLE_NAME, columns, where, null, null, null, null)) { while (cursor != null && cursor.moveToNext()) { - DatabaseFactory.getAttachmentDatabase(context).deleteAttachment(new AttachmentId(cursor.getLong(0), cursor.getLong(1))); + SignalDatabase.attachments().deleteAttachment(new AttachmentId(cursor.getLong(0), cursor.getLong(1))); } } - DatabaseFactory.getMentionDatabase(context).deleteAbandonedMentions(); + SignalDatabase.mentions().deleteAbandonedMentions(); try (Cursor cursor = database.query(ThreadDatabase.TABLE_NAME, new String[] { ThreadDatabase.ID }, ThreadDatabase.EXPIRES_IN + " > 0", null, null, null, null)) { while (cursor != null && cursor.moveToNext()) { - DatabaseFactory.getThreadDatabase(context).setLastScrolled(cursor.getLong(0), 0); - DatabaseFactory.getThreadDatabase(context).update(cursor.getLong(0), false); + SignalDatabase.threads().setLastScrolled(cursor.getLong(0), 0); + SignalDatabase.threads().update(cursor.getLong(0), false); } } } @@ -1135,8 +1133,8 @@ public class MmsDatabase extends MessageDatabase { public OutgoingMediaMessage getOutgoingMessage(long messageId) throws MmsException, NoSuchMessageException { - AttachmentDatabase attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context); - MentionDatabase mentionDatabase = DatabaseFactory.getMentionDatabase(context); + AttachmentDatabase attachmentDatabase = SignalDatabase.attachments(); + MentionDatabase mentionDatabase = SignalDatabase.mentions(); Cursor cursor = null; try { @@ -1154,7 +1152,7 @@ public class MmsDatabase extends MessageDatabase { boolean viewOnce = cursor.getLong(cursor.getColumnIndexOrThrow(VIEW_ONCE)) == 1; long recipientId = cursor.getLong(cursor.getColumnIndexOrThrow(RECIPIENT_ID)); long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(THREAD_ID)); - int distributionType = DatabaseFactory.getThreadDatabase(context).getDistributionType(threadId); + int distributionType = SignalDatabase.threads().getDistributionType(threadId); String mismatchDocument = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.MISMATCHED_IDENTITIES)); String networkDocument = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.NETWORK_FAILURE)); @@ -1358,8 +1356,8 @@ public class MmsDatabase extends MessageDatabase { long messageId = insertMediaMessage(threadId, retrieved.getBody(), retrieved.getAttachments(), quoteAttachments, retrieved.getSharedContacts(), retrieved.getLinkPreviews(), retrieved.getMentions(), contentValues, null, true); if (!Types.isExpirationTimerUpdate(mailbox)) { - DatabaseFactory.getThreadDatabase(context).incrementUnread(threadId, 1); - DatabaseFactory.getThreadDatabase(context).update(threadId, true); + SignalDatabase.threads().incrementUnread(threadId, 1); + SignalDatabase.threads().update(threadId, true); } notifyConversationListeners(threadId); @@ -1454,10 +1452,10 @@ public class MmsDatabase extends MessageDatabase { notifyConversationListeners(threadId); if (org.thoughtcrime.securesms.util.Util.isDefaultSmsProvider(context)) { - DatabaseFactory.getThreadDatabase(context).incrementUnread(threadId, 1); + SignalDatabase.threads().incrementUnread(threadId, 1); } - DatabaseFactory.getThreadDatabase(context).update(threadId, true); + SignalDatabase.threads().update(threadId, true); TrimThreadJob.enqueueAsync(threadId); } @@ -1549,7 +1547,7 @@ public class MmsDatabase extends MessageDatabase { if (message.getRecipient().isGroup()) { OutgoingGroupUpdateMessage outgoingGroupUpdateMessage = (message instanceof OutgoingGroupUpdateMessage) ? (OutgoingGroupUpdateMessage) message : null; - GroupReceiptDatabase receiptDatabase = DatabaseFactory.getGroupReceiptDatabase(context); + GroupReceiptDatabase receiptDatabase = SignalDatabase.groupReceipts(); Set members = new HashSet<>(); if (outgoingGroupUpdateMessage != null && outgoingGroupUpdateMessage.isV2Group()) { @@ -1560,7 +1558,7 @@ public class MmsDatabase extends MessageDatabase { .toList()); members.remove(Recipient.self().getId()); } else { - members.addAll(Stream.of(DatabaseFactory.getGroupDatabase(context).getGroupMembers(message.getRecipient().requireGroupId(), GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF)).map(Recipient::getId).toList()); + members.addAll(Stream.of(SignalDatabase.groups().getGroupMembers(message.getRecipient().requireGroupId(), GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF)).map(Recipient::getId).toList()); } receiptDatabase.insert(members, messageId, defaultReceiptStatus, message.getSentTimeMillis()); @@ -1570,7 +1568,7 @@ public class MmsDatabase extends MessageDatabase { } } - DatabaseFactory.getThreadDatabase(context).updateLastSeenAndMarkSentAndLastScrolledSilenty(threadId); + SignalDatabase.threads().updateLastSeenAndMarkSentAndLastScrolledSilenty(threadId); ApplicationDependencies.getDatabaseObserver().notifyMessageInsertObservers(threadId, new MessageId(messageId, true)); notifyConversationListListeners(); @@ -1603,8 +1601,8 @@ public class MmsDatabase extends MessageDatabase { throws MmsException { SQLiteDatabase db = databaseHelper.getSignalWritableDatabase(); - AttachmentDatabase partsDatabase = DatabaseFactory.getAttachmentDatabase(context); - MentionDatabase mentionDatabase = DatabaseFactory.getMentionDatabase(context); + AttachmentDatabase partsDatabase = SignalDatabase.attachments(); + MentionDatabase mentionDatabase = SignalDatabase.mentions(); boolean mentionsSelf = Stream.of(mentions).filter(m -> Recipient.resolved(m.getRecipientId()).isSelf()).findFirst().isPresent(); @@ -1666,8 +1664,8 @@ public class MmsDatabase extends MessageDatabase { long contentValuesThreadId = contentValues.getAsLong(THREAD_ID); if (updateThread) { - DatabaseFactory.getThreadDatabase(context).setLastScrolled(contentValuesThreadId, 0); - DatabaseFactory.getThreadDatabase(context).update(threadId, true); + SignalDatabase.threads().setLastScrolled(contentValuesThreadId, 0); + SignalDatabase.threads().update(threadId, true); } } } @@ -1677,20 +1675,20 @@ public class MmsDatabase extends MessageDatabase { Log.d(TAG, "deleteMessage(" + messageId + ")"); long threadId = getThreadIdForMessage(messageId); - AttachmentDatabase attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context); + AttachmentDatabase attachmentDatabase = SignalDatabase.attachments(); attachmentDatabase.deleteAttachmentsForMessage(messageId); - GroupReceiptDatabase groupReceiptDatabase = DatabaseFactory.getGroupReceiptDatabase(context); + GroupReceiptDatabase groupReceiptDatabase = SignalDatabase.groupReceipts(); groupReceiptDatabase.deleteRowsForMessage(messageId); - MentionDatabase mentionDatabase = DatabaseFactory.getMentionDatabase(context); + MentionDatabase mentionDatabase = SignalDatabase.mentions(); mentionDatabase.deleteMentionsForMessage(messageId); SQLiteDatabase database = databaseHelper.getSignalWritableDatabase(); database.delete(TABLE_NAME, ID_WHERE, new String[] {messageId+""}); - DatabaseFactory.getThreadDatabase(context).setLastScrolled(threadId, 0); - boolean threadDeleted = DatabaseFactory.getThreadDatabase(context).update(threadId, false); + SignalDatabase.threads().setLastScrolled(threadId, 0); + boolean threadDeleted = SignalDatabase.threads().update(threadId, false); notifyConversationListeners(threadId); notifyStickerListeners(); notifyStickerPackListeners(); @@ -1855,9 +1853,9 @@ public class MmsDatabase extends MessageDatabase { @Override public void deleteAllThreads() { Log.d(TAG, "deleteAllThreads()"); - DatabaseFactory.getAttachmentDatabase(context).deleteAllAttachments(); - DatabaseFactory.getGroupReceiptDatabase(context).deleteAllRows(); - DatabaseFactory.getMentionDatabase(context).deleteAllMentions(); + SignalDatabase.attachments().deleteAllAttachments(); + SignalDatabase.groupReceipts().deleteAllRows(); + SignalDatabase.mentions().deleteAllMentions(); SQLiteDatabase database = databaseHelper.getSignalWritableDatabase(); database.delete(TABLE_NAME, null, null); @@ -2111,7 +2109,7 @@ public class MmsDatabase extends MessageDatabase { Recipient recipient = Recipient.live(RecipientId.from(recipientId)).get(); Set mismatches = getMismatchedIdentities(mismatchDocument); Set networkFailures = getFailures(networkDocument); - List attachments = DatabaseFactory.getAttachmentDatabase(context).getAttachments(cursor); + List attachments = SignalDatabase.attachments().getAttachments(cursor); List contacts = getSharedContacts(cursor, attachments); Set contactAttachments = Stream.of(contacts).map(Contact::getAvatarAttachment).withoutNulls().collect(Collectors.toSet()); List previews = getLinkPreviews(cursor, attachments); @@ -2165,7 +2163,7 @@ public class MmsDatabase extends MessageDatabase { CharSequence quoteText = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.QUOTE_BODY)); boolean quoteMissing = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.QUOTE_MISSING)) == 1; List quoteMentions = parseQuoteMentions(context, cursor); - List attachments = DatabaseFactory.getAttachmentDatabase(context).getAttachments(cursor); + List attachments = SignalDatabase.attachments().getAttachments(cursor); List quoteAttachments = Stream.of(attachments).filter(Attachment::isQuote).toList(); SlideDeck quoteDeck = new SlideDeck(context, quoteAttachments); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java index 70fd59fa42..2a36ee2865 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java @@ -30,7 +30,6 @@ import net.zetetic.database.sqlcipher.SQLiteQueryBuilder; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId; import org.thoughtcrime.securesms.database.MessageDatabase.ThreadUpdate; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.notifications.v2.MessageNotifierV2; import org.thoughtcrime.securesms.recipients.Recipient; @@ -116,7 +115,7 @@ public class MmsSmsDatabase extends Database { "ORDER BY " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " DESC " + "LIMIT 1"; - public MmsSmsDatabase(Context context, SQLCipherOpenHelper databaseHelper) { + public MmsSmsDatabase(Context context, SignalDatabase databaseHelper) { super(context, databaseHelper); } @@ -141,8 +140,8 @@ public class MmsSmsDatabase extends Database { } private @NonNull Pair getGroupAddedBy(long threadId, long lastQuitChecked) { - MessageDatabase mmsDatabase = DatabaseFactory.getMmsDatabase(context); - MessageDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context); + MessageDatabase mmsDatabase = SignalDatabase.mms(); + MessageDatabase smsDatabase = SignalDatabase.sms(); long latestQuit = mmsDatabase.getLatestGroupQuitTimestamp(threadId, lastQuitChecked); RecipientId id = smsDatabase.getOldestGroupUpdateSender(threadId, latestQuit); @@ -182,9 +181,9 @@ public class MmsSmsDatabase extends Database { } public @NonNull List getMessagesAfterVoiceNoteInclusive(long messageId, long limit) throws NoSuchMessageException { - MessageRecord origin = DatabaseFactory.getMmsDatabase(context).getMessageRecord(messageId); - List mms = DatabaseFactory.getMmsDatabase(context).getMessagesInThreadAfterInclusive(origin.getThreadId(), origin.getDateReceived(), limit); - List sms = DatabaseFactory.getSmsDatabase(context).getMessagesInThreadAfterInclusive(origin.getThreadId(), origin.getDateReceived(), limit); + MessageRecord origin = SignalDatabase.mms().getMessageRecord(messageId); + List mms = SignalDatabase.mms().getMessagesInThreadAfterInclusive(origin.getThreadId(), origin.getDateReceived(), limit); + List sms = SignalDatabase.sms().getMessagesInThreadAfterInclusive(origin.getThreadId(), origin.getDateReceived(), limit); mms.addAll(sms); Collections.sort(mms, (a, b) -> Long.compare(a.getDateReceived(), b.getDateReceived())); @@ -214,9 +213,9 @@ public class MmsSmsDatabase extends Database { long id = CursorUtil.requireLong(cursor, MmsSmsColumns.ID); if (isMms) { - return DatabaseFactory.getMmsDatabase(context).getMessageRecord(id); + return SignalDatabase.mms().getMessageRecord(id); } else { - return DatabaseFactory.getSmsDatabase(context).getMessageRecord(id); + return SignalDatabase.sms().getMessageRecord(id); } } else { throw new NoSuchMessageException("no message"); @@ -275,8 +274,8 @@ public class MmsSmsDatabase extends Database { } public boolean checkMessageExists(@NonNull MessageRecord messageRecord) { - MessageDatabase db = messageRecord.isMms() ? DatabaseFactory.getMmsDatabase(context) - : DatabaseFactory.getSmsDatabase(context); + MessageDatabase db = messageRecord.isMms() ? SignalDatabase.mms() + : SignalDatabase.sms(); try (Cursor cursor = db.getMessageCursor(messageRecord.getId())) { return cursor != null && cursor.getCount() > 0; @@ -288,8 +287,8 @@ public class MmsSmsDatabase extends Database { return 0; } - int count = DatabaseFactory.getSmsDatabase(context).getSecureMessageCount(threadId); - count += DatabaseFactory.getMmsDatabase(context).getSecureMessageCount(threadId); + int count = SignalDatabase.sms().getSecureMessageCount(threadId); + count += SignalDatabase.mms().getSecureMessageCount(threadId); return count; } @@ -299,34 +298,34 @@ public class MmsSmsDatabase extends Database { return 0; } - int count = DatabaseFactory.getSmsDatabase(context).getOutgoingSecureMessageCount(threadId); - count += DatabaseFactory.getMmsDatabase(context).getOutgoingSecureMessageCount(threadId); + int count = SignalDatabase.sms().getOutgoingSecureMessageCount(threadId); + count += SignalDatabase.mms().getOutgoingSecureMessageCount(threadId); return count; } public int getConversationCount(long threadId) { - int count = DatabaseFactory.getSmsDatabase(context).getMessageCountForThread(threadId); - count += DatabaseFactory.getMmsDatabase(context).getMessageCountForThread(threadId); + int count = SignalDatabase.sms().getMessageCountForThread(threadId); + count += SignalDatabase.mms().getMessageCountForThread(threadId); return count; } public int getConversationCount(long threadId, long beforeTime) { - return DatabaseFactory.getSmsDatabase(context).getMessageCountForThread(threadId, beforeTime) + - DatabaseFactory.getMmsDatabase(context).getMessageCountForThread(threadId, beforeTime); + return SignalDatabase.sms().getMessageCountForThread(threadId, beforeTime) + + SignalDatabase.mms().getMessageCountForThread(threadId, beforeTime); } public int getInsecureSentCount(long threadId) { - int count = DatabaseFactory.getSmsDatabase(context).getInsecureMessagesSentForThread(threadId); - count += DatabaseFactory.getMmsDatabase(context).getInsecureMessagesSentForThread(threadId); + int count = SignalDatabase.sms().getInsecureMessagesSentForThread(threadId); + count += SignalDatabase.mms().getInsecureMessagesSentForThread(threadId); return count; } public int getInsecureMessageCountForInsights() { - int count = DatabaseFactory.getSmsDatabase(context).getInsecureMessageCountForInsights(); - count += DatabaseFactory.getMmsDatabase(context).getInsecureMessageCountForInsights(); + int count = SignalDatabase.sms().getInsecureMessageCountForInsights(); + count += SignalDatabase.mms().getInsecureMessageCountForInsights(); return count; } @@ -344,8 +343,8 @@ public class MmsSmsDatabase extends Database { } public int getSecureMessageCountForInsights() { - int count = DatabaseFactory.getSmsDatabase(context).getSecureMessageCountForInsights(); - count += DatabaseFactory.getMmsDatabase(context).getSecureMessageCountForInsights(); + int count = SignalDatabase.sms().getSecureMessageCountForInsights(); + count += SignalDatabase.mms().getSecureMessageCountForInsights(); return count; } @@ -355,14 +354,14 @@ public class MmsSmsDatabase extends Database { return false; } - return DatabaseFactory.getSmsDatabase(context).hasMeaningfulMessage(threadId) || - DatabaseFactory.getMmsDatabase(context).hasMeaningfulMessage(threadId); + return SignalDatabase.sms().hasMeaningfulMessage(threadId) || + SignalDatabase.mms().hasMeaningfulMessage(threadId); } public long getThreadForMessageId(long messageId) { - long id = DatabaseFactory.getSmsDatabase(context).getThreadIdForMessage(messageId); + long id = SignalDatabase.sms().getThreadIdForMessage(messageId); - if (id == -1) return DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(messageId); + if (id == -1) return SignalDatabase.mms().getThreadIdForMessage(messageId); else return id; } @@ -403,7 +402,7 @@ public class MmsSmsDatabase extends Database { */ private boolean incrementReceiptCount(SyncMessageId syncMessageId, long timestamp, @NonNull MessageDatabase.ReceiptType receiptType) { SQLiteDatabase db = databaseHelper.getSignalWritableDatabase(); - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); + ThreadDatabase threadDatabase = SignalDatabase.threads(); Set threadUpdates = new HashSet<>(); db.beginTransaction(); @@ -437,7 +436,7 @@ public class MmsSmsDatabase extends Database { */ private @NonNull Collection incrementReceiptCounts(@NonNull List syncMessageIds, long timestamp, @NonNull MessageDatabase.ReceiptType receiptType) { SQLiteDatabase db = databaseHelper.getSignalWritableDatabase(); - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); + ThreadDatabase threadDatabase = SignalDatabase.threads(); Set threadUpdates = new HashSet<>(); Collection unhandled = new HashSet<>(); @@ -484,8 +483,8 @@ public class MmsSmsDatabase extends Database { private @NonNull Set incrementReceiptCountInternal(SyncMessageId syncMessageId, long timestamp, MessageDatabase.ReceiptType receiptType) { Set threadUpdates = new HashSet<>(); - threadUpdates.addAll(DatabaseFactory.getSmsDatabase(context).incrementReceiptCount(syncMessageId, timestamp, receiptType)); - threadUpdates.addAll(DatabaseFactory.getMmsDatabase(context).incrementReceiptCount(syncMessageId, timestamp, receiptType)); + threadUpdates.addAll(SignalDatabase.sms().incrementReceiptCount(syncMessageId, timestamp, receiptType)); + threadUpdates.addAll(SignalDatabase.mms().incrementReceiptCount(syncMessageId, timestamp, receiptType)); return threadUpdates; } @@ -538,7 +537,7 @@ public class MmsSmsDatabase extends Database { } boolean hasReceivedAnyCallsSince(long threadId, long timestamp) { - return DatabaseFactory.getSmsDatabase(context).hasReceivedAnyCallsSince(threadId, timestamp); + return SignalDatabase.sms().hasReceivedAnyCallsSince(threadId, timestamp); } /** @@ -576,27 +575,27 @@ public class MmsSmsDatabase extends Database { } public void setNotifiedTimestamp(long timestamp, @NonNull List smsIds, @NonNull List mmsIds) { - DatabaseFactory.getSmsDatabase(context).setNotifiedTimestamp(timestamp, smsIds); - DatabaseFactory.getMmsDatabase(context).setNotifiedTimestamp(timestamp, mmsIds); + SignalDatabase.sms().setNotifiedTimestamp(timestamp, smsIds); + SignalDatabase.mms().setNotifiedTimestamp(timestamp, mmsIds); } public int deleteMessagesInThreadBeforeDate(long threadId, long trimBeforeDate) { Log.d(TAG, "deleteMessagesInThreadBeforeData(" + threadId + ", " + trimBeforeDate + ")"); - int deletes = DatabaseFactory.getSmsDatabase(context).deleteMessagesInThreadBeforeDate(threadId, trimBeforeDate); - deletes += DatabaseFactory.getMmsDatabase(context).deleteMessagesInThreadBeforeDate(threadId, trimBeforeDate); + int deletes = SignalDatabase.sms().deleteMessagesInThreadBeforeDate(threadId, trimBeforeDate); + deletes += SignalDatabase.mms().deleteMessagesInThreadBeforeDate(threadId, trimBeforeDate); return deletes; } public void deleteAbandonedMessages() { Log.d(TAG, "deleteAbandonedMessages()"); - DatabaseFactory.getSmsDatabase(context).deleteAbandonedMessages(); - DatabaseFactory.getMmsDatabase(context).deleteAbandonedMessages(); + SignalDatabase.sms().deleteAbandonedMessages(); + SignalDatabase.mms().deleteAbandonedMessages(); } public @NonNull List getReportSpamMessageServerData(long threadId, long timestamp, int limit) { List data = new ArrayList<>(); - data.addAll(DatabaseFactory.getSmsDatabase(context).getReportSpamMessageServerGuids(threadId, timestamp)); - data.addAll(DatabaseFactory.getMmsDatabase(context).getReportSpamMessageServerGuids(threadId, timestamp)); + data.addAll(SignalDatabase.sms().getReportSpamMessageServerGuids(threadId, timestamp)); + data.addAll(SignalDatabase.mms().getReportSpamMessageServerGuids(threadId, timestamp)); return data.stream() .sorted((l, r) -> -Long.compare(l.getDateReceived(), r.getDateReceived())) .limit(limit) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/OneTimePreKeyDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/OneTimePreKeyDatabase.java index dc1ff884d1..1c84ca60a4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/OneTimePreKeyDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/OneTimePreKeyDatabase.java @@ -8,7 +8,6 @@ import android.database.Cursor; import androidx.annotation.Nullable; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.util.Base64; import org.whispersystems.libsignal.InvalidKeyException; import org.whispersystems.libsignal.ecc.Curve; @@ -35,7 +34,7 @@ public class OneTimePreKeyDatabase extends Database { PUBLIC_KEY + " TEXT NOT NULL, " + PRIVATE_KEY + " TEXT NOT NULL);"; - OneTimePreKeyDatabase(Context context, SQLCipherOpenHelper databaseHelper) { + OneTimePreKeyDatabase(Context context, SignalDatabase databaseHelper) { super(context, databaseHelper); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/PaymentDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/PaymentDatabase.java index 1335a10448..22555797d2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/PaymentDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/PaymentDatabase.java @@ -15,7 +15,6 @@ import com.google.protobuf.InvalidProtocolBufferException; import com.mobilecoin.lib.exceptions.SerializationException; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.database.model.databaseprotos.CryptoValue; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.payments.CryptoValueUtil; @@ -31,7 +30,6 @@ import org.thoughtcrime.securesms.util.Base64; import org.thoughtcrime.securesms.util.CursorUtil; import org.thoughtcrime.securesms.util.SqlUtil; import org.thoughtcrime.securesms.util.livedata.LiveDataUtil; -import org.whispersystems.signalservice.api.InvalidMessageStructureException; import org.whispersystems.signalservice.api.payments.Money; import java.util.Arrays; @@ -93,7 +91,7 @@ public final class PaymentDatabase extends Database { private final MutableLiveData changeSignal; - PaymentDatabase(@NonNull Context context, @NonNull SQLCipherOpenHelper databaseHelper) { + PaymentDatabase(@NonNull Context context, @NonNull SignalDatabase databaseHelper) { super(context, databaseHelper); this.changeSignal = new MutableLiveData<>(new Object()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/PendingRetryReceiptCache.kt b/app/src/main/java/org/thoughtcrime/securesms/database/PendingRetryReceiptCache.kt index 1b405d5c6d..5d0f37b638 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/PendingRetryReceiptCache.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/PendingRetryReceiptCache.kt @@ -17,7 +17,7 @@ import org.thoughtcrime.securesms.util.FeatureFlags class PendingRetryReceiptCache @VisibleForTesting constructor( private val database: PendingRetryReceiptDatabase ) { - constructor(context: Context) : this(DatabaseFactory.getPendingRetryReceiptDatabase(context)) + constructor(context: Context) : this(SignalDatabase.pendingRetryReceipts) private val pendingRetries: MutableMap = HashMap() private var populated: Boolean = false diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/PendingRetryReceiptDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/PendingRetryReceiptDatabase.java index 7ecbf14142..d19b7b6baa 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/PendingRetryReceiptDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/PendingRetryReceiptDatabase.java @@ -8,7 +8,6 @@ import androidx.annotation.NonNull; import net.zetetic.database.sqlcipher.SQLiteDatabase; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.database.model.PendingRetryReceiptModel; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.util.CursorUtil; @@ -41,7 +40,7 @@ public final class PendingRetryReceiptDatabase extends Database { THREAD_ID + " INTEGER NOT NULL, " + "UNIQUE(" + AUTHOR + "," + SENT_TIMESTAMP + ") ON CONFLICT REPLACE);"; - PendingRetryReceiptDatabase(Context context, SQLCipherOpenHelper databaseHelper) { + PendingRetryReceiptDatabase(Context context, SignalDatabase databaseHelper) { super(context, databaseHelper); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/PushDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/PushDatabase.java index a3d7bc07ab..196907eae7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/PushDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/PushDatabase.java @@ -6,8 +6,6 @@ import android.database.Cursor; import androidx.annotation.NonNull; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; - import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.util.Base64; import org.whispersystems.libsignal.util.guava.Optional; @@ -47,7 +45,7 @@ public class PushDatabase extends Database { SERVER_DELIVERED_TIMESTAMP + " INTEGER DEFAULT 0, " + SERVER_GUID + " TEXT DEFAULT NULL);"; - public PushDatabase(Context context, SQLCipherOpenHelper databaseHelper) { + public PushDatabase(Context context, SignalDatabase databaseHelper) { super(context, databaseHelper); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/ReactionDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/ReactionDatabase.kt index 75ce45a13b..6bc5ffff4f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/ReactionDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/ReactionDatabase.kt @@ -3,7 +3,6 @@ package org.thoughtcrime.securesms.database import android.content.ContentValues import android.content.Context import android.database.Cursor -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper import org.thoughtcrime.securesms.database.model.MessageId import org.thoughtcrime.securesms.database.model.ReactionRecord import org.thoughtcrime.securesms.dependencies.ApplicationDependencies @@ -14,7 +13,7 @@ import org.thoughtcrime.securesms.util.SqlUtil /** * Store reactions on messages. */ -class ReactionDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Database(context, databaseHelper) { +class ReactionDatabase(context: Context, databaseHelper: SignalDatabase) : Database(context, databaseHelper) { companion object { private const val TABLE_NAME = "reaction" @@ -132,9 +131,9 @@ class ReactionDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : db.insert(TABLE_NAME, null, values) if (messageId.mms) { - DatabaseFactory.getMmsDatabase(context).updateReactionsUnread(db, messageId.id, hasReactions(messageId), false) + SignalDatabase.mms.updateReactionsUnread(db, messageId.id, hasReactions(messageId), false) } else { - DatabaseFactory.getSmsDatabase(context).updateReactionsUnread(db, messageId.id, hasReactions(messageId), false) + SignalDatabase.sms.updateReactionsUnread(db, messageId.id, hasReactions(messageId), false) } db.setTransactionSuccessful() @@ -156,9 +155,9 @@ class ReactionDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : db.delete(TABLE_NAME, query, args) if (messageId.mms) { - DatabaseFactory.getMmsDatabase(context).updateReactionsUnread(db, messageId.id, hasReactions(messageId), true) + SignalDatabase.mms.updateReactionsUnread(db, messageId.id, hasReactions(messageId), true) } else { - DatabaseFactory.getSmsDatabase(context).updateReactionsUnread(db, messageId.id, hasReactions(messageId), true) + SignalDatabase.sms.updateReactionsUnread(db, messageId.id, hasReactions(messageId), true) } db.setTransactionSuccessful() diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java index 7981ac7bca..6e2bf9d362 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java @@ -32,7 +32,6 @@ import org.thoughtcrime.securesms.conversation.colors.ChatColorsMapper; import org.thoughtcrime.securesms.crypto.ProfileKeyUtil; import org.thoughtcrime.securesms.crypto.storage.TextSecureIdentityKeyStore; import org.thoughtcrime.securesms.database.IdentityDatabase.VerifiedStatus; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.whispersystems.signalservice.api.push.ACI; import org.thoughtcrime.securesms.database.model.IdentityRecord; @@ -66,7 +65,6 @@ import org.thoughtcrime.securesms.util.GroupUtil; import org.thoughtcrime.securesms.util.IdentityUtil; import org.thoughtcrime.securesms.util.SqlUtil; import org.thoughtcrime.securesms.util.StringUtil; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.Util; import org.thoughtcrime.securesms.wallpaper.ChatWallpaper; import org.thoughtcrime.securesms.wallpaper.ChatWallpaperFactory; @@ -98,7 +96,6 @@ import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Set; -import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.function.Function; @@ -393,7 +390,7 @@ public class RecipientDatabase extends Database { ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.DATE + " > ?" + " ORDER BY " + ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.DATE + " DESC LIMIT 50"; - public RecipientDatabase(Context context, SQLCipherOpenHelper databaseHelper) { + public RecipientDatabase(Context context, SignalDatabase databaseHelper) { super(context, databaseHelper); } @@ -626,9 +623,9 @@ public class RecipientDatabase extends Database { if (existing.isPresent()) { return existing.get(); - } else if (groupId.isV1() && DatabaseFactory.getGroupDatabase(context).groupExists(groupId.requireV1().deriveV2MigrationGroupId())) { + } else if (groupId.isV1() && SignalDatabase.groups().groupExists(groupId.requireV1().deriveV2MigrationGroupId())) { throw new GroupDatabase.LegacyGroupInsertException(groupId); - } else if (groupId.isV2() && DatabaseFactory.getGroupDatabase(context).getGroupV1ByExpectedV2(groupId.requireV2()).isPresent()) { + } else if (groupId.isV2() && SignalDatabase.groups().getGroupV1ByExpectedV2(groupId.requireV2()).isPresent()) { throw new GroupDatabase.MissedGroupMigrationInsertException(groupId); } else { ContentValues values = new ContentValues(); @@ -642,9 +639,9 @@ public class RecipientDatabase extends Database { if (existing.isPresent()) { return existing.get(); - } else if (groupId.isV1() && DatabaseFactory.getGroupDatabase(context).groupExists(groupId.requireV1().deriveV2MigrationGroupId())) { + } else if (groupId.isV1() && SignalDatabase.groups().groupExists(groupId.requireV1().deriveV2MigrationGroupId())) { throw new GroupDatabase.LegacyGroupInsertException(groupId); - } else if (groupId.isV2() && DatabaseFactory.getGroupDatabase(context).getGroupV1ByExpectedV2(groupId.requireV2()).isPresent()) { + } else if (groupId.isV2() && SignalDatabase.groups().getGroupV1ByExpectedV2(groupId.requireV2()).isPresent()) { throw new GroupDatabase.MissedGroupMigrationInsertException(groupId); } else { throw new AssertionError("Failed to insert recipient!"); @@ -696,7 +693,7 @@ public class RecipientDatabase extends Database { } if (groupId.isV2()) { - Optional v1 = DatabaseFactory.getGroupDatabase(context).getGroupV1ByExpectedV2(groupId.requireV2()); + Optional v1 = SignalDatabase.groups().getGroupV1ByExpectedV2(groupId.requireV2()); if (v1.isPresent()) { db.setTransactionSuccessful(); return v1.get().getRecipientId(); @@ -740,7 +737,7 @@ public class RecipientDatabase extends Database { if (cursor != null && cursor.moveToNext()) { return getRecipientSettings(context, cursor); } else { - Optional remapped = RemappedRecords.getInstance().getRecipient(context, id); + Optional remapped = RemappedRecords.getInstance().getRecipient(id); if (remapped.isPresent()) { Log.w(TAG, "Missing recipient for " + id + ", but found it in the remapped records as " + remapped.get()); return getRecipientSettings(remapped.get()); @@ -822,7 +819,7 @@ public class RecipientDatabase extends Database { public void applyStorageSyncContactInsert(@NonNull SignalContactRecord insert) { SQLiteDatabase db = databaseHelper.getSignalWritableDatabase(); - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); + ThreadDatabase threadDatabase = SignalDatabase.threads(); ContentValues values = getValuesForStorageContact(insert, true); long id = db.insertWithOnConflict(TABLE_NAME, null, values, SQLiteDatabase.CONFLICT_IGNORE); @@ -840,7 +837,7 @@ public class RecipientDatabase extends Database { try { IdentityKey identityKey = new IdentityKey(insert.getIdentityKey().get(), 0); - DatabaseFactory.getIdentityDatabase(context).updateIdentityAfterSync(insert.getAddress().getIdentifier(), recipientId, identityKey, StorageSyncModels.remoteToLocalIdentityStatus(insert.getIdentityState())); + SignalDatabase.identities().updateIdentityAfterSync(insert.getAddress().getIdentifier(), recipientId, identityKey, StorageSyncModels.remoteToLocalIdentityStatus(insert.getIdentityState())); } catch (InvalidKeyException e) { Log.w(TAG, "Failed to process identity key during insert! Skipping.", e); } @@ -884,7 +881,7 @@ public class RecipientDatabase extends Database { if (update.getNew().getIdentityKey().isPresent() && update.getNew().getAddress().hasValidAci()) { IdentityKey identityKey = new IdentityKey(update.getNew().getIdentityKey().get(), 0); - DatabaseFactory.getIdentityDatabase(context).updateIdentityAfterSync(update.getNew().getAddress().getIdentifier(), recipientId, identityKey, StorageSyncModels.remoteToLocalIdentityStatus(update.getNew().getIdentityState())); + SignalDatabase.identities().updateIdentityAfterSync(update.getNew().getAddress().getIdentifier(), recipientId, identityKey, StorageSyncModels.remoteToLocalIdentityStatus(update.getNew().getIdentityState())); } Optional newIdentityRecord = identityStore.getIdentityRecord(recipientId); @@ -902,7 +899,7 @@ public class RecipientDatabase extends Database { Log.w(TAG, "Failed to process identity key during update! Skipping.", e); } - DatabaseFactory.getThreadDatabase(context).applyStorageSyncUpdate(recipientId, update.getNew()); + SignalDatabase.threads().applyStorageSyncUpdate(recipientId, update.getNew()); Recipient.live(recipientId).refresh(); } @@ -913,7 +910,7 @@ public class RecipientDatabase extends Database { long id = db.insertOrThrow(TABLE_NAME, null, getValuesForStorageGroupV1(insert, true)); RecipientId recipientId = RecipientId.from(id); - DatabaseFactory.getThreadDatabase(context).applyStorageSyncUpdate(recipientId, insert); + SignalDatabase.threads().applyStorageSyncUpdate(recipientId, insert); Recipient.live(recipientId).refresh(); } @@ -930,7 +927,7 @@ public class RecipientDatabase extends Database { Recipient recipient = Recipient.externalGroupExact(context, GroupId.v1orThrow(update.getOld().getGroupId())); - DatabaseFactory.getThreadDatabase(context).applyStorageSyncUpdate(recipient.getId(), update.getNew()); + SignalDatabase.threads().applyStorageSyncUpdate(recipient.getId(), update.getNew()); recipient.live().refresh(); } @@ -945,17 +942,17 @@ public class RecipientDatabase extends Database { Recipient recipient = Recipient.externalGroupExact(context, groupId); Log.i(TAG, "Creating restore placeholder for " + groupId); - DatabaseFactory.getGroupDatabase(context) - .create(masterKey, - DecryptedGroup.newBuilder() - .setRevision(GroupsV2StateProcessor.RESTORE_PLACEHOLDER_REVISION) - .build()); + SignalDatabase.groups() + .create(masterKey, + DecryptedGroup.newBuilder() + .setRevision(GroupsV2StateProcessor.RESTORE_PLACEHOLDER_REVISION) + .build()); Log.i(TAG, "Scheduling request for latest group info for " + groupId); ApplicationDependencies.getJobManager().add(new RequestGroupV2InfoJob(groupId)); - DatabaseFactory.getThreadDatabase(context).applyStorageSyncUpdate(recipient.getId(), insert); + SignalDatabase.threads().applyStorageSyncUpdate(recipient.getId(), insert); recipient.live().refresh(); } @@ -973,7 +970,7 @@ public class RecipientDatabase extends Database { GroupMasterKey masterKey = update.getOld().getMasterKeyOrThrow(); Recipient recipient = Recipient.externalGroupExact(context, GroupId.v2(masterKey)); - DatabaseFactory.getThreadDatabase(context).applyStorageSyncUpdate(recipient.getId(), update.getNew()); + SignalDatabase.threads().applyStorageSyncUpdate(recipient.getId(), update.getNew()); recipient.live().refresh(); } @@ -1012,7 +1009,7 @@ public class RecipientDatabase extends Database { ApplicationDependencies.getJobManager().add(new RefreshAttributesJob()); } - DatabaseFactory.getThreadDatabase(context).applyStorageSyncUpdate(Recipient.self().getId(), update.getNew()); + SignalDatabase.threads().applyStorageSyncUpdate(Recipient.self().getId(), update.getNew()); Recipient.self().live().refresh(); } @@ -1189,7 +1186,7 @@ public class RecipientDatabase extends Database { } } - for (GroupId.V2 id : DatabaseFactory.getGroupDatabase(context).getAllGroupV2Ids()) { + for (GroupId.V2 id : SignalDatabase.groups().getAllGroupV2Ids()) { Recipient recipient = Recipient.externalGroupExact(context, id); RecipientId recipientId = recipient.getId(); RecipientSettings recipientSettingsForSync = getRecipientSettingsForSync(recipientId); @@ -1947,7 +1944,7 @@ public class RecipientDatabase extends Database { boolean profiledUpdated = update(id, contentValues); if (profiledUpdated && enabled) { - Optional group = DatabaseFactory.getGroupDatabase(context).getGroup(id); + Optional group = SignalDatabase.groups().getGroup(id); if (group.isPresent()) { setHasGroupsInCommon(group.get().getMembers()); @@ -2687,7 +2684,7 @@ public class RecipientDatabase extends Database { * @param limit Only return at most this many contact. */ public List getRecipientsForRoutineProfileFetch(long lastInteractionThreshold, long lastProfileFetchThreshold, int limit) { - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); + ThreadDatabase threadDatabase = SignalDatabase.threads(); Set recipientsWithinInteractionThreshold = new LinkedHashSet<>(); try (ThreadDatabase.Reader reader = threadDatabase.readerFor(threadDatabase.getRecentPushConversationList(-1, false))) { @@ -3029,7 +3026,7 @@ public class RecipientDatabase extends Database { db.update(GroupReceiptDatabase.TABLE_NAME, groupReceiptValues, GroupReceiptDatabase.RECIPIENT_ID + " = ?", SqlUtil.buildArgs(byE164)); // Groups - GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); + GroupDatabase groupDatabase = SignalDatabase.groups(); for (GroupDatabase.GroupRecord group : groupDatabase.getGroupsContainingMember(byE164, false, true)) { LinkedHashSet newMembers = new LinkedHashSet<>(group.getMembers()); newMembers.remove(byE164); @@ -3045,7 +3042,7 @@ public class RecipientDatabase extends Database { } // Threads - ThreadDatabase.MergeResult threadMerge = DatabaseFactory.getThreadDatabase(context).merge(byUuid, byE164); + ThreadDatabase.MergeResult threadMerge = SignalDatabase.threads().merge(byUuid, byE164); // SMS Messages ContentValues smsValues = new ContentValues(); @@ -3070,7 +3067,7 @@ public class RecipientDatabase extends Database { } // Sessions - SessionDatabase sessionDatabase = DatabaseFactory.getSessionDatabase(context); + SessionDatabase sessionDatabase = SignalDatabase.sessions(); boolean hasE164Session = sessionDatabase.getAllFor(e164Settings.e164).size() > 0; boolean hasUuidSession = sessionDatabase.getAllFor(uuidSettings.aci.toString()).size() > 0; @@ -3090,7 +3087,7 @@ public class RecipientDatabase extends Database { } // MSL - DatabaseFactory.getMessageLogDatabase(context).remapRecipient(byE164, byUuid); + SignalDatabase.messageLog().remapRecipient(byE164, byUuid); // Mentions ContentValues mentionRecipientValues = new ContentValues(); @@ -3102,16 +3099,16 @@ public class RecipientDatabase extends Database { db.update(MentionDatabase.TABLE_NAME, mentionThreadValues, MentionDatabase.THREAD_ID + " = ?", SqlUtil.buildArgs(threadMerge.previousThreadId)); } - DatabaseFactory.getThreadDatabase(context).setLastScrolled(threadMerge.threadId, 0); - DatabaseFactory.getThreadDatabase(context).update(threadMerge.threadId, false, false); + SignalDatabase.threads().setLastScrolled(threadMerge.threadId, 0); + SignalDatabase.threads().update(threadMerge.threadId, false, false); // Reactions - DatabaseFactory.getReactionDatabase(context).remapRecipient(byE164, byUuid); + SignalDatabase.reactions().remapRecipient(byE164, byUuid); // Recipient Log.w(TAG, "Deleting recipient " + byE164, true); db.delete(TABLE_NAME, ID_WHERE, SqlUtil.buildArgs(byE164)); - RemappedRecords.getInstance().addRecipient(context, byE164, byUuid); + RemappedRecords.getInstance().addRecipient(byE164, byUuid); ContentValues uuidValues = new ContentValues(); uuidValues.put(PHONE, e164Settings.getE164()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/RemappedRecords.java b/app/src/main/java/org/thoughtcrime/securesms/database/RemappedRecords.java index c19a54e0d1..bbb120f87b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/RemappedRecords.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/RemappedRecords.java @@ -40,23 +40,23 @@ class RemappedRecords { return INSTANCE; } - @NonNull Optional getRecipient(@NonNull Context context, @NonNull RecipientId oldId) { - ensureRecipientMapIsPopulated(context); + @NonNull Optional getRecipient(@NonNull RecipientId oldId) { + ensureRecipientMapIsPopulated(); return Optional.fromNullable(recipientMap.get(oldId)); } - @NonNull Optional getThread(@NonNull Context context, long oldId) { - ensureThreadMapIsPopulated(context); + @NonNull Optional getThread(long oldId) { + ensureThreadMapIsPopulated(); return Optional.fromNullable(threadMap.get(oldId)); } - boolean areAnyRemapped(@NonNull Context context, @NonNull Collection recipientIds) { - ensureRecipientMapIsPopulated(context); + boolean areAnyRemapped(@NonNull Collection recipientIds) { + ensureRecipientMapIsPopulated(); return recipientIds.stream().anyMatch(id -> recipientMap.containsKey(id)); } - @NonNull Set remap(@NonNull Context context, @NonNull Collection recipientIds) { - ensureRecipientMapIsPopulated(context); + @NonNull Set remap(@NonNull Collection recipientIds) { + ensureRecipientMapIsPopulated(); Set remapped = new LinkedHashSet<>(); @@ -71,7 +71,7 @@ class RemappedRecords { return remapped; } - @NonNull String buildRemapDescription(@NonNull Context context, @NonNull Collection recipientIds) { + @NonNull String buildRemapDescription(@NonNull Collection recipientIds) { StringBuilder builder = new StringBuilder(); for (RecipientId original : recipientIds) { @@ -86,39 +86,39 @@ class RemappedRecords { /** * Can only be called inside of a transaction. */ - void addRecipient(@NonNull Context context, @NonNull RecipientId oldId, @NonNull RecipientId newId) { + void addRecipient(@NonNull RecipientId oldId, @NonNull RecipientId newId) { Log.w(TAG, "[Recipient] Remapping " + oldId + " to " + newId); - ensureInTransaction(context); - ensureRecipientMapIsPopulated(context); + ensureInTransaction(); + ensureRecipientMapIsPopulated(); recipientMap.put(oldId, newId); - DatabaseFactory.getRemappedRecordsDatabase(context).addRecipientMapping(oldId, newId); + SignalDatabase.remappedRecords().addRecipientMapping(oldId, newId); } /** * Can only be called inside of a transaction. */ - void addThread(@NonNull Context context, long oldId, long newId) { + void addThread(long oldId, long newId) { Log.w(TAG, "[Thread] Remapping " + oldId + " to " + newId); - ensureInTransaction(context); - ensureThreadMapIsPopulated(context); + ensureInTransaction(); + ensureThreadMapIsPopulated(); threadMap.put(oldId, newId); - DatabaseFactory.getRemappedRecordsDatabase(context).addThreadMapping(oldId, newId); + SignalDatabase.remappedRecords().addThreadMapping(oldId, newId); } - private void ensureRecipientMapIsPopulated(@NonNull Context context) { + private void ensureRecipientMapIsPopulated() { if (recipientMap == null) { - recipientMap = DatabaseFactory.getRemappedRecordsDatabase(context).getAllRecipientMappings(); + recipientMap = SignalDatabase.remappedRecords().getAllRecipientMappings(); } } - private void ensureThreadMapIsPopulated(@NonNull Context context) { + private void ensureThreadMapIsPopulated() { if (threadMap == null) { - threadMap = DatabaseFactory.getRemappedRecordsDatabase(context).getAllThreadMappings(); + threadMap = SignalDatabase.remappedRecords().getAllThreadMappings(); } } - private void ensureInTransaction(@NonNull Context context) { - if (!DatabaseFactory.inTransaction(context)) { + private void ensureInTransaction() { + if (!SignalDatabase.inTransaction()) { throw new IllegalStateException("Must be in a transaction!"); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/RemappedRecordsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/RemappedRecordsDatabase.java index b3d5efba52..4a86cdd654 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/RemappedRecordsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/RemappedRecordsDatabase.java @@ -6,7 +6,6 @@ import android.database.Cursor; import androidx.annotation.NonNull; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.util.CursorUtil; @@ -43,7 +42,7 @@ public class RemappedRecordsDatabase extends Database { NEW_ID + " INTEGER)"; } - RemappedRecordsDatabase(Context context, SQLCipherOpenHelper databaseHelper) { + RemappedRecordsDatabase(Context context, SignalDatabase databaseHelper) { super(context, databaseHelper); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SearchDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/SearchDatabase.java index 4401f407d0..a8b427cd2b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SearchDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SearchDatabase.java @@ -8,8 +8,6 @@ import androidx.annotation.NonNull; import com.annimon.stream.Stream; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; - /** * Contains all databases necessary for full-text search (FTS). */ @@ -120,7 +118,7 @@ public class SearchDatabase extends Database { "ORDER BY " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " DESC " + "LIMIT 500"; - public SearchDatabase(@NonNull Context context, @NonNull SQLCipherOpenHelper databaseHelper) { + public SearchDatabase(@NonNull Context context, @NonNull SignalDatabase databaseHelper) { super(context, databaseHelper); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SenderKeyDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/SenderKeyDatabase.java index 6d73189ec0..d58fe373b1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SenderKeyDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SenderKeyDatabase.java @@ -9,14 +9,12 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.recipients.Recipient; import org.whispersystems.libsignal.SignalProtocolAddress; import org.whispersystems.signalservice.api.push.DistributionId; import org.thoughtcrime.securesms.util.CursorUtil; import org.thoughtcrime.securesms.util.SqlUtil; import org.whispersystems.libsignal.groups.state.SenderKeyRecord; -import org.whispersystems.signalservice.api.push.SignalServiceAddress; import java.io.IOException; @@ -47,7 +45,7 @@ public class SenderKeyDatabase extends Database { CREATED_AT + " INTEGER NOT NULL, " + "UNIQUE(" + ADDRESS + "," + DEVICE + ", " + DISTRIBUTION_ID + ") ON CONFLICT REPLACE);"; - SenderKeyDatabase(Context context, SQLCipherOpenHelper databaseHelper) { + SenderKeyDatabase(Context context, SignalDatabase databaseHelper) { super(context, databaseHelper); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SenderKeySharedDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/SenderKeySharedDatabase.java index 768726dd59..7a995f7b1c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SenderKeySharedDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SenderKeySharedDatabase.java @@ -8,7 +8,6 @@ import android.database.Cursor; import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.recipients.Recipient; import org.whispersystems.libsignal.SignalProtocolAddress; import org.whispersystems.signalservice.api.push.DistributionId; @@ -43,7 +42,7 @@ public class SenderKeySharedDatabase extends Database { TIMESTAMP + " INTEGER DEFAULT 0, " + "UNIQUE(" + DISTRIBUTION_ID + "," + ADDRESS + ", " + DEVICE + ") ON CONFLICT REPLACE);"; - SenderKeySharedDatabase(Context context, SQLCipherOpenHelper databaseHelper) { + SenderKeySharedDatabase(Context context, SignalDatabase databaseHelper) { super(context, databaseHelper); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SessionDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/SessionDatabase.java index 9395e2052c..4e49b67c58 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SessionDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SessionDatabase.java @@ -9,8 +9,6 @@ import androidx.annotation.Nullable; import net.zetetic.database.sqlcipher.SQLiteStatement; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; - import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.util.CursorUtil; import org.thoughtcrime.securesms.util.SqlUtil; @@ -42,7 +40,7 @@ public class SessionDatabase extends Database { RECORD + " BLOB NOT NULL, " + "UNIQUE(" + ADDRESS + "," + DEVICE + "));"; - SessionDatabase(Context context, SQLCipherOpenHelper databaseHelper) { + SessionDatabase(Context context, SignalDatabase databaseHelper) { super(context, databaseHelper); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SignalDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/SignalDatabase.kt new file mode 100644 index 0000000000..6b05499dc2 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SignalDatabase.kt @@ -0,0 +1,439 @@ +package org.thoughtcrime.securesms.database + +import android.app.Application +import android.content.Context +import net.zetetic.database.sqlcipher.SQLiteOpenHelper +import org.signal.core.util.logging.Log +import org.thoughtcrime.securesms.contacts.ContactsDatabase +import org.thoughtcrime.securesms.crypto.AttachmentSecret +import org.thoughtcrime.securesms.crypto.DatabaseSecret +import org.thoughtcrime.securesms.crypto.MasterSecret +import org.thoughtcrime.securesms.database.helpers.ClassicOpenHelper +import org.thoughtcrime.securesms.database.helpers.PreKeyMigrationHelper +import org.thoughtcrime.securesms.database.helpers.SQLCipherMigrationHelper +import org.thoughtcrime.securesms.database.helpers.SessionStoreMigrationHelper +import org.thoughtcrime.securesms.database.helpers.SignalDatabaseMigrations +import org.thoughtcrime.securesms.database.helpers.SignalDatabaseMigrations.migrate +import org.thoughtcrime.securesms.database.helpers.SignalDatabaseMigrations.migratePostTransaction +import org.thoughtcrime.securesms.database.model.AvatarPickerDatabase +import org.thoughtcrime.securesms.dependencies.ApplicationDependencies +import org.thoughtcrime.securesms.jobs.RefreshPreKeysJob +import org.thoughtcrime.securesms.migrations.LegacyMigrationJob +import org.thoughtcrime.securesms.migrations.LegacyMigrationJob.DatabaseUpgradeListener +import org.thoughtcrime.securesms.service.KeyCachingService +import org.thoughtcrime.securesms.util.SqlUtil +import org.thoughtcrime.securesms.util.TextSecurePreferences +import java.io.File +import java.lang.UnsupportedOperationException + +open class SignalDatabase(private val context: Application, databaseSecret: DatabaseSecret, attachmentSecret: AttachmentSecret) : + SQLiteOpenHelper( + context, + DATABASE_NAME, + databaseSecret.asString(), + null, + SignalDatabaseMigrations.DATABASE_VERSION, + 0, + SqlCipherErrorHandler(DATABASE_NAME), + SqlCipherDatabaseHook() + ), + SignalDatabaseOpenHelper { + + val sms: SmsDatabase = SmsDatabase(context, this) + val mms: MmsDatabase = MmsDatabase(context, this) + val attachments: AttachmentDatabase = AttachmentDatabase(context, this, attachmentSecret) + val media: MediaDatabase = MediaDatabase(context, this) + val thread: ThreadDatabase = ThreadDatabase(context, this) + val mmsSmsDatabase: MmsSmsDatabase = MmsSmsDatabase(context, this) + val identityDatabase: IdentityDatabase = IdentityDatabase(context, this) + val draftDatabase: DraftDatabase = DraftDatabase(context, this) + val pushDatabase: PushDatabase = PushDatabase(context, this) + val groupDatabase: GroupDatabase = GroupDatabase(context, this) + val recipientDatabase: RecipientDatabase = RecipientDatabase(context, this) + val contactsDatabase: ContactsDatabase = ContactsDatabase(context) + val groupReceiptDatabase: GroupReceiptDatabase = GroupReceiptDatabase(context, this) + val preKeyDatabase: OneTimePreKeyDatabase = OneTimePreKeyDatabase(context, this) + val signedPreKeyDatabase: SignedPreKeyDatabase = SignedPreKeyDatabase(context, this) + val sessionDatabase: SessionDatabase = SessionDatabase(context, this) + val senderKeyDatabase: SenderKeyDatabase = SenderKeyDatabase(context, this) + val senderKeySharedDatabase: SenderKeySharedDatabase = SenderKeySharedDatabase(context, this) + val pendingRetryReceiptDatabase: PendingRetryReceiptDatabase = PendingRetryReceiptDatabase(context, this) + val searchDatabase: SearchDatabase = SearchDatabase(context, this) + val stickerDatabase: StickerDatabase = StickerDatabase(context, this, attachmentSecret) + val storageIdDatabase: UnknownStorageIdDatabase = UnknownStorageIdDatabase(context, this) + val remappedRecordsDatabase: RemappedRecordsDatabase = RemappedRecordsDatabase(context, this) + val mentionDatabase: MentionDatabase = MentionDatabase(context, this) + val paymentDatabase: PaymentDatabase = PaymentDatabase(context, this) + val chatColorsDatabase: ChatColorsDatabase = ChatColorsDatabase(context, this) + val emojiSearchDatabase: EmojiSearchDatabase = EmojiSearchDatabase(context, this) + val messageSendLogDatabase: MessageSendLogDatabase = MessageSendLogDatabase(context, this) + val avatarPickerDatabase: AvatarPickerDatabase = AvatarPickerDatabase(context, this) + val groupCallRingDatabase: GroupCallRingDatabase = GroupCallRingDatabase(context, this) + val reactionDatabase: ReactionDatabase = ReactionDatabase(context, this) + + override fun onOpen(db: net.zetetic.database.sqlcipher.SQLiteDatabase) { + db.enableWriteAheadLogging() + db.setForeignKeyConstraintsEnabled(true) + } + + override fun onCreate(db: net.zetetic.database.sqlcipher.SQLiteDatabase) { + db.execSQL(SmsDatabase.CREATE_TABLE) + db.execSQL(MmsDatabase.CREATE_TABLE) + db.execSQL(AttachmentDatabase.CREATE_TABLE) + db.execSQL(ThreadDatabase.CREATE_TABLE) + db.execSQL(IdentityDatabase.CREATE_TABLE) + db.execSQL(DraftDatabase.CREATE_TABLE) + db.execSQL(PushDatabase.CREATE_TABLE) + db.execSQL(GroupDatabase.CREATE_TABLE) + db.execSQL(RecipientDatabase.CREATE_TABLE) + db.execSQL(GroupReceiptDatabase.CREATE_TABLE) + db.execSQL(OneTimePreKeyDatabase.CREATE_TABLE) + db.execSQL(SignedPreKeyDatabase.CREATE_TABLE) + db.execSQL(SessionDatabase.CREATE_TABLE) + db.execSQL(SenderKeyDatabase.CREATE_TABLE) + db.execSQL(SenderKeySharedDatabase.CREATE_TABLE) + db.execSQL(PendingRetryReceiptDatabase.CREATE_TABLE) + db.execSQL(StickerDatabase.CREATE_TABLE) + db.execSQL(UnknownStorageIdDatabase.CREATE_TABLE) + db.execSQL(MentionDatabase.CREATE_TABLE) + db.execSQL(PaymentDatabase.CREATE_TABLE) + db.execSQL(ChatColorsDatabase.CREATE_TABLE) + db.execSQL(EmojiSearchDatabase.CREATE_TABLE) + db.execSQL(AvatarPickerDatabase.CREATE_TABLE) + db.execSQL(GroupCallRingDatabase.CREATE_TABLE) + db.execSQL(ReactionDatabase.CREATE_TABLE) + executeStatements(db, SearchDatabase.CREATE_TABLE) + executeStatements(db, RemappedRecordsDatabase.CREATE_TABLE) + executeStatements(db, MessageSendLogDatabase.CREATE_TABLE) + executeStatements(db, RecipientDatabase.CREATE_INDEXS) + executeStatements(db, SmsDatabase.CREATE_INDEXS) + executeStatements(db, MmsDatabase.CREATE_INDEXS) + executeStatements(db, AttachmentDatabase.CREATE_INDEXS) + executeStatements(db, ThreadDatabase.CREATE_INDEXS) + executeStatements(db, DraftDatabase.CREATE_INDEXS) + executeStatements(db, GroupDatabase.CREATE_INDEXS) + executeStatements(db, GroupReceiptDatabase.CREATE_INDEXES) + executeStatements(db, StickerDatabase.CREATE_INDEXES) + executeStatements(db, UnknownStorageIdDatabase.CREATE_INDEXES) + executeStatements(db, MentionDatabase.CREATE_INDEXES) + executeStatements(db, PaymentDatabase.CREATE_INDEXES) + executeStatements(db, MessageSendLogDatabase.CREATE_INDEXES) + executeStatements(db, GroupCallRingDatabase.CREATE_INDEXES) + executeStatements(db, MessageSendLogDatabase.CREATE_TRIGGERS) + executeStatements(db, ReactionDatabase.CREATE_TRIGGERS) + if (context.getDatabasePath(ClassicOpenHelper.NAME).exists()) { + val legacyHelper = ClassicOpenHelper(context) + val legacyDb = legacyHelper.writableDatabase + SQLCipherMigrationHelper.migratePlaintext(context, legacyDb, db) + val masterSecret = KeyCachingService.getMasterSecret(context) + if (masterSecret != null) SQLCipherMigrationHelper.migrateCiphertext(context, masterSecret, legacyDb, db, null) else TextSecurePreferences.setNeedsSqlCipherMigration(context, true) + if (!PreKeyMigrationHelper.migratePreKeys(context, db)) { + ApplicationDependencies.getJobManager().add(RefreshPreKeysJob()) + } + SessionStoreMigrationHelper.migrateSessions(context, db) + PreKeyMigrationHelper.cleanUpPreKeys(context) + } + } + + override fun onUpgrade(db: net.zetetic.database.sqlcipher.SQLiteDatabase, oldVersion: Int, newVersion: Int) { + Log.i(TAG, "Upgrading database: $oldVersion, $newVersion") + val startTime = System.currentTimeMillis() + db.beginTransaction() + try { + migrate(context, db, oldVersion, newVersion) + db.setTransactionSuccessful() + } finally { + db.endTransaction() + } + migratePostTransaction(context, oldVersion) + Log.i(TAG, "Upgrade complete. Took " + (System.currentTimeMillis() - startTime) + " ms.") + } + + override fun getReadableDatabase(): net.zetetic.database.sqlcipher.SQLiteDatabase { + throw UnsupportedOperationException("Call getSignalReadableDatabase() instead!") + } + + override fun getWritableDatabase(): net.zetetic.database.sqlcipher.SQLiteDatabase { + throw UnsupportedOperationException("Call getSignalWritableDatabase() instead!") + } + + open val rawReadableDatabase: net.zetetic.database.sqlcipher.SQLiteDatabase + get() = super.getReadableDatabase() + + open val rawWritableDatabase: net.zetetic.database.sqlcipher.SQLiteDatabase + get() = super.getWritableDatabase() + + open val signalReadableDatabase: SQLiteDatabase + get() = SQLiteDatabase(super.getReadableDatabase()) + + open val signalWritableDatabase: SQLiteDatabase + get() = SQLiteDatabase(super.getWritableDatabase()) + + override fun getSqlCipherDatabase(): net.zetetic.database.sqlcipher.SQLiteDatabase { + return super.getWritableDatabase() + } + + open fun markCurrent(db: net.zetetic.database.sqlcipher.SQLiteDatabase) { + db.version = SignalDatabaseMigrations.DATABASE_VERSION + } + + private fun executeStatements(db: net.zetetic.database.sqlcipher.SQLiteDatabase, statements: Array) { + for (statement in statements) db.execSQL(statement) + } + + companion object { + private val TAG = Log.tag(SignalDatabase::class.java) + private const val DATABASE_NAME = "signal.db" + + @JvmStatic + @Volatile + var instance: SignalDatabase? = null + private set + + @JvmStatic + fun init(application: Application, databaseSecret: DatabaseSecret, attachmentSecret: AttachmentSecret) { + if (instance == null) { + synchronized(SignalDatabase::class.java) { + if (instance == null) { + instance = SignalDatabase(application, databaseSecret, attachmentSecret) + } + } + } + } + + @JvmStatic + val rawDatabase: net.zetetic.database.sqlcipher.SQLiteDatabase + get() = instance!!.rawWritableDatabase + + @JvmStatic + val backupDatabase: net.zetetic.database.sqlcipher.SQLiteDatabase + get() = instance!!.rawReadableDatabase + + @JvmStatic + @get:JvmName("inTransaction") + val inTransaction: Boolean + get() = instance!!.rawWritableDatabase.inTransaction() + + @JvmStatic + fun databaseFileExists(context: Context): Boolean { + return context.getDatabasePath(DATABASE_NAME).exists() + } + + @JvmStatic + fun getDatabaseFile(context: Context): File { + return context.getDatabasePath(DATABASE_NAME) + } + + @JvmStatic + fun upgradeRestored(database: net.zetetic.database.sqlcipher.SQLiteDatabase) { + synchronized(SignalDatabase::class.java) { + instance!!.onUpgrade(database, database.getVersion(), -1) + instance!!.markCurrent(database) + instance!!.sms.deleteAbandonedMessages() + instance!!.mms.deleteAbandonedMessages() + instance!!.mms.trimEntriesForExpiredMessages() + instance!!.rawWritableDatabase.execSQL("DROP TABLE IF EXISTS key_value") + instance!!.rawWritableDatabase.execSQL("DROP TABLE IF EXISTS megaphone") + instance!!.rawWritableDatabase.execSQL("DROP TABLE IF EXISTS job_spec") + instance!!.rawWritableDatabase.execSQL("DROP TABLE IF EXISTS constraint_spec") + instance!!.rawWritableDatabase.execSQL("DROP TABLE IF EXISTS dependency_spec") + } + } + + @JvmStatic + fun hasTable(table: String): Boolean { + return SqlUtil.tableExists(instance!!.rawReadableDatabase, table) + } + + @JvmStatic + fun triggerDatabaseAccess() { + instance!!.signalWritableDatabase + } + + @Deprecated("Only used for a legacy migration.") + @JvmStatic + fun onApplicationLevelUpgrade( + context: Context, + masterSecret: MasterSecret, + fromVersion: Int, + listener: DatabaseUpgradeListener? + ) { + instance!!.signalWritableDatabase + var legacyOpenHelper: ClassicOpenHelper? = null + if (fromVersion < LegacyMigrationJob.ASYMMETRIC_MASTER_SECRET_FIX_VERSION) { + legacyOpenHelper = ClassicOpenHelper(context) + legacyOpenHelper.onApplicationLevelUpgrade(context, masterSecret, fromVersion, listener) + } + + if (fromVersion < LegacyMigrationJob.SQLCIPHER && TextSecurePreferences.getNeedsSqlCipherMigration(context)) { + if (legacyOpenHelper == null) { + legacyOpenHelper = ClassicOpenHelper(context) + } + + SQLCipherMigrationHelper.migrateCiphertext( + context, + masterSecret, + legacyOpenHelper.writableDatabase, + instance!!.rawWritableDatabase, + listener + ) + } + } + + @get:JvmStatic + @get:JvmName("attachments") + val attachments: AttachmentDatabase + get() = instance!!.attachments + + @get:JvmStatic + @get:JvmName("avatarPicker") + val avatarPicker: AvatarPickerDatabase + get() = instance!!.avatarPickerDatabase + + @get:JvmStatic + @get:JvmName("chatColors") + val chatColors: ChatColorsDatabase + get() = instance!!.chatColorsDatabase + + @get:JvmStatic + @get:JvmName("contacts") + val contacts: ContactsDatabase + get() = instance!!.contactsDatabase + + @get:JvmStatic + @get:JvmName("drafts") + val drafts: DraftDatabase + get() = instance!!.draftDatabase + + @get:JvmStatic + @get:JvmName("emojiSearch") + val emojiSearch: EmojiSearchDatabase + get() = instance!!.emojiSearchDatabase + + @get:JvmStatic + @get:JvmName("groupCallRings") + val groupCallRings: GroupCallRingDatabase + get() = instance!!.groupCallRingDatabase + + @get:JvmStatic + @get:JvmName("groupReceipts") + val groupReceipts: GroupReceiptDatabase + get() = instance!!.groupReceiptDatabase + + @get:JvmStatic + @get:JvmName("groups") + val groups: GroupDatabase + get() = instance!!.groupDatabase + + @get:JvmStatic + @get:JvmName("identities") + val identities: IdentityDatabase + get() = instance!!.identityDatabase + + @get:JvmStatic + @get:JvmName("media") + val media: MediaDatabase + get() = instance!!.media + + @get:JvmStatic + @get:JvmName("mentions") + val mentions: MentionDatabase + get() = instance!!.mentionDatabase + + @get:JvmStatic + @get:JvmName("messageSearch") + val messageSearch: SearchDatabase + get() = instance!!.searchDatabase + + @get:JvmStatic + @get:JvmName("messageLog") + val messageLog: MessageSendLogDatabase + get() = instance!!.messageSendLogDatabase + + @get:JvmStatic + @get:JvmName("mms") + val mms: MmsDatabase + get() = instance!!.mms + + @get:JvmStatic + @get:JvmName("mmsSms") + val mmsSms: MmsSmsDatabase + get() = instance!!.mmsSmsDatabase + + @get:JvmStatic + @get:JvmName("payments") + val payments: PaymentDatabase + get() = instance!!.paymentDatabase + + @get:JvmStatic + @get:JvmName("pendingRetryReceipts") + val pendingRetryReceipts: PendingRetryReceiptDatabase + get() = instance!!.pendingRetryReceiptDatabase + + @get:JvmStatic + @get:JvmName("preKeys") + val preKeys: OneTimePreKeyDatabase + get() = instance!!.preKeyDatabase + + @get:Deprecated("This only exists to migrate from legacy storage. There shouldn't be any new usages.") + @get:JvmStatic + @get:JvmName("push") + val push: PushDatabase + get() = instance!!.pushDatabase + + @get:JvmStatic + @get:JvmName("recipients") + val recipients: RecipientDatabase + get() = instance!!.recipientDatabase + + @get:JvmStatic + @get:JvmName("signedPreKeys") + val signedPreKeys: SignedPreKeyDatabase + get() = instance!!.signedPreKeyDatabase + + @get:JvmStatic + @get:JvmName("sms") + val sms: SmsDatabase + get() = instance!!.sms + + @get:JvmStatic + @get:JvmName("threads") + val threads: ThreadDatabase + get() = instance!!.thread + + @get:JvmStatic + @get:JvmName("reactions") + val reactions: ReactionDatabase + get() = instance!!.reactionDatabase + + @get:JvmStatic + @get:JvmName("remappedRecords") + val remappedRecords: RemappedRecordsDatabase + get() = instance!!.remappedRecordsDatabase + + @get:JvmStatic + @get:JvmName("senderKeys") + val senderKeys: SenderKeyDatabase + get() = instance!!.senderKeyDatabase + + @get:JvmStatic + @get:JvmName("senderKeyShared") + val senderKeyShared: SenderKeySharedDatabase + get() = instance!!.senderKeySharedDatabase + + @get:JvmStatic + @get:JvmName("sessions") + val sessions: SessionDatabase + get() = instance!!.sessionDatabase + + @get:JvmStatic + @get:JvmName("stickers") + val stickers: StickerDatabase + get() = instance!!.stickerDatabase + + @get:JvmStatic + @get:JvmName("unknownStorageIds") + val unknownStorageIds: UnknownStorageIdDatabase + get() = instance!!.storageIdDatabase + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SignalDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/SignalDatabaseOpenHelper.java similarity index 87% rename from app/src/main/java/org/thoughtcrime/securesms/database/SignalDatabase.java rename to app/src/main/java/org/thoughtcrime/securesms/database/SignalDatabaseOpenHelper.java index ed278cbba4..8b7fa77116 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SignalDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SignalDatabaseOpenHelper.java @@ -6,7 +6,7 @@ import net.zetetic.database.sqlcipher.SQLiteDatabase; * Simple interface for common methods across our various * {@link net.zetetic.database.sqlcipher.SQLiteOpenHelper}s. */ -public interface SignalDatabase { +public interface SignalDatabaseOpenHelper { SQLiteDatabase getSqlCipherDatabase(); String getDatabaseName(); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SignedPreKeyDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/SignedPreKeyDatabase.java index 251242c4a5..1a3bbc3cd7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SignedPreKeyDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SignedPreKeyDatabase.java @@ -9,7 +9,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.util.Base64; import org.whispersystems.libsignal.InvalidKeyException; import org.whispersystems.libsignal.ecc.Curve; @@ -43,7 +42,7 @@ public class SignedPreKeyDatabase extends Database { SIGNATURE + " TEXT NOT NULL, " + TIMESTAMP + " INTEGER DEFAULT 0);"; - SignedPreKeyDatabase(Context context, SQLCipherOpenHelper databaseHelper) { + SignedPreKeyDatabase(Context context, SignalDatabase databaseHelper) { super(context, databaseHelper); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java index 324d915a16..f447a1435f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java @@ -35,11 +35,9 @@ import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch; import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatchSet; import org.thoughtcrime.securesms.database.documents.NetworkFailure; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.database.model.GroupCallUpdateDetailsUtil; import org.thoughtcrime.securesms.database.model.MessageId; import org.thoughtcrime.securesms.database.model.MessageRecord; -import org.thoughtcrime.securesms.database.model.ReactionRecord; import org.thoughtcrime.securesms.database.model.SmsMessageRecord; import org.thoughtcrime.securesms.database.model.databaseprotos.GroupCallUpdateDetails; import org.thoughtcrime.securesms.database.model.databaseprotos.ProfileChangeDetails; @@ -156,7 +154,7 @@ public class SmsDatabase extends MessageDatabase { private static final EarlyReceiptCache earlyDeliveryReceiptCache = new EarlyReceiptCache("SmsDelivery"); - public SmsDatabase(Context context, SQLCipherOpenHelper databaseHelper) { + public SmsDatabase(Context context, SignalDatabase databaseHelper) { super(context, databaseHelper); } @@ -193,7 +191,7 @@ public class SmsDatabase extends MessageDatabase { threadId = getThreadIdForMessage(id); - DatabaseFactory.getThreadDatabase(context).updateSnippetTypeSilently(threadId); + SignalDatabase.threads().updateSnippetTypeSilently(threadId); db.setTransactionSuccessful(); } finally { @@ -394,8 +392,8 @@ public class SmsDatabase extends MessageDatabase { threadId = getThreadIdForMessage(id); - DatabaseFactory.getThreadDatabase(context).update(threadId, false); - DatabaseFactory.getMessageLogDatabase(context).deleteAllRelatedToMessage(id, false); + SignalDatabase.threads().update(threadId, false); + SignalDatabase.messageLog().deleteAllRelatedToMessage(id, false); db.setTransactionSuccessful(); } finally { @@ -448,7 +446,7 @@ public class SmsDatabase extends MessageDatabase { db.endTransaction(); } - DatabaseFactory.getThreadDatabase(context).update(threadId, false); + SignalDatabase.threads().update(threadId, false); notifyConversationListeners(threadId); } @@ -462,7 +460,7 @@ public class SmsDatabase extends MessageDatabase { db.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {id+""}); long threadId = getThreadIdForMessage(id); - DatabaseFactory.getThreadDatabase(context).update(threadId, false); + SignalDatabase.threads().update(threadId, false); notifyConversationListeners(threadId); } @@ -562,8 +560,8 @@ public class SmsDatabase extends MessageDatabase { database.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {cursor.getLong(cursor.getColumnIndexOrThrow(ID)) + ""}); - DatabaseFactory.getThreadDatabase(context).updateReadState(threadId); - DatabaseFactory.getThreadDatabase(context).setLastSeen(threadId); + SignalDatabase.threads().updateReadState(threadId); + SignalDatabase.threads().setLastSeen(threadId); notifyConversationListeners(threadId); Long latest = threadToLatestRead.get(threadId); @@ -665,7 +663,7 @@ public class SmsDatabase extends MessageDatabase { long threadId = getThreadIdForMessage(messageId); - DatabaseFactory.getThreadDatabase(context).update(threadId, true); + SignalDatabase.threads().update(threadId, true); notifyConversationListeners(threadId); return new InsertResult(messageId, threadId); @@ -713,7 +711,7 @@ public class SmsDatabase extends MessageDatabase { { SQLiteDatabase db = databaseHelper.getSignalWritableDatabase(); Recipient recipient = Recipient.resolved(groupRecipientId); - long threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient); + long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(recipient); boolean peerEraIdSameAsPrevious = updatePreviousGroupCall(threadId, peekGroupCallEraId, peekJoinedUuids, isCallFull); try { @@ -746,10 +744,10 @@ public class SmsDatabase extends MessageDatabase { db.insert(TABLE_NAME, null, values); - DatabaseFactory.getThreadDatabase(context).incrementUnread(threadId, 1); + SignalDatabase.threads().incrementUnread(threadId, 1); } - DatabaseFactory.getThreadDatabase(context).update(threadId, true); + SignalDatabase.threads().update(threadId, true); db.setTransactionSuccessful(); } finally { @@ -775,7 +773,7 @@ public class SmsDatabase extends MessageDatabase { Recipient recipient = Recipient.resolved(groupRecipientId); - threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient); + threadId = SignalDatabase.threads().getOrCreateThreadIdFor(recipient); String where = TYPE + " = ? AND " + THREAD_ID + " = ?"; String[] args = SqlUtil.buildArgs(Types.GROUP_CALL_TYPE, threadId); @@ -823,10 +821,10 @@ public class SmsDatabase extends MessageDatabase { db.insert(TABLE_NAME, null, values); - DatabaseFactory.getThreadDatabase(context).incrementUnread(threadId, 1); + SignalDatabase.threads().incrementUnread(threadId, 1); } - DatabaseFactory.getThreadDatabase(context).update(threadId, true); + SignalDatabase.threads().update(threadId, true); db.setTransactionSuccessful(); } finally { @@ -880,7 +878,7 @@ public class SmsDatabase extends MessageDatabase { private @NonNull Pair insertCallLog(@NonNull RecipientId recipientId, long type, boolean unread, long timestamp) { Recipient recipient = Recipient.resolved(recipientId); - long threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient); + long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(recipient); ContentValues values = new ContentValues(6); values.put(RECIPIENT_ID, recipientId.serialize()); @@ -895,10 +893,10 @@ public class SmsDatabase extends MessageDatabase { long messageId = db.insert(TABLE_NAME, null, values); if (unread) { - DatabaseFactory.getThreadDatabase(context).incrementUnread(threadId, 1); + SignalDatabase.threads().incrementUnread(threadId, 1); } - DatabaseFactory.getThreadDatabase(context).update(threadId, true); + SignalDatabase.threads().update(threadId, true); notifyConversationListeners(threadId); TrimThreadJob.enqueueAsync(threadId); @@ -939,8 +937,8 @@ public class SmsDatabase extends MessageDatabase { @Override public void insertProfileNameChangeMessages(@NonNull Recipient recipient, @NonNull String newProfileName, @NonNull String previousProfileName) { - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); - List groupRecords = DatabaseFactory.getGroupDatabase(context).getGroupsContainingMember(recipient.getId(), false); + ThreadDatabase threadDatabase = SignalDatabase.threads(); + List groupRecords = SignalDatabase.groups().getGroupsContainingMember(recipient.getId(), false); List threadIdsToUpdate = new LinkedList<>(); byte[] profileChangeDetails = ProfileChangeDetails.newBuilder() @@ -1032,8 +1030,8 @@ public class SmsDatabase extends MessageDatabase { @Override public void insertNumberChangeMessages(@NonNull Recipient recipient) { - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); - List groupRecords = DatabaseFactory.getGroupDatabase(context).getGroupsContainingMember(recipient.getId(), false); + ThreadDatabase threadDatabase = SignalDatabase.threads(); + List groupRecords = SignalDatabase.groups().getGroupsContainingMember(recipient.getId(), false); List threadIdsToUpdate = new LinkedList<>(); SQLiteDatabase db = databaseHelper.getSignalWritableDatabase(); @@ -1072,7 +1070,7 @@ public class SmsDatabase extends MessageDatabase { .filter(Objects::nonNull) .forEach(threadId -> { TrimThreadJob.enqueueAsync(threadId); - DatabaseFactory.getThreadDatabase(context).update(threadId, true); + SignalDatabase.threads().update(threadId, true); notifyConversationListeners(threadId); }); } @@ -1120,7 +1118,7 @@ public class SmsDatabase extends MessageDatabase { if (message.getGroupId() == null) { groupRecipient = null; } else { - RecipientId id = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromPossiblyMigratedGroupId(message.getGroupId()); + RecipientId id = SignalDatabase.recipients().getOrInsertFromPossiblyMigratedGroupId(message.getGroupId()); groupRecipient = Recipient.resolved(id); } @@ -1135,8 +1133,8 @@ public class SmsDatabase extends MessageDatabase { long threadId; - if (groupRecipient == null) threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient); - else threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(groupRecipient); + if (groupRecipient == null) threadId = SignalDatabase.threads().getOrCreateThreadIdFor(recipient); + else threadId = SignalDatabase.threads().getOrCreateThreadIdFor(groupRecipient); ContentValues values = new ContentValues(); values.put(RECIPIENT_ID, message.getSender().serialize()); @@ -1168,15 +1166,15 @@ public class SmsDatabase extends MessageDatabase { long messageId = db.insert(TABLE_NAME, null, values); if (unread) { - DatabaseFactory.getThreadDatabase(context).incrementUnread(threadId, 1); + SignalDatabase.threads().incrementUnread(threadId, 1); } if (!silent) { - DatabaseFactory.getThreadDatabase(context).update(threadId, true); + SignalDatabase.threads().update(threadId, true); } if (message.getSubscriptionId() != -1) { - DatabaseFactory.getRecipientDatabase(context).setDefaultSubscriptionId(recipient.getId(), message.getSubscriptionId()); + SignalDatabase.recipients().setDefaultSubscriptionId(recipient.getId(), message.getSubscriptionId()); } notifyConversationListeners(threadId); @@ -1197,7 +1195,7 @@ public class SmsDatabase extends MessageDatabase { @Override public @NonNull InsertResult insertChatSessionRefreshedMessage(@NonNull RecipientId recipientId, long senderDeviceId, long sentTimestamp) { SQLiteDatabase db = databaseHelper.getSignalWritableDatabase(); - long threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(Recipient.resolved(recipientId)); + long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(Recipient.resolved(recipientId)); long type = Types.SECURE_MESSAGE_BIT | Types.PUSH_MESSAGE_BIT; type = type & (Types.TOTAL_MASK - Types.ENCRYPTION_MASK) | Types.ENCRYPTION_REMOTE_FAILED_BIT; @@ -1214,8 +1212,8 @@ public class SmsDatabase extends MessageDatabase { long messageId = db.insert(TABLE_NAME, null, values); - DatabaseFactory.getThreadDatabase(context).incrementUnread(threadId, 1); - DatabaseFactory.getThreadDatabase(context).update(threadId, true); + SignalDatabase.threads().incrementUnread(threadId, 1); + SignalDatabase.threads().update(threadId, true); notifyConversationListeners(threadId); @@ -1238,8 +1236,8 @@ public class SmsDatabase extends MessageDatabase { databaseHelper.getSignalWritableDatabase().insert(TABLE_NAME, null, values); - DatabaseFactory.getThreadDatabase(context).incrementUnread(threadId, 1); - DatabaseFactory.getThreadDatabase(context).update(threadId, true); + SignalDatabase.threads().incrementUnread(threadId, 1); + SignalDatabase.threads().update(threadId, true); notifyConversationListeners(threadId); @@ -1285,11 +1283,11 @@ public class SmsDatabase extends MessageDatabase { } if (!message.isIdentityVerified() && !message.isIdentityDefault()) { - DatabaseFactory.getThreadDatabase(context).setLastScrolled(threadId, 0); - DatabaseFactory.getThreadDatabase(context).setLastSeenSilently(threadId); + SignalDatabase.threads().setLastScrolled(threadId, 0); + SignalDatabase.threads().setLastSeenSilently(threadId); } - DatabaseFactory.getThreadDatabase(context).setHasSentSilently(threadId, true); + SignalDatabase.threads().setHasSentSilently(threadId, true); ApplicationDependencies.getDatabaseObserver().notifyMessageInsertObservers(threadId, new MessageId(messageId, false)); @@ -1341,8 +1339,8 @@ public class SmsDatabase extends MessageDatabase { db.delete(TABLE_NAME, ID_WHERE, new String[] { messageId + "" }); - DatabaseFactory.getThreadDatabase(context).setLastScrolled(threadId, 0); - threadDeleted = DatabaseFactory.getThreadDatabase(context).update(threadId, false, true); + SignalDatabase.threads().setLastScrolled(threadId, 0); + threadDeleted = SignalDatabase.threads().update(threadId, false, true); db.setTransactionSuccessful(); } finally { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SmsMigrator.java b/app/src/main/java/org/thoughtcrime/securesms/database/SmsMigrator.java index 49f48f8186..26a8c4ead8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SmsMigrator.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SmsMigrator.java @@ -163,7 +163,7 @@ public class SmsMigrator { ProgressDescription progress, long theirThreadId, long ourThreadId) { - MessageDatabase ourSmsDatabase = DatabaseFactory.getSmsDatabase(context); + MessageDatabase ourSmsDatabase = SignalDatabase.sms(); Cursor cursor = null; SQLiteStatement statement = null; @@ -194,9 +194,9 @@ public class SmsMigrator { } ourSmsDatabase.endTransaction(transaction); - DatabaseFactory.getThreadDatabase(context).update(ourThreadId, true); - DatabaseFactory.getThreadDatabase(context).setLastScrolled(ourThreadId, 0); - DatabaseFactory.getThreadDatabase(context).notifyConversationListeners(ourThreadId); + SignalDatabase.threads().update(ourThreadId, true); + SignalDatabase.threads().setLastScrolled(ourThreadId, 0); + SignalDatabase.threads().notifyConversationListeners(ourThreadId); } finally { if (statement != null) @@ -211,7 +211,7 @@ public class SmsMigrator { // if (context.getSharedPreferences("SecureSMS", Context.MODE_PRIVATE).getBoolean("migrated", false)) // return; - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); + ThreadDatabase threadDatabase = SignalDatabase.threads(); Cursor cursor = null; try { @@ -233,8 +233,8 @@ public class SmsMigrator { List recipientIds = Stream.of(ourRecipients).map(Recipient::getId).toList(); - GroupId.Mms ourGroupId = DatabaseFactory.getGroupDatabase(context).getOrCreateMmsGroupForMembers(recipientIds); - RecipientId ourGroupRecipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(ourGroupId); + GroupId.Mms ourGroupId = SignalDatabase.groups().getOrCreateMmsGroupForMembers(recipientIds); + RecipientId ourGroupRecipientId = SignalDatabase.recipients().getOrInsertFromGroupId(ourGroupId); Recipient ourGroupRecipient = Recipient.resolved(ourGroupRecipientId); long ourThreadId = threadDatabase.getOrCreateThreadIdFor(ourGroupRecipient, ThreadDatabase.DistributionTypes.CONVERSATION); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SqlCipherLibraryLoader.kt b/app/src/main/java/org/thoughtcrime/securesms/database/SqlCipherLibraryLoader.kt index 47d377f292..79a702143c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SqlCipherLibraryLoader.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SqlCipherLibraryLoader.kt @@ -4,21 +4,18 @@ package org.thoughtcrime.securesms.database * A simple wrapper to load SQLCipher libs exactly once. The exact entry point of database access is non-deterministic because content providers run before * Application#onCreate(). */ -class SqlCipherLibraryLoader { +object SqlCipherLibraryLoader { + @Volatile + private var loaded = false + private val LOCK = Object() - companion object { - @Volatile - private var loaded = false - private val LOCK = Object() - - @JvmStatic - fun load() { - if (!loaded) { - synchronized(LOCK) { - if (!loaded) { - System.loadLibrary("sqlcipher") - loaded = true - } + @JvmStatic + fun load() { + if (!loaded) { + synchronized(LOCK) { + if (!loaded) { + System.loadLibrary("sqlcipher") + loaded = true } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/StickerDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/StickerDatabase.java index 2ff7bf382c..cbccf7fb62 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/StickerDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/StickerDatabase.java @@ -15,7 +15,6 @@ import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.crypto.AttachmentSecret; import org.thoughtcrime.securesms.crypto.ModernDecryptingPartInputStream; import org.thoughtcrime.securesms.crypto.ModernEncryptingPartOutputStream; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.database.model.IncomingSticker; import org.thoughtcrime.securesms.database.model.StickerPackRecord; import org.thoughtcrime.securesms.database.model.StickerRecord; @@ -81,7 +80,7 @@ public class StickerDatabase extends Database { private final AttachmentSecret attachmentSecret; - public StickerDatabase(Context context, SQLCipherOpenHelper databaseHelper, AttachmentSecret attachmentSecret) { + public StickerDatabase(Context context, SignalDatabase databaseHelper, AttachmentSecret attachmentSecret) { super(context, databaseHelper); this.attachmentSecret = attachmentSecret; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java index 37b592881e..29f10d4e39 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java @@ -36,7 +36,6 @@ import org.signal.zkgroup.InvalidInputException; import org.signal.zkgroup.groups.GroupMasterKey; import org.thoughtcrime.securesms.database.MessageDatabase.MarkedMessageInfo; import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientSettings; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.database.model.MmsMessageRecord; @@ -157,7 +156,7 @@ public class ThreadDatabase extends Database { private static final String[] RECIPIENT_ID_PROJECTION = new String[] { RECIPIENT_ID }; - public ThreadDatabase(Context context, SQLCipherOpenHelper databaseHelper) { + public ThreadDatabase(Context context, SignalDatabase databaseHelper) { super(context, databaseHelper); } @@ -261,10 +260,10 @@ public class ThreadDatabase extends Database { } SQLiteDatabase db = databaseHelper.getSignalWritableDatabase(); - AttachmentDatabase attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context); - GroupReceiptDatabase groupReceiptDatabase = DatabaseFactory.getGroupReceiptDatabase(context); - MmsSmsDatabase mmsSmsDatabase = DatabaseFactory.getMmsSmsDatabase(context); - MentionDatabase mentionDatabase = DatabaseFactory.getMentionDatabase(context); + AttachmentDatabase attachmentDatabase = SignalDatabase.attachments(); + GroupReceiptDatabase groupReceiptDatabase = SignalDatabase.groupReceipts(); + MmsSmsDatabase mmsSmsDatabase = SignalDatabase.mmsSms(); + MentionDatabase mentionDatabase = SignalDatabase.mentions(); int deletes = 0; try (Cursor cursor = databaseHelper.getSignalReadableDatabase().query(TABLE_NAME, new String[] { ID }, null, null, null, null, null)) { @@ -300,10 +299,10 @@ public class ThreadDatabase extends Database { } SQLiteDatabase db = databaseHelper.getSignalWritableDatabase(); - AttachmentDatabase attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context); - GroupReceiptDatabase groupReceiptDatabase = DatabaseFactory.getGroupReceiptDatabase(context); - MmsSmsDatabase mmsSmsDatabase = DatabaseFactory.getMmsSmsDatabase(context); - MentionDatabase mentionDatabase = DatabaseFactory.getMentionDatabase(context); + AttachmentDatabase attachmentDatabase = SignalDatabase.attachments(); + GroupReceiptDatabase groupReceiptDatabase = SignalDatabase.groupReceipts(); + MmsSmsDatabase mmsSmsDatabase = SignalDatabase.mmsSms(); + MentionDatabase mentionDatabase = SignalDatabase.mentions(); int deletes = 0; db.beginTransaction(); @@ -334,7 +333,7 @@ public class ThreadDatabase extends Database { } if (length != NO_TRIM_MESSAGE_COUNT_SET) { - try (Cursor cursor = DatabaseFactory.getMmsSmsDatabase(context).getConversation(threadId)) { + try (Cursor cursor = SignalDatabase.mmsSms().getConversation(threadId)) { if (cursor != null && length > 0 && cursor.getCount() > length) { cursor.moveToPosition(length - 1); trimBeforeDate = Math.max(trimBeforeDate, cursor.getLong(cursor.getColumnIndexOrThrow(MmsSmsColumns.NORMALIZED_DATE_RECEIVED))); @@ -345,7 +344,7 @@ public class ThreadDatabase extends Database { if (trimBeforeDate != NO_TRIM_BEFORE_DATE_SET) { Log.i(TAG, "Trimming thread: " + threadId + " before: " + trimBeforeDate); - int deletes = DatabaseFactory.getMmsSmsDatabase(context).deleteMessagesInThreadBeforeDate(threadId, trimBeforeDate); + int deletes = SignalDatabase.mmsSms().deleteMessagesInThreadBeforeDate(threadId, trimBeforeDate); if (deletes > 0) { Log.i(TAG, "Trimming deleted " + deletes + " messages thread: " + threadId); @@ -366,11 +365,11 @@ public class ThreadDatabase extends Database { db.update(TABLE_NAME, contentValues, null, null); - final List smsRecords = DatabaseFactory.getSmsDatabase(context).setAllMessagesRead(); - final List mmsRecords = DatabaseFactory.getMmsDatabase(context).setAllMessagesRead(); + final List smsRecords = SignalDatabase.sms().setAllMessagesRead(); + final List mmsRecords = SignalDatabase.mms().setAllMessagesRead(); - DatabaseFactory.getSmsDatabase(context).setAllReactionsSeen(); - DatabaseFactory.getMmsDatabase(context).setAllReactionsSeen(); + SignalDatabase.sms().setAllReactionsSeen(); + SignalDatabase.mms().setAllReactionsSeen(); notifyConversationListListeners(); @@ -382,14 +381,14 @@ public class ThreadDatabase extends Database { } public boolean hasReceivedAnyCallsSince(long threadId, long timestamp) { - return DatabaseFactory.getMmsSmsDatabase(context).hasReceivedAnyCallsSince(threadId, timestamp); + return SignalDatabase.mmsSms().hasReceivedAnyCallsSince(threadId, timestamp); } public List setEntireThreadRead(long threadId) { setRead(threadId, false); - final List smsRecords = DatabaseFactory.getSmsDatabase(context).setEntireThreadRead(threadId); - final List mmsRecords = DatabaseFactory.getMmsDatabase(context).setEntireThreadRead(threadId); + final List smsRecords = SignalDatabase.sms().setEntireThreadRead(threadId); + final List mmsRecords = SignalDatabase.mms().setEntireThreadRead(threadId); return Util.concatenatedList(smsRecords, mmsRecords); } @@ -429,20 +428,20 @@ public class ThreadDatabase extends Database { ThreadRecord previous = getThreadRecord(threadId); - smsRecords.addAll(DatabaseFactory.getSmsDatabase(context).setMessagesReadSince(threadId, sinceTimestamp)); - mmsRecords.addAll(DatabaseFactory.getMmsDatabase(context).setMessagesReadSince(threadId, sinceTimestamp)); + smsRecords.addAll(SignalDatabase.sms().setMessagesReadSince(threadId, sinceTimestamp)); + mmsRecords.addAll(SignalDatabase.mms().setMessagesReadSince(threadId, sinceTimestamp)); - DatabaseFactory.getSmsDatabase(context).setReactionsSeen(threadId, sinceTimestamp); - DatabaseFactory.getMmsDatabase(context).setReactionsSeen(threadId, sinceTimestamp); + SignalDatabase.sms().setReactionsSeen(threadId, sinceTimestamp); + SignalDatabase.mms().setReactionsSeen(threadId, sinceTimestamp); - int unreadCount = DatabaseFactory.getMmsSmsDatabase(context).getUnreadCount(threadId); + int unreadCount = SignalDatabase.mmsSms().getUnreadCount(threadId); contentValues.put(UNREAD_COUNT, unreadCount); db.update(TABLE_NAME, contentValues, ID_WHERE, SqlUtil.buildArgs(threadId)); if (previous != null && previous.isForcedUnread()) { - DatabaseFactory.getRecipientDatabase(context).markNeedsSync(previous.getRecipient().getId()); + SignalDatabase.recipients().markNeedsSync(previous.getRecipient().getId()); needsSync = true; } } @@ -476,7 +475,7 @@ public class ThreadDatabase extends Database { db.update(TABLE_NAME, contentValues, query.getWhere(), query.getWhereArgs()); recipientIds = getRecipientIdsForThreadIds(threadIds); - DatabaseFactory.getRecipientDatabase(context).markNeedsSyncWithoutRefresh(recipientIds); + SignalDatabase.recipients().markNeedsSyncWithoutRefresh(recipientIds); db.setTransactionSuccessful(); } finally { @@ -658,7 +657,7 @@ public class ThreadDatabase extends Database { } recipientIds = getRecipientIdsForThreadIds(threadIds); - DatabaseFactory.getRecipientDatabase(context).markNeedsSyncWithoutRefresh(recipientIds); + SignalDatabase.recipients().markNeedsSyncWithoutRefresh(recipientIds); db.setTransactionSuccessful(); } finally { @@ -870,7 +869,7 @@ public class ThreadDatabase extends Database { notifyConversationListListeners(); - DatabaseFactory.getRecipientDatabase(context).markNeedsSync(Recipient.self().getId()); + SignalDatabase.recipients().markNeedsSync(Recipient.self().getId()); StorageSyncHelper.scheduleSyncForDataChange(); } @@ -885,7 +884,7 @@ public class ThreadDatabase extends Database { db.update(TABLE_NAME, contentValues, selection, SqlUtil.buildArgs(Stream.of(threadIds).toArray())); notifyConversationListListeners(); - DatabaseFactory.getRecipientDatabase(context).markNeedsSync(Recipient.self().getId()); + SignalDatabase.recipients().markNeedsSync(Recipient.self().getId()); StorageSyncHelper.scheduleSyncForDataChange(); } @@ -939,9 +938,9 @@ public class ThreadDatabase extends Database { db.beginTransaction(); try { - DatabaseFactory.getSmsDatabase(context).deleteThread(threadId); - DatabaseFactory.getMmsDatabase(context).deleteThread(threadId); - DatabaseFactory.getDraftDatabase(context).clearDrafts(threadId); + SignalDatabase.sms().deleteThread(threadId); + SignalDatabase.mms().deleteThread(threadId); + SignalDatabase.drafts().clearDrafts(threadId); db.delete(TABLE_NAME, ID_WHERE, new String[]{threadId + ""}); @@ -961,9 +960,9 @@ public class ThreadDatabase extends Database { db.beginTransaction(); try { - DatabaseFactory.getSmsDatabase(context).deleteThreads(selectedConversations); - DatabaseFactory.getMmsDatabase(context).deleteThreads(selectedConversations); - DatabaseFactory.getDraftDatabase(context).clearDrafts(selectedConversations); + SignalDatabase.sms().deleteThreads(selectedConversations); + SignalDatabase.mms().deleteThreads(selectedConversations); + SignalDatabase.drafts().clearDrafts(selectedConversations); StringBuilder where = new StringBuilder(); @@ -991,10 +990,10 @@ public class ThreadDatabase extends Database { db.beginTransaction(); try { - DatabaseFactory.getMessageLogDatabase(context).deleteAll(); - DatabaseFactory.getSmsDatabase(context).deleteAllThreads(); - DatabaseFactory.getMmsDatabase(context).deleteAllThreads(); - DatabaseFactory.getDraftDatabase(context).clearAllDrafts(); + SignalDatabase.messageLog().deleteAll(); + SignalDatabase.sms().deleteAllThreads(); + SignalDatabase.mms().deleteAllThreads(); + SignalDatabase.drafts().clearAllDrafts(); db.delete(TABLE_NAME, null, null); @@ -1040,7 +1039,7 @@ public class ThreadDatabase extends Database { public long getOrCreateValidThreadId(@NonNull Recipient recipient, long candidateId, int distributionType) { if (candidateId != -1) { - Optional remapped = RemappedRecords.getInstance().getThread(context, candidateId); + Optional remapped = RemappedRecords.getInstance().getThread(candidateId); if (remapped.isPresent()) { Log.i(TAG, "Using remapped threadId: " + candidateId + " -> " + remapped.get()); @@ -1136,7 +1135,7 @@ public class ThreadDatabase extends Database { void updateReadState(long threadId) { ThreadRecord previous = getThreadRecord(threadId); - int unreadCount = DatabaseFactory.getMmsSmsDatabase(context).getUnreadCount(threadId); + int unreadCount = SignalDatabase.mmsSms().getUnreadCount(threadId); ContentValues contentValues = new ContentValues(); contentValues.put(READ, unreadCount == 0 ? ReadStatus.READ.serialize() : ReadStatus.UNREAD.serialize()); @@ -1147,7 +1146,7 @@ public class ThreadDatabase extends Database { notifyConversationListListeners(); if (previous != null && previous.isForcedUnread()) { - DatabaseFactory.getRecipientDatabase(context).markNeedsSync(previous.getRecipient().getId()); + SignalDatabase.recipients().markNeedsSync(previous.getRecipient().getId()); StorageSyncHelper.scheduleSyncForDataChange(); } } @@ -1228,7 +1227,7 @@ public class ThreadDatabase extends Database { values.put(READ, ReadStatus.FORCED_UNREAD.serialize()); } else { if (threadId != null) { - int unreadCount = DatabaseFactory.getMmsSmsDatabase(context).getUnreadCount(threadId); + int unreadCount = SignalDatabase.mmsSms().getUnreadCount(threadId); values.put(READ, unreadCount == 0 ? ReadStatus.READ.serialize() : ReadStatus.UNREAD.serialize()); values.put(UNREAD_COUNT, unreadCount); @@ -1255,7 +1254,7 @@ public class ThreadDatabase extends Database { } private boolean update(long threadId, boolean unarchive, boolean allowDeletion, boolean notifyListeners) { - MmsSmsDatabase mmsSmsDatabase = DatabaseFactory.getMmsSmsDatabase(context); + MmsSmsDatabase mmsSmsDatabase = SignalDatabase.mmsSms(); boolean meaningfulMessages = mmsSmsDatabase.hasMeaningfulMessage(threadId); if (!meaningfulMessages) { @@ -1303,7 +1302,7 @@ public class ThreadDatabase extends Database { long type; try { - type = DatabaseFactory.getMmsSmsDatabase(context).getConversationSnippetType(threadId); + type = SignalDatabase.mmsSms().getConversationSnippetType(threadId); } catch (NoSuchMessageException e) { Log.w(TAG, "Unable to find snippet message for thread: " + threadId, e); return; @@ -1387,7 +1386,7 @@ public class ThreadDatabase extends Database { db.update(SearchDatabase.SMS_FTS_TABLE_NAME, searchValues, SearchDatabase.THREAD_ID + " = ?", SqlUtil.buildArgs(secondary.getThreadId())); db.update(SearchDatabase.MMS_FTS_TABLE_NAME, searchValues, SearchDatabase.THREAD_ID + " = ?", SqlUtil.buildArgs(secondary.getThreadId())); - RemappedRecords.getInstance().addThread(context, secondary.getThreadId(), primary.getThreadId()); + RemappedRecords.getInstance().addThread(secondary.getThreadId(), primary.getThreadId()); return new MergeResult(primary.getThreadId(), secondary.getThreadId(), true); } @@ -1457,7 +1456,7 @@ public class ThreadDatabase extends Database { Log.w(TAG, "Falling back to unknown message request state for GV2 message"); return Extra.forMessageRequest(individualRecipientId); } else { - RecipientId recipientId = DatabaseFactory.getMmsSmsDatabase(context).getGroupAddedBy(record.getThreadId()); + RecipientId recipientId = SignalDatabase.mmsSms().getGroupAddedBy(record.getThreadId()); if (recipientId != null) { return Extra.forGroupMessageRequest(recipientId, individualRecipientId); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/UnknownStorageIdDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/UnknownStorageIdDatabase.java index 4067d9aba2..4869c66014 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/UnknownStorageIdDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/UnknownStorageIdDatabase.java @@ -9,7 +9,6 @@ import androidx.annotation.Nullable; import com.annimon.stream.Stream; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.util.Base64; import org.thoughtcrime.securesms.util.SqlUtil; import org.whispersystems.libsignal.util.guava.Preconditions; @@ -40,7 +39,7 @@ public class UnknownStorageIdDatabase extends Database { "CREATE INDEX IF NOT EXISTS storage_key_type_index ON " + TABLE_NAME + " (" + TYPE + ");" }; - public UnknownStorageIdDatabase(Context context, SQLCipherOpenHelper databaseHelper) { + public UnknownStorageIdDatabase(Context context, SignalDatabase databaseHelper) { super(context, databaseHelper); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/ClassicOpenHelper.java b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/ClassicOpenHelper.java index c173b52884..40e5713638 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/ClassicOpenHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/ClassicOpenHelper.java @@ -67,7 +67,7 @@ import java.util.regex.Pattern; public class ClassicOpenHelper extends SQLiteOpenHelper { - static final String NAME = "messages.db"; + public static final String NAME = "messages.db"; private static final int INTRODUCED_IDENTITIES_VERSION = 2; private static final int INTRODUCED_INDEXES_VERSION = 3; diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/PreKeyMigrationHelper.java b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/PreKeyMigrationHelper.java index cbe125e5be..a49f7aba8e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/PreKeyMigrationHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/PreKeyMigrationHelper.java @@ -26,7 +26,7 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; -class PreKeyMigrationHelper { +public final class PreKeyMigrationHelper { private static final String PREKEY_DIRECTORY = "prekeys"; private static final String SIGNED_PREKEY_DIRECTORY = "signed_prekeys"; @@ -36,7 +36,7 @@ class PreKeyMigrationHelper { private static final String TAG = Log.tag(PreKeyMigrationHelper.class); - static boolean migratePreKeys(Context context, SQLiteDatabase database) { + public static boolean migratePreKeys(Context context, SQLiteDatabase database) { File[] preKeyFiles = getPreKeyDirectory(context).listFiles(); boolean clean = true; @@ -118,7 +118,7 @@ class PreKeyMigrationHelper { return clean; } - static void cleanUpPreKeys(@NonNull Context context) { + public static void cleanUpPreKeys(@NonNull Context context) { File preKeyDirectory = getPreKeyDirectory(context); File[] preKeyFiles = preKeyDirectory.listFiles(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherMigrationHelper.java b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherMigrationHelper.java index b74d0505ab..02b2077794 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherMigrationHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherMigrationHelper.java @@ -38,9 +38,9 @@ public class SQLCipherMigrationHelper { private static final long ENCRYPTION_SYMMETRIC_BIT = 0x80000000; private static final long ENCRYPTION_ASYMMETRIC_BIT = 0x40000000; - static void migratePlaintext(@NonNull Context context, - @NonNull android.database.sqlite.SQLiteDatabase legacyDb, - @NonNull SQLiteDatabase modernDb) + public static void migratePlaintext(@NonNull Context context, + @NonNull android.database.sqlite.SQLiteDatabase legacyDb, + @NonNull SQLiteDatabase modernDb) { modernDb.beginTransaction(); int foregroundId = GenericForegroundService.startForegroundTask(context, context.getString(R.string.SQLCipherMigrationHelper_migrating_signal_database)).getId(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java deleted file mode 100644 index 97c6c2ce6a..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java +++ /dev/null @@ -1,2198 +0,0 @@ -package org.thoughtcrime.securesms.database.helpers; - - -import android.app.NotificationChannel; -import android.app.NotificationManager; -import android.content.ContentValues; -import android.content.Context; -import android.database.Cursor; -import android.net.Uri; -import android.os.Build; -import android.os.SystemClock; -import android.preference.PreferenceManager; -import android.text.TextUtils; - -import androidx.annotation.NonNull; - -import com.annimon.stream.Stream; -import com.bumptech.glide.Glide; -import com.google.protobuf.InvalidProtocolBufferException; - -import net.zetetic.database.sqlcipher.SQLiteDatabase; -import net.zetetic.database.sqlcipher.SQLiteOpenHelper; - -import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.color.MaterialColor; -import org.thoughtcrime.securesms.contacts.avatars.ContactColorsLegacy; -import org.thoughtcrime.securesms.conversation.colors.AvatarColor; -import org.thoughtcrime.securesms.conversation.colors.ChatColors; -import org.thoughtcrime.securesms.conversation.colors.ChatColorsMapper; -import org.thoughtcrime.securesms.crypto.DatabaseSecret; -import org.thoughtcrime.securesms.crypto.MasterSecret; -import org.thoughtcrime.securesms.database.AttachmentDatabase; -import org.thoughtcrime.securesms.database.ChatColorsDatabase; -import org.thoughtcrime.securesms.database.DraftDatabase; -import org.thoughtcrime.securesms.database.EmojiSearchDatabase; -import org.thoughtcrime.securesms.database.GroupCallRingDatabase; -import org.thoughtcrime.securesms.database.GroupDatabase; -import org.thoughtcrime.securesms.database.GroupReceiptDatabase; -import org.thoughtcrime.securesms.database.IdentityDatabase; -import org.thoughtcrime.securesms.database.MentionDatabase; -import org.thoughtcrime.securesms.database.MessageSendLogDatabase; -import org.thoughtcrime.securesms.database.MmsDatabase; -import org.thoughtcrime.securesms.database.OneTimePreKeyDatabase; -import org.thoughtcrime.securesms.database.PaymentDatabase; -import org.thoughtcrime.securesms.database.PendingRetryReceiptDatabase; -import org.thoughtcrime.securesms.database.PushDatabase; -import org.thoughtcrime.securesms.database.ReactionDatabase; -import org.thoughtcrime.securesms.database.RecipientDatabase; -import org.thoughtcrime.securesms.database.RemappedRecordsDatabase; -import org.thoughtcrime.securesms.database.SearchDatabase; -import org.thoughtcrime.securesms.database.SenderKeyDatabase; -import org.thoughtcrime.securesms.database.SenderKeySharedDatabase; -import org.thoughtcrime.securesms.database.SessionDatabase; -import org.thoughtcrime.securesms.database.SignalDatabase; -import org.thoughtcrime.securesms.database.SignedPreKeyDatabase; -import org.thoughtcrime.securesms.database.SmsDatabase; -import org.thoughtcrime.securesms.database.SqlCipherDatabaseHook; -import org.thoughtcrime.securesms.database.SqlCipherErrorHandler; -import org.thoughtcrime.securesms.database.StickerDatabase; -import org.thoughtcrime.securesms.database.ThreadDatabase; -import org.thoughtcrime.securesms.database.UnknownStorageIdDatabase; -import org.thoughtcrime.securesms.database.model.AvatarPickerDatabase; -import org.thoughtcrime.securesms.database.model.databaseprotos.ReactionList; -import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; -import org.thoughtcrime.securesms.groups.GroupId; -import org.thoughtcrime.securesms.jobs.RefreshPreKeysJob; -import org.thoughtcrime.securesms.keyvalue.SignalStore; -import org.thoughtcrime.securesms.notifications.NotificationChannels; -import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter; -import org.thoughtcrime.securesms.profiles.AvatarHelper; -import org.thoughtcrime.securesms.profiles.ProfileName; -import org.thoughtcrime.securesms.recipients.RecipientId; -import org.thoughtcrime.securesms.service.KeyCachingService; -import org.thoughtcrime.securesms.storage.StorageSyncHelper; -import org.thoughtcrime.securesms.util.Base64; -import org.thoughtcrime.securesms.util.CursorUtil; -import org.thoughtcrime.securesms.util.FileUtils; -import org.thoughtcrime.securesms.util.Hex; -import org.thoughtcrime.securesms.util.ServiceUtil; -import org.thoughtcrime.securesms.util.SqlUtil; -import org.thoughtcrime.securesms.util.Stopwatch; -import org.thoughtcrime.securesms.util.TextSecurePreferences; -import org.thoughtcrime.securesms.util.Triple; -import org.thoughtcrime.securesms.util.Util; -import org.whispersystems.signalservice.api.push.DistributionId; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -public class SQLCipherOpenHelper extends SQLiteOpenHelper implements SignalDatabase { - - @SuppressWarnings("unused") - private static final String TAG = Log.tag(SQLCipherOpenHelper.class); - - private static final int RECIPIENT_CALL_RINGTONE_VERSION = 2; - private static final int MIGRATE_PREKEYS_VERSION = 3; - private static final int MIGRATE_SESSIONS_VERSION = 4; - private static final int NO_MORE_IMAGE_THUMBNAILS_VERSION = 5; - private static final int ATTACHMENT_DIMENSIONS = 6; - private static final int QUOTED_REPLIES = 7; - private static final int SHARED_CONTACTS = 8; - private static final int FULL_TEXT_SEARCH = 9; - private static final int BAD_IMPORT_CLEANUP = 10; - private static final int QUOTE_MISSING = 11; - private static final int NOTIFICATION_CHANNELS = 12; - private static final int SECRET_SENDER = 13; - private static final int ATTACHMENT_CAPTIONS = 14; - private static final int ATTACHMENT_CAPTIONS_FIX = 15; - private static final int PREVIEWS = 16; - private static final int CONVERSATION_SEARCH = 17; - private static final int SELF_ATTACHMENT_CLEANUP = 18; - private static final int RECIPIENT_FORCE_SMS_SELECTION = 19; - private static final int JOBMANAGER_STRIKES_BACK = 20; - private static final int STICKERS = 21; - private static final int REVEALABLE_MESSAGES = 22; - private static final int VIEW_ONCE_ONLY = 23; - private static final int RECIPIENT_IDS = 24; - private static final int RECIPIENT_SEARCH = 25; - private static final int RECIPIENT_CLEANUP = 26; - private static final int MMS_RECIPIENT_CLEANUP = 27; - private static final int ATTACHMENT_HASHING = 28; - private static final int NOTIFICATION_RECIPIENT_IDS = 29; - private static final int BLUR_HASH = 30; - private static final int MMS_RECIPIENT_CLEANUP_2 = 31; - private static final int ATTACHMENT_TRANSFORM_PROPERTIES = 32; - private static final int ATTACHMENT_CLEAR_HASHES = 33; - private static final int ATTACHMENT_CLEAR_HASHES_2 = 34; - private static final int UUIDS = 35; - private static final int USERNAMES = 36; - private static final int REACTIONS = 37; - private static final int STORAGE_SERVICE = 38; - private static final int REACTIONS_UNREAD_INDEX = 39; - private static final int RESUMABLE_DOWNLOADS = 40; - private static final int KEY_VALUE_STORE = 41; - private static final int ATTACHMENT_DISPLAY_ORDER = 42; - private static final int SPLIT_PROFILE_NAMES = 43; - private static final int STICKER_PACK_ORDER = 44; - private static final int MEGAPHONES = 45; - private static final int MEGAPHONE_FIRST_APPEARANCE = 46; - private static final int PROFILE_KEY_TO_DB = 47; - private static final int PROFILE_KEY_CREDENTIALS = 48; - private static final int ATTACHMENT_FILE_INDEX = 49; - private static final int STORAGE_SERVICE_ACTIVE = 50; - private static final int GROUPS_V2_RECIPIENT_CAPABILITY = 51; - private static final int TRANSFER_FILE_CLEANUP = 52; - private static final int PROFILE_DATA_MIGRATION = 53; - private static final int AVATAR_LOCATION_MIGRATION = 54; - private static final int GROUPS_V2 = 55; - private static final int ATTACHMENT_UPLOAD_TIMESTAMP = 56; - private static final int ATTACHMENT_CDN_NUMBER = 57; - private static final int JOB_INPUT_DATA = 58; - private static final int SERVER_TIMESTAMP = 59; - private static final int REMOTE_DELETE = 60; - private static final int COLOR_MIGRATION = 61; - private static final int LAST_SCROLLED = 62; - private static final int LAST_PROFILE_FETCH = 63; - private static final int SERVER_DELIVERED_TIMESTAMP = 64; - private static final int QUOTE_CLEANUP = 65; - private static final int BORDERLESS = 66; - private static final int REMAPPED_RECORDS = 67; - private static final int MENTIONS = 68; - private static final int PINNED_CONVERSATIONS = 69; - private static final int MENTION_GLOBAL_SETTING_MIGRATION = 70; - private static final int UNKNOWN_STORAGE_FIELDS = 71; - private static final int STICKER_CONTENT_TYPE = 72; - private static final int STICKER_EMOJI_IN_NOTIFICATIONS = 73; - private static final int THUMBNAIL_CLEANUP = 74; - private static final int STICKER_CONTENT_TYPE_CLEANUP = 75; - private static final int MENTION_CLEANUP = 76; - private static final int MENTION_CLEANUP_V2 = 77; - private static final int REACTION_CLEANUP = 78; - private static final int CAPABILITIES_REFACTOR = 79; - private static final int GV1_MIGRATION = 80; - private static final int NOTIFIED_TIMESTAMP = 81; - private static final int GV1_MIGRATION_LAST_SEEN = 82; - private static final int VIEWED_RECEIPTS = 83; - private static final int CLEAN_UP_GV1_IDS = 84; - private static final int GV1_MIGRATION_REFACTOR = 85; - private static final int CLEAR_PROFILE_KEY_CREDENTIALS = 86; - private static final int LAST_RESET_SESSION_TIME = 87; - private static final int WALLPAPER = 88; - private static final int ABOUT = 89; - private static final int SPLIT_SYSTEM_NAMES = 90; - private static final int PAYMENTS = 91; - private static final int CLEAN_STORAGE_IDS = 92; - private static final int MP4_GIF_SUPPORT = 93; - private static final int BLUR_AVATARS = 94; - private static final int CLEAN_STORAGE_IDS_WITHOUT_INFO = 95; - private static final int CLEAN_REACTION_NOTIFICATIONS = 96; - private static final int STORAGE_SERVICE_REFACTOR = 97; - private static final int CLEAR_MMS_STORAGE_IDS = 98; - private static final int SERVER_GUID = 99; - private static final int CHAT_COLORS = 100; - private static final int AVATAR_COLORS = 101; - private static final int EMOJI_SEARCH = 102; - private static final int SENDER_KEY = 103; - private static final int MESSAGE_DUPE_INDEX = 104; - private static final int MESSAGE_LOG = 105; - private static final int MESSAGE_LOG_2 = 106; - private static final int ABANDONED_MESSAGE_CLEANUP = 107; - private static final int THREAD_AUTOINCREMENT = 108; - private static final int MMS_AUTOINCREMENT = 109; - private static final int ABANDONED_ATTACHMENT_CLEANUP = 110; - private static final int AVATAR_PICKER = 111; - private static final int THREAD_CLEANUP = 112; - private static final int SESSION_MIGRATION = 113; - private static final int IDENTITY_MIGRATION = 114; - private static final int GROUP_CALL_RING_TABLE = 115; - private static final int CLEANUP_SESSION_MIGRATION = 116; - private static final int RECEIPT_TIMESTAMP = 117; - private static final int BADGES = 118; - private static final int SENDER_KEY_UUID = 119; - private static final int SENDER_KEY_SHARED_TIMESTAMP = 120; - private static final int REACTION_REFACTOR = 121; - - private static final int DATABASE_VERSION = 121; - private static final String DATABASE_NAME = "signal.db"; - - private final Context context; - - public SQLCipherOpenHelper(@NonNull Context context, @NonNull DatabaseSecret databaseSecret) { - super(context, DATABASE_NAME, databaseSecret.asString(), null, DATABASE_VERSION, 0, new SqlCipherErrorHandler(DATABASE_NAME), new SqlCipherDatabaseHook()); - - this.context = context.getApplicationContext(); - } - - @Override - public void onOpen(SQLiteDatabase db) { - db.enableWriteAheadLogging(); - db.setForeignKeyConstraintsEnabled(true); - } - - @Override - public void onCreate(SQLiteDatabase db) { - db.execSQL(SmsDatabase.CREATE_TABLE); - db.execSQL(MmsDatabase.CREATE_TABLE); - db.execSQL(AttachmentDatabase.CREATE_TABLE); - db.execSQL(ThreadDatabase.CREATE_TABLE); - db.execSQL(IdentityDatabase.CREATE_TABLE); - db.execSQL(DraftDatabase.CREATE_TABLE); - db.execSQL(PushDatabase.CREATE_TABLE); - db.execSQL(GroupDatabase.CREATE_TABLE); - db.execSQL(RecipientDatabase.CREATE_TABLE); - db.execSQL(GroupReceiptDatabase.CREATE_TABLE); - db.execSQL(OneTimePreKeyDatabase.CREATE_TABLE); - db.execSQL(SignedPreKeyDatabase.CREATE_TABLE); - db.execSQL(SessionDatabase.CREATE_TABLE); - db.execSQL(SenderKeyDatabase.CREATE_TABLE); - db.execSQL(SenderKeySharedDatabase.CREATE_TABLE); - db.execSQL(PendingRetryReceiptDatabase.CREATE_TABLE); - db.execSQL(StickerDatabase.CREATE_TABLE); - db.execSQL(UnknownStorageIdDatabase.CREATE_TABLE); - db.execSQL(MentionDatabase.CREATE_TABLE); - db.execSQL(PaymentDatabase.CREATE_TABLE); - db.execSQL(ChatColorsDatabase.CREATE_TABLE); - db.execSQL(EmojiSearchDatabase.CREATE_TABLE); - db.execSQL(AvatarPickerDatabase.CREATE_TABLE); - db.execSQL(GroupCallRingDatabase.CREATE_TABLE); - db.execSQL(ReactionDatabase.CREATE_TABLE); - executeStatements(db, SearchDatabase.CREATE_TABLE); - executeStatements(db, RemappedRecordsDatabase.CREATE_TABLE); - executeStatements(db, MessageSendLogDatabase.CREATE_TABLE); - - executeStatements(db, RecipientDatabase.CREATE_INDEXS); - executeStatements(db, SmsDatabase.CREATE_INDEXS); - executeStatements(db, MmsDatabase.CREATE_INDEXS); - executeStatements(db, AttachmentDatabase.CREATE_INDEXS); - executeStatements(db, ThreadDatabase.CREATE_INDEXS); - executeStatements(db, DraftDatabase.CREATE_INDEXS); - executeStatements(db, GroupDatabase.CREATE_INDEXS); - executeStatements(db, GroupReceiptDatabase.CREATE_INDEXES); - executeStatements(db, StickerDatabase.CREATE_INDEXES); - executeStatements(db, UnknownStorageIdDatabase.CREATE_INDEXES); - executeStatements(db, MentionDatabase.CREATE_INDEXES); - executeStatements(db, PaymentDatabase.CREATE_INDEXES); - executeStatements(db, MessageSendLogDatabase.CREATE_INDEXES); - executeStatements(db, GroupCallRingDatabase.CREATE_INDEXES); - - executeStatements(db, MessageSendLogDatabase.CREATE_TRIGGERS); - executeStatements(db, ReactionDatabase.CREATE_TRIGGERS); - - if (context.getDatabasePath(ClassicOpenHelper.NAME).exists()) { - ClassicOpenHelper legacyHelper = new ClassicOpenHelper(context); - android.database.sqlite.SQLiteDatabase legacyDb = legacyHelper.getWritableDatabase(); - - SQLCipherMigrationHelper.migratePlaintext(context, legacyDb, db); - - MasterSecret masterSecret = KeyCachingService.getMasterSecret(context); - - if (masterSecret != null) SQLCipherMigrationHelper.migrateCiphertext(context, masterSecret, legacyDb, db, null); - else TextSecurePreferences.setNeedsSqlCipherMigration(context, true); - - if (!PreKeyMigrationHelper.migratePreKeys(context, db)) { - ApplicationDependencies.getJobManager().add(new RefreshPreKeysJob()); - } - - SessionStoreMigrationHelper.migrateSessions(context, db); - PreKeyMigrationHelper.cleanUpPreKeys(context); - } - } - - @Override - public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - Log.i(TAG, "Upgrading database: " + oldVersion + ", " + newVersion); - long startTime = System.currentTimeMillis(); - - db.beginTransaction(); - - try { - - if (oldVersion < RECIPIENT_CALL_RINGTONE_VERSION) { - db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN call_ringtone TEXT DEFAULT NULL"); - db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN call_vibrate INTEGER DEFAULT " + RecipientDatabase.VibrateState.DEFAULT.getId()); - } - - if (oldVersion < MIGRATE_PREKEYS_VERSION) { - db.execSQL("CREATE TABLE signed_prekeys (_id INTEGER PRIMARY KEY, key_id INTEGER UNIQUE, public_key TEXT NOT NULL, private_key TEXT NOT NULL, signature TEXT NOT NULL, timestamp INTEGER DEFAULT 0)"); - db.execSQL("CREATE TABLE one_time_prekeys (_id INTEGER PRIMARY KEY, key_id INTEGER UNIQUE, public_key TEXT NOT NULL, private_key TEXT NOT NULL)"); - - if (!PreKeyMigrationHelper.migratePreKeys(context, db)) { - ApplicationDependencies.getJobManager().add(new RefreshPreKeysJob()); - } - } - - if (oldVersion < MIGRATE_SESSIONS_VERSION) { - db.execSQL("CREATE TABLE sessions (_id INTEGER PRIMARY KEY, address TEXT NOT NULL, device INTEGER NOT NULL, record BLOB NOT NULL, UNIQUE(address, device) ON CONFLICT REPLACE)"); - SessionStoreMigrationHelper.migrateSessions(context, db); - } - - if (oldVersion < NO_MORE_IMAGE_THUMBNAILS_VERSION) { - ContentValues update = new ContentValues(); - update.put("thumbnail", (String)null); - update.put("aspect_ratio", (String)null); - update.put("thumbnail_random", (String)null); - - try (Cursor cursor = db.query("part", new String[] {"_id", "ct", "thumbnail"}, "thumbnail IS NOT NULL", null, null, null, null)) { - while (cursor != null && cursor.moveToNext()) { - long id = cursor.getLong(cursor.getColumnIndexOrThrow("_id")); - String contentType = cursor.getString(cursor.getColumnIndexOrThrow("ct")); - - if (contentType != null && !contentType.startsWith("video")) { - String thumbnailPath = cursor.getString(cursor.getColumnIndexOrThrow("thumbnail")); - File thumbnailFile = new File(thumbnailPath); - thumbnailFile.delete(); - - db.update("part", update, "_id = ?", new String[] {String.valueOf(id)}); - } - } - } - } - - if (oldVersion < ATTACHMENT_DIMENSIONS) { - db.execSQL("ALTER TABLE part ADD COLUMN width INTEGER DEFAULT 0"); - db.execSQL("ALTER TABLE part ADD COLUMN height INTEGER DEFAULT 0"); - } - - if (oldVersion < QUOTED_REPLIES) { - db.execSQL("ALTER TABLE mms ADD COLUMN quote_id INTEGER DEFAULT 0"); - db.execSQL("ALTER TABLE mms ADD COLUMN quote_author TEXT"); - db.execSQL("ALTER TABLE mms ADD COLUMN quote_body TEXT"); - db.execSQL("ALTER TABLE mms ADD COLUMN quote_attachment INTEGER DEFAULT -1"); - - db.execSQL("ALTER TABLE part ADD COLUMN quote INTEGER DEFAULT 0"); - } - - if (oldVersion < SHARED_CONTACTS) { - db.execSQL("ALTER TABLE mms ADD COLUMN shared_contacts TEXT"); - } - - if (oldVersion < FULL_TEXT_SEARCH) { - db.execSQL("CREATE VIRTUAL TABLE sms_fts USING fts5(body, content=sms, content_rowid=_id)"); - db.execSQL("CREATE TRIGGER sms_ai AFTER INSERT ON sms BEGIN\n" + - " INSERT INTO sms_fts(rowid, body) VALUES (new._id, new.body);\n" + - "END;"); - db.execSQL("CREATE TRIGGER sms_ad AFTER DELETE ON sms BEGIN\n" + - " INSERT INTO sms_fts(sms_fts, rowid, body) VALUES('delete', old._id, old.body);\n" + - "END;\n"); - db.execSQL("CREATE TRIGGER sms_au AFTER UPDATE ON sms BEGIN\n" + - " INSERT INTO sms_fts(sms_fts, rowid, body) VALUES('delete', old._id, old.body);\n" + - " INSERT INTO sms_fts(rowid, body) VALUES(new._id, new.body);\n" + - "END;"); - - db.execSQL("CREATE VIRTUAL TABLE mms_fts USING fts5(body, content=mms, content_rowid=_id)"); - db.execSQL("CREATE TRIGGER mms_ai AFTER INSERT ON mms BEGIN\n" + - " INSERT INTO mms_fts(rowid, body) VALUES (new._id, new.body);\n" + - "END;"); - db.execSQL("CREATE TRIGGER mms_ad AFTER DELETE ON mms BEGIN\n" + - " INSERT INTO mms_fts(mms_fts, rowid, body) VALUES('delete', old._id, old.body);\n" + - "END;\n"); - db.execSQL("CREATE TRIGGER mms_au AFTER UPDATE ON mms BEGIN\n" + - " INSERT INTO mms_fts(mms_fts, rowid, body) VALUES('delete', old._id, old.body);\n" + - " INSERT INTO mms_fts(rowid, body) VALUES(new._id, new.body);\n" + - "END;"); - - Log.i(TAG, "Beginning to build search index."); - long start = SystemClock.elapsedRealtime(); - - db.execSQL("INSERT INTO sms_fts (rowid, body) SELECT _id, body FROM sms"); - - long smsFinished = SystemClock.elapsedRealtime(); - Log.i(TAG, "Indexing SMS completed in " + (smsFinished - start) + " ms"); - - db.execSQL("INSERT INTO mms_fts (rowid, body) SELECT _id, body FROM mms"); - - long mmsFinished = SystemClock.elapsedRealtime(); - Log.i(TAG, "Indexing MMS completed in " + (mmsFinished - smsFinished) + " ms"); - Log.i(TAG, "Indexing finished. Total time: " + (mmsFinished - start) + " ms"); - } - - if (oldVersion < BAD_IMPORT_CLEANUP) { - String trimmedCondition = " NOT IN (SELECT _id FROM mms)"; - - db.delete("group_receipts", "mms_id" + trimmedCondition, null); - - String[] columns = new String[] { "_id", "unique_id", "_data", "thumbnail"}; - - try (Cursor cursor = db.query("part", columns, "mid" + trimmedCondition, null, null, null, null)) { - while (cursor != null && cursor.moveToNext()) { - db.delete("part", "_id = ? AND unique_id = ?", new String[] { String.valueOf(cursor.getLong(0)), String.valueOf(cursor.getLong(1)) }); - - String data = cursor.getString(2); - String thumbnail = cursor.getString(3); - - if (!TextUtils.isEmpty(data)) { - new File(data).delete(); - } - - if (!TextUtils.isEmpty(thumbnail)) { - new File(thumbnail).delete(); - } - } - } - } - - // Note: This column only being checked due to upgrade issues as described in #8184 - if (oldVersion < QUOTE_MISSING && !SqlUtil.columnExists(db, "mms", "quote_missing")) { - db.execSQL("ALTER TABLE mms ADD COLUMN quote_missing INTEGER DEFAULT 0"); - } - - // Note: The column only being checked due to upgrade issues as described in #8184 - if (oldVersion < NOTIFICATION_CHANNELS && !SqlUtil.columnExists(db, "recipient_preferences", "notification_channel")) { - db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN notification_channel TEXT DEFAULT NULL"); - NotificationChannels.create(context); - - try (Cursor cursor = db.rawQuery("SELECT recipient_ids, system_display_name, signal_profile_name, notification, vibrate FROM recipient_preferences WHERE notification NOT NULL OR vibrate != 0", null)) { - while (cursor != null && cursor.moveToNext()) { - String rawAddress = cursor.getString(cursor.getColumnIndexOrThrow("recipient_ids")); - String address = PhoneNumberFormatter.get(context).format(rawAddress); - String systemName = cursor.getString(cursor.getColumnIndexOrThrow("system_display_name")); - String profileName = cursor.getString(cursor.getColumnIndexOrThrow("signal_profile_name")); - String messageSound = cursor.getString(cursor.getColumnIndexOrThrow("notification")); - Uri messageSoundUri = messageSound != null ? Uri.parse(messageSound) : null; - int vibrateState = cursor.getInt(cursor.getColumnIndexOrThrow("vibrate")); - String displayName = NotificationChannels.getChannelDisplayNameFor(context, systemName, profileName, null, address); - boolean vibrateEnabled = vibrateState == 0 ? SignalStore.settings().isMessageVibrateEnabled() :vibrateState == 1; - - if (GroupId.isEncodedGroup(address)) { - try(Cursor groupCursor = db.rawQuery("SELECT title FROM groups WHERE group_id = ?", new String[] { address })) { - if (groupCursor != null && groupCursor.moveToFirst()) { - String title = groupCursor.getString(groupCursor.getColumnIndexOrThrow("title")); - - if (!TextUtils.isEmpty(title)) { - displayName = title; - } - } - } - } - - String channelId = NotificationChannels.createChannelFor(context, "contact_" + address + "_" + System.currentTimeMillis(), displayName, messageSoundUri, vibrateEnabled, null); - - ContentValues values = new ContentValues(1); - values.put("notification_channel", channelId); - db.update("recipient_preferences", values, "recipient_ids = ?", new String[] { rawAddress }); - } - } - } - - if (oldVersion < SECRET_SENDER) { - db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN unidentified_access_mode INTEGER DEFAULT 0"); - db.execSQL("ALTER TABLE push ADD COLUMN server_timestamp INTEGER DEFAULT 0"); - db.execSQL("ALTER TABLE push ADD COLUMN server_guid TEXT DEFAULT NULL"); - db.execSQL("ALTER TABLE group_receipts ADD COLUMN unidentified INTEGER DEFAULT 0"); - db.execSQL("ALTER TABLE mms ADD COLUMN unidentified INTEGER DEFAULT 0"); - db.execSQL("ALTER TABLE sms ADD COLUMN unidentified INTEGER DEFAULT 0"); - } - - if (oldVersion < ATTACHMENT_CAPTIONS) { - db.execSQL("ALTER TABLE part ADD COLUMN caption TEXT DEFAULT NULL"); - } - - // 4.30.8 included a migration, but not a correct CREATE_TABLE statement, so we need to add - // this column if it isn't present. - if (oldVersion < ATTACHMENT_CAPTIONS_FIX) { - if (!SqlUtil.columnExists(db, "part", "caption")) { - db.execSQL("ALTER TABLE part ADD COLUMN caption TEXT DEFAULT NULL"); - } - } - - if (oldVersion < PREVIEWS) { - db.execSQL("ALTER TABLE mms ADD COLUMN previews TEXT"); - } - - if (oldVersion < CONVERSATION_SEARCH) { - db.execSQL("DROP TABLE sms_fts"); - db.execSQL("DROP TABLE mms_fts"); - db.execSQL("DROP TRIGGER sms_ai"); - db.execSQL("DROP TRIGGER sms_au"); - db.execSQL("DROP TRIGGER sms_ad"); - db.execSQL("DROP TRIGGER mms_ai"); - db.execSQL("DROP TRIGGER mms_au"); - db.execSQL("DROP TRIGGER mms_ad"); - - db.execSQL("CREATE VIRTUAL TABLE sms_fts USING fts5(body, thread_id UNINDEXED, content=sms, content_rowid=_id)"); - db.execSQL("CREATE TRIGGER sms_ai AFTER INSERT ON sms BEGIN\n" + - " INSERT INTO sms_fts(rowid, body, thread_id) VALUES (new._id, new.body, new.thread_id);\n" + - "END;"); - db.execSQL("CREATE TRIGGER sms_ad AFTER DELETE ON sms BEGIN\n" + - " INSERT INTO sms_fts(sms_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id);\n" + - "END;\n"); - db.execSQL("CREATE TRIGGER sms_au AFTER UPDATE ON sms BEGIN\n" + - " INSERT INTO sms_fts(sms_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id);\n" + - " INSERT INTO sms_fts(rowid, body, thread_id) VALUES(new._id, new.body, new.thread_id);\n" + - "END;"); - - db.execSQL("CREATE VIRTUAL TABLE mms_fts USING fts5(body, thread_id UNINDEXED, content=mms, content_rowid=_id)"); - db.execSQL("CREATE TRIGGER mms_ai AFTER INSERT ON mms BEGIN\n" + - " INSERT INTO mms_fts(rowid, body, thread_id) VALUES (new._id, new.body, new.thread_id);\n" + - "END;"); - db.execSQL("CREATE TRIGGER mms_ad AFTER DELETE ON mms BEGIN\n" + - " INSERT INTO mms_fts(mms_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id);\n" + - "END;\n"); - db.execSQL("CREATE TRIGGER mms_au AFTER UPDATE ON mms BEGIN\n" + - " INSERT INTO mms_fts(mms_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id);\n" + - " INSERT INTO mms_fts(rowid, body, thread_id) VALUES(new._id, new.body, new.thread_id);\n" + - "END;"); - - Log.i(TAG, "Beginning to build search index."); - long start = SystemClock.elapsedRealtime(); - - db.execSQL("INSERT INTO sms_fts (rowid, body, thread_id) SELECT _id, body, thread_id FROM sms"); - - long smsFinished = SystemClock.elapsedRealtime(); - Log.i(TAG, "Indexing SMS completed in " + (smsFinished - start) + " ms"); - - db.execSQL("INSERT INTO mms_fts (rowid, body, thread_id) SELECT _id, body, thread_id FROM mms"); - - long mmsFinished = SystemClock.elapsedRealtime(); - Log.i(TAG, "Indexing MMS completed in " + (mmsFinished - smsFinished) + " ms"); - Log.i(TAG, "Indexing finished. Total time: " + (mmsFinished - start) + " ms"); - } - - if (oldVersion < SELF_ATTACHMENT_CLEANUP) { - String localNumber = SignalStore.account().getE164(); - - if (!TextUtils.isEmpty(localNumber)) { - try (Cursor threadCursor = db.rawQuery("SELECT _id FROM thread WHERE recipient_ids = ?", new String[]{ localNumber })) { - if (threadCursor != null && threadCursor.moveToFirst()) { - long threadId = threadCursor.getLong(0); - ContentValues updateValues = new ContentValues(1); - - updateValues.put("pending_push", 0); - - int count = db.update("part", updateValues, "mid IN (SELECT _id FROM mms WHERE thread_id = ?)", new String[]{ String.valueOf(threadId) }); - Log.i(TAG, "Updated " + count + " self-sent attachments."); - } - } - } - } - - if (oldVersion < RECIPIENT_FORCE_SMS_SELECTION) { - db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN force_sms_selection INTEGER DEFAULT 0"); - } - - if (oldVersion < JOBMANAGER_STRIKES_BACK) { - db.execSQL("CREATE TABLE job_spec(_id INTEGER PRIMARY KEY AUTOINCREMENT, " + - "job_spec_id TEXT UNIQUE, " + - "factory_key TEXT, " + - "queue_key TEXT, " + - "create_time INTEGER, " + - "next_run_attempt_time INTEGER, " + - "run_attempt INTEGER, " + - "max_attempts INTEGER, " + - "max_backoff INTEGER, " + - "max_instances INTEGER, " + - "lifespan INTEGER, " + - "serialized_data TEXT, " + - "is_running INTEGER)"); - - db.execSQL("CREATE TABLE constraint_spec(_id INTEGER PRIMARY KEY AUTOINCREMENT, " + - "job_spec_id TEXT, " + - "factory_key TEXT, " + - "UNIQUE(job_spec_id, factory_key))"); - - db.execSQL("CREATE TABLE dependency_spec(_id INTEGER PRIMARY KEY AUTOINCREMENT, " + - "job_spec_id TEXT, " + - "depends_on_job_spec_id TEXT, " + - "UNIQUE(job_spec_id, depends_on_job_spec_id))"); - } - - if (oldVersion < STICKERS) { - db.execSQL("CREATE TABLE sticker (_id INTEGER PRIMARY KEY AUTOINCREMENT, " + - "pack_id TEXT NOT NULL, " + - "pack_key TEXT NOT NULL, " + - "pack_title TEXT NOT NULL, " + - "pack_author TEXT NOT NULL, " + - "sticker_id INTEGER, " + - "cover INTEGER, " + - "emoji TEXT NOT NULL, " + - "last_used INTEGER, " + - "installed INTEGER," + - "file_path TEXT NOT NULL, " + - "file_length INTEGER, " + - "file_random BLOB, " + - "UNIQUE(pack_id, sticker_id, cover) ON CONFLICT IGNORE)"); - - db.execSQL("CREATE INDEX IF NOT EXISTS sticker_pack_id_index ON sticker (pack_id);"); - db.execSQL("CREATE INDEX IF NOT EXISTS sticker_sticker_id_index ON sticker (sticker_id);"); - - db.execSQL("ALTER TABLE part ADD COLUMN sticker_pack_id TEXT"); - db.execSQL("ALTER TABLE part ADD COLUMN sticker_pack_key TEXT"); - db.execSQL("ALTER TABLE part ADD COLUMN sticker_id INTEGER DEFAULT -1"); - db.execSQL("CREATE INDEX IF NOT EXISTS part_sticker_pack_id_index ON part (sticker_pack_id)"); - } - - if (oldVersion < REVEALABLE_MESSAGES) { - db.execSQL("ALTER TABLE mms ADD COLUMN reveal_duration INTEGER DEFAULT 0"); - db.execSQL("ALTER TABLE mms ADD COLUMN reveal_start_time INTEGER DEFAULT 0"); - - db.execSQL("ALTER TABLE thread ADD COLUMN snippet_content_type TEXT DEFAULT NULL"); - db.execSQL("ALTER TABLE thread ADD COLUMN snippet_extras TEXT DEFAULT NULL"); - } - - if (oldVersion < VIEW_ONCE_ONLY) { - db.execSQL("UPDATE mms SET reveal_duration = 1 WHERE reveal_duration > 0"); - db.execSQL("UPDATE mms SET reveal_start_time = 0"); - } - - if (oldVersion < RECIPIENT_IDS) { - RecipientIdMigrationHelper.execute(db); - } - - if (oldVersion < RECIPIENT_SEARCH) { - db.execSQL("ALTER TABLE recipient ADD COLUMN system_phone_type INTEGER DEFAULT -1"); - - String localNumber = SignalStore.account().getE164(); - if (!TextUtils.isEmpty(localNumber)) { - try (Cursor cursor = db.query("recipient", null, "phone = ?", new String[] { localNumber }, null, null, null)) { - if (cursor == null || !cursor.moveToFirst()) { - ContentValues values = new ContentValues(); - values.put("phone", localNumber); - values.put("registered", 1); - values.put("profile_sharing", 1); - db.insert("recipient", null, values); - } else { - db.execSQL("UPDATE recipient SET registered = ?, profile_sharing = ? WHERE phone = ?", - new String[] { "1", "1", localNumber }); - } - } - } - } - - if (oldVersion < RECIPIENT_CLEANUP) { - RecipientIdCleanupHelper.execute(db); - } - - if (oldVersion < MMS_RECIPIENT_CLEANUP) { - ContentValues values = new ContentValues(1); - values.put("address", "-1"); - int count = db.update("mms", values, "address = ?", new String[] { "0" }); - Log.i(TAG, "MMS recipient cleanup updated " + count + " rows."); - } - - if (oldVersion < ATTACHMENT_HASHING) { - db.execSQL("ALTER TABLE part ADD COLUMN data_hash TEXT DEFAULT NULL"); - db.execSQL("CREATE INDEX IF NOT EXISTS part_data_hash_index ON part (data_hash)"); - } - - if (oldVersion < NOTIFICATION_RECIPIENT_IDS && Build.VERSION.SDK_INT >= 26) { - NotificationManager notificationManager = ServiceUtil.getNotificationManager(context); - List channels = Stream.of(notificationManager.getNotificationChannels()) - .filter(c -> c.getId().startsWith("contact_")) - .toList(); - - Log.i(TAG, "Migrating " + channels.size() + " channels to use RecipientId's."); - - for (NotificationChannel oldChannel : channels) { - notificationManager.deleteNotificationChannel(oldChannel.getId()); - - int startIndex = "contact_".length(); - int endIndex = oldChannel.getId().lastIndexOf("_"); - String address = oldChannel.getId().substring(startIndex, endIndex); - - String recipientId; - - try (Cursor cursor = db.query("recipient", new String[] { "_id" }, "phone = ? OR email = ? OR group_id = ?", new String[] { address, address, address}, null, null, null)) { - if (cursor != null && cursor.moveToFirst()) { - recipientId = cursor.getString(cursor.getColumnIndexOrThrow("_id")); - } else { - Log.w(TAG, "Couldn't find recipient for address: " + address); - continue; - } - } - - String newId = "contact_" + recipientId + "_" + System.currentTimeMillis(); - NotificationChannel newChannel = new NotificationChannel(newId, oldChannel.getName(), oldChannel.getImportance()); - - Log.i(TAG, "Updating channel ID from '" + oldChannel.getId() + "' to '" + newChannel.getId() + "'."); - - newChannel.setGroup(oldChannel.getGroup()); - newChannel.setSound(oldChannel.getSound(), oldChannel.getAudioAttributes()); - newChannel.setBypassDnd(oldChannel.canBypassDnd()); - newChannel.enableVibration(oldChannel.shouldVibrate()); - newChannel.setVibrationPattern(oldChannel.getVibrationPattern()); - newChannel.setLockscreenVisibility(oldChannel.getLockscreenVisibility()); - newChannel.setShowBadge(oldChannel.canShowBadge()); - newChannel.setLightColor(oldChannel.getLightColor()); - newChannel.enableLights(oldChannel.shouldShowLights()); - - notificationManager.createNotificationChannel(newChannel); - - ContentValues contentValues = new ContentValues(1); - contentValues.put("notification_channel", newChannel.getId()); - db.update("recipient", contentValues, "_id = ?", new String[] { recipientId }); - } - } - - if (oldVersion < BLUR_HASH) { - db.execSQL("ALTER TABLE part ADD COLUMN blur_hash TEXT DEFAULT NULL"); - } - - if (oldVersion < MMS_RECIPIENT_CLEANUP_2) { - ContentValues values = new ContentValues(1); - values.put("address", "-1"); - int count = db.update("mms", values, "address = ? OR address IS NULL", new String[] { "0" }); - Log.i(TAG, "MMS recipient cleanup 2 updated " + count + " rows."); - } - - if (oldVersion < ATTACHMENT_TRANSFORM_PROPERTIES) { - db.execSQL("ALTER TABLE part ADD COLUMN transform_properties TEXT DEFAULT NULL"); - } - - if (oldVersion < ATTACHMENT_CLEAR_HASHES) { - db.execSQL("UPDATE part SET data_hash = null"); - } - - if (oldVersion < ATTACHMENT_CLEAR_HASHES_2) { - db.execSQL("UPDATE part SET data_hash = null"); - Glide.get(context).clearDiskCache(); - } - - if (oldVersion < UUIDS) { - db.execSQL("ALTER TABLE recipient ADD COLUMN uuid_supported INTEGER DEFAULT 0"); - db.execSQL("ALTER TABLE push ADD COLUMN source_uuid TEXT DEFAULT NULL"); - } - - if (oldVersion < USERNAMES) { - db.execSQL("ALTER TABLE recipient ADD COLUMN username TEXT DEFAULT NULL"); - db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS recipient_username_index ON recipient (username)"); - } - - if (oldVersion < REACTIONS) { - db.execSQL("ALTER TABLE sms ADD COLUMN reactions BLOB DEFAULT NULL"); - db.execSQL("ALTER TABLE mms ADD COLUMN reactions BLOB DEFAULT NULL"); - - db.execSQL("ALTER TABLE sms ADD COLUMN reactions_unread INTEGER DEFAULT 0"); - db.execSQL("ALTER TABLE mms ADD COLUMN reactions_unread INTEGER DEFAULT 0"); - - db.execSQL("ALTER TABLE sms ADD COLUMN reactions_last_seen INTEGER DEFAULT -1"); - db.execSQL("ALTER TABLE mms ADD COLUMN reactions_last_seen INTEGER DEFAULT -1"); - } - - if (oldVersion < STORAGE_SERVICE) { - db.execSQL("CREATE TABLE storage_key (_id INTEGER PRIMARY KEY AUTOINCREMENT, " + - "type INTEGER, " + - "key TEXT UNIQUE)"); - db.execSQL("CREATE INDEX IF NOT EXISTS storage_key_type_index ON storage_key (type)"); - - db.execSQL("ALTER TABLE recipient ADD COLUMN system_info_pending INTEGER DEFAULT 0"); - db.execSQL("ALTER TABLE recipient ADD COLUMN storage_service_key TEXT DEFAULT NULL"); - db.execSQL("ALTER TABLE recipient ADD COLUMN dirty INTEGER DEFAULT 0"); - - db.execSQL("CREATE UNIQUE INDEX recipient_storage_service_key ON recipient (storage_service_key)"); - db.execSQL("CREATE INDEX recipient_dirty_index ON recipient (dirty)"); - } - - if (oldVersion < REACTIONS_UNREAD_INDEX) { - db.execSQL("CREATE INDEX IF NOT EXISTS sms_reactions_unread_index ON sms (reactions_unread);"); - db.execSQL("CREATE INDEX IF NOT EXISTS mms_reactions_unread_index ON mms (reactions_unread);"); - } - - if (oldVersion < RESUMABLE_DOWNLOADS) { - db.execSQL("ALTER TABLE part ADD COLUMN transfer_file TEXT DEFAULT NULL"); - } - - if (oldVersion < KEY_VALUE_STORE) { - db.execSQL("CREATE TABLE key_value (_id INTEGER PRIMARY KEY AUTOINCREMENT, " + - "key TEXT UNIQUE, " + - "value TEXT, " + - "type INTEGER)"); - } - - if (oldVersion < ATTACHMENT_DISPLAY_ORDER) { - db.execSQL("ALTER TABLE part ADD COLUMN display_order INTEGER DEFAULT 0"); - } - - if (oldVersion < SPLIT_PROFILE_NAMES) { - db.execSQL("ALTER TABLE recipient ADD COLUMN profile_family_name TEXT DEFAULT NULL"); - db.execSQL("ALTER TABLE recipient ADD COLUMN profile_joined_name TEXT DEFAULT NULL"); - } - - if (oldVersion < STICKER_PACK_ORDER) { - db.execSQL("ALTER TABLE sticker ADD COLUMN pack_order INTEGER DEFAULT 0"); - } - - if (oldVersion < MEGAPHONES) { - db.execSQL("CREATE TABLE megaphone (_id INTEGER PRIMARY KEY AUTOINCREMENT, " + - "event TEXT UNIQUE, " + - "seen_count INTEGER, " + - "last_seen INTEGER, " + - "finished INTEGER)"); - } - - if (oldVersion < MEGAPHONE_FIRST_APPEARANCE) { - db.execSQL("ALTER TABLE megaphone ADD COLUMN first_visible INTEGER DEFAULT 0"); - } - - if (oldVersion < PROFILE_KEY_TO_DB) { - String localNumber = SignalStore.account().getE164(); - if (!TextUtils.isEmpty(localNumber)) { - String encodedProfileKey = PreferenceManager.getDefaultSharedPreferences(context).getString("pref_profile_key", null); - byte[] profileKey = encodedProfileKey != null ? Base64.decodeOrThrow(encodedProfileKey) : Util.getSecretBytes(32); - ContentValues values = new ContentValues(1); - - values.put("profile_key", Base64.encodeBytes(profileKey)); - - if (db.update("recipient", values, "phone = ?", new String[]{localNumber}) == 0) { - throw new AssertionError("No rows updated!"); - } - } - } - - if (oldVersion < PROFILE_KEY_CREDENTIALS) { - db.execSQL("ALTER TABLE recipient ADD COLUMN profile_key_credential TEXT DEFAULT NULL"); - } - - if (oldVersion < ATTACHMENT_FILE_INDEX) { - db.execSQL("CREATE INDEX IF NOT EXISTS part_data_index ON part (_data)"); - } - - if (oldVersion < STORAGE_SERVICE_ACTIVE) { - db.execSQL("ALTER TABLE recipient ADD COLUMN group_type INTEGER DEFAULT 0"); - db.execSQL("CREATE INDEX IF NOT EXISTS recipient_group_type_index ON recipient (group_type)"); - - db.execSQL("UPDATE recipient set group_type = 1 WHERE group_id NOT NULL AND group_id LIKE '__signal_mms_group__%'"); - db.execSQL("UPDATE recipient set group_type = 2 WHERE group_id NOT NULL AND group_id LIKE '__textsecure_group__%'"); - - try (Cursor cursor = db.rawQuery("SELECT _id FROM recipient WHERE registered = 1 or group_type = 2", null)) { - while (cursor != null && cursor.moveToNext()) { - String id = cursor.getString(cursor.getColumnIndexOrThrow("_id")); - ContentValues values = new ContentValues(1); - - values.put("dirty", 2); - values.put("storage_service_key", Base64.encodeBytes(StorageSyncHelper.generateKey())); - - db.update("recipient", values, "_id = ?", new String[] { id }); - } - } - } - - if (oldVersion < GROUPS_V2_RECIPIENT_CAPABILITY) { - db.execSQL("ALTER TABLE recipient ADD COLUMN gv2_capability INTEGER DEFAULT 0"); - } - - if (oldVersion < TRANSFER_FILE_CLEANUP) { - File partsDirectory = context.getDir("parts", Context.MODE_PRIVATE); - - if (partsDirectory.exists()) { - File[] transferFiles = partsDirectory.listFiles((dir, name) -> name.startsWith("transfer")); - int deleteCount = 0; - - Log.i(TAG, "Found " + transferFiles.length + " dangling transfer files."); - - for (File file : transferFiles) { - if (file.delete()) { - Log.i(TAG, "Deleted " + file.getName()); - deleteCount++; - } - } - - Log.i(TAG, "Deleted " + deleteCount + " dangling transfer files."); - } else { - Log.w(TAG, "Part directory did not exist. Skipping."); - } - } - - if (oldVersion < PROFILE_DATA_MIGRATION) { - String localNumber = SignalStore.account().getE164(); - if (localNumber != null) { - String encodedProfileName = PreferenceManager.getDefaultSharedPreferences(context).getString("pref_profile_name", null); - ProfileName profileName = ProfileName.fromSerialized(encodedProfileName); - - db.execSQL("UPDATE recipient SET signal_profile_name = ?, profile_family_name = ?, profile_joined_name = ? WHERE phone = ?", - new String[] { profileName.getGivenName(), profileName.getFamilyName(), profileName.toString(), localNumber }); - } - } - - if (oldVersion < AVATAR_LOCATION_MIGRATION) { - File oldAvatarDirectory = new File(context.getFilesDir(), "avatars"); - File[] results = oldAvatarDirectory.listFiles(); - - if (results != null) { - Log.i(TAG, "Preparing to migrate " + results.length + " avatars."); - - for (File file : results) { - if (Util.isLong(file.getName())) { - try { - AvatarHelper.setAvatar(context, RecipientId.from(file.getName()), new FileInputStream(file)); - } catch(IOException e) { - Log.w(TAG, "Failed to copy file " + file.getName() + "! Skipping."); - } - } else { - Log.w(TAG, "Invalid avatar name '" + file.getName() + "'! Skipping."); - } - } - } else { - Log.w(TAG, "No avatar directory files found."); - } - - if (!FileUtils.deleteDirectory(oldAvatarDirectory)) { - Log.w(TAG, "Failed to delete avatar directory."); - } - - try (Cursor cursor = db.rawQuery("SELECT recipient_id, avatar FROM groups", null)) { - while (cursor != null && cursor.moveToNext()) { - RecipientId recipientId = RecipientId.from(cursor.getLong(cursor.getColumnIndexOrThrow("recipient_id"))); - byte[] avatar = cursor.getBlob(cursor.getColumnIndexOrThrow("avatar")); - - try { - AvatarHelper.setAvatar(context, recipientId, avatar != null ? new ByteArrayInputStream(avatar) : null); - } catch (IOException e) { - Log.w(TAG, "Failed to copy avatar for " + recipientId + "! Skipping.", e); - } - } - } - - db.execSQL("UPDATE groups SET avatar_id = 0 WHERE avatar IS NULL"); - db.execSQL("UPDATE groups SET avatar = NULL"); - } - - if (oldVersion < GROUPS_V2) { - db.execSQL("ALTER TABLE groups ADD COLUMN master_key"); - db.execSQL("ALTER TABLE groups ADD COLUMN revision"); - db.execSQL("ALTER TABLE groups ADD COLUMN decrypted_group"); - } - - if (oldVersion < ATTACHMENT_UPLOAD_TIMESTAMP) { - db.execSQL("ALTER TABLE part ADD COLUMN upload_timestamp DEFAULT 0"); - } - - if (oldVersion < ATTACHMENT_CDN_NUMBER) { - db.execSQL("ALTER TABLE part ADD COLUMN cdn_number INTEGER DEFAULT 0"); - } - - if (oldVersion < JOB_INPUT_DATA) { - db.execSQL("ALTER TABLE job_spec ADD COLUMN serialized_input_data TEXT DEFAULT NULL"); - } - - if (oldVersion < SERVER_TIMESTAMP) { - db.execSQL("ALTER TABLE sms ADD COLUMN date_server INTEGER DEFAULT -1"); - db.execSQL("CREATE INDEX IF NOT EXISTS sms_date_server_index ON sms (date_server)"); - - db.execSQL("ALTER TABLE mms ADD COLUMN date_server INTEGER DEFAULT -1"); - db.execSQL("CREATE INDEX IF NOT EXISTS mms_date_server_index ON mms (date_server)"); - } - - if (oldVersion < REMOTE_DELETE) { - db.execSQL("ALTER TABLE sms ADD COLUMN remote_deleted INTEGER DEFAULT 0"); - db.execSQL("ALTER TABLE mms ADD COLUMN remote_deleted INTEGER DEFAULT 0"); - } - - if (oldVersion < COLOR_MIGRATION) { - try (Cursor cursor = db.rawQuery("SELECT _id, system_display_name FROM recipient WHERE system_display_name NOT NULL AND color IS NULL", null)) { - while (cursor != null && cursor.moveToNext()) { - long id = cursor.getLong(cursor.getColumnIndexOrThrow("_id")); - String name = cursor.getString(cursor.getColumnIndexOrThrow("system_display_name")); - - ContentValues values = new ContentValues(); - values.put("color", ContactColorsLegacy.generateForV2(name).serialize()); - - db.update("recipient", values, "_id = ?", new String[] { String.valueOf(id) }); - } - } - } - - if (oldVersion < LAST_SCROLLED) { - db.execSQL("ALTER TABLE thread ADD COLUMN last_scrolled INTEGER DEFAULT 0"); - } - - if (oldVersion < LAST_PROFILE_FETCH) { - db.execSQL("ALTER TABLE recipient ADD COLUMN last_profile_fetch INTEGER DEFAULT 0"); - } - - if (oldVersion < SERVER_DELIVERED_TIMESTAMP) { - db.execSQL("ALTER TABLE push ADD COLUMN server_delivered_timestamp INTEGER DEFAULT 0"); - } - - if (oldVersion < QUOTE_CLEANUP) { - String query = "SELECT _data " + - "FROM (SELECT _data, MIN(quote) AS all_quotes " + - "FROM part " + - "WHERE _data NOT NULL AND data_hash NOT NULL " + - "GROUP BY _data) " + - "WHERE all_quotes = 1"; - - int count = 0; - - try (Cursor cursor = db.rawQuery(query, null)) { - while (cursor != null && cursor.moveToNext()) { - String data = cursor.getString(cursor.getColumnIndexOrThrow("_data")); - - if (new File(data).delete()) { - ContentValues values = new ContentValues(); - values.putNull("_data"); - values.putNull("data_random"); - values.putNull("thumbnail"); - values.putNull("thumbnail_random"); - values.putNull("data_hash"); - db.update("part", values, "_data = ?", new String[] { data }); - - count++; - } else { - Log.w(TAG, "[QuoteCleanup] Failed to delete " + data); - } - } - } - - Log.i(TAG, "[QuoteCleanup] Cleaned up " + count + " quotes."); - } - - if (oldVersion < BORDERLESS) { - db.execSQL("ALTER TABLE part ADD COLUMN borderless INTEGER DEFAULT 0"); - } - - if (oldVersion < REMAPPED_RECORDS) { - db.execSQL("CREATE TABLE remapped_recipients (_id INTEGER PRIMARY KEY AUTOINCREMENT, " + - "old_id INTEGER UNIQUE, " + - "new_id INTEGER)"); - db.execSQL("CREATE TABLE remapped_threads (_id INTEGER PRIMARY KEY AUTOINCREMENT, " + - "old_id INTEGER UNIQUE, " + - "new_id INTEGER)"); - } - - if (oldVersion < MENTIONS) { - db.execSQL("CREATE TABLE mention (_id INTEGER PRIMARY KEY AUTOINCREMENT, " + - "thread_id INTEGER, " + - "message_id INTEGER, " + - "recipient_id INTEGER, " + - "range_start INTEGER, " + - "range_length INTEGER)"); - - db.execSQL("CREATE INDEX IF NOT EXISTS mention_message_id_index ON mention (message_id)"); - db.execSQL("CREATE INDEX IF NOT EXISTS mention_recipient_id_thread_id_index ON mention (recipient_id, thread_id);"); - - db.execSQL("ALTER TABLE mms ADD COLUMN quote_mentions BLOB DEFAULT NULL"); - db.execSQL("ALTER TABLE mms ADD COLUMN mentions_self INTEGER DEFAULT 0"); - - db.execSQL("ALTER TABLE recipient ADD COLUMN mention_setting INTEGER DEFAULT 0"); - } - - if (oldVersion < PINNED_CONVERSATIONS) { - db.execSQL("ALTER TABLE thread ADD COLUMN pinned INTEGER DEFAULT 0"); - db.execSQL("CREATE INDEX IF NOT EXISTS thread_pinned_index ON thread (pinned)"); - } - - if (oldVersion < MENTION_GLOBAL_SETTING_MIGRATION) { - ContentValues updateAlways = new ContentValues(); - updateAlways.put("mention_setting", 0); - db.update("recipient", updateAlways, "mention_setting = 1", null); - - ContentValues updateNever = new ContentValues(); - updateNever.put("mention_setting", 1); - db.update("recipient", updateNever, "mention_setting = 2", null); - } - - if (oldVersion < UNKNOWN_STORAGE_FIELDS) { - db.execSQL("ALTER TABLE recipient ADD COLUMN storage_proto TEXT DEFAULT NULL"); - } - - if (oldVersion < STICKER_CONTENT_TYPE) { - db.execSQL("ALTER TABLE sticker ADD COLUMN content_type TEXT DEFAULT NULL"); - } - - if (oldVersion < STICKER_EMOJI_IN_NOTIFICATIONS) { - db.execSQL("ALTER TABLE part ADD COLUMN sticker_emoji TEXT DEFAULT NULL"); - } - - if (oldVersion < THUMBNAIL_CLEANUP) { - int total = 0; - int deleted = 0; - - try (Cursor cursor = db.rawQuery("SELECT thumbnail FROM part WHERE thumbnail NOT NULL", null)) { - if (cursor != null) { - total = cursor.getCount(); - Log.w(TAG, "Found " + total + " thumbnails to delete."); - } - - while (cursor != null && cursor.moveToNext()) { - File file = new File(CursorUtil.requireString(cursor, "thumbnail")); - - if (file.delete()) { - deleted++; - } else { - Log.w(TAG, "Failed to delete file! " + file.getAbsolutePath()); - } - } - } - - Log.w(TAG, "Deleted " + deleted + "/" + total + " thumbnail files."); - } - - if (oldVersion < STICKER_CONTENT_TYPE_CLEANUP) { - ContentValues values = new ContentValues(); - values.put("ct", "image/webp"); - - String query = "sticker_id NOT NULL AND (ct IS NULL OR ct = '')"; - - int rows = db.update("part", values, query, null); - Log.i(TAG, "Updated " + rows + " sticker attachment content types."); - } - - if (oldVersion < MENTION_CLEANUP) { - String selectMentionIdsNotInGroupsV2 = "select mention._id from mention left join thread on mention.thread_id = thread._id left join recipient on thread.recipient_ids = recipient._id where recipient.group_type != 3"; - db.delete("mention", "_id in (" + selectMentionIdsNotInGroupsV2 + ")", null); - db.delete("mention", "message_id NOT IN (SELECT _id FROM mms) OR thread_id NOT IN (SELECT _id from thread)", null); - - List idsToDelete = new LinkedList<>(); - try (Cursor cursor = db.rawQuery("select mention.*, mms.body from mention inner join mms on mention.message_id = mms._id", null)) { - while (cursor != null && cursor.moveToNext()) { - int rangeStart = CursorUtil.requireInt(cursor, "range_start"); - int rangeLength = CursorUtil.requireInt(cursor, "range_length"); - String body = CursorUtil.requireString(cursor, "body"); - - if (body == null || body.isEmpty() || rangeStart < 0 || rangeLength < 0 || (rangeStart + rangeLength) > body.length()) { - idsToDelete.add(CursorUtil.requireLong(cursor, "_id")); - } - } - } - - if (Util.hasItems(idsToDelete)) { - String ids = TextUtils.join(",", idsToDelete); - db.delete("mention", "_id in (" + ids + ")", null); - } - } - - if (oldVersion < MENTION_CLEANUP_V2) { - String selectMentionIdsWithMismatchingThreadIds = "select mention._id from mention left join mms on mention.message_id = mms._id where mention.thread_id != mms.thread_id"; - db.delete("mention", "_id in (" + selectMentionIdsWithMismatchingThreadIds + ")", null); - - List idsToDelete = new LinkedList<>(); - Set> mentionTuples = new HashSet<>(); - try (Cursor cursor = db.rawQuery("select mention.*, mms.body from mention inner join mms on mention.message_id = mms._id order by mention._id desc", null)) { - while (cursor != null && cursor.moveToNext()) { - long mentionId = CursorUtil.requireLong(cursor, "_id"); - long messageId = CursorUtil.requireLong(cursor, "message_id"); - int rangeStart = CursorUtil.requireInt(cursor, "range_start"); - int rangeLength = CursorUtil.requireInt(cursor, "range_length"); - String body = CursorUtil.requireString(cursor, "body"); - - if (body != null && rangeStart < body.length() && body.charAt(rangeStart) != '\uFFFC') { - idsToDelete.add(mentionId); - } else { - Triple tuple = new Triple<>(messageId, rangeStart, rangeLength); - if (mentionTuples.contains(tuple)) { - idsToDelete.add(mentionId); - } else { - mentionTuples.add(tuple); - } - } - } - - if (Util.hasItems(idsToDelete)) { - String ids = TextUtils.join(",", idsToDelete); - db.delete("mention", "_id in (" + ids + ")", null); - } - } - } - - if (oldVersion < REACTION_CLEANUP) { - ContentValues values = new ContentValues(); - values.putNull("reactions"); - db.update("sms", values, "remote_deleted = ?", new String[] { "1" }); - } - - if (oldVersion < CAPABILITIES_REFACTOR) { - db.execSQL("ALTER TABLE recipient ADD COLUMN capabilities INTEGER DEFAULT 0"); - - db.execSQL("UPDATE recipient SET capabilities = 1 WHERE gv2_capability = 1"); - db.execSQL("UPDATE recipient SET capabilities = 2 WHERE gv2_capability = -1"); - } - - if (oldVersion < GV1_MIGRATION) { - db.execSQL("ALTER TABLE groups ADD COLUMN expected_v2_id TEXT DEFAULT NULL"); - db.execSQL("ALTER TABLE groups ADD COLUMN former_v1_members TEXT DEFAULT NULL"); - db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS expected_v2_id_index ON groups (expected_v2_id)"); - - int count = 0; - try (Cursor cursor = db.rawQuery("SELECT * FROM groups WHERE group_id LIKE '__textsecure_group__!%' AND LENGTH(group_id) = 53", null)) { - while (cursor.moveToNext()) { - String gv1 = CursorUtil.requireString(cursor, "group_id"); - String gv2 = GroupId.parseOrThrow(gv1).requireV1().deriveV2MigrationGroupId().toString(); - - ContentValues values = new ContentValues(); - values.put("expected_v2_id", gv2); - count += db.update("groups", values, "group_id = ?", SqlUtil.buildArgs(gv1)); - } - } - - Log.i(TAG, "Updated " + count + " GV1 groups with expected GV2 IDs."); - } - - if (oldVersion < NOTIFIED_TIMESTAMP) { - db.execSQL("ALTER TABLE sms ADD COLUMN notified_timestamp INTEGER DEFAULT 0"); - db.execSQL("ALTER TABLE mms ADD COLUMN notified_timestamp INTEGER DEFAULT 0"); - } - - if (oldVersion < GV1_MIGRATION_LAST_SEEN) { - db.execSQL("ALTER TABLE recipient ADD COLUMN last_gv1_migrate_reminder INTEGER DEFAULT 0"); - } - - if (oldVersion < VIEWED_RECEIPTS) { - db.execSQL("ALTER TABLE mms ADD COLUMN viewed_receipt_count INTEGER DEFAULT 0"); - } - - if (oldVersion < CLEAN_UP_GV1_IDS) { - List deletableRecipients = new LinkedList<>(); - try (Cursor cursor = db.rawQuery("SELECT _id, group_id FROM recipient\n" + - "WHERE group_id NOT IN (SELECT group_id FROM groups)\n" + - "AND group_id LIKE '__textsecure_group__!%' AND length(group_id) <> 53\n" + - "AND (_id NOT IN (SELECT recipient_ids FROM thread) OR _id IN (SELECT recipient_ids FROM thread WHERE message_count = 0))", null)) - { - while (cursor.moveToNext()) { - String recipientId = cursor.getString(cursor.getColumnIndexOrThrow("_id")); - String groupIdV1 = cursor.getString(cursor.getColumnIndexOrThrow("group_id")); - deletableRecipients.add(recipientId); - Log.d(TAG, String.format(Locale.US, "Found invalid GV1 on %s with no or empty thread %s length %d", recipientId, groupIdV1, groupIdV1.length())); - } - } - - for (String recipientId : deletableRecipients) { - db.delete("recipient", "_id = ?", new String[]{recipientId}); - Log.d(TAG, "Deleted recipient " + recipientId); - } - - List orphanedThreads = new LinkedList<>(); - try (Cursor cursor = db.rawQuery("SELECT _id FROM thread WHERE message_count = 0 AND recipient_ids NOT IN (SELECT _id FROM recipient)", null)) { - while (cursor.moveToNext()) { - orphanedThreads.add(cursor.getString(cursor.getColumnIndexOrThrow("_id"))); - } - } - - for (String orphanedThreadId : orphanedThreads) { - db.delete("thread", "_id = ?", new String[]{orphanedThreadId}); - Log.d(TAG, "Deleted orphaned thread " + orphanedThreadId); - } - - List remainingInvalidGV1Recipients = new LinkedList<>(); - try (Cursor cursor = db.rawQuery("SELECT _id, group_id FROM recipient\n" + - "WHERE group_id NOT IN (SELECT group_id FROM groups)\n" + - "AND group_id LIKE '__textsecure_group__!%' AND length(group_id) <> 53\n" + - "AND _id IN (SELECT recipient_ids FROM thread)", null)) - { - while (cursor.moveToNext()) { - String recipientId = cursor.getString(cursor.getColumnIndexOrThrow("_id")); - String groupIdV1 = cursor.getString(cursor.getColumnIndexOrThrow("group_id")); - remainingInvalidGV1Recipients.add(recipientId); - Log.d(TAG, String.format(Locale.US, "Found invalid GV1 on %s with non-empty thread %s length %d", recipientId, groupIdV1, groupIdV1.length())); - } - } - - for (String recipientId : remainingInvalidGV1Recipients) { - String newId = "__textsecure_group__!" + Hex.toStringCondensed(Util.getSecretBytes(16)); - ContentValues values = new ContentValues(1); - values.put("group_id", newId); - - db.update("recipient", values, "_id = ?", new String[] { String.valueOf(recipientId) }); - Log.d(TAG, String.format("Replaced group id on recipient %s now %s", recipientId, newId)); - } - } - - if (oldVersion < GV1_MIGRATION_REFACTOR) { - ContentValues values = new ContentValues(1); - values.putNull("former_v1_members"); - - int count = db.update("groups", values, "former_v1_members NOT NULL", null); - - Log.i(TAG, "Cleared former_v1_members for " + count + " rows"); - } - - if (oldVersion < CLEAR_PROFILE_KEY_CREDENTIALS) { - ContentValues values = new ContentValues(1); - values.putNull("profile_key_credential"); - - int count = db.update("recipient", values, "profile_key_credential NOT NULL", null); - - Log.i(TAG, "Cleared profile key credentials for " + count + " rows"); - } - - if (oldVersion < LAST_RESET_SESSION_TIME) { - db.execSQL("ALTER TABLE recipient ADD COLUMN last_session_reset BLOB DEFAULT NULL"); - } - - if (oldVersion < WALLPAPER) { - db.execSQL("ALTER TABLE recipient ADD COLUMN wallpaper BLOB DEFAULT NULL"); - db.execSQL("ALTER TABLE recipient ADD COLUMN wallpaper_file TEXT DEFAULT NULL"); - } - - if (oldVersion < ABOUT) { - db.execSQL("ALTER TABLE recipient ADD COLUMN about TEXT DEFAULT NULL"); - db.execSQL("ALTER TABLE recipient ADD COLUMN about_emoji TEXT DEFAULT NULL"); - } - - if (oldVersion < SPLIT_SYSTEM_NAMES) { - db.execSQL("ALTER TABLE recipient ADD COLUMN system_family_name TEXT DEFAULT NULL"); - db.execSQL("ALTER TABLE recipient ADD COLUMN system_given_name TEXT DEFAULT NULL"); - db.execSQL("UPDATE recipient SET system_given_name = system_display_name"); - } - - if (oldVersion < PAYMENTS) { - db.execSQL("CREATE TABLE payments(_id INTEGER PRIMARY KEY, " + - "uuid TEXT DEFAULT NULL, " + - "recipient INTEGER DEFAULT 0, " + - "recipient_address TEXT DEFAULT NULL, " + - "timestamp INTEGER, " + - "note TEXT DEFAULT NULL, " + - "direction INTEGER, " + - "state INTEGER, " + - "failure_reason INTEGER, " + - "amount BLOB NOT NULL, " + - "fee BLOB NOT NULL, " + - "transaction_record BLOB DEFAULT NULL, " + - "receipt BLOB DEFAULT NULL, " + - "payment_metadata BLOB DEFAULT NULL, " + - "receipt_public_key TEXT DEFAULT NULL, " + - "block_index INTEGER DEFAULT 0, " + - "block_timestamp INTEGER DEFAULT 0, " + - "seen INTEGER, " + - "UNIQUE(uuid) ON CONFLICT ABORT)"); - - db.execSQL("CREATE INDEX IF NOT EXISTS timestamp_direction_index ON payments (timestamp, direction);"); - db.execSQL("CREATE INDEX IF NOT EXISTS timestamp_index ON payments (timestamp);"); - db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS receipt_public_key_index ON payments (receipt_public_key);"); - } - - if (oldVersion < CLEAN_STORAGE_IDS) { - ContentValues values = new ContentValues(); - values.putNull("storage_service_key"); - int count = db.update("recipient", values, "storage_service_key NOT NULL AND ((phone NOT NULL AND INSTR(phone, '+') = 0) OR (group_id NOT NULL AND (LENGTH(group_id) != 85 and LENGTH(group_id) != 53)))", null); - Log.i(TAG, "There were " + count + " bad rows that had their storageID removed."); - } - - if (oldVersion < MP4_GIF_SUPPORT) { - db.execSQL("ALTER TABLE part ADD COLUMN video_gif INTEGER DEFAULT 0"); - } - - if (oldVersion < BLUR_AVATARS) { - db.execSQL("ALTER TABLE recipient ADD COLUMN extras BLOB DEFAULT NULL"); - db.execSQL("ALTER TABLE recipient ADD COLUMN groups_in_common INTEGER DEFAULT 0"); - - String secureOutgoingSms = "EXISTS(SELECT 1 FROM sms WHERE thread_id = t._id AND (type & 31) = 23 AND (type & 10485760) AND (type & 131072 = 0))"; - String secureOutgoingMms = "EXISTS(SELECT 1 FROM mms WHERE thread_id = t._id AND (msg_box & 31) = 23 AND (msg_box & 10485760) AND (msg_box & 131072 = 0))"; - - String selectIdsToUpdateProfileSharing = "SELECT r._id FROM recipient AS r INNER JOIN thread AS t ON r._id = t.recipient_ids WHERE profile_sharing = 0 AND (" + secureOutgoingSms + " OR " + secureOutgoingMms + ")"; - - db.execSQL("UPDATE recipient SET profile_sharing = 1 WHERE _id IN (" + selectIdsToUpdateProfileSharing + ")"); - - String selectIdsWithGroupsInCommon = "SELECT r._id FROM recipient AS r WHERE EXISTS(" - + "SELECT 1 FROM groups AS g INNER JOIN recipient AS gr ON (g.recipient_id = gr._id AND gr.profile_sharing = 1) WHERE g.active = 1 AND (g.members LIKE r._id || ',%' OR g.members LIKE '%,' || r._id || ',%' OR g.members LIKE '%,' || r._id)" - + ")"; - db.execSQL("UPDATE recipient SET groups_in_common = 1 WHERE _id IN (" + selectIdsWithGroupsInCommon + ")"); - } - - if (oldVersion < CLEAN_STORAGE_IDS_WITHOUT_INFO) { - ContentValues values = new ContentValues(); - values.putNull("storage_service_key"); - int count = db.update("recipient", values, "storage_service_key NOT NULL AND phone IS NULL AND uuid IS NULL AND group_id IS NULL", null); - Log.i(TAG, "There were " + count + " bad rows that had their storageID removed due to not having any other identifier."); - } - - if (oldVersion < CLEAN_REACTION_NOTIFICATIONS) { - ContentValues values = new ContentValues(1); - values.put("notified", 1); - - int count = 0; - count += db.update("sms", values, "notified = 0 AND read = 1 AND reactions_unread = 1 AND NOT ((type & 31) = 23 AND (type & 10485760) AND (type & 131072 = 0))", null); - count += db.update("mms", values, "notified = 0 AND read = 1 AND reactions_unread = 1 AND NOT ((msg_box & 31) = 23 AND (msg_box & 10485760) AND (msg_box & 131072 = 0))", null); - Log.d(TAG, "Resetting notified for " + count + " read incoming messages that were incorrectly flipped when receiving reactions"); - - List smsIds = new ArrayList<>(); - - try (Cursor cursor = db.query("sms", new String[]{"_id", "reactions", "notified_timestamp"}, "notified = 0 AND reactions_unread = 1", null, null, null, null)) { - while (cursor.moveToNext()) { - byte[] reactions = cursor.getBlob(cursor.getColumnIndexOrThrow("reactions")); - long notifiedTimestamp = cursor.getLong(cursor.getColumnIndexOrThrow("notified_timestamp")); - - if (reactions == null) { - continue; - } - - try { - boolean hasReceiveLaterThanNotified = ReactionList.parseFrom(reactions) - .getReactionsList() - .stream() - .anyMatch(r -> r.getReceivedTime() > notifiedTimestamp); - if (!hasReceiveLaterThanNotified) { - smsIds.add(cursor.getLong(cursor.getColumnIndexOrThrow("_id"))); - } - } catch (InvalidProtocolBufferException e) { - Log.e(TAG, e); - } - } - } - - if (smsIds.size() > 0) { - Log.d(TAG, "Updating " + smsIds.size() + " records in sms"); - db.execSQL("UPDATE sms SET reactions_last_seen = notified_timestamp WHERE _id in (" + Util.join(smsIds, ",") + ")"); - } - - List mmsIds = new ArrayList<>(); - - try (Cursor cursor = db.query("mms", new String[]{"_id", "reactions", "notified_timestamp"}, "notified = 0 AND reactions_unread = 1", null, null, null, null)) { - while (cursor.moveToNext()) { - byte[] reactions = cursor.getBlob(cursor.getColumnIndexOrThrow("reactions")); - long notifiedTimestamp = cursor.getLong(cursor.getColumnIndexOrThrow("notified_timestamp")); - - if (reactions == null) { - continue; - } - - try { - boolean hasReceiveLaterThanNotified = ReactionList.parseFrom(reactions) - .getReactionsList() - .stream() - .anyMatch(r -> r.getReceivedTime() > notifiedTimestamp); - if (!hasReceiveLaterThanNotified) { - mmsIds.add(cursor.getLong(cursor.getColumnIndexOrThrow("_id"))); - } - } catch (InvalidProtocolBufferException e) { - Log.e(TAG, e); - } - } - } - - if (mmsIds.size() > 0) { - Log.d(TAG, "Updating " + mmsIds.size() + " records in mms"); - db.execSQL("UPDATE mms SET reactions_last_seen = notified_timestamp WHERE _id in (" + Util.join(mmsIds, ",") + ")"); - } - } - - if (oldVersion < STORAGE_SERVICE_REFACTOR) { - int deleteCount; - int insertCount; - int updateCount; - int dirtyCount; - - ContentValues deleteValues = new ContentValues(); - deleteValues.putNull("storage_service_key"); - deleteCount = db.update("recipient", deleteValues, "storage_service_key NOT NULL AND (dirty = 3 OR group_type = 1 OR (group_type = 0 AND registered = 2))", null); - - try (Cursor cursor = db.query("recipient", new String[]{"_id"}, "storage_service_key IS NULL AND (dirty = 2 OR registered = 1)", null, null, null, null)) { - insertCount = cursor.getCount(); - - while (cursor.moveToNext()) { - ContentValues insertValues = new ContentValues(); - insertValues.put("storage_service_key", Base64.encodeBytes(StorageSyncHelper.generateKey())); - - long id = cursor.getLong(cursor.getColumnIndexOrThrow("_id")); - db.update("recipient", insertValues, "_id = ?", SqlUtil.buildArgs(id)); - } - } - - try (Cursor cursor = db.query("recipient", new String[]{"_id"}, "storage_service_key NOT NULL AND dirty = 1", null, null, null, null)) { - updateCount = cursor.getCount(); - - while (cursor.moveToNext()) { - ContentValues updateValues = new ContentValues(); - updateValues.put("storage_service_key", Base64.encodeBytes(StorageSyncHelper.generateKey())); - - long id = cursor.getLong(cursor.getColumnIndexOrThrow("_id")); - db.update("recipient", updateValues, "_id = ?", SqlUtil.buildArgs(id)); - } - } - - ContentValues clearDirtyValues = new ContentValues(); - clearDirtyValues.put("dirty", 0); - dirtyCount = db.update("recipient", clearDirtyValues, "dirty != 0", null); - - Log.d(TAG, String.format(Locale.US, "For storage service refactor migration, there were %d inserts, %d updated, and %d deletes. Cleared the dirty status on %d rows.", insertCount, updateCount, deleteCount, dirtyCount)); - } - - if (oldVersion < CLEAR_MMS_STORAGE_IDS) { - ContentValues deleteValues = new ContentValues(); - deleteValues.putNull("storage_service_key"); - - int deleteCount = db.update("recipient", deleteValues, "storage_service_key NOT NULL AND (group_type = 1 OR (group_type = 0 AND phone IS NULL AND uuid IS NULL))", null); - - Log.d(TAG, "Cleared storageIds from " + deleteCount + " rows. They were either MMS groups or empty contacts."); - } - - if (oldVersion < SERVER_GUID) { - db.execSQL("ALTER TABLE sms ADD COLUMN server_guid TEXT DEFAULT NULL"); - db.execSQL("ALTER TABLE mms ADD COLUMN server_guid TEXT DEFAULT NULL"); - } - - if (oldVersion < CHAT_COLORS) { - db.execSQL("ALTER TABLE recipient ADD COLUMN chat_colors BLOB DEFAULT NULL"); - db.execSQL("ALTER TABLE recipient ADD COLUMN custom_chat_colors_id INTEGER DEFAULT 0"); - db.execSQL("CREATE TABLE chat_colors (" + - "_id INTEGER PRIMARY KEY AUTOINCREMENT," + - "chat_colors BLOB)"); - - Set> entrySet = ChatColorsMapper.getEntrySet(); - String where = "color = ? AND group_id is NULL"; - - for (Map.Entry entry : entrySet) { - String[] whereArgs = SqlUtil.buildArgs(entry.getKey().serialize()); - ContentValues values = new ContentValues(2); - - values.put("chat_colors", entry.getValue().serialize().toByteArray()); - values.put("custom_chat_colors_id", entry.getValue().getId().getLongValue()); - - db.update("recipient", values, where, whereArgs); - } - } - - if (oldVersion < AVATAR_COLORS) { - try (Cursor cursor = db.query("recipient", new String[] { "_id" }, "color IS NULL", null, null, null, null)) { - while (cursor.moveToNext()) { - long id = cursor.getInt(cursor.getColumnIndexOrThrow("_id")); - - ContentValues values = new ContentValues(1); - values.put("color", AvatarColor.random().serialize()); - - db.update("recipient", values, "_id = ?", new String[] { String.valueOf(id) }); - } - } - } - - if (oldVersion < EMOJI_SEARCH) { - db.execSQL("CREATE VIRTUAL TABLE emoji_search USING fts5(label, emoji UNINDEXED)"); - } - - if (oldVersion < SENDER_KEY && !SqlUtil.tableExists(db, "sender_keys")) { - db.execSQL("CREATE TABLE sender_keys (_id INTEGER PRIMARY KEY AUTOINCREMENT, " + - "recipient_id INTEGER NOT NULL, " + - "device INTEGER NOT NULL, " + - "distribution_id TEXT NOT NULL, " + - "record BLOB NOT NULL, " + - "created_at INTEGER NOT NULL, " + - "UNIQUE(recipient_id, device, distribution_id) ON CONFLICT REPLACE)"); - - db.execSQL("CREATE TABLE sender_key_shared (_id INTEGER PRIMARY KEY AUTOINCREMENT, " + - "distribution_id TEXT NOT NULL, " + - "address TEXT NOT NULL, " + - "device INTEGER NOT NULL, " + - "UNIQUE(distribution_id, address, device) ON CONFLICT REPLACE)"); - - db.execSQL("CREATE TABLE pending_retry_receipts (_id INTEGER PRIMARY KEY AUTOINCREMENT, " + - "author TEXT NOT NULL, " + - "device INTEGER NOT NULL, " + - "sent_timestamp INTEGER NOT NULL, " + - "received_timestamp TEXT NOT NULL, " + - "thread_id INTEGER NOT NULL, " + - "UNIQUE(author, sent_timestamp) ON CONFLICT REPLACE);"); - - db.execSQL("ALTER TABLE groups ADD COLUMN distribution_id TEXT DEFAULT NULL"); - db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS group_distribution_id_index ON groups (distribution_id)"); - - try (Cursor cursor = db.query("groups", new String[] { "group_id" }, "LENGTH(group_id) = 85", null, null, null, null)) { - while (cursor.moveToNext()) { - String groupId = cursor.getString(cursor.getColumnIndexOrThrow("group_id")); - ContentValues values = new ContentValues(); - - values.put("distribution_id", DistributionId.create().toString()); - - db.update("groups", values, "group_id = ?", new String[] { groupId }); - } - } - } - - if (oldVersion < MESSAGE_DUPE_INDEX) { - db.execSQL("DROP INDEX sms_date_sent_index"); - db.execSQL("CREATE INDEX sms_date_sent_index on sms(date_sent, address, thread_id)"); - - db.execSQL("DROP INDEX mms_date_sent_index"); - db.execSQL("CREATE INDEX mms_date_sent_index on mms(date, address, thread_id)"); - } - - if (oldVersion < MESSAGE_LOG) { - db.execSQL("CREATE TABLE message_send_log (_id INTEGER PRIMARY KEY, " + - "date_sent INTEGER NOT NULL, " + - "content BLOB NOT NULL, " + - "related_message_id INTEGER DEFAULT -1, " + - "is_related_message_mms INTEGER DEFAULT 0, " + - "content_hint INTEGER NOT NULL, " + - "group_id BLOB DEFAULT NULL)"); - - db.execSQL("CREATE INDEX message_log_date_sent_index ON message_send_log (date_sent)"); - db.execSQL("CREATE INDEX message_log_related_message_index ON message_send_log (related_message_id, is_related_message_mms)"); - - db.execSQL("CREATE TRIGGER msl_sms_delete AFTER DELETE ON sms BEGIN DELETE FROM message_send_log WHERE related_message_id = old._id AND is_related_message_mms = 0; END"); - db.execSQL("CREATE TRIGGER msl_mms_delete AFTER DELETE ON mms BEGIN DELETE FROM message_send_log WHERE related_message_id = old._id AND is_related_message_mms = 1; END"); - - db.execSQL("CREATE TABLE message_send_log_recipients (_id INTEGER PRIMARY KEY, " + - "message_send_log_id INTEGER NOT NULL REFERENCES message_send_log (_id) ON DELETE CASCADE, " + - "recipient_id INTEGER NOT NULL, " + - "device INTEGER NOT NULL)"); - - db.execSQL("CREATE INDEX message_send_log_recipients_recipient_index ON message_send_log_recipients (recipient_id, device)"); - } - - if (oldVersion < MESSAGE_LOG_2) { - db.execSQL("DROP TABLE message_send_log"); - db.execSQL("DROP INDEX IF EXISTS message_log_date_sent_index"); - db.execSQL("DROP INDEX IF EXISTS message_log_related_message_index"); - db.execSQL("DROP TRIGGER msl_sms_delete"); - db.execSQL("DROP TRIGGER msl_mms_delete"); - db.execSQL("DROP TABLE message_send_log_recipients"); - db.execSQL("DROP INDEX IF EXISTS message_send_log_recipients_recipient_index"); - - db.execSQL("CREATE TABLE msl_payload (_id INTEGER PRIMARY KEY, " + - "date_sent INTEGER NOT NULL, " + - "content BLOB NOT NULL, " + - "content_hint INTEGER NOT NULL)"); - - db.execSQL("CREATE INDEX msl_payload_date_sent_index ON msl_payload (date_sent)"); - - db.execSQL("CREATE TABLE msl_recipient (_id INTEGER PRIMARY KEY, " + - "payload_id INTEGER NOT NULL REFERENCES msl_payload (_id) ON DELETE CASCADE, " + - "recipient_id INTEGER NOT NULL, " + - "device INTEGER NOT NULL)"); - - db.execSQL("CREATE INDEX msl_recipient_recipient_index ON msl_recipient (recipient_id, device, payload_id)"); - db.execSQL("CREATE INDEX msl_recipient_payload_index ON msl_recipient (payload_id)"); - - db.execSQL("CREATE TABLE msl_message (_id INTEGER PRIMARY KEY, " + - "payload_id INTEGER NOT NULL REFERENCES msl_payload (_id) ON DELETE CASCADE, " + - "message_id INTEGER NOT NULL, " + - "is_mms INTEGER NOT NULL)"); - - db.execSQL("CREATE INDEX msl_message_message_index ON msl_message (message_id, is_mms, payload_id)"); - - db.execSQL("CREATE TRIGGER msl_sms_delete AFTER DELETE ON sms BEGIN DELETE FROM msl_payload WHERE _id IN (SELECT payload_id FROM msl_message WHERE message_id = old._id AND is_mms = 0); END"); - db.execSQL("CREATE TRIGGER msl_mms_delete AFTER DELETE ON mms BEGIN DELETE FROM msl_payload WHERE _id IN (SELECT payload_id FROM msl_message WHERE message_id = old._id AND is_mms = 1); END"); - db.execSQL("CREATE TRIGGER msl_attachment_delete AFTER DELETE ON part BEGIN DELETE FROM msl_payload WHERE _id IN (SELECT payload_id FROM msl_message WHERE message_id = old.mid AND is_mms = 1); END"); - } - - if (oldVersion < ABANDONED_MESSAGE_CLEANUP) { - long start = System.currentTimeMillis(); - int smsDeleteCount = db.delete("sms", "thread_id NOT IN (SELECT _id FROM thread)", null); - int mmsDeleteCount = db.delete("mms", "thread_id NOT IN (SELECT _id FROM thread)", null); - Log.i(TAG, "Deleted " + smsDeleteCount + " sms and " + mmsDeleteCount + " mms in " + (System.currentTimeMillis() - start) + " ms"); - } - - if (oldVersion < THREAD_AUTOINCREMENT) { - Stopwatch stopwatch = new Stopwatch("thread-autoincrement"); - - db.execSQL("CREATE TABLE thread_tmp (_id INTEGER PRIMARY KEY AUTOINCREMENT, " + - "date INTEGER DEFAULT 0, " + - "thread_recipient_id INTEGER, " + - "message_count INTEGER DEFAULT 0, " + - "snippet TEXT, " + - "snippet_charset INTEGER DEFAULT 0, " + - "snippet_type INTEGER DEFAULT 0, " + - "snippet_uri TEXT DEFAULT NULL, " + - "snippet_content_type INTEGER DEFAULT NULL, " + - "snippet_extras TEXT DEFAULT NULL, " + - "read INTEGER DEFAULT 1, " + - "type INTEGER DEFAULT 0, " + - "error INTEGER DEFAULT 0, " + - "archived INTEGER DEFAULT 0, " + - "status INTEGER DEFAULT 0, " + - "expires_in INTEGER DEFAULT 0, " + - "last_seen INTEGER DEFAULT 0, " + - "has_sent INTEGER DEFAULT 0, " + - "delivery_receipt_count INTEGER DEFAULT 0, " + - "read_receipt_count INTEGER DEFAULT 0, " + - "unread_count INTEGER DEFAULT 0, " + - "last_scrolled INTEGER DEFAULT 0, " + - "pinned INTEGER DEFAULT 0)"); - stopwatch.split("table-create"); - - db.execSQL("INSERT INTO thread_tmp SELECT _id, " + - "date, " + - "recipient_ids, " + - "message_count, " + - "snippet, " + - "snippet_cs, " + - "snippet_type, " + - "snippet_uri, " + - "snippet_content_type, " + - "snippet_extras, " + - "read, " + - "type, " + - "error, " + - "archived, " + - "status, " + - "expires_in, " + - "last_seen, " + - "has_sent, " + - "delivery_receipt_count, " + - "read_receipt_count, " + - "unread_count, " + - "last_scrolled, " + - "pinned " + - "FROM thread"); - - stopwatch.split("table-copy"); - - db.execSQL("DROP TABLE thread"); - db.execSQL("ALTER TABLE thread_tmp RENAME TO thread"); - - stopwatch.split("table-rename"); - - db.execSQL("CREATE INDEX thread_recipient_id_index ON thread (thread_recipient_id)"); - db.execSQL("CREATE INDEX archived_count_index ON thread (archived, message_count)"); - db.execSQL("CREATE INDEX thread_pinned_index ON thread (pinned)"); - - stopwatch.split("indexes"); - - db.execSQL("DELETE FROM remapped_threads"); - - stopwatch.split("delete-remap"); - - stopwatch.stop(TAG); - } - - if (oldVersion < MMS_AUTOINCREMENT) { - Stopwatch mmsStopwatch = new Stopwatch("mms-autoincrement"); - - db.execSQL("CREATE TABLE mms_tmp (_id INTEGER PRIMARY KEY AUTOINCREMENT, " + - "thread_id INTEGER, " + - "date INTEGER, " + - "date_received INTEGER, " + - "date_server INTEGER DEFAULT -1, " + - "msg_box INTEGER, " + - "read INTEGER DEFAULT 0, " + - "body TEXT, " + - "part_count INTEGER, " + - "ct_l TEXT, " + - "address INTEGER, " + - "address_device_id INTEGER, " + - "exp INTEGER, " + - "m_type INTEGER, " + - "m_size INTEGER, " + - "st INTEGER, " + - "tr_id TEXT, " + - "delivery_receipt_count INTEGER DEFAULT 0, " + - "mismatched_identities TEXT DEFAULT NULL, " + - "network_failures TEXT DEFAULT NULL, " + - "subscription_id INTEGER DEFAULT -1, " + - "expires_in INTEGER DEFAULT 0, " + - "expire_started INTEGER DEFAULT 0, " + - "notified INTEGER DEFAULT 0, " + - "read_receipt_count INTEGER DEFAULT 0, " + - "quote_id INTEGER DEFAULT 0, " + - "quote_author TEXT, " + - "quote_body TEXT, " + - "quote_attachment INTEGER DEFAULT -1, " + - "quote_missing INTEGER DEFAULT 0, " + - "quote_mentions BLOB DEFAULT NULL, " + - "shared_contacts TEXT, " + - "unidentified INTEGER DEFAULT 0, " + - "previews TEXT, " + - "reveal_duration INTEGER DEFAULT 0, " + - "reactions BLOB DEFAULT NULL, " + - "reactions_unread INTEGER DEFAULT 0, " + - "reactions_last_seen INTEGER DEFAULT -1, " + - "remote_deleted INTEGER DEFAULT 0, " + - "mentions_self INTEGER DEFAULT 0, " + - "notified_timestamp INTEGER DEFAULT 0, " + - "viewed_receipt_count INTEGER DEFAULT 0, " + - "server_guid TEXT DEFAULT NULL);"); - - mmsStopwatch.split("table-create"); - - db.execSQL("INSERT INTO mms_tmp SELECT _id, " + - "thread_id, " + - "date, " + - "date_received, " + - "date_server, " + - "msg_box, " + - "read, " + - "body, " + - "part_count, " + - "ct_l, " + - "address, " + - "address_device_id, " + - "exp, " + - "m_type, " + - "m_size, " + - "st, " + - "tr_id, " + - "delivery_receipt_count, " + - "mismatched_identities, " + - "network_failures, " + - "subscription_id, " + - "expires_in, " + - "expire_started, " + - "notified, " + - "read_receipt_count, " + - "quote_id, " + - "quote_author, " + - "quote_body, " + - "quote_attachment, " + - "quote_missing, " + - "quote_mentions, " + - "shared_contacts, " + - "unidentified, " + - "previews, " + - "reveal_duration, " + - "reactions, " + - "reactions_unread, " + - "reactions_last_seen, " + - "remote_deleted, " + - "mentions_self, " + - "notified_timestamp, " + - "viewed_receipt_count, " + - "server_guid " + - "FROM mms"); - - mmsStopwatch.split("table-copy"); - - db.execSQL("DROP TABLE mms"); - db.execSQL("ALTER TABLE mms_tmp RENAME TO mms"); - - mmsStopwatch.split("table-rename"); - - db.execSQL("CREATE INDEX mms_read_and_notified_and_thread_id_index ON mms(read, notified, thread_id)"); - db.execSQL("CREATE INDEX mms_message_box_index ON mms (msg_box)"); - db.execSQL("CREATE INDEX mms_date_sent_index ON mms (date, address, thread_id)"); - db.execSQL("CREATE INDEX mms_date_server_index ON mms (date_server)"); - db.execSQL("CREATE INDEX mms_thread_date_index ON mms (thread_id, date_received)"); - db.execSQL("CREATE INDEX mms_reactions_unread_index ON mms (reactions_unread)"); - - mmsStopwatch.split("indexes"); - - db.execSQL("CREATE TRIGGER mms_ai AFTER INSERT ON mms BEGIN INSERT INTO mms_fts(rowid, body, thread_id) VALUES (new._id, new.body, new.thread_id); END"); - db.execSQL("CREATE TRIGGER mms_ad AFTER DELETE ON mms BEGIN INSERT INTO mms_fts(mms_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id); END"); - db.execSQL("CREATE TRIGGER mms_au AFTER UPDATE ON mms BEGIN INSERT INTO mms_fts(mms_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id); INSERT INTO mms_fts(rowid, body, thread_id) VALUES (new._id, new.body, new.thread_id); END"); - db.execSQL("CREATE TRIGGER msl_mms_delete AFTER DELETE ON mms BEGIN DELETE FROM msl_payload WHERE _id IN (SELECT payload_id FROM msl_message WHERE message_id = old._id AND is_mms = 1); END"); - - mmsStopwatch.split("triggers"); - mmsStopwatch.stop(TAG); - - Stopwatch smsStopwatch = new Stopwatch("sms-autoincrement"); - - db.execSQL("CREATE TABLE sms_tmp (_id INTEGER PRIMARY KEY AUTOINCREMENT, " + - "thread_id INTEGER, " + - "address INTEGER, " + - "address_device_id INTEGER DEFAULT 1, " + - "person INTEGER, " + - "date INTEGER, " + - "date_sent INTEGER, " + - "date_server INTEGER DEFAULT -1, " + - "protocol INTEGER, " + - "read INTEGER DEFAULT 0, " + - "status INTEGER DEFAULT -1, " + - "type INTEGER, " + - "reply_path_present INTEGER, " + - "delivery_receipt_count INTEGER DEFAULT 0, " + - "subject TEXT, " + - "body TEXT, " + - "mismatched_identities TEXT DEFAULT NULL, " + - "service_center TEXT, " + - "subscription_id INTEGER DEFAULT -1, " + - "expires_in INTEGER DEFAULT 0, " + - "expire_started INTEGER DEFAULT 0, " + - "notified DEFAULT 0, " + - "read_receipt_count INTEGER DEFAULT 0, " + - "unidentified INTEGER DEFAULT 0, " + - "reactions BLOB DEFAULT NULL, " + - "reactions_unread INTEGER DEFAULT 0, " + - "reactions_last_seen INTEGER DEFAULT -1, " + - "remote_deleted INTEGER DEFAULT 0, " + - "notified_timestamp INTEGER DEFAULT 0, " + - "server_guid TEXT DEFAULT NULL)"); - - smsStopwatch.split("table-create"); - - db.execSQL("INSERT INTO sms_tmp SELECT _id, " + - "thread_id, " + - "address, " + - "address_device_id, " + - "person, " + - "date, " + - "date_sent, " + - "date_server , " + - "protocol, " + - "read, " + - "status , " + - "type, " + - "reply_path_present, " + - "delivery_receipt_count, " + - "subject, " + - "body, " + - "mismatched_identities, " + - "service_center, " + - "subscription_id , " + - "expires_in, " + - "expire_started, " + - "notified, " + - "read_receipt_count, " + - "unidentified, " + - "reactions BLOB, " + - "reactions_unread, " + - "reactions_last_seen , " + - "remote_deleted, " + - "notified_timestamp, " + - "server_guid " + - "FROM sms"); - - smsStopwatch.split("table-copy"); - - db.execSQL("DROP TABLE sms"); - db.execSQL("ALTER TABLE sms_tmp RENAME TO sms"); - - smsStopwatch.split("table-rename"); - - db.execSQL("CREATE INDEX sms_read_and_notified_and_thread_id_index ON sms(read, notified, thread_id)"); - db.execSQL("CREATE INDEX sms_type_index ON sms (type)"); - db.execSQL("CREATE INDEX sms_date_sent_index ON sms (date_sent, address, thread_id)"); - db.execSQL("CREATE INDEX sms_date_server_index ON sms (date_server)"); - db.execSQL("CREATE INDEX sms_thread_date_index ON sms (thread_id, date)"); - db.execSQL("CREATE INDEX sms_reactions_unread_index ON sms (reactions_unread)"); - - smsStopwatch.split("indexes"); - - db.execSQL("CREATE TRIGGER sms_ai AFTER INSERT ON sms BEGIN INSERT INTO sms_fts(rowid, body, thread_id) VALUES (new._id, new.body, new.thread_id); END;"); - db.execSQL("CREATE TRIGGER sms_ad AFTER DELETE ON sms BEGIN INSERT INTO sms_fts(sms_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id); END;"); - db.execSQL("CREATE TRIGGER sms_au AFTER UPDATE ON sms BEGIN INSERT INTO sms_fts(sms_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id); INSERT INTO sms_fts(rowid, body, thread_id) VALUES(new._id, new.body, new.thread_id); END;"); - db.execSQL("CREATE TRIGGER msl_sms_delete AFTER DELETE ON sms BEGIN DELETE FROM msl_payload WHERE _id IN (SELECT payload_id FROM msl_message WHERE message_id = old._id AND is_mms = 0); END"); - - smsStopwatch.split("triggers"); - smsStopwatch.stop(TAG); - } - - if (oldVersion < ABANDONED_ATTACHMENT_CLEANUP) { - db.delete("part", "mid != -8675309 AND mid NOT IN (SELECT _id FROM mms)", null); - } - - if (oldVersion < AVATAR_PICKER) { - db.execSQL("CREATE TABLE avatar_picker (_id INTEGER PRIMARY KEY AUTOINCREMENT, " + - "last_used INTEGER DEFAULT 0, " + - "group_id TEXT DEFAULT NULL, " + - "avatar BLOB NOT NULL)"); - - try (Cursor cursor = db.query("recipient", new String[] { "_id" }, "color IS NULL", null, null, null, null)) { - while (cursor.moveToNext()) { - long id = cursor.getInt(cursor.getColumnIndexOrThrow("_id")); - - ContentValues values = new ContentValues(1); - values.put("color", AvatarColor.random().serialize()); - - db.update("recipient", values, "_id = ?", new String[] { String.valueOf(id) }); - } - } - } - - if (oldVersion < THREAD_CLEANUP) { - db.delete("mms", "thread_id NOT IN (SELECT _id FROM thread)", null); - db.delete("part", "mid != -8675309 AND mid NOT IN (SELECT _id FROM mms)", null); - } - - if (oldVersion < SESSION_MIGRATION) { - long start = System.currentTimeMillis(); - - db.execSQL("CREATE TABLE sessions_tmp (_id INTEGER PRIMARY KEY AUTOINCREMENT, " + - "address TEXT NOT NULL, " + - "device INTEGER NOT NULL, " + - "record BLOB NOT NULL, " + - "UNIQUE(address, device))"); - - db.execSQL("INSERT INTO sessions_tmp (address, device, record) " + - "SELECT COALESCE(recipient.uuid, recipient.phone) AS new_address, " + - "sessions.device, " + - "sessions.record " + - "FROM sessions INNER JOIN recipient ON sessions.address = recipient._id " + - "WHERE new_address NOT NULL"); - - db.execSQL("DROP TABLE sessions"); - db.execSQL("ALTER TABLE sessions_tmp RENAME TO sessions"); - - Log.d(TAG, "Session migration took " + (System.currentTimeMillis() - start) + " ms"); - } - - if (oldVersion < IDENTITY_MIGRATION) { - long start = System.currentTimeMillis(); - - db.execSQL("CREATE TABLE identities_tmp (_id INTEGER PRIMARY KEY AUTOINCREMENT, " + - "address TEXT UNIQUE NOT NULL, " + - "identity_key TEXT, " + - "first_use INTEGER DEFAULT 0, " + - "timestamp INTEGER DEFAULT 0, " + - "verified INTEGER DEFAULT 0, " + - "nonblocking_approval INTEGER DEFAULT 0)"); - - db.execSQL("INSERT INTO identities_tmp (address, identity_key, first_use, timestamp, verified, nonblocking_approval) " + - "SELECT COALESCE(recipient.uuid, recipient.phone) AS new_address, " + - "identities.key, " + - "identities.first_use, " + - "identities.timestamp, " + - "identities.verified, " + - "identities.nonblocking_approval " + - "FROM identities INNER JOIN recipient ON identities.address = recipient._id " + - "WHERE new_address NOT NULL"); - - db.execSQL("DROP TABLE identities"); - db.execSQL("ALTER TABLE identities_tmp RENAME TO identities"); - - Log.d(TAG, "Identity migration took " + (System.currentTimeMillis() - start) + " ms"); - } - - if (oldVersion < GROUP_CALL_RING_TABLE) { - db.execSQL("CREATE TABLE group_call_ring (_id INTEGER PRIMARY KEY, ring_id INTEGER UNIQUE, date_received INTEGER, ring_state INTEGER)"); - db.execSQL("CREATE INDEX date_received_index on group_call_ring (date_received)"); - } - - if (oldVersion < CLEANUP_SESSION_MIGRATION) { - int sessionCount = db.delete("sessions", "address LIKE '+%'", null); - Log.i(TAG, "Cleaned up " + sessionCount + " sessions."); - - ContentValues storageValues = new ContentValues(); - storageValues.putNull("storage_service_key"); - - int storageCount = db.update("recipient", storageValues, "storage_service_key NOT NULL AND group_id IS NULL AND uuid IS NULL", null); - Log.i(TAG, "Cleaned up " + storageCount + " storageIds."); - } - - if (oldVersion < RECEIPT_TIMESTAMP) { - db.execSQL("ALTER TABLE sms ADD COLUMN receipt_timestamp INTEGER DEFAULT -1"); - db.execSQL("ALTER TABLE mms ADD COLUMN receipt_timestamp INTEGER DEFAULT -1"); - } - - if (oldVersion < BADGES) { - db.execSQL("ALTER TABLE recipient ADD COLUMN badges BLOB DEFAULT NULL"); - } - - if (oldVersion < SENDER_KEY_UUID) { - long start = System.currentTimeMillis(); - - db.execSQL("CREATE TABLE sender_keys_tmp (_id INTEGER PRIMARY KEY AUTOINCREMENT, " + - "address TEXT NOT NULL, " + - "device INTEGER NOT NULL, " + - "distribution_id TEXT NOT NULL, " + - "record BLOB NOT NULL, " + - "created_at INTEGER NOT NULL, " + - "UNIQUE(address, device, distribution_id) ON CONFLICT REPLACE)"); - - db.execSQL("INSERT INTO sender_keys_tmp (address, device, distribution_id, record, created_at) " + - "SELECT recipient.uuid AS new_address, " + - "sender_keys.device, " + - "sender_keys.distribution_id, " + - "sender_keys.record, " + - "sender_keys.created_at " + - "FROM sender_keys INNER JOIN recipient ON sender_keys.recipient_id = recipient._id " + - "WHERE new_address NOT NULL"); - - db.execSQL("DROP TABLE sender_keys"); - db.execSQL("ALTER TABLE sender_keys_tmp RENAME TO sender_keys"); - - Log.d(TAG, "Sender key migration took " + (System.currentTimeMillis() - start) + " ms"); - } - - if (oldVersion < SENDER_KEY_SHARED_TIMESTAMP) { - db.execSQL("ALTER TABLE sender_key_shared ADD COLUMN timestamp INTEGER DEFAULT 0"); - } - - if (oldVersion < REACTION_REFACTOR) { - db.execSQL("CREATE TABLE reaction (_id INTEGER PRIMARY KEY, " + - "message_id INTEGER NOT NULL, " + - "is_mms INTEGER NOT NULL, " + - "author_id INTEGER NOT NULL REFERENCES recipient (_id) ON DELETE CASCADE, " + - "emoji TEXT NOT NULL, " + - "date_sent INTEGER NOT NULL, " + - "date_received INTEGER NOT NULL, " + - "UNIQUE(message_id, is_mms, author_id) ON CONFLICT REPLACE)"); - - try (Cursor cursor = db.rawQuery("SELECT _id, reactions FROM sms WHERE reactions NOT NULL", null)) { - while (cursor.moveToNext()) { - migrateReaction(db, cursor, false); - } - } - - try (Cursor cursor = db.rawQuery("SELECT _id, reactions FROM mms WHERE reactions NOT NULL", null)) { - while (cursor.moveToNext()) { - migrateReaction(db, cursor, true); - } - } - - db.execSQL("UPDATE reaction SET author_id = IFNULL((SELECT new_id FROM remapped_recipients WHERE author_id = old_id), author_id)"); - - db.execSQL("CREATE TRIGGER reactions_sms_delete AFTER DELETE ON sms BEGIN DELETE FROM reaction WHERE message_id = old._id AND is_mms = 0; END"); - db.execSQL("CREATE TRIGGER reactions_mms_delete AFTER DELETE ON mms BEGIN DELETE FROM reaction WHERE message_id = old._id AND is_mms = 0; END"); - - db.execSQL("UPDATE sms SET reactions = NULL WHERE reactions NOT NULL"); - db.execSQL("UPDATE mms SET reactions = NULL WHERE reactions NOT NULL"); - } - - db.setTransactionSuccessful(); - } finally { - db.endTransaction(); - } - - if (oldVersion < MIGRATE_PREKEYS_VERSION) { - PreKeyMigrationHelper.cleanUpPreKeys(context); - } - - Log.i(TAG, "Upgrade complete. Took " + (System.currentTimeMillis() - startTime) + " ms."); - } - - private void migrateReaction(@NonNull SQLiteDatabase db, @NonNull Cursor cursor, boolean isMms) { - try { - long messageId = CursorUtil.requireLong(cursor, "_id"); - ReactionList reactionList = ReactionList.parseFrom(CursorUtil.requireBlob(cursor, "reactions")); - - for (ReactionList.Reaction reaction : reactionList.getReactionsList()) { - ContentValues contentValues = new ContentValues(); - contentValues.put("message_id", messageId); - contentValues.put("is_mms", isMms ? 1 : 0); - contentValues.put("author_id", reaction.getAuthor()); - contentValues.put("emoji", reaction.getEmoji()); - contentValues.put("date_sent", reaction.getSentTime()); - contentValues.put("date_received", reaction.getReceivedTime()); - - db.insert("reaction", null, contentValues); - } - } catch (InvalidProtocolBufferException e) { - Log.w(TAG, "Failed to parse reaction!"); - } - } - - @Override - public net.zetetic.database.sqlcipher.SQLiteDatabase getReadableDatabase() { - throw new UnsupportedOperationException("Call getSignalReadableDatabase() instead!"); - } - - @Override - public net.zetetic.database.sqlcipher.SQLiteDatabase getWritableDatabase() { - throw new UnsupportedOperationException("Call getSignalWritableDatabase() instead!"); - } - - public net.zetetic.database.sqlcipher.SQLiteDatabase getRawReadableDatabase() { - return super.getReadableDatabase(); - } - - public net.zetetic.database.sqlcipher.SQLiteDatabase getRawWritableDatabase() { - return super.getWritableDatabase(); - } - - public org.thoughtcrime.securesms.database.SQLiteDatabase getSignalReadableDatabase() { - return new org.thoughtcrime.securesms.database.SQLiteDatabase(super.getReadableDatabase()); - } - - public org.thoughtcrime.securesms.database.SQLiteDatabase getSignalWritableDatabase() { - return new org.thoughtcrime.securesms.database.SQLiteDatabase(super.getWritableDatabase()); - } - - @Override - public @NonNull net.zetetic.database.sqlcipher.SQLiteDatabase getSqlCipherDatabase() { - return super.getWritableDatabase(); - } - - public void markCurrent(SQLiteDatabase db) { - db.setVersion(DATABASE_VERSION); - } - - public static boolean databaseFileExists(@NonNull Context context) { - return context.getDatabasePath(DATABASE_NAME).exists(); - } - - public static File getDatabaseFile(@NonNull Context context) { - return context.getDatabasePath(DATABASE_NAME); - } - - private void executeStatements(SQLiteDatabase db, String[] statements) { - for (String statement : statements) - db.execSQL(statement); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SessionStoreMigrationHelper.java b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SessionStoreMigrationHelper.java index ca91f9b599..2adb317c85 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SessionStoreMigrationHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SessionStoreMigrationHelper.java @@ -16,7 +16,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; -class SessionStoreMigrationHelper { +public final class SessionStoreMigrationHelper { private static final String TAG = Log.tag(SessionStoreMigrationHelper.class); @@ -28,7 +28,7 @@ class SessionStoreMigrationHelper { private static final int PLAINTEXT_VERSION = 3; private static final int CURRENT_VERSION = 3; - static void migrateSessions(Context context, SQLiteDatabase database) { + public static void migrateSessions(Context context, SQLiteDatabase database) { File directory = new File(context.getFilesDir(), SESSIONS_DIRECTORY_V2); if (directory.exists()) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt new file mode 100644 index 0000000000..e311182b34 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt @@ -0,0 +1,2202 @@ +package org.thoughtcrime.securesms.database.helpers + +import android.app.NotificationChannel +import android.content.ContentValues +import android.content.Context +import android.database.Cursor +import android.net.Uri +import android.os.Build +import android.os.SystemClock +import android.preference.PreferenceManager +import android.text.TextUtils +import com.annimon.stream.Stream +import com.bumptech.glide.Glide +import com.google.protobuf.InvalidProtocolBufferException +import net.zetetic.database.sqlcipher.SQLiteDatabase +import org.signal.core.util.logging.Log +import org.thoughtcrime.securesms.color.MaterialColor +import org.thoughtcrime.securesms.contacts.avatars.ContactColorsLegacy +import org.thoughtcrime.securesms.conversation.colors.AvatarColor +import org.thoughtcrime.securesms.conversation.colors.ChatColors +import org.thoughtcrime.securesms.conversation.colors.ChatColorsMapper.entrySet +import org.thoughtcrime.securesms.database.RecipientDatabase +import org.thoughtcrime.securesms.database.model.databaseprotos.ReactionList +import org.thoughtcrime.securesms.dependencies.ApplicationDependencies +import org.thoughtcrime.securesms.groups.GroupId +import org.thoughtcrime.securesms.jobs.RefreshPreKeysJob +import org.thoughtcrime.securesms.keyvalue.SignalStore +import org.thoughtcrime.securesms.notifications.NotificationChannels +import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter +import org.thoughtcrime.securesms.profiles.AvatarHelper +import org.thoughtcrime.securesms.profiles.ProfileName +import org.thoughtcrime.securesms.recipients.RecipientId +import org.thoughtcrime.securesms.storage.StorageSyncHelper +import org.thoughtcrime.securesms.util.Base64 +import org.thoughtcrime.securesms.util.CursorUtil +import org.thoughtcrime.securesms.util.FileUtils +import org.thoughtcrime.securesms.util.Hex +import org.thoughtcrime.securesms.util.ServiceUtil +import org.thoughtcrime.securesms.util.SqlUtil +import org.thoughtcrime.securesms.util.Stopwatch +import org.thoughtcrime.securesms.util.Triple +import org.thoughtcrime.securesms.util.Util +import org.whispersystems.signalservice.api.push.DistributionId +import java.io.ByteArrayInputStream +import java.io.File +import java.io.FileInputStream +import java.io.IOException +import java.lang.AssertionError +import java.util.ArrayList +import java.util.HashSet +import java.util.LinkedList +import java.util.Locale + +/** + * Contains all of the database migrations for [SignalDatabase]. Broken into a separate file for cleanliness. + */ +object SignalDatabaseMigrations { + + private val TAG: String = Log.tag(SignalDatabaseMigrations.javaClass) + + private const val RECIPIENT_CALL_RINGTONE_VERSION = 2 + private const val MIGRATE_PREKEYS_VERSION = 3 + private const val MIGRATE_SESSIONS_VERSION = 4 + private const val NO_MORE_IMAGE_THUMBNAILS_VERSION = 5 + private const val ATTACHMENT_DIMENSIONS = 6 + private const val QUOTED_REPLIES = 7 + private const val SHARED_CONTACTS = 8 + private const val FULL_TEXT_SEARCH = 9 + private const val BAD_IMPORT_CLEANUP = 10 + private const val QUOTE_MISSING = 11 + private const val NOTIFICATION_CHANNELS = 12 + private const val SECRET_SENDER = 13 + private const val ATTACHMENT_CAPTIONS = 14 + private const val ATTACHMENT_CAPTIONS_FIX = 15 + private const val PREVIEWS = 16 + private const val CONVERSATION_SEARCH = 17 + private const val SELF_ATTACHMENT_CLEANUP = 18 + private const val RECIPIENT_FORCE_SMS_SELECTION = 19 + private const val JOBMANAGER_STRIKES_BACK = 20 + private const val STICKERS = 21 + private const val REVEALABLE_MESSAGES = 22 + private const val VIEW_ONCE_ONLY = 23 + private const val RECIPIENT_IDS = 24 + private const val RECIPIENT_SEARCH = 25 + private const val RECIPIENT_CLEANUP = 26 + private const val MMS_RECIPIENT_CLEANUP = 27 + private const val ATTACHMENT_HASHING = 28 + private const val NOTIFICATION_RECIPIENT_IDS = 29 + private const val BLUR_HASH = 30 + private const val MMS_RECIPIENT_CLEANUP_2 = 31 + private const val ATTACHMENT_TRANSFORM_PROPERTIES = 32 + private const val ATTACHMENT_CLEAR_HASHES = 33 + private const val ATTACHMENT_CLEAR_HASHES_2 = 34 + private const val UUIDS = 35 + private const val USERNAMES = 36 + private const val REACTIONS = 37 + private const val STORAGE_SERVICE = 38 + private const val REACTIONS_UNREAD_INDEX = 39 + private const val RESUMABLE_DOWNLOADS = 40 + private const val KEY_VALUE_STORE = 41 + private const val ATTACHMENT_DISPLAY_ORDER = 42 + private const val SPLIT_PROFILE_NAMES = 43 + private const val STICKER_PACK_ORDER = 44 + private const val MEGAPHONES = 45 + private const val MEGAPHONE_FIRST_APPEARANCE = 46 + private const val PROFILE_KEY_TO_DB = 47 + private const val PROFILE_KEY_CREDENTIALS = 48 + private const val ATTACHMENT_FILE_INDEX = 49 + private const val STORAGE_SERVICE_ACTIVE = 50 + private const val GROUPS_V2_RECIPIENT_CAPABILITY = 51 + private const val TRANSFER_FILE_CLEANUP = 52 + private const val PROFILE_DATA_MIGRATION = 53 + private const val AVATAR_LOCATION_MIGRATION = 54 + private const val GROUPS_V2 = 55 + private const val ATTACHMENT_UPLOAD_TIMESTAMP = 56 + private const val ATTACHMENT_CDN_NUMBER = 57 + private const val JOB_INPUT_DATA = 58 + private const val SERVER_TIMESTAMP = 59 + private const val REMOTE_DELETE = 60 + private const val COLOR_MIGRATION = 61 + private const val LAST_SCROLLED = 62 + private const val LAST_PROFILE_FETCH = 63 + private const val SERVER_DELIVERED_TIMESTAMP = 64 + private const val QUOTE_CLEANUP = 65 + private const val BORDERLESS = 66 + private const val REMAPPED_RECORDS = 67 + private const val MENTIONS = 68 + private const val PINNED_CONVERSATIONS = 69 + private const val MENTION_GLOBAL_SETTING_MIGRATION = 70 + private const val UNKNOWN_STORAGE_FIELDS = 71 + private const val STICKER_CONTENT_TYPE = 72 + private const val STICKER_EMOJI_IN_NOTIFICATIONS = 73 + private const val THUMBNAIL_CLEANUP = 74 + private const val STICKER_CONTENT_TYPE_CLEANUP = 75 + private const val MENTION_CLEANUP = 76 + private const val MENTION_CLEANUP_V2 = 77 + private const val REACTION_CLEANUP = 78 + private const val CAPABILITIES_REFACTOR = 79 + private const val GV1_MIGRATION = 80 + private const val NOTIFIED_TIMESTAMP = 81 + private const val GV1_MIGRATION_LAST_SEEN = 82 + private const val VIEWED_RECEIPTS = 83 + private const val CLEAN_UP_GV1_IDS = 84 + private const val GV1_MIGRATION_REFACTOR = 85 + private const val CLEAR_PROFILE_KEY_CREDENTIALS = 86 + private const val LAST_RESET_SESSION_TIME = 87 + private const val WALLPAPER = 88 + private const val ABOUT = 89 + private const val SPLIT_SYSTEM_NAMES = 90 + private const val PAYMENTS = 91 + private const val CLEAN_STORAGE_IDS = 92 + private const val MP4_GIF_SUPPORT = 93 + private const val BLUR_AVATARS = 94 + private const val CLEAN_STORAGE_IDS_WITHOUT_INFO = 95 + private const val CLEAN_REACTION_NOTIFICATIONS = 96 + private const val STORAGE_SERVICE_REFACTOR = 97 + private const val CLEAR_MMS_STORAGE_IDS = 98 + private const val SERVER_GUID = 99 + private const val CHAT_COLORS = 100 + private const val AVATAR_COLORS = 101 + private const val EMOJI_SEARCH = 102 + private const val SENDER_KEY = 103 + private const val MESSAGE_DUPE_INDEX = 104 + private const val MESSAGE_LOG = 105 + private const val MESSAGE_LOG_2 = 106 + private const val ABANDONED_MESSAGE_CLEANUP = 107 + private const val THREAD_AUTOINCREMENT = 108 + private const val MMS_AUTOINCREMENT = 109 + private const val ABANDONED_ATTACHMENT_CLEANUP = 110 + private const val AVATAR_PICKER = 111 + private const val THREAD_CLEANUP = 112 + private const val SESSION_MIGRATION = 113 + private const val IDENTITY_MIGRATION = 114 + private const val GROUP_CALL_RING_TABLE = 115 + private const val CLEANUP_SESSION_MIGRATION = 116 + private const val RECEIPT_TIMESTAMP = 117 + private const val BADGES = 118 + private const val SENDER_KEY_UUID = 119 + private const val SENDER_KEY_SHARED_TIMESTAMP = 120 + private const val REACTION_REFACTOR = 121 + + const val DATABASE_VERSION = 121 + + @JvmStatic + fun migrate(context: Context, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { + if (oldVersion < RECIPIENT_CALL_RINGTONE_VERSION) { + db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN call_ringtone TEXT DEFAULT NULL") + db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN call_vibrate INTEGER DEFAULT " + RecipientDatabase.VibrateState.DEFAULT.id) + } + + if (oldVersion < MIGRATE_PREKEYS_VERSION) { + db.execSQL("CREATE TABLE signed_prekeys (_id INTEGER PRIMARY KEY, key_id INTEGER UNIQUE, public_key TEXT NOT NULL, private_key TEXT NOT NULL, signature TEXT NOT NULL, timestamp INTEGER DEFAULT 0)") + db.execSQL("CREATE TABLE one_time_prekeys (_id INTEGER PRIMARY KEY, key_id INTEGER UNIQUE, public_key TEXT NOT NULL, private_key TEXT NOT NULL)") + + if (!PreKeyMigrationHelper.migratePreKeys(context, db)) { + ApplicationDependencies.getJobManager().add(RefreshPreKeysJob()) + } + } + + if (oldVersion < MIGRATE_SESSIONS_VERSION) { + db.execSQL("CREATE TABLE sessions (_id INTEGER PRIMARY KEY, address TEXT NOT NULL, device INTEGER NOT NULL, record BLOB NOT NULL, UNIQUE(address, device) ON CONFLICT REPLACE)") + SessionStoreMigrationHelper.migrateSessions(context, db) + } + + if (oldVersion < NO_MORE_IMAGE_THUMBNAILS_VERSION) { + val update = ContentValues().apply { + put("thumbnail", null as String?) + put("aspect_ratio", null as String?) + put("thumbnail_random", null as String?) + } + + db.query("part", arrayOf("_id", "ct", "thumbnail"), "thumbnail IS NOT NULL", null, null, null, null).use { cursor -> + while (cursor != null && cursor.moveToNext()) { + val id: Long = cursor.getLong(cursor.getColumnIndexOrThrow("_id")) + val contentType: String? = cursor.getString(cursor.getColumnIndexOrThrow("ct")) + if (contentType != null && !contentType.startsWith("video")) { + val thumbnailPath: String = cursor.getString(cursor.getColumnIndexOrThrow("thumbnail")) + val thumbnailFile: File = File(thumbnailPath) + thumbnailFile.delete() + db.update("part", update, "_id = ?", arrayOf(id.toString())) + } + } + } + } + + if (oldVersion < ATTACHMENT_DIMENSIONS) { + db.execSQL("ALTER TABLE part ADD COLUMN width INTEGER DEFAULT 0") + db.execSQL("ALTER TABLE part ADD COLUMN height INTEGER DEFAULT 0") + } + + if (oldVersion < QUOTED_REPLIES) { + db.execSQL("ALTER TABLE mms ADD COLUMN quote_id INTEGER DEFAULT 0") + db.execSQL("ALTER TABLE mms ADD COLUMN quote_author TEXT") + db.execSQL("ALTER TABLE mms ADD COLUMN quote_body TEXT") + db.execSQL("ALTER TABLE mms ADD COLUMN quote_attachment INTEGER DEFAULT -1") + db.execSQL("ALTER TABLE part ADD COLUMN quote INTEGER DEFAULT 0") + } + + if (oldVersion < SHARED_CONTACTS) { + db.execSQL("ALTER TABLE mms ADD COLUMN shared_contacts TEXT") + } + + if (oldVersion < FULL_TEXT_SEARCH) { + // language=text + db.execSQL("CREATE VIRTUAL TABLE sms_fts USING fts5(body, content=sms, content_rowid=_id)") + db.execSQL( + // language=sql + """ + CREATE TRIGGER sms_ai AFTER INSERT ON sms BEGIN + INSERT INTO sms_fts(rowid, body) VALUES (new._id, new.body); + END; + """.trimIndent() + ) + db.execSQL( + // language=sql + """ + CREATE TRIGGER sms_ad AFTER DELETE ON sms BEGIN + INSERT INTO sms_fts(sms_fts, rowid, body) VALUES('delete', old._id, old.body); + END; + """.trimIndent() + ) + db.execSQL( + // language=sql + """ + CREATE TRIGGER sms_au AFTER UPDATE ON sms BEGIN + INSERT INTO sms_fts(sms_fts, rowid, body) VALUES('delete', old._id, old.body); + INSERT INTO sms_fts(rowid, body) VALUES(new._id, new.body); + END; + """.trimIndent() + ) + // language=text + db.execSQL("CREATE VIRTUAL TABLE mms_fts USING fts5(body, content=mms, content_rowid=_id)") + db.execSQL( + // language=sql + """ + CREATE TRIGGER mms_ai AFTER INSERT ON mms BEGIN + INSERT INTO mms_fts(rowid, body) VALUES (new._id, new.body); + END; + """.trimIndent() + ) + db.execSQL( + // language=sql + """ + CREATE TRIGGER mms_ad AFTER DELETE ON mms BEGIN + INSERT INTO mms_fts(mms_fts, rowid, body) VALUES('delete', old._id, old.body); + END; + """.trimIndent() + ) + db.execSQL( + // language=sql + """ + CREATE TRIGGER mms_au AFTER UPDATE ON mms BEGIN + INSERT INTO mms_fts(mms_fts, rowid, body) VALUES('delete', old._id, old.body); + INSERT INTO mms_fts(rowid, body) VALUES(new._id, new.body); + END; + """.trimIndent() + ) + + Log.i(TAG, "Beginning to build search index.") + + val start = SystemClock.elapsedRealtime() + db.execSQL("INSERT INTO sms_fts (rowid, body) SELECT _id, body FROM sms") + + val smsFinished = SystemClock.elapsedRealtime() + + Log.i(TAG, "Indexing SMS completed in " + (smsFinished - start) + " ms") + db.execSQL("INSERT INTO mms_fts (rowid, body) SELECT _id, body FROM mms") + + val mmsFinished = SystemClock.elapsedRealtime() + + Log.i(TAG, "Indexing MMS completed in " + (mmsFinished - smsFinished) + " ms") + Log.i(TAG, "Indexing finished. Total time: " + (mmsFinished - start) + " ms") + } + + if (oldVersion < BAD_IMPORT_CLEANUP) { + val trimmedCondition = " NOT IN (SELECT _id FROM mms)" + db.delete("group_receipts", "mms_id$trimmedCondition", null) + + val columns = arrayOf("_id", "unique_id", "_data", "thumbnail") + + db.query("part", columns, "mid$trimmedCondition", null, null, null, null).use { cursor -> + while (cursor != null && cursor.moveToNext()) { + db.delete("part", "_id = ? AND unique_id = ?", arrayOf(cursor.getLong(0).toString(), cursor.getLong(1).toString())) + + val data: String = cursor.getString(2) + val thumbnail: String = cursor.getString(3) + + if (!TextUtils.isEmpty(data)) { + File(data).delete() + } + + if (!TextUtils.isEmpty(thumbnail)) { + File(thumbnail).delete() + } + } + } + } + + // Note: This column only being checked due to upgrade issues as described in #8184 + if (oldVersion < QUOTE_MISSING && !SqlUtil.columnExists(db, "mms", "quote_missing")) { + db.execSQL("ALTER TABLE mms ADD COLUMN quote_missing INTEGER DEFAULT 0") + } + + // Note: The column only being checked due to upgrade issues as described in #8184 + if (oldVersion < NOTIFICATION_CHANNELS && !SqlUtil.columnExists(db, "recipient_preferences", "notification_channel")) { + db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN notification_channel TEXT DEFAULT NULL") + NotificationChannels.create(context) + + db.rawQuery("SELECT recipient_ids, system_display_name, signal_profile_name, notification, vibrate FROM recipient_preferences WHERE notification NOT NULL OR vibrate != 0", null).use { cursor -> + while (cursor != null && cursor.moveToNext()) { + val rawAddress: String = cursor.getString(cursor.getColumnIndexOrThrow("recipient_ids")) + val address: String = PhoneNumberFormatter.get(context).format(rawAddress) + val systemName: String = cursor.getString(cursor.getColumnIndexOrThrow("system_display_name")) + val profileName: String = cursor.getString(cursor.getColumnIndexOrThrow("signal_profile_name")) + val messageSound: String? = cursor.getString(cursor.getColumnIndexOrThrow("notification")) + val messageSoundUri: Uri? = if (messageSound != null) Uri.parse(messageSound) else null + val vibrateState: Int = cursor.getInt(cursor.getColumnIndexOrThrow("vibrate")) + var displayName: String? = NotificationChannels.getChannelDisplayNameFor(context, systemName, profileName, null, address) + val vibrateEnabled: Boolean = if (vibrateState == 0) SignalStore.settings().isMessageVibrateEnabled() else vibrateState == 1 + if (GroupId.isEncodedGroup(address)) { + db.rawQuery("SELECT title FROM groups WHERE group_id = ?", arrayOf(address)).use { groupCursor -> + if (groupCursor != null && groupCursor.moveToFirst()) { + val title: String = groupCursor.getString(groupCursor.getColumnIndexOrThrow("title")) + if (!TextUtils.isEmpty(title)) { + displayName = title + } + } + } + } + val channelId: String? = NotificationChannels.createChannelFor(context, "contact_" + address + "_" + System.currentTimeMillis(), (displayName)!!, messageSoundUri, vibrateEnabled, null) + val values = ContentValues(1).apply { + put("notification_channel", channelId) + } + db.update("recipient_preferences", values, "recipient_ids = ?", arrayOf(rawAddress)) + } + } + } + + if (oldVersion < SECRET_SENDER) { + db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN unidentified_access_mode INTEGER DEFAULT 0") + db.execSQL("ALTER TABLE push ADD COLUMN server_timestamp INTEGER DEFAULT 0") + db.execSQL("ALTER TABLE push ADD COLUMN server_guid TEXT DEFAULT NULL") + db.execSQL("ALTER TABLE group_receipts ADD COLUMN unidentified INTEGER DEFAULT 0") + db.execSQL("ALTER TABLE mms ADD COLUMN unidentified INTEGER DEFAULT 0") + db.execSQL("ALTER TABLE sms ADD COLUMN unidentified INTEGER DEFAULT 0") + } + + if (oldVersion < ATTACHMENT_CAPTIONS) { + db.execSQL("ALTER TABLE part ADD COLUMN caption TEXT DEFAULT NULL") + } + + // 4.30.8 included a migration, but not a correct CREATE_TABLE statement, so we need to add + // this column if it isn't present. + if (oldVersion < ATTACHMENT_CAPTIONS_FIX) { + if (!SqlUtil.columnExists(db, "part", "caption")) { + db.execSQL("ALTER TABLE part ADD COLUMN caption TEXT DEFAULT NULL") + } + } + + if (oldVersion < PREVIEWS) { + db.execSQL("ALTER TABLE mms ADD COLUMN previews TEXT") + } + + if (oldVersion < CONVERSATION_SEARCH) { + db.execSQL("DROP TABLE sms_fts") + db.execSQL("DROP TABLE mms_fts") + db.execSQL("DROP TRIGGER sms_ai") + db.execSQL("DROP TRIGGER sms_au") + db.execSQL("DROP TRIGGER sms_ad") + db.execSQL("DROP TRIGGER mms_ai") + db.execSQL("DROP TRIGGER mms_au") + db.execSQL("DROP TRIGGER mms_ad") + // language=text + db.execSQL("CREATE VIRTUAL TABLE sms_fts USING fts5(body, thread_id UNINDEXED, content=sms, content_rowid=_id)") + db.execSQL( + // language=sql + """ + CREATE TRIGGER sms_ai AFTER INSERT ON sms BEGIN + INSERT INTO sms_fts(rowid, body, thread_id) VALUES (new._id, new.body, new.thread_id); + END; + """.trimIndent() + ) + db.execSQL( + // language=sql + """ + CREATE TRIGGER sms_ad AFTER DELETE ON sms BEGIN + INSERT INTO sms_fts(sms_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id); + END; + """.trimIndent() + ) + db.execSQL( + // language=sql + """ + CREATE TRIGGER sms_au AFTER UPDATE ON sms BEGIN + INSERT INTO sms_fts(sms_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id); + INSERT INTO sms_fts(rowid, body, thread_id) VALUES(new._id, new.body, new.thread_id); + END; + """.trimIndent() + ) + // language=text + db.execSQL("CREATE VIRTUAL TABLE mms_fts USING fts5(body, thread_id UNINDEXED, content=mms, content_rowid=_id)") + db.execSQL( + // language=sql + """ + CREATE TRIGGER mms_ai AFTER INSERT ON mms BEGIN + INSERT INTO mms_fts(rowid, body, thread_id) VALUES (new._id, new.body, new.thread_id); + END; + """.trimIndent() + ) + db.execSQL( + // language=sql + """ + CREATE TRIGGER mms_ad AFTER DELETE ON mms BEGIN + INSERT INTO mms_fts(mms_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id); + END; + """.trimIndent() + ) + db.execSQL( + // language=sql + """ + CREATE TRIGGER mms_au AFTER UPDATE ON mms BEGIN + INSERT INTO mms_fts(mms_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id); + INSERT INTO mms_fts(rowid, body, thread_id) VALUES(new._id, new.body, new.thread_id); + END; + """.trimIndent() + ) + + Log.i(TAG, "Beginning to build search index.") + val start = SystemClock.elapsedRealtime() + db.execSQL("INSERT INTO sms_fts (rowid, body, thread_id) SELECT _id, body, thread_id FROM sms") + val smsFinished = SystemClock.elapsedRealtime() + + Log.i(TAG, "Indexing SMS completed in " + (smsFinished - start) + " ms") + db.execSQL("INSERT INTO mms_fts (rowid, body, thread_id) SELECT _id, body, thread_id FROM mms") + val mmsFinished = SystemClock.elapsedRealtime() + Log.i(TAG, "Indexing MMS completed in " + (mmsFinished - smsFinished) + " ms") + + Log.i(TAG, "Indexing finished. Total time: " + (mmsFinished - start) + " ms") + } + + if (oldVersion < SELF_ATTACHMENT_CLEANUP) { + val localNumber = SignalStore.account().e164 + if (!TextUtils.isEmpty(localNumber)) { + db.rawQuery("SELECT _id FROM thread WHERE recipient_ids = ?", arrayOf(localNumber)).use { threadCursor -> + if (threadCursor != null && threadCursor.moveToFirst()) { + val threadId: Long = threadCursor.getLong(0) + val updateValues = ContentValues(1).apply { + put("pending_push", 0) + } + val count: Int = db.update("part", updateValues, "mid IN (SELECT _id FROM mms WHERE thread_id = ?)", arrayOf(threadId.toString())) + Log.i(TAG, "Updated $count self-sent attachments.") + } + } + } + } + + if (oldVersion < RECIPIENT_FORCE_SMS_SELECTION) { + db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN force_sms_selection INTEGER DEFAULT 0") + } + + if (oldVersion < JOBMANAGER_STRIKES_BACK) { + db.execSQL( + // language=sql + """ + CREATE TABLE job_spec( + _id INTEGER PRIMARY KEY AUTOINCREMENT, + job_spec_id TEXT UNIQUE, + factory_key TEXT, + queue_key TEXT, + create_time INTEGER, + next_run_attempt_time INTEGER, + run_attempt INTEGER, + max_attempts INTEGER, + max_backoff INTEGER, + max_instances INTEGER, + lifespan INTEGER, + serialized_data TEXT, + is_running INTEGER + ) + """.trimIndent() + ) + db.execSQL( + // language=sql + """ + CREATE TABLE constraint_spec( + _id INTEGER PRIMARY KEY AUTOINCREMENT, + job_spec_id TEXT, + factory_key TEXT, + UNIQUE(job_spec_id, factory_key) + ) + """.trimIndent() + ) + db.execSQL( + // language=sql + """ + CREATE TABLE dependency_spec( + _id INTEGER PRIMARY KEY AUTOINCREMENT, + job_spec_id TEXT, + depends_on_job_spec_id TEXT, + UNIQUE(job_spec_id, depends_on_job_spec_id) + ) + """.trimIndent() + ) + } + + if (oldVersion < STICKERS) { + db.execSQL( + // language=sql + """ + CREATE TABLE sticker ( + _id INTEGER PRIMARY KEY AUTOINCREMENT, + pack_id TEXT NOT NULL, + pack_key TEXT NOT NULL, + pack_title TEXT NOT NULL, + pack_author TEXT NOT NULL, + sticker_id INTEGER, + cover INTEGER, + emoji TEXT NOT NULL, + last_used INTEGER, + installed INTEGER, + file_path TEXT NOT NULL, + file_length INTEGER, + file_random BLOB, + UNIQUE(pack_id, sticker_id, cover) ON CONFLICT IGNORE + ) + """.trimIndent() + ) + db.execSQL("CREATE INDEX IF NOT EXISTS sticker_pack_id_index ON sticker (pack_id);") + db.execSQL("CREATE INDEX IF NOT EXISTS sticker_sticker_id_index ON sticker (sticker_id);") + db.execSQL("ALTER TABLE part ADD COLUMN sticker_pack_id TEXT") + db.execSQL("ALTER TABLE part ADD COLUMN sticker_pack_key TEXT") + db.execSQL("ALTER TABLE part ADD COLUMN sticker_id INTEGER DEFAULT -1") + db.execSQL("CREATE INDEX IF NOT EXISTS part_sticker_pack_id_index ON part (sticker_pack_id)") + } + + if (oldVersion < REVEALABLE_MESSAGES) { + db.execSQL("ALTER TABLE mms ADD COLUMN reveal_duration INTEGER DEFAULT 0") + db.execSQL("ALTER TABLE mms ADD COLUMN reveal_start_time INTEGER DEFAULT 0") + db.execSQL("ALTER TABLE thread ADD COLUMN snippet_content_type TEXT DEFAULT NULL") + db.execSQL("ALTER TABLE thread ADD COLUMN snippet_extras TEXT DEFAULT NULL") + } + + if (oldVersion < VIEW_ONCE_ONLY) { + db.execSQL("UPDATE mms SET reveal_duration = 1 WHERE reveal_duration > 0") + db.execSQL("UPDATE mms SET reveal_start_time = 0") + } + + if (oldVersion < RECIPIENT_IDS) { + RecipientIdMigrationHelper.execute(db) + } + + if (oldVersion < RECIPIENT_SEARCH) { + db.execSQL("ALTER TABLE recipient ADD COLUMN system_phone_type INTEGER DEFAULT -1") + val localNumber = SignalStore.account().e164 + if (!TextUtils.isEmpty(localNumber)) { + db.query("recipient", null, "phone = ?", arrayOf(localNumber), null, null, null).use { cursor -> + if (cursor == null || !cursor.moveToFirst()) { + val values = ContentValues().apply { + put("phone", localNumber) + put("registered", 1) + put("profile_sharing", 1) + } + db.insert("recipient", null, values) + } else { + db.execSQL("UPDATE recipient SET registered = ?, profile_sharing = ? WHERE phone = ?", arrayOf("1", "1", localNumber)) + } + } + } + } + + if (oldVersion < RECIPIENT_CLEANUP) { + RecipientIdCleanupHelper.execute(db) + } + + if (oldVersion < MMS_RECIPIENT_CLEANUP) { + val values = ContentValues(1) + values.put("address", "-1") + val count = db.update("mms", values, "address = ?", arrayOf("0")) + Log.i(TAG, "MMS recipient cleanup updated $count rows.") + } + + if (oldVersion < ATTACHMENT_HASHING) { + db.execSQL("ALTER TABLE part ADD COLUMN data_hash TEXT DEFAULT NULL") + db.execSQL("CREATE INDEX IF NOT EXISTS part_data_hash_index ON part (data_hash)") + } + + if (oldVersion < NOTIFICATION_RECIPIENT_IDS && Build.VERSION.SDK_INT >= 26) { + val notificationManager = ServiceUtil.getNotificationManager(context) + val channels = Stream.of(notificationManager.notificationChannels) + .filter { c: NotificationChannel -> c.getId().startsWith("contact_") } + .toList() + + Log.i(TAG, "Migrating " + channels.size + " channels to use RecipientId's.") + + for (oldChannel: NotificationChannel in channels) { + notificationManager.deleteNotificationChannel(oldChannel.id) + val startIndex = "contact_".length + val endIndex = oldChannel.id.lastIndexOf("_") + val address = oldChannel.id.substring(startIndex, endIndex) + var recipientId: String? + + db.query("recipient", arrayOf("_id"), "phone = ? OR email = ? OR group_id = ?", arrayOf(address, address, address), null, null, null).use { cursor -> + recipientId = if (cursor != null && cursor.moveToFirst()) { + cursor.getString(cursor.getColumnIndexOrThrow("_id")) + } else { + Log.w(TAG, "Couldn't find recipient for address: $address") + null + } + } + + if (recipientId == null) { + continue + } + + val newId = "contact_" + recipientId + "_" + System.currentTimeMillis() + val newChannel = NotificationChannel(newId, oldChannel.name, oldChannel.importance) + Log.i(TAG, "Updating channel ID from '" + oldChannel.id + "' to '" + newChannel.id + "'.") + newChannel.group = oldChannel.group + newChannel.setSound(oldChannel.sound, oldChannel.audioAttributes) + newChannel.setBypassDnd(oldChannel.canBypassDnd()) + newChannel.enableVibration(oldChannel.shouldVibrate()) + newChannel.vibrationPattern = oldChannel.vibrationPattern + newChannel.lockscreenVisibility = oldChannel.lockscreenVisibility + newChannel.setShowBadge(oldChannel.canShowBadge()) + newChannel.lightColor = oldChannel.lightColor + newChannel.enableLights(oldChannel.shouldShowLights()) + notificationManager.createNotificationChannel(newChannel) + val contentValues = ContentValues(1).apply { + put("notification_channel", newChannel.id) + } + db.update("recipient", contentValues, "_id = ?", arrayOf(recipientId)) + } + } + + if (oldVersion < BLUR_HASH) { + db.execSQL("ALTER TABLE part ADD COLUMN blur_hash TEXT DEFAULT NULL") + } + + if (oldVersion < MMS_RECIPIENT_CLEANUP_2) { + val values = ContentValues(1).apply { + put("address", "-1") + } + val count = db.update("mms", values, "address = ? OR address IS NULL", arrayOf("0")) + Log.i(TAG, "MMS recipient cleanup 2 updated $count rows.") + } + + if (oldVersion < ATTACHMENT_TRANSFORM_PROPERTIES) { + db.execSQL("ALTER TABLE part ADD COLUMN transform_properties TEXT DEFAULT NULL") + } + + if (oldVersion < ATTACHMENT_CLEAR_HASHES) { + db.execSQL("UPDATE part SET data_hash = null") + } + + if (oldVersion < ATTACHMENT_CLEAR_HASHES_2) { + db.execSQL("UPDATE part SET data_hash = null") + Glide.get(context).clearDiskCache() + } + + if (oldVersion < UUIDS) { + db.execSQL("ALTER TABLE recipient ADD COLUMN uuid_supported INTEGER DEFAULT 0") + db.execSQL("ALTER TABLE push ADD COLUMN source_uuid TEXT DEFAULT NULL") + } + + if (oldVersion < USERNAMES) { + db.execSQL("ALTER TABLE recipient ADD COLUMN username TEXT DEFAULT NULL") + db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS recipient_username_index ON recipient (username)") + } + + if (oldVersion < REACTIONS) { + db.execSQL("ALTER TABLE sms ADD COLUMN reactions BLOB DEFAULT NULL") + db.execSQL("ALTER TABLE mms ADD COLUMN reactions BLOB DEFAULT NULL") + db.execSQL("ALTER TABLE sms ADD COLUMN reactions_unread INTEGER DEFAULT 0") + db.execSQL("ALTER TABLE mms ADD COLUMN reactions_unread INTEGER DEFAULT 0") + db.execSQL("ALTER TABLE sms ADD COLUMN reactions_last_seen INTEGER DEFAULT -1") + db.execSQL("ALTER TABLE mms ADD COLUMN reactions_last_seen INTEGER DEFAULT -1") + } + + if (oldVersion < STORAGE_SERVICE) { + db.execSQL( + // language=sql + """ + CREATE TABLE storage_key ( + _id INTEGER PRIMARY KEY AUTOINCREMENT, + type INTEGER, + key TEXT UNIQUE + ) + """.trimIndent() + ) + db.execSQL("CREATE INDEX IF NOT EXISTS storage_key_type_index ON storage_key (type)") + db.execSQL("ALTER TABLE recipient ADD COLUMN system_info_pending INTEGER DEFAULT 0") + db.execSQL("ALTER TABLE recipient ADD COLUMN storage_service_key TEXT DEFAULT NULL") + db.execSQL("ALTER TABLE recipient ADD COLUMN dirty INTEGER DEFAULT 0") + db.execSQL("CREATE UNIQUE INDEX recipient_storage_service_key ON recipient (storage_service_key)") + db.execSQL("CREATE INDEX recipient_dirty_index ON recipient (dirty)") + } + + if (oldVersion < REACTIONS_UNREAD_INDEX) { + db.execSQL("CREATE INDEX IF NOT EXISTS sms_reactions_unread_index ON sms (reactions_unread);") + db.execSQL("CREATE INDEX IF NOT EXISTS mms_reactions_unread_index ON mms (reactions_unread);") + } + + if (oldVersion < RESUMABLE_DOWNLOADS) { + db.execSQL("ALTER TABLE part ADD COLUMN transfer_file TEXT DEFAULT NULL") + } + + if (oldVersion < KEY_VALUE_STORE) { + db.execSQL( + // language=sql + """ + CREATE TABLE key_value ( + _id INTEGER PRIMARY KEY AUTOINCREMENT, + key TEXT UNIQUE, + value TEXT, + type INTEGER + ) + """.trimIndent() + ) + } + + if (oldVersion < ATTACHMENT_DISPLAY_ORDER) { + db.execSQL("ALTER TABLE part ADD COLUMN display_order INTEGER DEFAULT 0") + } + + if (oldVersion < SPLIT_PROFILE_NAMES) { + db.execSQL("ALTER TABLE recipient ADD COLUMN profile_family_name TEXT DEFAULT NULL") + db.execSQL("ALTER TABLE recipient ADD COLUMN profile_joined_name TEXT DEFAULT NULL") + } + + if (oldVersion < STICKER_PACK_ORDER) { + db.execSQL("ALTER TABLE sticker ADD COLUMN pack_order INTEGER DEFAULT 0") + } + + if (oldVersion < MEGAPHONES) { + db.execSQL( + // language=sql + """ + CREATE TABLE megaphone ( + _id INTEGER PRIMARY KEY AUTOINCREMENT, + event TEXT UNIQUE, + seen_count INTEGER, + last_seen INTEGER, + finished INTEGER + ) + """.trimIndent() + ) + } + + if (oldVersion < MEGAPHONE_FIRST_APPEARANCE) { + db.execSQL("ALTER TABLE megaphone ADD COLUMN first_visible INTEGER DEFAULT 0") + } + + if (oldVersion < PROFILE_KEY_TO_DB) { + val localNumber = SignalStore.account().e164 + if (!TextUtils.isEmpty(localNumber)) { + val encodedProfileKey = PreferenceManager.getDefaultSharedPreferences(context).getString("pref_profile_key", null) + val profileKey = if (encodedProfileKey != null) Base64.decodeOrThrow(encodedProfileKey) else Util.getSecretBytes(32) + val values = ContentValues(1).apply { + put("profile_key", Base64.encodeBytes(profileKey)) + } + if (db.update("recipient", values, "phone = ?", arrayOf(localNumber)) == 0) { + throw AssertionError("No rows updated!") + } + } + } + + if (oldVersion < PROFILE_KEY_CREDENTIALS) { + db.execSQL("ALTER TABLE recipient ADD COLUMN profile_key_credential TEXT DEFAULT NULL") + } + + if (oldVersion < ATTACHMENT_FILE_INDEX) { + db.execSQL("CREATE INDEX IF NOT EXISTS part_data_index ON part (_data)") + } + + if (oldVersion < STORAGE_SERVICE_ACTIVE) { + db.execSQL("ALTER TABLE recipient ADD COLUMN group_type INTEGER DEFAULT 0") + db.execSQL("CREATE INDEX IF NOT EXISTS recipient_group_type_index ON recipient (group_type)") + db.execSQL("UPDATE recipient set group_type = 1 WHERE group_id NOT NULL AND group_id LIKE '__signal_mms_group__%'") + db.execSQL("UPDATE recipient set group_type = 2 WHERE group_id NOT NULL AND group_id LIKE '__textsecure_group__%'") + db.rawQuery("SELECT _id FROM recipient WHERE registered = 1 or group_type = 2", null).use { cursor -> + while (cursor != null && cursor.moveToNext()) { + val id: String = cursor.getString(cursor.getColumnIndexOrThrow("_id")) + val values = ContentValues(2).apply { + put("dirty", 2) + put("storage_service_key", Base64.encodeBytes(StorageSyncHelper.generateKey())) + } + db.update("recipient", values, "_id = ?", arrayOf(id)) + } + } + } + + if (oldVersion < GROUPS_V2_RECIPIENT_CAPABILITY) { + db.execSQL("ALTER TABLE recipient ADD COLUMN gv2_capability INTEGER DEFAULT 0") + } + + if (oldVersion < TRANSFER_FILE_CLEANUP) { + val partsDirectory: File = context.getDir("parts", Context.MODE_PRIVATE) + if (partsDirectory.exists()) { + val transferFiles = partsDirectory.listFiles { dir: File?, name: String -> name.startsWith("transfer") } + var deleteCount = 0 + Log.i(TAG, "Found " + transferFiles.size + " dangling transfer files.") + for (file: File in transferFiles) { + if (file.delete()) { + Log.i(TAG, "Deleted " + file.name) + deleteCount++ + } + } + Log.i(TAG, "Deleted $deleteCount dangling transfer files.") + } else { + Log.w(TAG, "Part directory did not exist. Skipping.") + } + } + + if (oldVersion < PROFILE_DATA_MIGRATION) { + val localNumber = SignalStore.account().e164 + if (localNumber != null) { + val encodedProfileName = PreferenceManager.getDefaultSharedPreferences(context).getString("pref_profile_name", null) + val profileName = ProfileName.fromSerialized(encodedProfileName) + db.execSQL("UPDATE recipient SET signal_profile_name = ?, profile_family_name = ?, profile_joined_name = ? WHERE phone = ?", arrayOf(profileName.givenName, profileName.familyName, profileName.toString(), localNumber)) + } + } + + if (oldVersion < AVATAR_LOCATION_MIGRATION) { + val oldAvatarDirectory: File = File(context.getFilesDir(), "avatars") + val results = oldAvatarDirectory.listFiles() + if (results != null) { + Log.i(TAG, "Preparing to migrate " + results.size + " avatars.") + for (file: File in results) { + if (Util.isLong(file.name)) { + try { + AvatarHelper.setAvatar(context, RecipientId.from(file.name), FileInputStream(file)) + } catch (e: IOException) { + Log.w(TAG, "Failed to copy file " + file.name + "! Skipping.") + } + } else { + Log.w(TAG, "Invalid avatar name '" + file.name + "'! Skipping.") + } + } + } else { + Log.w(TAG, "No avatar directory files found.") + } + if (!FileUtils.deleteDirectory(oldAvatarDirectory)) { + Log.w(TAG, "Failed to delete avatar directory.") + } + db.rawQuery("SELECT recipient_id, avatar FROM groups", null).use { cursor -> + while (cursor != null && cursor.moveToNext()) { + val recipientId: RecipientId = RecipientId.from(cursor.getLong(cursor.getColumnIndexOrThrow("recipient_id"))) + val avatar: ByteArray? = cursor.getBlob(cursor.getColumnIndexOrThrow("avatar")) + try { + AvatarHelper.setAvatar(context, recipientId, if (avatar != null) ByteArrayInputStream(avatar) else null) + } catch (e: IOException) { + Log.w(TAG, "Failed to copy avatar for " + recipientId + "! Skipping.", e) + } + } + } + db.execSQL("UPDATE groups SET avatar_id = 0 WHERE avatar IS NULL") + db.execSQL("UPDATE groups SET avatar = NULL") + } + + if (oldVersion < GROUPS_V2) { + db.execSQL("ALTER TABLE groups ADD COLUMN master_key") + db.execSQL("ALTER TABLE groups ADD COLUMN revision") + db.execSQL("ALTER TABLE groups ADD COLUMN decrypted_group") + } + + if (oldVersion < ATTACHMENT_UPLOAD_TIMESTAMP) { + db.execSQL("ALTER TABLE part ADD COLUMN upload_timestamp DEFAULT 0") + } + + if (oldVersion < ATTACHMENT_CDN_NUMBER) { + db.execSQL("ALTER TABLE part ADD COLUMN cdn_number INTEGER DEFAULT 0") + } + + if (oldVersion < JOB_INPUT_DATA) { + db.execSQL("ALTER TABLE job_spec ADD COLUMN serialized_input_data TEXT DEFAULT NULL") + } + + if (oldVersion < SERVER_TIMESTAMP) { + db.execSQL("ALTER TABLE sms ADD COLUMN date_server INTEGER DEFAULT -1") + db.execSQL("CREATE INDEX IF NOT EXISTS sms_date_server_index ON sms (date_server)") + db.execSQL("ALTER TABLE mms ADD COLUMN date_server INTEGER DEFAULT -1") + db.execSQL("CREATE INDEX IF NOT EXISTS mms_date_server_index ON mms (date_server)") + } + + if (oldVersion < REMOTE_DELETE) { + db.execSQL("ALTER TABLE sms ADD COLUMN remote_deleted INTEGER DEFAULT 0") + db.execSQL("ALTER TABLE mms ADD COLUMN remote_deleted INTEGER DEFAULT 0") + } + + if (oldVersion < COLOR_MIGRATION) { + db.rawQuery("SELECT _id, system_display_name FROM recipient WHERE system_display_name NOT NULL AND color IS NULL", null).use { cursor -> + while (cursor != null && cursor.moveToNext()) { + val id: Long = cursor.getLong(cursor.getColumnIndexOrThrow("_id")) + val name: String = cursor.getString(cursor.getColumnIndexOrThrow("system_display_name")) + val values: ContentValues = ContentValues() + values.put("color", ContactColorsLegacy.generateForV2(name).serialize()) + db.update("recipient", values, "_id = ?", arrayOf(id.toString())) + } + } + } + + if (oldVersion < LAST_SCROLLED) { + db.execSQL("ALTER TABLE thread ADD COLUMN last_scrolled INTEGER DEFAULT 0") + } + + if (oldVersion < LAST_PROFILE_FETCH) { + db.execSQL("ALTER TABLE recipient ADD COLUMN last_profile_fetch INTEGER DEFAULT 0") + } + + if (oldVersion < SERVER_DELIVERED_TIMESTAMP) { + db.execSQL("ALTER TABLE push ADD COLUMN server_delivered_timestamp INTEGER DEFAULT 0") + } + + if (oldVersion < QUOTE_CLEANUP) { + val query = ( + // language=sql + """ + SELECT _data + FROM ( + SELECT _data, MIN(quote) AS all_quotes + FROM part + WHERE _data NOT NULL AND data_hash NOT NULL + GROUP BY _data + ) + WHERE all_quotes = 1 + """.trimIndent() + ) + var count = 0 + db.rawQuery(query, null).use { cursor -> + while (cursor != null && cursor.moveToNext()) { + val data: String = cursor.getString(cursor.getColumnIndexOrThrow("_data")) + if (File(data).delete()) { + val values = ContentValues().apply { + putNull("_data") + putNull("data_random") + putNull("thumbnail") + putNull("thumbnail_random") + putNull("data_hash") + } + db.update("part", values, "_data = ?", arrayOf(data)) + count++ + } else { + Log.w(TAG, "[QuoteCleanup] Failed to delete " + data) + } + } + } + Log.i(TAG, "[QuoteCleanup] Cleaned up $count quotes.") + } + + if (oldVersion < BORDERLESS) { + db.execSQL("ALTER TABLE part ADD COLUMN borderless INTEGER DEFAULT 0") + } + + if (oldVersion < REMAPPED_RECORDS) { + db.execSQL( + // language=sql + """ + CREATE TABLE remapped_recipients ( + _id INTEGER PRIMARY KEY AUTOINCREMENT, + old_id INTEGER UNIQUE, + new_id INTEGER + ) + """.trimIndent() + ) + db.execSQL( + // language=sql + """ + CREATE TABLE remapped_threads ( + _id INTEGER PRIMARY KEY AUTOINCREMENT, + old_id INTEGER UNIQUE, + new_id INTEGER + ) + """.trimIndent() + ) + } + + if (oldVersion < MENTIONS) { + db.execSQL( + // language=sql + """ + CREATE TABLE mention ( + _id INTEGER PRIMARY KEY AUTOINCREMENT, + thread_id INTEGER, + message_id INTEGER, + recipient_id INTEGER, + range_start INTEGER, + range_length INTEGER + ) + """ + ) + db.execSQL("CREATE INDEX IF NOT EXISTS mention_message_id_index ON mention (message_id)") + db.execSQL("CREATE INDEX IF NOT EXISTS mention_recipient_id_thread_id_index ON mention (recipient_id, thread_id);") + db.execSQL("ALTER TABLE mms ADD COLUMN quote_mentions BLOB DEFAULT NULL") + db.execSQL("ALTER TABLE mms ADD COLUMN mentions_self INTEGER DEFAULT 0") + db.execSQL("ALTER TABLE recipient ADD COLUMN mention_setting INTEGER DEFAULT 0") + } + + if (oldVersion < PINNED_CONVERSATIONS) { + db.execSQL("ALTER TABLE thread ADD COLUMN pinned INTEGER DEFAULT 0") + db.execSQL("CREATE INDEX IF NOT EXISTS thread_pinned_index ON thread (pinned)") + } + + if (oldVersion < MENTION_GLOBAL_SETTING_MIGRATION) { + val updateAlways = ContentValues() + updateAlways.put("mention_setting", 0) + db.update("recipient", updateAlways, "mention_setting = 1", null) + val updateNever = ContentValues() + updateNever.put("mention_setting", 1) + db.update("recipient", updateNever, "mention_setting = 2", null) + } + + if (oldVersion < UNKNOWN_STORAGE_FIELDS) { + db.execSQL("ALTER TABLE recipient ADD COLUMN storage_proto TEXT DEFAULT NULL") + } + + if (oldVersion < STICKER_CONTENT_TYPE) { + db.execSQL("ALTER TABLE sticker ADD COLUMN content_type TEXT DEFAULT NULL") + } + + if (oldVersion < STICKER_EMOJI_IN_NOTIFICATIONS) { + db.execSQL("ALTER TABLE part ADD COLUMN sticker_emoji TEXT DEFAULT NULL") + } + + if (oldVersion < THUMBNAIL_CLEANUP) { + var total = 0 + var deleted = 0 + db.rawQuery("SELECT thumbnail FROM part WHERE thumbnail NOT NULL", null).use { cursor -> + if (cursor != null) { + total = cursor.getCount() + Log.w(TAG, "Found " + total + " thumbnails to delete.") + } + while (cursor != null && cursor.moveToNext()) { + val file: File = File(CursorUtil.requireString(cursor, "thumbnail")) + if (file.delete()) { + deleted++ + } else { + Log.w(TAG, "Failed to delete file! " + file.getAbsolutePath()) + } + } + } + Log.w(TAG, "Deleted $deleted/$total thumbnail files.") + } + + if (oldVersion < STICKER_CONTENT_TYPE_CLEANUP) { + val values = ContentValues().apply { + put("ct", "image/webp") + } + val query = "sticker_id NOT NULL AND (ct IS NULL OR ct = '')" + val rows = db.update("part", values, query, null) + Log.i(TAG, "Updated $rows sticker attachment content types.") + } + + if (oldVersion < MENTION_CLEANUP) { + val selectMentionIdsNotInGroupsV2 = "select mention._id from mention left join thread on mention.thread_id = thread._id left join recipient on thread.recipient_ids = recipient._id where recipient.group_type != 3" + db.delete("mention", "_id in ($selectMentionIdsNotInGroupsV2)", null) + db.delete("mention", "message_id NOT IN (SELECT _id FROM mms) OR thread_id NOT IN (SELECT _id from thread)", null) + + val idsToDelete: MutableList = LinkedList() + db.rawQuery("select mention.*, mms.body from mention inner join mms on mention.message_id = mms._id", null).use { cursor -> + while (cursor != null && cursor.moveToNext()) { + val rangeStart: Int = CursorUtil.requireInt(cursor, "range_start") + val rangeLength: Int = CursorUtil.requireInt(cursor, "range_length") + val body: String? = CursorUtil.requireString(cursor, "body") + if ((body == null) || body.isEmpty() || (rangeStart < 0) || (rangeLength < 0) || ((rangeStart + rangeLength) > body.length)) { + idsToDelete.add(CursorUtil.requireLong(cursor, "_id")) + } + } + } + + if (Util.hasItems(idsToDelete)) { + val ids = TextUtils.join(",", idsToDelete) + db.delete("mention", "_id in ($ids)", null) + } + } + + if (oldVersion < MENTION_CLEANUP_V2) { + val selectMentionIdsWithMismatchingThreadIds = "select mention._id from mention left join mms on mention.message_id = mms._id where mention.thread_id != mms.thread_id" + db.delete("mention", "_id in ($selectMentionIdsWithMismatchingThreadIds)", null) + + val idsToDelete: MutableList = LinkedList() + val mentionTuples: MutableSet> = HashSet() + + db.rawQuery("select mention.*, mms.body from mention inner join mms on mention.message_id = mms._id order by mention._id desc", null).use { cursor -> + while (cursor != null && cursor.moveToNext()) { + val mentionId: Long = CursorUtil.requireLong(cursor, "_id") + val messageId: Long = CursorUtil.requireLong(cursor, "message_id") + val rangeStart: Int = CursorUtil.requireInt(cursor, "range_start") + val rangeLength: Int = CursorUtil.requireInt(cursor, "range_length") + val body: String? = CursorUtil.requireString(cursor, "body") + + if ((body != null) && (rangeStart < body.length) && (body.get(rangeStart) != '\uFFFC')) { + idsToDelete.add(mentionId) + } else { + val tuple: Triple = Triple(messageId, rangeStart, rangeLength) + if (mentionTuples.contains(tuple)) { + idsToDelete.add(mentionId) + } else { + mentionTuples.add(tuple) + } + } + } + + if (Util.hasItems(idsToDelete)) { + val ids: String = TextUtils.join(",", idsToDelete) + db.delete("mention", "_id in (" + ids + ")", null) + } + } + } + + if (oldVersion < REACTION_CLEANUP) { + val values = ContentValues().apply { + putNull("reactions") + } + db.update("sms", values, "remote_deleted = ?", arrayOf("1")) + } + + if (oldVersion < CAPABILITIES_REFACTOR) { + db.execSQL("ALTER TABLE recipient ADD COLUMN capabilities INTEGER DEFAULT 0") + db.execSQL("UPDATE recipient SET capabilities = 1 WHERE gv2_capability = 1") + db.execSQL("UPDATE recipient SET capabilities = 2 WHERE gv2_capability = -1") + } + + if (oldVersion < GV1_MIGRATION) { + db.execSQL("ALTER TABLE groups ADD COLUMN expected_v2_id TEXT DEFAULT NULL") + db.execSQL("ALTER TABLE groups ADD COLUMN former_v1_members TEXT DEFAULT NULL") + db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS expected_v2_id_index ON groups (expected_v2_id)") + var count = 0 + db.rawQuery("SELECT * FROM groups WHERE group_id LIKE '__textsecure_group__!%' AND LENGTH(group_id) = 53", null).use { cursor -> + while (cursor.moveToNext()) { + val gv1: String = CursorUtil.requireString(cursor, "group_id") + val gv2: String = GroupId.parseOrThrow(gv1).requireV1().deriveV2MigrationGroupId().toString() + val values = ContentValues().apply { + put("expected_v2_id", gv2) + } + count += db.update("groups", values, "group_id = ?", SqlUtil.buildArgs(gv1)) + } + } + Log.i(TAG, "Updated $count GV1 groups with expected GV2 IDs.") + } + + if (oldVersion < NOTIFIED_TIMESTAMP) { + db.execSQL("ALTER TABLE sms ADD COLUMN notified_timestamp INTEGER DEFAULT 0") + db.execSQL("ALTER TABLE mms ADD COLUMN notified_timestamp INTEGER DEFAULT 0") + } + + if (oldVersion < GV1_MIGRATION_LAST_SEEN) { + db.execSQL("ALTER TABLE recipient ADD COLUMN last_gv1_migrate_reminder INTEGER DEFAULT 0") + } + + if (oldVersion < VIEWED_RECEIPTS) { + db.execSQL("ALTER TABLE mms ADD COLUMN viewed_receipt_count INTEGER DEFAULT 0") + } + + if (oldVersion < CLEAN_UP_GV1_IDS) { + val deletableRecipients: MutableList = LinkedList() + db.rawQuery( + // language=sql + """ + SELECT _id, group_id + FROM recipient + WHERE group_id NOT IN (SELECT group_id FROM groups) + AND group_id LIKE '__textsecure_group__!%' AND length(group_id) <> 53 + AND (_id NOT IN (SELECT recipient_ids FROM thread) OR _id IN (SELECT recipient_ids FROM thread WHERE message_count = 0)) + """.trimIndent(), + null + ).use { cursor -> + while (cursor.moveToNext()) { + val recipientId: String = cursor.getString(cursor.getColumnIndexOrThrow("_id")) + val groupIdV1: String = cursor.getString(cursor.getColumnIndexOrThrow("group_id")) + deletableRecipients.add(recipientId) + Log.d(TAG, String.format(Locale.US, "Found invalid GV1 on %s with no or empty thread %s length %d", recipientId, groupIdV1, groupIdV1.length)) + } + } + for (recipientId: String in deletableRecipients) { + db.delete("recipient", "_id = ?", arrayOf(recipientId)) + Log.d(TAG, "Deleted recipient $recipientId") + } + val orphanedThreads: MutableList = LinkedList() + db.rawQuery("SELECT _id FROM thread WHERE message_count = 0 AND recipient_ids NOT IN (SELECT _id FROM recipient)", null).use { cursor -> + while (cursor.moveToNext()) { + orphanedThreads.add(cursor.getString(cursor.getColumnIndexOrThrow("_id"))) + } + } + for (orphanedThreadId: String in orphanedThreads) { + db.delete("thread", "_id = ?", arrayOf(orphanedThreadId)) + Log.d(TAG, "Deleted orphaned thread $orphanedThreadId") + } + val remainingInvalidGV1Recipients: MutableList = LinkedList() + db.rawQuery( + // language=sql + """ + SELECT _id, group_id FROM recipient + WHERE group_id NOT IN (SELECT group_id FROM groups) + AND group_id LIKE '__textsecure_group__!%' AND length(group_id) <> 53 + AND _id IN (SELECT recipient_ids FROM thread) + """.trimIndent(), + null + ).use { cursor -> + while (cursor.moveToNext()) { + val recipientId: String = cursor.getString(cursor.getColumnIndexOrThrow("_id")) + val groupIdV1: String = cursor.getString(cursor.getColumnIndexOrThrow("group_id")) + remainingInvalidGV1Recipients.add(recipientId) + Log.d(TAG, String.format(Locale.US, "Found invalid GV1 on %s with non-empty thread %s length %d", recipientId, groupIdV1, groupIdV1.length)) + } + } + for (recipientId: String in remainingInvalidGV1Recipients) { + val newId = "__textsecure_group__!" + Hex.toStringCondensed(Util.getSecretBytes(16)) + val values = ContentValues(1) + values.put("group_id", newId) + db.update("recipient", values, "_id = ?", arrayOf(recipientId)) + Log.d(TAG, String.format("Replaced group id on recipient %s now %s", recipientId, newId)) + } + } + + if (oldVersion < GV1_MIGRATION_REFACTOR) { + val values = ContentValues(1) + values.putNull("former_v1_members") + val count = db.update("groups", values, "former_v1_members NOT NULL", null) + Log.i(TAG, "Cleared former_v1_members for $count rows") + } + + if (oldVersion < CLEAR_PROFILE_KEY_CREDENTIALS) { + val values = ContentValues(1) + values.putNull("profile_key_credential") + val count = db.update("recipient", values, "profile_key_credential NOT NULL", null) + Log.i(TAG, "Cleared profile key credentials for $count rows") + } + + if (oldVersion < LAST_RESET_SESSION_TIME) { + db.execSQL("ALTER TABLE recipient ADD COLUMN last_session_reset BLOB DEFAULT NULL") + } + + if (oldVersion < WALLPAPER) { + db.execSQL("ALTER TABLE recipient ADD COLUMN wallpaper BLOB DEFAULT NULL") + db.execSQL("ALTER TABLE recipient ADD COLUMN wallpaper_file TEXT DEFAULT NULL") + } + + if (oldVersion < ABOUT) { + db.execSQL("ALTER TABLE recipient ADD COLUMN about TEXT DEFAULT NULL") + db.execSQL("ALTER TABLE recipient ADD COLUMN about_emoji TEXT DEFAULT NULL") + } + + if (oldVersion < SPLIT_SYSTEM_NAMES) { + db.execSQL("ALTER TABLE recipient ADD COLUMN system_family_name TEXT DEFAULT NULL") + db.execSQL("ALTER TABLE recipient ADD COLUMN system_given_name TEXT DEFAULT NULL") + db.execSQL("UPDATE recipient SET system_given_name = system_display_name") + } + + if (oldVersion < PAYMENTS) { + db.execSQL( + // language=sql + """ + CREATE TABLE payments( + _id INTEGER PRIMARY KEY, + uuid TEXT DEFAULT NULL, + recipient INTEGER DEFAULT 0, + recipient_address TEXT DEFAULT NULL, + timestamp INTEGER, + note TEXT DEFAULT NULL, + direction INTEGER, + state INTEGER, + failure_reason INTEGER, + amount BLOB NOT NULL, + fee BLOB NOT NULL, + transaction_record BLOB DEFAULT NULL, + receipt BLOB DEFAULT NULL, + payment_metadata BLOB DEFAULT NULL, + receipt_public_key TEXT DEFAULT NULL, + block_index INTEGER DEFAULT 0, + block_timestamp INTEGER DEFAULT 0, + seen INTEGER, + UNIQUE(uuid) ON CONFLICT ABORT + ) + """.trimIndent() + ) + db.execSQL("CREATE INDEX IF NOT EXISTS timestamp_direction_index ON payments (timestamp, direction);") + db.execSQL("CREATE INDEX IF NOT EXISTS timestamp_index ON payments (timestamp);") + db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS receipt_public_key_index ON payments (receipt_public_key);") + } + + if (oldVersion < CLEAN_STORAGE_IDS) { + val values = ContentValues() + values.putNull("storage_service_key") + val count = db.update("recipient", values, "storage_service_key NOT NULL AND ((phone NOT NULL AND INSTR(phone, '+') = 0) OR (group_id NOT NULL AND (LENGTH(group_id) != 85 and LENGTH(group_id) != 53)))", null) + Log.i(TAG, "There were $count bad rows that had their storageID removed.") + } + + if (oldVersion < MP4_GIF_SUPPORT) { + db.execSQL("ALTER TABLE part ADD COLUMN video_gif INTEGER DEFAULT 0") + } + + if (oldVersion < BLUR_AVATARS) { + db.execSQL("ALTER TABLE recipient ADD COLUMN extras BLOB DEFAULT NULL") + db.execSQL("ALTER TABLE recipient ADD COLUMN groups_in_common INTEGER DEFAULT 0") + val secureOutgoingSms = "EXISTS(SELECT 1 FROM sms WHERE thread_id = t._id AND (type & 31) = 23 AND (type & 10485760) AND (type & 131072 = 0))" + val secureOutgoingMms = "EXISTS(SELECT 1 FROM mms WHERE thread_id = t._id AND (msg_box & 31) = 23 AND (msg_box & 10485760) AND (msg_box & 131072 = 0))" + val selectIdsToUpdateProfileSharing = "SELECT r._id FROM recipient AS r INNER JOIN thread AS t ON r._id = t.recipient_ids WHERE profile_sharing = 0 AND ($secureOutgoingSms OR $secureOutgoingMms)" + db.execSQL("UPDATE recipient SET profile_sharing = 1 WHERE _id IN ($selectIdsToUpdateProfileSharing)") + val selectIdsWithGroupsInCommon = + // language=sql + """ + SELECT r._id FROM recipient AS r WHERE EXISTS ( + SELECT 1 + FROM groups AS g + INNER JOIN recipient AS gr ON (g.recipient_id = gr._id AND gr.profile_sharing = 1) + WHERE g.active = 1 AND (g.members LIKE r._id || ',%' OR g.members LIKE '%,' || r._id || ',%' OR g.members LIKE '%,' || r._id) + ) + """.trimIndent() + + db.execSQL("UPDATE recipient SET groups_in_common = 1 WHERE _id IN ($selectIdsWithGroupsInCommon)") + } + + if (oldVersion < CLEAN_STORAGE_IDS_WITHOUT_INFO) { + val values = ContentValues() + values.putNull("storage_service_key") + val count = db.update("recipient", values, "storage_service_key NOT NULL AND phone IS NULL AND uuid IS NULL AND group_id IS NULL", null) + Log.i(TAG, "There were $count bad rows that had their storageID removed due to not having any other identifier.") + } + + if (oldVersion < CLEAN_REACTION_NOTIFICATIONS) { + val values = ContentValues(1) + values.put("notified", 1) + var count = 0 + count += db.update("sms", values, "notified = 0 AND read = 1 AND reactions_unread = 1 AND NOT ((type & 31) = 23 AND (type & 10485760) AND (type & 131072 = 0))", null) + count += db.update("mms", values, "notified = 0 AND read = 1 AND reactions_unread = 1 AND NOT ((msg_box & 31) = 23 AND (msg_box & 10485760) AND (msg_box & 131072 = 0))", null) + Log.d(TAG, "Resetting notified for $count read incoming messages that were incorrectly flipped when receiving reactions") + val smsIds: MutableList = ArrayList() + db.query("sms", arrayOf("_id", "reactions", "notified_timestamp"), "notified = 0 AND reactions_unread = 1", null, null, null, null).use { cursor -> + while (cursor.moveToNext()) { + val reactions: ByteArray? = cursor.getBlob(cursor.getColumnIndexOrThrow("reactions")) + val notifiedTimestamp: Long = cursor.getLong(cursor.getColumnIndexOrThrow("notified_timestamp")) + if (reactions == null) { + continue + } + try { + val hasReceiveLaterThanNotified: Boolean = ReactionList.parseFrom(reactions) + .getReactionsList() + .stream() + .anyMatch { r: ReactionList.Reaction -> r.getReceivedTime() > notifiedTimestamp } + if (!hasReceiveLaterThanNotified) { + smsIds.add(cursor.getLong(cursor.getColumnIndexOrThrow("_id"))) + } + } catch (e: InvalidProtocolBufferException) { + Log.e(TAG, e) + } + } + } + + if (smsIds.size > 0) { + Log.d(TAG, "Updating " + smsIds.size + " records in sms") + db.execSQL("UPDATE sms SET reactions_last_seen = notified_timestamp WHERE _id in (" + Util.join(smsIds, ",") + ")") + } + + val mmsIds: MutableList = ArrayList() + db.query("mms", arrayOf("_id", "reactions", "notified_timestamp"), "notified = 0 AND reactions_unread = 1", null, null, null, null).use { cursor -> + while (cursor.moveToNext()) { + val reactions: ByteArray? = cursor.getBlob(cursor.getColumnIndexOrThrow("reactions")) + val notifiedTimestamp: Long = cursor.getLong(cursor.getColumnIndexOrThrow("notified_timestamp")) + if (reactions == null) { + continue + } + try { + val hasReceiveLaterThanNotified: Boolean = ReactionList.parseFrom(reactions) + .getReactionsList() + .stream() + .anyMatch { r: ReactionList.Reaction -> r.getReceivedTime() > notifiedTimestamp } + if (!hasReceiveLaterThanNotified) { + mmsIds.add(cursor.getLong(cursor.getColumnIndexOrThrow("_id"))) + } + } catch (e: InvalidProtocolBufferException) { + Log.e(TAG, e) + } + } + } + if (mmsIds.size > 0) { + Log.d(TAG, "Updating " + mmsIds.size + " records in mms") + db.execSQL("UPDATE mms SET reactions_last_seen = notified_timestamp WHERE _id in (${Util.join(mmsIds, ",")})") + } + } + + if (oldVersion < STORAGE_SERVICE_REFACTOR) { + val deleteCount: Int + var insertCount: Int + var updateCount: Int + val dirtyCount: Int + val deleteValues = ContentValues() + + deleteValues.putNull("storage_service_key") + deleteCount = db.update("recipient", deleteValues, "storage_service_key NOT NULL AND (dirty = 3 OR group_type = 1 OR (group_type = 0 AND registered = 2))", null) + + db.query("recipient", arrayOf("_id"), "storage_service_key IS NULL AND (dirty = 2 OR registered = 1)", null, null, null, null).use { cursor -> + insertCount = cursor.getCount() + while (cursor.moveToNext()) { + val insertValues = ContentValues().apply { + put("storage_service_key", Base64.encodeBytes(StorageSyncHelper.generateKey())) + } + val id: Long = cursor.getLong(cursor.getColumnIndexOrThrow("_id")) + db.update("recipient", insertValues, "_id = ?", SqlUtil.buildArgs(id)) + } + } + + db.query("recipient", arrayOf("_id"), "storage_service_key NOT NULL AND dirty = 1", null, null, null, null).use { cursor -> + updateCount = cursor.getCount() + while (cursor.moveToNext()) { + val updateValues = ContentValues().apply { + put("storage_service_key", Base64.encodeBytes(StorageSyncHelper.generateKey())) + } + val id: Long = cursor.getLong(cursor.getColumnIndexOrThrow("_id")) + db.update("recipient", updateValues, "_id = ?", SqlUtil.buildArgs(id)) + } + } + + val clearDirtyValues = ContentValues().apply { + put("dirty", 0) + } + + dirtyCount = db.update("recipient", clearDirtyValues, "dirty != 0", null) + Log.d(TAG, String.format(Locale.US, "For storage service refactor migration, there were %d inserts, %d updated, and %d deletes. Cleared the dirty status on %d rows.", insertCount, updateCount, deleteCount, dirtyCount)) + } + + if (oldVersion < CLEAR_MMS_STORAGE_IDS) { + val deleteValues = ContentValues().apply { + putNull("storage_service_key") + } + val deleteCount = db.update("recipient", deleteValues, "storage_service_key NOT NULL AND (group_type = 1 OR (group_type = 0 AND phone IS NULL AND uuid IS NULL))", null) + Log.d(TAG, "Cleared storageIds from $deleteCount rows. They were either MMS groups or empty contacts.") + } + + if (oldVersion < SERVER_GUID) { + db.execSQL("ALTER TABLE sms ADD COLUMN server_guid TEXT DEFAULT NULL") + db.execSQL("ALTER TABLE mms ADD COLUMN server_guid TEXT DEFAULT NULL") + } + + if (oldVersion < CHAT_COLORS) { + db.execSQL("ALTER TABLE recipient ADD COLUMN chat_colors BLOB DEFAULT NULL") + db.execSQL("ALTER TABLE recipient ADD COLUMN custom_chat_colors_id INTEGER DEFAULT 0") + db.execSQL( + // language=sql + """ + CREATE TABLE chat_colors ( + _id INTEGER PRIMARY KEY AUTOINCREMENT, + chat_colors BLOB + ) + """ + ) + val entrySet: Set> = entrySet + val where = "color = ? AND group_id is NULL" + for (entry: Map.Entry in entrySet) { + val whereArgs = SqlUtil.buildArgs(entry.key.serialize()) + val values = ContentValues(2) + values.put("chat_colors", entry.value.serialize().toByteArray()) + values.put("custom_chat_colors_id", entry.value.id.longValue) + db.update("recipient", values, where, whereArgs) + } + } + + if (oldVersion < AVATAR_COLORS) { + db.query("recipient", arrayOf("_id"), "color IS NULL", null, null, null, null).use { cursor -> + while (cursor.moveToNext()) { + val id: Long = cursor.getInt(cursor.getColumnIndexOrThrow("_id")).toLong() + val values: ContentValues = ContentValues(1) + values.put("color", AvatarColor.random().serialize()) + db.update("recipient", values, "_id = ?", arrayOf(id.toString())) + } + } + } + + if (oldVersion < EMOJI_SEARCH) { + // language=text + db.execSQL("CREATE VIRTUAL TABLE emoji_search USING fts5(label, emoji UNINDEXED)") + } + + if (oldVersion < SENDER_KEY && !SqlUtil.tableExists(db, "sender_keys")) { + db.execSQL( + // language=sql + """ + CREATE TABLE sender_keys ( + _id INTEGER PRIMARY KEY AUTOINCREMENT, + recipient_id INTEGER NOT NULL, + device INTEGER NOT NULL, + distribution_id TEXT NOT NULL, + record BLOB NOT NULL, + created_at INTEGER NOT NULL, + UNIQUE(recipient_id, device, distribution_id) ON CONFLICT REPLACE + ) + """.trimIndent() + ) + db.execSQL( + // language=sql + """ + CREATE TABLE sender_key_shared ( + _id INTEGER PRIMARY KEY AUTOINCREMENT, + distribution_id TEXT NOT NULL, + address TEXT NOT NULL, + device INTEGER NOT NULL, + UNIQUE(distribution_id, address, device) ON CONFLICT REPLACE + ) + """.trimIndent() + ) + db.execSQL( + // language=sql + """ + CREATE TABLE pending_retry_receipts ( + _id INTEGER PRIMARY KEY AUTOINCREMENT, + author TEXT NOT NULL, + device INTEGER NOT NULL, + sent_timestamp INTEGER NOT NULL, + received_timestamp TEXT NOT NULL, + thread_id INTEGER NOT NULL, + UNIQUE(author, sent_timestamp) ON CONFLICT REPLACE + ); + """.trimIndent() + ) + db.execSQL("ALTER TABLE groups ADD COLUMN distribution_id TEXT DEFAULT NULL") + db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS group_distribution_id_index ON groups (distribution_id)") + db.query("groups", arrayOf("group_id"), "LENGTH(group_id) = 85", null, null, null, null).use { cursor -> + while (cursor.moveToNext()) { + val groupId: String = cursor.getString(cursor.getColumnIndexOrThrow("group_id")) + val values = ContentValues().apply { + put("distribution_id", DistributionId.create().toString()) + } + db.update("groups", values, "group_id = ?", arrayOf(groupId)) + } + } + } + + if (oldVersion < MESSAGE_DUPE_INDEX) { + db.execSQL("DROP INDEX sms_date_sent_index") + db.execSQL("CREATE INDEX sms_date_sent_index on sms(date_sent, address, thread_id)") + db.execSQL("DROP INDEX mms_date_sent_index") + db.execSQL("CREATE INDEX mms_date_sent_index on mms(date, address, thread_id)") + } + + if (oldVersion < MESSAGE_LOG) { + db.execSQL( + // language=sql + """ + CREATE TABLE message_send_log ( + _id INTEGER PRIMARY KEY, + date_sent INTEGER NOT NULL, + content BLOB NOT NULL, + related_message_id INTEGER DEFAULT -1, + is_related_message_mms INTEGER DEFAULT 0, + content_hint INTEGER NOT NULL, + group_id BLOB DEFAULT NULL + ) + """.trimIndent() + ) + db.execSQL("CREATE INDEX message_log_date_sent_index ON message_send_log (date_sent)") + db.execSQL("CREATE INDEX message_log_related_message_index ON message_send_log (related_message_id, is_related_message_mms)") + db.execSQL("CREATE TRIGGER msl_sms_delete AFTER DELETE ON sms BEGIN DELETE FROM message_send_log WHERE related_message_id = old._id AND is_related_message_mms = 0; END") + db.execSQL("CREATE TRIGGER msl_mms_delete AFTER DELETE ON mms BEGIN DELETE FROM message_send_log WHERE related_message_id = old._id AND is_related_message_mms = 1; END") + db.execSQL( + // language=sql + """ + CREATE TABLE message_send_log_recipients ( + _id INTEGER PRIMARY KEY, + message_send_log_id INTEGER NOT NULL REFERENCES message_send_log (_id) ON DELETE CASCADE, + recipient_id INTEGER NOT NULL, + device INTEGER NOT NULL + ) + """.trimIndent() + ) + db.execSQL("CREATE INDEX message_send_log_recipients_recipient_index ON message_send_log_recipients (recipient_id, device)") + } + + if (oldVersion < MESSAGE_LOG_2) { + db.execSQL("DROP TABLE message_send_log") + db.execSQL("DROP INDEX IF EXISTS message_log_date_sent_index") + db.execSQL("DROP INDEX IF EXISTS message_log_related_message_index") + db.execSQL("DROP TRIGGER msl_sms_delete") + db.execSQL("DROP TRIGGER msl_mms_delete") + db.execSQL("DROP TABLE message_send_log_recipients") + db.execSQL("DROP INDEX IF EXISTS message_send_log_recipients_recipient_index") + db.execSQL( + // language=sql + """ + CREATE TABLE msl_payload ( + _id INTEGER PRIMARY KEY, + date_sent INTEGER NOT NULL, + content BLOB NOT NULL, + content_hint INTEGER NOT NULL + ) + """.trimIndent() + ) + db.execSQL("CREATE INDEX msl_payload_date_sent_index ON msl_payload (date_sent)") + db.execSQL( + // language=sql + """ + CREATE TABLE msl_recipient ( + _id INTEGER PRIMARY KEY, + payload_id INTEGER NOT NULL REFERENCES msl_payload (_id) ON DELETE CASCADE, + recipient_id INTEGER NOT NULL, + device INTEGER NOT NULL + ) + """.trimIndent() + ) + db.execSQL("CREATE INDEX msl_recipient_recipient_index ON msl_recipient (recipient_id, device, payload_id)") + db.execSQL("CREATE INDEX msl_recipient_payload_index ON msl_recipient (payload_id)") + db.execSQL( + // language=sql + """ + CREATE TABLE msl_message ( + _id INTEGER PRIMARY KEY, + payload_id INTEGER NOT NULL REFERENCES msl_payload (_id) ON DELETE CASCADE, + message_id INTEGER NOT NULL, + is_mms INTEGER NOT NULL + ) + """ + ) + + db.execSQL("CREATE INDEX msl_message_message_index ON msl_message (message_id, is_mms, payload_id)") + db.execSQL("CREATE TRIGGER msl_sms_delete AFTER DELETE ON sms BEGIN DELETE FROM msl_payload WHERE _id IN (SELECT payload_id FROM msl_message WHERE message_id = old._id AND is_mms = 0); END") + db.execSQL("CREATE TRIGGER msl_mms_delete AFTER DELETE ON mms BEGIN DELETE FROM msl_payload WHERE _id IN (SELECT payload_id FROM msl_message WHERE message_id = old._id AND is_mms = 1); END") + db.execSQL("CREATE TRIGGER msl_attachment_delete AFTER DELETE ON part BEGIN DELETE FROM msl_payload WHERE _id IN (SELECT payload_id FROM msl_message WHERE message_id = old.mid AND is_mms = 1); END") + } + + if (oldVersion < ABANDONED_MESSAGE_CLEANUP) { + val start = System.currentTimeMillis() + val smsDeleteCount = db.delete("sms", "thread_id NOT IN (SELECT _id FROM thread)", null) + val mmsDeleteCount = db.delete("mms", "thread_id NOT IN (SELECT _id FROM thread)", null) + Log.i(TAG, "Deleted " + smsDeleteCount + " sms and " + mmsDeleteCount + " mms in " + (System.currentTimeMillis() - start) + " ms") + } + + if (oldVersion < THREAD_AUTOINCREMENT) { + val stopwatch = Stopwatch("thread-autoincrement") + db.execSQL( + // language=sql + """ + CREATE TABLE thread_tmp ( + _id INTEGER PRIMARY KEY AUTOINCREMENT, + date INTEGER DEFAULT 0, + thread_recipient_id INTEGER, + message_count INTEGER DEFAULT 0, + snippet TEXT, + snippet_charset INTEGER DEFAULT 0, + snippet_type INTEGER DEFAULT 0, + snippet_uri TEXT DEFAULT NULL, + snippet_content_type INTEGER DEFAULT NULL, + snippet_extras TEXT DEFAULT NULL, + read INTEGER DEFAULT 1, + type INTEGER DEFAULT 0, + error INTEGER DEFAULT 0, + archived INTEGER DEFAULT 0, + status INTEGER DEFAULT 0, + expires_in INTEGER DEFAULT 0, + last_seen INTEGER DEFAULT 0, + has_sent INTEGER DEFAULT 0, + delivery_receipt_count INTEGER DEFAULT 0, + read_receipt_count INTEGER DEFAULT 0, + unread_count INTEGER DEFAULT 0, + last_scrolled INTEGER DEFAULT 0, + pinned INTEGER DEFAULT 0 + ) + """.trimIndent() + ) + stopwatch.split("table-create") + + db.execSQL( + // language=sql + """ + INSERT INTO thread_tmp + SELECT + _id, + date, + recipient_ids, + message_count, + snippet, + snippet_cs, + snippet_type, + snippet_uri, + snippet_content_type, + snippet_extras, + read, + type, + error, + archived, + status, + expires_in, + last_seen, + has_sent, + delivery_receipt_count, + read_receipt_count, + unread_count, + last_scrolled, + pinned + FROM thread + """.trimIndent() + ) + stopwatch.split("table-copy") + + db.execSQL("DROP TABLE thread") + db.execSQL("ALTER TABLE thread_tmp RENAME TO thread") + stopwatch.split("table-rename") + + db.execSQL("CREATE INDEX thread_recipient_id_index ON thread (thread_recipient_id)") + db.execSQL("CREATE INDEX archived_count_index ON thread (archived, message_count)") + db.execSQL("CREATE INDEX thread_pinned_index ON thread (pinned)") + stopwatch.split("indexes") + + db.execSQL("DELETE FROM remapped_threads") + stopwatch.split("delete-remap") + + stopwatch.stop(TAG) + } + + if (oldVersion < MMS_AUTOINCREMENT) { + val mmsStopwatch = Stopwatch("mms-autoincrement") + db.execSQL( + // language=sql + """ + CREATE TABLE mms_tmp ( + _id INTEGER PRIMARY KEY AUTOINCREMENT, + thread_id INTEGER, + date INTEGER, + date_received INTEGER, + date_server INTEGER DEFAULT -1, + msg_box INTEGER, + read INTEGER DEFAULT 0, + body TEXT, + part_count INTEGER, + ct_l TEXT, + address INTEGER, + address_device_id INTEGER, + exp INTEGER, + m_type INTEGER, + m_size INTEGER, + st INTEGER, + tr_id TEXT, + delivery_receipt_count INTEGER DEFAULT 0, + mismatched_identities TEXT DEFAULT NULL, + network_failures TEXT DEFAULT NULL, + subscription_id INTEGER DEFAULT -1, + expires_in INTEGER DEFAULT 0, + expire_started INTEGER DEFAULT 0, + notified INTEGER DEFAULT 0, + read_receipt_count INTEGER DEFAULT 0, + quote_id INTEGER DEFAULT 0, + quote_author TEXT, + quote_body TEXT, + quote_attachment INTEGER DEFAULT -1, + quote_missing INTEGER DEFAULT 0, + quote_mentions BLOB DEFAULT NULL, + shared_contacts TEXT, + unidentified INTEGER DEFAULT 0, + previews TEXT, + reveal_duration INTEGER DEFAULT 0, + reactions BLOB DEFAULT NULL, + reactions_unread INTEGER DEFAULT 0, + reactions_last_seen INTEGER DEFAULT -1, + remote_deleted INTEGER DEFAULT 0, + mentions_self INTEGER DEFAULT 0, + notified_timestamp INTEGER DEFAULT 0, + viewed_receipt_count INTEGER DEFAULT 0, + server_guid TEXT DEFAULT NULL + ); + """.trimIndent() + ) + mmsStopwatch.split("table-create") + + db.execSQL( + // language=sql + """ + INSERT INTO mms_tmp + SELECT + _id, + thread_id, + date, + date_received, + date_server, + msg_box, + read, + body, + part_count, + ct_l, + address, + address_device_id, + exp, + m_type, + m_size, + st, + tr_id, + delivery_receipt_count, + mismatched_identities, + network_failures, + subscription_id, + expires_in, + expire_started, + notified, + read_receipt_count, + quote_id, + quote_author, + quote_body, + quote_attachment, + quote_missing, + quote_mentions, + shared_contacts, + unidentified, + previews, + reveal_duration, + reactions, + reactions_unread, + reactions_last_seen, + remote_deleted, + mentions_self, + notified_timestamp, + viewed_receipt_count, + server_guid + FROM mms + """.trimIndent() + ) + mmsStopwatch.split("table-copy") + + db.execSQL("DROP TABLE mms") + db.execSQL("ALTER TABLE mms_tmp RENAME TO mms") + mmsStopwatch.split("table-rename") + + db.execSQL("CREATE INDEX mms_read_and_notified_and_thread_id_index ON mms(read, notified, thread_id)") + db.execSQL("CREATE INDEX mms_message_box_index ON mms (msg_box)") + db.execSQL("CREATE INDEX mms_date_sent_index ON mms (date, address, thread_id)") + db.execSQL("CREATE INDEX mms_date_server_index ON mms (date_server)") + db.execSQL("CREATE INDEX mms_thread_date_index ON mms (thread_id, date_received)") + db.execSQL("CREATE INDEX mms_reactions_unread_index ON mms (reactions_unread)") + mmsStopwatch.split("indexes") + + db.execSQL("CREATE TRIGGER mms_ai AFTER INSERT ON mms BEGIN INSERT INTO mms_fts(rowid, body, thread_id) VALUES (new._id, new.body, new.thread_id); END") + db.execSQL("CREATE TRIGGER mms_ad AFTER DELETE ON mms BEGIN INSERT INTO mms_fts(mms_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id); END") + // language=text + db.execSQL("CREATE TRIGGER mms_au AFTER UPDATE ON mms BEGIN INSERT INTO mms_fts(mms_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id); INSERT INTO mms_fts(rowid, body, thread_id) VALUES (new._id, new.body, new.thread_id); END") + db.execSQL("CREATE TRIGGER msl_mms_delete AFTER DELETE ON mms BEGIN DELETE FROM msl_payload WHERE _id IN (SELECT payload_id FROM msl_message WHERE message_id = old._id AND is_mms = 1); END") + mmsStopwatch.split("triggers") + + mmsStopwatch.stop(TAG) + + val smsStopwatch = Stopwatch("sms-autoincrement") + db.execSQL( + // language=sql + """ + CREATE TABLE sms_tmp ( + _id INTEGER PRIMARY KEY AUTOINCREMENT, + thread_id INTEGER, + address INTEGER, + address_device_id INTEGER DEFAULT 1, + person INTEGER, + date INTEGER, + date_sent INTEGER, + date_server INTEGER DEFAULT -1, + protocol INTEGER, + read INTEGER DEFAULT 0, + status INTEGER DEFAULT -1, + type INTEGER, + reply_path_present INTEGER, + delivery_receipt_count INTEGER DEFAULT 0, + subject TEXT, + body TEXT, + mismatched_identities TEXT DEFAULT NULL, + service_center TEXT, + subscription_id INTEGER DEFAULT -1, + expires_in INTEGER DEFAULT 0, + expire_started INTEGER DEFAULT 0, + notified DEFAULT 0, + read_receipt_count INTEGER DEFAULT 0, + unidentified INTEGER DEFAULT 0, + reactions BLOB DEFAULT NULL, + reactions_unread INTEGER DEFAULT 0, + reactions_last_seen INTEGER DEFAULT -1, + remote_deleted INTEGER DEFAULT 0, + notified_timestamp INTEGER DEFAULT 0, + server_guid TEXT DEFAULT NULL + ) + """.trimIndent() + ) + smsStopwatch.split("table-create") + db.execSQL( + // language=sql + """ + INSERT INTO sms_tmp + SELECT + _id, + thread_id, + address, + address_device_id, + person, + date, + date_sent, + date_server , + protocol, + read, + status , + type, + reply_path_present, + delivery_receipt_count, + subject, + body, + mismatched_identities, + service_center, + subscription_id , + expires_in, + expire_started, + notified, + read_receipt_count, + unidentified, + reactions BLOB, + reactions_unread, + reactions_last_seen , + remote_deleted, + notified_timestamp, + server_guid + FROM sms + """.trimIndent() + ) + smsStopwatch.split("table-copy") + + db.execSQL("DROP TABLE sms") + db.execSQL("ALTER TABLE sms_tmp RENAME TO sms") + smsStopwatch.split("table-rename") + + db.execSQL("CREATE INDEX sms_read_and_notified_and_thread_id_index ON sms(read, notified, thread_id)") + db.execSQL("CREATE INDEX sms_type_index ON sms (type)") + db.execSQL("CREATE INDEX sms_date_sent_index ON sms (date_sent, address, thread_id)") + db.execSQL("CREATE INDEX sms_date_server_index ON sms (date_server)") + db.execSQL("CREATE INDEX sms_thread_date_index ON sms (thread_id, date)") + db.execSQL("CREATE INDEX sms_reactions_unread_index ON sms (reactions_unread)") + smsStopwatch.split("indexes") + + db.execSQL("CREATE TRIGGER sms_ai AFTER INSERT ON sms BEGIN INSERT INTO sms_fts(rowid, body, thread_id) VALUES (new._id, new.body, new.thread_id); END;") + db.execSQL("CREATE TRIGGER sms_ad AFTER DELETE ON sms BEGIN INSERT INTO sms_fts(sms_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id); END;") + // language=text + db.execSQL("CREATE TRIGGER sms_au AFTER UPDATE ON sms BEGIN INSERT INTO sms_fts(sms_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id); INSERT INTO sms_fts(rowid, body, thread_id) VALUES(new._id, new.body, new.thread_id); END;") + db.execSQL("CREATE TRIGGER msl_sms_delete AFTER DELETE ON sms BEGIN DELETE FROM msl_payload WHERE _id IN (SELECT payload_id FROM msl_message WHERE message_id = old._id AND is_mms = 0); END") + smsStopwatch.split("triggers") + + smsStopwatch.stop(TAG) + } + + if (oldVersion < ABANDONED_ATTACHMENT_CLEANUP) { + db.delete("part", "mid != -8675309 AND mid NOT IN (SELECT _id FROM mms)", null) + } + + if (oldVersion < AVATAR_PICKER) { + db.execSQL( + // language=sql + """ + CREATE TABLE avatar_picker ( + _id INTEGER PRIMARY KEY AUTOINCREMENT, + last_used INTEGER DEFAULT 0, + group_id TEXT DEFAULT NULL, + avatar BLOB NOT NULL + ) + """.trimIndent() + ) + db.query("recipient", arrayOf("_id"), "color IS NULL", null, null, null, null).use { cursor -> + while (cursor.moveToNext()) { + val id: Long = cursor.getInt(cursor.getColumnIndexOrThrow("_id")).toLong() + val values = ContentValues(1).apply { + put("color", AvatarColor.random().serialize()) + } + db.update("recipient", values, "_id = ?", arrayOf(id.toString())) + } + } + } + + if (oldVersion < THREAD_CLEANUP) { + db.delete("mms", "thread_id NOT IN (SELECT _id FROM thread)", null) + db.delete("part", "mid != -8675309 AND mid NOT IN (SELECT _id FROM mms)", null) + } + + if (oldVersion < SESSION_MIGRATION) { + val start = System.currentTimeMillis() + db.execSQL( + // language=sql + """ + CREATE TABLE sessions_tmp ( + _id INTEGER PRIMARY KEY AUTOINCREMENT, + address TEXT NOT NULL, + device INTEGER NOT NULL, + record BLOB NOT NULL, + UNIQUE(address, device)) + """.trimIndent() + ) + db.execSQL( + // language=sql + """ + INSERT INTO sessions_tmp (address, device, record) + SELECT + COALESCE(recipient.uuid, recipient.phone) AS new_address, + sessions.device, + sessions.record + FROM sessions INNER JOIN recipient ON sessions.address = recipient._id + WHERE new_address NOT NULL + """.trimIndent() + ) + db.execSQL("DROP TABLE sessions") + db.execSQL("ALTER TABLE sessions_tmp RENAME TO sessions") + Log.d(TAG, "Session migration took " + (System.currentTimeMillis() - start) + " ms") + } + + if (oldVersion < IDENTITY_MIGRATION) { + val start = System.currentTimeMillis() + db.execSQL( + // language=sql + """ + CREATE TABLE identities_tmp ( + _id INTEGER PRIMARY KEY AUTOINCREMENT, + address TEXT UNIQUE NOT NULL, + identity_key TEXT, + first_use INTEGER DEFAULT 0, + timestamp INTEGER DEFAULT 0, + verified INTEGER DEFAULT 0, + nonblocking_approval INTEGER DEFAULT 0) + """.trimIndent() + ) + db.execSQL( + // language=sql + """ + INSERT INTO identities_tmp (address, identity_key, first_use, timestamp, verified, nonblocking_approval) + SELECT + COALESCE(recipient.uuid, recipient.phone) AS new_address, + identities.key, + identities.first_use, + identities.timestamp, + identities.verified, + identities.nonblocking_approval + FROM identities INNER JOIN recipient ON identities.address = recipient._id + WHERE new_address NOT NULL + """.trimIndent() + ) + db.execSQL("DROP TABLE identities") + db.execSQL("ALTER TABLE identities_tmp RENAME TO identities") + Log.d(TAG, "Identity migration took " + (System.currentTimeMillis() - start) + " ms") + } + + if (oldVersion < GROUP_CALL_RING_TABLE) { + db.execSQL("CREATE TABLE group_call_ring (_id INTEGER PRIMARY KEY, ring_id INTEGER UNIQUE, date_received INTEGER, ring_state INTEGER)") + db.execSQL("CREATE INDEX date_received_index on group_call_ring (date_received)") + } + + if (oldVersion < CLEANUP_SESSION_MIGRATION) { + val sessionCount = db.delete("sessions", "address LIKE '+%'", null) + Log.i(TAG, "Cleaned up $sessionCount sessions.") + val storageValues = ContentValues() + storageValues.putNull("storage_service_key") + val storageCount = db.update("recipient", storageValues, "storage_service_key NOT NULL AND group_id IS NULL AND uuid IS NULL", null) + Log.i(TAG, "Cleaned up $storageCount storageIds.") + } + + if (oldVersion < RECEIPT_TIMESTAMP) { + db.execSQL("ALTER TABLE sms ADD COLUMN receipt_timestamp INTEGER DEFAULT -1") + db.execSQL("ALTER TABLE mms ADD COLUMN receipt_timestamp INTEGER DEFAULT -1") + } + + if (oldVersion < BADGES) { + db.execSQL("ALTER TABLE recipient ADD COLUMN badges BLOB DEFAULT NULL") + } + + if (oldVersion < SENDER_KEY_UUID) { + val start = System.currentTimeMillis() + db.execSQL( + // language=sql + """ + CREATE TABLE sender_keys_tmp ( + _id INTEGER PRIMARY KEY AUTOINCREMENT, + address TEXT NOT NULL, + device INTEGER NOT NULL, + distribution_id TEXT NOT NULL, + record BLOB NOT NULL, + created_at INTEGER NOT NULL, + UNIQUE(address, device, distribution_id) ON CONFLICT REPLACE + ) + """.trimIndent() + ) + + db.execSQL( + // language=sql + """ + INSERT INTO sender_keys_tmp (address, device, distribution_id, record, created_at) + SELECT + recipient.uuid AS new_address, + sender_keys.device, + sender_keys.distribution_id, + sender_keys.record, + sender_keys.created_at + FROM sender_keys INNER JOIN recipient ON sender_keys.recipient_id = recipient._id + WHERE new_address NOT NULL + """.trimIndent() + ) + + db.execSQL("DROP TABLE sender_keys") + db.execSQL("ALTER TABLE sender_keys_tmp RENAME TO sender_keys") + + Log.d(TAG, "Sender key migration took " + (System.currentTimeMillis() - start) + " ms") + } + + if (oldVersion < SENDER_KEY_SHARED_TIMESTAMP) { + db.execSQL("ALTER TABLE sender_key_shared ADD COLUMN timestamp INTEGER DEFAULT 0") + } + + if (oldVersion < REACTION_REFACTOR) { + db.execSQL( + // language=sql + """ + CREATE TABLE reaction ( + _id INTEGER PRIMARY KEY, + message_id INTEGER NOT NULL, + is_mms INTEGER NOT NULL, + author_id INTEGER NOT NULL REFERENCES recipient (_id) ON DELETE CASCADE, + emoji TEXT NOT NULL, + date_sent INTEGER NOT NULL, + date_received INTEGER NOT NULL, + UNIQUE(message_id, is_mms, author_id) ON CONFLICT REPLACE + ) + """.trimIndent() + ) + + db.rawQuery("SELECT _id, reactions FROM sms WHERE reactions NOT NULL", null).use { cursor -> + while (cursor.moveToNext()) { + migrateReaction(db, cursor, false) + } + } + + db.rawQuery("SELECT _id, reactions FROM mms WHERE reactions NOT NULL", null).use { cursor -> + while (cursor.moveToNext()) { + migrateReaction(db, cursor, true) + } + } + + db.execSQL("UPDATE reaction SET author_id = IFNULL((SELECT new_id FROM remapped_recipients WHERE author_id = old_id), author_id)") + db.execSQL("CREATE TRIGGER reactions_sms_delete AFTER DELETE ON sms BEGIN DELETE FROM reaction WHERE message_id = old._id AND is_mms = 0; END") + db.execSQL("CREATE TRIGGER reactions_mms_delete AFTER DELETE ON mms BEGIN DELETE FROM reaction WHERE message_id = old._id AND is_mms = 0; END") + db.execSQL("UPDATE sms SET reactions = NULL WHERE reactions NOT NULL") + db.execSQL("UPDATE mms SET reactions = NULL WHERE reactions NOT NULL") + } + } + + @JvmStatic + fun migratePostTransaction(context: Context, oldVersion: Int) { + if (oldVersion < MIGRATE_PREKEYS_VERSION) { + PreKeyMigrationHelper.cleanUpPreKeys(context) + } + } + + private fun migrateReaction(db: SQLiteDatabase, cursor: Cursor, isMms: Boolean) { + try { + val messageId = CursorUtil.requireLong(cursor, "_id") + val reactionList = ReactionList.parseFrom(CursorUtil.requireBlob(cursor, "reactions")) + + for (reaction in reactionList.reactionsList) { + val contentValues = ContentValues().apply { + put("message_id", messageId) + put("is_mms", if (isMms) 1 else 0) + put("author_id", reaction.author) + put("emoji", reaction.emoji) + put("date_sent", reaction.sentTime) + put("date_received", reaction.receivedTime) + } + db.insert("reaction", null, contentValues) + } + } catch (e: InvalidProtocolBufferException) { + Log.w(TAG, "Failed to parse reaction!") + } + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/loaders/GroupedThreadMediaLoader.java b/app/src/main/java/org/thoughtcrime/securesms/database/loaders/GroupedThreadMediaLoader.java index e8ef3a9d21..25617240a7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/loaders/GroupedThreadMediaLoader.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/loaders/GroupedThreadMediaLoader.java @@ -11,7 +11,6 @@ import androidx.loader.content.AsyncTaskLoader; import org.signal.core.util.ThreadUtil; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.DatabaseObserver; import org.thoughtcrime.securesms.database.MediaDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/loaders/PagingMediaLoader.java b/app/src/main/java/org/thoughtcrime/securesms/database/loaders/PagingMediaLoader.java index fba59c637a..e937ad6128 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/loaders/PagingMediaLoader.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/loaders/PagingMediaLoader.java @@ -12,10 +12,10 @@ import org.signal.core.util.ThreadUtil; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.attachments.AttachmentId; import org.thoughtcrime.securesms.database.AttachmentDatabase; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.DatabaseObserver; import org.thoughtcrime.securesms.database.MediaDatabase; import org.thoughtcrime.securesms.database.MediaDatabase.Sorting; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.mms.PartAuthority; import org.thoughtcrime.securesms.util.AsyncLoader; @@ -46,7 +46,7 @@ public final class PagingMediaLoader extends AsyncLoader> public @Nullable Pair loadInBackground() { ApplicationDependencies.getDatabaseObserver().registerConversationObserver(threadId, observer); - Cursor cursor = DatabaseFactory.getMediaDatabase(getContext()).getGalleryMediaForThread(threadId, sorting, threadId == MediaDatabase.ALL_THREADS); + Cursor cursor = SignalDatabase.media().getGalleryMediaForThread(threadId, sorting, threadId == MediaDatabase.ALL_THREADS); while (cursor.moveToNext()) { AttachmentId attachmentId = new AttachmentId(cursor.getLong(cursor.getColumnIndexOrThrow(AttachmentDatabase.ROW_ID)), cursor.getLong(cursor.getColumnIndexOrThrow(AttachmentDatabase.UNIQUE_ID))); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/loaders/RecipientMediaLoader.java b/app/src/main/java/org/thoughtcrime/securesms/database/loaders/RecipientMediaLoader.java index b991d2110e..44e761ba86 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/loaders/RecipientMediaLoader.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/loaders/RecipientMediaLoader.java @@ -6,8 +6,8 @@ import android.database.Cursor; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MediaDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; @@ -35,8 +35,7 @@ public final class RecipientMediaLoader extends MediaLoader { public Cursor getCursor() { if (recipientId == null || recipientId.isUnknown()) return null; - long threadId = DatabaseFactory.getThreadDatabase(getContext()) - .getOrCreateThreadIdFor(Recipient.resolved(recipientId)); + long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(Recipient.resolved(recipientId)); return ThreadMediaLoader.createThreadMediaCursor(context, threadId, mediaType, sorting); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/loaders/ThreadMediaLoader.java b/app/src/main/java/org/thoughtcrime/securesms/database/loaders/ThreadMediaLoader.java index 3703896cab..fbf9a26246 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/loaders/ThreadMediaLoader.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/loaders/ThreadMediaLoader.java @@ -5,8 +5,8 @@ import android.database.Cursor; import androidx.annotation.NonNull; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MediaDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; public final class ThreadMediaLoader extends MediaLoader { @@ -34,7 +34,7 @@ public final class ThreadMediaLoader extends MediaLoader { long threadId, @NonNull MediaType mediaType, @NonNull MediaDatabase.Sorting sorting) { - MediaDatabase mediaDatabase = DatabaseFactory.getMediaDatabase(context); + MediaDatabase mediaDatabase = SignalDatabase.media(); switch (mediaType) { case GALLERY : return mediaDatabase.getGalleryMediaForThread(threadId, sorting); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/AvatarPickerDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/model/AvatarPickerDatabase.kt index 5c56ce6b87..7d76d7d36f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/AvatarPickerDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/AvatarPickerDatabase.kt @@ -6,7 +6,7 @@ import android.net.Uri import org.thoughtcrime.securesms.avatar.Avatar import org.thoughtcrime.securesms.avatar.Avatars import org.thoughtcrime.securesms.database.Database -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.database.model.databaseprotos.CustomAvatar import org.thoughtcrime.securesms.groups.GroupId import org.thoughtcrime.securesms.util.CursorUtil @@ -15,7 +15,7 @@ import org.thoughtcrime.securesms.util.SqlUtil /** * Database which manages the record keeping for custom created avatars. */ -class AvatarPickerDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Database(context, databaseHelper) { +class AvatarPickerDatabase(context: Context, databaseHelper: SignalDatabase) : Database(context, databaseHelper) { companion object { const val TABLE_NAME = "avatar_picker" 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 4220cc87da..fbae06b74e 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 @@ -16,7 +16,7 @@ import org.thoughtcrime.securesms.backup.BackupPassphrase; import org.thoughtcrime.securesms.backup.FullBackupBase; import org.thoughtcrime.securesms.backup.FullBackupImporter; import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.notifications.NotificationChannels; import java.io.IOException; @@ -38,7 +38,7 @@ final class NewDeviceServerTask implements ServerTask { EventBus.getDefault().register(this); try { - SQLiteDatabase database = DatabaseFactory.getBackupDatabase(context); + SQLiteDatabase database = SignalDatabase.getBackupDatabase(); String passphrase = "deadbeef"; @@ -49,7 +49,7 @@ final class NewDeviceServerTask implements ServerTask { inputStream, passphrase); - DatabaseFactory.upgradeRestored(context, database); + SignalDatabase.upgradeRestored(database); NotificationChannels.restoreContactNotificationChannels(context); AppInitialization.onPostBackupRestore(context); diff --git a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/olddevice/OldDeviceClientTask.java b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/olddevice/OldDeviceClientTask.java index 042f9c873a..4e65f88714 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/olddevice/OldDeviceClientTask.java +++ b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/olddevice/OldDeviceClientTask.java @@ -12,7 +12,7 @@ import org.signal.devicetransfer.ClientTask; import org.thoughtcrime.securesms.backup.FullBackupBase; import org.thoughtcrime.securesms.backup.FullBackupExporter; import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.net.DeviceTransferBlockingInterceptor; @@ -41,7 +41,7 @@ final class OldDeviceClientTask implements ClientTask { try { FullBackupExporter.transfer(context, AttachmentSecretProvider.getInstance(context).getOrCreateAttachmentSecret(), - DatabaseFactory.getBackupDatabase(context), + SignalDatabase.getBackupDatabase(), outputStream, "deadbeef"); } catch (Exception e) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/gcm/FcmReceiveService.java b/app/src/main/java/org/thoughtcrime/securesms/gcm/FcmReceiveService.java index 26aaf86a52..decede38c7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/gcm/FcmReceiveService.java +++ b/app/src/main/java/org/thoughtcrime/securesms/gcm/FcmReceiveService.java @@ -14,7 +14,6 @@ import org.thoughtcrime.securesms.jobs.FcmRefreshJob; import org.thoughtcrime.securesms.jobs.SubmitRateLimitPushChallengeJob; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.registration.PushChallengeRequest; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import java.util.Locale; diff --git a/app/src/main/java/org/thoughtcrime/securesms/giph/mp4/GiphyMp4PlaybackController.java b/app/src/main/java/org/thoughtcrime/securesms/giph/mp4/GiphyMp4PlaybackController.java index 5eec67ada6..1471e18d8d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/giph/mp4/GiphyMp4PlaybackController.java +++ b/app/src/main/java/org/thoughtcrime/securesms/giph/mp4/GiphyMp4PlaybackController.java @@ -1,6 +1,5 @@ package org.thoughtcrime.securesms.giph.mp4; -import android.graphics.Canvas; import android.view.View; import androidx.annotation.NonNull; diff --git a/app/src/main/java/org/thoughtcrime/securesms/giph/mp4/GiphyMp4PlaybackPolicy.java b/app/src/main/java/org/thoughtcrime/securesms/giph/mp4/GiphyMp4PlaybackPolicy.java index a6d71f61ac..e2a5baf896 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/giph/mp4/GiphyMp4PlaybackPolicy.java +++ b/app/src/main/java/org/thoughtcrime/securesms/giph/mp4/GiphyMp4PlaybackPolicy.java @@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.giph.mp4; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.util.DeviceProperties; -import org.thoughtcrime.securesms.util.FeatureFlags; import java.util.concurrent.TimeUnit; diff --git a/app/src/main/java/org/thoughtcrime/securesms/giph/mp4/GiphyMp4ProjectionRecycler.java b/app/src/main/java/org/thoughtcrime/securesms/giph/mp4/GiphyMp4ProjectionRecycler.java index d2bd39f66e..6547ca2a58 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/giph/mp4/GiphyMp4ProjectionRecycler.java +++ b/app/src/main/java/org/thoughtcrime/securesms/giph/mp4/GiphyMp4ProjectionRecycler.java @@ -1,7 +1,6 @@ package org.thoughtcrime.securesms.giph.mp4; import android.util.SparseArray; -import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; diff --git a/app/src/main/java/org/thoughtcrime/securesms/giph/mp4/GiphyMp4VideoPlayer.java b/app/src/main/java/org/thoughtcrime/securesms/giph/mp4/GiphyMp4VideoPlayer.java index 38b49a655b..58e3a5002e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/giph/mp4/GiphyMp4VideoPlayer.java +++ b/app/src/main/java/org/thoughtcrime/securesms/giph/mp4/GiphyMp4VideoPlayer.java @@ -8,10 +8,8 @@ import android.widget.FrameLayout; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.lifecycle.DefaultLifecycleObserver; -import androidx.lifecycle.LifecycleOwner; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.MediaItem; import com.google.android.exoplayer2.SimpleExoPlayer; import com.google.android.exoplayer2.ui.AspectRatioFrameLayout; @@ -20,9 +18,7 @@ import com.google.android.exoplayer2.ui.PlayerView; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.components.CornerMask; -import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.util.Projection; -import org.thoughtcrime.securesms.video.exo.ExoPlayerKt; /** * Video Player class specifically created for the GiphyMp4Fragment. diff --git a/app/src/main/java/org/thoughtcrime/securesms/giph/ui/GiphyActivityToolbar.java b/app/src/main/java/org/thoughtcrime/securesms/giph/ui/GiphyActivityToolbar.java index 744937284c..0aa4bf5216 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/giph/ui/GiphyActivityToolbar.java +++ b/app/src/main/java/org/thoughtcrime/securesms/giph/ui/GiphyActivityToolbar.java @@ -17,12 +17,10 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.widget.Toolbar; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.components.AnimatingToggle; public class GiphyActivityToolbar extends Toolbar { diff --git a/app/src/main/java/org/thoughtcrime/securesms/glide/cache/LimitedReader.kt b/app/src/main/java/org/thoughtcrime/securesms/glide/cache/LimitedReader.kt index 51abb3d79a..372c26889e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/glide/cache/LimitedReader.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/glide/cache/LimitedReader.kt @@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.glide.cache import org.signal.glide.common.io.Reader import java.io.IOException -import kotlin.jvm.Throws /** * Restrict the number of bytes that can be read to prevent breaking the input stream in Glide's diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManager.java b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManager.java index 8649183341..89b6d98d7b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManager.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManager.java @@ -13,8 +13,8 @@ import org.signal.storageservice.protos.groups.local.DecryptedGroupJoinInfo; import org.signal.zkgroup.VerificationFailedException; import org.signal.zkgroup.groups.GroupMasterKey; import org.signal.zkgroup.groups.UuidCiphertext; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.groups.v2.GroupInviteLinkUrl; import org.thoughtcrime.securesms.groups.v2.GroupLinkPassword; import org.thoughtcrime.securesms.keyvalue.SignalStore; @@ -81,8 +81,8 @@ public final class GroupManager { avatarChanged); } } else if (groupId.isV1()) { - List members = DatabaseFactory.getGroupDatabase(context) - .getGroupMembers(groupId, GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF); + List members = SignalDatabase.groups() + .getGroupMembers(groupId, GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF); Set recipientIds = getMemberIds(new HashSet<>(members)); @@ -229,7 +229,7 @@ public final class GroupManager { public static void updateSelfProfileKeyInGroup(@NonNull Context context, @NonNull GroupId.V2 groupId) throws IOException, GroupChangeBusyException, GroupInsufficientRightsException, GroupNotAMemberException, GroupChangeFailedException { - if (!DatabaseFactory.getGroupDatabase(context).groupExists(groupId)) { + if (!SignalDatabase.groups().groupExists(groupId)) { Log.i(TAG, "Group is not available locally " + groupId); return; } @@ -245,8 +245,7 @@ public final class GroupManager { { try (GroupManagerV2.GroupEditor editor = new GroupManagerV2(context).edit(groupId.requireV2())) { editor.acceptInvite(); - DatabaseFactory.getGroupDatabase(context) - .setActive(groupId, true); + SignalDatabase.groups().setActive(groupId, true); } } @@ -361,7 +360,7 @@ public final class GroupManager { return editor.addMembers(newMembers); } } else { - GroupDatabase.GroupRecord groupRecord = DatabaseFactory.getGroupDatabase(context).requireGroup(groupId); + GroupDatabase.GroupRecord groupRecord = SignalDatabase.groups().requireGroup(groupId); List members = groupRecord.getMembers(); byte[] avatar = groupRecord.hasAvatar() ? AvatarHelper.getAvatarBytes(context, groupRecord.getRecipientId()) : null; Set recipientIds = new HashSet<>(members); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManagerV1.java b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManagerV1.java index 10d013ea4e..8b536fd816 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManagerV1.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManagerV1.java @@ -13,9 +13,9 @@ import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.attachments.UriAttachment; import org.thoughtcrime.securesms.database.AttachmentDatabase; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.groups.GroupManager.GroupActionResult; import org.thoughtcrime.securesms.mms.OutgoingExpirationUpdateMessage; @@ -49,10 +49,10 @@ final class GroupManagerV1 { @Nullable String name, boolean mms) { - final GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); + final GroupDatabase groupDatabase = SignalDatabase.groups(); final SecureRandom secureRandom = new SecureRandom(); final GroupId groupId = mms ? GroupId.createMms(secureRandom) : GroupId.createV1(secureRandom); - final RecipientId groupRecipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupId); + final RecipientId groupRecipientId = SignalDatabase.recipients().getOrInsertFromGroupId(groupId); final Recipient groupRecipient = Recipient.resolved(groupRecipientId); memberIds.add(Recipient.self().getId()); @@ -68,7 +68,7 @@ final class GroupManagerV1 { Log.w(TAG, "Failed to save avatar!", e); } groupDatabase.onAvatarUpdated(groupIdV1, avatarBytes != null); - DatabaseFactory.getRecipientDatabase(context).setProfileSharing(groupRecipient.getId(), true); + SignalDatabase.recipients().setProfileSharing(groupRecipient.getId(), true); return sendGroupUpdate(context, groupIdV1, memberIds, name, avatarBytes, memberIds.size() - 1); } else { groupDatabase.create(groupId.requireMms(), name, memberIds); @@ -80,7 +80,7 @@ final class GroupManagerV1 { } groupDatabase.onAvatarUpdated(groupId, avatarBytes != null); - long threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(groupRecipient, ThreadDatabase.DistributionTypes.CONVERSATION); + long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(groupRecipient, ThreadDatabase.DistributionTypes.CONVERSATION); return new GroupActionResult(groupRecipient, threadId, memberIds.size() - 1, Collections.emptyList()); } } @@ -92,8 +92,8 @@ final class GroupManagerV1 { @Nullable String name, int newMemberCount) { - final GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); - final RecipientId groupRecipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupId); + final GroupDatabase groupDatabase = SignalDatabase.groups(); + final RecipientId groupRecipientId = SignalDatabase.recipients().getOrInsertFromGroupId(groupId); memberAddresses.add(Recipient.self().getId()); groupDatabase.updateMembers(groupId, new LinkedList<>(memberAddresses)); @@ -112,7 +112,7 @@ final class GroupManagerV1 { return sendGroupUpdate(context, groupIdV1, memberAddresses, name, avatarBytes, newMemberCount); } else { Recipient groupRecipient = Recipient.resolved(groupRecipientId); - long threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(groupRecipient); + long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(groupRecipient); return new GroupActionResult(groupRecipient, threadId, newMemberCount, Collections.emptyList()); } } @@ -122,10 +122,10 @@ final class GroupManagerV1 { @Nullable byte[] avatarBytes, @Nullable String name) { - GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); - RecipientId groupRecipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupId); + GroupDatabase groupDatabase = SignalDatabase.groups(); + RecipientId groupRecipientId = SignalDatabase.recipients().getOrInsertFromGroupId(groupId); Recipient groupRecipient = Recipient.resolved(groupRecipientId); - long threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(groupRecipient); + long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(groupRecipient); groupDatabase.updateTitle(groupId, name); groupDatabase.onAvatarUpdated(groupId, avatarBytes != null); @@ -147,7 +147,7 @@ final class GroupManagerV1 { int newMemberCount) { Attachment avatarAttachment = null; - RecipientId groupRecipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupId); + RecipientId groupRecipientId = SignalDatabase.recipients().getOrInsertFromGroupId(groupId); Recipient groupRecipient = Recipient.resolved(groupRecipientId); List uuidMembers = new ArrayList<>(members.size()); @@ -194,8 +194,8 @@ final class GroupManagerV1 { @WorkerThread static void updateGroupTimer(@NonNull Context context, @NonNull GroupId.V1 groupId, int expirationTime) { - RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); + RecipientDatabase recipientDatabase = SignalDatabase.recipients(); + ThreadDatabase threadDatabase = SignalDatabase.threads(); Recipient recipient = Recipient.externalGroupExact(context, groupId); long threadId = threadDatabase.getOrCreateThreadIdFor(recipient); @@ -209,7 +209,7 @@ final class GroupManagerV1 { @NonNull GroupId.V1 groupId, @NonNull Recipient groupRecipient) { - GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); + GroupDatabase groupDatabase = SignalDatabase.groups(); if (!groupDatabase.isActive(groupId)) { Log.w(TAG, "Group has already been left."); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManagerV2.java b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManagerV2.java index 20a0498548..e5bbd85e83 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManagerV2.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManagerV2.java @@ -31,8 +31,8 @@ import org.signal.zkgroup.groups.UuidCiphertext; import org.signal.zkgroup.profiles.ProfileKey; import org.signal.zkgroup.profiles.ProfileKeyCredential; import org.thoughtcrime.securesms.crypto.ProfileKeyUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.database.model.databaseprotos.DecryptedGroupV2Context; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; @@ -98,7 +98,7 @@ final class GroupManagerV2 { GroupManagerV2(@NonNull Context context) { this.context = context; - this.groupDatabase = DatabaseFactory.getGroupDatabase(context); + this.groupDatabase = SignalDatabase.groups(); this.groupsV2Api = ApplicationDependencies.getSignalServiceAccountManager().getGroupsV2Api(); this.groupsV2Operations = ApplicationDependencies.getGroupsV2Operations(); this.authorization = ApplicationDependencies.getGroupsV2Authorization(); @@ -121,7 +121,7 @@ final class GroupManagerV2 { @NonNull GroupExternalCredential getGroupExternalCredential(@NonNull GroupId.V2 groupId) throws IOException, VerificationFailedException { - GroupMasterKey groupMasterKey = DatabaseFactory.getGroupDatabase(context) + GroupMasterKey groupMasterKey = SignalDatabase.groups() .requireGroup(groupId) .requireV2GroupProperties() .getGroupMasterKey(); @@ -133,7 +133,7 @@ final class GroupManagerV2 { @WorkerThread @NonNull Map getUuidCipherTexts(@NonNull GroupId.V2 groupId) { - GroupDatabase.GroupRecord groupRecord = DatabaseFactory.getGroupDatabase(context).requireGroup(groupId); + GroupDatabase.GroupRecord groupRecord = SignalDatabase.groups().requireGroup(groupId); GroupDatabase.V2GroupProperties v2GroupProperties = groupRecord.requireV2GroupProperties(); GroupMasterKey groupMasterKey = v2GroupProperties.getGroupMasterKey(); ClientZkGroupCipher clientZkGroupCipher = new ClientZkGroupCipher(GroupSecretParams.deriveFromMasterKey(groupMasterKey)); @@ -164,10 +164,10 @@ final class GroupManagerV2 { @WorkerThread GroupJoiner cancelRequest(@NonNull GroupId.V2 groupId) throws GroupChangeBusyException { - GroupMasterKey groupMasterKey = DatabaseFactory.getGroupDatabase(context) - .requireGroup(groupId) - .requireV2GroupProperties() - .getGroupMasterKey(); + GroupMasterKey groupMasterKey = SignalDatabase.groups() + .requireGroup(groupId) + .requireV2GroupProperties() + .getGroupMasterKey(); return new GroupJoiner(groupMasterKey, null, GroupsV2ProcessingLock.acquireGroupProcessingLock()); } @@ -260,12 +260,12 @@ final class GroupManagerV2 { GroupMasterKey masterKey = groupSecretParams.getMasterKey(); GroupId.V2 groupId = groupDatabase.create(masterKey, decryptedGroup); - RecipientId groupRecipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupId); + RecipientId groupRecipientId = SignalDatabase.recipients().getOrInsertFromGroupId(groupId); Recipient groupRecipient = Recipient.resolved(groupRecipientId); AvatarHelper.setAvatar(context, groupRecipientId, avatar != null ? new ByteArrayInputStream(avatar) : null); groupDatabase.onAvatarUpdated(groupId, avatar != null); - DatabaseFactory.getRecipientDatabase(context).setProfileSharing(groupRecipient.getId(), true); + SignalDatabase.recipients().setProfileSharing(groupRecipient.getId(), true); DecryptedGroupChange groupChange = DecryptedGroupChange.newBuilder(GroupChangeReconstruct.reconstructGroupChange(DecryptedGroup.newBuilder().build(), decryptedGroup)) .setEditor(selfAci.toByteString()) @@ -569,7 +569,7 @@ final class GroupManagerV2 { if (GroupChangeUtil.changeIsEmpty(change.build())) { Log.i(TAG, "Change is empty after conflict resolution"); Recipient groupRecipient = Recipient.externalGroupExact(context, groupId); - long threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(groupRecipient); + long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(groupRecipient); return new GroupManager.GroupActionResult(groupRecipient, threadId, 0, Collections.emptyList()); } @@ -830,17 +830,17 @@ final class GroupManagerV2 { Log.i(TAG, "Created local group with placeholder"); } - RecipientId groupRecipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupId); + RecipientId groupRecipientId = SignalDatabase.recipients().getOrInsertFromGroupId(groupId); Recipient groupRecipient = Recipient.resolved(groupRecipientId); AvatarHelper.setAvatar(context, groupRecipientId, avatar != null ? new ByteArrayInputStream(avatar) : null); groupDatabase.onAvatarUpdated(groupId, avatar != null); - DatabaseFactory.getRecipientDatabase(context).setProfileSharing(groupRecipientId, true); + SignalDatabase.recipients().setProfileSharing(groupRecipientId, true); if (alreadyAMember) { Log.i(TAG, "Already a member of the group"); - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); + ThreadDatabase threadDatabase = SignalDatabase.threads(); long threadId = threadDatabase.getOrCreateValidThreadId(groupRecipient, -1); return new GroupManager.GroupActionResult(groupRecipient, diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupV1MessageProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupV1MessageProcessor.java index 2da41ee9dc..b4dad5637c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupV1MessageProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupV1MessageProcessor.java @@ -10,10 +10,10 @@ import com.annimon.stream.Stream; import com.google.protobuf.ByteString; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.MessageDatabase; import org.thoughtcrime.securesms.database.MessageDatabase.InsertResult; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobs.AvatarGroupsV1DownloadJob; import org.thoughtcrime.securesms.jobs.PushGroupUpdateJob; @@ -65,7 +65,7 @@ public final class GroupV1MessageProcessor { return null; } - GroupDatabase database = DatabaseFactory.getGroupDatabase(context); + GroupDatabase database = SignalDatabase.groups(); SignalServiceGroup group = groupV1.get(); GroupId id = GroupId.v1(group.getGroupId()); Optional record = database.getGroup(id); @@ -89,7 +89,7 @@ public final class GroupV1MessageProcessor { @NonNull SignalServiceGroup group, boolean outgoing) { - GroupDatabase database = DatabaseFactory.getGroupDatabase(context); + GroupDatabase database = SignalDatabase.groups(); GroupId.V1 id = GroupId.v1orThrow(group.getGroupId()); GroupContext.Builder builder = createGroupContext(group); builder.setType(GroupContext.Type.UPDATE); @@ -110,7 +110,7 @@ public final class GroupV1MessageProcessor { if (sender.isSystemContact() || sender.isProfileSharing()) { Log.i(TAG, "Auto-enabling profile sharing because 'adder' is trusted. contact: " + sender.isSystemContact() + ", profileSharing: " + sender.isProfileSharing()); - DatabaseFactory.getRecipientDatabase(context).setProfileSharing(Recipient.externalGroupExact(context, id).getId(), true); + SignalDatabase.recipients().setProfileSharing(Recipient.externalGroupExact(context, id).getId(), true); } return storeMessage(context, content, group, builder.build(), outgoing); @@ -123,7 +123,7 @@ public final class GroupV1MessageProcessor { boolean outgoing) { - GroupDatabase database = DatabaseFactory.getGroupDatabase(context); + GroupDatabase database = SignalDatabase.groups(); GroupId.V1 id = GroupId.v1orThrow(group.getGroupId()); Set recordMembers = new HashSet<>(groupRecord.getMembers()); @@ -202,7 +202,7 @@ public final class GroupV1MessageProcessor { @NonNull GroupRecord record, boolean outgoing) { - GroupDatabase database = DatabaseFactory.getGroupDatabase(context); + GroupDatabase database = SignalDatabase.groups(); GroupId id = GroupId.v1orThrow(group.getGroupId()); List members = record.getMembers(); @@ -235,18 +235,18 @@ public final class GroupV1MessageProcessor { try { if (outgoing) { - MessageDatabase mmsDatabase = DatabaseFactory.getMmsDatabase(context); - RecipientId recipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(GroupId.v1orThrow(group.getGroupId())); + MessageDatabase mmsDatabase = SignalDatabase.mms(); + RecipientId recipientId = SignalDatabase.recipients().getOrInsertFromGroupId(GroupId.v1orThrow(group.getGroupId())); Recipient recipient = Recipient.resolved(recipientId); OutgoingGroupUpdateMessage outgoingMessage = new OutgoingGroupUpdateMessage(recipient, storage, null, content.getTimestamp(), 0, false, null, Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); - long threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient); + long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(recipient); long messageId = mmsDatabase.insertMessageOutbox(outgoingMessage, threadId, false, null); mmsDatabase.markAsSent(messageId, true); return threadId; } else { - MessageDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context); + MessageDatabase smsDatabase = SignalDatabase.sms(); String body = Base64.encodeBytes(storage.toByteArray()); IncomingTextMessage incoming = new IncomingTextMessage(Recipient.externalHighTrustPush(context, content.getSender()).getId(), content.getSenderDevice(), content.getTimestamp(), content.getServerReceivedTimestamp(), System.currentTimeMillis(), body, Optional.of(GroupId.v1orThrow(group.getGroupId())), 0, content.isNeedsReceipt(), content.getServerUuid()); IncomingGroupUpdateMessage groupMessage = new IncomingGroupUpdateMessage(incoming, storage, body); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupsV1MigrationUtil.java b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupsV1MigrationUtil.java index f7600f17d8..87fe434a5d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupsV1MigrationUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupsV1MigrationUtil.java @@ -10,9 +10,9 @@ import com.annimon.stream.Stream; import org.signal.core.util.logging.Log; import org.signal.storageservice.protos.groups.local.DecryptedGroup; import org.signal.zkgroup.groups.GroupMasterKey; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.mms.MmsException; import org.thoughtcrime.securesms.mms.OutgoingMediaMessage; @@ -39,8 +39,8 @@ public final class GroupsV1MigrationUtil { throws IOException, RetryLaterException, GroupChangeBusyException, InvalidMigrationStateException { Recipient groupRecipient = Recipient.resolved(recipientId); - Long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipientId); - GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); + Long threadId = SignalDatabase.threads().getThreadIdFor(recipientId); + GroupDatabase groupDatabase = SignalDatabase.groups(); if (threadId == null) { Log.w(TAG, "No thread found!"); @@ -146,13 +146,13 @@ public final class GroupsV1MigrationUtil { { Log.i(TAG, "Beginning local migration! V1 ID: " + gv1Id, new Throwable()); try (Closeable ignored = GroupsV2ProcessingLock.acquireGroupProcessingLock()) { - if (DatabaseFactory.getGroupDatabase(context).groupExists(gv1Id.deriveV2MigrationGroupId())) { + if (SignalDatabase.groups().groupExists(gv1Id.deriveV2MigrationGroupId())) { Log.w(TAG, "Group was already migrated! Could have been waiting for the lock.", new Throwable()); return; } Recipient recipient = Recipient.externalGroupExact(context, gv1Id); - long threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient); + long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(recipient); performLocalMigration(context, gv1Id, threadId, recipient); Log.i(TAG, "Migration complete! (" + gv1Id + ", " + threadId + ", " + recipient.getId() + ")", new Throwable()); @@ -182,7 +182,7 @@ public final class GroupsV1MigrationUtil { } Log.i(TAG, "[Local] Migrating group over to the version we were added to: V" + decryptedGroup.getRevision()); - DatabaseFactory.getGroupDatabase(context).migrateToV2(threadId, gv1Id, decryptedGroup); + SignalDatabase.groups().migrateToV2(threadId, gv1Id, decryptedGroup); Log.i(TAG, "[Local] Applying all changes since V" + decryptedGroup.getRevision()); try { @@ -198,14 +198,14 @@ public final class GroupsV1MigrationUtil { private static void handleLeftBehind(@NonNull Context context, @NonNull GroupId.V1 gv1Id, @NonNull Recipient groupRecipient, long threadId) { OutgoingMediaMessage leaveMessage = GroupUtil.createGroupV1LeaveMessage(gv1Id, groupRecipient); try { - long id = DatabaseFactory.getMmsDatabase(context).insertMessageOutbox(leaveMessage, threadId, false, null); - DatabaseFactory.getMmsDatabase(context).markAsSent(id, true); + long id = SignalDatabase.mms().insertMessageOutbox(leaveMessage, threadId, false, null); + SignalDatabase.mms().markAsSent(id, true); } catch (MmsException e) { Log.w(TAG, "Failed to insert group leave message!", e); } - DatabaseFactory.getGroupDatabase(context).setActive(gv1Id, false); - DatabaseFactory.getGroupDatabase(context).remove(gv1Id, Recipient.self().getId()); + SignalDatabase.groups().setActive(gv1Id, false); + SignalDatabase.groups().remove(gv1Id, Recipient.self().getId()); } /** diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/LiveGroup.java b/app/src/main/java/org/thoughtcrime/securesms/groups/LiveGroup.java index 89387aed2f..6f305406af 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/LiveGroup.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/LiveGroup.java @@ -17,8 +17,8 @@ import org.signal.storageservice.protos.groups.AccessControl; import org.signal.storageservice.protos.groups.local.DecryptedGroup; import org.signal.storageservice.protos.groups.local.DecryptedRequestingMember; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.ui.GroupMemberEntry; import org.thoughtcrime.securesms.groups.v2.GroupInviteLinkUrl; @@ -56,7 +56,7 @@ public final class LiveGroup { Context context = ApplicationDependencies.getApplication(); MutableLiveData liveRecipient = new MutableLiveData<>(); - this.groupDatabase = DatabaseFactory.getGroupDatabase(context); + this.groupDatabase = SignalDatabase.groups(); this.recipient = Transformations.switchMap(liveRecipient, LiveRecipient::getLiveData); this.groupRecord = LiveDataUtil.filterNotNull(LiveDataUtil.mapAsync(recipient, groupRecipient -> groupDatabase.getGroup(groupRecipient.getId()).orNull())); this.fullMembers = mapToFullMembers(this.groupRecord); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/LeaveGroupDialog.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/LeaveGroupDialog.java index fdfb082e0a..d4bdb4d9e6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/LeaveGroupDialog.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/LeaveGroupDialog.java @@ -12,8 +12,8 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.groups.GroupChangeException; import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.groups.GroupManager; @@ -54,10 +54,10 @@ public final class LeaveGroupDialog { } SimpleTask.run(activity.getLifecycle(), () -> { - GroupDatabase.V2GroupProperties groupProperties = DatabaseFactory.getGroupDatabase(activity) - .getGroup(groupId) - .transform(GroupDatabase.GroupRecord::requireV2GroupProperties) - .orNull(); + GroupDatabase.V2GroupProperties groupProperties = SignalDatabase.groups() + .getGroup(groupId) + .transform(GroupDatabase.GroupRecord::requireV2GroupProperties) + .orNull(); if (groupProperties != null && groupProperties.isAdmin(Recipient.self())) { List otherMemberRecipients = groupProperties.getMemberRecipients(GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/addmembers/AddMembersRepository.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/addmembers/AddMembersRepository.java index 55a3dd1ba0..13cd9ca28d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/addmembers/AddMembersRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/addmembers/AddMembersRepository.java @@ -6,7 +6,7 @@ import androidx.annotation.NonNull; import androidx.annotation.WorkerThread; import org.thoughtcrime.securesms.contacts.SelectedContact; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.recipients.RecipientId; @@ -28,6 +28,6 @@ final class AddMembersRepository { @WorkerThread String getGroupTitle() { - return DatabaseFactory.getGroupDatabase(context).requireGroup(groupId).getTitle(); + return SignalDatabase.groups().requireGroup(groupId).getTitle(); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/invitesandrequests/invited/PendingMemberInvitesRepository.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/invitesandrequests/invited/PendingMemberInvitesRepository.java index bd925d4972..47a17d41a2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/invitesandrequests/invited/PendingMemberInvitesRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/invitesandrequests/invited/PendingMemberInvitesRepository.java @@ -15,8 +15,8 @@ import org.signal.storageservice.protos.groups.local.DecryptedGroup; import org.signal.storageservice.protos.groups.local.DecryptedPendingMember; import org.signal.zkgroup.InvalidInputException; import org.signal.zkgroup.groups.UuidCiphertext; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.groups.GroupChangeException; import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.groups.GroupManager; @@ -48,7 +48,7 @@ final class PendingMemberInvitesRepository { public void getInvitees(@NonNull Consumer onInviteesLoaded) { executor.execute(() -> { - GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); + GroupDatabase groupDatabase = SignalDatabase.groups(); GroupDatabase.V2GroupProperties v2GroupProperties = groupDatabase.getGroup(groupId).get().requireV2GroupProperties(); DecryptedGroup decryptedGroup = v2GroupProperties.getDecryptedGroup(); List pendingMembersList = decryptedGroup.getPendingMembersList(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationSuggestionsDialog.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationSuggestionsDialog.java index 4d00253f6a..c2916b05b4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationSuggestionsDialog.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationSuggestionsDialog.java @@ -10,7 +10,7 @@ import androidx.fragment.app.FragmentActivity; import org.signal.core.util.concurrent.SignalExecutors; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.groups.GroupChangeBusyException; import org.thoughtcrime.securesms.groups.GroupChangeFailedException; import org.thoughtcrime.securesms.groups.GroupId; @@ -77,14 +77,14 @@ public final class GroupsV1MigrationSuggestionsDialog { try { GroupManager.addMembers(fragmentActivity, groupId.requirePush(), suggestions); Log.i(TAG, "Successfully added members! Removing these dropped members from the list."); - DatabaseFactory.getGroupDatabase(fragmentActivity).removeUnmigratedV1Members(groupId, suggestions); + SignalDatabase.groups().removeUnmigratedV1Members(groupId, suggestions); return Result.SUCCESS; } catch (IOException | GroupChangeBusyException e) { Log.w(TAG, "Temporary failure.", e); return Result.NETWORK_ERROR; } catch (GroupNotAMemberException | GroupInsufficientRightsException | MembershipNotSuitableForV2Exception | GroupChangeFailedException e) { Log.w(TAG, "Permanent failure! Removing these dropped members from the list.", e); - DatabaseFactory.getGroupDatabase(fragmentActivity).removeUnmigratedV1Members(groupId, suggestions); + SignalDatabase.groups().removeUnmigratedV1Members(groupId, suggestions); return Result.IMPOSSIBLE; } }, result -> { diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/v2/GroupCandidateHelper.java b/app/src/main/java/org/thoughtcrime/securesms/groups/v2/GroupCandidateHelper.java index cecb718505..32ca1c7fd0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/v2/GroupCandidateHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/v2/GroupCandidateHelper.java @@ -9,8 +9,8 @@ import org.signal.core.util.logging.Log; import org.signal.zkgroup.profiles.ProfileKey; import org.signal.zkgroup.profiles.ProfileKeyCredential; import org.thoughtcrime.securesms.crypto.ProfileKeyUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.RecipientDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; @@ -24,7 +24,6 @@ import java.util.Collection; import java.util.HashSet; import java.util.Locale; import java.util.Set; -import java.util.UUID; public final class GroupCandidateHelper { private final SignalServiceAccountManager signalServiceAccountManager; @@ -32,7 +31,7 @@ public final class GroupCandidateHelper { public GroupCandidateHelper(@NonNull Context context) { signalServiceAccountManager = ApplicationDependencies.getSignalServiceAccountManager(); - recipientDatabase = DatabaseFactory.getRecipientDatabase(context); + recipientDatabase = SignalDatabase.recipients(); } private static final String TAG = Log.tag(GroupCandidateHelper.class); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/v2/processing/GroupsV2StateProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/groups/v2/processing/GroupsV2StateProcessor.java index a7cdf30b37..7596485b21 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/v2/processing/GroupsV2StateProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/v2/processing/GroupsV2StateProcessor.java @@ -17,10 +17,10 @@ import org.signal.storageservice.protos.groups.local.DecryptedPendingMember; import org.signal.zkgroup.VerificationFailedException; import org.signal.zkgroup.groups.GroupMasterKey; import org.signal.zkgroup.groups.GroupSecretParams; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.MessageDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.database.model.databaseprotos.DecryptedGroupV2Context; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; @@ -96,8 +96,8 @@ public final class GroupsV2StateProcessor { this.jobManager = ApplicationDependencies.getJobManager(); this.groupsV2Authorization = ApplicationDependencies.getGroupsV2Authorization(); this.groupsV2Api = ApplicationDependencies.getSignalServiceAccountManager().getGroupsV2Api(); - this.recipientDatabase = DatabaseFactory.getRecipientDatabase(context); - this.groupDatabase = DatabaseFactory.getGroupDatabase(context); + this.recipientDatabase = SignalDatabase.recipients(); + this.groupDatabase = SignalDatabase.groups(); } public StateProcessorForGroup forGroup(@NonNull GroupMasterKey groupMasterKey) { @@ -311,8 +311,8 @@ public final class GroupsV2StateProcessor { Collections.emptyList()); try { - MessageDatabase mmsDatabase = DatabaseFactory.getMmsDatabase(context); - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); + MessageDatabase mmsDatabase = SignalDatabase.mms(); + ThreadDatabase threadDatabase = SignalDatabase.threads(); long threadId = threadDatabase.getOrCreateThreadIdFor(groupRecipient); long id = mmsDatabase.insertMessageOutbox(leaveMessage, threadId, false, null); mmsDatabase.markAsSent(id, true); @@ -503,8 +503,8 @@ public final class GroupsV2StateProcessor { if (outgoing) { try { - MessageDatabase mmsDatabase = DatabaseFactory.getMmsDatabase(context); - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); + MessageDatabase mmsDatabase = SignalDatabase.mms(); + ThreadDatabase threadDatabase = SignalDatabase.threads(); RecipientId recipientId = recipientDatabase.getOrInsertFromGroupId(groupId); Recipient recipient = Recipient.resolved(recipientId); OutgoingGroupUpdateMessage outgoingMessage = new OutgoingGroupUpdateMessage(recipient, decryptedGroupV2Context, null, timestamp, 0, false, null, Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); @@ -517,14 +517,14 @@ public final class GroupsV2StateProcessor { Log.w(TAG, e); } } else { - MessageDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context); + MessageDatabase smsDatabase = SignalDatabase.sms(); RecipientId sender = RecipientId.from(editor.get(), null); IncomingTextMessage incoming = new IncomingTextMessage(sender, -1, timestamp, timestamp, timestamp, "", Optional.of(groupId), 0, false, null); IncomingGroupUpdateMessage groupMessage = new IncomingGroupUpdateMessage(incoming, decryptedGroupV2Context); Optional insertResult = smsDatabase.insertMessageInbox(groupMessage); if (insertResult.isPresent()) { - DatabaseFactory.getThreadDatabase(context).update(insertResult.get().getThreadId(), false, false); + SignalDatabase.threads().update(insertResult.get().getThreadId(), false, false); } else { Log.w(TAG, "Could not insert update message"); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/help/HelpViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/help/HelpViewModel.java index 2aa6a63e18..d8df9f6dd6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/help/HelpViewModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/help/HelpViewModel.java @@ -3,18 +3,12 @@ package org.thoughtcrime.securesms.help; import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; -import androidx.lifecycle.Transformations; import androidx.lifecycle.ViewModel; -import org.thoughtcrime.securesms.logsubmit.LogLine; import org.thoughtcrime.securesms.logsubmit.SubmitDebugLogRepository; -import org.thoughtcrime.securesms.util.livedata.LiveDataPair; import org.thoughtcrime.securesms.util.livedata.LiveDataUtil; -import org.whispersystems.libsignal.util.Pair; import org.whispersystems.libsignal.util.guava.Optional; -import java.util.List; - public class HelpViewModel extends ViewModel { private static final int MINIMUM_PROBLEM_CHARS = 10; diff --git a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsRepository.java b/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsRepository.java index 6106e3461c..e832647bbb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsRepository.java @@ -13,9 +13,9 @@ import org.thoughtcrime.securesms.contacts.avatars.GeneratedContactPhoto; import org.thoughtcrime.securesms.contacts.avatars.ProfileContactPhoto; import org.thoughtcrime.securesms.conversation.colors.ChatColors; import org.thoughtcrime.securesms.conversation.colors.ChatColorsPalette; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MmsSmsDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.sms.MessageSender; @@ -37,7 +37,7 @@ public class InsightsRepository implements InsightsDashboardViewModel.Repository @Override public void getInsightsData(@NonNull Consumer insightsDataConsumer) { SimpleTask.run(() -> { - MmsSmsDatabase mmsSmsDatabase = DatabaseFactory.getMmsSmsDatabase(context); + MmsSmsDatabase mmsSmsDatabase = SignalDatabase.mmsSms(); int insecure = mmsSmsDatabase.getInsecureMessageCountForInsights(); int secure = mmsSmsDatabase.getSecureMessageCountForInsights(); @@ -52,7 +52,7 @@ public class InsightsRepository implements InsightsDashboardViewModel.Repository @Override public void getInsecureRecipients(@NonNull Consumer> insecureRecipientsConsumer) { SimpleTask.run(() -> { - RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase recipientDatabase = SignalDatabase.recipients(); List unregisteredRecipients = recipientDatabase.getUninvitedRecipientsForInsights(); return Stream.of(unregisteredRecipients) @@ -83,7 +83,7 @@ public class InsightsRepository implements InsightsDashboardViewModel.Repository MessageSender.send(context, new OutgoingTextMessage(resolved, message, subscriptionId), -1L, true, null, null); - RecipientDatabase database = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase database = SignalDatabase.recipients(); database.setHasSentInvite(recipient.getId()); return null; diff --git a/app/src/main/java/org/thoughtcrime/securesms/invites/InviteReminderModel.java b/app/src/main/java/org/thoughtcrime/securesms/invites/InviteReminderModel.java index 4a276e16ea..6803dc7799 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/invites/InviteReminderModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/invites/InviteReminderModel.java @@ -9,8 +9,7 @@ import androidx.annotation.WorkerThread; import org.thoughtcrime.securesms.components.reminder.FirstInviteReminder; import org.thoughtcrime.securesms.components.reminder.Reminder; import org.thoughtcrime.securesms.components.reminder.SecondInviteReminder; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.MmsSmsDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.recipients.LiveRecipient; import org.thoughtcrime.securesms.recipients.Recipient; @@ -49,11 +48,11 @@ public final class InviteReminderModel { return new NoReminderInfo(); } - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); + ThreadDatabase threadDatabase = SignalDatabase.threads(); Long threadId = threadDatabase.getThreadIdFor(recipient.getId()); if (threadId != null) { - int conversationCount = DatabaseFactory.getMmsSmsDatabase(context).getInsecureSentCount(threadId); + int conversationCount = SignalDatabase.mmsSms().getInsecureSentCount(threadId); if (conversationCount >= SECOND_INVITE_REMINDER_MESSAGE_THRESHOLD && !resolved.hasSeenSecondInviteReminder()) { return new SecondInviteReminderInfo(context, resolved, repository, repository.getPercentOfInsecureMessages(conversationCount)); diff --git a/app/src/main/java/org/thoughtcrime/securesms/invites/InviteReminderRepository.java b/app/src/main/java/org/thoughtcrime/securesms/invites/InviteReminderRepository.java index 1c9276a283..81fc07a0ed 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/invites/InviteReminderRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/invites/InviteReminderRepository.java @@ -2,9 +2,9 @@ package org.thoughtcrime.securesms.invites; import android.content.Context; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MmsSmsDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.recipients.Recipient; public final class InviteReminderRepository implements InviteReminderModel.Repository { @@ -17,19 +17,19 @@ public final class InviteReminderRepository implements InviteReminderModel.Repos @Override public void setHasSeenFirstInviteReminder(Recipient recipient) { - RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase recipientDatabase = SignalDatabase.recipients(); recipientDatabase.setSeenFirstInviteReminder(recipient.getId()); } @Override public void setHasSeenSecondInviteReminder(Recipient recipient) { - RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase recipientDatabase = SignalDatabase.recipients(); recipientDatabase.setSeenSecondInviteReminder(recipient.getId()); } @Override public int getPercentOfInsecureMessages(int insecureCount) { - MmsSmsDatabase mmsSmsDatabase = DatabaseFactory.getMmsSmsDatabase(context); + MmsSmsDatabase mmsSmsDatabase = SignalDatabase.mmsSms(); int insecure = mmsSmsDatabase.getInsecureMessageCountForInsights(); int secure = mmsSmsDatabase.getSecureMessageCountForInsights(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/migrations/PushDecryptMessageJobEnvelopeMigration.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/migrations/PushDecryptMessageJobEnvelopeMigration.java index f4a029d4bb..b72120d8d6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/migrations/PushDecryptMessageJobEnvelopeMigration.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/migrations/PushDecryptMessageJobEnvelopeMigration.java @@ -5,23 +5,14 @@ import android.content.Context; import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.NoSuchMessageException; import org.thoughtcrime.securesms.database.PushDatabase; -import org.thoughtcrime.securesms.groups.BadGroupIdException; -import org.thoughtcrime.securesms.groups.GroupId; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.JobMigration; import org.thoughtcrime.securesms.jobs.FailingJob; -import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.recipients.RecipientId; -import org.thoughtcrime.securesms.util.Base64; -import org.thoughtcrime.securesms.util.GroupUtil; -import org.whispersystems.signalservice.api.messages.SignalServiceContent; import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope; -import java.io.IOException; - /** * We removed the messageId property from the job data and replaced it with a serialized envelope, * so we need to take jobs that referenced an ID and replace it with the envelope instead. @@ -34,7 +25,7 @@ public class PushDecryptMessageJobEnvelopeMigration extends JobMigration { public PushDecryptMessageJobEnvelopeMigration(@NonNull Context context) { super(8); - this.pushDatabase = DatabaseFactory.getPushDatabase(context); + this.pushDatabase = SignalDatabase.push(); } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentCompressionJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentCompressionJob.java index eda39f61f6..82bc004747 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentCompressionJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentCompressionJob.java @@ -20,7 +20,7 @@ import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider; import org.thoughtcrime.securesms.crypto.ModernDecryptingPartInputStream; import org.thoughtcrime.securesms.crypto.ModernEncryptingPartOutputStream; import org.thoughtcrime.securesms.database.AttachmentDatabase; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.events.PartProgressEvent; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; @@ -129,7 +129,7 @@ public final class AttachmentCompressionJob extends BaseJob { public void onRun() throws Exception { Log.d(TAG, "Running for: " + attachmentId); - AttachmentDatabase database = DatabaseFactory.getAttachmentDatabase(context); + AttachmentDatabase database = SignalDatabase.attachments(); DatabaseAttachment databaseAttachment = database.getAttachment(attachmentId); if (databaseAttachment == null) { @@ -226,8 +226,7 @@ public final class AttachmentCompressionJob extends BaseJob { Log.i(TAG, "Compressing with streaming muxer"); AttachmentSecret attachmentSecret = AttachmentSecretProvider.getInstance(context).getOrCreateAttachmentSecret(); - File file = DatabaseFactory.getAttachmentDatabase(context) - .newFile(); + File file = SignalDatabase.attachments().newFile(); file.deleteOnExit(); try { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentCopyJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentCopyJob.java index b1f2796858..d95b743ec2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentCopyJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentCopyJob.java @@ -4,7 +4,7 @@ import androidx.annotation.NonNull; import org.thoughtcrime.securesms.attachments.AttachmentId; import org.thoughtcrime.securesms.database.AttachmentDatabase; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.util.JsonUtils; @@ -75,7 +75,7 @@ public class AttachmentCopyJob extends BaseJob { @Override protected void onRun() throws Exception { - AttachmentDatabase database = DatabaseFactory.getAttachmentDatabase(context); + AttachmentDatabase database = SignalDatabase.attachments(); for (AttachmentId destinationId : destinationIds) { database.copyAttachmentData(sourceId, destinationId); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentDownloadJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentDownloadJob.java index 8fb9b42df7..d90838793b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentDownloadJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentDownloadJob.java @@ -12,7 +12,7 @@ import org.thoughtcrime.securesms.attachments.AttachmentId; import org.thoughtcrime.securesms.attachments.DatabaseAttachment; import org.thoughtcrime.securesms.blurhash.BlurHash; import org.thoughtcrime.securesms.database.AttachmentDatabase; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.events.PartProgressEvent; import org.thoughtcrime.securesms.jobmanager.Data; @@ -96,7 +96,7 @@ public final class AttachmentDownloadJob extends BaseJob { public void onAdded() { Log.i(TAG, "onAdded() messageId: " + messageId + " partRowId: " + partRowId + " partUniqueId: " + partUniqueId + " manual: " + manual); - final AttachmentDatabase database = DatabaseFactory.getAttachmentDatabase(context); + final AttachmentDatabase database = SignalDatabase.attachments(); final AttachmentId attachmentId = new AttachmentId(partRowId, partUniqueId); final DatabaseAttachment attachment = database.getAttachment(attachmentId); final boolean pending = attachment != null && attachment.getTransferState() != AttachmentDatabase.TRANSFER_PROGRESS_DONE; @@ -116,7 +116,7 @@ public final class AttachmentDownloadJob extends BaseJob { public void doWork() throws IOException, RetryLaterException { Log.i(TAG, "onRun() messageId: " + messageId + " partRowId: " + partRowId + " partUniqueId: " + partUniqueId + " manual: " + manual); - final AttachmentDatabase database = DatabaseFactory.getAttachmentDatabase(context); + final AttachmentDatabase database = SignalDatabase.attachments(); final AttachmentId attachmentId = new AttachmentId(partRowId, partUniqueId); final DatabaseAttachment attachment = database.getAttachment(attachmentId); @@ -162,7 +162,7 @@ public final class AttachmentDownloadJob extends BaseJob { throws IOException, RetryLaterException { - AttachmentDatabase database = DatabaseFactory.getAttachmentDatabase(context); + AttachmentDatabase database = SignalDatabase.attachments(); File attachmentFile = database.getOrCreateTransferFile(attachmentId); try { @@ -224,7 +224,7 @@ public final class AttachmentDownloadJob extends BaseJob { private void markFailed(long messageId, AttachmentId attachmentId) { try { - AttachmentDatabase database = DatabaseFactory.getAttachmentDatabase(context); + AttachmentDatabase database = SignalDatabase.attachments(); database.setTransferProgressFailed(attachmentId, messageId); } catch (MmsException e) { Log.w(TAG, e); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentMarkUploadedJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentMarkUploadedJob.java index 2771592cf7..e3a5dc2e56 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentMarkUploadedJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentMarkUploadedJob.java @@ -6,7 +6,7 @@ import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.attachments.AttachmentId; import org.thoughtcrime.securesms.attachments.DatabaseAttachment; import org.thoughtcrime.securesms.database.AttachmentDatabase; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; @@ -60,7 +60,7 @@ public final class AttachmentMarkUploadedJob extends BaseJob { @Override public void onRun() throws Exception { - AttachmentDatabase database = DatabaseFactory.getAttachmentDatabase(context); + AttachmentDatabase database = SignalDatabase.attachments(); DatabaseAttachment databaseAttachment = database.getAttachment(attachmentId); if (databaseAttachment == null) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.java index ae18d89e49..a4153054f7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.java @@ -16,7 +16,7 @@ import org.thoughtcrime.securesms.attachments.DatabaseAttachment; import org.thoughtcrime.securesms.attachments.PointerAttachment; import org.thoughtcrime.securesms.blurhash.BlurHashEncoder; import org.thoughtcrime.securesms.database.AttachmentDatabase; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.events.PartProgressEvent; import org.thoughtcrime.securesms.jobmanager.Data; @@ -32,7 +32,6 @@ import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.SignalServiceMessageSender; import org.whispersystems.signalservice.api.messages.SignalServiceAttachment; import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer; -import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException; import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResumableUploadResponseCodeException; import org.whispersystems.signalservice.api.push.exceptions.ResumeLocationInvalidException; import org.whispersystems.signalservice.internal.push.http.ResumableUploadSpec; @@ -125,7 +124,7 @@ public final class AttachmentUploadJob extends BaseJob { } SignalServiceMessageSender messageSender = ApplicationDependencies.getSignalServiceMessageSender(); - AttachmentDatabase database = DatabaseFactory.getAttachmentDatabase(context); + AttachmentDatabase database = SignalDatabase.attachments(); DatabaseAttachment databaseAttachment = database.getAttachment(attachmentId); if (databaseAttachment == null) { @@ -167,7 +166,7 @@ public final class AttachmentUploadJob extends BaseJob { @Override public void onFailure() { if (isCanceled()) { - DatabaseFactory.getAttachmentDatabase(context).deleteAttachment(attachmentId); + SignalDatabase.attachments().deleteAttachment(attachmentId); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/AutomaticSessionResetJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/AutomaticSessionResetJob.java index 69b5fabb38..a6f9b6db27 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/AutomaticSessionResetJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/AutomaticSessionResetJob.java @@ -5,8 +5,8 @@ import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.crypto.SessionUtil; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessageDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.databaseprotos.DeviceLastResetTime; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; @@ -85,12 +85,12 @@ public class AutomaticSessionResetJob extends BaseJob { @Override protected void onRun() throws Exception { SessionUtil.archiveSession(recipientId, deviceId); - DatabaseFactory.getSenderKeySharedDatabase(context).deleteAllFor(recipientId); + SignalDatabase.senderKeyShared().deleteAllFor(recipientId); insertLocalMessage(); if (FeatureFlags.automaticSessionReset()) { long resetInterval = TimeUnit.SECONDS.toMillis(FeatureFlags.automaticSessionResetIntervalSeconds()); - DeviceLastResetTime resetTimes = DatabaseFactory.getRecipientDatabase(context).getLastSessionResetTimes(recipientId); + DeviceLastResetTime resetTimes = SignalDatabase.recipients().getLastSessionResetTimes(recipientId); long timeSinceLastReset = System.currentTimeMillis() - getLastResetTime(resetTimes, deviceId); Log.i(TAG, "DeviceId: " + deviceId + ", Reset interval: " + resetInterval + ", Time since last reset: " + timeSinceLastReset); @@ -98,7 +98,7 @@ public class AutomaticSessionResetJob extends BaseJob { if (timeSinceLastReset > resetInterval) { Log.i(TAG, "We're good! Sending a null message."); - DatabaseFactory.getRecipientDatabase(context).setLastSessionResetTime(recipientId, setLastResetTime(resetTimes, deviceId, System.currentTimeMillis())); + SignalDatabase.recipients().setLastSessionResetTime(recipientId, setLastResetTime(resetTimes, deviceId, System.currentTimeMillis())); Log.i(TAG, "Marked last reset time: " + System.currentTimeMillis()); sendNullMessage(); @@ -121,7 +121,7 @@ public class AutomaticSessionResetJob extends BaseJob { } private void insertLocalMessage() { - MessageDatabase.InsertResult result = DatabaseFactory.getSmsDatabase(context).insertChatSessionRefreshedMessage(recipientId, deviceId, sentTimestamp); + MessageDatabase.InsertResult result = SignalDatabase.sms().insertChatSessionRefreshedMessage(recipientId, deviceId, sentTimestamp); ApplicationDependencies.getMessageNotifier().updateNotification(context, result.getThreadId()); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/AvatarGroupsV1DownloadJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/AvatarGroupsV1DownloadJob.java index 557b0095ce..41023f5528 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/AvatarGroupsV1DownloadJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/AvatarGroupsV1DownloadJob.java @@ -3,9 +3,9 @@ package org.thoughtcrime.securesms.jobs; import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.jobmanager.Data; @@ -60,7 +60,7 @@ public final class AvatarGroupsV1DownloadJob extends BaseJob { @Override public void onRun() throws IOException { - GroupDatabase database = DatabaseFactory.getGroupDatabase(context); + GroupDatabase database = SignalDatabase.groups(); Optional record = database.getGroup(groupId); File attachment = null; @@ -89,7 +89,7 @@ public final class AvatarGroupsV1DownloadJob extends BaseJob { InputStream inputStream = receiver.retrieveAttachment(pointer, attachment, AvatarHelper.AVATAR_DOWNLOAD_FAILSAFE_MAX_SIZE); AvatarHelper.setAvatar(context, record.get().getRecipientId(), inputStream); - DatabaseFactory.getGroupDatabase(context).onAvatarUpdated(groupId, true); + SignalDatabase.groups().onAvatarUpdated(groupId, true); inputStream.close(); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/AvatarGroupsV2DownloadJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/AvatarGroupsV2DownloadJob.java index f94a0f4bc8..34bae1781c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/AvatarGroupsV2DownloadJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/AvatarGroupsV2DownloadJob.java @@ -9,9 +9,9 @@ import org.signal.core.util.StreamUtil; import org.signal.core.util.logging.Log; import org.signal.zkgroup.groups.GroupMasterKey; import org.signal.zkgroup.groups.GroupSecretParams; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.jobmanager.Data; @@ -74,7 +74,7 @@ public final class AvatarGroupsV2DownloadJob extends BaseJob { @Override public void onRun() throws IOException { - GroupDatabase database = DatabaseFactory.getGroupDatabase(context); + GroupDatabase database = SignalDatabase.groups(); Optional record = database.getGroup(groupId); File attachment = null; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/ConversationShortcutUpdateJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/ConversationShortcutUpdateJob.java index fa5cd97aca..5bd8b73c50 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/ConversationShortcutUpdateJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/ConversationShortcutUpdateJob.java @@ -1,12 +1,9 @@ package org.thoughtcrime.securesms.jobs; -import android.os.Build; - import androidx.annotation.NonNull; -import androidx.annotation.RequiresApi; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.database.model.ThreadRecord; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; @@ -21,8 +18,6 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; -import static org.thoughtcrime.securesms.util.ConversationUtil.CONVERSATION_SUPPORT_VERSION; - /** * On some devices, interacting with the ShortcutManager can take a very long time (several seconds). * So, we interact with it in a job instead, and keep it in one queue so it can't starve the other @@ -68,7 +63,7 @@ public class ConversationShortcutUpdateJob extends BaseJob { return; } - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); + ThreadDatabase threadDatabase = SignalDatabase.threads(); int maxShortcuts = ConversationUtil.getMaxShortcuts(context); List ranked = new ArrayList<>(maxShortcuts); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/DonationReceiptRedemptionJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/DonationReceiptRedemptionJob.java index 5e9ba1d2d3..139e237db2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/DonationReceiptRedemptionJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/DonationReceiptRedemptionJob.java @@ -8,8 +8,8 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; -import org.thoughtcrime.securesms.subscription.SubscriptionNotification; import org.thoughtcrime.securesms.keyvalue.SignalStore; +import org.thoughtcrime.securesms.subscription.SubscriptionNotification; import org.whispersystems.signalservice.internal.EmptyResponse; import org.whispersystems.signalservice.internal.ServiceResponse; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/EmojiSearchIndexDownloadJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/EmojiSearchIndexDownloadJob.java index 7f9b9071d1..ef96922cf5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/EmojiSearchIndexDownloadJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/EmojiSearchIndexDownloadJob.java @@ -5,9 +5,7 @@ import androidx.annotation.NonNull; import com.fasterxml.jackson.annotation.JsonProperty; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.components.emoji.Emoji; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.EmojiSearchDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.EmojiSearchData; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; @@ -24,11 +22,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Locale; -import java.util.Map; import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -import javax.annotation.Nullable; import okhttp3.Call; import okhttp3.OkHttpClient; @@ -113,7 +107,7 @@ public final class EmojiSearchIndexDownloadJob extends BaseJob { List searchIndex = downloadSearchIndex(client, manifest.getVersion(), remoteLanguage); - DatabaseFactory.getEmojiSearchDatabase(context).setSearchIndex(searchIndex); + SignalDatabase.emojiSearch().setSearchIndex(searchIndex); SignalStore.emojiValues().onSearchIndexUpdated(manifest.getVersion(), remoteLanguage); SignalStore.emojiValues().setLastSearchIndexCheck(System.currentTimeMillis()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/FastJobStorage.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/FastJobStorage.java index e6b07c1c29..af4cc2d243 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/FastJobStorage.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/FastJobStorage.java @@ -18,7 +18,6 @@ import org.thoughtcrime.securesms.util.Util; import org.whispersystems.libsignal.util.guava.Optional; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; 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 92c07a00b5..c9a7caf346 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/FcmRefreshJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/FcmRefreshJob.java @@ -40,7 +40,6 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.notifications.NotificationChannels; import org.thoughtcrime.securesms.notifications.NotificationIds; import org.thoughtcrime.securesms.transport.RetryLaterException; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/GroupCallUpdateSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/GroupCallUpdateSendJob.java index d2dbd6642b..40bce96368 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/GroupCallUpdateSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/GroupCallUpdateSendJob.java @@ -7,9 +7,6 @@ import androidx.annotation.WorkerThread; import com.annimon.stream.Stream; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; -import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.messages.GroupSendUtil; @@ -19,14 +16,10 @@ import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.recipients.RecipientUtil; import org.thoughtcrime.securesms.transport.RetryLaterException; import org.thoughtcrime.securesms.util.GroupUtil; -import org.whispersystems.libsignal.util.guava.Optional; -import org.whispersystems.signalservice.api.SignalServiceMessageSender; import org.whispersystems.signalservice.api.crypto.ContentHint; -import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair; import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException; import org.whispersystems.signalservice.api.messages.SendMessageResult; import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage; -import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException; import java.io.IOException; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/GroupSendJobHelper.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/GroupSendJobHelper.java index b6d4e3aff6..b8322a2fde 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/GroupSendJobHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/GroupSendJobHelper.java @@ -1,7 +1,5 @@ package org.thoughtcrime.securesms.jobs; -import android.content.Context; - import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/GroupV1MigrationJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/GroupV1MigrationJob.java index 4f3806659c..c5917af576 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/GroupV1MigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/GroupV1MigrationJob.java @@ -8,7 +8,7 @@ import com.annimon.stream.Stream; import org.signal.core.util.concurrent.SignalExecutors; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.ThreadRecord; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupChangeBusyException; @@ -21,7 +21,6 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.transport.RetryLaterException; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.signalservice.api.groupsv2.NoCredentialForRedemptionTimeException; import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException; @@ -87,7 +86,7 @@ public class GroupV1MigrationJob extends BaseJob { SignalExecutors.BOUNDED.execute(() -> { JobManager jobManager = ApplicationDependencies.getJobManager(); - List threads = DatabaseFactory.getThreadDatabase(application).getRecentV1Groups(ROUTINE_LIMIT); + List threads = SignalDatabase.threads().getRecentV1Groups(ROUTINE_LIMIT); Set needsRefresh = new HashSet<>(); if (threads.size() > 0) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java index e866f640bc..4d1582902c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java @@ -4,7 +4,7 @@ import android.app.Application; import androidx.annotation.NonNull; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.jobmanager.Constraint; import org.thoughtcrime.securesms.jobmanager.ConstraintObserver; import org.thoughtcrime.securesms.jobmanager.Job; @@ -246,7 +246,7 @@ public final class JobManagerFactories { return Arrays.asList(new RecipientIdJobMigration(application), new RecipientIdFollowUpJobMigration(), new RecipientIdFollowUpJobMigration2(), - new SendReadReceiptsJobMigration(DatabaseFactory.getMmsSmsDatabase(application)), + new SendReadReceiptsJobMigration(SignalDatabase.mmsSms()), new PushProcessMessageQueueJobMigration(application), new RetrieveProfileJobMigration(), new PushDecryptMessageJobEnvelopeMigration(application)); 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 b887206dee..e78a2a8ab0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/LocalBackupJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/LocalBackupJob.java @@ -11,8 +11,8 @@ import org.thoughtcrime.securesms.backup.BackupFileIOError; import org.thoughtcrime.securesms.backup.BackupPassphrase; import org.thoughtcrime.securesms.backup.FullBackupExporter; import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.NoExternalStorageException; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; @@ -113,7 +113,7 @@ public final class LocalBackupJob extends BaseJob { try { FullBackupExporter.export(context, AttachmentSecretProvider.getInstance(context).getOrCreateAttachmentSecret(), - DatabaseFactory.getBackupDatabase(context), + SignalDatabase.getBackupDatabase(), tempFile, backupPassword, this::isCanceled); 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 c8f5afc4d5..efa59255da 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/LocalBackupJobApi29.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/LocalBackupJobApi29.java @@ -12,7 +12,7 @@ import org.thoughtcrime.securesms.backup.BackupFileIOError; import org.thoughtcrime.securesms.backup.BackupPassphrase; import org.thoughtcrime.securesms.backup.FullBackupExporter; import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.keyvalue.SignalStore; @@ -107,7 +107,7 @@ public final class LocalBackupJobApi29 extends BaseJob { try { FullBackupExporter.export(context, AttachmentSecretProvider.getInstance(context).getOrCreateAttachmentSecret(), - DatabaseFactory.getBackupDatabase(context), + SignalDatabase.getBackupDatabase(), temporaryFile, backupPassword, this::isCanceled); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java index 094782d955..5315434642 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java @@ -17,10 +17,10 @@ import org.thoughtcrime.securesms.attachments.UriAttachment; import org.thoughtcrime.securesms.contactshare.Contact; import org.thoughtcrime.securesms.contactshare.VCardUtil; import org.thoughtcrime.securesms.database.AttachmentDatabase; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessageDatabase; import org.thoughtcrime.securesms.database.MessageDatabase.InsertResult; import org.thoughtcrime.securesms.database.MmsDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.jobmanager.Data; @@ -37,7 +37,6 @@ import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.service.KeyCachingService; import org.thoughtcrime.securesms.util.MediaUtil; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.Util; import org.whispersystems.libsignal.util.guava.Optional; @@ -99,7 +98,7 @@ public class MmsDownloadJob extends BaseJob { @Override public void onAdded() { if (automatic && KeyCachingService.isLocked(context)) { - DatabaseFactory.getMmsDatabase(context).markIncomingNotificationReceived(threadId); + SignalDatabase.mms().markIncomingNotificationReceived(threadId); ApplicationDependencies.getMessageNotifier().updateNotification(context); } } @@ -110,7 +109,7 @@ public class MmsDownloadJob extends BaseJob { throw new NotReadyException(); } - MessageDatabase database = DatabaseFactory.getMmsDatabase(context); + MessageDatabase database = SignalDatabase.mms(); Optional notification = database.getNotification(messageId); if (!notification.isPresent()) { @@ -170,7 +169,7 @@ public class MmsDownloadJob extends BaseJob { @Override public void onFailure() { - MessageDatabase database = DatabaseFactory.getMmsDatabase(context); + MessageDatabase database = SignalDatabase.mms(); database.markDownloadState(messageId, MmsDatabase.Status.DOWNLOAD_SOFT_FAILURE); if (automatic) { @@ -189,7 +188,7 @@ public class MmsDownloadJob extends BaseJob { int subscriptionId, @Nullable RecipientId notificationFrom) throws MmsException { - MessageDatabase database = DatabaseFactory.getMmsDatabase(context); + MessageDatabase database = SignalDatabase.mms(); Optional group = Optional.absent(); Set members = new HashSet<>(); String body = null; @@ -247,7 +246,7 @@ public class MmsDownloadJob extends BaseJob { if (members.size() > 2) { List recipients = new ArrayList<>(members); - group = Optional.of(DatabaseFactory.getGroupDatabase(context).getOrCreateMmsGroupForMembers(recipients)); + group = Optional.of(SignalDatabase.groups().getOrCreateMmsGroupForMembers(recipients)); } IncomingMediaMessage message = new IncomingMediaMessage(from, group, body, TimeUnit.SECONDS.toMillis(retrieved.getDate()), -1, System.currentTimeMillis(), attachments, subscriptionId, 0, false, false, false, Optional.of(sharedContacts)); @@ -261,7 +260,7 @@ public class MmsDownloadJob extends BaseJob { private void handleDownloadError(long messageId, long threadId, int downloadStatus, boolean automatic) { - MessageDatabase db = DatabaseFactory.getMmsDatabase(context); + MessageDatabase db = SignalDatabase.mms(); db.markDownloadState(messageId, downloadStatus); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsReceiveJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsReceiveJob.java index 56ae7951a7..d196d7e519 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsReceiveJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsReceiveJob.java @@ -8,8 +8,8 @@ import com.google.android.mms.pdu_alt.PduHeaders; import com.google.android.mms.pdu_alt.PduParser; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessageDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; @@ -72,7 +72,7 @@ public class MmsReceiveJob extends BaseJob { } if (isNotification(pdu) && !isBlocked(pdu)) { - MessageDatabase database = DatabaseFactory.getMmsDatabase(context); + MessageDatabase database = SignalDatabase.mms(); Pair messageAndThreadId = database.insertMessageInbox((NotificationInd)pdu, subscriptionId); Log.i(TAG, "Inserted received MMS notification..."); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsSendJob.java index 96a1625d57..fb4b8e672f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsSendJob.java @@ -26,10 +26,10 @@ import org.signal.core.util.StreamUtil; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.attachments.DatabaseAttachment; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.MessageDatabase; import org.thoughtcrime.securesms.database.NoSuchMessageException; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; @@ -49,7 +49,6 @@ import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.transport.InsecureFallbackApprovalException; import org.thoughtcrime.securesms.transport.UndeliverableMessageException; import org.thoughtcrime.securesms.util.Hex; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.Util; import java.io.ByteArrayOutputStream; @@ -80,7 +79,7 @@ public final class MmsSendJob extends SendJob { /** Enqueues compression jobs for attachments and finally the MMS send job. */ @WorkerThread public static void enqueue(@NonNull Context context, @NonNull JobManager jobManager, long messageId) { - MessageDatabase database = DatabaseFactory.getMmsDatabase(context); + MessageDatabase database = SignalDatabase.mms(); OutgoingMediaMessage message; try { @@ -117,12 +116,12 @@ public final class MmsSendJob extends SendJob { @Override public void onAdded() { - DatabaseFactory.getMmsDatabase(context).markAsSending(messageId); + SignalDatabase.mms().markAsSending(messageId); } @Override public void onSend() throws MmsException, NoSuchMessageException, IOException { - MessageDatabase database = DatabaseFactory.getMmsDatabase(context); + MessageDatabase database = SignalDatabase.mms(); OutgoingMediaMessage message = database.getOutgoingMessage(messageId); if (database.isSent(messageId)) { @@ -164,7 +163,7 @@ public final class MmsSendJob extends SendJob { @Override public void onFailure() { Log.i(TAG, JobLogger.format(this, "onFailure() messageId: " + messageId)); - DatabaseFactory.getMmsDatabase(context).markAsSentFailed(messageId); + SignalDatabase.mms().markAsSentFailed(messageId); notifyMediaMessageDeliveryFailed(context, messageId); } @@ -240,7 +239,7 @@ public final class MmsSendJob extends SendJob { } if (message.getRecipient().isMmsGroup()) { - List members = DatabaseFactory.getGroupDatabase(context).getGroupMembers(message.getRecipient().requireGroupId(), GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF); + List members = SignalDatabase.groups().getGroupMembers(message.getRecipient().requireGroupId(), GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF); for (Recipient member : members) { if (!member.hasSmsAddress()) { @@ -344,8 +343,8 @@ public final class MmsSendJob extends SendJob { } private void notifyMediaMessageDeliveryFailed(Context context, long messageId) { - long threadId = DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(messageId); - Recipient recipient = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(threadId); + long threadId = SignalDatabase.mms().getThreadIdForMessage(messageId); + Recipient recipient = SignalDatabase.threads().getRecipientForThreadId(threadId); if (recipient != null) { ApplicationDependencies.getMessageNotifier().notifyMessageDeliveryFailed(context, recipient, threadId); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceBlockedUpdateJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceBlockedUpdateJob.java index a3b4738f5c..305bf4d0a4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceBlockedUpdateJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceBlockedUpdateJob.java @@ -4,9 +4,9 @@ import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.RecipientDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientReader; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; @@ -71,7 +71,7 @@ public class MultiDeviceBlockedUpdateJob extends BaseJob { return; } - RecipientDatabase database = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase database = SignalDatabase.recipients(); try (RecipientReader reader = database.readerForBlocked(database.getBlocked())) { List blockedIndividuals = new LinkedList<>(); 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 d6271083ee..69b925f390 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java @@ -15,9 +15,8 @@ import org.signal.zkgroup.profiles.ProfileKey; import org.thoughtcrime.securesms.conversation.colors.ChatColorsMapper; import org.thoughtcrime.securesms.crypto.ProfileKeyUtil; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.IdentityDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.IdentityRecord; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; @@ -147,8 +146,8 @@ public class MultiDeviceContactUpdateJob extends BaseJob { Optional identityRecord = ApplicationDependencies.getIdentityStore().getIdentityRecord(recipient.getId()); Optional verifiedMessage = getVerifiedMessage(recipient, identityRecord); - Map inboxPositions = DatabaseFactory.getThreadDatabase(context).getInboxPositions(); - Set archived = DatabaseFactory.getThreadDatabase(context).getArchivedRecipients(); + Map inboxPositions = SignalDatabase.threads().getInboxPositions(); + Set archived = SignalDatabase.threads().getArchivedRecipients(); out.write(new DeviceContact(RecipientUtil.toSignalServiceAddress(context, recipient), Optional.fromNullable(recipient.isGroup() || recipient.isSystemContact() ? recipient.getDisplayName(context) : null), @@ -199,9 +198,9 @@ public class MultiDeviceContactUpdateJob extends BaseJob { try { DeviceContactsOutputStream out = new DeviceContactsOutputStream(writeDetails.outputStream); - List recipients = DatabaseFactory.getRecipientDatabase(context).getRecipientsForMultiDeviceSync(); - Map inboxPositions = DatabaseFactory.getThreadDatabase(context).getInboxPositions(); - Set archived = DatabaseFactory.getThreadDatabase(context).getArchivedRecipients(); + List recipients = SignalDatabase.recipients().getRecipientsForMultiDeviceSync(); + Map inboxPositions = SignalDatabase.threads().getInboxPositions(); + Set archived = SignalDatabase.threads().getArchivedRecipients(); for (Recipient recipient : recipients) { Optional identity = ApplicationDependencies.getIdentityStore().getIdentityRecord(recipient.getId()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceGroupUpdateJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceGroupUpdateJob.java index 66b5e9b995..fb4150b21a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceGroupUpdateJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceGroupUpdateJob.java @@ -8,8 +8,8 @@ import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.conversation.colors.ChatColorsMapper; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; @@ -91,7 +91,7 @@ public class MultiDeviceGroupUpdateJob extends BaseJob { () -> Log.i(TAG, "Write successful."), e -> Log.w(TAG, "Error during write.", e)); - try (GroupDatabase.Reader reader = DatabaseFactory.getGroupDatabase(context).getGroups()) { + try (GroupDatabase.Reader reader = SignalDatabase.groups().getGroups()) { DeviceGroupsOutputStream out = new DeviceGroupsOutputStream(new ParcelFileDescriptor.AutoCloseOutputStream(pipe[1])); boolean hasData = false; @@ -106,11 +106,11 @@ public class MultiDeviceGroupUpdateJob extends BaseJob { members.add(RecipientUtil.toSignalServiceAddress(context, member)); } - RecipientId recipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromPossiblyMigratedGroupId(record.getId()); + RecipientId recipientId = SignalDatabase.recipients().getOrInsertFromPossiblyMigratedGroupId(record.getId()); Recipient recipient = Recipient.resolved(recipientId); Optional expirationTimer = recipient.getExpiresInSeconds() > 0 ? Optional.of(recipient.getExpiresInSeconds()) : Optional.absent(); - Map inboxPositions = DatabaseFactory.getThreadDatabase(context).getInboxPositions(); - Set archived = DatabaseFactory.getThreadDatabase(context).getArchivedRecipients(); + Map inboxPositions = SignalDatabase.threads().getInboxPositions(); + Set archived = SignalDatabase.threads().getArchivedRecipients(); out.write(new DeviceGroup(record.getId().getDecodedId(), Optional.fromNullable(record.getTitle()), diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceMessageRequestResponseJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceMessageRequestResponseJob.java index 0c47ec831d..2f21e86041 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceMessageRequestResponseJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceMessageRequestResponseJob.java @@ -5,7 +5,6 @@ import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.database.RecipientDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceOutgoingPaymentSyncJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceOutgoingPaymentSyncJob.java index 4b2f498b49..cb9b8988f4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceOutgoingPaymentSyncJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceOutgoingPaymentSyncJob.java @@ -6,8 +6,8 @@ import com.google.protobuf.ByteString; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.PaymentDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; @@ -78,7 +78,7 @@ public final class MultiDeviceOutgoingPaymentSyncJob extends BaseJob { return; } - PaymentDatabase.PaymentTransaction payment = DatabaseFactory.getPaymentDatabase(context).getPayment(uuid); + PaymentDatabase.PaymentTransaction payment = SignalDatabase.payments().getPayment(uuid); if (payment == null) { Log.w(TAG, "Payment not found " + uuid); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceReadUpdateJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceReadUpdateJob.java index 54b78a7f68..5015377a0b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceReadUpdateJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceReadUpdateJob.java @@ -8,7 +8,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; import org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId; -import org.thoughtcrime.securesms.database.RecipientDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceStickerPackSyncJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceStickerPackSyncJob.java index fd8571b10a..a9a8fad7a9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceStickerPackSyncJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceStickerPackSyncJob.java @@ -4,7 +4,7 @@ import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.StickerDatabase.StickerPackRecordReader; import org.thoughtcrime.securesms.database.model.StickerPackRecord; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; @@ -69,7 +69,7 @@ public class MultiDeviceStickerPackSyncJob extends BaseJob { List operations = new LinkedList<>(); - try (StickerPackRecordReader reader = new StickerPackRecordReader(DatabaseFactory.getStickerDatabase(context).getInstalledStickerPacks())) { + try (StickerPackRecordReader reader = new StickerPackRecordReader(SignalDatabase.stickers().getInstalledStickerPacks())) { StickerPackRecord pack; while ((pack = reader.getNext()) != null) { byte[] packIdBytes = Hex.fromStringCondensed(pack.getPackId()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceVerifiedUpdateJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceVerifiedUpdateJob.java index 0373a4096f..144586df3e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceVerifiedUpdateJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceVerifiedUpdateJob.java @@ -6,7 +6,6 @@ import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; import org.thoughtcrime.securesms.database.IdentityDatabase.VerifiedStatus; -import org.thoughtcrime.securesms.database.RecipientDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceViewOnceOpenJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceViewOnceOpenJob.java index faa8316a43..d112f8c491 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceViewOnceOpenJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceViewOnceOpenJob.java @@ -7,7 +7,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; import org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId; -import org.thoughtcrime.securesms.database.RecipientDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceViewedUpdateJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceViewedUpdateJob.java index 5c0951849e..ca9b100bf8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceViewedUpdateJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceViewedUpdateJob.java @@ -8,7 +8,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; import org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId; -import org.thoughtcrime.securesms.database.RecipientDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/NullMessageSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/NullMessageSendJob.java index 82cadc60db..7ba48af7f3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/NullMessageSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/NullMessageSendJob.java @@ -4,7 +4,6 @@ import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.database.RecipientDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PaymentLedgerUpdateJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PaymentLedgerUpdateJob.java index 05b958d4d6..f6d247493d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PaymentLedgerUpdateJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PaymentLedgerUpdateJob.java @@ -4,8 +4,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.PaymentDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; @@ -62,8 +62,8 @@ public final class PaymentLedgerUpdateJob extends BaseJob { Long minimumBlockIndex = null; if (paymentUuid != null) { - PaymentDatabase.PaymentTransaction payment = DatabaseFactory.getPaymentDatabase(context) - .getPayment(paymentUuid); + PaymentDatabase.PaymentTransaction payment = SignalDatabase.payments() + .getPayment(paymentUuid); if (payment != null) { minimumBlockIndex = payment.getBlockIndex(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PaymentNotificationSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PaymentNotificationSendJob.java index 89ddc3d32e..ba594e223d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PaymentNotificationSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PaymentNotificationSendJob.java @@ -4,8 +4,8 @@ import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.PaymentDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; @@ -82,7 +82,7 @@ public final class PaymentNotificationSendJob extends BaseJob { throw new NotPushRegisteredException(); } - PaymentDatabase paymentDatabase = DatabaseFactory.getPaymentDatabase(context); + PaymentDatabase paymentDatabase = SignalDatabase.payments(); Recipient recipient = Recipient.resolved(recipientId); if (recipient.isUnregistered()) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PaymentSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PaymentSendJob.java index 296fa77aa3..8644298ec4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PaymentSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PaymentSendJob.java @@ -5,8 +5,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.PaymentDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; @@ -136,7 +136,7 @@ public final class PaymentSendJob extends BaseJob { Stopwatch stopwatch = new Stopwatch("Payment submission"); Wallet wallet = ApplicationDependencies.getPayments().getWallet(); - PaymentDatabase paymentDatabase = DatabaseFactory.getPaymentDatabase(context); + PaymentDatabase paymentDatabase = SignalDatabase.payments(); paymentDatabase.createOutgoingPayment(uuid, recipientId, diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PaymentTransactionCheckJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PaymentTransactionCheckJob.java index e7a587864a..a325a09b64 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PaymentTransactionCheckJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PaymentTransactionCheckJob.java @@ -3,8 +3,8 @@ package org.thoughtcrime.securesms.jobs; import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.PaymentDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; @@ -52,7 +52,7 @@ public final class PaymentTransactionCheckJob extends BaseJob { @Override protected void onRun() throws Exception { - PaymentDatabase paymentDatabase = DatabaseFactory.getPaymentDatabase(context); + PaymentDatabase paymentDatabase = SignalDatabase.payments(); PaymentDatabase.PaymentTransaction payment = paymentDatabase.getPayment(uuid); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/ProfileKeySendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/ProfileKeySendJob.java index 0c6669c060..c947dd7e51 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/ProfileKeySendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/ProfileKeySendJob.java @@ -8,9 +8,7 @@ import androidx.annotation.WorkerThread; import com.annimon.stream.Stream; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.jobmanager.impl.DecryptionsDrainedConstraint; @@ -21,15 +19,10 @@ import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.recipients.RecipientUtil; import org.thoughtcrime.securesms.transport.RetryLaterException; -import org.whispersystems.libsignal.util.guava.Optional; -import org.whispersystems.signalservice.api.SignalServiceMessageSender; import org.whispersystems.signalservice.api.crypto.ContentHint; -import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair; import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException; import org.whispersystems.signalservice.api.messages.SendMessageResult; import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage; -import org.whispersystems.signalservice.api.messages.SignalServiceGroup; -import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException; import java.io.IOException; @@ -55,7 +48,7 @@ public class ProfileKeySendJob extends BaseJob { */ @WorkerThread public static ProfileKeySendJob create(@NonNull Context context, long threadId, boolean queueLimits) { - Recipient conversationRecipient = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(threadId); + Recipient conversationRecipient = SignalDatabase.threads().getRecipientForThreadId(threadId); if (conversationRecipient == null) { throw new AssertionError("We have a thread but no recipient!"); @@ -100,7 +93,7 @@ public class ProfileKeySendJob extends BaseJob { throw new NotPushRegisteredException(); } - Recipient conversationRecipient = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(threadId); + Recipient conversationRecipient = SignalDatabase.threads().getRecipientForThreadId(threadId); if (conversationRecipient == null) { Log.w(TAG, "Thread no longer present"); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/ProfileUploadJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/ProfileUploadJob.java index ac38d61fe9..b96f3f74e1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/ProfileUploadJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/ProfileUploadJob.java @@ -9,7 +9,6 @@ import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.util.ProfileUtil; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import java.util.concurrent.TimeUnit; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java index 247d97fb66..b0cc51a3d1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java @@ -12,13 +12,13 @@ import com.google.protobuf.ByteString; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.attachments.Attachment; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.GroupReceiptDatabase; import org.thoughtcrime.securesms.database.GroupReceiptDatabase.GroupReceiptInfo; import org.thoughtcrime.securesms.database.MessageDatabase; import org.thoughtcrime.securesms.database.NoSuchMessageException; import org.thoughtcrime.securesms.database.RecipientDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch; import org.thoughtcrime.securesms.database.documents.NetworkFailure; import org.thoughtcrime.securesms.database.model.MessageId; @@ -106,11 +106,11 @@ public final class PushGroupSendJob extends PushSendJob { throw new AssertionError("Not a group!"); } - MessageDatabase database = DatabaseFactory.getMmsDatabase(context); + MessageDatabase database = SignalDatabase.mms(); OutgoingMediaMessage message = database.getOutgoingMessage(messageId); Set attachmentUploadIds = enqueueCompressingAndUploadAttachmentsChains(jobManager, message); - if (!DatabaseFactory.getGroupDatabase(context).isActive(group.requireGroupId()) && !isGv2UpdateMessage(message)) { + if (!SignalDatabase.groups().isActive(group.requireGroupId()) && !isGv2UpdateMessage(message)) { throw new MmsException("Inactive group!"); } @@ -118,7 +118,7 @@ public final class PushGroupSendJob extends PushSendJob { } catch (NoSuchMessageException | MmsException e) { Log.w(TAG, "Failed to enqueue message.", e); - DatabaseFactory.getMmsDatabase(context).markAsSentFailed(messageId); + SignalDatabase.mms().markAsSentFailed(messageId); notifyMediaMessageDeliveryFailed(context, messageId); } } @@ -141,7 +141,7 @@ public final class PushGroupSendJob extends PushSendJob { @Override public void onAdded() { - DatabaseFactory.getMmsDatabase(context).markAsSending(messageId); + SignalDatabase.mms().markAsSending(messageId); } @Override @@ -150,7 +150,7 @@ public final class PushGroupSendJob extends PushSendJob { { SignalLocalMetrics.GroupMessageSend.onJobStarted(messageId); - MessageDatabase database = DatabaseFactory.getMmsDatabase(context); + MessageDatabase database = SignalDatabase.mms(); OutgoingMediaMessage message = database.getOutgoingMessage(messageId); long threadId = database.getMessageRecord(messageId).getThreadId(); Set existingNetworkFailures = message.getNetworkFailures(); @@ -201,7 +201,7 @@ public final class PushGroupSendJob extends PushSendJob { List resolvedIdentityFailures = Stream.of(existingIdentityMismatches).filter(failure -> successIds.contains(failure.getRecipientId(context))).toList(); List unregisteredRecipients = Stream.of(results).filter(SendMessageResult::isUnregisteredFailure).map(result -> Recipient.externalPush(context, result.getAddress())).toList(); - RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase recipientDatabase = SignalDatabase.recipients(); for (Recipient unregistered : unregisteredRecipients) { recipientDatabase.markUnregistered(unregistered.getId()); } @@ -212,7 +212,7 @@ public final class PushGroupSendJob extends PushSendJob { existingIdentityMismatches.removeAll(resolvedIdentityFailures); database.setMismatchedIdentities(messageId, existingIdentityMismatches); - DatabaseFactory.getGroupReceiptDatabase(context).setUnidentified(successUnidentifiedStatus, messageId); + SignalDatabase.groupReceipts().setUnidentified(successUnidentifiedStatus, messageId); if (proofRequired != null) { handleProofRequiredException(proofRequired, groupRecipient, threadId, messageId, true); @@ -230,7 +230,7 @@ public final class PushGroupSendJob extends PushSendJob { } if (message.isViewOnce()) { - DatabaseFactory.getAttachmentDatabase(context).deleteAttachmentFilesForViewOnceMessage(messageId); + SignalDatabase.attachments().deleteAttachmentFilesForViewOnceMessage(messageId); } } else if (!identityMismatches.isEmpty()) { Log.w(TAG, "Failing because there were " + identityMismatches.size() + " identity mismatches."); @@ -263,7 +263,7 @@ public final class PushGroupSendJob extends PushSendJob { @Override public void onFailure() { - DatabaseFactory.getMmsDatabase(context).markAsSentFailed(messageId); + SignalDatabase.mms().markAsSentFailed(messageId); } private List deliver(OutgoingMediaMessage message, @NonNull Recipient groupRecipient, @NonNull List destinations) @@ -281,7 +281,7 @@ public final class PushGroupSendJob extends PushSendJob { List mentions = getMentionsFor(message.getMentions()); List attachments = Stream.of(message.getAttachments()).filterNot(Attachment::isSticker).toList(); List attachmentPointers = getAttachmentPointersFor(attachments); - boolean isRecipientUpdate = Stream.of(DatabaseFactory.getGroupReceiptDatabase(context).getGroupReceiptInfo(messageId)) + boolean isRecipientUpdate = Stream.of(SignalDatabase.groupReceipts().getGroupReceiptInfo(messageId)) .anyMatch(info -> info.getStatus() > GroupReceiptDatabase.STATUS_UNDELIVERED); if (message.isGroup()) { @@ -309,7 +309,7 @@ public final class PushGroupSendJob extends PushSendJob { throw new UndeliverableMessageException("Messages can no longer be sent to V1 groups!"); } } else { - Optional groupRecord = DatabaseFactory.getGroupDatabase(context).getGroup(groupRecipient.requireGroupId()); + Optional groupRecord = SignalDatabase.groups().getGroup(groupRecipient.requireGroupId()); if (groupRecord.isPresent() && groupRecord.get().isAnnouncementGroup() && !groupRecord.get().isAdmin(Recipient.self())) { throw new UndeliverableMessageException("Non-admins cannot send messages in announcement groups!"); @@ -349,7 +349,7 @@ public final class PushGroupSendJob extends PushSendJob { } private @NonNull List getGroupMessageRecipients(@NonNull GroupId groupId, long messageId) { - List destinations = DatabaseFactory.getGroupReceiptDatabase(context).getGroupReceiptInfo(messageId); + List destinations = SignalDatabase.groupReceipts().getGroupReceiptInfo(messageId); if (!destinations.isEmpty()) { return RecipientUtil.getEligibleForSending(Stream.of(destinations) @@ -358,8 +358,7 @@ public final class PushGroupSendJob extends PushSendJob { .toList()); } - List members = Stream.of(DatabaseFactory.getGroupDatabase(context) - .getGroupMembers(groupId, GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF)) + List members = Stream.of(SignalDatabase.groups().getGroupMembers(groupId, GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF)) .map(Recipient::resolve) .toList(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushGroupUpdateJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushGroupUpdateJob.java index c5c0cf0afb..8f0043efa4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushGroupUpdateJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushGroupUpdateJob.java @@ -5,9 +5,9 @@ import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.jobmanager.Data; @@ -90,7 +90,7 @@ public class PushGroupUpdateJob extends BaseJob { return; } - GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); + GroupDatabase groupDatabase = SignalDatabase.groups(); Optional record = groupDatabase.getGroup(groupId); SignalServiceAttachment avatar = null; @@ -124,7 +124,7 @@ public class PushGroupUpdateJob extends BaseJob { .withName(record.get().getTitle()) .build(); - RecipientId groupRecipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupId); + RecipientId groupRecipientId = SignalDatabase.recipients().getOrInsertFromGroupId(groupId); Recipient groupRecipient = Recipient.resolved(groupRecipientId); SignalServiceDataMessage message = SignalServiceDataMessage.newBuilder() diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java index 7d05d48c24..a69b1f2053 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java @@ -10,11 +10,11 @@ import com.annimon.stream.Stream; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessageDatabase; import org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId; import org.thoughtcrime.securesms.database.NoSuchMessageException; import org.thoughtcrime.securesms.database.RecipientDatabase.UnidentifiedAccessMode; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.MessageId; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; @@ -30,7 +30,6 @@ import org.thoughtcrime.securesms.service.ExpiringMessageManager; import org.thoughtcrime.securesms.transport.InsecureFallbackApprovalException; import org.thoughtcrime.securesms.transport.RetryLaterException; import org.thoughtcrime.securesms.transport.UndeliverableMessageException; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.Util; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.SignalServiceMessageSender; @@ -80,7 +79,7 @@ public class PushMediaSendJob extends PushSendJob { throw new AssertionError(); } - MessageDatabase database = DatabaseFactory.getMmsDatabase(context); + MessageDatabase database = SignalDatabase.mms(); OutgoingMediaMessage message = database.getOutgoingMessage(messageId); Set attachmentUploadIds = enqueueCompressingAndUploadAttachmentsChains(jobManager, message); @@ -88,7 +87,7 @@ public class PushMediaSendJob extends PushSendJob { } catch (NoSuchMessageException | MmsException e) { Log.w(TAG, "Failed to enqueue message.", e); - DatabaseFactory.getMmsDatabase(context).markAsSentFailed(messageId); + SignalDatabase.mms().markAsSentFailed(messageId); notifyMediaMessageDeliveryFailed(context, messageId); } } @@ -105,7 +104,7 @@ public class PushMediaSendJob extends PushSendJob { @Override public void onAdded() { - DatabaseFactory.getMmsDatabase(context).markAsSending(messageId); + SignalDatabase.mms().markAsSending(messageId); } @Override @@ -113,7 +112,7 @@ public class PushMediaSendJob extends PushSendJob { throws IOException, MmsException, NoSuchMessageException, UndeliverableMessageException, RetryLaterException { ExpiringMessageManager expirationManager = ApplicationDependencies.getExpiringMessageManager(); - MessageDatabase database = DatabaseFactory.getMmsDatabase(context); + MessageDatabase database = SignalDatabase.mms(); OutgoingMediaMessage message = database.getOutgoingMessage(messageId); long threadId = database.getMessageRecord(messageId).getThreadId(); @@ -139,20 +138,20 @@ public class PushMediaSendJob extends PushSendJob { if (recipient.isSelf()) { SyncMessageId id = new SyncMessageId(recipient.getId(), message.getSentTimeMillis()); - DatabaseFactory.getMmsSmsDatabase(context).incrementDeliveryReceiptCount(id, System.currentTimeMillis()); - DatabaseFactory.getMmsSmsDatabase(context).incrementReadReceiptCount(id, System.currentTimeMillis()); - DatabaseFactory.getMmsSmsDatabase(context).incrementViewedReceiptCount(id, System.currentTimeMillis()); + SignalDatabase.mmsSms().incrementDeliveryReceiptCount(id, System.currentTimeMillis()); + SignalDatabase.mmsSms().incrementReadReceiptCount(id, System.currentTimeMillis()); + SignalDatabase.mmsSms().incrementViewedReceiptCount(id, System.currentTimeMillis()); } if (unidentified && accessMode == UnidentifiedAccessMode.UNKNOWN && profileKey == null) { log(TAG, String.valueOf(message.getSentTimeMillis()), "Marking recipient as UD-unrestricted following a UD send."); - DatabaseFactory.getRecipientDatabase(context).setUnidentifiedAccessMode(recipient.getId(), UnidentifiedAccessMode.UNRESTRICTED); + SignalDatabase.recipients().setUnidentifiedAccessMode(recipient.getId(), UnidentifiedAccessMode.UNRESTRICTED); } else if (unidentified && accessMode == UnidentifiedAccessMode.UNKNOWN) { log(TAG, String.valueOf(message.getSentTimeMillis()), "Marking recipient as UD-enabled following a UD send."); - DatabaseFactory.getRecipientDatabase(context).setUnidentifiedAccessMode(recipient.getId(), UnidentifiedAccessMode.ENABLED); + SignalDatabase.recipients().setUnidentifiedAccessMode(recipient.getId(), UnidentifiedAccessMode.ENABLED); } else if (!unidentified && accessMode != UnidentifiedAccessMode.DISABLED) { log(TAG, String.valueOf(message.getSentTimeMillis()), "Marking recipient as UD-disabled following a non-UD send."); - DatabaseFactory.getRecipientDatabase(context).setUnidentifiedAccessMode(recipient.getId(), UnidentifiedAccessMode.DISABLED); + SignalDatabase.recipients().setUnidentifiedAccessMode(recipient.getId(), UnidentifiedAccessMode.DISABLED); } if (message.getExpiresIn() > 0 && !message.isExpirationUpdate()) { @@ -161,7 +160,7 @@ public class PushMediaSendJob extends PushSendJob { } if (message.isViewOnce()) { - DatabaseFactory.getAttachmentDatabase(context).deleteAttachmentFilesForViewOnceMessage(messageId); + SignalDatabase.attachments().deleteAttachmentFilesForViewOnceMessage(messageId); } log(TAG, String.valueOf(message.getSentTimeMillis()), "Sent message: " + messageId); @@ -178,13 +177,13 @@ public class PushMediaSendJob extends PushSendJob { database.markAsSentFailed(messageId); RetrieveProfileJob.enqueue(recipientId); } catch (ProofRequiredException e) { - handleProofRequiredException(e, DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(threadId), threadId, messageId, true); + handleProofRequiredException(e, SignalDatabase.threads().getRecipientForThreadId(threadId), threadId, messageId, true); } } @Override public void onFailure() { - DatabaseFactory.getMmsDatabase(context).markAsSentFailed(messageId); + SignalDatabase.mms().markAsSentFailed(messageId); notifyMediaMessageDeliveryFailed(context, messageId); } @@ -232,11 +231,11 @@ public class PushMediaSendJob extends PushSendJob { SignalServiceSyncMessage syncMessage = buildSelfSendSyncMessage(context, mediaMessage, syncAccess); SendMessageResult result = messageSender.sendSyncMessage(syncMessage, syncAccess); - DatabaseFactory.getMessageLogDatabase(context).insertIfPossible(messageRecipient.getId(), message.getSentTimeMillis(), result, ContentHint.RESENDABLE, new MessageId(messageId, true)); + SignalDatabase.messageLog().insertIfPossible(messageRecipient.getId(), message.getSentTimeMillis(), result, ContentHint.RESENDABLE, new MessageId(messageId, true)); return syncAccess.isPresent(); } else { SendMessageResult result = messageSender.sendDataMessage(address, UnidentifiedAccessUtil.getAccessFor(context, messageRecipient), ContentHint.RESENDABLE, mediaMessage, IndividualSendEvents.EMPTY); - DatabaseFactory.getMessageLogDatabase(context).insertIfPossible(messageRecipient.getId(), message.getSentTimeMillis(), result, ContentHint.RESENDABLE, new MessageId(messageId, true)); + SignalDatabase.messageLog().insertIfPossible(messageRecipient.getId(), message.getSentTimeMillis(), result, ContentHint.RESENDABLE, new MessageId(messageId, true)); return result.getSuccess().isUnidentified(); } } catch (UnregisteredUserException e) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushProcessMessageJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushProcessMessageJob.java index 060f7fd0e9..9187dd0932 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushProcessMessageJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushProcessMessageJob.java @@ -7,7 +7,7 @@ import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.BadGroupIdException; import org.thoughtcrime.securesms.groups.GroupChangeBusyException; @@ -129,11 +129,10 @@ public final class PushProcessMessageJob extends BaseJob { queueName = getQueueName(Recipient.externalPossiblyMigratedGroup(context, groupId).getId()); if (groupId.isV2()) { - int localRevision = DatabaseFactory.getGroupDatabase(context) - .getGroupV2Revision(groupId.requireV2()); + int localRevision = SignalDatabase.groups().getGroupV2Revision(groupId.requireV2()); if (signalServiceGroupContext.getGroupV2().get().getRevision() > localRevision || - DatabaseFactory.getGroupDatabase(context).getGroupV1ByExpectedV2(groupId.requireV2()).isPresent()) + SignalDatabase.groups().getGroupV1ByExpectedV2(groupId.requireV2()).isPresent()) { Log.i(TAG, "Adding network constraint to group-related job."); builder.addConstraint(NetworkConstraint.KEY) diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java index f585493e02..790399871c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java @@ -23,7 +23,7 @@ import org.thoughtcrime.securesms.blurhash.BlurHash; import org.thoughtcrime.securesms.contactshare.Contact; import org.thoughtcrime.securesms.contactshare.ContactModelMapper; import org.thoughtcrime.securesms.crypto.ProfileKeyUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.Mention; import org.thoughtcrime.securesms.database.model.StickerRecord; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; @@ -289,8 +289,8 @@ public abstract class PushSendJob extends SendJob { } protected static void notifyMediaMessageDeliveryFailed(Context context, long messageId) { - long threadId = DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(messageId); - Recipient recipient = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(threadId); + long threadId = SignalDatabase.mms().getThreadIdForMessage(messageId); + Recipient recipient = SignalDatabase.threads().getRecipientForThreadId(threadId); if (threadId != -1 && recipient != null) { ApplicationDependencies.getMessageNotifier().notifyMessageDeliveryFailed(context, recipient, threadId); @@ -369,7 +369,7 @@ public abstract class PushSendJob extends SendJob { byte[] packId = Hex.fromStringCondensed(stickerAttachment.getSticker().getPackId()); byte[] packKey = Hex.fromStringCondensed(stickerAttachment.getSticker().getPackKey()); int stickerId = stickerAttachment.getSticker().getStickerId(); - StickerRecord record = DatabaseFactory.getStickerDatabase(context).getSticker(stickerAttachment.getSticker().getPackId(), stickerId, false); + StickerRecord record = SignalDatabase.stickers().getSticker(stickerAttachment.getSticker().getPackId(), stickerId, false); String emoji = record != null ? record.getEmoji() : null; SignalServiceAttachment attachment = getAttachmentPointerFor(stickerAttachment); @@ -485,9 +485,9 @@ public abstract class PushSendJob extends SendJob { warn(TAG, "[Proof Required] Marking message as rate-limited. (id: " + messageId + ", mms: " + isMms + ", thread: " + threadId + ")"); if (isMms) { - DatabaseFactory.getMmsDatabase(context).markAsRateLimited(messageId); + SignalDatabase.mms().markAsRateLimited(messageId); } else { - DatabaseFactory.getSmsDatabase(context).markAsRateLimited(messageId); + SignalDatabase.sms().markAsRateLimited(messageId); } if (proofRequired.getOptions().contains(ProofRequiredException.Option.RECAPTCHA)) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushTextSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushTextSendJob.java index f2bf64845a..4bbbf79c09 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushTextSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushTextSendJob.java @@ -4,11 +4,11 @@ import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessageDatabase; import org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId; import org.thoughtcrime.securesms.database.NoSuchMessageException; import org.thoughtcrime.securesms.database.RecipientDatabase.UnidentifiedAccessMode; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.MessageId; import org.thoughtcrime.securesms.database.model.SmsMessageRecord; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; @@ -23,7 +23,6 @@ import org.thoughtcrime.securesms.transport.InsecureFallbackApprovalException; import org.thoughtcrime.securesms.transport.RetryLaterException; import org.thoughtcrime.securesms.transport.UndeliverableMessageException; import org.thoughtcrime.securesms.util.SignalLocalMetrics; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.Util; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.SignalServiceMessageSender; @@ -71,7 +70,7 @@ public class PushTextSendJob extends PushSendJob { @Override public void onAdded() { - DatabaseFactory.getSmsDatabase(context).markAsSending(messageId); + SignalDatabase.sms().markAsSending(messageId); } @Override @@ -79,7 +78,7 @@ public class PushTextSendJob extends PushSendJob { SignalLocalMetrics.IndividualMessageSend.onJobStarted(messageId); ExpiringMessageManager expirationManager = ApplicationDependencies.getExpiringMessageManager(); - MessageDatabase database = DatabaseFactory.getSmsDatabase(context); + MessageDatabase database = SignalDatabase.sms(); SmsMessageRecord record = database.getSmsMessage(messageId); if (!record.isPending() && !record.isFailed()) { @@ -103,19 +102,19 @@ public class PushTextSendJob extends PushSendJob { if (recipient.isSelf()) { SyncMessageId id = new SyncMessageId(recipient.getId(), record.getDateSent()); - DatabaseFactory.getMmsSmsDatabase(context).incrementDeliveryReceiptCount(id, System.currentTimeMillis()); - DatabaseFactory.getMmsSmsDatabase(context).incrementReadReceiptCount(id, System.currentTimeMillis()); + SignalDatabase.mmsSms().incrementDeliveryReceiptCount(id, System.currentTimeMillis()); + SignalDatabase.mmsSms().incrementReadReceiptCount(id, System.currentTimeMillis()); } if (unidentified && accessMode == UnidentifiedAccessMode.UNKNOWN && profileKey == null) { log(TAG, String.valueOf(record.getDateSent()), "Marking recipient as UD-unrestricted following a UD send."); - DatabaseFactory.getRecipientDatabase(context).setUnidentifiedAccessMode(recipient.getId(), UnidentifiedAccessMode.UNRESTRICTED); + SignalDatabase.recipients().setUnidentifiedAccessMode(recipient.getId(), UnidentifiedAccessMode.UNRESTRICTED); } else if (unidentified && accessMode == UnidentifiedAccessMode.UNKNOWN) { log(TAG, String.valueOf(record.getDateSent()), "Marking recipient as UD-enabled following a UD send."); - DatabaseFactory.getRecipientDatabase(context).setUnidentifiedAccessMode(recipient.getId(), UnidentifiedAccessMode.ENABLED); + SignalDatabase.recipients().setUnidentifiedAccessMode(recipient.getId(), UnidentifiedAccessMode.ENABLED); } else if (!unidentified && accessMode != UnidentifiedAccessMode.DISABLED) { log(TAG, String.valueOf(record.getDateSent()), "Marking recipient as UD-disabled following a non-UD send."); - DatabaseFactory.getRecipientDatabase(context).setUnidentifiedAccessMode(recipient.getId(), UnidentifiedAccessMode.DISABLED); + SignalDatabase.recipients().setUnidentifiedAccessMode(recipient.getId(), UnidentifiedAccessMode.DISABLED); } if (record.getExpiresIn() > 0) { @@ -152,10 +151,10 @@ public class PushTextSendJob extends PushSendJob { @Override public void onFailure() { - DatabaseFactory.getSmsDatabase(context).markAsSentFailed(messageId); + SignalDatabase.sms().markAsSentFailed(messageId); - long threadId = DatabaseFactory.getSmsDatabase(context).getThreadIdForMessage(messageId); - Recipient recipient = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(threadId); + long threadId = SignalDatabase.sms().getThreadIdForMessage(messageId); + Recipient recipient = SignalDatabase.threads().getRecipientForThreadId(threadId); if (threadId != -1 && recipient != null) { ApplicationDependencies.getMessageNotifier().notifyMessageDeliveryFailed(context, recipient, threadId); @@ -196,13 +195,13 @@ public class PushTextSendJob extends PushSendJob { SignalLocalMetrics.IndividualMessageSend.onDeliveryStarted(messageId); SendMessageResult result = messageSender.sendSyncMessage(syncMessage, syncAccess); - DatabaseFactory.getMessageLogDatabase(context).insertIfPossible(messageRecipient.getId(), message.getDateSent(), result, ContentHint.RESENDABLE, new MessageId(messageId, false)); + SignalDatabase.messageLog().insertIfPossible(messageRecipient.getId(), message.getDateSent(), result, ContentHint.RESENDABLE, new MessageId(messageId, false)); return syncAccess.isPresent(); } else { SignalLocalMetrics.IndividualMessageSend.onDeliveryStarted(messageId); SendMessageResult result = messageSender.sendDataMessage(address, unidentifiedAccess, ContentHint.RESENDABLE, textSecureMessage, new MetricEventListener(messageId)); - DatabaseFactory.getMessageLogDatabase(context).insertIfPossible(messageRecipient.getId(), message.getDateSent(), result, ContentHint.RESENDABLE, new MessageId(messageId, false)); + SignalDatabase.messageLog().insertIfPossible(messageRecipient.getId(), message.getDateSent(), result, ContentHint.RESENDABLE, new MessageId(messageId, false)); return result.getSuccess().isUnidentified(); } } catch (UnregisteredUserException e) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/ReactionSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/ReactionSendJob.java index aaff470dff..6de5a80ae4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/ReactionSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/ReactionSendJob.java @@ -6,18 +6,17 @@ import androidx.annotation.NonNull; import androidx.annotation.WorkerThread; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.MessageDatabase; import org.thoughtcrime.securesms.database.NoSuchMessageException; import org.thoughtcrime.securesms.database.ReactionDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.MessageId; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.database.model.ReactionRecord; import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.net.NotPushRegisteredException; import org.thoughtcrime.securesms.messages.GroupSendUtil; +import org.thoughtcrime.securesms.net.NotPushRegisteredException; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.recipients.RecipientUtil; @@ -65,10 +64,10 @@ public class ReactionSendJob extends BaseJob { boolean remove) throws NoSuchMessageException { - MessageRecord message = messageId.isMms() ? DatabaseFactory.getMmsDatabase(context).getMessageRecord(messageId.getId()) - : DatabaseFactory.getSmsDatabase(context).getSmsMessage(messageId.getId()); + MessageRecord message = messageId.isMms() ? SignalDatabase.mms().getMessageRecord(messageId.getId()) + : SignalDatabase.sms().getSmsMessage(messageId.getId()); - Recipient conversationRecipient = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(message.getThreadId()); + Recipient conversationRecipient = SignalDatabase.threads().getRecipientForThreadId(message.getThreadId()); if (conversationRecipient == null) { throw new AssertionError("We have a message, but couldn't find the thread!"); @@ -135,14 +134,14 @@ public class ReactionSendJob extends BaseJob { throw new NotPushRegisteredException(); } - ReactionDatabase reactionDatabase = DatabaseFactory.getReactionDatabase(context); + ReactionDatabase reactionDatabase = SignalDatabase.reactions(); MessageRecord message; if (messageId.isMms()) { - message = DatabaseFactory.getMmsDatabase(context).getMessageRecord(messageId.getId()); + message = SignalDatabase.mms().getMessageRecord(messageId.getId()); } else { - message = DatabaseFactory.getSmsDatabase(context).getSmsMessage(messageId.getId()); + message = SignalDatabase.sms().getSmsMessage(messageId.getId()); } Recipient targetAuthor = message.isOutgoing() ? Recipient.self() : message.getIndividualRecipient(); @@ -158,7 +157,7 @@ public class ReactionSendJob extends BaseJob { return; } - Recipient conversationRecipient = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(message.getThreadId()); + Recipient conversationRecipient = SignalDatabase.threads().getRecipientForThreadId(message.getThreadId()); if (conversationRecipient == null) { throw new AssertionError("We have a message, but couldn't find the thread!"); @@ -202,7 +201,7 @@ public class ReactionSendJob extends BaseJob { Log.w(TAG, "Failed to send the reaction to all recipients!"); - ReactionDatabase reactionDatabase = DatabaseFactory.getReactionDatabase(context); + ReactionDatabase reactionDatabase = SignalDatabase.reactions(); if (remove && !reactionDatabase.hasReaction(messageId, reaction)) { Log.w(TAG, "Reaction removal failed, so adding the reaction back."); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RecipientChangedNumberJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/RecipientChangedNumberJob.kt index 3ef284e53e..35811f99c2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RecipientChangedNumberJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RecipientChangedNumberJob.kt @@ -1,7 +1,7 @@ package org.thoughtcrime.securesms.jobs import org.signal.core.util.logging.Log -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.jobmanager.Data import org.thoughtcrime.securesms.jobmanager.Job import org.thoughtcrime.securesms.recipients.Recipient @@ -32,7 +32,7 @@ class RecipientChangedNumberJob(parameters: Parameters, private val recipientId: if (!recipient.isBlocked && !recipient.isGroup && !recipient.isSelf) { Log.i(TAG, "Writing a number change event.") - DatabaseFactory.getSmsDatabase(context).insertNumberChangeMessages(recipient) + SignalDatabase.sms.insertNumberChangeMessages(recipient) } else { Log.i(TAG, "Number changed but not relevant. blocked: ${recipient.isBlocked} isGroup: ${recipient.isGroup} isSelf: ${recipient.isSelf}") } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshOwnProfileJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshOwnProfileJob.java index f6df2fae34..6aa23ec53e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshOwnProfileJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshOwnProfileJob.java @@ -12,8 +12,8 @@ import org.thoughtcrime.securesms.badges.BadgeRepository; import org.thoughtcrime.securesms.badges.Badges; import org.thoughtcrime.securesms.badges.models.Badge; import org.thoughtcrime.securesms.crypto.ProfileKeyUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.RecipientDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; @@ -22,7 +22,6 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.profiles.ProfileName; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.util.ProfileUtil; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.Util; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.crypto.InvalidCiphertextException; @@ -31,7 +30,6 @@ import org.whispersystems.signalservice.api.profiles.SignalServiceProfile; import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException; import java.io.IOException; -import java.sql.Ref; import java.util.Comparator; import java.util.List; import java.util.Objects; @@ -110,7 +108,7 @@ public class RefreshOwnProfileJob extends BaseJob { @NonNull ProfileKey recipientProfileKey, @NonNull ProfileKeyCredential credential) { - RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase recipientDatabase = SignalDatabase.recipients(); recipientDatabase.setProfileKeyCredential(recipient.getId(), recipientProfileKey, credential); } @@ -135,7 +133,7 @@ public class RefreshOwnProfileJob extends BaseJob { ProfileName profileName = ProfileName.fromSerialized(plaintextName); Log.d(TAG, "Saving " + (!Util.isEmpty(plaintextName) ? "non-" : "") + "empty name."); - DatabaseFactory.getRecipientDatabase(context).setProfileName(Recipient.self().getId(), profileName); + SignalDatabase.recipients().setProfileName(Recipient.self().getId(), profileName); } catch (InvalidCiphertextException | IOException e) { Log.w(TAG, e); } @@ -150,7 +148,7 @@ public class RefreshOwnProfileJob extends BaseJob { Log.d(TAG, "Saving " + (!Util.isEmpty(plaintextAbout) ? "non-" : "") + "empty about."); Log.d(TAG, "Saving " + (!Util.isEmpty(plaintextEmoji) ? "non-" : "") + "empty emoji."); - DatabaseFactory.getRecipientDatabase(context).setAbout(Recipient.self().getId(), plaintextAbout, plaintextEmoji); + SignalDatabase.recipients().setAbout(Recipient.self().getId(), plaintextAbout, plaintextEmoji); } catch (InvalidCiphertextException | IOException e) { Log.w(TAG, e); } @@ -166,7 +164,7 @@ public class RefreshOwnProfileJob extends BaseJob { return; } - DatabaseFactory.getRecipientDatabase(context).setCapabilities(Recipient.self().getId(), capabilities); + SignalDatabase.recipients().setCapabilities(Recipient.self().getId(), capabilities); } private void setProfileBadges(@Nullable List badges) { @@ -229,8 +227,7 @@ public class RefreshOwnProfileJob extends BaseJob { BadgeRepository badgeRepository = new BadgeRepository(context); badgeRepository.setVisibilityForAllBadges(displayBadgesOnProfile, appBadges).blockingSubscribe(); } else { - DatabaseFactory.getRecipientDatabase(context) - .setBadges(Recipient.self().getId(), appBadges); + SignalDatabase.recipients().setBadges(Recipient.self().getId(), appBadges); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RemoteConfigRefreshJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/RemoteConfigRefreshJob.java index 94c2fd3e25..5128fdceba 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RemoteConfigRefreshJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RemoteConfigRefreshJob.java @@ -9,7 +9,6 @@ import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.util.FeatureFlags; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException; import java.util.Map; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RemoteDeleteSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/RemoteDeleteSendJob.java index 0b320a30d8..41090b683c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RemoteDeleteSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RemoteDeleteSendJob.java @@ -8,31 +8,25 @@ import androidx.annotation.WorkerThread; import com.annimon.stream.Stream; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessageDatabase; import org.thoughtcrime.securesms.database.NoSuchMessageException; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.MessageId; import org.thoughtcrime.securesms.database.model.MessageRecord; -import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.net.NotPushRegisteredException; import org.thoughtcrime.securesms.messages.GroupSendUtil; +import org.thoughtcrime.securesms.net.NotPushRegisteredException; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.recipients.RecipientUtil; import org.thoughtcrime.securesms.transport.RetryLaterException; import org.thoughtcrime.securesms.util.GroupUtil; -import org.whispersystems.libsignal.util.guava.Optional; -import org.whispersystems.signalservice.api.SignalServiceMessageSender; import org.whispersystems.signalservice.api.crypto.ContentHint; -import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair; import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException; import org.whispersystems.signalservice.api.messages.SendMessageResult; import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage; -import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException; import java.io.IOException; @@ -62,10 +56,10 @@ public class RemoteDeleteSendJob extends BaseJob { boolean isMms) throws NoSuchMessageException { - MessageRecord message = isMms ? DatabaseFactory.getMmsDatabase(context).getMessageRecord(messageId) - : DatabaseFactory.getSmsDatabase(context).getSmsMessage(messageId); + MessageRecord message = isMms ? SignalDatabase.mms().getMessageRecord(messageId) + : SignalDatabase.sms().getSmsMessage(messageId); - Recipient conversationRecipient = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(message.getThreadId()); + Recipient conversationRecipient = SignalDatabase.threads().getRecipientForThreadId(message.getThreadId()); if (conversationRecipient == null) { throw new AssertionError("We have a message, but couldn't find the thread!"); @@ -125,15 +119,15 @@ public class RemoteDeleteSendJob extends BaseJob { MessageRecord message; if (isMms) { - db = DatabaseFactory.getMmsDatabase(context); - message = DatabaseFactory.getMmsDatabase(context).getMessageRecord(messageId); + db = SignalDatabase.mms(); + message = SignalDatabase.mms().getMessageRecord(messageId); } else { - db = DatabaseFactory.getSmsDatabase(context); - message = DatabaseFactory.getSmsDatabase(context).getSmsMessage(messageId); + db = SignalDatabase.sms(); + message = SignalDatabase.sms().getSmsMessage(messageId); } long targetSentTimestamp = message.getDateSent(); - Recipient conversationRecipient = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(message.getThreadId()); + Recipient conversationRecipient = SignalDatabase.threads().getRecipientForThreadId(message.getThreadId()); if (conversationRecipient == null) { throw new AssertionError("We have a message, but couldn't find the thread!"); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/ReportSpamJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/ReportSpamJob.java index 05be241811..19204a5315 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/ReportSpamJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/ReportSpamJob.java @@ -3,15 +3,14 @@ package org.thoughtcrime.securesms.jobs; import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessageDatabase.ReportSpamData; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.SignalServiceAccountManager; import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException; @@ -69,7 +68,7 @@ public class ReportSpamJob extends BaseJob { } int count = 0; - List reportSpamData = DatabaseFactory.getMmsSmsDatabase(context).getReportSpamMessageServerData(threadId, timestamp, MAX_MESSAGE_COUNT); + List reportSpamData = SignalDatabase.mmsSms().getReportSpamMessageServerData(threadId, timestamp, MAX_MESSAGE_COUNT); SignalServiceAccountManager signalServiceAccountManager = ApplicationDependencies.getSignalServiceAccountManager(); for (ReportSpamData data : reportSpamData) { Optional e164 = Recipient.resolved(data.getRecipientId()).getE164(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RequestGroupV2InfoWorkerJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/RequestGroupV2InfoWorkerJob.java index 6c0c0d1083..e42579e0c0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RequestGroupV2InfoWorkerJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RequestGroupV2InfoWorkerJob.java @@ -4,8 +4,8 @@ import androidx.annotation.NonNull; import androidx.annotation.WorkerThread; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupChangeBusyException; import org.thoughtcrime.securesms.groups.GroupId; @@ -77,7 +77,7 @@ final class RequestGroupV2InfoWorkerJob extends BaseJob { Log.i(TAG, "Updating group to revision " + toRevision); } - Optional group = DatabaseFactory.getGroupDatabase(context).getGroup(groupId); + Optional group = SignalDatabase.groups().getGroup(groupId); if (!group.isPresent()) { Log.w(TAG, "Group not found"); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/ResendMessageJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/ResendMessageJob.java index 195a40d952..6ca7b4e567 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/ResendMessageJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/ResendMessageJob.java @@ -9,10 +9,8 @@ import com.google.protobuf.InvalidProtocolBufferException; import org.signal.core.util.ThreadUtil; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.crypto.storage.SignalSenderKeyStore; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.jobmanager.Data; @@ -138,7 +136,7 @@ public class ResendMessageJob extends BaseJob { Content contentToSend = content; if (distributionId != null) { - Optional groupRecord = DatabaseFactory.getGroupDatabase(context).getGroupByDistributionId(distributionId); + Optional groupRecord = SignalDatabase.groups().getGroupByDistributionId(distributionId); if (!groupRecord.isPresent()) { Log.w(TAG, "Could not find a matching group for the distributionId! Skipping message send."); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileAvatarJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileAvatarJob.java index a658081429..acd2113462 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileAvatarJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileAvatarJob.java @@ -8,8 +8,8 @@ import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; import org.signal.zkgroup.profiles.ProfileKey; import org.thoughtcrime.securesms.crypto.ProfileKeyUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.RecipientDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; @@ -73,7 +73,7 @@ public class RetrieveProfileAvatarJob extends BaseJob { @Override public void onRun() throws IOException { - RecipientDatabase database = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase database = SignalDatabase.recipients(); ProfileKey profileKey = ProfileKeyUtil.profileKeyOrNull(recipient.resolve().getProfileKey()); if (profileKey == null) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileJob.java index 60cec8ce91..df4e2456cd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileJob.java @@ -17,10 +17,10 @@ import org.signal.zkgroup.profiles.ProfileKey; import org.signal.zkgroup.profiles.ProfileKeyCredential; import org.thoughtcrime.securesms.badges.Badges; import org.thoughtcrime.securesms.crypto.ProfileKeyUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase.UnidentifiedAccessMode; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; @@ -37,7 +37,6 @@ import org.thoughtcrime.securesms.util.IdentityUtil; import org.thoughtcrime.securesms.util.ProfileUtil; import org.thoughtcrime.securesms.util.SetUtil; import org.thoughtcrime.securesms.util.Stopwatch; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.Util; import org.whispersystems.libsignal.IdentityKey; import org.whispersystems.libsignal.InvalidKeyException; @@ -119,7 +118,7 @@ public class RetrieveProfileJob extends BaseJob { return new RefreshOwnProfileJob(); } else if (recipient.isGroup()) { Context context = ApplicationDependencies.getApplication(); - List recipients = DatabaseFactory.getGroupDatabase(context).getGroupMembers(recipient.requireGroupId(), GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF); + List recipients = SignalDatabase.groups().getGroupMembers(recipient.requireGroupId(), GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF); return new RetrieveProfileJob(Stream.of(recipients).map(Recipient::getId).collect(Collectors.toSet())); } else { @@ -144,7 +143,7 @@ public class RetrieveProfileJob extends BaseJob { if (recipient.isSelf()) { includeSelf = true; } else if (recipient.isGroup()) { - List recipients = DatabaseFactory.getGroupDatabase(context).getGroupMembers(recipient.requireGroupId(), GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF); + List recipients = SignalDatabase.groups().getGroupMembers(recipient.requireGroupId(), GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF); combined.addAll(Stream.of(recipients).map(Recipient::getId).toList()); } else { combined.add(recipientId); @@ -184,7 +183,7 @@ public class RetrieveProfileJob extends BaseJob { } SignalExecutors.BOUNDED.execute(() -> { - RecipientDatabase db = DatabaseFactory.getRecipientDatabase(application); + RecipientDatabase db = SignalDatabase.recipients(); long current = System.currentTimeMillis(); List ids = db.getRecipientsForRoutineProfileFetch(current - TimeUnit.DAYS.toMillis(30), @@ -242,7 +241,7 @@ public class RetrieveProfileJob extends BaseJob { } Stopwatch stopwatch = new Stopwatch("RetrieveProfile"); - RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase recipientDatabase = SignalDatabase.recipients(); RecipientUtil.ensureUuidsAreAvailable(context, Stream.of(Recipient.resolvedList(recipientIds)) .filter(r -> r.getRegistered() != RecipientDatabase.RegisteredState.NOT_REGISTERED) @@ -349,7 +348,7 @@ public class RetrieveProfileJob extends BaseJob { return; } - DatabaseFactory.getRecipientDatabase(context) + SignalDatabase.recipients() .setBadges(recipient.getId(), badges.stream().map(Badges::fromServiceBadge).collect(java.util.stream.Collectors.toList())); } @@ -358,7 +357,7 @@ public class RetrieveProfileJob extends BaseJob { @NonNull ProfileKey recipientProfileKey, @NonNull ProfileKeyCredential credential) { - RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase recipientDatabase = SignalDatabase.recipients(); recipientDatabase.setProfileKeyCredential(recipient.getId(), recipientProfileKey, credential); } @@ -389,7 +388,7 @@ public class RetrieveProfileJob extends BaseJob { } private void setUnidentifiedAccessMode(Recipient recipient, String unidentifiedAccessVerifier, boolean unrestrictedUnidentifiedAccess) { - RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase recipientDatabase = SignalDatabase.recipients(); ProfileKey profileKey = ProfileKeyUtil.profileKeyOrNull(recipient.getProfileKey()); if (unrestrictedUnidentifiedAccess && unidentifiedAccessVerifier != null) { @@ -434,7 +433,7 @@ public class RetrieveProfileJob extends BaseJob { if (!remoteProfileName.equals(localProfileName)) { Log.i(TAG, "Profile name updated. Writing new value."); - DatabaseFactory.getRecipientDatabase(context).setProfileName(recipient.getId(), remoteProfileName); + SignalDatabase.recipients().setProfileName(recipient.getId(), remoteProfileName); String remoteDisplayName = remoteProfileName.toString(); String localDisplayName = localProfileName.toString(); @@ -446,7 +445,7 @@ public class RetrieveProfileJob extends BaseJob { !remoteDisplayName.equals(localDisplayName)) { Log.i(TAG, "Writing a profile name change event."); - DatabaseFactory.getSmsDatabase(context).insertProfileNameChangeMessages(recipient, remoteDisplayName, localDisplayName); + SignalDatabase.sms().insertProfileNameChangeMessages(recipient, remoteDisplayName, localDisplayName); } else { Log.i(TAG, String.format(Locale.US, "Name changed, but wasn't relevant to write an event. blocked: %s, group: %s, self: %s, firstSet: %s, displayChange: %s", recipient.isBlocked(), recipient.isGroup(), recipient.isSelf(), localDisplayName.isEmpty(), !remoteDisplayName.equals(localDisplayName))); @@ -471,7 +470,7 @@ public class RetrieveProfileJob extends BaseJob { String plaintextAbout = ProfileUtil.decryptString(profileKey, encryptedAbout); String plaintextEmoji = ProfileUtil.decryptString(profileKey, encryptedEmoji); - DatabaseFactory.getRecipientDatabase(context).setAbout(recipient.getId(), plaintextAbout, plaintextEmoji); + SignalDatabase.recipients().setAbout(recipient.getId(), plaintextAbout, plaintextEmoji); } catch (InvalidCiphertextException | IOException e) { Log.w(TAG, e); } @@ -486,7 +485,7 @@ public class RetrieveProfileJob extends BaseJob { } private void clearUsername(Recipient recipient) { - DatabaseFactory.getRecipientDatabase(context).setUsername(recipient.getId(), null); + SignalDatabase.recipients().setUsername(recipient.getId(), null); } private void setProfileCapabilities(@NonNull Recipient recipient, @Nullable SignalServiceProfile.Capabilities capabilities) { @@ -494,7 +493,7 @@ public class RetrieveProfileJob extends BaseJob { return; } - DatabaseFactory.getRecipientDatabase(context).setCapabilities(recipient.getId(), capabilities); + SignalDatabase.recipients().setCapabilities(recipient.getId(), capabilities); } /** 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 e12d2f6a38..33f86f89c5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RotateCertificateJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RotateCertificateJob.java @@ -9,7 +9,6 @@ import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; import org.thoughtcrime.securesms.keyvalue.CertificateType; import org.thoughtcrime.securesms.keyvalue.SignalStore; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.signalservice.api.SignalServiceAccountManager; import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RotateProfileKeyJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/RotateProfileKeyJob.java index 74158013ef..68fe86e20b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RotateProfileKeyJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RotateProfileKeyJob.java @@ -4,7 +4,7 @@ import androidx.annotation.NonNull; import org.signal.zkgroup.profiles.ProfileKey; import org.thoughtcrime.securesms.crypto.ProfileKeyUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.jobmanager.Data; @@ -43,7 +43,7 @@ public class RotateProfileKeyJob extends BaseJob { ProfileKey newProfileKey = ProfileKeyUtil.createNew(); Recipient self = Recipient.self(); - DatabaseFactory.getRecipientDatabase(context).setProfileKey(self.getId(), newProfileKey); + SignalDatabase.recipients().setProfileKey(self.getId(), newProfileKey); ApplicationDependencies.getJobManager().add(new ProfileUploadJob()); ApplicationDependencies.getJobManager().add(new RefreshAttributesJob()); @@ -53,7 +53,7 @@ public class RotateProfileKeyJob extends BaseJob { } private void updateProfileKeyOnAllV2Groups() { - List allGv2Groups = DatabaseFactory.getGroupDatabase(context).getAllGroupV2Ids(); + List allGv2Groups = SignalDatabase.groups().getAllGroupV2Ids(); for (GroupId.V2 groupId : allGv2Groups) { ApplicationDependencies.getJobManager().add(GroupV2UpdateSelfProfileKeyJob.withoutLimits(groupId)); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/SendDeliveryReceiptJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/SendDeliveryReceiptJob.java index 4acdf20575..12bae1ed0c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/SendDeliveryReceiptJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/SendDeliveryReceiptJob.java @@ -6,7 +6,7 @@ import androidx.annotation.Nullable; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.MessageId; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; @@ -117,7 +117,7 @@ public class SendDeliveryReceiptJob extends BaseJob { receiptMessage); if (messageId != null) { - DatabaseFactory.getMessageLogDatabase(context).insertIfPossible(recipientId, timestamp, result, ContentHint.IMPLICIT, messageId); + SignalDatabase.messageLog().insertIfPossible(recipientId, timestamp, result, ContentHint.IMPLICIT, messageId); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/SendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/SendJob.java index 8af226b414..793eb12219 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/SendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/SendJob.java @@ -11,14 +11,12 @@ import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.attachments.DatabaseAttachment; import org.thoughtcrime.securesms.contactshare.Contact; import org.thoughtcrime.securesms.database.AttachmentDatabase; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.keyvalue.SignalStore; -import org.thoughtcrime.securesms.linkpreview.LinkPreview; import org.thoughtcrime.securesms.mms.OutgoingMediaMessage; import org.thoughtcrime.securesms.util.Util; -import java.lang.reflect.Array; import java.util.LinkedList; import java.util.List; import java.util.stream.Collectors; @@ -58,7 +56,7 @@ public abstract class SendJob extends BaseJob { attachments.addAll(message.getOutgoingQuote().getAttachments()); } - AttachmentDatabase database = DatabaseFactory.getAttachmentDatabase(context); + AttachmentDatabase database = SignalDatabase.attachments(); for (Attachment attachment : attachments) { database.markAttachmentUploaded(messageId, attachment); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/SendReadReceiptJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/SendReadReceiptJob.java index 9f7d675f41..a89255eec6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/SendReadReceiptJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/SendReadReceiptJob.java @@ -7,9 +7,8 @@ import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.MessageDatabase; import org.thoughtcrime.securesms.database.MessageDatabase.MarkedMessageInfo; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.MessageId; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; @@ -23,7 +22,6 @@ import org.thoughtcrime.securesms.recipients.RecipientUtil; import org.thoughtcrime.securesms.transport.UndeliverableMessageException; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.Util; -import org.whispersystems.libsignal.util.guava.Preconditions; import org.whispersystems.signalservice.api.SignalServiceMessageSender; import org.whispersystems.signalservice.api.crypto.ContentHint; import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException; @@ -35,7 +33,6 @@ import org.whispersystems.signalservice.api.push.exceptions.ServerRejectedExcept import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; @@ -173,7 +170,7 @@ public class SendReadReceiptJob extends BaseJob { receiptMessage); if (Util.hasItems(messageIds)) { - DatabaseFactory.getMessageLogDatabase(context).insertIfPossible(recipientId, timestamp, result, ContentHint.IMPLICIT, messageIds); + SignalDatabase.messageLog().insertIfPossible(recipientId, timestamp, result, ContentHint.IMPLICIT, messageIds); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/SendRetryReceiptJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/SendRetryReceiptJob.java index ab03b6cd14..79906158f6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/SendRetryReceiptJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/SendRetryReceiptJob.java @@ -15,9 +15,7 @@ import org.thoughtcrime.securesms.recipients.RecipientUtil; import org.whispersystems.libsignal.InvalidMessageException; import org.whispersystems.libsignal.protocol.DecryptionErrorMessage; import org.whispersystems.libsignal.util.guava.Optional; -import org.whispersystems.signalservice.api.crypto.ContentHint; import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair; -import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/SendViewedReceiptJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/SendViewedReceiptJob.java index 8d7c2bbf00..f71eb41e44 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/SendViewedReceiptJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/SendViewedReceiptJob.java @@ -7,8 +7,8 @@ import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessageDatabase.MarkedMessageInfo; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.MessageId; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; @@ -176,7 +176,7 @@ public class SendViewedReceiptJob extends BaseJob { receiptMessage); if (Util.hasItems(messageIds)) { - DatabaseFactory.getMessageLogDatabase(context).insertIfPossible(recipientId, timestamp, result, ContentHint.IMPLICIT, messageIds); + SignalDatabase.messageLog().insertIfPossible(recipientId, timestamp, result, ContentHint.IMPLICIT, messageIds); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/SenderKeyDistributionSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/SenderKeyDistributionSendJob.java index 0bc5233d9e..c6554986df 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/SenderKeyDistributionSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/SenderKeyDistributionSendJob.java @@ -4,9 +4,8 @@ import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.crypto.storage.SignalSenderKeyStore; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.jobmanager.Data; @@ -77,7 +76,7 @@ public final class SenderKeyDistributionSendJob extends BaseJob { @Override protected void onRun() throws Exception { - GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); + GroupDatabase groupDatabase = SignalDatabase.groups(); if (!groupDatabase.isCurrentMember(groupId, recipientId)) { Log.w(TAG, recipientId + " is no longer a member of " + groupId + "! Not sending."); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsReceiveJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsReceiveJob.java index a680ed816b..02f12237e3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsReceiveJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsReceiveJob.java @@ -16,9 +16,9 @@ import com.google.android.gms.common.api.Status; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessageDatabase; import org.thoughtcrime.securesms.database.MessageDatabase.InsertResult; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; @@ -151,7 +151,7 @@ public class SmsReceiveJob extends BaseJob { } private Optional storeMessage(IncomingTextMessage message) throws MigrationPendingException { - MessageDatabase database = DatabaseFactory.getSmsDatabase(context); + MessageDatabase database = SignalDatabase.sms(); database.ensureMigration(); if (TextSecurePreferences.getNeedsSqlCipherMigration(context)) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsSendJob.java index c024a855a8..90c8a26026 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsSendJob.java @@ -11,9 +11,9 @@ import android.telephony.SmsManager; import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessageDatabase; import org.thoughtcrime.securesms.database.NoSuchMessageException; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.SmsMessageRecord; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; @@ -68,7 +68,7 @@ public class SmsSendJob extends SendJob { @Override public void onAdded() { - DatabaseFactory.getSmsDatabase(context).markAsSending(messageId); + SignalDatabase.sms().markAsSending(messageId); } @Override @@ -78,7 +78,7 @@ public class SmsSendJob extends SendJob { throw new TooManyRetriesException(); } - MessageDatabase database = DatabaseFactory.getSmsDatabase(context); + MessageDatabase database = SignalDatabase.sms(); SmsMessageRecord record = database.getSmsMessage(messageId); if (!record.isPending() && !record.isFailed()) { @@ -96,7 +96,7 @@ public class SmsSendJob extends SendJob { log(TAG, String.valueOf(record.getDateSent()), "Sent message: " + messageId); } catch (UndeliverableMessageException ude) { warn(TAG, ude); - DatabaseFactory.getSmsDatabase(context).markAsSentFailed(record.getId()); + SignalDatabase.sms().markAsSentFailed(record.getId()); ApplicationDependencies.getMessageNotifier().notifyMessageDeliveryFailed(context, record.getRecipient(), record.getThreadId()); } } @@ -109,10 +109,10 @@ public class SmsSendJob extends SendJob { @Override public void onFailure() { warn(TAG, "onFailure() messageId: " + messageId); - long threadId = DatabaseFactory.getSmsDatabase(context).getThreadIdForMessage(messageId); - Recipient recipient = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(threadId); + long threadId = SignalDatabase.sms().getThreadIdForMessage(messageId); + Recipient recipient = SignalDatabase.threads().getRecipientForThreadId(threadId); - DatabaseFactory.getSmsDatabase(context).markAsSentFailed(messageId); + SignalDatabase.sms().markAsSentFailed(messageId); if (threadId != -1 && recipient != null) { ApplicationDependencies.getMessageNotifier().notifyMessageDeliveryFailed(context, recipient, threadId); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsSentJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsSentJob.java index 93918306bb..47f7d20585 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsSentJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsSentJob.java @@ -6,9 +6,9 @@ import android.telephony.SmsManager; import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessageDatabase; import org.thoughtcrime.securesms.database.NoSuchMessageException; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.SmsMessageRecord; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; @@ -91,12 +91,12 @@ public class SmsSentJob extends BaseJob { } private void handleDeliveredResult(long messageId, int result) { - DatabaseFactory.getSmsDatabase(context).markSmsStatus(messageId, result); + SignalDatabase.sms().markSmsStatus(messageId, result); } private void handleSentResult(long messageId, int result) { try { - MessageDatabase database = DatabaseFactory.getSmsDatabase(context); + MessageDatabase database = SignalDatabase.sms(); SmsMessageRecord record = database.getSmsMessage(messageId); switch (result) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/StickerDownloadJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/StickerDownloadJob.java index 1a4ea149b2..52073278ec 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/StickerDownloadJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/StickerDownloadJob.java @@ -3,7 +3,7 @@ package org.thoughtcrime.securesms.jobs; import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.StickerDatabase; import org.thoughtcrime.securesms.database.model.IncomingSticker; import org.thoughtcrime.securesms.database.model.StickerRecord; @@ -77,7 +77,7 @@ public class StickerDownloadJob extends BaseJob { @Override protected void onRun() throws Exception { - StickerDatabase db = DatabaseFactory.getStickerDatabase(context); + StickerDatabase db = SignalDatabase.stickers(); StickerRecord stickerRecord = db.getSticker(sticker.getPackId(), sticker.getStickerId(), sticker.isCover()); if (stickerRecord != null) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/StickerPackDownloadJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/StickerPackDownloadJob.java index bc8546aadc..a42b7bb361 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/StickerPackDownloadJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/StickerPackDownloadJob.java @@ -4,7 +4,7 @@ import androidx.annotation.NonNull; import androidx.core.util.Preconditions; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.StickerDatabase; import org.thoughtcrime.securesms.database.model.IncomingSticker; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; @@ -102,19 +102,19 @@ public class StickerPackDownloadJob extends BaseJob { @Override protected void onRun() throws IOException, InvalidMessageException { - if (isReferencePack && !DatabaseFactory.getAttachmentDatabase(context).containsStickerPackId(packId) && !BlessedPacks.contains(packId)) { + if (isReferencePack && !SignalDatabase.attachments().containsStickerPackId(packId) && !BlessedPacks.contains(packId)) { Log.w(TAG, "There are no attachments with the requested packId present for this reference pack. Skipping."); return; } - if (isReferencePack && DatabaseFactory.getStickerDatabase(context).isPackAvailableAsReference(packId)) { + if (isReferencePack && SignalDatabase.stickers().isPackAvailableAsReference(packId)) { Log.i(TAG, "Sticker pack already available for reference. Skipping."); return; } SignalServiceMessageReceiver receiver = ApplicationDependencies.getSignalServiceMessageReceiver(); JobManager jobManager = ApplicationDependencies.getJobManager(); - StickerDatabase stickerDatabase = DatabaseFactory.getStickerDatabase(context); + StickerDatabase stickerDatabase = SignalDatabase.stickers(); byte[] packIdBytes = Hex.fromStringCondensed(packId); byte[] packKeyBytes = Hex.fromStringCondensed(packKey); SignalServiceStickerManifest manifest = receiver.retrieveStickerManifest(packIdBytes, packKeyBytes); @@ -172,8 +172,8 @@ public class StickerPackDownloadJob extends BaseJob { @Override public void onFailure() { Log.w(TAG, "Failed to download manifest! Uninstalling pack."); - DatabaseFactory.getStickerDatabase(context).uninstallPack(packId); - DatabaseFactory.getStickerDatabase(context).deleteOrphanedPacks(); + SignalDatabase.stickers().uninstallPack(packId); + SignalDatabase.stickers().deleteOrphanedPacks(); } public static final class Factory implements Job.Factory { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageAccountRestoreJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageAccountRestoreJob.java index 48b79dde28..85277c4dd7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageAccountRestoreJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageAccountRestoreJob.java @@ -3,7 +3,7 @@ package org.thoughtcrime.securesms.jobs; import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; @@ -13,7 +13,6 @@ import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.storage.StorageSyncHelper; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.SignalServiceAccountManager; import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException; @@ -104,12 +103,12 @@ public class StorageAccountRestoreJob extends BaseJob { Log.i(TAG, "Applying changes locally..."); - DatabaseFactory.getInstance(context).getRawDatabase().beginTransaction(); + SignalDatabase.getRawDatabase().beginTransaction(); try { StorageSyncHelper.applyAccountStorageSyncUpdates(context, Recipient.self(), accountRecord, false); - DatabaseFactory.getInstance(context).getRawDatabase().setTransactionSuccessful(); + SignalDatabase.getRawDatabase().setTransactionSuccessful(); } finally { - DatabaseFactory.getInstance(context).getRawDatabase().endTransaction(); + SignalDatabase.getRawDatabase().endTransaction(); } JobManager jobManager = ApplicationDependencies.getJobManager(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageForcePushJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageForcePushJob.java index 45a97af0f8..fc79556a8a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageForcePushJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageForcePushJob.java @@ -5,8 +5,8 @@ import androidx.annotation.NonNull; import com.annimon.stream.Stream; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.RecipientDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.UnknownStorageIdDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; @@ -19,7 +19,6 @@ import org.thoughtcrime.securesms.storage.StorageSyncHelper; import org.thoughtcrime.securesms.storage.StorageSyncModels; import org.thoughtcrime.securesms.storage.StorageSyncValidations; import org.thoughtcrime.securesms.transport.RetryLaterException; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.libsignal.InvalidKeyException; import org.whispersystems.signalservice.api.SignalServiceAccountManager; import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException; @@ -74,8 +73,8 @@ public class StorageForcePushJob extends BaseJob { protected void onRun() throws IOException, RetryLaterException { StorageKey storageServiceKey = SignalStore.storageService().getOrCreateStorageKey(); SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager(); - RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); - UnknownStorageIdDatabase storageIdDatabase = DatabaseFactory.getUnknownStorageIdDatabase(context); + RecipientDatabase recipientDatabase = SignalDatabase.recipients(); + UnknownStorageIdDatabase storageIdDatabase = SignalDatabase.unknownStorageIds(); long currentVersion = accountManager.getStorageManifestVersion(); Map oldContactStorageIds = recipientDatabase.getContactStorageSyncIdsMap(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJob.java index fe4c4d4c3a..f20af47d90 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJob.java @@ -9,9 +9,9 @@ import com.annimon.stream.Stream; import net.zetetic.database.sqlcipher.SQLiteDatabase; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.RecipientDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientSettings; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.UnknownStorageIdDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; @@ -205,9 +205,9 @@ public class StorageSyncJob extends BaseJob { private boolean performSync() throws IOException, RetryLaterException, InvalidKeyException { final Stopwatch stopwatch = new Stopwatch("StorageSync"); - final SQLiteDatabase db = DatabaseFactory.getInstance(context).getRawDatabase(); + final SQLiteDatabase db = SignalDatabase.getRawDatabase(); final SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager(); - final UnknownStorageIdDatabase storageIdDatabase = DatabaseFactory.getUnknownStorageIdDatabase(context); + final UnknownStorageIdDatabase storageIdDatabase = SignalDatabase.unknownStorageIds(); final StorageKey storageServiceKey = SignalStore.storageService().getOrCreateStorageKey(); final SignalStorageManifest localManifest = SignalStore.storageService().getManifest(); @@ -221,7 +221,7 @@ public class StorageSyncJob extends BaseJob { if (self.getStorageServiceId() == null) { Log.w(TAG, "No storageId for self. Generating."); - DatabaseFactory.getRecipientDatabase(context).updateStorageId(self.getId(), StorageSyncHelper.generateKey()); + SignalDatabase.recipients().updateStorageId(self.getId(), StorageSyncHelper.generateKey()); self = freshSelf(); } @@ -371,9 +371,9 @@ public class StorageSyncJob extends BaseJob { } private static @NonNull List getAllLocalStorageIds(@NonNull Context context, @NonNull Recipient self) { - return Util.concatenatedList(DatabaseFactory.getRecipientDatabase(context).getContactStorageSyncIds(), + return Util.concatenatedList(SignalDatabase.recipients().getContactStorageSyncIds(), Collections.singletonList(StorageId.forAccount(self.getStorageServiceId())), - DatabaseFactory.getUnknownStorageIdDatabase(context).getAllUnknownIds()); + SignalDatabase.unknownStorageIds().getAllUnknownIds()); } private static @NonNull List buildLocalStorageRecords(@NonNull Context context, @NonNull Recipient self, @NonNull Collection ids) { @@ -381,8 +381,8 @@ public class StorageSyncJob extends BaseJob { return Collections.emptyList(); } - RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); - UnknownStorageIdDatabase storageIdDatabase = DatabaseFactory.getUnknownStorageIdDatabase(context); + RecipientDatabase recipientDatabase = SignalDatabase.recipients(); + UnknownStorageIdDatabase storageIdDatabase = SignalDatabase.unknownStorageIds(); List records = new ArrayList<>(ids.size()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/SubscriptionReceiptRequestResponseJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/SubscriptionReceiptRequestResponseJob.java index d8a7b5bec8..5a26059537 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/SubscriptionReceiptRequestResponseJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/SubscriptionReceiptRequestResponseJob.java @@ -4,7 +4,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; -import org.signal.core.util.ThreadUtil; import org.signal.core.util.logging.Log; import org.signal.zkgroup.InvalidInputException; import org.signal.zkgroup.VerificationFailedException; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/ThreadUpdateJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/ThreadUpdateJob.java index ff22e598a9..6335c7bb64 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/ThreadUpdateJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/ThreadUpdateJob.java @@ -3,7 +3,7 @@ package org.thoughtcrime.securesms.jobs; import androidx.annotation.NonNull; import org.signal.core.util.ThreadUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; @@ -45,7 +45,7 @@ public final class ThreadUpdateJob extends BaseJob { @Override protected void onRun() throws Exception { - DatabaseFactory.getThreadDatabase(context).update(threadId, true); + SignalDatabase.threads().update(threadId, true); ThreadUtil.sleep(1000); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/TrimThreadJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/TrimThreadJob.java index fdaa15435d..59dcb97f45 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/TrimThreadJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/TrimThreadJob.java @@ -20,7 +20,7 @@ import androidx.annotation.NonNull; import org.signal.core.util.concurrent.SignalExecutors; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; @@ -76,7 +76,7 @@ public class TrimThreadJob extends BaseJob { long trimBeforeDate = keepMessagesDuration != KeepMessagesDuration.FOREVER ? System.currentTimeMillis() - keepMessagesDuration.getDuration() : ThreadDatabase.NO_TRIM_BEFORE_DATE_SET; - DatabaseFactory.getThreadDatabase(context).trimThread(threadId, trimLength, trimBeforeDate); + SignalDatabase.threads().trimThread(threadId, trimLength, trimBeforeDate); } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/TypingSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/TypingSendJob.java index f036c17a42..4dcbc5bf15 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/TypingSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/TypingSendJob.java @@ -5,27 +5,21 @@ import androidx.annotation.NonNull; import com.annimon.stream.Stream; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; -import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; -import org.thoughtcrime.securesms.net.NotPushRegisteredException; import org.thoughtcrime.securesms.messages.GroupSendUtil; +import org.thoughtcrime.securesms.net.NotPushRegisteredException; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientUtil; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.CancelationException; -import org.whispersystems.signalservice.api.SignalServiceMessageSender; -import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair; import org.whispersystems.signalservice.api.messages.SignalServiceTypingMessage; import org.whispersystems.signalservice.api.messages.SignalServiceTypingMessage.Action; -import org.whispersystems.signalservice.api.push.DistributionId; -import org.whispersystems.signalservice.api.push.SignalServiceAddress; import java.util.Collections; import java.util.List; @@ -91,7 +85,7 @@ public class TypingSendJob extends BaseJob { Log.d(TAG, "Sending typing " + (typing ? "started" : "stopped") + " for thread " + threadId); - Recipient recipient = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(threadId); + Recipient recipient = SignalDatabase.threads().getRecipientForThreadId(threadId); if (recipient == null) { Log.w(TAG, "Tried to send a typing indicator to a non-existent thread."); @@ -122,7 +116,7 @@ public class TypingSendJob extends BaseJob { Optional groupId = Optional.absent(); if (recipient.isGroup()) { - recipients = DatabaseFactory.getGroupDatabase(context).getGroupMembers(recipient.requireGroupId(), GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF); + recipients = SignalDatabase.groups().getGroupMembers(recipient.requireGroupId(), GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF); groupId = Optional.of(recipient.requireGroupId().getDecodedId()); } 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 5b9982b21a..068b13d6e9 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 @@ -6,8 +6,8 @@ import org.signal.core.util.concurrent.SignalExecutors import org.thoughtcrime.securesms.components.emoji.Emoji import org.thoughtcrime.securesms.components.emoji.EmojiPageModel import org.thoughtcrime.securesms.components.emoji.RecentEmojiPageModel -import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.EmojiSearchDatabase +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.emoji.EmojiSource import org.thoughtcrime.securesms.util.TextSecurePreferences import java.util.function.Consumer @@ -17,7 +17,7 @@ private const val EMOJI_SEARCH_LIMIT = 20 class EmojiSearchRepository(private val context: Context) { - private val emojiSearchDatabase: EmojiSearchDatabase = DatabaseFactory.getEmojiSearchDatabase(context) + private val emojiSearchDatabase: EmojiSearchDatabase = SignalDatabase.emojiSearch fun submitQuery(query: String, includeRecents: Boolean, limit: Int = EMOJI_SEARCH_LIMIT, consumer: Consumer) { if (query.length < MINIMUM_QUERY_THRESHOLD && includeRecents) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerKeyboardPageViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerKeyboardPageViewModel.kt index 9345a0fa30..0b5411cba6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerKeyboardPageViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerKeyboardPageViewModel.kt @@ -5,7 +5,7 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.keyboard.sticker.KeyboardStickerPackListAdapter.StickerPack import org.thoughtcrime.securesms.util.MappingModelList import org.thoughtcrime.securesms.util.livedata.LiveDataUtil @@ -57,7 +57,7 @@ class StickerKeyboardPageViewModel(private val repository: StickerKeyboardReposi } class Factory(context: Context) : ViewModelProvider.Factory { - private val repository = StickerKeyboardRepository(DatabaseFactory.getStickerDatabase(context)) + private val repository = StickerKeyboardRepository(SignalDatabase.stickers) override fun create(modelClass: Class): T { return requireNotNull(modelClass.cast(StickerKeyboardPageViewModel(repository))) diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerSearchRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerSearchRepository.kt index db4b233cf5..381da7b095 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerSearchRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerSearchRepository.kt @@ -3,8 +3,8 @@ package org.thoughtcrime.securesms.keyboard.sticker import android.content.Context import androidx.annotation.WorkerThread import org.thoughtcrime.securesms.components.emoji.EmojiUtil -import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.EmojiSearchDatabase +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.database.StickerDatabase import org.thoughtcrime.securesms.database.StickerDatabase.StickerRecordReader import org.thoughtcrime.securesms.database.model.StickerRecord @@ -14,8 +14,8 @@ private const val EMOJI_SEARCH_RESULTS_LIMIT = 20 class StickerSearchRepository(context: Context) { - private val emojiSearchDatabase: EmojiSearchDatabase = DatabaseFactory.getEmojiSearchDatabase(context) - private val stickerDatabase: StickerDatabase = DatabaseFactory.getStickerDatabase(context) + private val emojiSearchDatabase: EmojiSearchDatabase = SignalDatabase.emojiSearch + private val stickerDatabase: StickerDatabase = SignalDatabase.stickers @WorkerThread fun search(query: String): List { 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 fd18bf3b8e..049c344758 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/AccountValues.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/AccountValues.kt @@ -4,7 +4,7 @@ import android.content.Context import androidx.annotation.VisibleForTesting import org.signal.core.util.logging.Log import org.thoughtcrime.securesms.crypto.ProfileKeyUtil -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.dependencies.ApplicationDependencies import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.util.TextSecurePreferences @@ -135,7 +135,7 @@ internal class AccountValues internal constructor(store: KeyValueStore) : Signal val newProfileKey = ProfileKeyUtil.createNew() val self = Recipient.self() - DatabaseFactory.getRecipientDatabase(context).setProfileKey(self.id, newProfileKey) + SignalDatabase.recipients.setProfileKey(self.id, newProfileKey) ApplicationDependencies.getGroupsV2Authorization().clear() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/PaymentsValues.kt b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/PaymentsValues.kt index 37e9f40f92..755d1e8ef9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/PaymentsValues.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/PaymentsValues.kt @@ -8,8 +8,7 @@ import com.google.protobuf.InvalidProtocolBufferException import com.mobilecoin.lib.Mnemonics import com.mobilecoin.lib.exceptions.BadMnemonicException import org.signal.core.util.logging.Log -import org.thoughtcrime.securesms.database.DatabaseFactory -import org.thoughtcrime.securesms.dependencies.ApplicationDependencies +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.keyvalue.PaymentsValues.WalletRestoreResult import org.thoughtcrime.securesms.lock.v2.PinKeyboardType import org.thoughtcrime.securesms.payments.Balance @@ -135,7 +134,7 @@ internal class PaymentsValues internal constructor(store: KeyValueStore) : Signa .putBoolean(USER_CONFIRMED_MNEMONIC, false) .commit() } - DatabaseFactory.getRecipientDatabase(ApplicationDependencies.getApplication()).markNeedsSync(Recipient.self().id) + SignalDatabase.recipients.markNeedsSync(Recipient.self().id) StorageSyncHelper.scheduleSyncForDataChange() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SettingsValues.java b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SettingsValues.java index ce772e5aa9..043a986604 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SettingsValues.java +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SettingsValues.java @@ -10,13 +10,12 @@ import androidx.annotation.Nullable; import androidx.lifecycle.LiveData; import org.signal.core.util.concurrent.SignalExecutors; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.mms.SentMediaQuality; import org.thoughtcrime.securesms.preferences.widgets.NotificationPrivacyPreference; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.storage.StorageSyncHelper; -import org.thoughtcrime.securesms.util.FeatureFlags; import org.thoughtcrime.securesms.util.SingleLiveEvent; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.signal.core.util.logging.Log; @@ -369,7 +368,7 @@ public final class SettingsValues extends SignalStoreValues { putBoolean(DEFAULT_SMS, value); SignalExecutors.BOUNDED.execute(() -> { - DatabaseFactory.getRecipientDatabase(ApplicationDependencies.getApplication()).markNeedsSync(Recipient.self().getId()); + SignalDatabase.recipients().markNeedsSync(Recipient.self().getId()); StorageSyncHelper.scheduleSyncForDataChange(); }); } @@ -378,7 +377,7 @@ public final class SettingsValues extends SignalStoreValues { public void setUniversalExpireTimer(int seconds) { putInteger(UNIVERSAL_EXPIRE_TIMER, seconds); SignalExecutors.BOUNDED.execute(() -> { - DatabaseFactory.getRecipientDatabase(ApplicationDependencies.getApplication()).markNeedsSync(Recipient.self().getId()); + SignalDatabase.recipients().markNeedsSync(Recipient.self().getId()); StorageSyncHelper.scheduleSyncForDataChange(); }); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java index 941841db62..f537af195f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java @@ -20,8 +20,8 @@ import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.attachments.UriAttachment; import org.thoughtcrime.securesms.database.AttachmentDatabase; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.groups.GroupManager; @@ -260,8 +260,7 @@ public class LinkPreviewRepository { GroupMasterKey groupMasterKey = groupInviteLinkUrl.getGroupMasterKey(); GroupId.V2 groupId = GroupId.v2(groupMasterKey); - Optional group = DatabaseFactory.getGroupDatabase(context) - .getGroup(groupId); + Optional group = SignalDatabase.groups().getGroup(groupId); if (group.isPresent()) { Log.i(TAG, "Creating preview for locally available group"); diff --git a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionRemappedRecords.java b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionRemappedRecords.java index f5b03725a6..ed947f5765 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionRemappedRecords.java +++ b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionRemappedRecords.java @@ -6,7 +6,7 @@ import android.database.Cursor; import androidx.annotation.NonNull; import org.signal.core.util.AsciiArt; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; /** * Renders data pertaining to sender key. While all private info is obfuscated, this is still only intended to be printed for internal users. @@ -23,12 +23,12 @@ public class LogSectionRemappedRecords implements LogSection { StringBuilder builder = new StringBuilder(); builder.append("--- Recipients").append("\n\n"); - try (Cursor cursor = DatabaseFactory.getRemappedRecordsDatabase(context).getAllRecipients()) { + try (Cursor cursor = SignalDatabase.remappedRecords().getAllRecipients()) { builder.append(AsciiArt.tableFor(cursor)).append("\n\n"); } builder.append("--- Threads").append("\n\n"); - try (Cursor cursor = DatabaseFactory.getRemappedRecordsDatabase(context).getAllThreads()) { + try (Cursor cursor = SignalDatabase.remappedRecords().getAllThreads()) { builder.append(AsciiArt.tableFor(cursor)).append("\n"); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionSenderKey.java b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionSenderKey.java index 118c1b01a7..982b1a5249 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionSenderKey.java +++ b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionSenderKey.java @@ -6,13 +6,7 @@ import android.database.Cursor; import androidx.annotation.NonNull; import org.signal.core.util.AsciiArt; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; -import org.whispersystems.libsignal.SignalProtocolAddress; -import org.whispersystems.signalservice.api.push.DistributionId; - -import java.util.Map; -import java.util.Set; +import org.thoughtcrime.securesms.database.SignalDatabase; /** * Renders data pertaining to sender key. While all private info is obfuscated, this is still only intended to be printed for internal users. @@ -29,12 +23,12 @@ public class LogSectionSenderKey implements LogSection { StringBuilder builder = new StringBuilder(); builder.append("--- Sender Keys Created By This Device").append("\n\n"); - try (Cursor cursor = DatabaseFactory.getSenderKeyDatabase(context).getAllCreatedBySelf()) { + try (Cursor cursor = SignalDatabase.senderKeys().getAllCreatedBySelf()) { builder.append(AsciiArt.tableFor(cursor)).append("\n\n"); } builder.append("--- Sender Key Shared State").append("\n\n"); - try (Cursor cursor = DatabaseFactory.getSenderKeySharedDatabase(context).getAllSharedWithCursor()) { + try (Cursor cursor = SignalDatabase.senderKeyShared().getAllSharedWithCursor()) { builder.append(AsciiArt.tableFor(cursor)).append("\n"); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/longmessage/LongMessageRepository.java b/app/src/main/java/org/thoughtcrime/securesms/longmessage/LongMessageRepository.java index 24ca5cb33f..2eb60a21a8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/longmessage/LongMessageRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/longmessage/LongMessageRepository.java @@ -11,9 +11,9 @@ import org.signal.core.util.StreamUtil; import org.signal.core.util.concurrent.SignalExecutors; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.conversation.ConversationMessage.ConversationMessageFactory; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessageDatabase; import org.thoughtcrime.securesms.database.MmsDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.SmsDatabase; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.database.model.MmsMessageRecord; @@ -32,8 +32,8 @@ class LongMessageRepository { private final MessageDatabase smsDatabase; LongMessageRepository(@NonNull Context context) { - this.mmsDatabase = DatabaseFactory.getMmsDatabase(context); - this.smsDatabase = DatabaseFactory.getSmsDatabase(context); + this.mmsDatabase = SignalDatabase.mms(); + this.smsDatabase = SignalDatabase.sms(); } void getMessage(@NonNull Context context, long messageId, boolean isMms, @NonNull Callback> callback) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/media/DecryptableUriMediaInput.java b/app/src/main/java/org/thoughtcrime/securesms/media/DecryptableUriMediaInput.java index b7de8521d5..255589c5fd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/media/DecryptableUriMediaInput.java +++ b/app/src/main/java/org/thoughtcrime/securesms/media/DecryptableUriMediaInput.java @@ -8,7 +8,7 @@ import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; import org.thoughtcrime.securesms.attachments.AttachmentId; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.mms.PartAuthority; import org.thoughtcrime.securesms.mms.PartUriParser; import org.thoughtcrime.securesms.providers.BlobProvider; @@ -41,8 +41,7 @@ public final class DecryptableUriMediaInput { throw new AssertionError(); } - MediaDataSource mediaDataSource = DatabaseFactory.getAttachmentDatabase(context) - .mediaDataSourceFor(partId); + MediaDataSource mediaDataSource = SignalDatabase.attachments().mediaDataSourceFor(partId); if (mediaDataSource == null) { throw new AssertionError(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediaoverview/MediaOverviewActivity.java b/app/src/main/java/org/thoughtcrime/securesms/mediaoverview/MediaOverviewActivity.java index c70fbc6a2d..6167f32b13 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediaoverview/MediaOverviewActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mediaoverview/MediaOverviewActivity.java @@ -40,9 +40,9 @@ import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.components.AnimatingToggle; import org.thoughtcrime.securesms.components.BoldSelectionTabItem; import org.thoughtcrime.securesms.components.ControllableTabLayout; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MediaDatabase; import org.thoughtcrime.securesms.database.MediaDatabase.Sorting; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.loaders.MediaLoader; import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme; import org.thoughtcrime.securesms.util.DynamicTheme; @@ -51,7 +51,6 @@ import org.whispersystems.libsignal.util.Pair; import java.util.ArrayList; import java.util.List; -import java.util.Objects; /** * Activity for displaying media attachments in-app @@ -200,7 +199,7 @@ public final class MediaOverviewActivity extends PassphraseRequiredActivity { if (threadId == MediaDatabase.ALL_THREADS) { getSupportActionBar().setTitle(R.string.MediaOverviewActivity_All_storage_use); } else { - SimpleTask.run(() -> DatabaseFactory.getThreadDatabase(this).getRecipientForThreadId(threadId), + SimpleTask.run(() -> SignalDatabase.threads().getRecipientForThreadId(threadId), (recipient) -> { if (recipient != null) { getSupportActionBar().setTitle(recipient.getDisplayName(this)); diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaPreviewFragment.java b/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaPreviewFragment.java index c7a7551b21..d0bc75c943 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaPreviewFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaPreviewFragment.java @@ -11,7 +11,7 @@ import androidx.fragment.app.Fragment; import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.attachments.AttachmentId; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.mms.PartUriParser; import org.thoughtcrime.securesms.util.MediaUtil; import org.thoughtcrime.securesms.util.concurrent.SimpleTask; @@ -93,7 +93,7 @@ public abstract class MediaPreviewFragment extends Fragment { final Context context = requireContext().getApplicationContext(); SimpleTask.run(getViewLifecycleOwner().getLifecycle(), - () -> DatabaseFactory.getAttachmentDatabase(context).hasAttachment(attachmentId), + () -> SignalDatabase.attachments().hasAttachment(attachmentId), hasAttachment -> { if (!hasAttachment) events.mediaNotAvailable(); }); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/CameraContactsRepository.java b/app/src/main/java/org/thoughtcrime/securesms/mediasend/CameraContactsRepository.java index c264f1fbfb..f774f2174f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/CameraContactsRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/CameraContactsRepository.java @@ -10,9 +10,9 @@ import androidx.annotation.WorkerThread; import org.signal.core.util.concurrent.SignalExecutors; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.contacts.ContactRepository; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.database.model.ThreadRecord; import org.thoughtcrime.securesms.recipients.Recipient; @@ -45,9 +45,9 @@ class CameraContactsRepository { CameraContactsRepository(@NonNull Context context) { this.context = context.getApplicationContext(); - this.threadDatabase = DatabaseFactory.getThreadDatabase(context); - this.groupDatabase = DatabaseFactory.getGroupDatabase(context); - this.recipientDatabase = DatabaseFactory.getRecipientDatabase(context); + this.threadDatabase = SignalDatabase.threads(); + this.groupDatabase = SignalDatabase.groups(); + this.recipientDatabase = SignalDatabase.recipients(); this.contactRepository = new ContactRepository(context); this.serialExecutor = SignalExecutors.SERIAL; this.parallelExecutor = SignalExecutors.BOUNDED; diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaUploadRepository.java b/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaUploadRepository.java index 91a34d065a..55ba4456b7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaUploadRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaUploadRepository.java @@ -14,7 +14,7 @@ import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.attachments.AttachmentId; import org.thoughtcrime.securesms.database.AttachmentDatabase; import org.thoughtcrime.securesms.database.AttachmentDatabase.TransformProperties; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.JobManager; import org.thoughtcrime.securesms.mms.GifSlide; @@ -136,7 +136,7 @@ public class MediaUploadRepository { public void deleteAbandonedAttachments() { executor.execute(() -> { - int deleted = DatabaseFactory.getAttachmentDatabase(context).deleteAbandonedPreuploadedAttachments(); + int deleted = SignalDatabase.attachments().deleteAbandonedPreuploadedAttachments(); Log.i(TAG, "Deleted " + deleted + " abandoned attachments."); }); } @@ -165,7 +165,7 @@ public class MediaUploadRepository { @WorkerThread private void updateCaptionsInternal(@NonNull List updatedMedia) { - AttachmentDatabase db = DatabaseFactory.getAttachmentDatabase(context); + AttachmentDatabase db = SignalDatabase.attachments(); for (Media updated : updatedMedia) { PreUploadResult result = uploadResults.get(updated); @@ -195,7 +195,7 @@ public class MediaUploadRepository { } } - DatabaseFactory.getAttachmentDatabase(context).updateDisplayOrder(orderMap); + SignalDatabase.attachments().updateDisplayOrder(orderMap); if (orderedUploadResults.size() == uploadResults.size()) { uploadResults.clear(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/megaphone/MegaphoneRepository.java b/app/src/main/java/org/thoughtcrime/securesms/megaphone/MegaphoneRepository.java index f132e2e0a6..4cb35408b8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/megaphone/MegaphoneRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/megaphone/MegaphoneRepository.java @@ -12,7 +12,6 @@ import com.annimon.stream.Collectors; import com.annimon.stream.Stream; import org.signal.core.util.concurrent.SignalExecutors; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MegaphoneDatabase; import org.thoughtcrime.securesms.database.model.MegaphoneRecord; import org.thoughtcrime.securesms.megaphone.Megaphones.Event; diff --git a/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageDetailsRepository.java b/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageDetailsRepository.java index 8a8c78b501..d3ff5cac38 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageDetailsRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageDetailsRepository.java @@ -10,9 +10,9 @@ import androidx.lifecycle.MutableLiveData; import org.signal.core.util.concurrent.SignalExecutors; import org.thoughtcrime.securesms.conversation.ConversationMessage.ConversationMessageFactory; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.GroupReceiptDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch; import org.thoughtcrime.securesms.database.documents.NetworkFailure; import org.thoughtcrime.securesms.database.model.MessageRecord; @@ -55,10 +55,10 @@ final class MessageDetailsRepository { getNetworkFailure(messageRecord, messageRecord.getRecipient()), getKeyMismatchFailure(messageRecord, messageRecord.getRecipient()))); } else { - List receiptInfoList = DatabaseFactory.getGroupReceiptDatabase(context).getGroupReceiptInfo(messageRecord.getId()); + List receiptInfoList = SignalDatabase.groupReceipts().getGroupReceiptInfo(messageRecord.getId()); if (receiptInfoList.isEmpty()) { - List group = DatabaseFactory.getGroupDatabase(context).getGroupMembers(messageRecord.getRecipient().requireGroupId(), GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF); + List group = SignalDatabase.groups().getGroupMembers(messageRecord.getRecipient().requireGroupId(), GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF); for (Recipient recipient : group) { recipients.add(new RecipientDeliveryStatus(messageRecord, diff --git a/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageRecordLiveData.java b/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageRecordLiveData.java index 7fa2106549..11a7806727 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageRecordLiveData.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageRecordLiveData.java @@ -8,11 +8,11 @@ import androidx.annotation.WorkerThread; import androidx.lifecycle.LiveData; import org.signal.core.util.concurrent.SignalExecutors; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.DatabaseObserver; import org.thoughtcrime.securesms.database.MessageDatabase; import org.thoughtcrime.securesms.database.MmsDatabase; import org.thoughtcrime.securesms.database.MmsSmsDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.SmsDatabase; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; @@ -82,7 +82,7 @@ final class MessageRecordLiveData extends LiveData { @WorkerThread private synchronized void handleSms() { - final MessageDatabase db = DatabaseFactory.getSmsDatabase(context); + final MessageDatabase db = SignalDatabase.sms(); final Cursor cursor = db.getMessageCursor(messageId); final MessageRecord record = SmsDatabase.readerFor(cursor).getNext(); @@ -93,7 +93,7 @@ final class MessageRecordLiveData extends LiveData { @WorkerThread private synchronized void handleMms() { - final MessageDatabase db = DatabaseFactory.getMmsDatabase(context); + final MessageDatabase db = SignalDatabase.mms(); final Cursor cursor = db.getMessageCursor(messageId); final MessageRecord record = MmsDatabase.readerFor(cursor).getNext(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/messagerequests/MessageRequestRepository.java b/app/src/main/java/org/thoughtcrime/securesms/messagerequests/MessageRequestRepository.java index 899ea9778f..7ebd8ef516 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messagerequests/MessageRequestRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messagerequests/MessageRequestRepository.java @@ -6,15 +6,13 @@ import androidx.annotation.NonNull; import androidx.annotation.WorkerThread; import androidx.core.util.Consumer; -import com.annimon.stream.Stream; - import org.signal.core.util.concurrent.SignalExecutors; import org.signal.core.util.logging.Log; import org.signal.storageservice.protos.groups.local.DecryptedGroup; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.MessageDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupChangeException; @@ -53,14 +51,14 @@ final class MessageRequestRepository { void getGroups(@NonNull RecipientId recipientId, @NonNull Consumer> onGroupsLoaded) { executor.execute(() -> { - GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); + GroupDatabase groupDatabase = SignalDatabase.groups(); onGroupsLoaded.accept(groupDatabase.getPushGroupNamesContainingMember(recipientId)); }); } void getGroupInfo(@NonNull RecipientId recipientId, @NonNull Consumer onGroupInfoLoaded) { executor.execute(() -> { - GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); + GroupDatabase groupDatabase = SignalDatabase.groups(); Optional groupRecord = groupDatabase.getGroup(recipientId); onGroupInfoLoaded.accept(groupRecord.transform(record -> { if (record.isV2Group()) { @@ -134,7 +132,7 @@ final class MessageRequestRepository { Log.i(TAG, "GV2 accepting invite"); GroupManager.acceptInvite(context, liveRecipient.get().requireGroupId().requireV2()); - RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase recipientDatabase = SignalDatabase.recipients(); recipientDatabase.setProfileSharing(liveRecipient.getId(), true); onMessageRequestAccepted.run(); @@ -143,18 +141,16 @@ final class MessageRequestRepository { error.onError(GroupChangeFailureReason.fromException(e)); } } else { - RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase recipientDatabase = SignalDatabase.recipients(); recipientDatabase.setProfileSharing(liveRecipient.getId(), true); MessageSender.sendProfileKey(context, threadId); - List messageIds = DatabaseFactory.getThreadDatabase(context) - .setEntireThreadRead(threadId); + List messageIds = SignalDatabase.threads().setEntireThreadRead(threadId); ApplicationDependencies.getMessageNotifier().updateNotification(context); MarkReadReceiver.process(context, messageIds); - List viewedInfos = DatabaseFactory.getMmsDatabase(context) - .getViewedIncomingMessages(threadId); + List viewedInfos = SignalDatabase.mms().getViewedIncomingMessages(threadId); SendViewedReceiptJob.enqueue(threadId, liveRecipient.getId(), viewedInfos); @@ -179,7 +175,7 @@ final class MessageRequestRepository { try { GroupManager.leaveGroupFromBlockOrMessageRequest(context, resolved.requireGroupId().requirePush()); } catch (GroupChangeException | GroupPatchNotAcceptedException e) { - if (DatabaseFactory.getGroupDatabase(context).isCurrentMember(resolved.requireGroupId().requirePush(), Recipient.self().getId())) { + if (SignalDatabase.groups().isCurrentMember(resolved.requireGroupId().requirePush(), Recipient.self().getId())) { Log.w(TAG, "Failed to leave group, and we're still a member.", e); error.onError(GroupChangeFailureReason.fromException(e)); return; @@ -197,7 +193,7 @@ final class MessageRequestRepository { ApplicationDependencies.getJobManager().add(MultiDeviceMessageRequestResponseJob.forDelete(recipient.getId())); } - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); + ThreadDatabase threadDatabase = SignalDatabase.threads(); threadDatabase.deleteConversation(threadId); onMessageRequestDeleted.run(); @@ -259,8 +255,7 @@ final class MessageRequestRepository { RecipientUtil.unblock(context, recipient); - List messageIds = DatabaseFactory.getThreadDatabase(context) - .setEntireThreadRead(threadId); + List messageIds = SignalDatabase.threads().setEntireThreadRead(threadId); ApplicationDependencies.getMessageNotifier().updateNotification(context); MarkReadReceiver.process(context, messageIds); @@ -273,7 +268,7 @@ final class MessageRequestRepository { } private GroupDatabase.MemberLevel getGroupMemberLevel(@NonNull RecipientId recipientId) { - return DatabaseFactory.getGroupDatabase(context) + return SignalDatabase.groups() .getGroup(recipientId) .transform(g -> g.memberLevel(Recipient.self())) .or(GroupDatabase.MemberLevel.NOT_A_MEMBER); @@ -283,7 +278,7 @@ final class MessageRequestRepository { @WorkerThread private boolean isLegacyThread(@NonNull Recipient recipient) { Context context = ApplicationDependencies.getApplication(); - Long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipient.getId()); + Long threadId = SignalDatabase.threads().getThreadIdFor(recipient.getId()); return threadId != null && (RecipientUtil.hasSentMessageInThread(context, threadId) || RecipientUtil.isPreMessageRequestThread(context, threadId)); diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/GroupSendUtil.java b/app/src/main/java/org/thoughtcrime/securesms/messages/GroupSendUtil.java index 166689f21d..c19e539956 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/GroupSendUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/GroupSendUtil.java @@ -9,9 +9,9 @@ import androidx.annotation.WorkerThread; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.crypto.SenderKeyUtil; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord; import org.thoughtcrime.securesms.database.MessageSendLogDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.MessageId; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupId; @@ -164,7 +164,7 @@ public final class GroupSendUtil { List registeredTargets = allTargets.stream().filter(r -> !unregisteredTargets.contains(r)).collect(Collectors.toList()); RecipientData recipients = new RecipientData(context, registeredTargets); - Optional groupRecord = groupId != null ? DatabaseFactory.getGroupDatabase(context).getGroup(groupId) : Optional.absent(); + Optional groupRecord = groupId != null ? SignalDatabase.groups().getGroup(groupId) : Optional.absent(); List senderKeyTargets = new LinkedList<>(); List legacyTargets = new LinkedList<>(); @@ -211,7 +211,7 @@ public final class GroupSendUtil { SignalServiceMessageSender messageSender = ApplicationDependencies.getSignalServiceMessageSender(); if (senderKeyTargets.size() > 0 && groupId != null) { - DistributionId distributionId = DatabaseFactory.getGroupDatabase(context).getOrCreateDistributionId(groupId); + DistributionId distributionId = SignalDatabase.groups().getOrCreateDistributionId(groupId); long keyCreateTime = SenderKeyUtil.getCreateTimeForOurKey(context, distributionId); long keyAge = System.currentTimeMillis() - keyCreateTime; @@ -231,7 +231,7 @@ public final class GroupSendUtil { Log.d(TAG, "Successfully sent using sender key to " + successCount + "/" + targets.size() + " sender key targets."); if (sendOperation.shouldIncludeInMessageLog()) { - DatabaseFactory.getMessageLogDatabase(context).insertIfPossible(sendOperation.getSentTimestamp(), senderKeyTargets, results, sendOperation.getContentHint(), sendOperation.getRelatedMessageId()); + SignalDatabase.messageLog().insertIfPossible(sendOperation.getSentTimestamp(), senderKeyTargets, results, sendOperation.getContentHint(), sendOperation.getRelatedMessageId()); } if (relatedMessageId != null) { @@ -275,7 +275,7 @@ public final class GroupSendUtil { List> access = legacyTargets.stream().map(r -> recipients.getAccessPair(r.getId())).collect(Collectors.toList()); boolean recipientUpdate = isRecipientUpdate || allResults.size() > 0; - final MessageSendLogDatabase messageLogDatabase = DatabaseFactory.getMessageLogDatabase(context); + final MessageSendLogDatabase messageLogDatabase = SignalDatabase.messageLog(); final AtomicLong entryId = new AtomicLong(-1); final boolean includeInMessageLog = sendOperation.shouldIncludeInMessageLog(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/IncomingMessageProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/messages/IncomingMessageProcessor.java index 2f8d13b89d..7546df0591 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/IncomingMessageProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/IncomingMessageProcessor.java @@ -9,10 +9,10 @@ import androidx.annotation.Nullable; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.crypto.ReentrantSessionLock; import org.thoughtcrime.securesms.crypto.IdentityKeyUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId; import org.thoughtcrime.securesms.database.MmsSmsDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.BadGroupIdException; import org.thoughtcrime.securesms.groups.GroupChangeBusyException; @@ -73,7 +73,7 @@ public class IncomingMessageProcessor { private Processor(@NonNull Context context) { this.context = context; - this.mmsSmsDatabase = DatabaseFactory.getMmsSmsDatabase(context); + this.mmsSmsDatabase = SignalDatabase.mmsSms(); this.jobManager = ApplicationDependencies.getJobManager(); } @@ -163,7 +163,7 @@ public class IncomingMessageProcessor { Log.i(TAG, "Received server receipt. Sender: " + sender.getId() + ", Device: " + envelope.getSourceDevice() + ", Timestamp: " + envelope.getTimestamp()); mmsSmsDatabase.incrementDeliveryReceiptCount(new SyncMessageId(sender.getId(), envelope.getTimestamp()), System.currentTimeMillis()); - DatabaseFactory.getMessageLogDatabase(context).deleteEntryForRecipient(envelope.getTimestamp(), sender.getId(), envelope.getSourceDevice()); + SignalDatabase.messageLog().deleteEntryForRecipient(envelope.getTimestamp(), sender.getId(), envelope.getSourceDevice()); } private boolean needsToEnqueueDecryption() { @@ -181,7 +181,7 @@ public class IncomingMessageProcessor { if (groupId.isV2()) { String queueName = PushProcessMessageJob.getQueueName(Recipient.externalPossiblyMigratedGroup(context, groupId).getId()); - GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); + GroupDatabase groupDatabase = SignalDatabase.groups(); return !jobManager.isQueueEmpty(queueName) || groupContext.getGroupV2().get().getRevision() > groupDatabase.getGroupV2Revision(groupId.requireV2()) || diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessor.java index b882939968..aa6593c8f9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessor.java @@ -27,7 +27,6 @@ import org.thoughtcrime.securesms.crypto.ProfileKeyUtil; import org.thoughtcrime.securesms.crypto.SecurityEvent; import org.thoughtcrime.securesms.crypto.SessionUtil; import org.thoughtcrime.securesms.database.AttachmentDatabase; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord; import org.thoughtcrime.securesms.database.GroupReceiptDatabase; @@ -39,6 +38,7 @@ import org.thoughtcrime.securesms.database.MmsSmsDatabase; import org.thoughtcrime.securesms.database.PaymentDatabase; import org.thoughtcrime.securesms.database.PaymentMetaDataUtil; import org.thoughtcrime.securesms.database.RecipientDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.StickerDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.database.model.Mention; @@ -239,7 +239,7 @@ public final class MessageContentProcessor { log(String.valueOf(content.getTimestamp()), "Beginning message processing. Sender: " + formatSender(senderRecipient, content)); if (content.getDataMessage().isPresent()) { - GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); + GroupDatabase groupDatabase = SignalDatabase.groups(); SignalServiceDataMessage message = content.getDataMessage().get(); boolean isMediaMessage = message.getAttachments().isPresent() || message.getQuote().isPresent() || message.getSharedContacts().isPresent() || message.getPreviews().isPresent() || message.getSticker().isPresent() || message.getMentions().isPresent(); Optional groupId = GroupUtil.idFromGroupContext(message.getGroupContext()); @@ -286,7 +286,7 @@ public final class MessageContentProcessor { } else if (!threadRecipient.isGroup()) { Log.i(TAG, "Message was to a 1:1. Ensuring this user has our profile key."); ApplicationDependencies.getJobManager().startChain(new RefreshAttributesJob(false)) - .then(ProfileKeySendJob.create(context, DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(threadRecipient), true)) + .then(ProfileKeySendJob.create(context, SignalDatabase.threads().getOrCreateThreadIdFor(threadRecipient), true)) .enqueue(); } } @@ -362,10 +362,10 @@ public final class MessageContentProcessor { if (pending != null) { warn(content.getTimestamp(), "Incoming message matches a pending retry we were expecting."); - Long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(destination.getId()); + Long threadId = SignalDatabase.threads().getThreadIdFor(destination.getId()); if (threadId != null) { - ThreadDatabase.ConversationMetadata metadata = DatabaseFactory.getThreadDatabase(context).getConversationMetadata(threadId); + ThreadDatabase.ConversationMetadata metadata = SignalDatabase.threads().getConversationMetadata(threadId); long visibleThread = ApplicationDependencies.getMessageNotifier().getVisibleThread(); if (threadId != visibleThread && metadata.getLastSeen() > 0 && metadata.getLastSeen() < pending.getReceivedTimestamp()) { @@ -393,7 +393,7 @@ public final class MessageContentProcessor { } SignalServiceDataMessage.PaymentNotification paymentNotification = message.getPayment().get().getPaymentNotification().get(); - PaymentDatabase paymentDatabase = DatabaseFactory.getPaymentDatabase(context); + PaymentDatabase paymentDatabase = SignalDatabase.payments(); UUID uuid = UUID.randomUUID(); String queue = "Payment_" + PushProcessMessageJob.getQueueName(senderRecipient.getId()); @@ -424,7 +424,7 @@ public final class MessageContentProcessor { private boolean handleGv2PreProcessing(@NonNull GroupId.V2 groupId, @NonNull SignalServiceContent content, @NonNull SignalServiceGroupV2 groupV2, @NonNull Recipient senderRecipient) throws IOException, GroupChangeBusyException { - GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); + GroupDatabase groupDatabase = SignalDatabase.groups(); Optional possibleGv1 = groupDatabase.getGroupV1ByExpectedV2(groupId); if (possibleGv1.isPresent()) { @@ -548,7 +548,7 @@ public final class MessageContentProcessor { log(String.valueOf(content.getTimestamp()), "handleCallOfferMessage..."); if (smsMessageId.isPresent()) { - MessageDatabase database = DatabaseFactory.getSmsDatabase(context); + MessageDatabase database = SignalDatabase.sms(); database.markAsMissedCall(smsMessageId.get(), message.getType() == OfferMessage.Type.VIDEO_CALL); } else { RemotePeer remotePeer = new RemotePeer(senderRecipient.getId(), new CallId(message.getId())); @@ -606,7 +606,7 @@ public final class MessageContentProcessor { { log(String.valueOf(content), "handleCallHangupMessage"); if (smsMessageId.isPresent()) { - DatabaseFactory.getSmsDatabase(context).markAsMissedCall(smsMessageId.get(), false); + SignalDatabase.sms().markAsMissedCall(smsMessageId.get(), false); } else { RemotePeer remotePeer = new RemotePeer(senderRecipient.getId(), new CallId(message.getId())); @@ -656,9 +656,9 @@ public final class MessageContentProcessor { return; } - RecipientId groupRecipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromPossiblyMigratedGroupId(groupId.get()); + RecipientId groupRecipientId = SignalDatabase.recipients().getOrInsertFromPossiblyMigratedGroupId(groupId.get()); - DatabaseFactory.getSmsDatabase(context).insertOrUpdateGroupCall(groupRecipientId, + SignalDatabase.sms().insertOrUpdateGroupCall(groupRecipientId, senderRecipient.getId(), content.getServerReceivedTimestamp(), message.getGroupCallUpdate().get().getEraId()); @@ -670,7 +670,7 @@ public final class MessageContentProcessor { @NonNull Optional smsMessageId, @NonNull Recipient senderRecipient) { - MessageDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context); + MessageDatabase smsDatabase = SignalDatabase.sms(); IncomingTextMessage incomingTextMessage = new IncomingTextMessage(senderRecipient.getId(), content.getSenderDevice(), content.getTimestamp(), @@ -708,12 +708,12 @@ public final class MessageContentProcessor { private long handleSynchronizeSentEndSessionMessage(@NonNull SentTranscriptMessage message) throws BadGroupIdException { - MessageDatabase database = DatabaseFactory.getSmsDatabase(context); + MessageDatabase database = SignalDatabase.sms(); Recipient recipient = getSyncMessageDestination(message); OutgoingTextMessage outgoingTextMessage = new OutgoingTextMessage(recipient, "", -1); OutgoingEndSessionMessage outgoingEndSessionMessage = new OutgoingEndSessionMessage(outgoingTextMessage); - long threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient); + long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(recipient); if (!recipient.isGroup()) { ApplicationDependencies.getSessionStore().deleteAllSessions(recipient.requireServiceId()); @@ -726,7 +726,7 @@ public final class MessageContentProcessor { message.getTimestamp(), null); database.markAsSent(messageId, true); - DatabaseFactory.getThreadDatabase(context).update(threadId, true); + SignalDatabase.threads().update(threadId, true); } return threadId; @@ -748,7 +748,7 @@ public final class MessageContentProcessor { } if (smsMessageId.isPresent()) { - DatabaseFactory.getSmsDatabase(context).deleteMessage(smsMessageId.get()); + SignalDatabase.sms().deleteMessage(smsMessageId.get()); } } @@ -766,7 +766,7 @@ public final class MessageContentProcessor { } } else if (group.getGroupV2().isPresent()) { warn(content.getTimestamp(), "Received a GV2 message for a group we have no knowledge of -- attempting to fix this state."); - DatabaseFactory.getGroupDatabase(context).fixMissingMasterKey(group.getGroupV2().get().getMasterKey()); + SignalDatabase.groups().fixMissingMasterKey(group.getGroupV2().get().getMasterKey()); } else { warn(content.getTimestamp(), "Received a message for a group we don't know about without a group context. Ignoring."); } @@ -795,7 +795,7 @@ public final class MessageContentProcessor { } try { - MessageDatabase database = DatabaseFactory.getMmsDatabase(context); + MessageDatabase database = SignalDatabase.mms(); IncomingMediaMessage mediaMessage = new IncomingMediaMessage(senderRecipient.getId(), content.getTimestamp(), content.getServerReceivedTimestamp(), @@ -817,10 +817,10 @@ public final class MessageContentProcessor { Optional insertResult = database.insertSecureDecryptedMessageInbox(mediaMessage, -1); - DatabaseFactory.getRecipientDatabase(context).setExpireMessages(threadRecipient.getId(), expiresInSeconds); + SignalDatabase.recipients().setExpireMessages(threadRecipient.getId(), expiresInSeconds); if (smsMessageId.isPresent()) { - DatabaseFactory.getSmsDatabase(context).deleteMessage(smsMessageId.get()); + SignalDatabase.sms().deleteMessage(smsMessageId.get()); } if (insertResult.isPresent()) { @@ -842,7 +842,7 @@ public final class MessageContentProcessor { } Recipient targetAuthor = Recipient.externalPush(context, reaction.getTargetAuthor()); - MessageRecord targetMessage = DatabaseFactory.getMmsSmsDatabase(context).getMessageFor(reaction.getTargetSentTimestamp(), targetAuthor.getId()); + MessageRecord targetMessage = SignalDatabase.mmsSms().getMessageFor(reaction.getTargetSentTimestamp(), targetAuthor.getId()); if (targetMessage == null) { warn(String.valueOf(content.getTimestamp()), "[handleReaction] Could not find matching message! Putting it in the early message cache. timestamp: " + reaction.getTargetSentTimestamp() + " author: " + targetAuthor.getId()); @@ -855,7 +855,7 @@ public final class MessageContentProcessor { return null; } - ThreadRecord targetThread = DatabaseFactory.getThreadDatabase(context).getThreadRecord(targetMessage.getThreadId()); + ThreadRecord targetThread = SignalDatabase.threads().getThreadRecord(targetMessage.getThreadId()); if (targetThread == null) { warn(String.valueOf(content.getTimestamp()), "[handleReaction] Could not find a thread for the message! timestamp: " + reaction.getTargetSentTimestamp() + " author: " + targetAuthor.getId()); @@ -877,11 +877,11 @@ public final class MessageContentProcessor { MessageId targetMessageId = new MessageId(targetMessage.getId(), targetMessage.isMms()); if (reaction.isRemove()) { - DatabaseFactory.getReactionDatabase(context).deleteReaction(targetMessageId, senderRecipient.getId()); + SignalDatabase.reactions().deleteReaction(targetMessageId, senderRecipient.getId()); ApplicationDependencies.getMessageNotifier().updateNotification(context); } else { ReactionRecord reactionRecord = new ReactionRecord(reaction.getEmoji(), senderRecipient.getId(), message.getTimestamp(), System.currentTimeMillis()); - DatabaseFactory.getReactionDatabase(context).addReaction(targetMessageId, reactionRecord); + SignalDatabase.reactions().addReaction(targetMessageId, reactionRecord); ApplicationDependencies.getMessageNotifier().updateNotification(context, targetMessage.getThreadId(), false); } @@ -891,10 +891,10 @@ public final class MessageContentProcessor { private @Nullable MessageId handleRemoteDelete(@NonNull SignalServiceContent content, @NonNull SignalServiceDataMessage message, @NonNull Recipient senderRecipient) { SignalServiceDataMessage.RemoteDelete delete = message.getRemoteDelete().get(); - MessageRecord targetMessage = DatabaseFactory.getMmsSmsDatabase(context).getMessageFor(delete.getTargetSentTimestamp(), senderRecipient.getId()); + MessageRecord targetMessage = SignalDatabase.mmsSms().getMessageFor(delete.getTargetSentTimestamp(), senderRecipient.getId()); if (targetMessage != null && RemoteDeleteUtil.isValidReceive(targetMessage, senderRecipient, content.getServerReceivedTimestamp())) { - MessageDatabase db = targetMessage.isMms() ? DatabaseFactory.getMmsDatabase(context) : DatabaseFactory.getSmsDatabase(context); + MessageDatabase db = targetMessage.isMms() ? SignalDatabase.mms() : SignalDatabase.sms(); db.markAsRemoteDelete(targetMessage.getId()); ApplicationDependencies.getMessageNotifier().updateNotification(context, targetMessage.getThreadId(), false); return new MessageId(targetMessage.getId(), targetMessage.isMms()); @@ -926,7 +926,7 @@ public final class MessageContentProcessor { jobManager.add(StickerPackDownloadJob.forInstall(packId, packKey, false)); break; case REMOVE: - DatabaseFactory.getStickerDatabase(context).uninstallPack(packId); + SignalDatabase.stickers().uninstallPack(packId); break; } } else { @@ -954,7 +954,7 @@ public final class MessageContentProcessor { } private void handleSynchronizeBlockedListMessage(@NonNull BlockedListMessage blockMessage) { - DatabaseFactory.getRecipientDatabase(context).applyBlockedUpdate(blockMessage.getAddresses(), blockMessage.getGroupIds()); + SignalDatabase.recipients().applyBlockedUpdate(blockMessage.getAddresses(), blockMessage.getGroupIds()); } private void handleSynchronizeFetchMessage(@NonNull SignalServiceSyncMessage.FetchType fetchType) { @@ -975,8 +975,8 @@ public final class MessageContentProcessor { private void handleSynchronizeMessageRequestResponse(@NonNull MessageRequestResponseMessage response) throws BadGroupIdException { - RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); + RecipientDatabase recipientDatabase = SignalDatabase.recipients(); + ThreadDatabase threadDatabase = SignalDatabase.threads(); Recipient recipient; @@ -1034,7 +1034,7 @@ public final class MessageContentProcessor { UUID uuid = UUID.randomUUID(); try { - DatabaseFactory.getPaymentDatabase(context) + SignalDatabase.payments() .createSuccessfulPayment(uuid, recipientId, address.get(), @@ -1060,7 +1060,7 @@ public final class MessageContentProcessor { log(String.valueOf(content.getTimestamp()), "Processing sent transcript for message with ID " + message.getTimestamp()); try { - GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); + GroupDatabase groupDatabase = SignalDatabase.groups(); if (message.getMessage().isGroupV2Message()) { GroupId.V2 groupId = GroupId.v2(message.getMessage().getGroupContext().get().getGroupV2().get().getMasterKey()); @@ -1080,7 +1080,7 @@ public final class MessageContentProcessor { threadId = gv1ThreadId == null ? -1 : gv1ThreadId; } else if (message.getMessage().isGroupV2Update()) { handleSynchronizeSentGv2Update(content, message); - threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(getSyncMessageDestination(message)); + threadId = SignalDatabase.threads().getOrCreateThreadIdFor(getSyncMessageDestination(message)); } else if (Build.VERSION.SDK_INT > 19 && message.getMessage().getGroupCallUpdate().isPresent()) { handleGroupCallUpdateMessage(content, message.getMessage(), GroupUtil.idFromGroupContext(message.getMessage().getGroupContext()), senderRecipient); } else if (message.getMessage().isEmptyGroupV2Message()) { @@ -1089,7 +1089,7 @@ public final class MessageContentProcessor { threadId = handleSynchronizeSentExpirationUpdate(message); } else if (message.getMessage().getReaction().isPresent()) { handleReaction(content, message.getMessage(), senderRecipient); - threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(getSyncMessageDestination(message)); + threadId = SignalDatabase.threads().getOrCreateThreadIdFor(getSyncMessageDestination(message)); } else if (message.getMessage().getRemoteDelete().isPresent()) { handleRemoteDelete(content, message.getMessage(), senderRecipient); } else if (message.getMessage().getAttachments().isPresent() || message.getMessage().getQuote().isPresent() || message.getMessage().getPreviews().isPresent() || message.getMessage().getSticker().isPresent() || message.getMessage().isViewOnce() || message.getMessage().getMentions().isPresent()) { @@ -1106,12 +1106,12 @@ public final class MessageContentProcessor { Recipient recipient = getSyncMessageDestination(message); if (recipient != null && !recipient.isSystemContact() && !recipient.isProfileSharing()) { - DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient.getId(), true); + SignalDatabase.recipients().setProfileSharing(recipient.getId(), true); } } if (threadId != -1) { - DatabaseFactory.getThreadDatabase(context).setRead(threadId, true); + SignalDatabase.threads().setRead(threadId, true); ApplicationDependencies.getMessageNotifier().updateNotification(context); } @@ -1169,12 +1169,12 @@ public final class MessageContentProcessor { { Map threadToLatestRead = new HashMap<>(); for (ReadMessage readMessage : readMessages) { - List> expiringText = DatabaseFactory.getSmsDatabase(context).setTimestampRead(new SyncMessageId(senderRecipient.getId(), readMessage.getTimestamp()), - envelopeTimestamp, - threadToLatestRead); - List> expiringMedia = DatabaseFactory.getMmsDatabase(context).setTimestampRead(new SyncMessageId(senderRecipient.getId(), readMessage.getTimestamp()), - envelopeTimestamp, - threadToLatestRead); + List> expiringText = SignalDatabase.sms().setTimestampRead(new SyncMessageId(senderRecipient.getId(), readMessage.getTimestamp()), + envelopeTimestamp, + threadToLatestRead); + List> expiringMedia = SignalDatabase.mms().setTimestampRead(new SyncMessageId(senderRecipient.getId(), readMessage.getTimestamp()), + envelopeTimestamp, + threadToLatestRead); for (Pair expiringMessage : expiringText) { ApplicationDependencies.getExpiringMessageManager() @@ -1187,7 +1187,7 @@ public final class MessageContentProcessor { } } - List markedMessages = DatabaseFactory.getThreadDatabase(context).setReadSince(threadToLatestRead, false); + List markedMessages = SignalDatabase.threads().setReadSince(threadToLatestRead, false); if (Util.hasItems(markedMessages)) { Log.i(TAG, "Updating past messages: " + markedMessages.size()); MarkReadReceiver.process(context, markedMessages); @@ -1203,13 +1203,13 @@ public final class MessageContentProcessor { List toMarkViewed = Stream.of(viewedMessages) .map(message -> { RecipientId author = Recipient.externalPush(context, message.getSender()).getId(); - return DatabaseFactory.getMmsSmsDatabase(context).getMessageFor(message.getTimestamp(), author); + return SignalDatabase.mmsSms().getMessageFor(message.getTimestamp(), author); }) .filter(message -> message != null && message.isMms()) .map(MessageRecord::getId) .toList(); - DatabaseFactory.getMmsDatabase(context).setIncomingMessagesViewed(toMarkViewed); + SignalDatabase.mms().setIncomingMessagesViewed(toMarkViewed); MessageNotifier messageNotifier = ApplicationDependencies.getMessageNotifier(); messageNotifier.setLastDesktopActivityTimestamp(envelopeTimestamp); @@ -1222,10 +1222,10 @@ public final class MessageContentProcessor { RecipientId author = Recipient.externalPush(context, openMessage.getSender()).getId(); long timestamp = openMessage.getTimestamp(); - MessageRecord record = DatabaseFactory.getMmsSmsDatabase(context).getMessageFor(timestamp, author); + MessageRecord record = SignalDatabase.mmsSms().getMessageFor(timestamp, author); if (record != null && record.isMms()) { - DatabaseFactory.getAttachmentDatabase(context).deleteAttachmentFilesForViewOnceMessage(record.getId()); + SignalDatabase.attachments().deleteAttachmentFilesForViewOnceMessage(record.getId()); } else { warn(String.valueOf(envelopeTimestamp), "Got a view-once open message for a message we don't have!"); } @@ -1248,7 +1248,7 @@ public final class MessageContentProcessor { Optional insertResult; - MessageDatabase database = DatabaseFactory.getMmsDatabase(context); + MessageDatabase database = SignalDatabase.mms(); database.beginTransaction(); try { @@ -1281,7 +1281,7 @@ public final class MessageContentProcessor { if (insertResult.isPresent()) { if (smsMessageId.isPresent()) { - DatabaseFactory.getSmsDatabase(context).deleteMessage(smsMessageId.get()); + SignalDatabase.sms().deleteMessage(smsMessageId.get()); } database.setTransactionSuccessful(); @@ -1293,7 +1293,7 @@ public final class MessageContentProcessor { } if (insertResult.isPresent()) { - List allAttachments = DatabaseFactory.getAttachmentDatabase(context).getAttachmentsForMessage(insertResult.get().getMessageId()); + List allAttachments = SignalDatabase.attachments().getAttachmentsForMessage(insertResult.get().getMessageId()); List stickerAttachments = Stream.of(allAttachments).filter(Attachment::isSticker).toList(); List attachments = Stream.of(allAttachments).filterNot(Attachment::isSticker).toList(); @@ -1319,19 +1319,19 @@ public final class MessageContentProcessor { private long handleSynchronizeSentExpirationUpdate(@NonNull SentTranscriptMessage message) throws MmsException, BadGroupIdException { - MessageDatabase database = DatabaseFactory.getMmsDatabase(context); + MessageDatabase database = SignalDatabase.mms(); Recipient recipient = getSyncMessageDestination(message); OutgoingExpirationUpdateMessage expirationUpdateMessage = new OutgoingExpirationUpdateMessage(recipient, message.getTimestamp(), TimeUnit.SECONDS.toMillis(message.getMessage().getExpiresInSeconds())); - long threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient); + long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(recipient); long messageId = database.insertMessageOutbox(expirationUpdateMessage, threadId, false, null); database.markAsSent(messageId, true); - DatabaseFactory.getRecipientDatabase(context).setExpireMessages(recipient.getId(), message.getMessage().getExpiresInSeconds()); + SignalDatabase.recipients().setExpireMessages(recipient.getId(), message.getMessage().getExpiresInSeconds()); return threadId; } @@ -1339,7 +1339,7 @@ public final class MessageContentProcessor { private long handleSynchronizeSentMediaMessage(@NonNull SentTranscriptMessage message) throws MmsException, BadGroupIdException { - MessageDatabase database = DatabaseFactory.getMmsDatabase(context); + MessageDatabase database = SignalDatabase.mms(); Recipient recipients = getSyncMessageDestination(message); Optional quote = getValidatedQuote(message.getMessage().getQuote()); Optional sticker = getStickerAttachment(message.getMessage().getSticker()); @@ -1371,7 +1371,7 @@ public final class MessageContentProcessor { handleSynchronizeSentExpirationUpdate(message); } - long threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipients); + long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(recipients); long messageId; List attachments; @@ -1389,7 +1389,7 @@ public final class MessageContentProcessor { database.markAsSent(messageId, true); - List allAttachments = DatabaseFactory.getAttachmentDatabase(context).getAttachmentsForMessage(messageId); + List allAttachments = SignalDatabase.attachments().getAttachmentsForMessage(messageId); stickerAttachments = Stream.of(allAttachments).filter(Attachment::isSticker).toList(); attachments = Stream.of(allAttachments).filterNot(Attachment::isSticker).toList(); @@ -1405,8 +1405,8 @@ public final class MessageContentProcessor { if (recipients.isSelf()) { SyncMessageId id = new SyncMessageId(recipients.getId(), message.getTimestamp()); - DatabaseFactory.getMmsSmsDatabase(context).incrementDeliveryReceiptCount(id, System.currentTimeMillis()); - DatabaseFactory.getMmsSmsDatabase(context).incrementReadReceiptCount(id, System.currentTimeMillis()); + SignalDatabase.mmsSms().incrementDeliveryReceiptCount(id, System.currentTimeMillis()); + SignalDatabase.mmsSms().incrementReadReceiptCount(id, System.currentTimeMillis()); } database.setTransactionSuccessful(); @@ -1433,7 +1433,7 @@ public final class MessageContentProcessor { return; } - MmsSmsDatabase database = DatabaseFactory.getMmsSmsDatabase(context); + MmsSmsDatabase database = SignalDatabase.mmsSms(); MessageRecord record = database.getMessageFor(message.getTimestamp(), Recipient.self().getId()); if (record == null) { @@ -1450,9 +1450,9 @@ public final class MessageContentProcessor { } private void updateGroupReceiptStatus(@NonNull SentTranscriptMessage message, long messageId, @NonNull GroupId groupString) { - GroupReceiptDatabase receiptDatabase = DatabaseFactory.getGroupReceiptDatabase(context); + GroupReceiptDatabase receiptDatabase = SignalDatabase.groupReceipts(); List messageRecipientIds = Stream.of(message.getRecipients()).map(RecipientId::from).toList(); - List members = DatabaseFactory.getGroupDatabase(context).getGroupMembers(groupString, GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF); + List members = SignalDatabase.groups().getGroupMembers(groupString, GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF); Map localReceipts = Stream.of(receiptDatabase.getGroupReceiptInfo(messageId)) .collect(Collectors.toMap(GroupReceiptInfo::getRecipientId, GroupReceiptInfo::getStatus)); @@ -1480,7 +1480,7 @@ public final class MessageContentProcessor { long receivedTime) throws StorageFailedException { - MessageDatabase database = DatabaseFactory.getSmsDatabase(context); + MessageDatabase database = SignalDatabase.sms(); String body = message.getBody().isPresent() ? message.getBody().get() : ""; if (message.getExpiresInSeconds() != threadRecipient.getExpiresInSeconds()) { @@ -1530,7 +1530,7 @@ public final class MessageContentProcessor { handleSynchronizeSentExpirationUpdate(message); } - long threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient); + long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(recipient); boolean isGroup = recipient.isGroup(); MessageDatabase database; @@ -1551,17 +1551,17 @@ public final class MessageContentProcessor { Collections.emptyList()); outgoingMediaMessage = new OutgoingSecureMediaMessage(outgoingMediaMessage); - messageId = DatabaseFactory.getMmsDatabase(context).insertMessageOutbox(outgoingMediaMessage, threadId, false, GroupReceiptDatabase.STATUS_UNKNOWN, null); - database = DatabaseFactory.getMmsDatabase(context); + messageId = SignalDatabase.mms().insertMessageOutbox(outgoingMediaMessage, threadId, false, GroupReceiptDatabase.STATUS_UNKNOWN, null); + database = SignalDatabase.mms(); updateGroupReceiptStatus(message, messageId, recipient.requireGroupId()); } else { OutgoingTextMessage outgoingTextMessage = new OutgoingEncryptedMessage(recipient, body, expiresInMillis); - messageId = DatabaseFactory.getSmsDatabase(context).insertMessageOutbox(threadId, outgoingTextMessage, false, message.getTimestamp(), null); - database = DatabaseFactory.getSmsDatabase(context); + messageId = SignalDatabase.sms().insertMessageOutbox(threadId, outgoingTextMessage, false, message.getTimestamp(), null); + database = SignalDatabase.sms(); database.markUnidentified(messageId, isUnidentified(message, recipient)); - DatabaseFactory.getThreadDatabase(context).update(threadId, true); + SignalDatabase.threads().update(threadId, true); } database.markAsSent(messageId, true); @@ -1574,8 +1574,8 @@ public final class MessageContentProcessor { if (recipient.isSelf()) { SyncMessageId id = new SyncMessageId(recipient.getId(), message.getTimestamp()); - DatabaseFactory.getMmsSmsDatabase(context).incrementDeliveryReceiptCount(id, System.currentTimeMillis()); - DatabaseFactory.getMmsSmsDatabase(context).incrementReadReceiptCount(id, System.currentTimeMillis()); + SignalDatabase.mmsSms().incrementDeliveryReceiptCount(id, System.currentTimeMillis()); + SignalDatabase.mmsSms().incrementReadReceiptCount(id, System.currentTimeMillis()); } return threadId; @@ -1584,7 +1584,7 @@ public final class MessageContentProcessor { private void handleInvalidVersionMessage(@NonNull String sender, int senderDevice, long timestamp, @NonNull Optional smsMessageId) { - MessageDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context); + MessageDatabase smsDatabase = SignalDatabase.sms(); if (!smsMessageId.isPresent()) { Optional insertResult = insertPlaceholder(sender, senderDevice, timestamp); @@ -1601,7 +1601,7 @@ public final class MessageContentProcessor { private void handleCorruptMessage(@NonNull String sender, int senderDevice, long timestamp, @NonNull Optional smsMessageId) { - MessageDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context); + MessageDatabase smsDatabase = SignalDatabase.sms(); if (!smsMessageId.isPresent()) { Optional insertResult = insertPlaceholder(sender, senderDevice, timestamp); @@ -1621,7 +1621,7 @@ public final class MessageContentProcessor { long timestamp, @NonNull Optional smsMessageId) { - MessageDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context); + MessageDatabase smsDatabase = SignalDatabase.sms(); if (!smsMessageId.isPresent()) { Optional insertResult = insertPlaceholder(sender, senderDevice, timestamp, groupId); @@ -1641,7 +1641,7 @@ public final class MessageContentProcessor { long timestamp, @NonNull Optional smsMessageId) { - MessageDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context); + MessageDatabase smsDatabase = SignalDatabase.sms(); if (!smsMessageId.isPresent()) { Optional insertResult = insertPlaceholder(sender.getIdentifier(), senderDevice, timestamp, groupId); @@ -1658,7 +1658,7 @@ public final class MessageContentProcessor { private void handleLegacyMessage(@NonNull String sender, int senderDevice, long timestamp, @NonNull Optional smsMessageId) { - MessageDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context); + MessageDatabase smsDatabase = SignalDatabase.sms(); if (!smsMessageId.isPresent()) { Optional insertResult = insertPlaceholder(sender, senderDevice, timestamp); @@ -1676,7 +1676,7 @@ public final class MessageContentProcessor { @NonNull byte[] messageProfileKeyBytes, @NonNull Recipient senderRecipient) { - RecipientDatabase database = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase database = SignalDatabase.recipients(); ProfileKey messageProfileKey = ProfileKeyUtil.profileKeyOrNull(messageProfileKeyBytes); if (messageProfileKey != null) { @@ -1710,7 +1710,7 @@ public final class MessageContentProcessor { .map(t -> new SyncMessageId(senderRecipient.getId(), t)) .toList(); - Collection unhandled = DatabaseFactory.getMmsSmsDatabase(context) + Collection unhandled = SignalDatabase.mmsSms() .incrementViewedReceiptCounts(ids, content.getTimestamp()); for (SyncMessageId id : unhandled) { @@ -1730,8 +1730,8 @@ public final class MessageContentProcessor { .map(t -> new SyncMessageId(senderRecipient.getId(), t)) .toList(); - DatabaseFactory.getMmsSmsDatabase(context).incrementDeliveryReceiptCounts(ids, System.currentTimeMillis()); - DatabaseFactory.getMessageLogDatabase(context).deleteEntriesForRecipient(message.getTimestamps(), senderRecipient.getId(), content.getSenderDevice()); + SignalDatabase.mmsSms().incrementDeliveryReceiptCounts(ids, System.currentTimeMillis()); + SignalDatabase.messageLog().deleteEntriesForRecipient(message.getTimestamps(), senderRecipient.getId(), content.getSenderDevice()); } @SuppressLint("DefaultLocale") @@ -1750,7 +1750,7 @@ public final class MessageContentProcessor { .map(t -> new SyncMessageId(senderRecipient.getId(), t)) .toList(); - Collection unhandled = DatabaseFactory.getMmsSmsDatabase(context).incrementReadReceiptCounts(ids, content.getTimestamp()); + Collection unhandled = SignalDatabase.mmsSms().incrementReadReceiptCounts(ids, content.getTimestamp()); for (SyncMessageId id : unhandled) { warn(String.valueOf(content.getTimestamp()), "[handleReadReceipt] Could not find matching message! timestamp: " + id.getTimetamp() + " author: " + senderRecipient.getId()); @@ -1772,16 +1772,16 @@ public final class MessageContentProcessor { if (typingMessage.getGroupId().isPresent()) { GroupId.Push groupId = GroupId.push(typingMessage.getGroupId().get()); - if (!DatabaseFactory.getGroupDatabase(context).isCurrentMember(groupId, senderRecipient.getId())) { + if (!SignalDatabase.groups().isCurrentMember(groupId, senderRecipient.getId())) { warn(String.valueOf(content.getTimestamp()), "Seen typing indicator for non-member " + senderRecipient.getId()); return; } Recipient groupRecipient = Recipient.externalPossiblyMigratedGroup(context, groupId); - threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(groupRecipient); + threadId = SignalDatabase.threads().getOrCreateThreadIdFor(groupRecipient); } else { - threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(senderRecipient); + threadId = SignalDatabase.threads().getOrCreateThreadIdFor(senderRecipient); } if (threadId <= 0) { @@ -1813,7 +1813,7 @@ public final class MessageContentProcessor { return; } - MessageLogEntry messageLogEntry = DatabaseFactory.getMessageLogDatabase(context).getLogEntry(senderRecipient.getId(), content.getSenderDevice(), sentTimestamp); + MessageLogEntry messageLogEntry = SignalDatabase.messageLog().getLogEntry(senderRecipient.getId(), content.getSenderDevice(), sentTimestamp); if (decryptionErrorMessage.getRatchetKey().isPresent()) { handleIndividualRetryReceipt(senderRecipient, messageLogEntry, content, decryptionErrorMessage); @@ -1835,7 +1835,7 @@ public final class MessageContentProcessor { return; } - Recipient threadRecipient = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(relatedMessage.getThreadId()); + Recipient threadRecipient = SignalDatabase.threads().getRecipientForThreadId(relatedMessage.getThreadId()); if (threadRecipient == null) { warn(content.getTimestamp(), "[RetryReceipt-SK] Could not find a thread recipient! Skipping."); return; @@ -1847,10 +1847,10 @@ public final class MessageContentProcessor { } GroupId.V2 groupId = threadRecipient.requireGroupId().requireV2(); - DistributionId distributionId = DatabaseFactory.getGroupDatabase(context).getOrCreateDistributionId(groupId); + DistributionId distributionId = SignalDatabase.groups().getOrCreateDistributionId(groupId); SignalProtocolAddress requesterAddress = new SignalProtocolAddress(requester.requireAci().toString(), content.getSenderDevice()); - DatabaseFactory.getSenderKeySharedDatabase(context).delete(distributionId, Collections.singleton(requesterAddress)); + SignalDatabase.senderKeyShared().delete(distributionId, Collections.singleton(requesterAddress)); if (messageLogEntry != null) { warn(content.getTimestamp(), "[RetryReceipt-SK] Found MSL entry for " + requester.getId() + " (" + requesterAddress + ") with timestamp " + sentTimestamp + ". Scheduling a resend."); @@ -1864,7 +1864,7 @@ public final class MessageContentProcessor { } else { warn(content.getTimestamp(), "[RetryReceipt-SK] Unable to find MSL entry for " + requester.getId() + " (" + requesterAddress + ") with timestamp " + sentTimestamp + "."); - Optional groupRecord = DatabaseFactory.getGroupDatabase(context).getGroup(groupId); + Optional groupRecord = SignalDatabase.groups().getGroup(groupId); if (!groupRecord.isPresent()) { warn(content.getTimestamp(), "[RetryReceipt-SK] Could not find a record for the group!"); @@ -1914,12 +1914,12 @@ public final class MessageContentProcessor { MessageId relatedMessage = messageLogEntry.getRelatedMessages().get(0); if (relatedMessage.isMms()) { - return DatabaseFactory.getMmsDatabase(context).getMessageRecordOrNull(relatedMessage.getId()); + return SignalDatabase.mms().getMessageRecordOrNull(relatedMessage.getId()); } else { - return DatabaseFactory.getSmsDatabase(context).getMessageRecordOrNull(relatedMessage.getId()); + return SignalDatabase.sms().getMessageRecordOrNull(relatedMessage.getId()); } } else { - return DatabaseFactory.getMmsSmsDatabase(context).getMessageFor(sentTimestamp, Recipient.self().getId()); + return SignalDatabase.mmsSms().getMessageFor(sentTimestamp, Recipient.self().getId()); } } @@ -1952,7 +1952,7 @@ public final class MessageContentProcessor { } RecipientId author = Recipient.externalPush(context, quote.get().getAuthor()).getId(); - MessageRecord message = DatabaseFactory.getMmsSmsDatabase(context).getMessageFor(quote.get().getId(), author); + MessageRecord message = SignalDatabase.mmsSms().getMessageFor(quote.get().getId(), author); if (message != null && !message.isRemoteDelete()) { log("Found matching message record..."); @@ -1963,7 +1963,7 @@ public final class MessageContentProcessor { if (message.isMms()) { MmsMessageRecord mmsMessage = (MmsMessageRecord) message; - mentions.addAll(DatabaseFactory.getMentionDatabase(context).getMentionsForMessage(mmsMessage.getId())); + mentions.addAll(SignalDatabase.mentions().getMentionsForMessage(mmsMessage.getId())); if (mmsMessage.isViewOnce()) { attachments.add(new TombstoneAttachment(MediaUtil.VIEW_ONCE, true)); @@ -2009,7 +2009,7 @@ public final class MessageContentProcessor { int stickerId = sticker.get().getStickerId(); String emoji = sticker.get().getEmoji(); StickerLocator stickerLocator = new StickerLocator(packId, packKey, stickerId, emoji); - StickerDatabase stickerDatabase = DatabaseFactory.getStickerDatabase(context); + StickerDatabase stickerDatabase = SignalDatabase.stickers(); StickerRecord stickerRecord = stickerDatabase.getSticker(stickerLocator.getPackId(), stickerLocator.getStickerId(), false); if (stickerRecord != null) { @@ -2098,7 +2098,7 @@ public final class MessageContentProcessor { } private Optional insertPlaceholder(@NonNull String sender, int senderDevice, long timestamp, Optional groupId) { - MessageDatabase database = DatabaseFactory.getSmsDatabase(context); + MessageDatabase database = SignalDatabase.sms(); IncomingTextMessage textMessage = new IncomingTextMessage(Recipient.external(context, sender).getId(), senderDevice, timestamp, -1, System.currentTimeMillis(), "", groupId, 0, false, null); @@ -2128,7 +2128,7 @@ public final class MessageContentProcessor { } private void notifyTypingStoppedFromIncomingMessage(@NonNull Recipient senderRecipient, @NonNull Recipient conversationRecipient, int device) { - long threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(conversationRecipient); + long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(conversationRecipient); if (threadId > 0 && TextSecurePreferences.isTypingIndicatorsEnabled(context)) { Log.d(TAG, "Typing stopped on thread " + threadId + " due to an incoming message."); @@ -2145,7 +2145,7 @@ public final class MessageContentProcessor { if (conversation.isGroup() && conversation.isBlocked()) { return true; } else if (conversation.isGroup()) { - GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); + GroupDatabase groupDatabase = SignalDatabase.groups(); Optional groupId = GroupUtil.idFromGroupContext(message.getGroupContext()); if (groupId.isPresent() && @@ -2187,7 +2187,7 @@ public final class MessageContentProcessor { if (groupRecipient.isBlocked() || !groupRecipient.isActiveGroup()) { return true; } else { - Optional groupRecord = DatabaseFactory.getGroupDatabase(context).getGroup(groupId); + Optional groupRecord = SignalDatabase.groups().getGroup(groupId); return groupRecord.isPresent() && groupRecord.get().isAnnouncementGroup() && !groupRecord.get().getAdmins().contains(sender); } } @@ -2198,7 +2198,7 @@ public final class MessageContentProcessor { private void resetRecipientToPush(@NonNull Recipient recipient) { if (recipient.isForceSmsSelection()) { - DatabaseFactory.getRecipientDatabase(context).setForceSmsSelection(recipient.getId(), false); + SignalDatabase.recipients().setForceSmsSelection(recipient.getId(), false); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/MessageDecryptionUtil.java b/app/src/main/java/org/thoughtcrime/securesms/messages/MessageDecryptionUtil.java index 015929d6ec..a0707c7c57 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/MessageDecryptionUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/MessageDecryptionUtil.java @@ -26,7 +26,7 @@ import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.crypto.ReentrantSessionLock; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; import org.thoughtcrime.securesms.crypto.storage.SignalProtocolStoreImpl; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.BadGroupIdException; import org.thoughtcrime.securesms.groups.GroupId; @@ -147,15 +147,15 @@ public final class MessageDecryptionUtil { if (groupId.isPresent()) { Recipient groupRecipient = Recipient.externalPossiblyMigratedGroup(context, groupId.get()); - threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(groupRecipient); + threadId = SignalDatabase.threads().getOrCreateThreadIdFor(groupRecipient); } else { - threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(sender); + threadId = SignalDatabase.threads().getOrCreateThreadIdFor(sender); } switch (contentHint) { case DEFAULT: Log.w(TAG, "[" + envelope.getTimestamp() + "] Inserting an error right away because it's " + contentHint); - DatabaseFactory.getSmsDatabase(context).insertBadDecryptMessage(sender.getId(), senderDevice, envelope.getTimestamp(), receivedTimestamp, threadId); + SignalDatabase.sms().insertBadDecryptMessage(sender.getId(), senderDevice, envelope.getTimestamp(), receivedTimestamp, threadId); break; case RESENDABLE: Log.w(TAG, "[" + envelope.getTimestamp() + "] Inserting into pending retries store because it's " + contentHint); diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/AccountRecordMigrationJob.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/AccountRecordMigrationJob.java index 5bb0f0bea0..7b00933405 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/AccountRecordMigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/AccountRecordMigrationJob.java @@ -3,14 +3,13 @@ package org.thoughtcrime.securesms.migrations; import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.jobs.StorageSyncJob; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.util.TextSecurePreferences; /** * Marks the AccountRecord as dirty and runs a storage sync. Can be enqueued when we've added a new @@ -47,7 +46,7 @@ public class AccountRecordMigrationJob extends MigrationJob { return; } - DatabaseFactory.getRecipientDatabase(context).markNeedsSync(Recipient.self().getId()); + SignalDatabase.recipients().markNeedsSync(Recipient.self().getId()); ApplicationDependencies.getJobManager().add(new StorageSyncJob()); } 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 a76a547205..d20abcaa95 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplyUnknownFieldsToSelfMigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplyUnknownFieldsToSelfMigrationJob.java @@ -5,14 +5,13 @@ import androidx.annotation.NonNull; import com.google.protobuf.InvalidProtocolBufferException; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.RecipientDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.storage.StorageSyncHelper; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.signalservice.api.storage.SignalAccountRecord; import org.whispersystems.signalservice.api.storage.StorageId; import org.whispersystems.signalservice.internal.storage.protos.AccountRecord; @@ -56,7 +55,7 @@ public class ApplyUnknownFieldsToSelfMigrationJob extends MigrationJob { try { self = Recipient.self(); - settings = DatabaseFactory.getRecipientDatabase(context).getRecipientSettingsForSync(self.getId()); + settings = SignalDatabase.recipients().getRecipientSettingsForSync(self.getId()); } catch (RecipientDatabase.MissingRecipientException e) { Log.w(TAG, "Unable to find self"); return; diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/AttachmentCleanupMigrationJob.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/AttachmentCleanupMigrationJob.java index 4e0bbddf3b..49e19e203f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/AttachmentCleanupMigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/AttachmentCleanupMigrationJob.java @@ -3,7 +3,7 @@ package org.thoughtcrime.securesms.migrations; import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; @@ -36,7 +36,7 @@ public class AttachmentCleanupMigrationJob extends MigrationJob { @Override public void performMigration() { - int deletes = DatabaseFactory.getAttachmentDatabase(context).deleteAbandonedAttachmentFiles(); + int deletes = SignalDatabase.attachments().deleteAbandonedAttachmentFiles(); Log.i(TAG, "Deleted " + deletes + " abandoned attachments."); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/DatabaseMigrationJob.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/DatabaseMigrationJob.java index 443c42e4d4..fec8bec8bc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/DatabaseMigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/DatabaseMigrationJob.java @@ -2,7 +2,7 @@ package org.thoughtcrime.securesms.migrations; import androidx.annotation.NonNull; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; @@ -34,7 +34,7 @@ public class DatabaseMigrationJob extends MigrationJob { @Override public void performMigration() { - DatabaseFactory.getInstance(context).triggerDatabaseAccess(); + SignalDatabase.triggerDatabaseAccess(); } @Override 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 638eb39334..f0e274fdd2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/LegacyMigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/LegacyMigrationJob.java @@ -1,25 +1,20 @@ package org.thoughtcrime.securesms.migrations; import android.content.Context; -import android.database.Cursor; import androidx.annotation.NonNull; import androidx.preference.PreferenceManager; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.attachments.DatabaseAttachment; -import org.thoughtcrime.securesms.color.MaterialColor; -import org.thoughtcrime.securesms.contacts.avatars.ContactColorsLegacy; -import org.thoughtcrime.securesms.conversation.colors.ChatColorsMapper; -import org.thoughtcrime.securesms.conversation.colors.ChatColorsPalette; import org.thoughtcrime.securesms.crypto.IdentityKeyUtil; import org.thoughtcrime.securesms.crypto.MasterSecret; import org.thoughtcrime.securesms.database.AttachmentDatabase; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessageDatabase; import org.thoughtcrime.securesms.database.MmsDatabase; import org.thoughtcrime.securesms.database.MmsDatabase.Reader; import org.thoughtcrime.securesms.database.PushDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; @@ -111,7 +106,7 @@ public class LegacyMigrationJob extends MigrationJob { MasterSecret masterSecret = KeyCachingService.getMasterSecret(context); if (lastSeenVersion < SQLCIPHER && masterSecret != null) { - DatabaseFactory.getInstance(context).onApplicationLevelUpgrade(context, masterSecret, lastSeenVersion, (progress, total) -> { + SignalDatabase.onApplicationLevelUpgrade(context, masterSecret, lastSeenVersion, (progress, total) -> { Log.i(TAG, "onApplicationLevelUpgrade: " + progress + "/" + total); }); } else if (lastSeenVersion < SQLCIPHER) { @@ -235,7 +230,7 @@ public class LegacyMigrationJob extends MigrationJob { if (lastSeenVersion < COLOR_MIGRATION) { long startTime = System.currentTimeMillis(); //noinspection deprecation - DatabaseFactory.getRecipientDatabase(context).updateSystemContactColors(); + SignalDatabase.recipients().updateSystemContactColors(); Log.i(TAG, "Color migration took " + (System.currentTimeMillis() - startTime) + " ms"); } @@ -256,9 +251,9 @@ public class LegacyMigrationJob extends MigrationJob { } private void schedulePendingIncomingParts(Context context) { - final AttachmentDatabase attachmentDb = DatabaseFactory.getAttachmentDatabase(context); - final MessageDatabase mmsDb = DatabaseFactory.getMmsDatabase(context); - final List pendingAttachments = DatabaseFactory.getAttachmentDatabase(context).getPendingAttachments(); + final AttachmentDatabase attachmentDb = SignalDatabase.attachments(); + final MessageDatabase mmsDb = SignalDatabase.mms(); + final List pendingAttachments = SignalDatabase.attachments().getPendingAttachments(); Log.i(TAG, pendingAttachments.size() + " pending parts."); for (DatabaseAttachment attachment : pendingAttachments) { @@ -277,7 +272,7 @@ public class LegacyMigrationJob extends MigrationJob { } private static void scheduleMessagesInPushDatabase(@NonNull Context context) { - PushDatabase pushDatabase = DatabaseFactory.getPushDatabase(context); + PushDatabase pushDatabase = SignalDatabase.push(); JobManager jobManager = ApplicationDependencies.getJobManager(); try (PushDatabase.Reader pushReader = pushDatabase.readerFor(pushDatabase.getPending())) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/ProfileSharingUpdateMigrationJob.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/ProfileSharingUpdateMigrationJob.java index d1309d3641..d932b23fde 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/ProfileSharingUpdateMigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/ProfileSharingUpdateMigrationJob.java @@ -2,7 +2,7 @@ package org.thoughtcrime.securesms.migrations; import androidx.annotation.NonNull; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.keyvalue.SignalStore; @@ -35,7 +35,7 @@ public class ProfileSharingUpdateMigrationJob extends MigrationJob { @Override public void performMigration() { long messageRequestEnableTime = SignalStore.misc().getMessageRequestEnableTime(); - DatabaseFactory.getRecipientDatabase(context).markPreMessageRequestRecipientsAsProfileSharingEnabled(messageRequestEnableTime); + SignalDatabase.recipients().markPreMessageRequestRecipientsAsProfileSharingEnabled(messageRequestEnableTime); } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/StickerLaunchMigrationJob.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/StickerLaunchMigrationJob.java index 4a37a61c20..908ecb81f2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/StickerLaunchMigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/StickerLaunchMigrationJob.java @@ -4,7 +4,7 @@ import android.content.Context; import androidx.annotation.NonNull; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.StickerDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; @@ -50,7 +50,7 @@ public class StickerLaunchMigrationJob extends MigrationJob { private static void installPack(@NonNull Context context, @NonNull BlessedPacks.Pack pack) { JobManager jobManager = ApplicationDependencies.getJobManager(); - StickerDatabase stickerDatabase = DatabaseFactory.getStickerDatabase(context); + StickerDatabase stickerDatabase = SignalDatabase.stickers(); if (stickerDatabase.isPackAvailableAsReference(pack.getPackId())) { stickerDatabase.markPackAsInstalled(pack.getPackId(), false); 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 c25535a860..7e709fec19 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/StorageServiceMigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/StorageServiceMigrationJob.java @@ -3,7 +3,7 @@ package org.thoughtcrime.securesms.migrations; import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; @@ -48,7 +48,7 @@ public class StorageServiceMigrationJob extends MigrationJob { return; } - DatabaseFactory.getRecipientDatabase(context).markNeedsSync(Recipient.self().getId()); + SignalDatabase.recipients().markNeedsSync(Recipient.self().getId()); JobManager jobManager = ApplicationDependencies.getJobManager(); 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 890c406dd9..8254d1cd3a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/UserNotificationMigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/UserNotificationMigrationJob.java @@ -13,7 +13,7 @@ import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.MainActivity; import org.thoughtcrime.securesms.NewConversationActivity; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; @@ -74,7 +74,7 @@ public class UserNotificationMigrationJob extends MigrationJob { return; } - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); + ThreadDatabase threadDatabase = SignalDatabase.threads(); int threadCount = threadDatabase.getUnarchivedConversationListCount() + threadDatabase.getArchivedConversationListCount(); @@ -84,8 +84,8 @@ public class UserNotificationMigrationJob extends MigrationJob { return; } - List registered = DatabaseFactory.getRecipientDatabase(context).getRegistered(); - List systemContacts = DatabaseFactory.getRecipientDatabase(context).getSystemContacts(); + List registered = SignalDatabase.recipients().getRegistered(); + List systemContacts = SignalDatabase.recipients().getSystemContacts(); Set registeredSystemContacts = SetUtil.intersection(registered, systemContacts); Set threadRecipients = threadDatabase.getAllThreadRecipients(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/UuidMigrationJob.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/UuidMigrationJob.java index a715962376..f3cc69a28e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/UuidMigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/UuidMigrationJob.java @@ -6,7 +6,7 @@ import android.text.TextUtils; import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; @@ -14,12 +14,10 @@ import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.signalservice.api.push.ACI; import java.io.IOException; import java.util.Objects; -import java.util.UUID; /** * Couple migrations steps need to happen after we move to UUIDS. @@ -68,14 +66,14 @@ public class UuidMigrationJob extends MigrationJob { } private static void ensureSelfRecipientExists(@NonNull Context context) { - DatabaseFactory.getRecipientDatabase(context).getOrInsertFromE164(Objects.requireNonNull(SignalStore.account().getE164())); + SignalDatabase.recipients().getOrInsertFromE164(Objects.requireNonNull(SignalStore.account().getE164())); } private static void fetchOwnUuid(@NonNull Context context) throws IOException { RecipientId self = Recipient.self().getId(); ACI localUuid = ApplicationDependencies.getSignalServiceAccountManager().getOwnAci(); - DatabaseFactory.getRecipientDatabase(context).markRegisteredOrThrow(self, localUuid); + SignalDatabase.recipients().markRegisteredOrThrow(self, localUuid); SignalStore.account().setAci(localUuid); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/AudioSlide.java b/app/src/main/java/org/thoughtcrime/securesms/mms/AudioSlide.java index 4661e3a09b..696b16c142 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mms/AudioSlide.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mms/AudioSlide.java @@ -29,11 +29,8 @@ import org.thoughtcrime.securesms.attachments.UriAttachment; import org.thoughtcrime.securesms.components.voice.VoiceNoteDraft; import org.thoughtcrime.securesms.database.AttachmentDatabase; import org.thoughtcrime.securesms.database.DraftDatabase; -import org.thoughtcrime.securesms.providers.BlobProvider; import org.thoughtcrime.securesms.util.MediaUtil; -import java.util.Objects; - public class AudioSlide extends Slide { diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/GifSlide.java b/app/src/main/java/org/thoughtcrime/securesms/mms/GifSlide.java index 9b3faede6a..1f3b6cb12f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mms/GifSlide.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mms/GifSlide.java @@ -6,7 +6,6 @@ import android.net.Uri; import androidx.annotation.Nullable; import org.thoughtcrime.securesms.attachments.Attachment; -import org.thoughtcrime.securesms.util.FeatureFlags; import org.thoughtcrime.securesms.util.MediaUtil; public class GifSlide extends ImageSlide { diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/ImageSlide.java b/app/src/main/java/org/thoughtcrime/securesms/mms/ImageSlide.java index acd408ab06..1445161c5f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mms/ImageSlide.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mms/ImageSlide.java @@ -28,7 +28,6 @@ import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.blurhash.BlurHash; -import org.thoughtcrime.securesms.database.AttachmentDatabase; import org.thoughtcrime.securesms.database.AttachmentDatabase.TransformProperties; import org.thoughtcrime.securesms.util.MediaUtil; diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/MessageGroupContext.java b/app/src/main/java/org/thoughtcrime/securesms/mms/MessageGroupContext.java index baf8a32e53..fee0df56b5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mms/MessageGroupContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mms/MessageGroupContext.java @@ -16,7 +16,6 @@ import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.util.Base64; import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil; import org.whispersystems.signalservice.api.push.ACI; -import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.util.UuidUtil; import org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContext; import org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContextV2; diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/PartAuthority.java b/app/src/main/java/org/thoughtcrime/securesms/mms/PartAuthority.java index 9166c0e58f..2cb3cf6ccc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mms/PartAuthority.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mms/PartAuthority.java @@ -12,7 +12,7 @@ import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.attachments.AttachmentId; import org.thoughtcrime.securesms.avatar.AvatarPickerStorage; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.emoji.EmojiFiles; import org.thoughtcrime.securesms.providers.BlobProvider; import org.thoughtcrime.securesms.providers.DeprecatedPersistentBlobProvider; @@ -70,8 +70,8 @@ public class PartAuthority { int match = uriMatcher.match(uri); try { switch (match) { - case PART_ROW: return DatabaseFactory.getAttachmentDatabase(context).getAttachmentStream(new PartUriParser(uri).getPartId(), 0); - case STICKER_ROW: return DatabaseFactory.getStickerDatabase(context).getStickerStream(ContentUris.parseId(uri)); + case PART_ROW: return SignalDatabase.attachments().getAttachmentStream(new PartUriParser(uri).getPartId(), 0); + case STICKER_ROW: return SignalDatabase.stickers().getStickerStream(ContentUris.parseId(uri)); case PERSISTENT_ROW: return DeprecatedPersistentBlobProvider.getInstance(context).getStream(context, ContentUris.parseId(uri)); case BLOB_ROW: return BlobProvider.getInstance().getStream(context, uri); case WALLPAPER_ROW: return WallpaperStorage.read(context, getWallpaperFilename(uri)); @@ -89,7 +89,7 @@ public class PartAuthority { switch (match) { case PART_ROW: - Attachment attachment = DatabaseFactory.getAttachmentDatabase(context).getAttachment(new PartUriParser(uri).getPartId()); + Attachment attachment = SignalDatabase.attachments().getAttachment(new PartUriParser(uri).getPartId()); if (attachment != null) return attachment.getFileName(); else return null; @@ -107,7 +107,7 @@ public class PartAuthority { switch (match) { case PART_ROW: - Attachment attachment = DatabaseFactory.getAttachmentDatabase(context).getAttachment(new PartUriParser(uri).getPartId()); + Attachment attachment = SignalDatabase.attachments().getAttachment(new PartUriParser(uri).getPartId()); if (attachment != null) return attachment.getSize(); else return null; @@ -125,7 +125,7 @@ public class PartAuthority { switch (match) { case PART_ROW: - Attachment attachment = DatabaseFactory.getAttachmentDatabase(context).getAttachment(new PartUriParser(uri).getPartId()); + Attachment attachment = SignalDatabase.attachments().getAttachment(new PartUriParser(uri).getPartId()); if (attachment != null) return attachment.getContentType(); else return null; @@ -143,7 +143,7 @@ public class PartAuthority { switch (match) { case PART_ROW: - Attachment attachment = DatabaseFactory.getAttachmentDatabase(context).getAttachment(new PartUriParser(uri).getPartId()); + Attachment attachment = SignalDatabase.attachments().getAttachment(new PartUriParser(uri).getPartId()); if (attachment != null) return attachment.isVideoGif(); else return false; diff --git a/app/src/main/java/org/thoughtcrime/securesms/net/SignalWebSocketHealthMonitor.java b/app/src/main/java/org/thoughtcrime/securesms/net/SignalWebSocketHealthMonitor.java index 9fc7012e6b..6b829d03bc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/net/SignalWebSocketHealthMonitor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/net/SignalWebSocketHealthMonitor.java @@ -18,7 +18,6 @@ import org.whispersystems.signalservice.api.websocket.WebSocketConnectionState; import org.whispersystems.signalservice.internal.websocket.WebSocketConnection; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; import io.reactivex.rxjava3.schedulers.Schedulers; diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/DeleteNotificationReceiver.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/DeleteNotificationReceiver.java index e3f60feb7e..005a9f0602 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/DeleteNotificationReceiver.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/DeleteNotificationReceiver.java @@ -6,7 +6,7 @@ import android.content.Context; import android.content.Intent; import org.signal.core.util.concurrent.SignalExecutors; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; public class DeleteNotificationReceiver extends BroadcastReceiver { @@ -40,9 +40,9 @@ public class DeleteNotificationReceiver extends BroadcastReceiver { SignalExecutors.BOUNDED.execute(() -> { for (int i = 0; i < ids.length; i++) { if (!mms[i]) { - DatabaseFactory.getSmsDatabase(context).markAsNotified(ids[i]); + SignalDatabase.sms().markAsNotified(ids[i]); } else { - DatabaseFactory.getMmsDatabase(context).markAsNotified(ids[i]); + SignalDatabase.mms().markAsNotified(ids[i]); } } finisher.finish(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/DoNotDisturbUtil.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/DoNotDisturbUtil.java index 2d3916f66a..c39154ef84 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/DoNotDisturbUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/DoNotDisturbUtil.java @@ -13,7 +13,7 @@ import androidx.annotation.RequiresApi; import androidx.annotation.WorkerThread; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.permissions.Permissions; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.util.CursorUtil; @@ -117,7 +117,7 @@ public final class DoNotDisturbUtil { } private static boolean isRepeatCaller(@NonNull Context context, @NonNull Recipient recipient) { - return DatabaseFactory.getThreadDatabase(context).hasCalledSince(recipient, System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(15)); + return SignalDatabase.threads().hasCalledSince(recipient, System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(15)); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/MarkReadReceiver.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/MarkReadReceiver.java index d2e17d9030..81189058c6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/MarkReadReceiver.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/MarkReadReceiver.java @@ -12,10 +12,10 @@ import com.annimon.stream.Stream; import org.signal.core.util.concurrent.SignalExecutors; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessageDatabase.ExpirationInfo; import org.thoughtcrime.securesms.database.MessageDatabase.MarkedMessageInfo; import org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobs.MultiDeviceReadUpdateJob; import org.thoughtcrime.securesms.jobs.SendReadReceiptJob; @@ -55,7 +55,7 @@ public class MarkReadReceiver extends BroadcastReceiver { for (long threadId : threadIds) { Log.i(TAG, "Marking as read: " + threadId); - List messageIds = DatabaseFactory.getThreadDatabase(context).setRead(threadId, true); + List messageIds = SignalDatabase.threads().setRead(threadId, true); messageIdsCollection.addAll(messageIds); } @@ -111,11 +111,11 @@ public class MarkReadReceiver extends BroadcastReceiver { @NonNull List mmsExpirationInfo) { if (smsExpirationInfo.size() > 0) { - DatabaseFactory.getSmsDatabase(context).markExpireStarted(Stream.of(smsExpirationInfo).map(ExpirationInfo::getId).toList(), System.currentTimeMillis()); + SignalDatabase.sms().markExpireStarted(Stream.of(smsExpirationInfo).map(ExpirationInfo::getId).toList(), System.currentTimeMillis()); } if (mmsExpirationInfo.size() > 0) { - DatabaseFactory.getMmsDatabase(context).markExpireStarted(Stream.of(mmsExpirationInfo).map(ExpirationInfo::getId).toList(), System.currentTimeMillis()); + SignalDatabase.mms().markExpireStarted(Stream.of(mmsExpirationInfo).map(ExpirationInfo::getId).toList(), System.currentTimeMillis()); } if (smsExpirationInfo.size() + mmsExpirationInfo.size() > 0) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationCancellationHelper.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationCancellationHelper.java index 904bffb9a2..8d57b1b9bb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationCancellationHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationCancellationHelper.java @@ -12,7 +12,7 @@ import androidx.annotation.RequiresApi; import com.annimon.stream.Stream; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.notifications.v2.MessageNotifierV2; import org.thoughtcrime.securesms.recipients.RecipientId; @@ -183,7 +183,7 @@ public final class NotificationCancellationHelper { return true; } - Long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipientId); + Long threadId = SignalDatabase.threads().getThreadIdFor(recipientId); long focusedThreadId = ApplicationDependencies.getMessageNotifier().getVisibleThread(); if (Objects.equals(threadId, focusedThreadId)) { 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 4a26ee02a7..6ffa5ca854 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationChannels.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationChannels.java @@ -19,7 +19,6 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; -import androidx.core.app.NotificationChannelCompat; import com.annimon.stream.Collectors; import com.annimon.stream.Stream; @@ -27,9 +26,9 @@ import com.annimon.stream.Stream; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.RecipientDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase.VibrateState; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; @@ -108,7 +107,7 @@ public class NotificationChannels { return; } - RecipientDatabase db = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase db = SignalDatabase.recipients(); try (RecipientDatabase.RecipientReader reader = db.getRecipientsWithNotificationChannels()) { Recipient recipient; @@ -328,7 +327,7 @@ public class NotificationChannels { generateChannelIdFor(recipient), channel -> channel.setSound(uri == null ? Settings.System.DEFAULT_NOTIFICATION_URI : uri, getRingtoneAudioAttributes())); - DatabaseFactory.getRecipientDatabase(context).setNotificationChannel(recipient.getId(), success ? newChannelId : null); + SignalDatabase.recipients().setNotificationChannel(recipient.getId(), success ? newChannelId : null); ensureCustomChannelConsistency(context); } @@ -396,7 +395,7 @@ public class NotificationChannels { newChannelId, channel -> setVibrationEnabled(channel, enabled)); - DatabaseFactory.getRecipientDatabase(context).setNotificationChannel(recipient.getId(), success ? newChannelId : null); + SignalDatabase.recipients().setNotificationChannel(recipient.getId(), success ? newChannelId : null); ensureCustomChannelConsistency(context); } @@ -496,7 +495,7 @@ public class NotificationChannels { if (channel.isPresent()) { Log.i(TAG, "Conversation channel created outside of app, while running. Update " + recipient.getId() + " to use '" + channel.get().getId() + "'"); - DatabaseFactory.getRecipientDatabase(context).setNotificationChannel(recipient.getId(), channel.get().getId()); + SignalDatabase.recipients().setNotificationChannel(recipient.getId(), channel.get().getId()); return true; } } @@ -536,7 +535,7 @@ public class NotificationChannels { Log.d(TAG, "ensureCustomChannelConsistency()"); NotificationManager notificationManager = ServiceUtil.getNotificationManager(context); - RecipientDatabase db = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase db = SignalDatabase.recipients(); List customRecipients = new ArrayList<>(); Set customChannelIds = new HashSet<>(); @@ -685,7 +684,7 @@ public class NotificationChannels { @WorkerThread @TargetApi(26) private static void updateAllRecipientChannelLedColors(@NonNull Context context, @NonNull NotificationManager notificationManager, @NonNull String color) { - RecipientDatabase database = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase database = SignalDatabase.recipients(); try (RecipientDatabase.RecipientReader recipients = database.getRecipientsWithNotificationChannels()) { Recipient recipient; diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/RemoteReplyReceiver.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/RemoteReplyReceiver.java index 0fd9c125da..e548923b92 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/RemoteReplyReceiver.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/RemoteReplyReceiver.java @@ -26,8 +26,8 @@ import android.os.Bundle; import androidx.core.app.RemoteInput; import org.signal.core.util.concurrent.SignalExecutors; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessageDatabase.MarkedMessageInfo; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.mms.OutgoingMediaMessage; import org.thoughtcrime.securesms.notifications.v2.MessageNotifierV2; @@ -111,7 +111,7 @@ public class RemoteReplyReceiver extends BroadcastReceiver { ApplicationDependencies.getMessageNotifier().addStickyThread(threadId, intent.getLongExtra(EARLIEST_TIMESTAMP, System.currentTimeMillis())); - List messageIds = DatabaseFactory.getThreadDatabase(context).setRead(threadId, true); + List messageIds = SignalDatabase.threads().setRead(threadId, true); ApplicationDependencies.getMessageNotifier().updateNotification(context); MarkReadReceiver.process(context, messageIds); diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/MessageNotifierV2.kt b/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/MessageNotifierV2.kt index 58888008a7..c4392b52a3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/MessageNotifierV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/MessageNotifierV2.kt @@ -13,8 +13,8 @@ import androidx.core.content.ContextCompat import me.leolin.shortcutbadger.ShortcutBadger import org.signal.core.util.logging.Log import org.thoughtcrime.securesms.R -import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.MessageDatabase +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.dependencies.ApplicationDependencies import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.messages.IncomingMessageObserver @@ -140,7 +140,7 @@ class MessageNotifierV2(context: Application) : MessageNotifier { .forEach { conversation -> cleanedUpThreadIds += conversation.threadId conversation.notificationItems.forEach { item -> - val messageDatabase: MessageDatabase = if (item.isMms) DatabaseFactory.getMmsDatabase(context) else DatabaseFactory.getSmsDatabase(context) + val messageDatabase: MessageDatabase = if (item.isMms) SignalDatabase.mms else SignalDatabase.sms messageDatabase.markAsNotified(item.id) } } @@ -192,7 +192,7 @@ class MessageNotifierV2(context: Application) : MessageNotifier { smsIds.add(item.id) } } - DatabaseFactory.getMmsSmsDatabase(context).setNotifiedTimestamp(System.currentTimeMillis(), smsIds, mmsIds) + SignalDatabase.mmsSms.setNotifiedTimestamp(System.currentTimeMillis(), smsIds, mmsIds) Log.i(TAG, "threads: ${state.threadCount} messages: ${state.messageCount}") } diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationBuilder.kt b/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationBuilder.kt index a72fdc8af5..ebf6f43492 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationBuilder.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationBuilder.kt @@ -17,9 +17,9 @@ import androidx.core.content.LocusIdCompat import androidx.core.graphics.drawable.IconCompat import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.conversation.ConversationIntents -import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.GroupDatabase import org.thoughtcrime.securesms.database.RecipientDatabase +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.notifications.NotificationChannels import org.thoughtcrime.securesms.notifications.ReplyMethod @@ -116,7 +116,7 @@ sealed class NotificationBuilder(protected val context: Context) { fun addReplyActions(conversation: NotificationConversation) { if (privacy.isDisplayMessage && isNotLocked && !conversation.recipient.isPushV1Group && RecipientUtil.isMessageRequestAccepted(context, conversation.recipient)) { if (conversation.recipient.isPushV2Group) { - val group: Optional = DatabaseFactory.getGroupDatabase(context).getGroup(conversation.recipient.requireGroupId()) + val group: Optional = SignalDatabase.groups.getGroup(conversation.recipient.requireGroupId()) if (group.isPresent && group.get().isAnnouncementGroup && !group.get().isAdmin(Recipient.self())) { return } diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationFactory.kt b/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationFactory.kt index 511c973a98..2799d18b4f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationFactory.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationFactory.kt @@ -20,7 +20,7 @@ import org.signal.core.util.logging.Log import org.thoughtcrime.securesms.MainActivity import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.conversation.ConversationIntents -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.database.model.InMemoryMessageRecord import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.notifications.NotificationChannels @@ -386,7 +386,7 @@ object NotificationFactory { Log.i(TAG, "Security exception when posting notification, clearing ringtone") if (threadRecipient != null) { SignalExecutors.BOUNDED.execute { - DatabaseFactory.getRecipientDatabase(context).setMessageRingtone(threadRecipient.id, null) + SignalDatabase.recipients.setMessageRingtone(threadRecipient.id, null) NotificationChannels.updateMessageRingtone(context, threadRecipient, null) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationItemV2.kt b/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationItemV2.kt index 381a4b0fa6..bfb0aa762e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationItemV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationItemV2.kt @@ -10,8 +10,8 @@ import org.signal.core.util.logging.Log import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.contactshare.Contact import org.thoughtcrime.securesms.contactshare.ContactUtil -import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.MentionUtil +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.database.ThreadBodyUtil import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.database.model.MmsMessageRecord @@ -304,7 +304,7 @@ class ReactionNotification(threadRecipient: Recipient, record: MessageRecord, va } override fun getStartingPosition(context: Context): Int { - return DatabaseFactory.getMmsSmsDatabase(context).getMessagePositionInConversation(threadId, record.dateReceived) + return SignalDatabase.mmsSms.getMessagePositionInConversation(threadId, record.dateReceived) } override fun getLargeIconUri(): Uri? = null diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationStateProvider.kt b/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationStateProvider.kt index f9a3db6b53..bfe6e0654a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationStateProvider.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationStateProvider.kt @@ -3,10 +3,10 @@ package org.thoughtcrime.securesms.notifications.v2 import android.content.Context import androidx.annotation.WorkerThread import org.signal.core.util.logging.Log -import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.MmsSmsColumns import org.thoughtcrime.securesms.database.MmsSmsDatabase import org.thoughtcrime.securesms.database.RecipientDatabase +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.database.model.MessageId import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.database.model.ReactionRecord @@ -25,7 +25,7 @@ object NotificationStateProvider { fun constructNotificationState(context: Context, stickyThreads: Map): NotificationStateV2 { val messages: MutableList = mutableListOf() - DatabaseFactory.getMmsSmsDatabase(context).getMessagesForNotificationState(stickyThreads.values).use { unreadMessages -> + SignalDatabase.mmsSms.getMessagesForNotificationState(stickyThreads.values).use { unreadMessages -> if (unreadMessages.count == 0) { return NotificationStateV2.EMPTY } @@ -33,13 +33,13 @@ object NotificationStateProvider { MmsSmsDatabase.readerFor(unreadMessages).use { reader -> var record: MessageRecord? = reader.next while (record != null) { - val threadRecipient: Recipient? = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(record.threadId) + val threadRecipient: Recipient? = SignalDatabase.threads.getRecipientForThreadId(record.threadId) if (threadRecipient != null) { val hasUnreadReactions = CursorUtil.requireInt(unreadMessages, MmsSmsColumns.REACTIONS_UNREAD) == 1 messages += NotificationMessage( messageRecord = record, - reactions = if (hasUnreadReactions) DatabaseFactory.getReactionDatabase(context).getReactions(MessageId(record.id, record.isMms)) else emptyList(), + reactions = if (hasUnreadReactions) SignalDatabase.reactions.getReactions(MessageId(record.id, record.isMms)) else emptyList(), threadRecipient = threadRecipient, threadId = record.threadId, stickyThread = stickyThreads.containsKey(record.threadId), diff --git a/app/src/main/java/org/thoughtcrime/securesms/payments/DataExportUtil.java b/app/src/main/java/org/thoughtcrime/securesms/payments/DataExportUtil.java index badce8fb40..944fc47973 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/payments/DataExportUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/payments/DataExportUtil.java @@ -6,8 +6,8 @@ import android.os.Build; import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.PaymentDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.payments.reconciliation.LedgerReconcile; @@ -33,11 +33,9 @@ public final class DataExportUtil { throw new AssertionError(); } - Context context = ApplicationDependencies.getApplication(); - List paymentTransactions = DatabaseFactory.getPaymentDatabase(context) - .getAll(); - MobileCoinLedgerWrapper ledger = SignalStore.paymentsValues().liveMobileCoinLedger().getValue(); - List reconciled = LedgerReconcile.reconcile(paymentTransactions, Objects.requireNonNull(ledger)); + List paymentTransactions = SignalDatabase.payments().getAll(); + MobileCoinLedgerWrapper ledger = SignalStore.paymentsValues().liveMobileCoinLedger().getValue(); + List reconciled = LedgerReconcile.reconcile(paymentTransactions, Objects.requireNonNull(ledger)); return createTsv(reconciled); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/payments/PaymentTransactionLiveData.java b/app/src/main/java/org/thoughtcrime/securesms/payments/PaymentTransactionLiveData.java index 6262f29f9a..14ae2b9c2d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/payments/PaymentTransactionLiveData.java +++ b/app/src/main/java/org/thoughtcrime/securesms/payments/PaymentTransactionLiveData.java @@ -4,9 +4,9 @@ import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; import org.signal.core.util.concurrent.SignalExecutors; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.DatabaseObserver; import org.thoughtcrime.securesms.database.PaymentDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.util.concurrent.SerialMonoLifoExecutor; @@ -22,7 +22,7 @@ public final class PaymentTransactionLiveData extends LiveData DatabaseFactory.getThreadDatabase(requireContext()).getThreadIdIfExistsFor(recipientId), + () -> SignalDatabase.threads().getThreadIdIfExistsFor(recipientId), threadId -> startActivity(ConversationIntents.createBuilder(requireContext(), recipientId, threadId).build())); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/PaymentsRepository.java b/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/PaymentsRepository.java index feacbde487..4152a18ca3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/PaymentsRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/PaymentsRepository.java @@ -9,9 +9,8 @@ import androidx.lifecycle.LiveData; import com.annimon.stream.Stream; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.PaymentDatabase; -import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.payments.Direction; import org.thoughtcrime.securesms.payments.MobileCoinLedgerWrapper; @@ -36,7 +35,7 @@ public class PaymentsRepository { private final LiveData> recentReceivedPayments; public PaymentsRepository() { - paymentDatabase = DatabaseFactory.getPaymentDatabase(ApplicationDependencies.getApplication()); + paymentDatabase = SignalDatabase.payments(); LiveData> localPayments = paymentDatabase.getAllLive(); LiveData ledger = SignalStore.paymentsValues().liveMobileCoinLedger(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/pin/PinState.java b/app/src/main/java/org/thoughtcrime/securesms/pin/PinState.java index 64e7245f26..46cb60d8a7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/pin/PinState.java +++ b/app/src/main/java/org/thoughtcrime/securesms/pin/PinState.java @@ -24,12 +24,9 @@ import org.whispersystems.libsignal.InvalidKeyException; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.KbsPinData; import org.whispersystems.signalservice.api.KeyBackupService; -import org.whispersystems.signalservice.api.KeyBackupServicePinException; -import org.whispersystems.signalservice.api.KeyBackupSystemNoDataException; import org.whispersystems.signalservice.api.kbs.HashedPin; import org.whispersystems.signalservice.api.kbs.MasterKey; import org.whispersystems.signalservice.internal.contacts.crypto.UnauthenticatedResponseException; -import org.whispersystems.signalservice.internal.contacts.entities.TokenResponse; import java.io.IOException; import java.util.Arrays; diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/ApplicationPreferencesViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/preferences/ApplicationPreferencesViewModel.java index 97ce8140a6..0e89c63600 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/ApplicationPreferencesViewModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/ApplicationPreferencesViewModel.java @@ -12,8 +12,8 @@ import androidx.lifecycle.ViewModelProviders; import org.signal.core.util.concurrent.SignalExecutors; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MediaDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.preferences.widgets.StorageGraphView; import java.util.Arrays; @@ -32,8 +32,7 @@ public class ApplicationPreferencesViewModel extends ViewModel { void refreshStorageBreakdown(@NonNull Context context) { SignalExecutors.BOUNDED.execute(() -> { - MediaDatabase.StorageBreakdown breakdown = DatabaseFactory.getMediaDatabase(context) - .getStorageBreakdown(); + MediaDatabase.StorageBreakdown breakdown = SignalDatabase.media().getStorageBreakdown(); StorageGraphView.StorageBreakdown latestStorageBreakdown = new StorageGraphView.StorageBreakdown(Arrays.asList( new StorageGraphView.Entry(ContextCompat.getColor(context, R.color.storage_color_photos), breakdown.getPhotoSize()), diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/StoragePreferenceFragment.java b/app/src/main/java/org/thoughtcrime/securesms/preferences/StoragePreferenceFragment.java index e0c2795b9d..8be8ceddca 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/StoragePreferenceFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/StoragePreferenceFragment.java @@ -27,7 +27,7 @@ import org.thoughtcrime.securesms.components.settings.BaseSettingsFragment; import org.thoughtcrime.securesms.components.settings.CustomizableSingleSelectSetting; import org.thoughtcrime.securesms.components.settings.SingleSelectSetting; import org.thoughtcrime.securesms.components.settings.app.wrapped.SettingsWrapperFragment; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.keyvalue.KeepMessagesDuration; @@ -132,7 +132,7 @@ public class StoragePreferenceFragment extends ListSummaryPreferenceFragment { new MaterialAlertDialogBuilder(requireActivity()) .setTitle(R.string.preferences_storage__are_you_sure_you_want_to_delete_all_message_history) .setMessage(R.string.preferences_storage__all_message_history_will_be_permanently_removed_this_action_cannot_be_undone) - .setPositiveButton(R.string.preferences_storage__delete_all_now, (d, w) -> SignalExecutors.BOUNDED.execute(() -> DatabaseFactory.getThreadDatabase(ApplicationDependencies.getApplication()).deleteAllConversations())) + .setPositiveButton(R.string.preferences_storage__delete_all_now, (d, w) -> SignalExecutors.BOUNDED.execute(() -> SignalDatabase.threads().deleteAllConversations())) .setNegativeButton(android.R.string.cancel, null) .show(); } @@ -300,7 +300,7 @@ public class StoragePreferenceFragment extends ListSummaryPreferenceFragment { long trimBeforeDate = keepMessagesDuration != KeepMessagesDuration.FOREVER ? System.currentTimeMillis() - keepMessagesDuration.getDuration() : ThreadDatabase.NO_TRIM_BEFORE_DATE_SET; - SignalExecutors.BOUNDED.execute(() -> DatabaseFactory.getThreadDatabase(ApplicationDependencies.getApplication()).trimAllThreads(length, trimBeforeDate)); + SignalExecutors.BOUNDED.execute(() -> SignalDatabase.threads().trimAllThreads(length, trimBeforeDate)); } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/profiles/edit/EditGroupProfileRepository.java b/app/src/main/java/org/thoughtcrime/securesms/profiles/edit/EditGroupProfileRepository.java index 9b0cdf2232..86b46940d4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/profiles/edit/EditGroupProfileRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/profiles/edit/EditGroupProfileRepository.java @@ -10,7 +10,7 @@ import androidx.core.util.Consumer; import org.signal.core.util.StreamUtil; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.conversation.colors.AvatarColor; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.groups.GroupChangeException; import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.groups.GroupManager; @@ -74,13 +74,13 @@ class EditGroupProfileRepository implements EditProfileRepository { RecipientId recipientId = getRecipientId(); Recipient recipient = Recipient.resolved(recipientId); - return DatabaseFactory.getGroupDatabase(context) - .getGroup(recipientId) - .transform(groupRecord -> { + return SignalDatabase.groups() + .getGroup(recipientId) + .transform(groupRecord -> { String title = groupRecord.getTitle(); return title == null ? "" : title; }) - .or(() -> recipient.getGroupName(context)); + .or(() -> recipient.getGroupName(context)); }, nameConsumer::accept); } @@ -89,13 +89,13 @@ class EditGroupProfileRepository implements EditProfileRepository { SimpleTask.run(() -> { RecipientId recipientId = getRecipientId(); - return DatabaseFactory.getGroupDatabase(context) - .getGroup(recipientId) - .transform(groupRecord -> { - String description = groupRecord.getDescription(); - return description == null ? "" : description; - }) - .or(""); + return SignalDatabase.groups() + .getGroup(recipientId) + .transform(groupRecord -> { + String description = groupRecord.getDescription(); + return description == null ? "" : description; + }) + .or(""); }, descriptionConsumer::accept); } @@ -128,9 +128,9 @@ class EditGroupProfileRepository implements EditProfileRepository { @WorkerThread private RecipientId getRecipientId() { - return DatabaseFactory.getRecipientDatabase(context).getByGroupId(groupId) - .or(() -> { - throw new AssertionError("Recipient ID for Group ID does not exist."); - }); + return SignalDatabase.recipients().getByGroupId(groupId) + .or(() -> { + throw new AssertionError("Recipient ID for Group ID does not exist."); + }); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/profiles/edit/EditSelfProfileRepository.java b/app/src/main/java/org/thoughtcrime/securesms/profiles/edit/EditSelfProfileRepository.java index 182179a3e6..7b4447790e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/profiles/edit/EditSelfProfileRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/profiles/edit/EditSelfProfileRepository.java @@ -10,7 +10,7 @@ import androidx.core.util.Consumer; import org.signal.core.util.StreamUtil; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.conversation.colors.AvatarColor; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobs.MultiDeviceProfileContentUpdateJob; import org.thoughtcrime.securesms.jobs.MultiDeviceProfileKeyUpdateJob; @@ -130,7 +130,7 @@ public class EditSelfProfileRepository implements EditProfileRepository { @NonNull Consumer uploadResultConsumer) { SimpleTask.run(() -> { - DatabaseFactory.getRecipientDatabase(context).setProfileName(Recipient.self().getId(), profileName); + SignalDatabase.recipients().setProfileName(Recipient.self().getId(), profileName); if (avatarChanged) { try { diff --git a/app/src/main/java/org/thoughtcrime/securesms/profiles/manage/EditProfileNameFragment.java b/app/src/main/java/org/thoughtcrime/securesms/profiles/manage/EditProfileNameFragment.java index 8d0392dfdb..bcbdfeb113 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/profiles/manage/EditProfileNameFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/profiles/manage/EditProfileNameFragment.java @@ -20,13 +20,9 @@ import com.dd.CircularProgressButton; import org.signal.core.util.EditTextUtil; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; -import org.thoughtcrime.securesms.jobs.ProfileUploadJob; import org.thoughtcrime.securesms.profiles.ProfileName; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.util.StringUtil; -import org.thoughtcrime.securesms.util.concurrent.SimpleTask; import org.thoughtcrime.securesms.util.text.AfterTextChanged; /** diff --git a/app/src/main/java/org/thoughtcrime/securesms/profiles/manage/ManageProfileRepository.java b/app/src/main/java/org/thoughtcrime/securesms/profiles/manage/ManageProfileRepository.java index 3c5bd485e2..5eb24168ca 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/profiles/manage/ManageProfileRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/profiles/manage/ManageProfileRepository.java @@ -3,12 +3,11 @@ package org.thoughtcrime.securesms.profiles.manage; import android.content.Context; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.core.util.Consumer; import org.signal.core.util.concurrent.SignalExecutors; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobs.MultiDeviceProfileContentUpdateJob; import org.thoughtcrime.securesms.keyvalue.SignalStore; @@ -29,7 +28,7 @@ final class ManageProfileRepository { SignalExecutors.UNBOUNDED.execute(() -> { try { ProfileUtil.uploadProfileWithName(context, profileName); - DatabaseFactory.getRecipientDatabase(context).setProfileName(Recipient.self().getId(), profileName); + SignalDatabase.recipients().setProfileName(Recipient.self().getId(), profileName); ApplicationDependencies.getJobManager().add(new MultiDeviceProfileContentUpdateJob()); callback.accept(Result.SUCCESS); @@ -44,7 +43,7 @@ final class ManageProfileRepository { SignalExecutors.UNBOUNDED.execute(() -> { try { ProfileUtil.uploadProfileWithAbout(context, about, emoji); - DatabaseFactory.getRecipientDatabase(context).setAbout(Recipient.self().getId(), about, emoji); + SignalDatabase.recipients().setAbout(Recipient.self().getId(), about, emoji); ApplicationDependencies.getJobManager().add(new MultiDeviceProfileContentUpdateJob()); callback.accept(Result.SUCCESS); diff --git a/app/src/main/java/org/thoughtcrime/securesms/profiles/manage/UsernameEditRepository.java b/app/src/main/java/org/thoughtcrime/securesms/profiles/manage/UsernameEditRepository.java index 430256b6c2..69390ceb48 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/profiles/manage/UsernameEditRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/profiles/manage/UsernameEditRepository.java @@ -7,7 +7,7 @@ import androidx.annotation.WorkerThread; import org.signal.core.util.concurrent.SignalExecutors; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.recipients.Recipient; import org.whispersystems.signalservice.api.SignalServiceAccountManager; @@ -43,7 +43,7 @@ class UsernameEditRepository { private @NonNull UsernameSetResult setUsernameInternal(@NonNull String username) { try { accountManager.setUsername(username); - DatabaseFactory.getRecipientDatabase(application).setUsername(Recipient.self().getId(), username); + SignalDatabase.recipients().setUsername(Recipient.self().getId(), username); Log.i(TAG, "[setUsername] Successfully set username."); return UsernameSetResult.SUCCESS; } catch (UsernameTakenException e) { @@ -62,7 +62,7 @@ class UsernameEditRepository { private @NonNull UsernameDeleteResult deleteUsernameInternal() { try { accountManager.deleteUsername(); - DatabaseFactory.getRecipientDatabase(application).setUsername(Recipient.self().getId(), null); + SignalDatabase.recipients().setUsername(Recipient.self().getId(), null); Log.i(TAG, "[deleteUsername] Successfully deleted the username."); return UsernameDeleteResult.SUCCESS; } catch (IOException e) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/profiles/spoofing/ReviewCardRepository.java b/app/src/main/java/org/thoughtcrime/securesms/profiles/spoofing/ReviewCardRepository.java index 3b43b7974d..f7df689294 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/profiles/spoofing/ReviewCardRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/profiles/spoofing/ReviewCardRepository.java @@ -8,7 +8,7 @@ import androidx.annotation.WorkerThread; import com.annimon.stream.Stream; import org.signal.core.util.concurrent.SignalExecutors; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupChangeException; @@ -86,7 +86,7 @@ class ReviewCardRepository { ApplicationDependencies.getJobManager().add(MultiDeviceMessageRequestResponseJob.forDelete(recipientId)); } - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); + ThreadDatabase threadDatabase = SignalDatabase.threads(); long threadId = Objects.requireNonNull(threadDatabase.getThreadIdFor(recipientId)); threadDatabase.deleteConversation(threadId); @@ -122,7 +122,7 @@ class ReviewCardRepository { SignalExecutors.BOUNDED.execute(() -> { Recipient resolved = Recipient.resolved(recipientId); - List recipientIds = DatabaseFactory.getRecipientDatabase(context) + List recipientIds = SignalDatabase.recipients() .getSimilarRecipientIds(resolved); if (recipientIds.isEmpty()) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/profiles/spoofing/ReviewUtil.java b/app/src/main/java/org/thoughtcrime/securesms/profiles/spoofing/ReviewUtil.java index 68d264be07..1d0b96c8cf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/profiles/spoofing/ReviewUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/profiles/spoofing/ReviewUtil.java @@ -7,8 +7,8 @@ import androidx.annotation.WorkerThread; import com.annimon.stream.Stream; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.database.model.databaseprotos.ProfileChangeDetails; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; @@ -46,9 +46,7 @@ public final class ReviewUtil { return false; } - return DatabaseFactory.getRecipientDatabase(ApplicationDependencies.getApplication()) - .getSimilarRecipientIds(recipient) - .size() > 1; + return SignalDatabase.recipients().getSimilarRecipientIds(recipient).size() > 1; } @WorkerThread @@ -61,7 +59,7 @@ public final class ReviewUtil { return Collections.emptyList(); } - List members = DatabaseFactory.getGroupDatabase(context) + List members = SignalDatabase.groups() .getGroupMembers(groupId, GroupDatabase.MemberSet.FULL_MEMBERS_INCLUDING_SELF); List changed = Stream.of(profileChangeRecords) @@ -92,19 +90,19 @@ public final class ReviewUtil { @WorkerThread public static @NonNull List getProfileChangeRecordsForGroup(@NonNull Context context, @NonNull GroupId.V2 groupId) { - RecipientId recipientId = DatabaseFactory.getRecipientDatabase(context).getByGroupId(groupId).get(); - Long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipientId); + RecipientId recipientId = SignalDatabase.recipients().getByGroupId(groupId).get(); + Long threadId = SignalDatabase.threads().getThreadIdFor(recipientId); if (threadId == null) { return Collections.emptyList(); } else { - return DatabaseFactory.getSmsDatabase(context).getProfileChangeDetailsRecords(threadId, System.currentTimeMillis() - TIMEOUT); + return SignalDatabase.sms().getProfileChangeDetailsRecords(threadId, System.currentTimeMillis() - TIMEOUT); } } @WorkerThread public static int getGroupsInCommonCount(@NonNull Context context, @NonNull RecipientId recipientId) { - return Stream.of(DatabaseFactory.getGroupDatabase(context) + return Stream.of(SignalDatabase.groups() .getPushGroupsContainingMember(recipientId)) .filter(g -> g.getMembers().contains(Recipient.self().getId())) .map(GroupDatabase.GroupRecord::getRecipientId) diff --git a/app/src/main/java/org/thoughtcrime/securesms/providers/BlobProvider.java b/app/src/main/java/org/thoughtcrime/securesms/providers/BlobProvider.java index 56f2ff1209..774c665036 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/providers/BlobProvider.java +++ b/app/src/main/java/org/thoughtcrime/securesms/providers/BlobProvider.java @@ -22,8 +22,8 @@ import org.thoughtcrime.securesms.crypto.AttachmentSecret; import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider; import org.thoughtcrime.securesms.crypto.ModernDecryptingPartInputStream; import org.thoughtcrime.securesms.crypto.ModernEncryptingPartOutputStream; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.DraftDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.util.IOFunction; import org.thoughtcrime.securesms.util.Util; import org.thoughtcrime.securesms.video.ByteArrayMediaDataSource; @@ -244,7 +244,7 @@ public class BlobProvider { return; } - DraftDatabase draftDatabase = DatabaseFactory.getDraftDatabase(context); + DraftDatabase draftDatabase = SignalDatabase.drafts(); DraftDatabase.Drafts voiceNoteDrafts = draftDatabase.getAllVoiceNoteDrafts(); @SuppressWarnings("ConstantConditions") diff --git a/app/src/main/java/org/thoughtcrime/securesms/providers/PartProvider.java b/app/src/main/java/org/thoughtcrime/securesms/providers/PartProvider.java index bb4286b6df..1c9167bcd1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/providers/PartProvider.java +++ b/app/src/main/java/org/thoughtcrime/securesms/providers/PartProvider.java @@ -32,7 +32,7 @@ import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.attachments.AttachmentId; import org.thoughtcrime.securesms.attachments.DatabaseAttachment; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.mms.PartUriParser; import org.thoughtcrime.securesms.service.KeyCachingService; import org.thoughtcrime.securesms.util.MemoryFileUtil; @@ -105,7 +105,7 @@ public final class PartProvider extends BaseContentProvider { if (uriMatcher.match(uri) == SINGLE_ROW) { PartUriParser partUriParser = new PartUriParser(uri); - DatabaseAttachment attachment = DatabaseFactory.getAttachmentDatabase(getContext()).getAttachment(partUriParser.getPartId()); + DatabaseAttachment attachment = SignalDatabase.attachments().getAttachment(partUriParser.getPartId()); if (attachment != null) { Log.i(TAG, "getType() called: " + uri + " It's " + attachment.getContentType()); @@ -128,7 +128,7 @@ public final class PartProvider extends BaseContentProvider { if (uriMatcher.match(url) == SINGLE_ROW) { PartUriParser partUri = new PartUriParser(url); - DatabaseAttachment attachment = DatabaseFactory.getAttachmentDatabase(getContext()).getAttachment(partUri.getPartId()); + DatabaseAttachment attachment = SignalDatabase.attachments().getAttachment(partUri.getPartId()); if (attachment == null) return null; @@ -155,10 +155,10 @@ public final class PartProvider extends BaseContentProvider { } private ParcelFileDescriptor getParcelStreamForAttachment(AttachmentId attachmentId) throws IOException { - long plaintextLength = StreamUtil.getStreamLength(DatabaseFactory.getAttachmentDatabase(getContext()).getAttachmentStream(attachmentId, 0)); + long plaintextLength = StreamUtil.getStreamLength(SignalDatabase.attachments().getAttachmentStream(attachmentId, 0)); MemoryFile memoryFile = new MemoryFile(attachmentId.toString(), Util.toIntExact(plaintextLength)); - InputStream in = DatabaseFactory.getAttachmentDatabase(getContext()).getAttachmentStream(attachmentId, 0); + InputStream in = SignalDatabase.attachments().getAttachmentStream(attachmentId, 0); OutputStream out = memoryFile.getOutputStream(); StreamUtil.copy(in, out); diff --git a/app/src/main/java/org/thoughtcrime/securesms/push/AccountManagerFactory.java b/app/src/main/java/org/thoughtcrime/securesms/push/AccountManagerFactory.java index a8b8f8287e..096ff047e3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/push/AccountManagerFactory.java +++ b/app/src/main/java/org/thoughtcrime/securesms/push/AccountManagerFactory.java @@ -14,8 +14,6 @@ import org.thoughtcrime.securesms.util.FeatureFlags; import org.whispersystems.signalservice.api.SignalServiceAccountManager; import org.whispersystems.signalservice.api.push.ACI; -import java.util.UUID; - public class AccountManagerFactory { private static final String TAG = Log.tag(AccountManagerFactory.class); diff --git a/app/src/main/java/org/thoughtcrime/securesms/push/SignalServiceNetworkAccess.java b/app/src/main/java/org/thoughtcrime/securesms/push/SignalServiceNetworkAccess.java index 657905ae5b..217553cab0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/push/SignalServiceNetworkAccess.java +++ b/app/src/main/java/org/thoughtcrime/securesms/push/SignalServiceNetworkAccess.java @@ -3,10 +3,10 @@ package org.thoughtcrime.securesms.push; import android.content.Context; -import com.annimon.stream.Stream; - import androidx.annotation.Nullable; +import com.annimon.stream.Stream; + import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.keyvalue.SignalStore; @@ -17,7 +17,6 @@ import org.thoughtcrime.securesms.net.RemoteDeprecationDetectorInterceptor; import org.thoughtcrime.securesms.net.SequentialDns; import org.thoughtcrime.securesms.net.StandardUserAgentInterceptor; import org.thoughtcrime.securesms.util.Base64; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.push.TrustStore; import org.whispersystems.signalservice.internal.configuration.SignalCdnUrl; @@ -35,8 +34,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import javax.net.ssl.SSLContext; - import okhttp3.CipherSuite; import okhttp3.ConnectionSpec; import okhttp3.Dns; diff --git a/app/src/main/java/org/thoughtcrime/securesms/ratelimit/RateLimitUtil.java b/app/src/main/java/org/thoughtcrime/securesms/ratelimit/RateLimitUtil.java index 479a4e860a..5154a2f55a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ratelimit/RateLimitUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ratelimit/RateLimitUtil.java @@ -6,7 +6,7 @@ import androidx.annotation.NonNull; import androidx.annotation.WorkerThread; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobs.PushGroupSendJob; @@ -26,8 +26,8 @@ public final class RateLimitUtil { */ @WorkerThread public static void retryAllRateLimitedMessages(@NonNull Context context) { - Set sms = DatabaseFactory.getSmsDatabase(context).getAllRateLimitedMessageIds(); - Set mms = DatabaseFactory.getMmsDatabase(context).getAllRateLimitedMessageIds(); + Set sms = SignalDatabase.sms().getAllRateLimitedMessageIds(); + Set mms = SignalDatabase.mms().getAllRateLimitedMessageIds(); if (sms.isEmpty() && mms.isEmpty()) { return; @@ -35,8 +35,8 @@ public final class RateLimitUtil { Log.i(TAG, "Retrying " + sms.size() + " sms records and " + mms.size() + " mms records."); - DatabaseFactory.getSmsDatabase(context).clearRateLimitStatus(sms); - DatabaseFactory.getMmsDatabase(context).clearRateLimitStatus(mms); + SignalDatabase.sms().clearRateLimitStatus(sms); + SignalDatabase.mms().clearRateLimitStatus(mms); ApplicationDependencies.getJobManager().update((job, serializer) -> { Data data = serializer.deserialize(job.getSerializedData()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/reactions/ReactionsRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/reactions/ReactionsRepository.kt index 83173a738a..aae36a7084 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/reactions/ReactionsRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/reactions/ReactionsRepository.kt @@ -5,8 +5,8 @@ import io.reactivex.rxjava3.core.Observable import io.reactivex.rxjava3.core.ObservableEmitter import io.reactivex.rxjava3.schedulers.Schedulers import org.thoughtcrime.securesms.components.emoji.EmojiUtil -import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.DatabaseObserver +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.database.model.MessageId import org.thoughtcrime.securesms.database.model.ReactionRecord import org.thoughtcrime.securesms.dependencies.ApplicationDependencies @@ -34,7 +34,7 @@ class ReactionsRepository { private fun fetchReactionDetails(messageId: MessageId): List { val context: Context = ApplicationDependencies.getApplication() - val reactions: List = DatabaseFactory.getReactionDatabase(context).getReactions(messageId) + val reactions: List = SignalDatabase.reactions.getReactions(messageId) return reactions.map { reaction -> ReactionDetails( diff --git a/app/src/main/java/org/thoughtcrime/securesms/reactions/any/ReactWithAnyEmojiRepository.java b/app/src/main/java/org/thoughtcrime/securesms/reactions/any/ReactWithAnyEmojiRepository.java index 64e8f27538..8d976cf784 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/reactions/any/ReactWithAnyEmojiRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/reactions/any/ReactWithAnyEmojiRepository.java @@ -2,9 +2,7 @@ package org.thoughtcrime.securesms.reactions.any; import android.content.Context; -import androidx.annotation.AttrRes; import androidx.annotation.NonNull; -import androidx.annotation.StringRes; import com.annimon.stream.Stream; @@ -12,13 +10,9 @@ import org.signal.core.util.ThreadUtil; import org.signal.core.util.concurrent.SignalExecutors; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.components.emoji.EmojiUtil; import org.thoughtcrime.securesms.components.emoji.RecentEmojiPageModel; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.MessageDatabase; -import org.thoughtcrime.securesms.database.NoSuchMessageException; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.MessageId; -import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.database.model.ReactionRecord; import org.thoughtcrime.securesms.emoji.EmojiCategory; import org.thoughtcrime.securesms.emoji.EmojiSource; @@ -71,7 +65,7 @@ final class ReactWithAnyEmojiRepository { void addEmojiToMessage(@NonNull String emoji, @NonNull MessageId messageId) { SignalExecutors.BOUNDED.execute(() -> { - ReactionRecord oldRecord = Stream.of(DatabaseFactory.getReactionDatabase(context).getReactions(messageId)) + ReactionRecord oldRecord = Stream.of(SignalDatabase.reactions().getReactions(messageId)) .filter(record -> record.getAuthor().equals(Recipient.self().getId())) .findFirst() .orElse(null); diff --git a/app/src/main/java/org/thoughtcrime/securesms/reactions/edit/EditReactionsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/reactions/edit/EditReactionsViewModel.kt index dfa5c021df..abaa8f516b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/reactions/edit/EditReactionsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/reactions/edit/EditReactionsViewModel.kt @@ -3,8 +3,7 @@ package org.thoughtcrime.securesms.reactions.edit import androidx.lifecycle.LiveData import androidx.lifecycle.ViewModel import org.signal.core.util.concurrent.SignalExecutors -import org.thoughtcrime.securesms.database.DatabaseFactory -import org.thoughtcrime.securesms.dependencies.ApplicationDependencies +import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.keyvalue.EmojiValues import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.recipients.Recipient @@ -44,7 +43,7 @@ class EditReactionsViewModel : ViewModel() { emojiValues.reactions = store.state.reactions SignalExecutors.BOUNDED.execute { - DatabaseFactory.getRecipientDatabase(ApplicationDependencies.getApplication()).markNeedsSync(Recipient.self().id) + SignalDatabase.recipients.markNeedsSync(Recipient.self().id) StorageSyncHelper.scheduleSyncForDataChange() } } 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 504cd1b4db..a10552b247 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/LiveRecipient.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/LiveRecipient.java @@ -13,11 +13,11 @@ import com.annimon.stream.Stream; import org.signal.core.util.ThreadUtil; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord; import org.thoughtcrime.securesms.database.RecipientDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientSettings; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.util.livedata.LiveDataUtil; import org.whispersystems.libsignal.util.guava.Optional; @@ -46,8 +46,8 @@ public final class LiveRecipient { this.context = context.getApplicationContext(); this.liveData = new MutableLiveData<>(defaultRecipient); this.recipient = new AtomicReference<>(defaultRecipient); - this.recipientDatabase = DatabaseFactory.getRecipientDatabase(context); - this.groupDatabase = DatabaseFactory.getGroupDatabase(context); + this.recipientDatabase = SignalDatabase.recipients(); + this.groupDatabase = SignalDatabase.groups(); this.observers = new CopyOnWriteArraySet<>(); this.foreverObserver = recipient -> { ThreadUtil.postToMain(() -> { 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 52caf115cc..2669340529 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/LiveRecipientCache.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/LiveRecipientCache.java @@ -11,18 +11,16 @@ import net.zetetic.database.sqlcipher.SQLiteDatabase; import org.signal.core.util.ThreadUtil; import org.signal.core.util.concurrent.SignalExecutors; -import org.signal.core.util.concurrent.TracingExecutorService; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.RecipientDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase.MissingRecipientException; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.database.model.ThreadRecord; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.util.CursorUtil; import org.thoughtcrime.securesms.util.LRUCache; import org.thoughtcrime.securesms.util.Stopwatch; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.concurrent.FilteredExecutor; import org.whispersystems.signalservice.api.push.ACI; @@ -55,12 +53,12 @@ public final class LiveRecipientCache { @SuppressLint("UseSparseArrays") public LiveRecipientCache(@NonNull Context context) { this.context = context.getApplicationContext(); - this.recipientDatabase = DatabaseFactory.getRecipientDatabase(context); + this.recipientDatabase = 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.db = DatabaseFactory.getInstance(context).getRawDatabase(); + this.db = SignalDatabase.getRawDatabase(); this.resolveExecutor = ThreadUtil.trace(new FilteredExecutor(SignalExecutors.BOUNDED, () -> !db.inTransaction())); } @@ -187,7 +185,7 @@ public final class LiveRecipientCache { Stopwatch stopwatch = new Stopwatch("recipient-warm-up"); SignalExecutors.BOUNDED.execute(() -> { - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); + ThreadDatabase threadDatabase = SignalDatabase.threads(); List recipients = new ArrayList<>(); try (ThreadDatabase.Reader reader = threadDatabase.readerFor(threadDatabase.getRecentConversationList(THREAD_CACHE_WARM_MAX, false, false))) { @@ -206,7 +204,7 @@ public final class LiveRecipientCache { stopwatch.split("thread"); if (SignalStore.registrationValues().isRegistrationComplete()) { - try (Cursor cursor = DatabaseFactory.getRecipientDatabase(context).getNonGroupContacts(false)) { + try (Cursor cursor = SignalDatabase.recipients().getNonGroupContacts(false)) { int count = 0; while (cursor != null && cursor.moveToNext() && count < CONTACT_CACHE_WARM_MAX) { RecipientId id = RecipientId.from(CursorUtil.requireLong(cursor, RecipientDatabase.ID)); diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java index 263c497a7d..d9456c02b0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java @@ -27,12 +27,12 @@ import org.thoughtcrime.securesms.contacts.avatars.TransparentContactPhoto; import org.thoughtcrime.securesms.conversation.colors.AvatarColor; import org.thoughtcrime.securesms.conversation.colors.ChatColors; import org.thoughtcrime.securesms.conversation.colors.ChatColorsPalette; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.RecipientDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase.MentionSetting; import org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState; import org.thoughtcrime.securesms.database.RecipientDatabase.UnidentifiedAccessMode; import org.thoughtcrime.securesms.database.RecipientDatabase.VibrateState; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.databaseprotos.RecipientExtras; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupId; @@ -165,7 +165,7 @@ public class Recipient { @WorkerThread public static @NonNull Recipient externalUsername(@NonNull Context context, @NonNull ACI aci, @NonNull String username) { Recipient recipient = externalPush(context, aci, null, false); - DatabaseFactory.getRecipientDatabase(context).setUsername(recipient.getId(), username); + SignalDatabase.recipients().setUsername(recipient.getId(), username); return recipient; } @@ -225,7 +225,7 @@ public class Recipient { throw new AssertionError(); } - RecipientDatabase db = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase db = SignalDatabase.recipients(); RecipientId recipientId = db.getAndPossiblyMerge(aci, e164, highTrust); Recipient resolved = resolved(recipientId); @@ -249,7 +249,7 @@ public class Recipient { */ @WorkerThread public static @NonNull Recipient externalContact(@NonNull Context context, @NonNull String identifier) { - RecipientDatabase db = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase db = SignalDatabase.recipients(); RecipientId id = null; if (UuidUtil.isUuid(identifier)) { @@ -274,7 +274,7 @@ public class Recipient { */ @WorkerThread public static @NonNull Recipient externalGroupExact(@NonNull Context context, @NonNull GroupId groupId) { - return Recipient.resolved(DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupId)); + return Recipient.resolved(SignalDatabase.recipients().getOrInsertFromGroupId(groupId)); } /** @@ -289,7 +289,7 @@ public class Recipient { */ @WorkerThread public static @NonNull Recipient externalPossiblyMigratedGroup(@NonNull Context context, @NonNull GroupId groupId) { - return Recipient.resolved(DatabaseFactory.getRecipientDatabase(context).getOrInsertFromPossiblyMigratedGroupId(groupId)); + return Recipient.resolved(SignalDatabase.recipients().getOrInsertFromPossiblyMigratedGroupId(groupId)); } /** @@ -305,7 +305,7 @@ public class Recipient { public static @NonNull Recipient external(@NonNull Context context, @NonNull String identifier) { Preconditions.checkNotNull(identifier, "Identifier cannot be null!"); - RecipientDatabase db = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase db = SignalDatabase.recipients(); RecipientId id = null; if (UuidUtil.isUuid(identifier)) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java index d66dd189d9..2cc0599bd3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java @@ -10,9 +10,9 @@ import com.annimon.stream.Stream; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.contacts.sync.DirectoryHelper; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupChangeBusyException; @@ -156,11 +156,11 @@ public class RecipientUtil { GroupManager.leaveGroupFromBlockOrMessageRequest(context, recipient.getGroupId().get().requirePush()); } - DatabaseFactory.getRecipientDatabase(context).setBlocked(recipient.getId(), true); + SignalDatabase.recipients().setBlocked(recipient.getId(), true); if (recipient.isSystemContact() || recipient.isProfileSharing() || isProfileSharedViaGroup(context, recipient)) { ApplicationDependencies.getJobManager().add(new RotateProfileKeyJob()); - DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient.getId(), false); + SignalDatabase.recipients().setProfileSharing(recipient.getId(), false); } ApplicationDependencies.getJobManager().add(new MultiDeviceBlockedUpdateJob()); @@ -173,8 +173,8 @@ public class RecipientUtil { throw new AssertionError("Recipient is not blockable!"); } - DatabaseFactory.getRecipientDatabase(context).setBlocked(recipient.getId(), false); - DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient.getId(), true); + SignalDatabase.recipients().setBlocked(recipient.getId(), false); + SignalDatabase.recipients().setProfileSharing(recipient.getId(), true); ApplicationDependencies.getJobManager().add(new MultiDeviceBlockedUpdateJob()); StorageSyncHelper.scheduleSyncForDataChange(); @@ -196,7 +196,7 @@ public class RecipientUtil { return true; } - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); + ThreadDatabase threadDatabase = SignalDatabase.threads(); Recipient threadRecipient = threadDatabase.getRecipientForThreadId(threadId); if (threadRecipient == null) { @@ -215,7 +215,7 @@ public class RecipientUtil { return true; } - Long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(threadRecipient.getId()); + Long threadId = SignalDatabase.threads().getThreadIdFor(threadRecipient.getId()); return isMessageRequestAccepted(context, threadId, threadRecipient); } @@ -229,7 +229,7 @@ public class RecipientUtil { return true; } - Long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(threadRecipient.getId()); + Long threadId = SignalDatabase.threads().getThreadIdFor(threadRecipient.getId()); return isCallRequestAccepted(context, threadId, threadRecipient); } @@ -239,7 +239,7 @@ public class RecipientUtil { @WorkerThread public static boolean isPreMessageRequestThread(@NonNull Context context, @Nullable Long threadId) { long beforeTime = SignalStore.misc().getMessageRequestEnableTime(); - return threadId != null && DatabaseFactory.getMmsSmsDatabase(context).getConversationCount(threadId, beforeTime) > 0; + return threadId != null && SignalDatabase.mmsSms().getConversationCount(threadId, beforeTime) > 0; } @WorkerThread @@ -248,16 +248,16 @@ public class RecipientUtil { return; } - long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(recipient.getId()); + long threadId = SignalDatabase.threads().getThreadIdIfExistsFor(recipient.getId()); if (isPreMessageRequestThread(context, threadId)) { return; } - boolean firstMessage = DatabaseFactory.getMmsSmsDatabase(context).getOutgoingSecureConversationCount(threadId) == 0; + boolean firstMessage = SignalDatabase.mmsSms().getOutgoingSecureConversationCount(threadId) == 0; if (firstMessage) { - DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient.getId(), true); + SignalDatabase.recipients().setProfileSharing(recipient.getId(), true); } } @@ -280,7 +280,7 @@ public class RecipientUtil { if (recipient.isProfileSharing()) { return true; } else { - GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); + GroupDatabase groupDatabase = SignalDatabase.groups(); return groupDatabase.getPushGroupsContainingMember(recipient.getId()) .stream() .anyMatch(GroupDatabase.GroupRecord::isV2Group); @@ -299,10 +299,10 @@ public class RecipientUtil { return false; } - if (threadId == -1 || !DatabaseFactory.getMmsSmsDatabase(context).hasMeaningfulMessage(threadId)) { - DatabaseFactory.getRecipientDatabase(context).setExpireMessages(recipient.getId(), defaultTimer); + if (threadId == -1 || !SignalDatabase.mmsSms().hasMeaningfulMessage(threadId)) { + SignalDatabase.recipients().setExpireMessages(recipient.getId(), defaultTimer); OutgoingExpirationUpdateMessage outgoingMessage = new OutgoingExpirationUpdateMessage(recipient, System.currentTimeMillis(), defaultTimer * 1000L); - MessageSender.send(context, outgoingMessage, DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient), false, null, null); + MessageSender.send(context, outgoingMessage, SignalDatabase.threads().getOrCreateThreadIdFor(recipient), false, null, null); return true; } return false; @@ -331,7 +331,7 @@ public class RecipientUtil { @WorkerThread public static boolean hasSentMessageInThread(@NonNull Context context, @Nullable Long threadId) { - return threadId != null && DatabaseFactory.getMmsSmsDatabase(context).getOutgoingSecureConversationCount(threadId) != 0; + return threadId != null && SignalDatabase.mmsSms().getOutgoingSecureConversationCount(threadId) != 0; } @WorkerThread @@ -340,13 +340,13 @@ public class RecipientUtil { return true; } - return DatabaseFactory.getMmsSmsDatabase(context).getSecureConversationCount(threadId) == 0 && - !DatabaseFactory.getThreadDatabase(context).hasReceivedAnyCallsSince(threadId, 0); + return SignalDatabase.mmsSms().getSecureConversationCount(threadId) == 0 && + !SignalDatabase.threads().hasReceivedAnyCallsSince(threadId, 0); } @WorkerThread private static boolean isProfileSharedViaGroup(@NonNull Context context, @NonNull Recipient recipient) { - return Stream.of(DatabaseFactory.getGroupDatabase(context).getPushGroupsContainingMember(recipient.getId())) + return Stream.of(SignalDatabase.groups().getPushGroupsContainingMember(recipient.getId())) .anyMatch(group -> Recipient.resolved(group.getRecipientId()).isProfileSharing()); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/bottomsheet/RecipientDialogRepository.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/bottomsheet/RecipientDialogRepository.java index 788c097567..5760f9a66d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/bottomsheet/RecipientDialogRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/bottomsheet/RecipientDialogRepository.java @@ -9,9 +9,8 @@ import androidx.core.util.Consumer; import org.signal.core.util.concurrent.SignalExecutors; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.contacts.sync.DirectoryHelper; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; -import org.thoughtcrime.securesms.database.IdentityDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.IdentityRecord; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupChangeException; @@ -107,7 +106,7 @@ final class RecipientDialogRepository { void getGroupMembership(@NonNull Consumer> onComplete) { SimpleTask.run(SignalExecutors.UNBOUNDED, () -> { - GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); + GroupDatabase groupDatabase = SignalDatabase.groups(); List groupRecords = groupDatabase.getPushGroupsContainingMember(recipientId); ArrayList groupRecipients = new ArrayList<>(groupRecords.size()); @@ -121,7 +120,7 @@ final class RecipientDialogRepository { } public void getActiveGroupCount(@NonNull Consumer onComplete) { - SignalExecutors.BOUNDED.execute(() -> onComplete.accept(DatabaseFactory.getGroupDatabase(context).getActiveGroupCount())); + SignalExecutors.BOUNDED.execute(() -> onComplete.accept(SignalDatabase.groups().getActiveGroupCount())); } interface RecipientCallback { diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/sharablegrouplink/ShareableGroupLinkRepository.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/sharablegrouplink/ShareableGroupLinkRepository.java index 61a0a54234..74e3f058ba 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/sharablegrouplink/ShareableGroupLinkRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/sharablegrouplink/ShareableGroupLinkRepository.java @@ -7,7 +7,7 @@ import androidx.annotation.WorkerThread; import org.signal.core.util.concurrent.SignalExecutors; import org.signal.storageservice.protos.groups.AccessControl; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.groups.GroupChangeBusyException; import org.thoughtcrime.securesms.groups.GroupChangeFailedException; import org.thoughtcrime.securesms.groups.GroupId; @@ -63,13 +63,13 @@ final class ShareableGroupLinkRepository { @WorkerThread private GroupManager.GroupLinkState toggleGroupLinkState(boolean toggleEnabled, boolean toggleApprovalNeeded) { - AccessControl.AccessRequired currentState = DatabaseFactory.getGroupDatabase(context) - .getGroup(groupId) - .get() - .requireV2GroupProperties() - .getDecryptedGroup() - .getAccessControl() - .getAddFromInviteLink(); + AccessControl.AccessRequired currentState = SignalDatabase.groups() + .getGroup(groupId) + .get() + .requireV2GroupProperties() + .getDecryptedGroup() + .getAccessControl() + .getAddFromInviteLink(); boolean enabled; boolean approvalNeeded; diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/RegistrationRepository.java b/app/src/main/java/org/thoughtcrime/securesms/registration/RegistrationRepository.java index c6522a39c4..8b75d2fcc8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/RegistrationRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/RegistrationRepository.java @@ -14,9 +14,9 @@ import org.thoughtcrime.securesms.crypto.PreKeyUtil; import org.thoughtcrime.securesms.crypto.ProfileKeyUtil; import org.thoughtcrime.securesms.crypto.SenderKeyUtil; import org.thoughtcrime.securesms.crypto.SessionUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.IdentityDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.JobManager; import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob; @@ -143,7 +143,7 @@ public final class RegistrationRepository { accountManager.setGcmId(Optional.fromNullable(registrationData.getFcmToken())); } - RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase recipientDatabase = SignalDatabase.recipients(); RecipientId selfId = Recipient.externalPush(context, aci, registrationData.getE164(), true).getId(); recipientDatabase.setProfileSharing(selfId, true); @@ -176,7 +176,7 @@ public final class RegistrationRepository { @WorkerThread private static @Nullable ProfileKey findExistingProfileKey(@NonNull Context context, @NonNull String e164number) { - RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase recipientDatabase = SignalDatabase.recipients(); Optional recipient = recipientDatabase.getByE164(e164number); if (recipient.isPresent()) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/RestoreBackupFragment.java b/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/RestoreBackupFragment.java index 12b364655d..2068d734ae 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/RestoreBackupFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/RestoreBackupFragment.java @@ -45,8 +45,8 @@ import org.thoughtcrime.securesms.backup.BackupPassphrase; import org.thoughtcrime.securesms.backup.FullBackupBase; import org.thoughtcrime.securesms.backup.FullBackupImporter; import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.NoExternalStorageException; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.notifications.NotificationChannels; import org.thoughtcrime.securesms.registration.viewmodel.RegistrationViewModel; @@ -256,7 +256,7 @@ public final class RestoreBackupFragment extends LoggingFragment { try { Log.i(TAG, "Starting backup restore."); - SQLiteDatabase database = DatabaseFactory.getBackupDatabase(context); + SQLiteDatabase database = SignalDatabase.getBackupDatabase(); BackupPassphrase.set(context, passphrase); FullBackupImporter.importFile(context, @@ -265,7 +265,7 @@ public final class RestoreBackupFragment extends LoggingFragment { backup.getUri(), passphrase); - DatabaseFactory.upgradeRestored(context, database); + SignalDatabase.upgradeRestored(database); NotificationChannels.restoreContactNotificationChannels(context); enableBackups(context); diff --git a/app/src/main/java/org/thoughtcrime/securesms/revealable/ViewOnceMessageManager.java b/app/src/main/java/org/thoughtcrime/securesms/revealable/ViewOnceMessageManager.java index 2b96e32938..414d02107a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/revealable/ViewOnceMessageManager.java +++ b/app/src/main/java/org/thoughtcrime/securesms/revealable/ViewOnceMessageManager.java @@ -11,10 +11,9 @@ import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.database.AttachmentDatabase; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessageDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.service.TimedEventManager; @@ -31,8 +30,8 @@ public class ViewOnceMessageManager extends TimedEventManager> callback) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorStickerSelectActivity.java b/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorStickerSelectActivity.java index f407b786a5..2a9b7a5020 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorStickerSelectActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorStickerSelectActivity.java @@ -14,7 +14,7 @@ import androidx.lifecycle.ViewModelProviders; import org.signal.core.util.concurrent.SignalExecutors; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.components.emoji.MediaKeyboard; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.StickerRecord; import org.thoughtcrime.securesms.keyboard.KeyboardPage; import org.thoughtcrime.securesms.keyboard.KeyboardPagerViewModel; @@ -61,8 +61,7 @@ public final class ImageEditorStickerSelectActivity extends AppCompatActivity im intent.setData(sticker.getUri()); setResult(RESULT_OK, intent); - SignalExecutors.BOUNDED.execute(() -> DatabaseFactory.getStickerDatabase(getApplicationContext()) - .updateStickerLastUsedTime(sticker.getRowId(), System.currentTimeMillis())); + SignalExecutors.BOUNDED.execute(() -> SignalDatabase.stickers().updateStickerLastUsedTime(sticker.getRowId(), System.currentTimeMillis())); ViewUtil.hideKeyboard(this, findViewById(android.R.id.content)); finish(); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/search/SearchRepository.java b/app/src/main/java/org/thoughtcrime/securesms/search/SearchRepository.java index bc4891233d..22ea35bf77 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/search/SearchRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/search/SearchRepository.java @@ -14,7 +14,6 @@ import org.signal.core.util.concurrent.SignalExecutors; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.contacts.ContactRepository; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.MentionDatabase; import org.thoughtcrime.securesms.database.MentionUtil; @@ -22,6 +21,7 @@ import org.thoughtcrime.securesms.database.MessageDatabase; import org.thoughtcrime.securesms.database.MmsSmsColumns; import org.thoughtcrime.securesms.database.RecipientDatabase; import org.thoughtcrime.securesms.database.SearchDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.database.model.Mention; import org.thoughtcrime.securesms.database.model.MessageRecord; @@ -68,11 +68,11 @@ public class SearchRepository { public SearchRepository() { this.context = ApplicationDependencies.getApplication().getApplicationContext(); - this.searchDatabase = DatabaseFactory.getSearchDatabase(context); - this.threadDatabase = DatabaseFactory.getThreadDatabase(context); - this.recipientDatabase = DatabaseFactory.getRecipientDatabase(context); - this.mentionDatabase = DatabaseFactory.getMentionDatabase(context); - this.mmsDatabase = DatabaseFactory.getMmsDatabase(context); + this.searchDatabase = SignalDatabase.messageSearch(); + this.threadDatabase = SignalDatabase.threads(); + this.recipientDatabase = SignalDatabase.recipients(); + this.mentionDatabase = SignalDatabase.mentions(); + this.mmsDatabase = SignalDatabase.mms(); this.contactRepository = new ContactRepository(context); this.searchExecutor = new LatestPrioritizedSerialExecutor(SignalExecutors.BOUNDED); this.serialExecutor = new SerialExecutor(SignalExecutors.BOUNDED); @@ -160,14 +160,14 @@ public class SearchRepository { Set recipientIds = new LinkedHashSet<>(); - try (Cursor cursor = DatabaseFactory.getRecipientDatabase(context).queryAllContacts(query)) { + try (Cursor cursor = SignalDatabase.recipients().queryAllContacts(query)) { while (cursor != null && cursor.moveToNext()) { recipientIds.add(RecipientId.from(CursorUtil.requireString(cursor, RecipientDatabase.ID))); } } GroupDatabase.GroupRecord record; - try (GroupDatabase.Reader reader = DatabaseFactory.getGroupDatabase(context).getGroupsFilteredByTitle(query, true, false, false)) { + try (GroupDatabase.Reader reader = SignalDatabase.groups().getGroupsFilteredByTitle(query, true, false, false)) { while ((record = reader.getNext()) != null) { recipientIds.add(record.getRecipientId()); } @@ -203,7 +203,7 @@ public class SearchRepository { return results; } - Map> mentions = DatabaseFactory.getMentionDatabase(context).getMentionsForMessages(messageIds); + Map> mentions = SignalDatabase.mentions().getMentionsForMessages(messageIds); if (mentions.isEmpty()) { return results; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/ExpiringMessageManager.java b/app/src/main/java/org/thoughtcrime/securesms/service/ExpiringMessageManager.java index 5daa247f6b..626bfc3c67 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/ExpiringMessageManager.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/ExpiringMessageManager.java @@ -3,9 +3,9 @@ package org.thoughtcrime.securesms.service; import android.content.Context; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessageDatabase; import org.thoughtcrime.securesms.database.MmsDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.SmsDatabase; import org.thoughtcrime.securesms.database.model.MessageRecord; @@ -27,8 +27,8 @@ public class ExpiringMessageManager { public ExpiringMessageManager(Context context) { this.context = context.getApplicationContext(); - this.smsDatabase = DatabaseFactory.getSmsDatabase(context); - this.mmsDatabase = DatabaseFactory.getMmsDatabase(context); + this.smsDatabase = SignalDatabase.sms(); + this.mmsDatabase = SignalDatabase.mms(); executor.execute(new LoadTask()); executor.execute(new ProcessTask()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/PendingRetryReceiptManager.java b/app/src/main/java/org/thoughtcrime/securesms/service/PendingRetryReceiptManager.java index 53e40bed65..c6875982f8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/PendingRetryReceiptManager.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/PendingRetryReceiptManager.java @@ -11,8 +11,8 @@ import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessageDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.PendingRetryReceiptModel; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.database.PendingRetryReceiptCache; @@ -33,7 +33,7 @@ public final class PendingRetryReceiptManager extends TimedEventManager groupId = recipient.getGroupId(); long ringId = currentState.getCallSetupState(RemotePeer.GROUP_CALL_ID).getRingId(); - DatabaseFactory.getGroupCallRingDatabase(context).insertOrUpdateGroupRing(ringId, + SignalDatabase.groupCallRings().insertOrUpdateGroupRing(ringId, System.currentTimeMillis(), CallManager.RingUpdate.DECLINED_ON_ANOTHER_DEVICE); diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/OutgoingCallActionProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/OutgoingCallActionProcessor.java index b48234c201..91db1ff943 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/OutgoingCallActionProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/OutgoingCallActionProcessor.java @@ -11,7 +11,7 @@ import org.signal.ringrtc.CallId; import org.signal.ringrtc.CallManager; import org.thoughtcrime.securesms.components.webrtc.EglBaseWrapper; import org.thoughtcrime.securesms.crypto.IdentityKeyUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.events.CallParticipant; import org.thoughtcrime.securesms.events.WebRtcViewModel; import org.thoughtcrime.securesms.recipients.Recipient; @@ -74,8 +74,8 @@ public class OutgoingCallActionProcessor extends DeviceAwareActionProcessor { webRtcInteractor.initializeAudioForCall(); webRtcInteractor.startOutgoingRinger(); - RecipientUtil.setAndSendUniversalExpireTimerIfNecessary(context, Recipient.resolved(remotePeer.getId()), DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(remotePeer.getId())); - DatabaseFactory.getSmsDatabase(context).insertOutgoingCall(remotePeer.getId(), isVideoCall); + RecipientUtil.setAndSendUniversalExpireTimerIfNecessary(context, Recipient.resolved(remotePeer.getId()), SignalDatabase.threads().getThreadIdIfExistsFor(remotePeer.getId())); + SignalDatabase.sms().insertOutgoingCall(remotePeer.getId(), isVideoCall); EglBaseWrapper.replaceHolder(EglBaseWrapper.OUTGOING_PLACEHOLDER, remotePeer.getCallId().longValue()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/SignalCallManager.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/SignalCallManager.java index fb8dd8948e..cbb46c1ea8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/SignalCallManager.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/SignalCallManager.java @@ -27,8 +27,8 @@ import org.signal.zkgroup.VerificationFailedException; import org.signal.zkgroup.groups.GroupIdentifier; import org.thoughtcrime.securesms.WebRtcCallActivity; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.events.GroupCallPeekEvent; import org.thoughtcrime.securesms.events.WebRtcViewModel; @@ -311,14 +311,14 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall. .toList(); callManager.peekGroupCall(SignalStore.internalValues().groupCallingServer(), credential.getTokenBytes().toByteArray(), members, peekInfo -> { - Long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(group.getId()); + Long threadId = SignalDatabase.threads().getThreadIdFor(group.getId()); if (threadId != null) { - DatabaseFactory.getSmsDatabase(context) - .updatePreviousGroupCall(threadId, - peekInfo.getEraId(), - peekInfo.getJoinedMembers(), - WebRtcUtil.isCallFull(peekInfo)); + SignalDatabase.sms() + .updatePreviousGroupCall(threadId, + peekInfo.getEraId(), + peekInfo.getJoinedMembers(), + WebRtcUtil.isCallFull(peekInfo)); ApplicationDependencies.getMessageNotifier().updateNotification(context, threadId, true, 0, BubbleUtil.BubbleState.HIDDEN); @@ -626,7 +626,7 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall. networkExecutor.execute(() -> { try { GroupId groupId = GroupId.v2(new GroupIdentifier(groupIdBytes)); - List recipients = DatabaseFactory.getGroupDatabase(context).getGroupMembers(groupId, GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF); + List recipients = SignalDatabase.groups().getGroupMembers(groupId, GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF); recipients = RecipientUtil.getEligibleForSending((recipients.stream() .map(Recipient::resolve) @@ -695,7 +695,7 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall. public void onGroupCallRingUpdate(@NonNull byte[] groupIdBytes, long ringId, @NonNull UUID uuid, @NonNull CallManager.RingUpdate ringUpdate) { try { GroupId.V2 groupId = GroupId.v2(new GroupIdentifier(groupIdBytes)); - Optional group = DatabaseFactory.getGroupDatabase(context).getGroup(groupId); + Optional group = SignalDatabase.groups().getGroup(groupId); if (group.isPresent()) { process((s, p) -> p.handleGroupCallRingUpdate(s, new RemotePeer(group.get().getRecipientId()), groupId, ringId, uuid, ringUpdate)); @@ -788,16 +788,14 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall. } public void insertMissedCall(@NonNull RemotePeer remotePeer, boolean signal, long timestamp, boolean isVideoOffer) { - Pair messageAndThreadId = DatabaseFactory.getSmsDatabase(context) - .insertMissedCall(remotePeer.getId(), timestamp, isVideoOffer); + Pair messageAndThreadId = SignalDatabase.sms().insertMissedCall(remotePeer.getId(), timestamp, isVideoOffer); ApplicationDependencies.getMessageNotifier() .updateNotification(context, messageAndThreadId.second(), signal); } public void insertReceivedCall(@NonNull RemotePeer remotePeer, boolean signal, boolean isVideoOffer) { - Pair messageAndThreadId = DatabaseFactory.getSmsDatabase(context) - .insertReceivedCall(remotePeer.getId(), isVideoOffer); + Pair messageAndThreadId = SignalDatabase.sms().insertReceivedCall(remotePeer.getId(), isVideoOffer); ApplicationDependencies.getMessageNotifier() .updateNotification(context, messageAndThreadId.second(), signal); @@ -843,7 +841,7 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall. } public void updateGroupCallUpdateMessage(@NonNull RecipientId groupId, @Nullable String groupCallEraId, @NonNull Collection joinedMembers, boolean isCallFull) { - SignalExecutors.BOUNDED.execute(() -> DatabaseFactory.getSmsDatabase(context).insertOrUpdateGroupCall(groupId, + SignalExecutors.BOUNDED.execute(() -> SignalDatabase.sms().insertOrUpdateGroupCall(groupId, Recipient.self().getId(), System.currentTimeMillis(), groupCallEraId, diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/WebRtcActionProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/WebRtcActionProcessor.java index c2461c2065..0084c2cf73 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/WebRtcActionProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/WebRtcActionProcessor.java @@ -19,7 +19,7 @@ import org.thoughtcrime.securesms.components.webrtc.BroadcastVideoSink; import org.thoughtcrime.securesms.components.webrtc.EglBaseWrapper; import org.thoughtcrime.securesms.components.webrtc.GroupCallSafetyNumberChangeNotificationUtil; import org.thoughtcrime.securesms.crypto.IdentityKeyUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.events.CallParticipant; import org.thoughtcrime.securesms.events.WebRtcViewModel; @@ -699,9 +699,9 @@ public abstract class WebRtcActionProcessor { if (ringUpdate != RingUpdate.BUSY_LOCALLY && ringUpdate != RingUpdate.BUSY_ON_ANOTHER_DEVICE) { webRtcInteractor.getCallManager().cancelGroupRing(groupId.getDecodedId(), ringId, CallManager.RingCancelReason.Busy); } - DatabaseFactory.getGroupCallRingDatabase(context).insertOrUpdateGroupRing(ringId, - System.currentTimeMillis(), - ringUpdate == RingUpdate.REQUESTED ? RingUpdate.BUSY_LOCALLY : ringUpdate); + SignalDatabase.groupCallRings().insertOrUpdateGroupRing(ringId, + System.currentTimeMillis(), + ringUpdate == RingUpdate.REQUESTED ? RingUpdate.BUSY_LOCALLY : ringUpdate); } catch (CallException e) { Log.w(tag, "Unable to cancel ring", e); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareActivity.java b/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareActivity.java index e632731cd3..bb714c62d7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareActivity.java @@ -48,7 +48,7 @@ import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.components.SearchToolbar; import org.thoughtcrime.securesms.contacts.ContactsCursorLoader.DisplayMode; import org.thoughtcrime.securesms.conversation.ConversationIntents; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.mediasend.Media; import org.thoughtcrime.securesms.mediasend.v2.MediaSelectionActivity; @@ -324,7 +324,7 @@ public class ShareActivity extends PassphraseRequiredActivity int distributionType = ThreadDatabase.DistributionTypes.DEFAULT; if (recipientId != null) { - threadId = DatabaseFactory.getThreadDatabase(this).getThreadIdFor(recipientId); + threadId = SignalDatabase.threads().getThreadIdFor(recipientId); extras.putString(EXTRA_RECIPIENT_ID, recipientId.serialize()); extras.putLong(EXTRA_THREAD_ID, threadId != null ? threadId : -1); extras.putInt(EXTRA_DISTRIBUTION_TYPE, distributionType); @@ -517,10 +517,10 @@ public class ShareActivity extends PassphraseRequiredActivity .or(() -> Recipient.external(this, contact.getNumber()))) .collect(Collectors.toSet()); - Map existingThreads = DatabaseFactory.getThreadDatabase(this) - .getThreadIdsIfExistsFor(Stream.of(recipients) - .map(Recipient::getId) - .toArray(RecipientId[]::new)); + Map existingThreads = SignalDatabase.threads() + .getThreadIdsIfExistsFor(Stream.of(recipients) + .map(Recipient::getId) + .toArray(RecipientId[]::new)); return Stream.of(recipients) .map(recipient -> new ShareContactAndThread(recipient.getId(), Util.getOrDefault(existingThreads, recipient.getId(), -1L), recipient.isForceSmsSelection() || !recipient.isRegistered())) @@ -537,7 +537,7 @@ public class ShareActivity extends PassphraseRequiredActivity recipient = Recipient.external(this, shareContact.getNumber()); } - long existingThread = DatabaseFactory.getThreadDatabase(this).getThreadIdIfExistsFor(recipient.getId()); + long existingThread = SignalDatabase.threads().getThreadIdIfExistsFor(recipient.getId()); return new ShareContactAndThread(recipient.getId(), existingThread, recipient.isForceSmsSelection() || !recipient.isRegistered()); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareViewModel.java index 273b5d8ae2..8ecbd52f81 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareViewModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareViewModel.java @@ -14,8 +14,8 @@ import androidx.lifecycle.ViewModelProvider; import com.annimon.stream.Stream; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.providers.BlobProvider; import org.thoughtcrime.securesms.recipients.Recipient; @@ -71,7 +71,7 @@ public class ShareViewModel extends ViewModel { Recipient recipient = Recipient.resolved(selectedContact.getRecipientId().get()); if (recipient.isPushV2Group()) { - Optional record = DatabaseFactory.getGroupDatabase(context).getGroup(recipient.requireGroupId()); + Optional record = SignalDatabase.groups().getGroup(recipient.requireGroupId()); if (record.isPresent() && record.get().isAnnouncementGroup() && !record.get().isAdmin(Recipient.self())) { return ContactSelectResult.FALSE_AND_SHOW_PERMISSION_TOAST; diff --git a/app/src/main/java/org/thoughtcrime/securesms/sms/MessageSender.java b/app/src/main/java/org/thoughtcrime/securesms/sms/MessageSender.java index db34a9af19..5dcc3eb505 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sms/MessageSender.java +++ b/app/src/main/java/org/thoughtcrime/securesms/sms/MessageSender.java @@ -16,7 +16,6 @@ */ package org.thoughtcrime.securesms.sms; -import android.app.Application; import android.content.Context; import android.os.Parcel; import android.os.Parcelable; @@ -35,12 +34,12 @@ import org.thoughtcrime.securesms.attachments.DatabaseAttachment; import org.thoughtcrime.securesms.contacts.sync.DirectoryHelper; import org.thoughtcrime.securesms.contactshare.Contact; import org.thoughtcrime.securesms.database.AttachmentDatabase; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessageDatabase; import org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId; import org.thoughtcrime.securesms.database.MmsSmsDatabase; import org.thoughtcrime.securesms.database.NoSuchMessageException; import org.thoughtcrime.securesms.database.RecipientDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.SmsDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.database.model.MessageId; @@ -63,7 +62,6 @@ import org.thoughtcrime.securesms.jobs.ReactionSendJob; import org.thoughtcrime.securesms.jobs.RemoteDeleteSendJob; import org.thoughtcrime.securesms.jobs.ResumableUploadSpecJob; import org.thoughtcrime.securesms.jobs.SmsSendJob; -import org.thoughtcrime.securesms.jobs.ThreadUpdateJob; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.linkpreview.LinkPreview; import org.thoughtcrime.securesms.mms.MmsException; @@ -108,11 +106,11 @@ public class MessageSender { final SmsDatabase.InsertListener insertListener) { Log.i(TAG, "Sending text message to " + message.getRecipient().getId() + ", thread: " + threadId); - MessageDatabase database = DatabaseFactory.getSmsDatabase(context); + MessageDatabase database = SignalDatabase.sms(); Recipient recipient = message.getRecipient(); boolean keyExchange = message.isKeyExchange(); - long allocatedThreadId = DatabaseFactory.getThreadDatabase(context).getOrCreateValidThreadId(recipient, threadId); + long allocatedThreadId = SignalDatabase.threads().getOrCreateValidThreadId(recipient, threadId); long messageId = database.insertMessageOutbox(allocatedThreadId, applyUniversalExpireTimerIfNecessary(context, recipient, message, allocatedThreadId), forceSms, @@ -123,7 +121,7 @@ public class MessageSender { sendTextMessage(context, recipient, forceSms, keyExchange, messageId); onMessageSent(); - DatabaseFactory.getThreadDatabase(context).update(threadId, true); + SignalDatabase.threads().update(threadId, true); return allocatedThreadId; } @@ -137,8 +135,8 @@ public class MessageSender { { Log.i(TAG, "Sending media message to " + message.getRecipient().getId() + ", thread: " + threadId); try { - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); - MessageDatabase database = DatabaseFactory.getMmsDatabase(context); + ThreadDatabase threadDatabase = SignalDatabase.threads(); + MessageDatabase database = SignalDatabase.mms(); long allocatedThreadId = threadDatabase.getOrCreateValidThreadId(message.getRecipient(), threadId, message.getDistributionType()); Recipient recipient = message.getRecipient(); @@ -171,9 +169,9 @@ public class MessageSender { Preconditions.checkArgument(message.getAttachments().isEmpty(), "If the media is pre-uploaded, there should be no attachments on the message."); try { - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); - MessageDatabase mmsDatabase = DatabaseFactory.getMmsDatabase(context); - AttachmentDatabase attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context); + ThreadDatabase threadDatabase = SignalDatabase.threads(); + MessageDatabase mmsDatabase = SignalDatabase.mms(); + AttachmentDatabase attachmentDatabase = SignalDatabase.attachments(); long allocatedThreadId; @@ -211,9 +209,9 @@ public class MessageSender { Preconditions.checkArgument(Stream.of(messages).allMatch(m -> m.getAttachments().isEmpty()), "Messages can't have attachments! They should be pre-uploaded."); JobManager jobManager = ApplicationDependencies.getJobManager(); - AttachmentDatabase attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context); - MessageDatabase mmsDatabase = DatabaseFactory.getMmsDatabase(context); - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); + AttachmentDatabase attachmentDatabase = SignalDatabase.attachments(); + MessageDatabase mmsDatabase = SignalDatabase.mms(); + ThreadDatabase threadDatabase = SignalDatabase.threads(); List preUploadAttachmentIds = Stream.of(preUploadResults).map(PreUploadResult::getAttachmentId).toList(); List preUploadJobIds = Stream.of(preUploadResults).map(PreUploadResult::getJobIds).flatMap(Stream::of).toList(); List messageIds = new ArrayList<>(messages.size()); @@ -301,7 +299,7 @@ public class MessageSender { Log.i(TAG, "Pre-uploading attachment for " + (recipient != null ? recipient.getId() : "null")); try { - AttachmentDatabase attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context); + AttachmentDatabase attachmentDatabase = SignalDatabase.attachments(); DatabaseAttachment databaseAttachment = attachmentDatabase.insertAttachmentForPreUpload(attachment); Job compressionJob = AttachmentCompressionJob.fromAttachment(databaseAttachment, false, -1); @@ -323,7 +321,7 @@ public class MessageSender { public static void sendNewReaction(@NonNull Context context, @NonNull MessageId messageId, @NonNull String emoji) { ReactionRecord reaction = new ReactionRecord(emoji, Recipient.self().getId(), System.currentTimeMillis(), System.currentTimeMillis()); - DatabaseFactory.getReactionDatabase(context).addReaction(messageId, reaction); + SignalDatabase.reactions().addReaction(messageId, reaction); try { ApplicationDependencies.getJobManager().add(ReactionSendJob.create(context, messageId, reaction, false)); @@ -334,7 +332,7 @@ public class MessageSender { } public static void sendReactionRemoval(@NonNull Context context, @NonNull MessageId messageId, @NonNull ReactionRecord reaction) { - DatabaseFactory.getReactionDatabase(context).deleteReaction(messageId, reaction.getAuthor()); + SignalDatabase.reactions().deleteReaction(messageId, reaction.getAuthor()); try { ApplicationDependencies.getJobManager().add(ReactionSendJob.create(context, messageId, reaction, true)); @@ -345,7 +343,7 @@ public class MessageSender { } public static void sendRemoteDelete(@NonNull Context context, long messageId, boolean isMms) { - MessageDatabase db = isMms ? DatabaseFactory.getMmsDatabase(context) : DatabaseFactory.getSmsDatabase(context); + MessageDatabase db = isMms ? SignalDatabase.mms() : SignalDatabase.sms(); db.markAsRemoteDelete(messageId); db.markAsSending(messageId); @@ -513,8 +511,8 @@ public class MessageSender { private static void sendLocalMediaSelf(Context context, long messageId) { try { ExpiringMessageManager expirationManager = ApplicationDependencies.getExpiringMessageManager(); - MessageDatabase mmsDatabase = DatabaseFactory.getMmsDatabase(context); - MmsSmsDatabase mmsSmsDatabase = DatabaseFactory.getMmsSmsDatabase(context); + MessageDatabase mmsDatabase = SignalDatabase.mms(); + MmsSmsDatabase mmsSmsDatabase = SignalDatabase.mmsSms(); OutgoingMediaMessage message = mmsDatabase.getOutgoingMessage(messageId); SyncMessageId syncId = new SyncMessageId(Recipient.self().getId(), message.getSentTimeMillis()); List attachments = new LinkedList<>(); @@ -564,8 +562,8 @@ public class MessageSender { private static void sendLocalTextSelf(Context context, long messageId) { try { ExpiringMessageManager expirationManager = ApplicationDependencies.getExpiringMessageManager(); - MessageDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context); - MmsSmsDatabase mmsSmsDatabase = DatabaseFactory.getMmsSmsDatabase(context); + MessageDatabase smsDatabase = SignalDatabase.sms(); + MmsSmsDatabase mmsSmsDatabase = SignalDatabase.mmsSms(); SmsMessageRecord message = smsDatabase.getSmsMessage(messageId); SyncMessageId syncId = new SyncMessageId(Recipient.self().getId(), message.getDateSent()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementRepository.java b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementRepository.java index 656c6ee4a7..c81bf3b719 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementRepository.java @@ -7,7 +7,7 @@ import androidx.annotation.NonNull; import org.signal.core.util.concurrent.SignalExecutors; import org.thoughtcrime.securesms.database.AttachmentDatabase; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.StickerDatabase; import org.thoughtcrime.securesms.database.StickerDatabase.StickerPackRecordReader; import org.thoughtcrime.securesms.database.model.StickerPackRecord; @@ -28,8 +28,8 @@ final class StickerManagementRepository { StickerManagementRepository(@NonNull Context context) { this.context = context.getApplicationContext(); - this.stickerDatabase = DatabaseFactory.getStickerDatabase(context); - this.attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context); + this.stickerDatabase = SignalDatabase.stickers(); + this.attachmentDatabase = SignalDatabase.attachments(); } void deleteOrphanedStickerPacks() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPackPreviewRepository.java b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPackPreviewRepository.java index 81148623ed..53755e72ea 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPackPreviewRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPackPreviewRepository.java @@ -10,7 +10,7 @@ import com.annimon.stream.Stream; import org.signal.core.util.concurrent.SignalExecutors; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.StickerDatabase; import org.thoughtcrime.securesms.database.model.StickerPackRecord; import org.thoughtcrime.securesms.database.model.StickerRecord; @@ -34,7 +34,7 @@ public final class StickerPackPreviewRepository { public StickerPackPreviewRepository(@NonNull Context context) { this.receiver = ApplicationDependencies.getSignalServiceMessageReceiver(); - this.stickerDatabase = DatabaseFactory.getStickerDatabase(context); + this.stickerDatabase = SignalDatabase.stickers(); } public void getStickerManifest(@NonNull String packId, diff --git a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerSearchRepository.java b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerSearchRepository.java index c8b21501fb..f39227d45f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerSearchRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerSearchRepository.java @@ -8,7 +8,7 @@ import androidx.annotation.NonNull; import org.signal.core.util.concurrent.SignalExecutors; import org.thoughtcrime.securesms.components.emoji.EmojiUtil; import org.thoughtcrime.securesms.database.AttachmentDatabase; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.StickerDatabase; import org.thoughtcrime.securesms.database.StickerDatabase.StickerRecordReader; import org.thoughtcrime.securesms.database.model.StickerRecord; @@ -23,8 +23,8 @@ public final class StickerSearchRepository { private final AttachmentDatabase attachmentDatabase; public StickerSearchRepository(@NonNull Context context) { - this.stickerDatabase = DatabaseFactory.getStickerDatabase(context); - this.attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context); + this.stickerDatabase = SignalDatabase.stickers(); + this.attachmentDatabase = SignalDatabase.attachments(); } public void searchByEmoji(@NonNull String emoji, @NonNull Callback> callback) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/storage/ContactRecordProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/storage/ContactRecordProcessor.java index 7764ab35eb..eb41d212a3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/storage/ContactRecordProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/storage/ContactRecordProcessor.java @@ -6,8 +6,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.RecipientDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.whispersystems.libsignal.util.guava.Optional; @@ -19,7 +19,6 @@ import org.whispersystems.signalservice.internal.storage.protos.ContactRecord.Id import java.util.Arrays; import java.util.Objects; -import java.util.UUID; public class ContactRecordProcessor extends DefaultStorageRecordProcessor { @@ -29,7 +28,7 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor gv1GroupsByExpectedGv2Id; public GroupV2RecordProcessor(@NonNull Context context) { - this(context, DatabaseFactory.getRecipientDatabase(context), DatabaseFactory.getGroupDatabase(context)); + this(context, SignalDatabase.recipients(), SignalDatabase.groups()); } GroupV2RecordProcessor(@NonNull Context context, @NonNull RecipientDatabase recipientDatabase, @NonNull GroupDatabase groupDatabase) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/storage/StorageSyncHelper.java b/app/src/main/java/org/thoughtcrime/securesms/storage/StorageSyncHelper.java index bf4ddd84a7..4e61282b36 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/storage/StorageSyncHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/storage/StorageSyncHelper.java @@ -10,9 +10,9 @@ import com.annimon.stream.Collectors; import com.annimon.stream.Stream; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.RecipientDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientSettings; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobs.RetrieveProfileAvatarJob; import org.thoughtcrime.securesms.jobs.StorageSyncJob; @@ -105,9 +105,9 @@ public final class StorageSyncHelper { } public static SignalStorageRecord buildAccountRecord(@NonNull Context context, @NonNull Recipient self) { - RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase recipientDatabase = SignalDatabase.recipients(); RecipientSettings settings = recipientDatabase.getRecipientSettingsForSync(self.getId()); - List pinned = Stream.of(DatabaseFactory.getThreadDatabase(context).getPinnedRecipientIds()) + List pinned = Stream.of(SignalDatabase.threads().getPinnedRecipientIds()) .map(recipientDatabase::getRecipientSettingsForSync) .toList(); @@ -145,7 +145,7 @@ public final class StorageSyncHelper { } public static void applyAccountStorageSyncUpdates(@NonNull Context context, @NonNull Recipient self, @NonNull StorageRecordUpdate update, boolean fetchProfile) { - DatabaseFactory.getRecipientDatabase(context).applyStorageSyncAccountUpdate(update); + SignalDatabase.recipients().applyStorageSyncAccountUpdate(update); TextSecurePreferences.setReadReceiptsEnabled(context, update.getNew().isReadReceiptsEnabled()); TextSecurePreferences.setTypingIndicatorsEnabled(context, update.getNew().isTypingIndicatorsEnabled()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/AttachmentUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/AttachmentUtil.java index e65703c3c6..f4460ccf55 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/AttachmentUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/AttachmentUtil.java @@ -2,8 +2,6 @@ package org.thoughtcrime.securesms.util; import android.content.Context; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; import android.text.TextUtils; import androidx.annotation.NonNull; @@ -13,8 +11,8 @@ import androidx.annotation.WorkerThread; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.attachments.AttachmentId; import org.thoughtcrime.securesms.attachments.DatabaseAttachment; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.NoSuchMessageException; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.jobmanager.impl.NotInCallConstraint; import org.thoughtcrime.securesms.recipients.Recipient; @@ -65,14 +63,14 @@ public class AttachmentUtil { { AttachmentId attachmentId = attachment.getAttachmentId(); long mmsId = attachment.getMmsId(); - int attachmentCount = DatabaseFactory.getAttachmentDatabase(context) - .getAttachmentsForMessage(mmsId) - .size(); + int attachmentCount = SignalDatabase.attachments() + .getAttachmentsForMessage(mmsId) + .size(); if (attachmentCount <= 1) { - DatabaseFactory.getMmsDatabase(context).deleteMessage(mmsId); + SignalDatabase.mms().deleteMessage(mmsId); } else { - DatabaseFactory.getAttachmentDatabase(context).deleteAttachment(attachmentId); + SignalDatabase.attachments().deleteAttachment(attachmentId); } } @@ -93,10 +91,10 @@ public class AttachmentUtil { @WorkerThread private static boolean isFromTrustedConversation(@NonNull Context context, @NonNull DatabaseAttachment attachment) { try { - MessageRecord message = DatabaseFactory.getMmsDatabase(context).getMessageRecord(attachment.getMmsId()); + MessageRecord message = SignalDatabase.mms().getMessageRecord(attachment.getMmsId()); Recipient individualRecipient = message.getRecipient(); - Recipient threadRecipient = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(message.getThreadId()); + Recipient threadRecipient = SignalDatabase.threads().getRecipientForThreadId(message.getThreadId()); if (threadRecipient != null && threadRecipient.isGroup()) { return threadRecipient.isProfileSharing() || isTrustedIndividual(individualRecipient, message); diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/CommunicationActions.java b/app/src/main/java/org/thoughtcrime/securesms/util/CommunicationActions.java index 74b070b8de..0486fde8ab 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/CommunicationActions.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/CommunicationActions.java @@ -26,8 +26,8 @@ import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.WebRtcCallActivity; import org.thoughtcrime.securesms.contacts.sync.DirectoryHelper; import org.thoughtcrime.securesms.conversation.ConversationIntents; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.groups.ui.invitesandrequests.joining.GroupJoinBottomSheetDialogFragment; @@ -105,7 +105,7 @@ public class CommunicationActions { new AsyncTask() { @Override protected Long doInBackground(Void... voids) { - return DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipient.getId()); + return SignalDatabase.threads().getThreadIdFor(recipient.getId()); } @Override @@ -197,9 +197,7 @@ public class CommunicationActions { GroupId.V2 groupId = GroupId.v2(groupInviteLinkUrl.getGroupMasterKey()); SimpleTask.run(SignalExecutors.BOUNDED, () -> { - GroupDatabase.GroupRecord group = DatabaseFactory.getGroupDatabase(activity) - .getGroup(groupId) - .orNull(); + GroupDatabase.GroupRecord group = SignalDatabase.groups().getGroup(groupId).orNull(); return group != null && group.isActive() ? Recipient.resolved(group.getRecipientId()) : null; diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/ConversationUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/ConversationUtil.java index 623e1f7539..a9b830eb48 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/ConversationUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/ConversationUtil.java @@ -17,8 +17,8 @@ import org.signal.core.util.concurrent.SignalExecutors; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.conversation.ConversationIntents; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.jobs.ConversationShortcutUpdateJob; import org.thoughtcrime.securesms.notifications.NotificationChannels; @@ -196,7 +196,7 @@ public final class ConversationUtil { { Recipient resolved = recipient.resolve(); Person[] persons = buildPersons(context, resolved); - Long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(resolved.getId()); + Long threadId = SignalDatabase.threads().getThreadIdFor(resolved.getId()); String shortName = resolved.isSelf() ? context.getString(R.string.note_to_self) : resolved.getShortDisplayName(context); String longName = resolved.isSelf() ? context.getString(R.string.note_to_self) : resolved.getDisplayName(context); String shortcutId = getShortcutId(resolved); @@ -232,7 +232,7 @@ public final class ConversationUtil { */ @WorkerThread private static @NonNull Person[] buildPersonsForGroup(@NonNull Context context, @NonNull GroupId groupId) { - List members = DatabaseFactory.getGroupDatabase(context).getGroupMembers(groupId, GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF); + List members = SignalDatabase.groups().getGroupMembers(groupId, GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF); return Stream.of(members).map(member -> buildPersonWithoutIcon(context, member.resolve())).toArray(Person[]::new); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/Dialogs.java b/app/src/main/java/org/thoughtcrime/securesms/util/Dialogs.java index ff93eb95db..66fcb1e9e8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/Dialogs.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/Dialogs.java @@ -18,8 +18,6 @@ package org.thoughtcrime.securesms.util; import android.content.Context; -import androidx.appcompat.app.AlertDialog; - import com.google.android.material.dialog.MaterialAlertDialogBuilder; import org.thoughtcrime.securesms.R; diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/GroupUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/GroupUtil.java index 29b6bd73e9..a8592de9db 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/GroupUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/GroupUtil.java @@ -12,8 +12,8 @@ import org.signal.core.util.logging.Log; import org.signal.zkgroup.InvalidInputException; import org.signal.zkgroup.groups.GroupMasterKey; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.groups.BadGroupIdException; import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.mms.MessageGroupContext; @@ -120,7 +120,7 @@ public final class GroupUtil { @NonNull GroupId.Push groupId) { if (groupId.isV2()) { - GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); + GroupDatabase groupDatabase = SignalDatabase.groups(); GroupDatabase.GroupRecord groupRecord = groupDatabase.requireGroup(groupId); GroupDatabase.V2GroupProperties v2GroupProperties = groupRecord.requireV2GroupProperties(); SignalServiceGroupV2 group = SignalServiceGroupV2.newBuilder(v2GroupProperties.getGroupMasterKey()) diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/IdentityUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/IdentityUtil.java index fb35caf9ad..4f6f34dca0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/IdentityUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/IdentityUtil.java @@ -11,15 +11,13 @@ import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.crypto.ReentrantSessionLock; import org.thoughtcrime.securesms.crypto.storage.TextSecureIdentityKeyStore; -import org.thoughtcrime.securesms.crypto.storage.TextSecureSessionStore; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.IdentityDatabase; -import org.thoughtcrime.securesms.database.model.IdentityRecord; import org.thoughtcrime.securesms.database.MessageDatabase; import org.thoughtcrime.securesms.database.MessageDatabase.InsertResult; +import org.thoughtcrime.securesms.database.SignalDatabase; +import org.thoughtcrime.securesms.database.model.IdentityRecord; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; -import org.thoughtcrime.securesms.jobs.ThreadUpdateJob; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.sms.IncomingIdentityDefaultMessage; @@ -62,8 +60,8 @@ public final class IdentityUtil { public static void markIdentityVerified(Context context, Recipient recipient, boolean verified, boolean remote) { long time = System.currentTimeMillis(); - MessageDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context); - GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); + MessageDatabase smsDatabase = SignalDatabase.sms(); + GroupDatabase groupDatabase = SignalDatabase.groups(); try (GroupDatabase.Reader reader = groupDatabase.getGroups()) { @@ -80,16 +78,16 @@ public final class IdentityUtil { smsDatabase.insertMessageInbox(incoming); } else { - RecipientId recipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupRecord.getId()); + RecipientId recipientId = SignalDatabase.recipients().getOrInsertFromGroupId(groupRecord.getId()); Recipient groupRecipient = Recipient.resolved(recipientId); - long threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(groupRecipient); + long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(groupRecipient); OutgoingTextMessage outgoing ; if (verified) outgoing = new OutgoingIdentityVerifiedMessage(recipient); else outgoing = new OutgoingIdentityDefaultMessage(recipient); - DatabaseFactory.getSmsDatabase(context).insertMessageOutbox(threadId, outgoing, false, time, null); - DatabaseFactory.getThreadDatabase(context).update(threadId, true); + SignalDatabase.sms().insertMessageOutbox(threadId, outgoing, false, time, null); + SignalDatabase.threads().update(threadId, true); } } } @@ -108,18 +106,18 @@ public final class IdentityUtil { if (verified) outgoing = new OutgoingIdentityVerifiedMessage(recipient); else outgoing = new OutgoingIdentityDefaultMessage(recipient); - long threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient); + long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(recipient); Log.i(TAG, "Inserting verified outbox..."); - DatabaseFactory.getSmsDatabase(context).insertMessageOutbox(threadId, outgoing, false, time, null); - DatabaseFactory.getThreadDatabase(context).update(threadId, true); + SignalDatabase.sms().insertMessageOutbox(threadId, outgoing, false, time, null); + SignalDatabase.threads().update(threadId, true); } } public static void markIdentityUpdate(@NonNull Context context, @NonNull RecipientId recipientId) { long time = System.currentTimeMillis(); - MessageDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context); - GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); + MessageDatabase smsDatabase = SignalDatabase.sms(); + GroupDatabase groupDatabase = SignalDatabase.groups(); try (GroupDatabase.Reader reader = groupDatabase.getGroups()) { GroupDatabase.GroupRecord groupRecord; diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/MediaUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/MediaUtil.java index 4fc3a98845..23183e3c92 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/MediaUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/MediaUtil.java @@ -24,7 +24,7 @@ import com.bumptech.glide.load.resource.gif.GifDrawable; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.attachments.AttachmentId; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.mediasend.Media; import org.thoughtcrime.securesms.mms.AudioSlide; import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri; @@ -404,7 +404,7 @@ public class MediaUtil { { try { AttachmentId attachmentId = PartAuthority.requireAttachmentId(uri); - MediaDataSource source = DatabaseFactory.getAttachmentDatabase(context).mediaDataSourceFor(attachmentId); + MediaDataSource source = SignalDatabase.attachments().mediaDataSourceFor(attachmentId); return extractFrame(source, timeUs); } catch (IOException e) { Log.w(TAG, "Failed to extract frame for URI: " + uri, e); diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/ProfileUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/ProfileUtil.java index 729909d3d8..c376338dcb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/ProfileUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/ProfileUtil.java @@ -13,8 +13,8 @@ import org.thoughtcrime.securesms.badges.models.Badge; import org.thoughtcrime.securesms.crypto.IdentityKeyUtil; import org.thoughtcrime.securesms.crypto.ProfileKeyUtil; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.RecipientDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.payments.MobileCoinPublicAddress; @@ -293,7 +293,7 @@ public final class ProfileUtil { avatar, badgeIds).orNull(); SignalStore.registrationValues().markHasUploadedProfile(); - DatabaseFactory.getRecipientDatabase(context).setProfileAvatar(Recipient.self().getId(), avatarPath); + SignalDatabase.recipients().setProfileAvatar(Recipient.self().getId(), avatarPath); } private static @Nullable SignalServiceProtos.PaymentAddress getSelfPaymentsAddressProtobuf() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/Projection.java b/app/src/main/java/org/thoughtcrime/securesms/util/Projection.java index c9f844b49a..db8220facd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/Projection.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/Projection.java @@ -10,10 +10,6 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.util.Pools; -import androidx.recyclerview.widget.RecyclerView; - -import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.components.CornerMask; import java.util.Arrays; import java.util.Collections; diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/RecipientAccessList.kt b/app/src/main/java/org/thoughtcrime/securesms/util/RecipientAccessList.kt index 05b80f9f4b..d81d2a5cd8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/RecipientAccessList.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/util/RecipientAccessList.kt @@ -4,7 +4,6 @@ import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.RecipientId import org.whispersystems.signalservice.api.push.ACI import org.whispersystems.signalservice.api.push.SignalServiceAddress -import java.lang.IllegalArgumentException /** * A list of Recipients, but with some helpful methods for retrieving them by various properties. Uses lazy properties to ensure that it will be as performant diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/SignalMeUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/SignalMeUtil.java index a405445784..69be8ec0c1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/SignalMeUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/SignalMeUtil.java @@ -1,7 +1,6 @@ package org.thoughtcrime.securesms.util; import android.content.Context; -import android.telephony.PhoneNumberUtils; import androidx.annotation.NonNull; import androidx.annotation.Nullable; diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/SignalUncaughtExceptionHandler.java b/app/src/main/java/org/thoughtcrime/securesms/util/SignalUncaughtExceptionHandler.java index 2db4803630..e7e6250b4f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/SignalUncaughtExceptionHandler.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/SignalUncaughtExceptionHandler.java @@ -6,8 +6,6 @@ import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.keyvalue.SignalStore; -import java.util.concurrent.TimeUnit; - import io.reactivex.rxjava3.exceptions.OnErrorNotImplementedException; public class SignalUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler { diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/SpanUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/SpanUtil.java index 2a6287eb47..ad0ce17968 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/SpanUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/SpanUtil.java @@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.util; import android.content.Context; import android.content.res.Resources; -import android.graphics.Bitmap; import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.os.Build; diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java b/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java index d04bdad06f..a60c6c978f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java @@ -19,7 +19,7 @@ import org.signal.zkgroup.profiles.ProfileKey; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.backup.BackupProtos; import org.thoughtcrime.securesms.crypto.ProfileKeyUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.impl.SqlCipherMigrationConstraintObserver; import org.thoughtcrime.securesms.keyvalue.SettingsValues; @@ -29,7 +29,6 @@ import org.thoughtcrime.securesms.notifications.NotificationChannels; import org.thoughtcrime.securesms.preferences.widgets.NotificationPrivacyPreference; import org.thoughtcrime.securesms.recipients.Recipient; import org.whispersystems.libsignal.util.Medium; -import org.whispersystems.signalservice.api.push.ACI; import java.io.IOException; import java.security.SecureRandom; @@ -39,7 +38,6 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.UUID; public class TextSecurePreferences { @@ -1178,7 +1176,7 @@ public class TextSecurePreferences { ProfileKey newProfileKey = ProfileKeyUtil.createNew(); Recipient self = Recipient.self(); - DatabaseFactory.getRecipientDatabase(context).setProfileKey(self.getId(), newProfileKey); + SignalDatabase.recipients().setProfileKey(self.getId(), newProfileKey); ApplicationDependencies.getGroupsV2Authorization().clear(); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/UsernameUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/UsernameUtil.java index 70e9eccde8..34aba1d086 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/UsernameUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/UsernameUtil.java @@ -8,7 +8,7 @@ import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; @@ -52,7 +52,7 @@ public class UsernameUtil { @WorkerThread public static @NonNull Optional fetchAciForUsername(@NonNull Context context, @NonNull String username) { - Optional localId = DatabaseFactory.getRecipientDatabase(context).getByUsername(username); + Optional localId = SignalDatabase.recipients().getByUsername(username); if (localId.isPresent()) { Recipient recipient = Recipient.resolved(localId.get()); @@ -62,7 +62,7 @@ public class UsernameUtil { return recipient.getAci(); } else { Log.w(TAG, "Found username locally, but it had no associated UUID! Clearing it."); - DatabaseFactory.getRecipientDatabase(context).clearUsernameIfExists(username); + SignalDatabase.recipients().clearUsernameIfExists(username); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/Util.java b/app/src/main/java/org/thoughtcrime/securesms/util/Util.java index 1918f8eb1e..eb60b200d5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/Util.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/Util.java @@ -54,7 +54,6 @@ import org.whispersystems.libsignal.util.guava.Optional; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.PrintStream; import java.io.UnsupportedEncodingException; import java.security.SecureRandom; import java.util.ArrayList; diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/WindowUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/WindowUtil.java index 2c737ebff8..91680ab1c7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/WindowUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/WindowUtil.java @@ -5,7 +5,6 @@ import android.graphics.Rect; import android.os.Build; import android.view.View; import android.view.Window; -import android.view.WindowInsetsController; import androidx.annotation.ColorInt; import androidx.annotation.NonNull; diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/dynamiclanguage/DynamicLanguageContextWrapper.java b/app/src/main/java/org/thoughtcrime/securesms/util/dynamiclanguage/DynamicLanguageContextWrapper.java index 958594be30..47e6fe5fb5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/dynamiclanguage/DynamicLanguageContextWrapper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/dynamiclanguage/DynamicLanguageContextWrapper.java @@ -5,7 +5,6 @@ import android.content.res.Configuration; import androidx.annotation.NonNull; -import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.util.TextSecurePreferences; import java.util.Locale; diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/storage/FileStorage.java b/app/src/main/java/org/thoughtcrime/securesms/util/storage/FileStorage.java index 9bda355b9b..1f4c10cb8b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/storage/FileStorage.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/storage/FileStorage.java @@ -3,7 +3,6 @@ package org.thoughtcrime.securesms.util.storage; import android.content.Context; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; import org.signal.core.util.StreamUtil; diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/views/CheckedLinearLayout.java b/app/src/main/java/org/thoughtcrime/securesms/util/views/CheckedLinearLayout.java index d76b398545..5fe27be0bc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/views/CheckedLinearLayout.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/views/CheckedLinearLayout.java @@ -1,7 +1,6 @@ package org.thoughtcrime.securesms.util.views; import android.content.Context; -import android.graphics.drawable.Drawable; import android.os.Parcel; import android.os.Parcelable; import android.util.AttributeSet; diff --git a/app/src/main/java/org/thoughtcrime/securesms/video/exo/ChunkedDataSource.java b/app/src/main/java/org/thoughtcrime/securesms/video/exo/ChunkedDataSource.java index 56558e1c9f..8b901dcbea 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/video/exo/ChunkedDataSource.java +++ b/app/src/main/java/org/thoughtcrime/securesms/video/exo/ChunkedDataSource.java @@ -11,8 +11,6 @@ import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.TransferListener; -import org.signal.core.util.ThreadUtil; -import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.net.ChunkedDataFetcher; diff --git a/app/src/main/java/org/thoughtcrime/securesms/video/exo/PartDataSource.java b/app/src/main/java/org/thoughtcrime/securesms/video/exo/PartDataSource.java index df6f8a8c15..8286279741 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/video/exo/PartDataSource.java +++ b/app/src/main/java/org/thoughtcrime/securesms/video/exo/PartDataSource.java @@ -13,7 +13,7 @@ import com.google.android.exoplayer2.upstream.TransferListener; import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.database.AttachmentDatabase; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.mms.PartUriParser; import java.io.EOFException; @@ -44,7 +44,7 @@ class PartDataSource implements DataSource { public long open(DataSpec dataSpec) throws IOException { this.uri = dataSpec.uri; - AttachmentDatabase attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context); + AttachmentDatabase attachmentDatabase = SignalDatabase.attachments(); PartUriParser partUri = new PartUriParser(uri); Attachment attachment = attachmentDatabase.getAttachment(partUri.getPartId()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/video/exo/SignalMediaSourceFactory.java b/app/src/main/java/org/thoughtcrime/securesms/video/exo/SignalMediaSourceFactory.java index 3e728392c5..5509005a69 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/video/exo/SignalMediaSourceFactory.java +++ b/app/src/main/java/org/thoughtcrime/securesms/video/exo/SignalMediaSourceFactory.java @@ -18,7 +18,6 @@ import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.source.MediaSourceFactory; import com.google.android.exoplayer2.source.ProgressiveMediaSource; import com.google.android.exoplayer2.upstream.DataSource; -import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; import com.google.android.exoplayer2.upstream.HttpDataSource; import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy; diff --git a/app/src/main/java/org/thoughtcrime/securesms/wallpaper/ChatWallpaperRepository.java b/app/src/main/java/org/thoughtcrime/securesms/wallpaper/ChatWallpaperRepository.java index 47dc0d06db..a07748a7ce 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/wallpaper/ChatWallpaperRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/wallpaper/ChatWallpaperRepository.java @@ -8,16 +8,14 @@ import androidx.core.util.Consumer; import org.signal.core.util.concurrent.SignalExecutors; import org.thoughtcrime.securesms.conversation.colors.ChatColors; import org.thoughtcrime.securesms.conversation.colors.ChatColorsPalette; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.util.concurrent.SerialExecutor; -import org.whispersystems.libsignal.util.guava.Optional; import java.util.ArrayList; -import java.util.LinkedList; import java.util.List; import java.util.Objects; import java.util.concurrent.Executor; @@ -61,7 +59,7 @@ class ChatWallpaperRepository { if (recipientId != null) { //noinspection CodeBlock2Expr EXECUTOR.execute(() -> { - DatabaseFactory.getRecipientDatabase(ApplicationDependencies.getApplication()).setWallpaper(recipientId, chatWallpaper); + SignalDatabase.recipients().setWallpaper(recipientId, chatWallpaper); onWallpaperSaved.run(); }); } else { @@ -73,7 +71,7 @@ class ChatWallpaperRepository { void resetAllWallpaper(@NonNull Runnable onWallpaperReset) { SignalStore.wallpaper().setWallpaper(ApplicationDependencies.getApplication(), null); EXECUTOR.execute(() -> { - DatabaseFactory.getRecipientDatabase(ApplicationDependencies.getApplication()).resetAllWallpaper(); + SignalDatabase.recipients().resetAllWallpaper(); onWallpaperReset.run(); }); } @@ -81,7 +79,7 @@ class ChatWallpaperRepository { void resetAllChatColors(@NonNull Runnable onColorsReset) { SignalStore.chatColorsValues().setChatColors(null); EXECUTOR.execute(() -> { - DatabaseFactory.getRecipientDatabase(ApplicationDependencies.getApplication()).clearAllColors(); + SignalDatabase.recipients().clearAllColors(); onColorsReset.run(); }); } @@ -91,13 +89,13 @@ class ChatWallpaperRepository { EXECUTOR.execute(() -> { Recipient recipient = Recipient.resolved(recipientId); if (recipient.hasOwnWallpaper()) { - DatabaseFactory.getRecipientDatabase(ApplicationDependencies.getApplication()).setDimWallpaperInDarkTheme(recipientId, dimInDarkTheme); + SignalDatabase.recipients().setDimWallpaperInDarkTheme(recipientId, dimInDarkTheme); } else if (recipient.hasWallpaper()) { - DatabaseFactory.getRecipientDatabase(ApplicationDependencies.getApplication()) - .setWallpaper(recipientId, - ChatWallpaperFactory.updateWithDimming(recipient.getWallpaper(), - dimInDarkTheme ? ChatWallpaper.FIXED_DIM_LEVEL_FOR_DARK_THEME - : 0f)); + SignalDatabase.recipients() + .setWallpaper(recipientId, + ChatWallpaperFactory.updateWithDimming(recipient.getWallpaper(), + dimInDarkTheme ? ChatWallpaper.FIXED_DIM_LEVEL_FOR_DARK_THEME + : 0f)); } else { throw new IllegalStateException("Unexpected call to setDimInDarkTheme, no wallpaper has been set on the given recipient or globally."); } @@ -113,7 +111,7 @@ class ChatWallpaperRepository { onChatColorCleared.run(); } else { EXECUTOR.execute(() -> { - DatabaseFactory.getRecipientDatabase(ApplicationDependencies.getApplication()).clearColor(recipientId); + SignalDatabase.recipients().clearColor(recipientId); onChatColorCleared.run(); }); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/wallpaper/WallpaperStorage.java b/app/src/main/java/org/thoughtcrime/securesms/wallpaper/WallpaperStorage.java index 8c2804f7ee..1064da017e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/wallpaper/WallpaperStorage.java +++ b/app/src/main/java/org/thoughtcrime/securesms/wallpaper/WallpaperStorage.java @@ -7,7 +7,7 @@ import androidx.annotation.NonNull; import androidx.annotation.WorkerThread; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.mms.PartAuthority; import org.thoughtcrime.securesms.util.storage.FileStorage; @@ -64,7 +64,7 @@ public final class WallpaperStorage { return; } - int recipientCount = DatabaseFactory.getRecipientDatabase(context).getWallpaperUriUsageCount(uri); + int recipientCount = SignalDatabase.recipients().getWallpaperUriUsageCount(uri); if (recipientCount > 0) { return; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/wallpaper/crop/WallpaperCropRepository.java b/app/src/main/java/org/thoughtcrime/securesms/wallpaper/crop/WallpaperCropRepository.java index dcb856b8f1..3f167f9e00 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/wallpaper/crop/WallpaperCropRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/wallpaper/crop/WallpaperCropRepository.java @@ -7,7 +7,7 @@ import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.recipients.RecipientId; @@ -37,7 +37,7 @@ final class WallpaperCropRepository { if (recipientId != null) { Log.i(TAG, "Setting image wallpaper for " + recipientId); - DatabaseFactory.getRecipientDatabase(context).setWallpaper(recipientId, wallpaper); + SignalDatabase.recipients().setWallpaper(recipientId, wallpaper); } else { Log.i(TAG, "Setting image wallpaper for default"); SignalStore.wallpaper().setWallpaper(context, wallpaper); diff --git a/app/src/main/res/layout/conversation_settings_avatar_preference_item.xml b/app/src/main/res/layout/conversation_settings_avatar_preference_item.xml index 9066b83c3a..da07eea335 100644 --- a/app/src/main/res/layout/conversation_settings_avatar_preference_item.xml +++ b/app/src/main/res/layout/conversation_settings_avatar_preference_item.xml @@ -1,7 +1,6 @@ diff --git a/app/src/main/res/layout/conversation_settings_internal_preference.xml b/app/src/main/res/layout/conversation_settings_internal_preference.xml index 083316fe2e..2d8298c034 100644 --- a/app/src/main/res/layout/conversation_settings_internal_preference.xml +++ b/app/src/main/res/layout/conversation_settings_internal_preference.xml @@ -1,6 +1,5 @@ diff --git a/app/src/main/res/layout/emoji_text_display_item_grid.xml b/app/src/main/res/layout/emoji_text_display_item_grid.xml index 55db24688d..32555bfe65 100644 --- a/app/src/main/res/layout/emoji_text_display_item_grid.xml +++ b/app/src/main/res/layout/emoji_text_display_item_grid.xml @@ -1,6 +1,5 @@ diff --git a/app/src/main/res/layout/new_device_transfer_complete_fragment.xml b/app/src/main/res/layout/new_device_transfer_complete_fragment.xml index 32c6bad785..222a8c171b 100644 --- a/app/src/main/res/layout/new_device_transfer_complete_fragment.xml +++ b/app/src/main/res/layout/new_device_transfer_complete_fragment.xml @@ -1,7 +1,6 @@ - + diff --git a/app/src/mock/java/org/thoughtcrime/securesms/MockAppDataInitializer.java b/app/src/mock/java/org/thoughtcrime/securesms/MockAppDataInitializer.java index 61fa8ddb97..544dfdcbf8 100644 --- a/app/src/mock/java/org/thoughtcrime/securesms/MockAppDataInitializer.java +++ b/app/src/mock/java/org/thoughtcrime/securesms/MockAppDataInitializer.java @@ -11,7 +11,6 @@ import org.signal.core.util.StreamUtil; import org.thoughtcrime.securesms.crypto.IdentityKeyUtil; import org.thoughtcrime.securesms.crypto.MasterSecret; import org.thoughtcrime.securesms.crypto.MasterSecretUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.KeyValueDatabase; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.recipients.Recipient; diff --git a/app/src/test/java/org/thoughtcrime/securesms/conversationlist/UnarchivedConversationListDataSourceTest.java b/app/src/test/java/org/thoughtcrime/securesms/conversationlist/UnarchivedConversationListDataSourceTest.java index 5786329084..b53bbe1d41 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/conversationlist/UnarchivedConversationListDataSourceTest.java +++ b/app/src/test/java/org/thoughtcrime/securesms/conversationlist/UnarchivedConversationListDataSourceTest.java @@ -3,7 +3,6 @@ package org.thoughtcrime.securesms.conversationlist; import android.app.Application; import android.database.Cursor; -import androidx.test.core.app.ApplicationProvider; import org.junit.Before; import org.junit.Ignore; @@ -16,16 +15,14 @@ import org.powermock.modules.junit4.rule.PowerMockRule; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; import org.thoughtcrime.securesms.conversationlist.model.ConversationReader; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.DatabaseObserver; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; -import org.thoughtcrime.securesms.util.paging.Invalidator; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyLong; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.verify; @@ -37,7 +34,7 @@ import static org.powermock.api.mockito.PowerMockito.when; @RunWith(RobolectricTestRunner.class) @Config(manifest = Config.NONE, application = Application.class) @PowerMockIgnore({ "org.mockito.*", "org.robolectric.*", "android.*", "androidx.*", "org.powermock.*" }) -@PrepareForTest({ ApplicationDependencies.class, DatabaseFactory.class, DatabaseObserver.class }) +@PrepareForTest({ ApplicationDependencies.class, SignalDatabase.class, DatabaseObserver.class }) public class UnarchivedConversationListDataSourceTest { @Rule @@ -50,11 +47,11 @@ public class UnarchivedConversationListDataSourceTest { @Before public void setUp() { mockStatic(ApplicationDependencies.class); - mockStatic(DatabaseFactory.class); + mockStatic(SignalDatabase.class); threadDatabase = mock(ThreadDatabase.class); - when(DatabaseFactory.getThreadDatabase(any())).thenReturn(threadDatabase); + when(SignalDatabase.threads()).thenReturn(threadDatabase); when(ApplicationDependencies.getDatabaseObserver()).thenReturn(mock(DatabaseObserver.class)); testSubject = new ConversationListDataSource.UnarchivedConversationListDataSource(mock(Application.class)); diff --git a/app/src/test/java/org/thoughtcrime/securesms/payments/MoneyViewTest.java b/app/src/test/java/org/thoughtcrime/securesms/payments/MoneyViewTest.java index 76e9bb7966..4f606022a4 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/payments/MoneyViewTest.java +++ b/app/src/test/java/org/thoughtcrime/securesms/payments/MoneyViewTest.java @@ -7,13 +7,8 @@ import androidx.test.core.app.ApplicationProvider; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.powermock.core.classloader.annotations.PowerMockIgnore; -import org.powermock.core.classloader.annotations.PrepareForTest; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.DatabaseObserver; -import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.whispersystems.signalservice.api.payments.Currency; import static org.junit.Assert.assertEquals; diff --git a/app/src/test/java/org/thoughtcrime/securesms/recipients/RecipientUtilTest.java b/app/src/test/java/org/thoughtcrime/securesms/recipients/RecipientUtilTest.java index ebe09d1595..7065136215 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/recipients/RecipientUtilTest.java +++ b/app/src/test/java/org/thoughtcrime/securesms/recipients/RecipientUtilTest.java @@ -8,15 +8,14 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MmsSmsDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase; +import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.util.FeatureFlags; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyLong; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -25,7 +24,7 @@ import static org.powermock.api.mockito.PowerMockito.mockStatic; import static org.powermock.api.mockito.PowerMockito.when; @RunWith(PowerMockRunner.class) -@PrepareForTest({DatabaseFactory.class, FeatureFlags.class}) +@PrepareForTest({SignalDatabase.class, FeatureFlags.class}) public class RecipientUtilTest { private Context context = mock(Context.class); @@ -36,10 +35,10 @@ public class RecipientUtilTest { @Before public void setUp() { - mockStatic(DatabaseFactory.class); - when(DatabaseFactory.getThreadDatabase(any())).thenReturn(mockThreadDatabase); - when(DatabaseFactory.getMmsSmsDatabase(any())).thenReturn(mockMmsSmsDatabase); - when(DatabaseFactory.getRecipientDatabase(any())).thenReturn(mockRecipientDatabase); + mockStatic(SignalDatabase.class); + when(SignalDatabase.threads()).thenReturn(mockThreadDatabase); + when(SignalDatabase.mmsSms()).thenReturn(mockMmsSmsDatabase); + when(SignalDatabase.recipients()).thenReturn(mockRecipientDatabase); mockStatic(FeatureFlags.class); when(recipient.getId()).thenReturn(RecipientId.from(5)); diff --git a/app/src/test/java/org/thoughtcrime/securesms/testing/ProxySQLCipherOpenHelper.kt b/app/src/test/java/org/thoughtcrime/securesms/testing/ProxySQLCipherOpenHelper.kt index 8541f6d92c..566f861f59 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/testing/ProxySQLCipherOpenHelper.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/testing/ProxySQLCipherOpenHelper.kt @@ -1,23 +1,23 @@ package org.thoughtcrime.securesms.testing -import android.content.Context +import android.app.Application +import org.thoughtcrime.securesms.crypto.AttachmentSecret import org.thoughtcrime.securesms.crypto.DatabaseSecret -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper +import org.thoughtcrime.securesms.database.SignalDatabase import java.security.SecureRandom import android.database.sqlite.SQLiteDatabase as AndroidSQLiteDatabase import net.zetetic.database.sqlcipher.SQLiteDatabase as SQLCipherSQLiteDatabase -import org.thoughtcrime.securesms.database.SQLiteDatabase as SignalSQLiteDatabase /** - * Proxy [SQLCipherOpenHelper] to the [TestSQLiteOpenHelper] interface. + * Proxy [SignalDatabase] to the [TestSQLiteOpenHelper] interface. */ class ProxySQLCipherOpenHelper( - context: Context, + context: Application, val readableDatabase: AndroidSQLiteDatabase, val writableDatabase: AndroidSQLiteDatabase, -) : SQLCipherOpenHelper(context, DatabaseSecret(ByteArray(32).apply { SecureRandom().nextBytes(this) })) { +) : SignalDatabase(context, DatabaseSecret(ByteArray(32).apply { SecureRandom().nextBytes(this) }), AttachmentSecret()) { - constructor(context: Context, testOpenHelper: TestSQLiteOpenHelper) : this(context, testOpenHelper.readableDatabase, testOpenHelper.writableDatabase) + constructor(context: Application, testOpenHelper: TestSQLiteOpenHelper) : this(context, testOpenHelper.readableDatabase, testOpenHelper.writableDatabase) override fun close() { throw UnsupportedOperationException() @@ -43,15 +43,15 @@ class ProxySQLCipherOpenHelper( throw UnsupportedOperationException() } - override fun onOpen(db: SQLCipherSQLiteDatabase?) { + override fun onOpen(db: net.zetetic.database.sqlcipher.SQLiteDatabase) { throw UnsupportedOperationException() } - override fun onCreate(db: SQLCipherSQLiteDatabase?) { + override fun onCreate(db: net.zetetic.database.sqlcipher.SQLiteDatabase) { throw UnsupportedOperationException() } - override fun onUpgrade(db: SQLCipherSQLiteDatabase?, oldVersion: Int, newVersion: Int) { + override fun onUpgrade(db: net.zetetic.database.sqlcipher.SQLiteDatabase, oldVersion: Int, newVersion: Int) { throw UnsupportedOperationException() } @@ -63,27 +63,23 @@ class ProxySQLCipherOpenHelper( throw UnsupportedOperationException() } - override fun getRawReadableDatabase(): SQLCipherSQLiteDatabase { - throw UnsupportedOperationException() - } + override val rawReadableDatabase: net.zetetic.database.sqlcipher.SQLiteDatabase + get() = throw UnsupportedOperationException() - override fun getRawWritableDatabase(): SQLCipherSQLiteDatabase { - throw UnsupportedOperationException() - } + override val rawWritableDatabase: net.zetetic.database.sqlcipher.SQLiteDatabase + get() = throw UnsupportedOperationException() - override fun getSignalReadableDatabase(): SignalSQLiteDatabase { - return ProxySignalSQLiteDatabase(readableDatabase) - } + override val signalReadableDatabase: org.thoughtcrime.securesms.database.SQLiteDatabase + get() = ProxySignalSQLiteDatabase(readableDatabase) - override fun getSignalWritableDatabase(): SignalSQLiteDatabase { - return ProxySignalSQLiteDatabase(writableDatabase) - } + override val signalWritableDatabase: org.thoughtcrime.securesms.database.SQLiteDatabase + get() = ProxySignalSQLiteDatabase(writableDatabase) override fun getSqlCipherDatabase(): SQLCipherSQLiteDatabase { throw UnsupportedOperationException() } - override fun markCurrent(db: SQLCipherSQLiteDatabase?) { + override fun markCurrent(db: net.zetetic.database.sqlcipher.SQLiteDatabase) { throw UnsupportedOperationException() } }