diff --git a/app/build.gradle b/app/build.gradle index 89327b29d..5cd521826 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,6 +9,7 @@ buildscript { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlinVersion" classpath "com.google.gms:google-services:4.3.3" + classpath 'com.google.dagger:hilt-android-gradle-plugin:2.38.1' } } @@ -19,6 +20,7 @@ apply plugin: 'witness' apply plugin: 'kotlin-kapt' apply plugin: 'com.google.gms.google-services' apply plugin: 'kotlinx-serialization' +apply plugin: 'dagger.hilt.android.plugin' configurations.all { exclude module: "commons-logging" @@ -70,9 +72,8 @@ dependencies { implementation 'com.theartofdev.edmodo:android-image-cropper:2.8.0' implementation 'com.melnykov:floatingactionbutton:1.3.0' implementation 'com.google.zxing:android-integration:3.1.0' - implementation 'com.squareup.dagger:dagger:1.2.2' - annotationProcessor 'com.squareup.dagger:dagger-compiler:1.2.2' - kapt 'com.squareup.dagger:dagger-compiler:1.2.2' + implementation "com.google.dagger:hilt-android:2.38.1" + kapt "com.google.dagger:hilt-compiler:2.38.1" implementation 'mobi.upod:time-duration-picker:1.1.3' implementation 'com.google.zxing:core:3.2.1' implementation ('com.davemorrissey.labs:subsampling-scale-image-view:3.6.0') { @@ -153,8 +154,8 @@ dependencies { testImplementation 'org.robolectric:shadows-multidex:4.4' } -def canonicalVersionCode = 222 -def canonicalVersionName = "1.11.10" +def canonicalVersionCode = 227 +def canonicalVersionName = "1.11.11" def postFixSize = 10 def abiPostFix = ['armeabi-v7a' : 1, diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index 363343696..d0d7ba60d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -15,6 +15,9 @@ */ package org.thoughtcrime.securesms; +import static nl.komponents.kovenant.android.KovenantAndroid.startKovenant; +import static nl.komponents.kovenant.android.KovenantAndroid.stopKovenant; + import android.app.Application; import android.content.Context; import android.content.Intent; @@ -30,6 +33,7 @@ import androidx.lifecycle.ProcessLifecycleOwner; import org.conscrypt.Conscrypt; import org.session.libsession.avatars.AvatarHelper; +import org.session.libsession.database.MessageDataProvider; import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsession.messaging.sending_receiving.notifications.MessageNotifier; import org.session.libsession.messaging.sending_receiving.pollers.ClosedGroupPollerV2; @@ -47,25 +51,27 @@ import org.session.libsignal.utilities.ThreadUtils; import org.signal.aesgcmprovider.AesGcmProvider; import org.thoughtcrime.securesms.components.TypingStatusSender; import org.thoughtcrime.securesms.crypto.KeyPairUtilities; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.dependencies.InjectableType; -import org.thoughtcrime.securesms.dependencies.SignalCommunicationModule; -import org.thoughtcrime.securesms.jobmanager.DependencyInjector; +import org.thoughtcrime.securesms.database.JobDatabase; +import org.thoughtcrime.securesms.database.LokiAPIDatabase; +import org.thoughtcrime.securesms.database.Storage; +import org.thoughtcrime.securesms.database.LokiAPIDatabase; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; +import org.thoughtcrime.securesms.dependencies.DatabaseModule; +import org.thoughtcrime.securesms.groups.OpenGroupManager; +import org.thoughtcrime.securesms.home.HomeActivity; +import org.thoughtcrime.securesms.groups.OpenGroupManager; +import org.thoughtcrime.securesms.home.HomeActivity; import org.thoughtcrime.securesms.jobmanager.JobManager; import org.thoughtcrime.securesms.jobmanager.impl.JsonDataSerializer; import org.thoughtcrime.securesms.jobs.FastJobStorage; import org.thoughtcrime.securesms.jobs.JobManagerFactories; import org.thoughtcrime.securesms.logging.AndroidLogger; +import org.thoughtcrime.securesms.logging.PersistentLogger; import org.thoughtcrime.securesms.logging.UncaughtExceptionLogger; -import org.thoughtcrime.securesms.home.HomeActivity; import org.thoughtcrime.securesms.notifications.BackgroundPollWorker; -import org.thoughtcrime.securesms.notifications.LokiPushNotificationManager; -import org.thoughtcrime.securesms.groups.OpenGroupManager; -import org.thoughtcrime.securesms.database.LokiAPIDatabase; -import org.thoughtcrime.securesms.util.Broadcaster; -import org.thoughtcrime.securesms.notifications.FcmUtils; -import org.thoughtcrime.securesms.util.UiModeUtilities; import org.thoughtcrime.securesms.notifications.DefaultMessageNotifier; +import org.thoughtcrime.securesms.notifications.FcmUtils; +import org.thoughtcrime.securesms.notifications.LokiPushNotificationManager; import org.thoughtcrime.securesms.notifications.NotificationChannels; import org.thoughtcrime.securesms.notifications.OptimizedMessageNotifier; import org.thoughtcrime.securesms.providers.BlobProvider; @@ -75,6 +81,8 @@ import org.thoughtcrime.securesms.service.UpdateApkRefreshListener; import org.thoughtcrime.securesms.sskenvironment.ProfileManager; import org.thoughtcrime.securesms.sskenvironment.ReadReceiptManager; import org.thoughtcrime.securesms.sskenvironment.TypingStatusRepository; +import org.thoughtcrime.securesms.util.Broadcaster; +import org.thoughtcrime.securesms.util.UiModeUtilities; import org.thoughtcrime.securesms.util.dynamiclanguage.LocaleParseHelper; import org.webrtc.PeerConnectionFactory; import org.webrtc.PeerConnectionFactory.InitializationOptions; @@ -88,14 +96,14 @@ import java.util.Date; import java.util.HashSet; import java.util.Set; -import dagger.ObjectGraph; +import javax.inject.Inject; + +import dagger.hilt.EntryPoints; +import dagger.hilt.android.HiltAndroidApp; import kotlin.Unit; import kotlinx.coroutines.Job; import network.loki.messenger.BuildConfig; -import static nl.komponents.kovenant.android.KovenantAndroid.startKovenant; -import static nl.komponents.kovenant.android.KovenantAndroid.stopKovenant; - /** * Will be called once when the TextSecure process is created. *

@@ -104,7 +112,8 @@ import static nl.komponents.kovenant.android.KovenantAndroid.stopKovenant; * * @author Moxie Marlinspike */ -public class ApplicationContext extends Application implements DependencyInjector, DefaultLifecycleObserver { +@HiltAndroidApp +public class ApplicationContext extends Application implements DefaultLifecycleObserver { public static final String PREFERENCES_NAME = "SecureSMS-Preferences"; @@ -116,13 +125,17 @@ public class ApplicationContext extends Application implements DependencyInjecto private JobManager jobManager; private ReadReceiptManager readReceiptManager; private ProfileManager profileManager; - private ObjectGraph objectGraph; public MessageNotifier messageNotifier = null; public Poller poller = null; public Broadcaster broadcaster = null; - public SignalCommunicationModule communicationModule; private Job firebaseInstanceIdJob; private Handler conversationListNotificationHandler; + private PersistentLogger persistentLogger; + + @Inject LokiAPIDatabase lokiAPIDatabase; + @Inject Storage storage; + @Inject MessageDataProvider messageDataProvider; + @Inject JobDatabase jobDatabase; private volatile boolean isAppVisible; @@ -130,29 +143,37 @@ public class ApplicationContext extends Application implements DependencyInjecto return (ApplicationContext) context.getApplicationContext(); } + public DatabaseComponent getDatabaseComponent() { + return EntryPoints.get(getApplicationContext(), DatabaseComponent.class); + } + public Handler getConversationListNotificationHandler() { return this.conversationListNotificationHandler; } + public PersistentLogger getPersistentLogger() { + return this.persistentLogger; + } + @Override public void onCreate() { + DatabaseModule.init(this); super.onCreate(); Log.i(TAG, "onCreate()"); startKovenant(); initializeSecurityProvider(); initializeLogging(); initializeCrashHandling(); - initializeDependencyInjection(); NotificationChannels.create(this); ProcessLifecycleOwner.get().getLifecycle().addObserver(this); AppContext.INSTANCE.configureKovenant(); messageNotifier = new OptimizedMessageNotifier(new DefaultMessageNotifier()); broadcaster = new Broadcaster(this); conversationListNotificationHandler = new Handler(Looper.getMainLooper()); - LokiAPIDatabase apiDB = DatabaseFactory.getLokiAPIDatabase(this); + LokiAPIDatabase apiDB = getDatabaseComponent().lokiAPIDatabase(); MessagingModuleConfiguration.Companion.configure(this, - DatabaseFactory.getStorage(this), - DatabaseFactory.getAttachmentProvider(this), + storage, + messageDataProvider, ()-> KeyPairUtilities.INSTANCE.getUserED25519KeyPair(this) ); SnodeModule.Companion.configure(apiDB, broadcaster); @@ -210,13 +231,6 @@ public class ApplicationContext extends Application implements DependencyInjecto super.onTerminate(); } - @Override - public void injectDependencies(Object object) { - if (object instanceof InjectableType) { - objectGraph.inject(object); - } - } - public void initializeLocaleParser() { LocaleParser.Companion.configure(new LocaleParseHelper()); } @@ -276,7 +290,10 @@ public class ApplicationContext extends Application implements DependencyInjecto } private void initializeLogging() { - Log.initialize(new AndroidLogger()); + if (persistentLogger == null) { + persistentLogger = new PersistentLogger(this); + } + Log.initialize(new AndroidLogger(), persistentLogger); } private void initializeCrashHandling() { @@ -290,16 +307,10 @@ public class ApplicationContext extends Application implements DependencyInjecto .setJobFactories(JobManagerFactories.getJobFactories(this)) .setConstraintFactories(JobManagerFactories.getConstraintFactories(this)) .setConstraintObservers(JobManagerFactories.getConstraintObservers(this)) - .setJobStorage(new FastJobStorage(DatabaseFactory.getJobDatabase(this))) - .setDependencyInjector(this) + .setJobStorage(new FastJobStorage(jobDatabase)) .build()); } - private void initializeDependencyInjection() { - communicationModule = new SignalCommunicationModule(this); - this.objectGraph = ObjectGraph.create(communicationModule); - } - private void initializeExpiringMessageManager() { this.expiringMessageManager = new ExpiringMessageManager(this); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/ShareActivity.java b/app/src/main/java/org/thoughtcrime/securesms/ShareActivity.java index 2741738c4..f03840c1a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ShareActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ShareActivity.java @@ -35,20 +35,19 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBar; import androidx.appcompat.widget.Toolbar; -import org.session.libsession.utilities.DistributionTypes; -import org.thoughtcrime.securesms.components.SearchToolbar; - import org.session.libsession.utilities.Address; -import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.session.libsession.utilities.DistributionTypes; +import org.session.libsession.utilities.ViewUtil; +import org.session.libsession.utilities.recipients.Recipient; import org.session.libsignal.utilities.Log; +import org.thoughtcrime.securesms.components.SearchToolbar; import org.thoughtcrime.securesms.contacts.ContactSelectionListFragment; import org.thoughtcrime.securesms.contacts.ContactSelectionListLoader.DisplayMode; +import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import org.thoughtcrime.securesms.mms.PartAuthority; import org.thoughtcrime.securesms.providers.BlobProvider; -import org.session.libsession.utilities.recipients.Recipient; import org.thoughtcrime.securesms.util.MediaUtil; -import org.session.libsession.utilities.ViewUtil; import java.io.FileInputStream; import java.io.IOException; @@ -251,7 +250,7 @@ public class ShareActivity extends PassphraseRequiredActionBarActivity @Override public void onContactSelected(String number) { Recipient recipient = Recipient.from(this, Address.fromExternal(this, number), true); - long existingThread = DatabaseFactory.getThreadDatabase(this).getThreadIdIfExistsFor(recipient); + long existingThread = DatabaseComponent.get(this).threadDatabase().getThreadIdIfExistsFor(recipient); createConversation(existingThread, recipient.getAddress(), DistributionTypes.DEFAULT); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachmentProvider.kt b/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachmentProvider.kt index e2f78eecc..fccfd7694 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachmentProvider.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachmentProvider.kt @@ -18,9 +18,9 @@ import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.guava.Optional import org.thoughtcrime.securesms.database.AttachmentDatabase import org.thoughtcrime.securesms.database.Database -import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.MessagingDatabase import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper +import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.events.PartProgressEvent import org.thoughtcrime.securesms.mms.MediaConstraints import org.thoughtcrime.securesms.mms.PartAuthority @@ -31,25 +31,25 @@ import java.io.InputStream class DatabaseAttachmentProvider(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper), MessageDataProvider { override fun getAttachmentStream(attachmentId: Long): SessionServiceAttachmentStream? { - val attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context) + val attachmentDatabase = DatabaseComponent.get(context).attachmentDatabase() val databaseAttachment = attachmentDatabase.getAttachment(AttachmentId(attachmentId, 0)) ?: return null return databaseAttachment.toAttachmentStream(context) } override fun getAttachmentPointer(attachmentId: Long): SessionServiceAttachmentPointer? { - val attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context) + val attachmentDatabase = DatabaseComponent.get(context).attachmentDatabase() val databaseAttachment = attachmentDatabase.getAttachment(AttachmentId(attachmentId, 0)) ?: return null return databaseAttachment.toAttachmentPointer() } override fun getSignalAttachmentStream(attachmentId: Long): SignalServiceAttachmentStream? { - val attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context) + val attachmentDatabase = DatabaseComponent.get(context).attachmentDatabase() val databaseAttachment = attachmentDatabase.getAttachment(AttachmentId(attachmentId, 0)) ?: return null return databaseAttachment.toSignalAttachmentStream(context) } override fun getScaledSignalAttachmentStream(attachmentId: Long): SignalServiceAttachmentStream? { - val database = DatabaseFactory.getAttachmentDatabase(context) + val database = DatabaseComponent.get(context).attachmentDatabase() val databaseAttachment = database.getAttachment(AttachmentId(attachmentId, 0)) ?: return null val mediaConstraints = MediaConstraints.getPushMediaConstraints() val scaledAttachment = scaleAndStripExif(database, mediaConstraints, databaseAttachment) ?: return null @@ -57,45 +57,47 @@ class DatabaseAttachmentProvider(context: Context, helper: SQLCipherOpenHelper) } override fun getSignalAttachmentPointer(attachmentId: Long): SignalServiceAttachmentPointer? { - val attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context) + val attachmentDatabase = DatabaseComponent.get(context).attachmentDatabase() val databaseAttachment = attachmentDatabase.getAttachment(AttachmentId(attachmentId, 0)) ?: return null return databaseAttachment.toSignalAttachmentPointer() } override fun setAttachmentState(attachmentState: AttachmentState, attachmentId: AttachmentId, messageID: Long) { - val attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context) + val attachmentDatabase = DatabaseComponent.get(context).attachmentDatabase() attachmentDatabase.setTransferState(messageID, attachmentId, attachmentState.value) } override fun getMessageForQuote(timestamp: Long, author: Address): Pair? { - val messagingDatabase = DatabaseFactory.getMmsSmsDatabase(context) + val messagingDatabase = DatabaseComponent.get(context).mmsSmsDatabase() val message = messagingDatabase.getMessageFor(timestamp, author) return if (message != null) Pair(message.id, message.isMms) else null } override fun getAttachmentsAndLinkPreviewFor(mmsId: Long): List { - return DatabaseFactory.getAttachmentDatabase(context).getAttachmentsForMessage(mmsId) + return DatabaseComponent.get(context).attachmentDatabase().getAttachmentsForMessage(mmsId) } override fun getMessageBodyFor(timestamp: Long, author: String): String { - val messagingDatabase = DatabaseFactory.getMmsSmsDatabase(context) + val messagingDatabase = DatabaseComponent.get(context).mmsSmsDatabase() return messagingDatabase.getMessageFor(timestamp, author)!!.body } override fun getAttachmentIDsFor(messageID: Long): List { - return DatabaseFactory.getAttachmentDatabase(context).getAttachmentsForMessage(messageID).mapNotNull { + return DatabaseComponent.get(context) + .attachmentDatabase() + .getAttachmentsForMessage(messageID).mapNotNull { if (it.isQuote) return@mapNotNull null it.attachmentId.rowId } } override fun getLinkPreviewAttachmentIDFor(messageID: Long): Long? { - val message = DatabaseFactory.getMmsDatabase(context).getOutgoingMessage(messageID) + val message = DatabaseComponent.get(context).mmsDatabase().getOutgoingMessage(messageID) return message.linkPreviews.firstOrNull()?.attachmentId?.rowId } override fun getIndividualRecipientForMms(mmsId: Long): Recipient? { - val mmsDb = DatabaseFactory.getMmsDatabase(context) + val mmsDb = DatabaseComponent.get(context).mmsDatabase() val message = mmsDb.getMessage(mmsId).use { mmsDb.readerFor(it).next } @@ -103,7 +105,7 @@ class DatabaseAttachmentProvider(context: Context, helper: SQLCipherOpenHelper) } override fun insertAttachment(messageId: Long, attachmentId: AttachmentId, stream: InputStream) { - val attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context) + val attachmentDatabase = DatabaseComponent.get(context).attachmentDatabase() attachmentDatabase.insertAttachmentsForPlaceholder(messageId, attachmentId, stream) } @@ -112,7 +114,7 @@ class DatabaseAttachmentProvider(context: Context, helper: SQLCipherOpenHelper) durationMs: Long, threadId: Long ) { - val attachmentDb = DatabaseFactory.getAttachmentDatabase(context) + val attachmentDb = DatabaseComponent.get(context).attachmentDatabase() attachmentDb.setAttachmentAudioExtras(DatabaseAttachmentAudioExtras( attachmentId = attachmentId, visualSamples = byteArrayOf(), @@ -121,20 +123,20 @@ class DatabaseAttachmentProvider(context: Context, helper: SQLCipherOpenHelper) } override fun isMmsOutgoing(mmsMessageId: Long): Boolean { - val mmsDb = DatabaseFactory.getMmsDatabase(context) + val mmsDb = DatabaseComponent.get(context).mmsDatabase() return mmsDb.getMessage(mmsMessageId).use { cursor -> mmsDb.readerFor(cursor).next }.isOutgoing } override fun isOutgoingMessage(timestamp: Long): Boolean { - val smsDatabase = DatabaseFactory.getSmsDatabase(context) - val mmsDatabase = DatabaseFactory.getMmsDatabase(context) + val smsDatabase = DatabaseComponent.get(context).smsDatabase() + val mmsDatabase = DatabaseComponent.get(context).mmsDatabase() return smsDatabase.isOutgoingMessage(timestamp) || mmsDatabase.isOutgoingMessage(timestamp) } override fun handleSuccessfulAttachmentUpload(attachmentId: Long, attachmentStream: SignalServiceAttachmentStream, attachmentKey: ByteArray, uploadResult: UploadResult) { - val database = DatabaseFactory.getAttachmentDatabase(context) + val database = DatabaseComponent.get(context).attachmentDatabase() val databaseAttachment = getDatabaseAttachment(attachmentId) ?: return val attachmentPointer = SignalServiceAttachmentPointer(uploadResult.id, attachmentStream.contentType, @@ -152,35 +154,35 @@ class DatabaseAttachmentProvider(context: Context, helper: SQLCipherOpenHelper) } override fun handleFailedAttachmentUpload(attachmentId: Long) { - val database = DatabaseFactory.getAttachmentDatabase(context) + val database = DatabaseComponent.get(context).attachmentDatabase() val databaseAttachment = getDatabaseAttachment(attachmentId) ?: return database.handleFailedAttachmentUpload(databaseAttachment.attachmentId) } override fun getMessageID(serverID: Long): Long? { - val openGroupMessagingDatabase = DatabaseFactory.getLokiMessageDatabase(context) + val openGroupMessagingDatabase = DatabaseComponent.get(context).lokiMessageDatabase() return openGroupMessagingDatabase.getMessageID(serverID) } override fun getMessageID(serverId: Long, threadId: Long): Pair? { - val messageDB = DatabaseFactory.getLokiMessageDatabase(context) + val messageDB = DatabaseComponent.get(context).lokiMessageDatabase() return messageDB.getMessageID(serverId, threadId) } override fun deleteMessage(messageID: Long, isSms: Boolean) { - val messagingDatabase: MessagingDatabase = if (isSms) DatabaseFactory.getSmsDatabase(context) - else DatabaseFactory.getMmsDatabase(context) + val messagingDatabase: MessagingDatabase = if (isSms) DatabaseComponent.get(context).smsDatabase() + else DatabaseComponent.get(context).mmsDatabase() messagingDatabase.deleteMessage(messageID) - DatabaseFactory.getLokiMessageDatabase(context).deleteMessage(messageID, isSms) - DatabaseFactory.getLokiMessageDatabase(context).deleteMessageServerHash(messageID) + DatabaseComponent.get(context).lokiMessageDatabase().deleteMessage(messageID, isSms) + DatabaseComponent.get(context).lokiMessageDatabase().deleteMessageServerHash(messageID) } override fun updateMessageAsDeleted(timestamp: Long, author: String) { - val database = DatabaseFactory.getMmsSmsDatabase(context) + val database = DatabaseComponent.get(context).mmsSmsDatabase() val address = Address.fromSerialized(author) val message = database.getMessageFor(timestamp, address) ?: return - val messagingDatabase: MessagingDatabase = if (message.isMms) DatabaseFactory.getMmsDatabase(context) - else DatabaseFactory.getSmsDatabase(context) + val messagingDatabase: MessagingDatabase = if (message.isMms) DatabaseComponent.get(context).mmsDatabase() + else DatabaseComponent.get(context).smsDatabase() messagingDatabase.markAsDeleted(message.id, message.isRead) if (message.isOutgoing) { messagingDatabase.deleteMessage(message.id) @@ -188,12 +190,12 @@ class DatabaseAttachmentProvider(context: Context, helper: SQLCipherOpenHelper) } override fun getServerHashForMessage(messageID: Long): String? { - val messageDB = DatabaseFactory.getLokiMessageDatabase(context) + val messageDB = DatabaseComponent.get(context).lokiMessageDatabase() return messageDB.getMessageServerHash(messageID) } override fun getDatabaseAttachment(attachmentId: Long): DatabaseAttachment? { - val attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context) + val attachmentDatabase = DatabaseComponent.get(context).attachmentDatabase() return attachmentDatabase.getAttachment(AttachmentId(attachmentId, 0)) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/BackupRestoreActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/BackupRestoreActivity.kt index 33b0a8a3f..a94c866c0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/BackupRestoreActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/BackupRestoreActivity.kt @@ -1,4 +1,4 @@ -package org.thoughtcrime.securesms.backup; +package org.thoughtcrime.securesms.backup import android.app.Activity import android.app.Application @@ -24,17 +24,18 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import network.loki.messenger.R +import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsignal.utilities.Log import org.thoughtcrime.securesms.BaseActionBarActivity import org.thoughtcrime.securesms.backup.FullBackupImporter.DatabaseDowngradeException import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider import org.thoughtcrime.securesms.database.DatabaseFactory -import org.session.libsignal.utilities.Log -import org.thoughtcrime.securesms.util.setUpActionBarSessionLogo -import org.thoughtcrime.securesms.util.show +import org.thoughtcrime.securesms.dependencies.DatabaseComponent +import org.thoughtcrime.securesms.home.HomeActivity import org.thoughtcrime.securesms.notifications.NotificationChannels import org.thoughtcrime.securesms.util.BackupUtil -import org.session.libsession.utilities.TextSecurePreferences -import org.thoughtcrime.securesms.home.HomeActivity +import org.thoughtcrime.securesms.util.setUpActionBarSessionLogo +import org.thoughtcrime.securesms.util.show class BackupRestoreActivity : BaseActionBarActivity() { @@ -170,11 +171,11 @@ class BackupRestoreViewModel(application: Application): AndroidViewModel(applica withContext(Dispatchers.IO) { result = try { - val database = DatabaseFactory.getBackupDatabase(context) + val database = DatabaseComponent.get(context).openHelper().readableDatabase FullBackupImporter.importFromUri( context, AttachmentSecretProvider.getInstance(context).getOrCreateAttachmentSecret(), - DatabaseFactory.getBackupDatabase(context), + database, backupFile, passphrase ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupImporter.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupImporter.kt index 81f314458..201671c1b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupImporter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupImporter.kt @@ -7,13 +7,6 @@ import android.net.Uri import androidx.annotation.WorkerThread import net.sqlcipher.database.SQLiteDatabase import org.greenrobot.eventbus.EventBus -import org.thoughtcrime.securesms.backup.BackupProtos.* -import org.thoughtcrime.securesms.crypto.AttachmentSecret -import org.thoughtcrime.securesms.crypto.ModernEncryptingPartOutputStream -import org.thoughtcrime.securesms.database.* -import org.session.libsignal.utilities.Log -import org.thoughtcrime.securesms.util.BackupUtil - import org.session.libsession.avatars.AvatarHelper import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId import org.session.libsession.utilities.Address @@ -21,7 +14,13 @@ import org.session.libsession.utilities.Conversions import org.session.libsession.utilities.Util import org.session.libsignal.crypto.kdf.HKDFv3 import org.session.libsignal.utilities.ByteUtil - +import org.session.libsignal.utilities.Log +import org.thoughtcrime.securesms.backup.BackupProtos.* +import org.thoughtcrime.securesms.crypto.AttachmentSecret +import org.thoughtcrime.securesms.crypto.ModernEncryptingPartOutputStream +import org.thoughtcrime.securesms.database.* +import org.thoughtcrime.securesms.dependencies.DatabaseComponent +import org.thoughtcrime.securesms.util.BackupUtil import java.io.* import java.security.InvalidAlgorithmParameterException import java.security.InvalidKeyException @@ -179,14 +178,14 @@ object FullBackupImporter { val where = AttachmentDatabase.MMS_ID + trimmedCondition db.query(AttachmentDatabase.TABLE_NAME, columns, where, null, null, null, null).use { cursor -> while (cursor != null && cursor.moveToNext()) { - DatabaseFactory.getAttachmentDatabase(context) + DatabaseComponent.get(context).attachmentDatabase() .deleteAttachment(AttachmentId(cursor.getLong(0), cursor.getLong(1))) } } db.query(ThreadDatabase.TABLE_NAME, arrayOf(ThreadDatabase.ID), ThreadDatabase.EXPIRES_IN + " > 0", null, null, null, null).use { cursor -> while (cursor != null && cursor.moveToNext()) { - DatabaseFactory.getThreadDatabase(context).update(cursor.getLong(0), false) + DatabaseComponent.get(context).threadDatabase().update(cursor.getLong(0), false) } } } 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 b93ae4ab6..195c066d4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/ConversationItemFooter.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/ConversationItemFooter.java @@ -15,8 +15,8 @@ import androidx.annotation.Nullable; import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.conversation.v2.components.ExpirationTimerView; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.model.MessageRecord; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import org.thoughtcrime.securesms.service.ExpiringMessageManager; import org.thoughtcrime.securesms.util.DateUtils; @@ -117,8 +117,8 @@ public class ConversationItemFooter extends LinearLayout { long id = messageRecord.getId(); boolean mms = messageRecord.isMms(); - if (mms) DatabaseFactory.getMmsDatabase(getContext()).markExpireStarted(id); - else DatabaseFactory.getSmsDatabase(getContext()).markExpireStarted(id); + if (mms) DatabaseComponent.get(getContext()).mmsDatabase().markExpireStarted(id); + else DatabaseComponent.get(getContext()).smsDatabase().markExpireStarted(id); expirationManager.scheduleDeletion(id, mms, messageRecord.getExpiresIn()); return null; diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/ProfilePictureView.kt b/app/src/main/java/org/thoughtcrime/securesms/components/ProfilePictureView.kt index eff857f69..59dfd6c96 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/ProfilePictureView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/ProfilePictureView.kt @@ -12,11 +12,9 @@ import kotlinx.android.synthetic.main.view_profile_picture.view.* import network.loki.messenger.R import org.session.libsession.avatars.ProfileContactPhoto import org.session.libsession.messaging.contacts.Contact -import org.session.libsession.messaging.mentions.MentionsManager import org.session.libsession.utilities.Address -import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.recipients.Recipient -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.mms.GlideRequests import org.thoughtcrime.securesms.util.AvatarPlaceholderGenerator @@ -46,14 +44,14 @@ class ProfilePictureView : RelativeLayout { // region Updating fun update(recipient: Recipient, threadID: Long) { fun getUserDisplayName(publicKey: String): String { - val contact = DatabaseFactory.getSessionContactDatabase(context).getContactWithSessionID(publicKey) + val contact = DatabaseComponent.get(context).sessionContactDatabase().getContactWithSessionID(publicKey) return contact?.displayName(Contact.ContactContext.REGULAR) ?: publicKey } fun isOpenGroupWithProfilePicture(recipient: Recipient): Boolean { return recipient.isOpenGroupRecipient && recipient.groupAvatarId != null } if (recipient.isGroupRecipient && !isOpenGroupWithProfilePicture(recipient)) { - val members = DatabaseFactory.getGroupDatabase(context) + val members = DatabaseComponent.get(context).groupDatabase() .getGroupMemberAddresses(recipient.address.toGroupString(), true) .sorted() .take(2) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/QuoteView.java b/app/src/main/java/org/thoughtcrime/securesms/components/QuoteView.java index 5e8c9a99c..a3b54d51e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/QuoteView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/QuoteView.java @@ -13,26 +13,28 @@ import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; + import com.annimon.stream.Stream; import com.bumptech.glide.load.engine.DiskCacheStrategy; import org.session.libsession.messaging.contacts.Contact; import org.session.libsession.messaging.sending_receiving.attachments.Attachment; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.session.libsession.utilities.TextSecurePreferences; +import org.session.libsession.utilities.ThemeUtil; +import org.session.libsession.utilities.Util; +import org.session.libsession.utilities.recipients.Recipient; +import org.session.libsession.utilities.recipients.RecipientModifiedListener; import org.thoughtcrime.securesms.database.SessionContactDatabase; -import org.thoughtcrime.securesms.util.UiModeUtilities; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri; import org.thoughtcrime.securesms.mms.GlideRequests; import org.thoughtcrime.securesms.mms.Slide; import org.thoughtcrime.securesms.mms.SlideDeck; -import org.session.libsession.utilities.recipients.Recipient; -import org.session.libsession.utilities.recipients.RecipientModifiedListener; -import org.session.libsession.utilities.TextSecurePreferences; -import org.session.libsession.utilities.ThemeUtil; -import org.session.libsession.utilities.Util; +import org.thoughtcrime.securesms.util.UiModeUtilities; import java.util.List; @@ -200,7 +202,7 @@ public class QuoteView extends FrameLayout implements RecipientModifiedListener if (senderHexEncodedPublicKey.equalsIgnoreCase(TextSecurePreferences.getLocalNumber(getContext()))) { quoteeDisplayName = TextSecurePreferences.getProfileName(getContext()); } else { - SessionContactDatabase contactDB = DatabaseFactory.getSessionContactDatabase(getContext()); + SessionContactDatabase contactDB = DatabaseComponent.get(getContext()).sessionContactDatabase(); Contact contact = contactDB.getContactWithSessionID(senderHexEncodedPublicKey); if (contact != null) { Contact.ContactContext context = (this.conversationRecipient.isOpenGroupRecipient()) ? Contact.ContactContext.OPEN_GROUP : Contact.ContactContext.REGULAR; diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/TypingStatusSender.java b/app/src/main/java/org/thoughtcrime/securesms/components/TypingStatusSender.java index b1ef0f9f7..c5f815a1e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/TypingStatusSender.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/TypingStatusSender.java @@ -2,15 +2,16 @@ package org.thoughtcrime.securesms.components; import android.annotation.SuppressLint; import android.content.Context; + import androidx.annotation.NonNull; import org.session.libsession.messaging.messages.control.TypingIndicator; import org.session.libsession.messaging.sending_receiving.MessageSender; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.ThreadDatabase; -import org.thoughtcrime.securesms.util.SessionMetaProtocol; -import org.session.libsession.utilities.recipients.Recipient; import org.session.libsession.utilities.Util; +import org.session.libsession.utilities.recipients.Recipient; +import org.thoughtcrime.securesms.database.ThreadDatabase; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; +import org.thoughtcrime.securesms.util.SessionMetaProtocol; import java.util.HashMap; import java.util.Map; @@ -76,7 +77,7 @@ public class TypingStatusSender { } private void sendTyping(long threadId, boolean typingStarted) { - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); + ThreadDatabase threadDatabase = DatabaseComponent.get(context).threadDatabase(); Recipient recipient = threadDatabase.getRecipientForThreadId(threadId); if (recipient == null) { return; } if (!SessionMetaProtocol.shouldSendTypingIndicator(recipient.getAddress())) { return; } 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 9b67bbfc4..ecd94cff4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactAccessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactAccessor.java @@ -21,17 +21,16 @@ import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.session.libsession.utilities.GroupRecord; +import org.session.libsession.utilities.TextSecurePreferences; import org.thoughtcrime.securesms.database.GroupDatabase; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import java.util.LinkedList; import java.util.List; import network.loki.messenger.R; -import org.session.libsession.utilities.GroupRecord; -import org.session.libsession.utilities.TextSecurePreferences; - /** * This class was originally a layer of indirection between * ContactAccessorNewApi and ContactAccesorOldApi, which corresponded @@ -71,7 +70,7 @@ public class ContactAccessor { GroupRecord record; try { - reader = DatabaseFactory.getGroupDatabase(context).getGroupsFilteredByTitle(constraint); + reader = DatabaseComponent.get(context).groupDatabase().getGroupsFilteredByTitle(constraint); while ((record = reader.getNext()) != null) { numberList.add(record.getEncodedId()); 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 ed38683eb..e1ea0c5e2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactsCursorLoader.java +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactsCursorLoader.java @@ -21,22 +21,22 @@ import android.database.Cursor; import android.database.MatrixCursor; import android.database.MergeCursor; import android.provider.ContactsContract; -import androidx.annotation.NonNull; -import androidx.loader.content.CursorLoader; import android.text.TextUtils; -import network.loki.messenger.R; +import androidx.annotation.NonNull; +import androidx.loader.content.CursorLoader; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.session.libsession.utilities.GroupRecord; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.database.model.ThreadRecord; - -import org.session.libsession.utilities.GroupRecord; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import java.util.ArrayList; import java.util.List; +import network.loki.messenger.R; + /** * CursorLoader that initializes a ContactsDatabase instance * @@ -169,7 +169,7 @@ public class ContactsCursorLoader extends CursorLoader { private Cursor getRecentConversationsCursor() { - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(getContext()); + ThreadDatabase threadDatabase = DatabaseComponent.get(getContext()).threadDatabase(); MatrixCursor recentConversations = new MatrixCursor(CONTACT_PROJECTION, RECENT_CONVERSATION_MAX); try (Cursor rawConversations = threadDatabase.getRecentConversationList(RECENT_CONVERSATION_MAX)) { @@ -208,7 +208,7 @@ public class ContactsCursorLoader extends CursorLoader { private Cursor getGroupsCursor() { MatrixCursor groupContacts = new MatrixCursor(CONTACT_PROJECTION); - try (GroupDatabase.Reader reader = DatabaseFactory.getGroupDatabase(getContext()).getGroupsFilteredByTitle(filter)) { + try (GroupDatabase.Reader reader = DatabaseComponent.get(getContext()).groupDatabase().getGroupsFilteredByTitle(filter)) { GroupRecord groupRecord; while ((groupRecord = reader.getNext()) != null) { groupContacts.addRow(new Object[] { groupRecord.getTitle(), diff --git a/app/src/main/java/org/thoughtcrime/securesms/contacts/UserView.kt b/app/src/main/java/org/thoughtcrime/securesms/contacts/UserView.kt index d2101973e..ebd8c93c6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contacts/UserView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/UserView.kt @@ -9,10 +9,10 @@ import kotlinx.android.synthetic.main.view_conversation.view.profilePictureView import kotlinx.android.synthetic.main.view_user.view.* import network.loki.messenger.R import org.session.libsession.messaging.contacts.Contact -import org.thoughtcrime.securesms.database.DatabaseFactory -import org.thoughtcrime.securesms.conversation.v2.utilities.MentionManagerUtilities -import org.thoughtcrime.securesms.mms.GlideRequests import org.session.libsession.utilities.recipients.Recipient +import org.thoughtcrime.securesms.conversation.v2.utilities.MentionManagerUtilities +import org.thoughtcrime.securesms.dependencies.DatabaseComponent +import org.thoughtcrime.securesms.mms.GlideRequests class UserView : LinearLayout { var openGroupThreadID: Long = -1 // FIXME: This is a bit ugly @@ -50,10 +50,10 @@ class UserView : LinearLayout { // region Updating fun bind(user: Recipient, glide: GlideRequests, actionIndicator: ActionIndicator, isSelected: Boolean = false) { fun getUserDisplayName(publicKey: String): String { - val contact = DatabaseFactory.getSessionContactDatabase(context).getContactWithSessionID(publicKey) + val contact = DatabaseComponent.get(context).sessionContactDatabase().getContactWithSessionID(publicKey) return contact?.displayName(Contact.ContactContext.REGULAR) ?: publicKey } - val threadID = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(user) + val threadID = DatabaseComponent.get(context).threadDatabase().getOrCreateThreadIdFor(user) MentionManagerUtilities.populateUserPublicKeyCacheIfNeeded(threadID, context) // FIXME: This is a bad place to do this val address = user.address.serialize() profilePictureView.glide = glide diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt index b536e36ea..bfcf6bbab 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt @@ -30,6 +30,7 @@ import androidx.loader.content.Loader import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.annimon.stream.Stream +import dagger.hilt.android.AndroidEntryPoint import kotlinx.android.synthetic.main.activity_conversation_v2.* import kotlinx.android.synthetic.main.activity_conversation_v2.view.* import kotlinx.android.synthetic.main.activity_conversation_v2_action_bar.* @@ -91,8 +92,7 @@ import org.thoughtcrime.securesms.conversation.v2.search.SearchViewModel import org.thoughtcrime.securesms.conversation.v2.utilities.* import org.thoughtcrime.securesms.crypto.IdentityKeyUtil import org.thoughtcrime.securesms.crypto.MnemonicUtilities -import org.thoughtcrime.securesms.database.DatabaseFactory -import org.thoughtcrime.securesms.database.DraftDatabase +import org.thoughtcrime.securesms.database.* import org.thoughtcrime.securesms.database.DraftDatabase.Drafts import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.database.model.MmsMessageRecord @@ -109,6 +109,7 @@ import org.thoughtcrime.securesms.permissions.Permissions import org.thoughtcrime.securesms.util.* import java.util.* import java.util.concurrent.ExecutionException +import javax.inject.Inject import kotlin.collections.component1 import kotlin.collections.component2 import kotlin.collections.set @@ -117,11 +118,26 @@ import kotlin.math.* // Some things that seemingly belong to the input bar (e.g. the voice message recording UI) are actually // part of the conversation activity layout. This is just because it makes the layout a lot simpler. The // price we pay is a bit of back and forth between the input bar and the conversation activity. - +@AndroidEntryPoint class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDelegate, InputBarRecordingViewDelegate, AttachmentManager.AttachmentListener, ActivityDispatcher, ConversationActionModeCallbackDelegate, VisibleMessageContentViewDelegate, RecipientModifiedListener, SearchBottomBar.EventListener, VoiceMessageViewDelegate { + + @Inject lateinit var threadDb: ThreadDatabase + @Inject lateinit var mmsSmsDb: MmsSmsDatabase + @Inject lateinit var draftDb: DraftDatabase + @Inject lateinit var lokiThreadDb: LokiThreadDatabase + @Inject lateinit var sessionContactDb: SessionContactDatabase + @Inject lateinit var groupDb: GroupDatabase + @Inject lateinit var lokiApiDb: LokiAPIDatabase + @Inject lateinit var recipientDb: RecipientDatabase + @Inject lateinit var smsDb: SmsDatabase + @Inject lateinit var mmsDb: MmsDatabase + @Inject lateinit var lokiMessageDb: LokiMessageDatabase + + + private val screenWidth = Resources.getSystem().displayMetrics.widthPixels private var linkPreviewViewModel: LinkPreviewViewModel? = null private var threadID: Long = -1 @@ -165,7 +181,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe } private val adapter by lazy { - val cursor = DatabaseFactory.getMmsSmsDatabase(this).getConversation(threadID) + val cursor = mmsSmsDb.getConversation(threadID) val adapter = ConversationAdapter( this, cursor, @@ -185,7 +201,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe } private val thread by lazy { - DatabaseFactory.getThreadDatabase(this).getRecipientForThreadId(threadID)!! + threadDb.getRecipientForThreadId(threadID)!! } private val glide by lazy { GlideApp.with(this) } @@ -216,14 +232,13 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe override fun onCreate(savedInstanceState: Bundle?, isReady: Boolean) { super.onCreate(savedInstanceState, isReady) setContentView(R.layout.activity_conversation_v2) - var threadID = intent.getLongExtra(THREAD_ID, -1L) + threadID = intent.getLongExtra(THREAD_ID, -1L) if (threadID == -1L) { val address = intent.getParcelableExtra

(ADDRESS) ?: return finish() val recipient = Recipient.from(this, address, false) - threadID = DatabaseFactory.getThreadDatabase(this).getOrCreateThreadIdFor(recipient) + threadID = threadDb.getOrCreateThreadIdFor(recipient) } - this.threadID = threadID - val thread = DatabaseFactory.getThreadDatabase(this).getRecipientForThreadId(threadID) + val thread = threadDb.getRecipientForThreadId(threadID) if (thread == null) { Toast.makeText(this, "This thread has been deleted.", Toast.LENGTH_LONG).show() return finish() @@ -242,7 +257,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe conversationRecyclerView.smoothScrollToPosition(0) } } - unreadCount = DatabaseFactory.getMmsSmsDatabase(this).getUnreadCount(threadID) + unreadCount = mmsSmsDb.getUnreadCount(threadID) updateUnreadCountIndicator() setUpTypingObserver() setUpRecipientObserver() @@ -254,7 +269,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe scrollToFirstUnreadMessageIfNeeded() showOrHideInputIfNeeded() if (this.thread.isOpenGroupRecipient) { - val openGroup = DatabaseFactory.getLokiThreadDatabase(this).getOpenGroupChat(threadID) + val openGroup = lokiThreadDb.getOpenGroupChat(threadID) if (openGroup == null) { Toast.makeText(this, "This thread has been deleted.", Toast.LENGTH_LONG).show() return finish() @@ -384,16 +399,15 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe val dataTextExtra = intent.getCharSequenceExtra(Intent.EXTRA_TEXT) ?: "" inputBar.text = dataTextExtra.toString() } else { - val draftDB = DatabaseFactory.getDraftDatabase(this) - val drafts = draftDB.getDrafts(threadID) - draftDB.clearDrafts(threadID) + val drafts = draftDb.getDrafts(threadID) + draftDb.clearDrafts(threadID) val text = drafts.find { it.type == DraftDatabase.Draft.TEXT }?.value ?: return inputBar.text = text } } private fun addOpenGroupGuidelinesIfNeeded() { - val openGroup = DatabaseFactory.getLokiThreadDatabase(this).getOpenGroupChat(threadID) ?: return + val openGroup = lokiThreadDb.getOpenGroupChat(threadID) ?: return val isOxenHostedOpenGroup = openGroup.room == "session" || openGroup.room == "oxen" || openGroup.room == "lokinet" || openGroup.room == "crypto" if (!isOxenHostedOpenGroup) { return } @@ -427,13 +441,13 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe } private fun getLatestOpenGroupInfoIfNeeded() { - val openGroup = DatabaseFactory.getLokiThreadDatabase(this).getOpenGroupChat(threadID) ?: return + val openGroup = lokiThreadDb.getOpenGroupChat(threadID) ?: return OpenGroupAPIV2.getMemberCount(openGroup.room, openGroup.server).successUi { updateSubtitle() } } private fun setUpBlockedBanner() { if (thread.isGroupRecipient) { return } - val contactDB = DatabaseFactory.getSessionContactDatabase(this) + val contactDB = sessionContactDb val sessionID = thread.address.toString() val contact = contactDB.getContactWithSessionID(sessionID) val name = contact?.displayName(Contact.ContactContext.REGULAR) ?: sessionID @@ -461,7 +475,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe } private fun scrollToFirstUnreadMessageIfNeeded() { - val lastSeenTimestamp = DatabaseFactory.getThreadDatabase(this).getLastSeenAndHasSent(threadID).first() + val lastSeenTimestamp = threadDb.getLastSeenAndHasSent(threadID).first() val lastSeenItemPosition = adapter.findLastSeenItemPosition(lastSeenTimestamp) ?: return if (lastSeenItemPosition <= 3) { return } conversationRecyclerView.scrollToPosition(lastSeenItemPosition) @@ -492,7 +506,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe private fun showOrHideInputIfNeeded() { if (thread.isClosedGroupRecipient) { - val group = DatabaseFactory.getGroupDatabase(this).getGroup(thread.address.toGroupString()).orNull() + val group = groupDb.getGroup(thread.address.toGroupString()).orNull() val isActive = (group?.isActive == true) inputBar.showInput = isActive } else { @@ -501,7 +515,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe } private fun markAllAsRead() { - val messages = DatabaseFactory.getThreadDatabase(this).setRead(threadID, true) + val messages = threadDb.setRead(threadID, true) if (thread.isGroupRecipient) { for (message in messages) { MarkReadReceiver.scheduleDeletion(this, message.expirationInfo) @@ -733,9 +747,9 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe conversationSubtitleView.text = getString(R.string.ConversationActivity_muted_forever) } } else if (thread.isGroupRecipient) { - val openGroup = DatabaseFactory.getLokiThreadDatabase(this).getOpenGroupChat(threadID) + val openGroup = lokiThreadDb.getOpenGroupChat(threadID) if (openGroup != null) { - val userCount = DatabaseFactory.getLokiAPIDatabase(this).getUserCount(openGroup.room, openGroup.server) ?: 0 + val userCount = lokiApiDb.getUserCount(openGroup.room, openGroup.server) ?: 0 conversationSubtitleView.text = getString(R.string.ConversationActivity_member_count, userCount) } else { conversationSubtitleView.isVisible = false @@ -867,7 +881,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe private fun unblock() { if (!thread.isContactRecipient) { return } - DatabaseFactory.getRecipientDatabase(this).setBlocked(thread, false) + recipientDb.setBlocked(thread, false) } private fun handleMentionSelected(mention: Mention) { @@ -937,7 +951,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe currentMentionStartIndex = -1 mentions.clear() // Put the message in the database - message.id = DatabaseFactory.getSmsDatabase(this).insertMessageOutbox(threadID, outgoingTextMessage, false, message.sentTimestamp!!) { } + message.id = smsDb.insertMessageOutbox(threadID, outgoingTextMessage, false, message.sentTimestamp!!) { } // Send it MessageSender.send(message, thread.address) // Send a typing stopped message @@ -968,7 +982,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe // Reset attachments button if needed if (isShowingAttachmentOptions) { toggleAttachmentOptions() } // Put the message in the database - message.id = DatabaseFactory.getMmsDatabase(this).insertMessageOutbox(outgoingTextMessage, threadID, false) { } + message.id = mmsDb.insertMessageOutbox(outgoingTextMessage, threadID, false) { } // Send it MessageSender.send(message, thread.address, attachments, quote, linkPreview) // Send a typing stopped message @@ -1070,7 +1084,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe val extras = intent?.extras ?: return if (!intent.hasExtra(SelectContactsActivity.selectedContactsKey)) { return } val selectedContacts = extras.getStringArray(selectedContactsKey)!! - val openGroup = DatabaseFactory.getLokiThreadDatabase(this).getOpenGroupChat(threadID) + val openGroup = lokiThreadDb.getOpenGroupChat(threadID) for (contact in selectedContacts) { val recipient = Recipient.from(this, fromSerialized(contact), true) val message = VisibleMessage() @@ -1080,7 +1094,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe openGroupInvitation.url = openGroup!!.joinURL message.openGroupInvitation = openGroupInvitation val outgoingTextMessage = OutgoingTextMessage.fromOpenGroupInvitation(openGroupInvitation, recipient, message.sentTimestamp) - DatabaseFactory.getSmsDatabase(this).insertMessageOutbox(-1, outgoingTextMessage, message.sentTimestamp!!) + smsDb.insertMessageOutbox(-1, outgoingTextMessage, message.sentTimestamp!!) MessageSender.send(message, recipient.address) } } @@ -1166,10 +1180,9 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe MessageSender.send(unsendRequest, thread.address) } val messageDataProvider = MessagingModuleConfiguration.shared.messageDataProvider - val messageDB = DatabaseFactory.getLokiMessageDatabase(this@ConversationActivityV2) - val openGroup = DatabaseFactory.getLokiThreadDatabase(this).getOpenGroupChat(threadID) + val openGroup = lokiThreadDb.getOpenGroupChat(threadID) if (openGroup != null) { - messageDB.getServerID(message.id, !message.isMms)?.let { messageServerID -> + lokiMessageDb.getServerID(message.id, !message.isMms)?.let { messageServerID -> OpenGroupAPIV2.deleteMessage(messageServerID, openGroup.room, openGroup.server) .success { messageDataProvider.deleteMessage(message.id, !message.isMms) @@ -1194,17 +1207,16 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe fun deleteMessagesWithoutUnsendRequest(messages: Set) { val messageCount = messages.size val messageDataProvider = MessagingModuleConfiguration.shared.messageDataProvider - val messageDB = DatabaseFactory.getLokiMessageDatabase(this@ConversationActivityV2) val builder = AlertDialog.Builder(this) builder.setTitle(resources.getQuantityString(R.plurals.ConversationFragment_delete_selected_messages, messageCount, messageCount)) builder.setMessage(resources.getQuantityString(R.plurals.ConversationFragment_this_will_permanently_delete_all_n_selected_messages, messageCount, messageCount)) builder.setCancelable(true) - val openGroup = DatabaseFactory.getLokiThreadDatabase(this).getOpenGroupChat(threadID) + val openGroup = lokiThreadDb.getOpenGroupChat(threadID) builder.setPositiveButton(R.string.delete) { _, _ -> if (openGroup != null) { val messageServerIDs = mutableMapOf() for (message in messages) { - val messageServerID = messageDB.getServerID(message.id, !message.isMms) ?: continue + val messageServerID = lokiMessageDb.getServerID(message.id, !message.isMms) ?: continue messageServerIDs[messageServerID] = message } for ((messageServerID, message) in messageServerIDs) { @@ -1218,9 +1230,9 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe } else { for (message in messages) { if (message.isMms) { - DatabaseFactory.getMmsDatabase(this@ConversationActivityV2).deleteMessage(message.id) + mmsDb.deleteMessage(message.id) } else { - DatabaseFactory.getSmsDatabase(this@ConversationActivityV2).deleteMessage(message.id) + smsDb.deleteMessage(message.id) } } } @@ -1239,7 +1251,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe return } val allSentByCurrentUser = messages.all { it.isOutgoing } - val allHasHash = messages.all { DatabaseFactory.getLokiMessageDatabase(this@ConversationActivityV2).getMessageServerHash(it.id) != null } + val allHasHash = messages.all { lokiMessageDb.getMessageServerHash(it.id) != null } if (thread.isOpenGroupRecipient) { val messageCount = messages.size val builder = AlertDialog.Builder(this) @@ -1305,7 +1317,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe builder.setTitle(R.string.ConversationFragment_ban_selected_user) builder.setMessage("This will ban the selected user from this room. It won't ban them from other rooms.") builder.setCancelable(true) - val openGroup = DatabaseFactory.getLokiThreadDatabase(this).getOpenGroupChat(threadID)!! + val openGroup = lokiThreadDb.getOpenGroupChat(threadID)!! builder.setPositiveButton(R.string.ban) { _, _ -> OpenGroupAPIV2.ban(sessionID, openGroup.room, openGroup.server).successUi { Toast.makeText(this@ConversationActivityV2, "Successfully banned user", Toast.LENGTH_LONG).show() @@ -1327,7 +1339,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe builder.setTitle(R.string.ConversationFragment_ban_selected_user) builder.setMessage("This will ban the selected user from this room and delete all messages sent by them. It won't ban them from other rooms or delete the messages they sent there.") builder.setCancelable(true) - val openGroup = DatabaseFactory.getLokiThreadDatabase(this).getOpenGroupChat(threadID)!! + val openGroup = lokiThreadDb.getOpenGroupChat(threadID)!! builder.setPositiveButton(R.string.ban) { _, _ -> OpenGroupAPIV2.banAndDeleteAll(sessionID, openGroup.room, openGroup.server).successUi { Toast.makeText(this@ConversationActivityV2, "Successfully banned user and deleted all their messages", Toast.LENGTH_LONG).show() @@ -1468,8 +1480,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe if (text.isEmpty()) { return } val drafts = Drafts() drafts.add(DraftDatabase.Draft(DraftDatabase.Draft.TEXT, text)) - val draftDB = DatabaseFactory.getDraftDatabase(this) - draftDB.insertDrafts(threadID, drafts) + draftDb.insertDrafts(threadID, drafts) } // endregion @@ -1502,7 +1513,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe private fun jumpToMessage(author: Address, timestamp: Long, onMessageNotFound: Runnable?) { SimpleTask.run(lifecycle, { - DatabaseFactory.getMmsSmsDatabase(this).getMessagePositionInConversation(threadID, timestamp, author) + mmsSmsDb.getMessagePositionInConversation(threadID, timestamp, author) }) { p: Int -> moveToMessagePosition(p, onMessageNotFound) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapter.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapter.kt index 59e9f4d6f..29f06e51e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapter.kt @@ -11,15 +11,15 @@ import org.thoughtcrime.securesms.conversation.v2.messages.ControlMessageView import org.thoughtcrime.securesms.conversation.v2.messages.VisibleMessageContentViewDelegate import org.thoughtcrime.securesms.conversation.v2.messages.VisibleMessageView import org.thoughtcrime.securesms.database.CursorRecyclerViewAdapter -import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.model.MessageRecord +import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.mms.GlideRequests class ConversationAdapter(context: Context, cursor: Cursor, private val onItemPress: (MessageRecord, Int, VisibleMessageView, MotionEvent) -> Unit, private val onItemSwipeToReply: (MessageRecord, Int) -> Unit, private val onItemLongPress: (MessageRecord, Int) -> Unit, private val glide: GlideRequests) : CursorRecyclerViewAdapter(context, cursor) { - private val messageDB = DatabaseFactory.getMmsSmsDatabase(context) + private val messageDB = DatabaseComponent.get(context).mmsSmsDatabase() var selectedItems = mutableSetOf() private var searchQuery: String? = null var visibleMessageContentViewDelegate: VisibleMessageContentViewDelegate? = null diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationLoader.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationLoader.kt index 08b5a0264..a78b9b3a8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationLoader.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationLoader.kt @@ -2,12 +2,12 @@ package org.thoughtcrime.securesms.conversation.v2 import android.content.Context import android.database.Cursor -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.util.AbstractCursorLoader class ConversationLoader(private val threadID: Long, context: Context) : AbstractCursorLoader(context) { override fun getCursor(): Cursor { - return DatabaseFactory.getMmsSmsDatabase(context).getConversation(threadID) + return DatabaseComponent.get(context).mmsSmsDatabase().getConversation(threadID) } } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/MessageDetailActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/MessageDetailActivity.kt index 8c870d7b0..7899a2e47 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/MessageDetailActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/MessageDetailActivity.kt @@ -2,31 +2,18 @@ package org.thoughtcrime.securesms.conversation.v2 import android.os.Bundle import android.view.View -import android.widget.LinearLayout -import androidx.annotation.DimenRes -import kotlinx.android.synthetic.main.activity_conversation_v2_action_bar.* import kotlinx.android.synthetic.main.activity_message_detail.* import network.loki.messenger.R -import org.session.libsession.messaging.MessagingModuleConfiguration -import org.session.libsession.messaging.messages.visible.LinkPreview -import org.session.libsession.messaging.messages.visible.OpenGroupInvitation -import org.session.libsession.messaging.messages.visible.Quote -import org.session.libsession.messaging.messages.visible.VisibleMessage -import org.session.libsession.messaging.sending_receiving.MessageSender -import org.session.libsession.messaging.utilities.UpdateMessageData import org.session.libsession.utilities.Address import org.session.libsession.utilities.ExpirationUtil import org.session.libsession.utilities.TextSecurePreferences -import org.session.libsession.utilities.recipients.Recipient import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.conversation.v2.utilities.ResendMessageUtilities -import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.model.MessageRecord -import org.thoughtcrime.securesms.database.model.MmsMessageRecord +import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.util.DateUtils import java.text.SimpleDateFormat import java.util.* -import kotlin.math.roundToInt class MessageDetailActivity: PassphraseRequiredActionBarActivity() { @@ -48,7 +35,7 @@ class MessageDetailActivity: PassphraseRequiredActionBarActivity() { // We only show this screen for messages fail to send, // so the author of the messages must be the current user. val author = Address.fromSerialized(TextSecurePreferences.getLocalNumber(this)!!) - messageRecord = DatabaseFactory.getMmsSmsDatabase (this).getMessageFor(timestamp, author) + messageRecord = DatabaseComponent.get(this).mmsSmsDatabase().getMessageFor(timestamp, author) updateContent() resend_button.setOnClickListener { ResendMessageUtilities.resend(messageRecord!!) @@ -61,7 +48,7 @@ class MessageDetailActivity: PassphraseRequiredActionBarActivity() { val dateFormatter: SimpleDateFormat = DateUtils.getDetailedDateFormatter(this, dateLocale) sent_time.text = dateFormatter.format(Date(messageRecord!!.dateSent)) - val errorMessage = DatabaseFactory.getLokiMessageDatabase(this).getErrorMessage(messageRecord!!.getId()) ?: "Message failed to send." + val errorMessage = DatabaseComponent.get(this).lokiMessageDatabase().getErrorMessage(messageRecord!!.getId()) ?: "Message failed to send." error_message.text = errorMessage if (messageRecord!!.getExpiresIn() <= 0 || messageRecord!!.getExpireStarted() <= 0) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/components/MentionCandidateSelectionView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/components/MentionCandidateSelectionView.kt index 5f16b2317..ee1e40846 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/components/MentionCandidateSelectionView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/components/MentionCandidateSelectionView.kt @@ -7,10 +7,10 @@ import android.view.View import android.view.ViewGroup import android.widget.BaseAdapter import android.widget.ListView -import org.thoughtcrime.securesms.database.DatabaseFactory -import org.thoughtcrime.securesms.util.toPx -import org.thoughtcrime.securesms.mms.GlideRequests import org.session.libsession.messaging.mentions.Mention +import org.thoughtcrime.securesms.dependencies.DatabaseComponent +import org.thoughtcrime.securesms.mms.GlideRequests +import org.thoughtcrime.securesms.util.toPx class MentionCandidateSelectionView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : ListView(context, attrs, defStyleAttr) { private var mentionCandidates = listOf() @@ -68,7 +68,7 @@ class MentionCandidateSelectionView(context: Context, attrs: AttributeSet?, defS } fun show(mentionCandidates: List, threadID: Long) { - val openGroup = DatabaseFactory.getLokiThreadDatabase(context).getOpenGroupChat(threadID) + val openGroup = DatabaseComponent.get(context).lokiThreadDatabase().getOpenGroupChat(threadID) if (openGroup != null) { openGroupServer = openGroup.server openGroupRoom = openGroup.room diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/BlockedDialog.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/BlockedDialog.kt index 3013ab890..fb4501c13 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/BlockedDialog.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/BlockedDialog.kt @@ -7,19 +7,18 @@ import android.text.style.StyleSpan import android.view.LayoutInflater import androidx.appcompat.app.AlertDialog import kotlinx.android.synthetic.main.dialog_blocked.view.* -import kotlinx.android.synthetic.main.dialog_blocked.view.cancelButton import network.loki.messenger.R import org.session.libsession.messaging.contacts.Contact import org.session.libsession.utilities.recipients.Recipient import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.dependencies.DatabaseComponent /** Shown upon sending a message to a user that's blocked. */ class BlockedDialog(private val recipient: Recipient) : BaseDialog() { override fun setContentView(builder: AlertDialog.Builder) { val contentView = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_blocked, null) - val contactDB = DatabaseFactory.getSessionContactDatabase(requireContext()) + val contactDB = DatabaseComponent.get(requireContext()).sessionContactDatabase() val sessionID = recipient.address.toString() val contact = contactDB.getContactWithSessionID(sessionID) val name = contact?.displayName(Contact.ContactContext.REGULAR) ?: sessionID @@ -36,7 +35,7 @@ class BlockedDialog(private val recipient: Recipient) : BaseDialog() { } private fun unblock() { - DatabaseFactory.getRecipientDatabase(requireContext()).setBlocked(recipient, false) + DatabaseComponent.get(requireContext()).recipientDatabase().setBlocked(recipient, false) dismiss() } } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/DownloadDialog.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/DownloadDialog.kt index db95e49dd..72033be87 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/DownloadDialog.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/DownloadDialog.kt @@ -6,6 +6,7 @@ import android.text.SpannableStringBuilder import android.text.style.StyleSpan import android.view.LayoutInflater import androidx.appcompat.app.AlertDialog +import dagger.hilt.android.AndroidEntryPoint import kotlinx.android.synthetic.main.dialog_download.view.* import network.loki.messenger.R import org.session.libsession.messaging.contacts.Contact @@ -13,15 +14,19 @@ import org.session.libsession.messaging.jobs.AttachmentDownloadJob import org.session.libsession.messaging.jobs.JobQueue import org.session.libsession.utilities.recipients.Recipient import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.database.SessionContactDatabase +import org.thoughtcrime.securesms.dependencies.DatabaseComponent +import javax.inject.Inject /** Shown when receiving media from a contact for the first time, to confirm that * they are to be trusted and files sent by them are to be downloaded. */ +@AndroidEntryPoint class DownloadDialog(private val recipient: Recipient) : BaseDialog() { + @Inject lateinit var contactDB: SessionContactDatabase + override fun setContentView(builder: AlertDialog.Builder) { val contentView = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_download, null) - val contactDB = DatabaseFactory.getSessionContactDatabase(requireContext()) val sessionID = recipient.address.toString() val contact = contactDB.getContactWithSessionID(sessionID) val name = contact?.displayName(Contact.ContactContext.REGULAR) ?: sessionID @@ -38,10 +43,9 @@ class DownloadDialog(private val recipient: Recipient) : BaseDialog() { } private fun trust() { - val contactDB = DatabaseFactory.getSessionContactDatabase(requireContext()) val sessionID = recipient.address.toString() val contact = contactDB.getContactWithSessionID(sessionID) ?: return - val threadID = DatabaseFactory.getThreadDatabase(requireContext()).getThreadIdIfExistsFor(recipient) + val threadID = DatabaseComponent.get(requireContext()).threadDatabase().getThreadIdIfExistsFor(recipient) contactDB.setContactIsTrusted(contact, true, threadID) JobQueue.shared.resumePendingJobs(AttachmentDownloadJob.KEY) dismiss() diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/input_bar/mentions/MentionCandidatesView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/input_bar/mentions/MentionCandidatesView.kt index 4fcfba74b..6e8f07741 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/input_bar/mentions/MentionCandidatesView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/input_bar/mentions/MentionCandidatesView.kt @@ -7,11 +7,14 @@ import android.view.View import android.view.ViewGroup import android.widget.BaseAdapter import android.widget.ListView -import org.thoughtcrime.securesms.database.DatabaseFactory -import org.thoughtcrime.securesms.util.toPx -import org.thoughtcrime.securesms.mms.GlideRequests +import dagger.hilt.android.AndroidEntryPoint import org.session.libsession.messaging.mentions.Mention +import org.thoughtcrime.securesms.database.LokiThreadDatabase +import org.thoughtcrime.securesms.mms.GlideRequests +import org.thoughtcrime.securesms.util.toPx +import javax.inject.Inject +@AndroidEntryPoint class MentionCandidatesView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : ListView(context, attrs, defStyleAttr) { private var candidates = listOf() set(newValue) { field = newValue; snAdapter.candidates = newValue } @@ -23,6 +26,8 @@ class MentionCandidatesView(context: Context, attrs: AttributeSet?, defStyleAttr set(newValue) { field = newValue; snAdapter.openGroupRoom = openGroupRoom } var onCandidateSelected: ((Mention) -> Unit)? = null + @Inject lateinit var threadDb: LokiThreadDatabase + private val snAdapter by lazy { Adapter(context) } private class Adapter(private val context: Context) : BaseAdapter() { @@ -60,7 +65,7 @@ class MentionCandidatesView(context: Context, attrs: AttributeSet?, defStyleAttr } fun show(candidates: List, threadID: Long) { - val openGroup = DatabaseFactory.getLokiThreadDatabase(context).getOpenGroupChat(threadID) + val openGroup = threadDb.getOpenGroupChat(threadID) if (openGroup != null) { openGroupServer = openGroup.server openGroupRoom = openGroup.room diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationActionModeCallback.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationActionModeCallback.kt index 48772f8ad..d5eb26b47 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationActionModeCallback.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationActionModeCallback.kt @@ -9,9 +9,9 @@ import org.session.libsession.messaging.open_groups.OpenGroupAPIV2 import org.session.libsession.utilities.TextSecurePreferences import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2 import org.thoughtcrime.securesms.conversation.v2.ConversationAdapter -import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord import org.thoughtcrime.securesms.database.model.MessageRecord +import org.thoughtcrime.securesms.dependencies.DatabaseComponent class ConversationActionModeCallback(private val adapter: ConversationAdapter, private val threadID: Long, private val context: Context) : ActionMode.Callback { @@ -31,8 +31,8 @@ class ConversationActionModeCallback(private val adapter: ConversationAdapter, p val hasText = selectedItems.any { it.body.isNotEmpty() } if (selectedItems.isEmpty()) { return } val firstMessage = selectedItems.iterator().next() - val openGroup = DatabaseFactory.getLokiThreadDatabase(context).getOpenGroupChat(threadID) - val thread = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(threadID)!! + val openGroup = DatabaseComponent.get(context).lokiThreadDatabase().getOpenGroupChat(threadID) + val thread = DatabaseComponent.get(context).threadDatabase().getRecipientForThreadId(threadID)!! val userPublicKey = TextSecurePreferences.getLocalNumber(context)!! fun userCanDeleteSelectedItems(): Boolean { val allSentByCurrentUser = selectedItems.all { it.isOutgoing } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt index 395d68bf3..8a33f985c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt @@ -39,7 +39,7 @@ import org.thoughtcrime.securesms.* import org.thoughtcrime.securesms.contacts.SelectContactsActivity import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2 import org.thoughtcrime.securesms.conversation.v2.utilities.NotificationUtils -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.groups.EditClosedGroupActivity import org.thoughtcrime.securesms.groups.EditClosedGroupActivity.Companion.groupIDKey import org.thoughtcrime.securesms.util.BitmapUtil @@ -214,11 +214,11 @@ object ConversationMenuHelper { private fun showExpiringMessagesDialog(context: Context, thread: Recipient) { if (thread.isClosedGroupRecipient) { - val group = DatabaseFactory.getGroupDatabase(context).getGroup(thread.address.toGroupString()).orNull() + val group = DatabaseComponent.get(context).groupDatabase().getGroup(thread.address.toGroupString()).orNull() if (group?.isActive == false) { return } } ExpirationDialog.show(context, thread.expireMessages) { expirationTime: Int -> - DatabaseFactory.getRecipientDatabase(context).setExpireMessages(thread, expirationTime) + DatabaseComponent.get(context).recipientDatabase().setExpireMessages(thread, expirationTime) val message = ExpirationTimerUpdate(expirationTime) message.recipient = thread.address.serialize() message.sentTimestamp = System.currentTimeMillis() @@ -239,7 +239,7 @@ object ConversationMenuHelper { .setMessage(message) .setNegativeButton(android.R.string.cancel, null) .setPositiveButton(R.string.ConversationActivity_unblock) { _, _ -> - DatabaseFactory.getRecipientDatabase(context) + DatabaseComponent.get(context).recipientDatabase() .setBlocked(thread, false) }.show() } @@ -253,7 +253,7 @@ object ConversationMenuHelper { .setMessage(message) .setNegativeButton(android.R.string.cancel, null) .setPositiveButton(R.string.RecipientPreferenceActivity_block) { _, _ -> - DatabaseFactory.getRecipientDatabase(context) + DatabaseComponent.get(context).recipientDatabase() .setBlocked(thread, true) }.show() } @@ -281,7 +281,7 @@ object ConversationMenuHelper { val builder = AlertDialog.Builder(context) builder.setTitle(context.resources.getString(R.string.ConversationActivity_leave_group)) builder.setCancelable(true) - val group = DatabaseFactory.getGroupDatabase(context).getGroup(thread.address.toGroupString()).orNull() + val group = DatabaseComponent.get(context).groupDatabase().getGroup(thread.address.toGroupString()).orNull() val admins = group.admins val sessionID = TextSecurePreferences.getLocalNumber(context) val isCurrentUserAdmin = admins.any { it.toString() == sessionID } @@ -296,7 +296,7 @@ object ConversationMenuHelper { var isClosedGroup: Boolean try { groupPublicKey = doubleDecodeGroupID(thread.address.toString()).toHexString() - isClosedGroup = DatabaseFactory.getLokiAPIDatabase(context).isClosedGroup(groupPublicKey) + isClosedGroup = DatabaseComponent.get(context).lokiAPIDatabase().isClosedGroup(groupPublicKey) } catch (e: IOException) { groupPublicKey = null isClosedGroup = false @@ -323,18 +323,18 @@ object ConversationMenuHelper { } private fun unmute(context: Context, thread: Recipient) { - DatabaseFactory.getRecipientDatabase(context).setMuted(thread, 0) + DatabaseComponent.get(context).recipientDatabase().setMuted(thread, 0) } private fun mute(context: Context, thread: Recipient) { MuteDialog.show(context) { until: Long -> - DatabaseFactory.getRecipientDatabase(context).setMuted(thread, until) + DatabaseComponent.get(context).recipientDatabase().setMuted(thread, until) } } private fun setNotifyType(context: Context, thread: Recipient) { NotificationUtils.showNotifyDialog(context, thread) { notifyType -> - DatabaseFactory.getRecipientDatabase(context).setNotifyType(thread, notifyType) + DatabaseComponent.get(context).recipientDatabase().setNotifyType(thread, notifyType) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/QuoteView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/QuoteView.kt index d873978ca..fee6ec02d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/QuoteView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/QuoteView.kt @@ -10,18 +10,20 @@ import androidx.annotation.ColorInt import androidx.core.content.res.ResourcesCompat import androidx.core.text.toSpannable import androidx.core.view.isVisible +import dagger.hilt.android.AndroidEntryPoint import kotlinx.android.synthetic.main.view_quote.view.* import network.loki.messenger.R import org.session.libsession.messaging.contacts.Contact import org.session.libsession.utilities.recipients.Recipient import org.thoughtcrime.securesms.conversation.v2.utilities.MentionUtilities import org.thoughtcrime.securesms.conversation.v2.utilities.TextUtilities -import org.thoughtcrime.securesms.database.DatabaseFactory -import org.thoughtcrime.securesms.util.* +import org.thoughtcrime.securesms.database.SessionContactDatabase import org.thoughtcrime.securesms.mms.GlideRequests import org.thoughtcrime.securesms.mms.SlideDeck import org.thoughtcrime.securesms.util.MediaUtil import org.thoughtcrime.securesms.util.UiModeUtilities +import org.thoughtcrime.securesms.util.toPx +import javax.inject.Inject import kotlin.math.max import kotlin.math.min import kotlin.math.roundToInt @@ -32,8 +34,11 @@ import kotlin.math.roundToInt // • Quoted images and videos in both private chats and group chats // • Quoted voice messages and documents in both private chats and group chats // • All of the above in both dark mode and light mode - +@AndroidEntryPoint class QuoteView : LinearLayout { + + @Inject lateinit var contactDb: SessionContactDatabase + private lateinit var mode: Mode private val vPadding by lazy { toPx(6, resources) } var delegate: QuoteViewDelegate? = null @@ -107,14 +112,13 @@ class QuoteView : LinearLayout { fun bind(authorPublicKey: String, body: String?, attachments: SlideDeck?, thread: Recipient, isOutgoingMessage: Boolean, maxContentWidth: Int, isOpenGroupInvitation: Boolean, threadID: Long, isOriginalMissing: Boolean, glide: GlideRequests) { - val contactDB = DatabaseFactory.getSessionContactDatabase(context) // Reduce the max body text view line count to 2 if this is a group thread because // we'll be showing the author text view and we don't want the overall quote view height // to get too big. quoteViewBodyTextView.maxLines = if (thread.isGroupRecipient) 2 else 3 // Author if (thread.isGroupRecipient) { - val author = contactDB.getContactWithSessionID(authorPublicKey) + val author = contactDb.getContactWithSessionID(authorPublicKey) val authorDisplayName = author?.displayName(Contact.contextForRecipient(thread)) ?: authorPublicKey quoteViewAuthorTextView.text = authorDisplayName quoteViewAuthorTextView.setTextColor(getTextColor(isOutgoingMessage)) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt index 4579281e1..521a249e0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt @@ -17,6 +17,7 @@ import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat import androidx.core.content.res.ResourcesCompat import androidx.core.view.isVisible +import dagger.hilt.android.AndroidEntryPoint import kotlinx.android.synthetic.main.view_visible_message.view.* import network.loki.messenger.R import org.session.libsession.messaging.contacts.Contact.ContactContext @@ -24,18 +25,27 @@ import org.session.libsession.messaging.open_groups.OpenGroupAPIV2 import org.session.libsession.utilities.ViewUtil import org.session.libsignal.utilities.ThreadUtils import org.thoughtcrime.securesms.ApplicationContext -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.database.* import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.home.UserDetailsBottomSheet import org.thoughtcrime.securesms.mms.GlideRequests import org.thoughtcrime.securesms.util.* import java.util.* +import javax.inject.Inject import kotlin.math.abs import kotlin.math.min import kotlin.math.roundToInt import kotlin.math.sqrt - +@AndroidEntryPoint class VisibleMessageView : LinearLayout { + + @Inject lateinit var threadDb: ThreadDatabase + @Inject lateinit var contactDb: SessionContactDatabase + @Inject lateinit var lokiThreadDb: LokiThreadDatabase + @Inject lateinit var mmsSmsDb: MmsSmsDatabase + @Inject lateinit var smsDb: SmsDatabase + @Inject lateinit var mmsDb: MmsDatabase + private val screenWidth = Resources.getSystem().displayMetrics.widthPixels private val swipeToReplyIcon = ContextCompat.getDrawable(context, R.drawable.ic_baseline_reply_24)!!.mutate() private val swipeToReplyIconRect = Rect() @@ -82,10 +92,8 @@ class VisibleMessageView : LinearLayout { val sender = message.individualRecipient val senderSessionID = sender.address.serialize() val threadID = message.threadId - val threadDB = DatabaseFactory.getThreadDatabase(context) - val thread = threadDB.getRecipientForThreadId(threadID) ?: return - val contactDB = DatabaseFactory.getSessionContactDatabase(context) - val contact = contactDB.getContactWithSessionID(senderSessionID) + val thread = threadDb.getRecipientForThreadId(threadID) ?: return + val contact = contactDb.getContactWithSessionID(senderSessionID) val isGroupThread = thread.isGroupRecipient val isStartOfMessageCluster = isStartOfMessageCluster(message, previous, isGroupThread) val isEndOfMessageCluster = isEndOfMessageCluster(message, next, isGroupThread) @@ -98,7 +106,7 @@ class VisibleMessageView : LinearLayout { profilePictureView.update(message.individualRecipient, threadID) profilePictureView.setOnClickListener { showUserDetails(message.recipient.address.toString()) } if (thread.isOpenGroupRecipient) { - val openGroup = DatabaseFactory.getLokiThreadDatabase(context).getOpenGroupChat(threadID) ?: return + val openGroup = lokiThreadDb.getOpenGroupChat(threadID) ?: return val isModerator = OpenGroupAPIV2.isUserModerator(senderSessionID, openGroup.room, openGroup.server) moderatorIconImageView.visibility = if (isModerator) View.VISIBLE else View.INVISIBLE } else { @@ -143,7 +151,7 @@ class VisibleMessageView : LinearLayout { messageStatusImageView.setImageDrawable(drawable) } if (message.isOutgoing) { - val lastMessageID = DatabaseFactory.getMmsSmsDatabase(context).getLastMessageID(message.threadId) + val lastMessageID = mmsSmsDb.getLastMessageID(message.threadId) messageStatusImageView.isVisible = !message.isSent || message.id == lastMessageID } else { messageStatusImageView.isVisible = false @@ -225,7 +233,7 @@ class VisibleMessageView : LinearLayout { val expirationManager = ApplicationContext.getInstance(context).expiringMessageManager val id = message.getId() val mms = message.isMms - if (mms) DatabaseFactory.getMmsDatabase(context).markExpireStarted(id) else DatabaseFactory.getSmsDatabase(context).markExpireStarted(id) + if (mms) mmsDb.markExpireStarted(id) else smsDb.markExpireStarted(id) expirationManager.scheduleDeletion(id, mms, message.expiresIn) } } else { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VoiceMessageView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VoiceMessageView.kt index ae96ac2e8..85f0bccc5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VoiceMessageView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VoiceMessageView.kt @@ -3,25 +3,29 @@ package org.thoughtcrime.securesms.conversation.v2.messages import android.content.Context import android.graphics.Canvas import android.util.AttributeSet -import android.util.Log import android.view.LayoutInflater import android.view.View import android.widget.LinearLayout import android.widget.RelativeLayout import androidx.core.view.isVisible +import dagger.hilt.android.AndroidEntryPoint import kotlinx.android.synthetic.main.view_voice_message.view.* import network.loki.messenger.R import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment import org.thoughtcrime.securesms.audio.AudioSlidePlayer import org.thoughtcrime.securesms.components.CornerMask import org.thoughtcrime.securesms.conversation.v2.utilities.MessageBubbleUtilities -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.database.AttachmentDatabase import org.thoughtcrime.securesms.database.model.MmsMessageRecord import java.util.concurrent.TimeUnit +import javax.inject.Inject import kotlin.math.roundToInt import kotlin.math.roundToLong - +@AndroidEntryPoint class VoiceMessageView : LinearLayout, AudioSlidePlayer.Listener { + + @Inject lateinit var attachmentDb: AttachmentDatabase + private val cornerMask by lazy { CornerMask(this) } private var isPlaying = false set(value) { @@ -67,7 +71,7 @@ class VoiceMessageView : LinearLayout, AudioSlidePlayer.Listener { this.player = player (audio.asAttachment() as? DatabaseAttachment)?.let { attachment -> - DatabaseFactory.getAttachmentDatabase(context).getAttachmentAudioExtras(attachment.attachmentId)?.let { audioExtras -> + attachmentDb.getAttachmentAudioExtras(attachment.attachmentId)?.let { audioExtras -> if (audioExtras.durationMs > 0) { duration = audioExtras.durationMs voiceMessageViewDurationTextView.visibility = View.VISIBLE diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/search/SearchViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/search/SearchViewModel.kt index eb3dd50d9..2a7dd099b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/search/SearchViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/search/SearchViewModel.kt @@ -1,21 +1,30 @@ package org.thoughtcrime.securesms.conversation.v2.search -import android.app.Application -import androidx.lifecycle.AndroidViewModel +import android.content.Context import androidx.lifecycle.LiveData +import androidx.lifecycle.ViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import dagger.hilt.android.qualifiers.ApplicationContext import org.session.libsession.utilities.Debouncer import org.session.libsession.utilities.Util.runOnMain import org.session.libsession.utilities.concurrent.SignalExecutors import org.thoughtcrime.securesms.contacts.ContactAccessor import org.thoughtcrime.securesms.database.CursorList -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.database.SearchDatabase +import org.thoughtcrime.securesms.database.ThreadDatabase import org.thoughtcrime.securesms.search.SearchRepository import org.thoughtcrime.securesms.search.model.MessageResult import org.thoughtcrime.securesms.util.CloseableLiveData import java.io.Closeable +import javax.inject.Inject +@HiltViewModel +class SearchViewModel @Inject constructor( + @ApplicationContext context: Context, + searchDb: SearchDatabase, + threadDb: ThreadDatabase +) : ViewModel() { -class SearchViewModel(application: Application) : AndroidViewModel(application) { private val searchRepository: SearchRepository private val result: CloseableLiveData private val debouncer: Debouncer @@ -99,13 +108,12 @@ class SearchViewModel(application: Application) : AndroidViewModel(application) } init { - val context = application.applicationContext result = CloseableLiveData() debouncer = Debouncer(500) searchRepository = SearchRepository(context, - DatabaseFactory.getSearchDatabase(context), - DatabaseFactory.getThreadDatabase(context), - ContactAccessor.getInstance(), - SignalExecutors.SERIAL) + searchDb, + threadDb, + ContactAccessor.getInstance(), + SignalExecutors.SERIAL) } } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/MentionManagerUtilities.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/MentionManagerUtilities.kt index ca1aeeed2..8dc9d2b5d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/MentionManagerUtilities.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/MentionManagerUtilities.kt @@ -1,10 +1,10 @@ package org.thoughtcrime.securesms.conversation.v2.utilities import android.content.Context -import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.messaging.mentions.MentionsManager -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.session.libsession.utilities.TextSecurePreferences import org.thoughtcrime.securesms.database.model.MessageRecord +import org.thoughtcrime.securesms.dependencies.DatabaseComponent object MentionManagerUtilities { @@ -13,12 +13,12 @@ object MentionManagerUtilities { if (MentionsManager.userPublicKeyCache[threadID] != null) return val result = mutableSetOf() - val recipient = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(threadID) ?: return + val recipient = DatabaseComponent.get(context).threadDatabase().getRecipientForThreadId(threadID) ?: return if (recipient.address.isClosedGroup) { - val members = DatabaseFactory.getGroupDatabase(context).getGroupMembers(recipient.address.toGroupString(), false).map { it.address.serialize() } + val members = DatabaseComponent.get(context).groupDatabase().getGroupMembers(recipient.address.toGroupString(), false).map { it.address.serialize() } result.addAll(members) } else { - val messageDatabase = DatabaseFactory.getMmsSmsDatabase(context) + val messageDatabase = DatabaseComponent.get(context).mmsSmsDatabase() val reader = messageDatabase.readerFor(messageDatabase.getConversation(threadID, 0, 200)) var record: MessageRecord? = reader.next while (record != null) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/MentionUtilities.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/MentionUtilities.kt index 3a0c6e7c1..7d36bf205 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/MentionUtilities.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/MentionUtilities.kt @@ -11,8 +11,8 @@ import androidx.core.content.res.ResourcesCompat import network.loki.messenger.R import nl.komponents.kovenant.combine.Tuple2 import org.session.libsession.messaging.contacts.Contact -import org.thoughtcrime.securesms.database.DatabaseFactory import org.session.libsession.utilities.TextSecurePreferences +import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.util.UiModeUtilities import java.util.regex.Pattern @@ -26,7 +26,7 @@ object MentionUtilities { @JvmStatic fun highlightMentions(text: CharSequence, isOutgoingMessage: Boolean, threadID: Long, context: Context): SpannableString { @Suppress("NAME_SHADOWING") var text = text - val threadDB = DatabaseFactory.getThreadDatabase(context) + val threadDB = DatabaseComponent.get(context).threadDatabase() val isOpenGroup = threadDB.getRecipientForThreadId(threadID)?.isOpenGroupRecipient ?: false val pattern = Pattern.compile("@[0-9a-fA-F]*") var matcher = pattern.matcher(text) @@ -39,7 +39,7 @@ object MentionUtilities { val userDisplayName: String? = if (publicKey.equals(userPublicKey, ignoreCase = true)) { TextSecurePreferences.getProfileName(context) } else { - val contact = DatabaseFactory.getSessionContactDatabase(context).getContactWithSessionID(publicKey) + val contact = DatabaseComponent.get(context).sessionContactDatabase().getContactWithSessionID(publicKey) @Suppress("NAME_SHADOWING") val context = if (isOpenGroup) Contact.ContactContext.OPEN_GROUP else Contact.ContactContext.REGULAR contact?.displayName(context) } 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 2f85f27d5..09f7b1157 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentDatabase.java @@ -52,6 +52,7 @@ 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.dependencies.DatabaseComponent; import org.thoughtcrime.securesms.mms.MediaStream; import org.thoughtcrime.securesms.mms.MmsException; import org.thoughtcrime.securesms.mms.PartAuthority; @@ -198,7 +199,7 @@ public class AttachmentDatabase extends Database { values.put(TRANSFER_STATE, AttachmentTransferProgress.TRANSFER_PROGRESS_FAILED); database.update(TABLE_NAME, values, PART_ID_WHERE, attachmentId.toStrings()); - notifyConversationListeners(DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(mmsId)); + notifyConversationListeners(DatabaseComponent.get(context).mmsDatabase().getThreadIdForMessage(mmsId)); } public @Nullable DatabaseAttachment getAttachment(@NonNull AttachmentId attachmentId) @@ -370,7 +371,7 @@ public class AttachmentDatabase extends Database { //noinspection ResultOfMethodCallIgnored dataInfo.file.delete(); } else { - notifyConversationListeners(DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(mmsId)); + notifyConversationListeners(DatabaseComponent.get(context).mmsDatabase().getThreadIdForMessage(mmsId)); notifyConversationListListeners(); } @@ -499,7 +500,7 @@ public class AttachmentDatabase extends Database { values.put(TRANSFER_STATE, AttachmentTransferProgress.TRANSFER_PROGRESS_DONE); database.update(TABLE_NAME, values, PART_ID_WHERE, ((DatabaseAttachment)attachment).getAttachmentId().toStrings()); - notifyConversationListeners(DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(messageId)); + notifyConversationListeners(DatabaseComponent.get(context).mmsDatabase().getThreadIdForMessage(messageId)); ((DatabaseAttachment) attachment).setUploaded(true); } @@ -509,7 +510,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(DatabaseComponent.get(context).mmsDatabase().getThreadIdForMessage(messageId)); } @SuppressWarnings("WeakerAccess") @@ -782,7 +783,7 @@ public class AttachmentDatabase extends Database { try { if (cursor != null && cursor.moveToFirst()) { - notifyConversationListeners(DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(cursor.getLong(cursor.getColumnIndexOrThrow(MMS_ID)))); + notifyConversationListeners(DatabaseComponent.get(context).mmsDatabase().getThreadIdForMessage(cursor.getLong(cursor.getColumnIndexOrThrow(MMS_ID)))); } } finally { if (cursor != null) cursor.close(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseFactory.java b/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseFactory.java index a5f9d4f17..74396e2a9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseFactory.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseFactory.java @@ -1,3 +1,4 @@ + /* * Copyright (C) 2018 Open Whisper Systems * @@ -18,296 +19,15 @@ package org.thoughtcrime.securesms.database; import android.content.Context; -import androidx.annotation.NonNull; - import net.sqlcipher.database.SQLiteDatabase; -import org.thoughtcrime.securesms.attachments.DatabaseAttachmentProvider; -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.database.helpers.SQLCipherOpenHelper; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; public class DatabaseFactory { - - private static final Object lock = new Object(); - - private static DatabaseFactory instance; - - private final SQLCipherOpenHelper databaseHelper; - private SmsDatabase sms; - private MmsDatabase mms; - private AttachmentDatabase attachments; - private MediaDatabase media; - private ThreadDatabase thread; - private MmsSmsDatabase mmsSmsDatabase; - private DraftDatabase draftDatabase; - private PushDatabase pushDatabase; - private GroupDatabase groupDatabase; - private RecipientDatabase recipientDatabase; - private GroupReceiptDatabase groupReceiptDatabase; - private SearchDatabase searchDatabase; - private JobDatabase jobDatabase; - private LokiAPIDatabase lokiAPIDatabase; - private LokiMessageDatabase lokiMessageDatabase; - private LokiThreadDatabase lokiThreadDatabase; - private LokiUserDatabase lokiUserDatabase; - private LokiBackupFilesDatabase lokiBackupFilesDatabase; - private SessionJobDatabase sessionJobDatabase; - private SessionContactDatabase sessionContactDatabase; - private Storage storage; - private DatabaseAttachmentProvider attachmentProvider; - - public static DatabaseFactory getInstance(Context context) { - synchronized (lock) { - if (instance == null) - instance = new DatabaseFactory(context.getApplicationContext()); - - return instance; - } - } - - public static MmsSmsDatabase getMmsSmsDatabase(Context context) { - DatabaseFactory factory = getInstance(context); - synchronized (lock) { - if (factory.mmsSmsDatabase == null) { - factory.mmsSmsDatabase = new MmsSmsDatabase(context, factory.databaseHelper); - } - return factory.mmsSmsDatabase; - } - } - - public static ThreadDatabase getThreadDatabase(Context context) { - DatabaseFactory factory = getInstance(context); - synchronized (lock) { - if (factory.thread == null) { - factory.thread = new ThreadDatabase(context, factory.databaseHelper); - } - return factory.thread; - } - } - - public static SmsDatabase getSmsDatabase(Context context) { - DatabaseFactory factory = getInstance(context); - synchronized (lock) { - if (factory.sms == null) { - factory.sms = new SmsDatabase(context, factory.databaseHelper); - } - return factory.sms; - } - } - - public static MmsDatabase getMmsDatabase(Context context) { - DatabaseFactory factory = getInstance(context); - synchronized (lock) { - if (factory.mms == null) { - factory.mms = new MmsDatabase(context, factory.databaseHelper); - } - return factory.mms; - } - } - - public static AttachmentDatabase getAttachmentDatabase(Context context) { - DatabaseFactory factory = getInstance(context); - synchronized (lock) { - if (factory.attachments == null) { - AttachmentSecret attachmentSecret = AttachmentSecretProvider.getInstance(context).getOrCreateAttachmentSecret(); - factory.attachments = new AttachmentDatabase(context, factory.databaseHelper, attachmentSecret); - } - return factory.attachments; - } - } - - public static MediaDatabase getMediaDatabase(Context context) { - DatabaseFactory factory = getInstance(context); - synchronized (lock) { - if (factory.media == null) { - factory.media = new MediaDatabase(context, factory.databaseHelper); - } - return factory.media; - } - } - - public static DraftDatabase getDraftDatabase(Context context) { - DatabaseFactory factory = getInstance(context); - synchronized (lock) { - if (factory.draftDatabase == null) { - factory.draftDatabase = new DraftDatabase(context, factory.databaseHelper); - } - return factory.draftDatabase; - } - } - - public static PushDatabase getPushDatabase(Context context) { - DatabaseFactory factory = getInstance(context); - synchronized (lock) { - if (factory.pushDatabase == null) { - factory.pushDatabase = new PushDatabase(context, factory.databaseHelper); - } - return factory.pushDatabase; - } - } - - public static GroupDatabase getGroupDatabase(Context context) { - DatabaseFactory factory = getInstance(context); - synchronized (lock) { - if (factory.groupDatabase == null) { - factory.groupDatabase = new GroupDatabase(context, factory.databaseHelper); - } - return factory.groupDatabase; - } - } - - public static RecipientDatabase getRecipientDatabase(Context context) { - DatabaseFactory factory = getInstance(context); - synchronized (lock) { - if (factory.recipientDatabase == null) { - factory.recipientDatabase = new RecipientDatabase(context, factory.databaseHelper); - } - return factory.recipientDatabase; - } - } - - public static GroupReceiptDatabase getGroupReceiptDatabase(Context context) { - DatabaseFactory factory = getInstance(context); - synchronized (lock) { - if (factory.groupReceiptDatabase == null) { - factory.groupReceiptDatabase = new GroupReceiptDatabase(context, factory.databaseHelper); - } - return factory.groupReceiptDatabase; - } - } - - public static SearchDatabase getSearchDatabase(Context context) { - DatabaseFactory factory = getInstance(context); - synchronized (lock) { - if (factory.searchDatabase == null) { - factory.searchDatabase = new SearchDatabase(context, factory.databaseHelper); - } - return factory.searchDatabase; - } - } - - public static JobDatabase getJobDatabase(Context context) { - DatabaseFactory factory = getInstance(context); - synchronized (lock) { - if (factory.jobDatabase == null) { - factory.jobDatabase = new JobDatabase(context, factory.databaseHelper); - } - return factory.jobDatabase; - } - } - - public static SQLiteDatabase getBackupDatabase(Context context) { - return getInstance(context).databaseHelper.getReadableDatabase(); - } - - // region Loki - public static LokiAPIDatabase getLokiAPIDatabase(Context context) { - DatabaseFactory factory = getInstance(context); - synchronized (lock) { - if (factory.lokiAPIDatabase == null) { - factory.lokiAPIDatabase = new LokiAPIDatabase(context, factory.databaseHelper); - } - return factory.lokiAPIDatabase; - } - } - - public static LokiMessageDatabase getLokiMessageDatabase(Context context) { - DatabaseFactory factory = getInstance(context); - synchronized (lock) { - if (factory.lokiMessageDatabase == null) { - factory.lokiMessageDatabase = new LokiMessageDatabase(context, factory.databaseHelper); - } - return factory.lokiMessageDatabase; - } - } - - public static LokiThreadDatabase getLokiThreadDatabase(Context context) { - DatabaseFactory factory = getInstance(context); - synchronized (lock) { - if (factory.lokiThreadDatabase == null) { - factory.lokiThreadDatabase = new LokiThreadDatabase(context, factory.databaseHelper); - } - return factory.lokiThreadDatabase; - } - } - - public static LokiUserDatabase getLokiUserDatabase(Context context) { - DatabaseFactory factory = getInstance(context); - synchronized (lock) { - if (factory.lokiUserDatabase == null) { - factory.lokiUserDatabase = new LokiUserDatabase(context, factory.databaseHelper); - } - return factory.lokiUserDatabase; - } - } - - public static LokiBackupFilesDatabase getLokiBackupFilesDatabase(Context context) { - DatabaseFactory factory = getInstance(context); - synchronized (lock) { - if (factory.lokiBackupFilesDatabase == null) { - factory.lokiBackupFilesDatabase = new LokiBackupFilesDatabase(context, factory.databaseHelper); - } - return factory.lokiBackupFilesDatabase; - } - } - - public static SessionJobDatabase getSessionJobDatabase(Context context) { - DatabaseFactory factory = getInstance(context); - synchronized (lock) { - if (factory.sessionJobDatabase == null) { - factory.sessionJobDatabase = new SessionJobDatabase(context, factory.databaseHelper); - } - return factory.sessionJobDatabase; - } - } - - public static SessionContactDatabase getSessionContactDatabase(Context context) { - DatabaseFactory factory = getInstance(context); - synchronized (lock) { - if (factory.sessionContactDatabase == null) { - factory.sessionContactDatabase = new SessionContactDatabase(context, factory.databaseHelper); - } - return factory.sessionContactDatabase; - } - } - // endregion - - // region Refactor - public static Storage getStorage(Context context) { - DatabaseFactory factory = getInstance(context); - synchronized (lock) { - if (factory.storage == null) { - factory.storage = new Storage(context, factory.databaseHelper); - } - return factory.storage; - } - } - - public static DatabaseAttachmentProvider getAttachmentProvider(Context context) { - DatabaseFactory factory = getInstance(context); - synchronized (lock) { - if (factory.attachmentProvider == null) { - factory.attachmentProvider = new DatabaseAttachmentProvider(context, factory.databaseHelper); - } - return factory.attachmentProvider; - } - } - // endregion - public static void upgradeRestored(Context context, SQLiteDatabase database){ - getInstance(context).databaseHelper.onUpgrade(database, database.getVersion(), -1); - getInstance(context).databaseHelper.markCurrent(database); + SQLCipherOpenHelper databaseHelper = DatabaseComponent.get(context).openHelper(); + databaseHelper.onUpgrade(database, database.getVersion(), -1); + databaseHelper.markCurrent(database); } - - private DatabaseFactory(@NonNull Context context) { - SQLiteDatabase.loadLibs(context); - - DatabaseSecret databaseSecret = new DatabaseSecretProvider(context).getOrCreateDatabaseSecret(); - - this.databaseHelper = new SQLCipherOpenHelper(context, databaseSecret); - } - } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/LokiThreadDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/LokiThreadDatabase.kt index 0b45875bd..16c475081 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/LokiThreadDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/LokiThreadDatabase.kt @@ -3,11 +3,12 @@ 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.session.libsession.messaging.open_groups.OpenGroupV2 import org.session.libsession.utilities.Address import org.session.libsession.utilities.recipients.Recipient import org.session.libsignal.utilities.JsonUtil +import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper +import org.thoughtcrime.securesms.dependencies.DatabaseComponent class LokiThreadDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper) { @@ -26,7 +27,7 @@ class LokiThreadDatabase(context: Context, helper: SQLCipherOpenHelper) : Databa fun getThreadID(hexEncodedPublicKey: String): Long { val address = Address.fromSerialized(hexEncodedPublicKey) val recipient = Recipient.from(context, address, false) - return DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient) + return DatabaseComponent.get(context).threadDatabase().getOrCreateThreadIdFor(recipient) } fun getAllV2OpenGroups(): Map { 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 c33f8d0e7..f16d663a1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MediaDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MediaDatabase.java @@ -3,6 +3,7 @@ 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; @@ -10,8 +11,8 @@ import net.sqlcipher.database.SQLiteDatabase; import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment; import org.session.libsession.utilities.Address; - import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import java.util.List; @@ -60,7 +61,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) { + public MediaDatabase(Context context, SQLCipherOpenHelper databaseHelper) { super(context, databaseHelper); } @@ -101,7 +102,7 @@ public class MediaDatabase extends Database { } public static MediaRecord from(@NonNull Context context, @NonNull Cursor cursor) { - AttachmentDatabase attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context); + AttachmentDatabase attachmentDatabase = DatabaseComponent.get(context).attachmentDatabase(); List attachments = attachmentDatabase.getAttachment(cursor); String serializedAddress = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.ADDRESS)); boolean outgoing = MessagingDatabase.Types.isOutgoingMessageType(cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.MESSAGE_BOX))); 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 f56792aa7..31ecbcb99 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java @@ -66,6 +66,7 @@ import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.database.model.MmsMessageRecord; import org.thoughtcrime.securesms.database.model.NotificationMmsMessageRecord; import org.thoughtcrime.securesms.database.model.Quote; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import org.thoughtcrime.securesms.mms.MmsException; import org.thoughtcrime.securesms.mms.SlideDeck; @@ -264,8 +265,8 @@ public class MmsDatabase extends MessagingDatabase { columnName + " = " + columnName + " + 1 WHERE " + ID + " = ?", new String[] {String.valueOf(id)}); - DatabaseFactory.getGroupReceiptDatabase(context).update(ourAddress, id, status, timestamp); - DatabaseFactory.getThreadDatabase(context).update(threadId, false); + DatabaseComponent.get(context).groupReceiptDatabase().update(ourAddress, id, status, timestamp); + DatabaseComponent.get(context).threadDatabase().update(threadId, false); notifyConversationListeners(threadId); } } @@ -312,10 +313,10 @@ public class MmsDatabase extends MessagingDatabase { private long getThreadIdFor(IncomingMediaMessage retrieved) throws RecipientFormattingException, MmsException { if (retrieved.getGroupId() != null) { Recipient groupRecipients = Recipient.from(context, retrieved.getGroupId(), true); - return DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(groupRecipients); + return DatabaseComponent.get(context).threadDatabase().getOrCreateThreadIdFor(groupRecipients); } else { Recipient sender = Recipient.from(context, retrieved.getFrom(), true); - return DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(sender); + return DatabaseComponent.get(context).threadDatabase().getOrCreateThreadIdFor(sender); } } @@ -324,7 +325,7 @@ public class MmsDatabase extends MessagingDatabase { ? Util.toIsoString(notification.getFrom().getTextString()) : ""; Recipient recipient = Recipient.from(context, Address.fromExternal(context, fromString), false); - return DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient); + return DatabaseComponent.get(context).threadDatabase().getOrCreateThreadIdFor(recipient); } private Cursor rawQuery(@NonNull String where, @Nullable String[] arguments) { @@ -353,7 +354,7 @@ public class MmsDatabase extends MessagingDatabase { " WHERE " + ID + " = ?", new String[] {id + ""}); if (threadId.isPresent()) { - DatabaseFactory.getThreadDatabase(context).update(threadId.get(), false); + DatabaseComponent.get(context).threadDatabase().update(threadId.get(), false); } } @@ -399,11 +400,11 @@ public class MmsDatabase extends MessagingDatabase { contentValues.put(BODY, ""); database.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {String.valueOf(messageId)}); - AttachmentDatabase attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context); + AttachmentDatabase attachmentDatabase = DatabaseComponent.get(context).attachmentDatabase(); ThreadUtils.queue(() -> attachmentDatabase.deleteAttachmentsForMessage(messageId)); long threadId = getThreadIdForMessage(messageId); - if (!read) { DatabaseFactory.getThreadDatabase(context).decrementUnread(threadId, 1); } + if (!read) { DatabaseComponent.get(context).threadDatabase().decrementUnread(threadId, 1); } updateMailboxBitmask(messageId, Types.BASE_TYPE_MASK, Types.BASE_DELETED_TYPE, Optional.of(threadId)); notifyConversationListeners(threadId); } @@ -478,7 +479,7 @@ public class MmsDatabase extends MessagingDatabase { public OutgoingMediaMessage getOutgoingMessage(long messageId) throws MmsException, NoSuchMessageException { - AttachmentDatabase attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context); + AttachmentDatabase attachmentDatabase = DatabaseComponent.get(context).attachmentDatabase(); Cursor cursor = null; try { @@ -494,7 +495,7 @@ public class MmsDatabase extends MessagingDatabase { long expiresIn = cursor.getLong(cursor.getColumnIndexOrThrow(EXPIRES_IN)); String address = cursor.getString(cursor.getColumnIndexOrThrow(ADDRESS)); long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(THREAD_ID)); - int distributionType = DatabaseFactory.getThreadDatabase(context).getDistributionType(threadId); + int distributionType = DatabaseComponent.get(context).threadDatabase().getDistributionType(threadId); String mismatchDocument = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.MISMATCHED_IDENTITIES)); String networkDocument = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.NETWORK_FAILURE)); @@ -687,8 +688,8 @@ public class MmsDatabase extends MessagingDatabase { long messageId = insertMediaMessage(retrieved.getBody(), retrieved.getAttachments(), quoteAttachments, retrieved.getSharedContacts(), retrieved.getLinkPreviews(), contentValues, null); if (!Types.isExpirationTimerUpdate(mailbox)) { - DatabaseFactory.getThreadDatabase(context).incrementUnread(threadId, 1); - DatabaseFactory.getThreadDatabase(context).update(threadId, true); + DatabaseComponent.get(context).threadDatabase().incrementUnread(threadId, 1); + DatabaseComponent.get(context).threadDatabase().update(threadId, true); } notifyConversationListeners(threadId); @@ -715,9 +716,9 @@ public class MmsDatabase extends MessagingDatabase { throw new MmsException(e); } Recipient group = Recipient.from(context, Address.fromSerialized(groupId), false); - threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(group); + threadId = DatabaseComponent.get(context).threadDatabase().getOrCreateThreadIdFor(group); } else { - threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(retrieved.getRecipient()); + threadId = DatabaseComponent.get(context).threadDatabase().getOrCreateThreadIdFor(retrieved.getRecipient()); } } long messageId = insertMessageOutbox(retrieved, threadId, false, null, serverTimestamp); @@ -823,8 +824,8 @@ public class MmsDatabase extends MessagingDatabase { long messageId = insertMediaMessage(message.getBody(), message.getAttachments(), quoteAttachments, message.getSharedContacts(), message.getLinkPreviews(), contentValues, insertListener); if (message.getRecipient().getAddress().isGroup()) { - List members = DatabaseFactory.getGroupDatabase(context).getGroupMembers(message.getRecipient().getAddress().toGroupString(), false); - GroupReceiptDatabase receiptDatabase = DatabaseFactory.getGroupReceiptDatabase(context); + List members = DatabaseComponent.get(context).groupDatabase().getGroupMembers(message.getRecipient().getAddress().toGroupString(), false); + GroupReceiptDatabase receiptDatabase = DatabaseComponent.get(context).groupReceiptDatabase(); receiptDatabase.insert(Stream.of(members).map(Recipient::getAddress).toList(), messageId, GroupReceiptDatabase.STATUS_UNDELIVERED, message.getSentTimeMillis()); @@ -833,8 +834,8 @@ public class MmsDatabase extends MessagingDatabase { for (Address address : earlyReadReceipts.keySet()) receiptDatabase.update(address, messageId, GroupReceiptDatabase.STATUS_READ, -1); } - DatabaseFactory.getThreadDatabase(context).setLastSeen(threadId); - DatabaseFactory.getThreadDatabase(context).setHasSent(threadId, true); + DatabaseComponent.get(context).threadDatabase().setLastSeen(threadId); + DatabaseComponent.get(context).threadDatabase().setHasSent(threadId, true); return messageId; } @@ -849,7 +850,7 @@ public class MmsDatabase extends MessagingDatabase { throws MmsException { SQLiteDatabase db = databaseHelper.getWritableDatabase(); - AttachmentDatabase partsDatabase = DatabaseFactory.getAttachmentDatabase(context); + AttachmentDatabase partsDatabase = DatabaseComponent.get(context).attachmentDatabase(); List allAttachments = new LinkedList<>(); List contactAttachments = Stream.of(sharedContacts).map(Contact::getAvatarAttachment).filter(a -> a != null).toList(); @@ -904,7 +905,7 @@ public class MmsDatabase extends MessagingDatabase { } notifyConversationListeners(contentValues.getAsLong(THREAD_ID)); - DatabaseFactory.getThreadDatabase(context).update(contentValues.getAsLong(THREAD_ID), true); + DatabaseComponent.get(context).threadDatabase().update(contentValues.getAsLong(THREAD_ID), true); } } @@ -926,10 +927,10 @@ public class MmsDatabase extends MessagingDatabase { @Override public boolean deleteMessage(long messageId) { long threadId = getThreadIdForMessage(messageId); - AttachmentDatabase attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context); + AttachmentDatabase attachmentDatabase = DatabaseComponent.get(context).attachmentDatabase(); ThreadUtils.queue(() -> attachmentDatabase.deleteAttachmentsForMessage(messageId)); - GroupReceiptDatabase groupReceiptDatabase = DatabaseFactory.getGroupReceiptDatabase(context); + GroupReceiptDatabase groupReceiptDatabase = DatabaseComponent.get(context).groupReceiptDatabase(); groupReceiptDatabase.deleteRowsForMessage(messageId); MessageRecord toDelete; @@ -940,7 +941,7 @@ public class MmsDatabase extends MessagingDatabase { deleteQuotedFromMessages(toDelete); SQLiteDatabase database = databaseHelper.getWritableDatabase(); database.delete(TABLE_NAME, ID_WHERE, new String[] {messageId+""}); - boolean threadDeleted = DatabaseFactory.getThreadDatabase(context).update(threadId, false); + boolean threadDeleted = DatabaseComponent.get(context).threadDatabase().update(threadId, false); notifyConversationListeners(threadId); notifyStickerListeners(); notifyStickerPackListeners(); @@ -1088,8 +1089,8 @@ public class MmsDatabase extends MessagingDatabase { public void deleteAllThreads() { - DatabaseFactory.getAttachmentDatabase(context).deleteAllAttachments(); - DatabaseFactory.getGroupReceiptDatabase(context).deleteAllRows(); + DatabaseComponent.get(context).attachmentDatabase().deleteAllAttachments(); + DatabaseComponent.get(context).groupReceiptDatabase().deleteAllRows(); SQLiteDatabase database = databaseHelper.getWritableDatabase(); database.delete(TABLE_NAME, null, null); @@ -1258,7 +1259,7 @@ public class MmsDatabase extends MessagingDatabase { Recipient recipient = getRecipientFor(address); List mismatches = getMismatchedIdentities(mismatchDocument); List networkFailures = getFailures(networkDocument); - List attachments = DatabaseFactory.getAttachmentDatabase(context).getAttachment(cursor); + List attachments = DatabaseComponent.get(context).attachmentDatabase().getAttachment(cursor); List contacts = getSharedContacts(cursor, attachments); Set contactAttachments = Stream.of(contacts).map(Contact::getAvatarAttachment).filter(a -> a != null).collect(Collectors.toSet()); List previews = getLinkPreviews(cursor, attachments); @@ -1321,7 +1322,7 @@ public class MmsDatabase extends MessagingDatabase { String quoteAuthor = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.QUOTE_AUTHOR)); String quoteText = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.QUOTE_BODY)); boolean quoteMissing = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.QUOTE_MISSING)) == 1; - List attachments = DatabaseFactory.getAttachmentDatabase(context).getAttachment(cursor); + List attachments = DatabaseComponent.get(context).attachmentDatabase().getAttachment(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 86b523164..54d07afe0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java @@ -30,6 +30,7 @@ import org.session.libsession.utilities.Util; import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId; import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.database.model.MessageRecord; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import java.util.HashSet; import java.util.Set; @@ -161,20 +162,20 @@ public class MmsSmsDatabase extends Database { } public int getConversationCount(long threadId) { - int count = DatabaseFactory.getSmsDatabase(context).getMessageCountForThread(threadId); - count += DatabaseFactory.getMmsDatabase(context).getMessageCountForThread(threadId); + int count = DatabaseComponent.get(context).smsDatabase().getMessageCountForThread(threadId); + count += DatabaseComponent.get(context).mmsDatabase().getMessageCountForThread(threadId); return count; } public void incrementDeliveryReceiptCount(SyncMessageId syncMessageId, long timestamp) { - DatabaseFactory.getSmsDatabase(context).incrementReceiptCount(syncMessageId, true, false); - DatabaseFactory.getMmsDatabase(context).incrementReceiptCount(syncMessageId, timestamp, true, false); + DatabaseComponent.get(context).smsDatabase().incrementReceiptCount(syncMessageId, true, false); + DatabaseComponent.get(context).mmsDatabase().incrementReceiptCount(syncMessageId, timestamp, true, false); } public void incrementReadReceiptCount(SyncMessageId syncMessageId, long timestamp) { - DatabaseFactory.getSmsDatabase(context).incrementReceiptCount(syncMessageId, false, true); - DatabaseFactory.getMmsDatabase(context).incrementReceiptCount(syncMessageId, timestamp, false, true); + DatabaseComponent.get(context).smsDatabase().incrementReceiptCount(syncMessageId, false, true); + DatabaseComponent.get(context).mmsDatabase().incrementReceiptCount(syncMessageId, timestamp, false, true); } public int getQuotedMessagePosition(long threadId, long quoteId, @NonNull Address address) { @@ -417,7 +418,7 @@ public class MmsSmsDatabase extends Database { private SmsDatabase.Reader getSmsReader() { if (smsReader == null) { - smsReader = DatabaseFactory.getSmsDatabase(context).readerFor(cursor); + smsReader = DatabaseComponent.get(context).smsDatabase().readerFor(cursor); } return smsReader; @@ -425,7 +426,7 @@ public class MmsSmsDatabase extends Database { private MmsDatabase.Reader getMmsReader() { if (mmsReader == null) { - mmsReader = DatabaseFactory.getMmsDatabase(context).readerFor(cursor); + mmsReader = DatabaseComponent.get(context).mmsDatabase().readerFor(cursor); } return mmsReader; 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 17a836477..558957515 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java @@ -43,6 +43,7 @@ import org.session.libsignal.utilities.guava.Optional; import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.database.model.SmsMessageRecord; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import java.io.IOException; import java.security.SecureRandom; @@ -120,7 +121,7 @@ public class SmsDatabase extends MessagingDatabase { long threadId = getThreadIdForMessage(id); - DatabaseFactory.getThreadDatabase(context).update(threadId, false); + DatabaseComponent.get(context).threadDatabase().update(threadId, false); notifyConversationListeners(threadId); } @@ -191,7 +192,7 @@ public class SmsDatabase extends MessagingDatabase { contentValues.put(BODY, ""); database.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {String.valueOf(messageId)}); long threadId = getThreadIdForMessage(messageId); - if (!read) { DatabaseFactory.getThreadDatabase(context).decrementUnread(threadId, 1); } + if (!read) { DatabaseComponent.get(context).threadDatabase().decrementUnread(threadId, 1); } updateTypeBitmask(messageId, Types.BASE_TYPE_MASK, Types.BASE_DELETED_TYPE); } @@ -210,7 +211,7 @@ public class SmsDatabase extends MessagingDatabase { long threadId = getThreadIdForMessage(id); - DatabaseFactory.getThreadDatabase(context).update(threadId, false); + DatabaseComponent.get(context).threadDatabase().update(threadId, false); notifyConversationListeners(threadId); } @@ -273,7 +274,7 @@ public class SmsDatabase extends MessagingDatabase { ID + " = ?", new String[] {String.valueOf(cursor.getLong(cursor.getColumnIndexOrThrow(ID)))}); - DatabaseFactory.getThreadDatabase(context).update(threadId, false); + DatabaseComponent.get(context).threadDatabase().update(threadId, false); notifyConversationListeners(threadId); foundMessage = true; } @@ -353,7 +354,7 @@ public class SmsDatabase extends MessagingDatabase { long threadId = getThreadIdForMessage(messageId); - DatabaseFactory.getThreadDatabase(context).update(threadId, true); + DatabaseComponent.get(context).threadDatabase().update(threadId, true); notifyConversationListeners(threadId); notifyConversationListListeners(); @@ -387,8 +388,8 @@ public class SmsDatabase extends MessagingDatabase { long threadId; - if (groupRecipient == null) threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient); - else threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(groupRecipient); + if (groupRecipient == null) threadId = DatabaseComponent.get(context).threadDatabase().getOrCreateThreadIdFor(recipient); + else threadId = DatabaseComponent.get(context).threadDatabase().getOrCreateThreadIdFor(groupRecipient); ContentValues values = new ContentValues(6); values.put(ADDRESS, message.getSender().serialize()); @@ -421,13 +422,13 @@ public class SmsDatabase extends MessagingDatabase { long messageId = db.insert(TABLE_NAME, null, values); if (unread) { - DatabaseFactory.getThreadDatabase(context).incrementUnread(threadId, 1); + DatabaseComponent.get(context).threadDatabase().incrementUnread(threadId, 1); } - DatabaseFactory.getThreadDatabase(context).update(threadId, true); + DatabaseComponent.get(context).threadDatabase().update(threadId, true); if (message.getSubscriptionId() != -1) { - DatabaseFactory.getRecipientDatabase(context).setDefaultSubscriptionId(recipient, message.getSubscriptionId()); + DatabaseComponent.get(context).recipientDatabase().setDefaultSubscriptionId(recipient, message.getSubscriptionId()); } notifyConversationListeners(threadId); @@ -446,7 +447,7 @@ public class SmsDatabase extends MessagingDatabase { public Optional insertMessageOutbox(long threadId, OutgoingTextMessage message, long serverTimestamp) { if (threadId == -1) { - threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(message.getRecipient()); + threadId = DatabaseComponent.get(context).threadDatabase().getOrCreateThreadIdFor(message.getRecipient()); } long messageId = insertMessageOutbox(threadId, message, false, serverTimestamp, null); if (messageId == -1) { @@ -493,10 +494,10 @@ public class SmsDatabase extends MessagingDatabase { insertListener.onComplete(); } - DatabaseFactory.getThreadDatabase(context).update(threadId, true); - DatabaseFactory.getThreadDatabase(context).setLastSeen(threadId); + DatabaseComponent.get(context).threadDatabase().update(threadId, true); + DatabaseComponent.get(context).threadDatabase().setLastSeen(threadId); - DatabaseFactory.getThreadDatabase(context).setHasSent(threadId, true); + DatabaseComponent.get(context).threadDatabase().setHasSent(threadId, true); notifyConversationListeners(threadId); @@ -536,12 +537,12 @@ public class SmsDatabase extends MessagingDatabase { long threadId = getThreadIdForMessage(messageId); try { SmsMessageRecord toDelete = getMessage(messageId); - DatabaseFactory.getMmsDatabase(context).deleteQuotedFromMessages(toDelete); + DatabaseComponent.get(context).mmsDatabase().deleteQuotedFromMessages(toDelete); } catch (NoSuchMessageException e) { Log.e(TAG, "Couldn't find message record for messageId "+messageId, e); } db.delete(TABLE_NAME, ID_WHERE, new String[] {messageId+""}); - boolean threadDeleted = DatabaseFactory.getThreadDatabase(context).update(threadId, false); + boolean threadDeleted = DatabaseComponent.get(context).threadDatabase().update(threadId, false); notifyConversationListeners(threadId); return threadDeleted; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt index 950b6d823..196bffcdb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -28,6 +28,7 @@ import org.session.libsignal.utilities.KeyHelper import org.session.libsignal.utilities.guava.Optional import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper +import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.groups.OpenGroupManager import org.thoughtcrime.securesms.jobs.RetrieveProfileAvatarJob import org.thoughtcrime.securesms.mms.PartAuthority @@ -40,7 +41,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, } override fun getUserX25519KeyPair(): ECKeyPair { - return DatabaseFactory.getLokiAPIDatabase(context).getUserX25519KeyPair() + return DatabaseComponent.get(context).lokiAPIDatabase().getUserX25519KeyPair() } override fun getUserDisplayName(): String? { @@ -74,13 +75,13 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, } override fun persistAttachments(messageID: Long, attachments: List): List { - val database = DatabaseFactory.getAttachmentDatabase(context) + val database = DatabaseComponent.get(context).attachmentDatabase() val databaseAttachments = attachments.mapNotNull { it.toSignalAttachment() } return database.insertAttachments(messageID, databaseAttachments) } override fun getAttachmentsForMessage(messageID: Long): List { - val database = DatabaseFactory.getAttachmentDatabase(context) + val database = DatabaseComponent.get(context).attachmentDatabase() return database.getAttachmentsForMessage(messageID) } @@ -110,7 +111,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, if (message.isMediaMessage() || attachments.isNotEmpty()) { val quote: Optional = if (quotes != null) Optional.of(quotes) else Optional.absent() val linkPreviews: Optional> = if (linkPreview.isEmpty()) Optional.absent() else Optional.of(linkPreview.mapNotNull { it!! }) - val mmsDatabase = DatabaseFactory.getMmsDatabase(context) + val mmsDatabase = DatabaseComponent.get(context).mmsDatabase() val insertResult = if (message.sender == getUserPublicKey()) { val mediaMessage = OutgoingMediaMessage.from(message, targetRecipient, pointers, quote.orNull(), linkPreviews.orNull()?.firstOrNull()) mmsDatabase.insertSecureDecryptedMessageOutbox(mediaMessage, message.threadID ?: -1, message.sentTimestamp!!) @@ -126,7 +127,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, messageID = insertResult.get().messageId } } else { - val smsDatabase = DatabaseFactory.getSmsDatabase(context) + val smsDatabase = DatabaseComponent.get(context).smsDatabase() val isOpenGroupInvitation = (message.openGroupInvitation != null) val insertResult = if (message.sender == getUserPublicKey()) { @@ -150,62 +151,62 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, } message.serverHash?.let { serverHash -> messageID?.let { id -> - DatabaseFactory.getLokiMessageDatabase(context).setMessageServerHash(id, serverHash) + DatabaseComponent.get(context).lokiMessageDatabase().setMessageServerHash(id, serverHash) } } return messageID } override fun persistJob(job: Job) { - DatabaseFactory.getSessionJobDatabase(context).persistJob(job) + DatabaseComponent.get(context).sessionJobDatabase().persistJob(job) } override fun markJobAsSucceeded(jobId: String) { - DatabaseFactory.getSessionJobDatabase(context).markJobAsSucceeded(jobId) + DatabaseComponent.get(context).sessionJobDatabase().markJobAsSucceeded(jobId) } override fun markJobAsFailedPermanently(jobId: String) { - DatabaseFactory.getSessionJobDatabase(context).markJobAsFailedPermanently(jobId) + DatabaseComponent.get(context).sessionJobDatabase().markJobAsFailedPermanently(jobId) } override fun getAllPendingJobs(type: String): Map { - return DatabaseFactory.getSessionJobDatabase(context).getAllPendingJobs(type) + return DatabaseComponent.get(context).sessionJobDatabase().getAllPendingJobs(type) } override fun getAttachmentUploadJob(attachmentID: Long): AttachmentUploadJob? { - return DatabaseFactory.getSessionJobDatabase(context).getAttachmentUploadJob(attachmentID) + return DatabaseComponent.get(context).sessionJobDatabase().getAttachmentUploadJob(attachmentID) } override fun getMessageSendJob(messageSendJobID: String): MessageSendJob? { - return DatabaseFactory.getSessionJobDatabase(context).getMessageSendJob(messageSendJobID) + return DatabaseComponent.get(context).sessionJobDatabase().getMessageSendJob(messageSendJobID) } override fun getMessageReceiveJob(messageReceiveJobID: String): MessageReceiveJob? { - return DatabaseFactory.getSessionJobDatabase(context).getMessageReceiveJob(messageReceiveJobID) + return DatabaseComponent.get(context).sessionJobDatabase().getMessageReceiveJob(messageReceiveJobID) } override fun resumeMessageSendJobIfNeeded(messageSendJobID: String) { - val job = DatabaseFactory.getSessionJobDatabase(context).getMessageSendJob(messageSendJobID) ?: return + val job = DatabaseComponent.get(context).sessionJobDatabase().getMessageSendJob(messageSendJobID) ?: return JobQueue.shared.resumePendingSendMessage(job) } override fun isJobCanceled(job: Job): Boolean { - return DatabaseFactory.getSessionJobDatabase(context).isJobCanceled(job) + return DatabaseComponent.get(context).sessionJobDatabase().isJobCanceled(job) } override fun getAuthToken(room: String, server: String): String? { val id = "$server.$room" - return DatabaseFactory.getLokiAPIDatabase(context).getAuthToken(id) + return DatabaseComponent.get(context).lokiAPIDatabase().getAuthToken(id) } override fun setAuthToken(room: String, server: String, newValue: String) { val id = "$server.$room" - DatabaseFactory.getLokiAPIDatabase(context).setAuthToken(id, newValue) + DatabaseComponent.get(context).lokiAPIDatabase().setAuthToken(id, newValue) } override fun removeAuthToken(room: String, server: String) { val id = "$server.$room" - DatabaseFactory.getLokiAPIDatabase(context).setAuthToken(id, null) + DatabaseComponent.get(context).lokiAPIDatabase().setAuthToken(id, null) } override fun getV2OpenGroup(threadId: Long): OpenGroupV2? { @@ -218,44 +219,44 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, } override fun getOpenGroupPublicKey(server: String): String? { - return DatabaseFactory.getLokiAPIDatabase(context).getOpenGroupPublicKey(server) + return DatabaseComponent.get(context).lokiAPIDatabase().getOpenGroupPublicKey(server) } override fun setOpenGroupPublicKey(server: String, newValue: String) { - DatabaseFactory.getLokiAPIDatabase(context).setOpenGroupPublicKey(server, newValue) + DatabaseComponent.get(context).lokiAPIDatabase().setOpenGroupPublicKey(server, newValue) } override fun getLastMessageServerID(room: String, server: String): Long? { - return DatabaseFactory.getLokiAPIDatabase(context).getLastMessageServerID(room, server) + return DatabaseComponent.get(context).lokiAPIDatabase().getLastMessageServerID(room, server) } override fun setLastMessageServerID(room: String, server: String, newValue: Long) { - DatabaseFactory.getLokiAPIDatabase(context).setLastMessageServerID(room, server, newValue) + DatabaseComponent.get(context).lokiAPIDatabase().setLastMessageServerID(room, server, newValue) } override fun removeLastMessageServerID(room: String, server: String) { - DatabaseFactory.getLokiAPIDatabase(context).removeLastMessageServerID(room, server) + DatabaseComponent.get(context).lokiAPIDatabase().removeLastMessageServerID(room, server) } override fun getLastDeletionServerID(room: String, server: String): Long? { - return DatabaseFactory.getLokiAPIDatabase(context).getLastDeletionServerID(room, server) + return DatabaseComponent.get(context).lokiAPIDatabase().getLastDeletionServerID(room, server) } override fun setLastDeletionServerID(room: String, server: String, newValue: Long) { - DatabaseFactory.getLokiAPIDatabase(context).setLastDeletionServerID(room, server, newValue) + DatabaseComponent.get(context).lokiAPIDatabase().setLastDeletionServerID(room, server, newValue) } override fun removeLastDeletionServerID(room: String, server: String) { - DatabaseFactory.getLokiAPIDatabase(context).removeLastDeletionServerID(room, server) + DatabaseComponent.get(context).lokiAPIDatabase().removeLastDeletionServerID(room, server) } override fun setUserCount(room: String, server: String, newValue: Int) { - DatabaseFactory.getLokiAPIDatabase(context).setUserCount(room, server, newValue) + DatabaseComponent.get(context).lokiAPIDatabase().setUserCount(room, server, newValue) } override fun setOpenGroupServerMessageID(messageID: Long, serverID: Long, threadID: Long, isSms: Boolean) { - DatabaseFactory.getLokiMessageDatabase(context).setServerID(messageID, serverID, isSms) - DatabaseFactory.getLokiMessageDatabase(context).setOriginalThreadID(messageID, serverID, threadID) + DatabaseComponent.get(context).lokiMessageDatabase().setServerID(messageID, serverID, isSms) + DatabaseComponent.get(context).lokiMessageDatabase().setOriginalThreadID(messageID, serverID, threadID) } override fun isDuplicateMessage(timestamp: Long): Boolean { @@ -263,11 +264,11 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, } override fun updateTitle(groupID: String, newValue: String) { - DatabaseFactory.getGroupDatabase(context).updateTitle(groupID, newValue) + DatabaseComponent.get(context).groupDatabase().updateTitle(groupID, newValue) } override fun updateProfilePicture(groupID: String, newValue: ByteArray) { - DatabaseFactory.getGroupDatabase(context).updateProfilePicture(groupID, newValue) + DatabaseComponent.get(context).groupDatabase().updateProfilePicture(groupID, newValue) } override fun getReceivedMessageTimestamps(): Set { @@ -283,7 +284,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, } override fun getMessageIdInDatabase(timestamp: Long, author: String): Long? { - val database = DatabaseFactory.getMmsSmsDatabase(context) + val database = DatabaseComponent.get(context).mmsSmsDatabase() val address = Address.fromSerialized(author) return database.getMessageFor(timestamp, address)?.getId() } @@ -295,59 +296,59 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, threadId: Long ) { if (isMms) { - val mmsDb = DatabaseFactory.getMmsDatabase(context) + val mmsDb = DatabaseComponent.get(context).mmsDatabase() mmsDb.updateSentTimestamp(messageID, openGroupSentTimestamp, threadId) } else { - val smsDb = DatabaseFactory.getSmsDatabase(context) + val smsDb = DatabaseComponent.get(context).smsDatabase() smsDb.updateSentTimestamp(messageID, openGroupSentTimestamp, threadId) } } override fun markAsSent(timestamp: Long, author: String) { - val database = DatabaseFactory.getMmsSmsDatabase(context) + val database = DatabaseComponent.get(context).mmsSmsDatabase() val messageRecord = database.getMessageFor(timestamp, author) ?: return if (messageRecord.isMms) { - val mmsDatabase = DatabaseFactory.getMmsDatabase(context) + val mmsDatabase = DatabaseComponent.get(context).mmsDatabase() mmsDatabase.markAsSent(messageRecord.getId(), true) } else { - val smsDatabase = DatabaseFactory.getSmsDatabase(context) + val smsDatabase = DatabaseComponent.get(context).smsDatabase() smsDatabase.markAsSent(messageRecord.getId(), true) } } override fun markAsSending(timestamp: Long, author: String) { - val database = DatabaseFactory.getMmsSmsDatabase(context) + val database = DatabaseComponent.get(context).mmsSmsDatabase() val messageRecord = database.getMessageFor(timestamp, author) ?: return if (messageRecord.isMms) { - val mmsDatabase = DatabaseFactory.getMmsDatabase(context) + val mmsDatabase = DatabaseComponent.get(context).mmsDatabase() mmsDatabase.markAsSending(messageRecord.getId()) } else { - val smsDatabase = DatabaseFactory.getSmsDatabase(context) + val smsDatabase = DatabaseComponent.get(context).smsDatabase() smsDatabase.markAsSending(messageRecord.getId()) messageRecord.isPending } } override fun markUnidentified(timestamp: Long, author: String) { - val database = DatabaseFactory.getMmsSmsDatabase(context) + val database = DatabaseComponent.get(context).mmsSmsDatabase() val messageRecord = database.getMessageFor(timestamp, author) ?: return if (messageRecord.isMms) { - val mmsDatabase = DatabaseFactory.getMmsDatabase(context) + val mmsDatabase = DatabaseComponent.get(context).mmsDatabase() mmsDatabase.markUnidentified(messageRecord.getId(), true) } else { - val smsDatabase = DatabaseFactory.getSmsDatabase(context) + val smsDatabase = DatabaseComponent.get(context).smsDatabase() smsDatabase.markUnidentified(messageRecord.getId(), true) } } override fun setErrorMessage(timestamp: Long, author: String, error: Exception) { - val database = DatabaseFactory.getMmsSmsDatabase(context) + val database = DatabaseComponent.get(context).mmsSmsDatabase() val messageRecord = database.getMessageFor(timestamp, author) ?: return if (messageRecord.isMms) { - val mmsDatabase = DatabaseFactory.getMmsDatabase(context) + val mmsDatabase = DatabaseComponent.get(context).mmsDatabase() mmsDatabase.markAsSentFailed(messageRecord.getId()) } else { - val smsDatabase = DatabaseFactory.getSmsDatabase(context) + val smsDatabase = DatabaseComponent.get(context).smsDatabase() smsDatabase.markAsSentFailed(messageRecord.getId()) } if (error.localizedMessage != null) { @@ -357,47 +358,47 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, } else { message = error.localizedMessage!! } - DatabaseFactory.getLokiMessageDatabase(context).setErrorMessage(messageRecord.getId(), message) + DatabaseComponent.get(context).lokiMessageDatabase().setErrorMessage(messageRecord.getId(), message) } else { - DatabaseFactory.getLokiMessageDatabase(context).setErrorMessage(messageRecord.getId(), error.javaClass.simpleName) + DatabaseComponent.get(context).lokiMessageDatabase().setErrorMessage(messageRecord.getId(), error.javaClass.simpleName) } } override fun setMessageServerHash(messageID: Long, serverHash: String) { - DatabaseFactory.getLokiMessageDatabase(context).setMessageServerHash(messageID, serverHash) + DatabaseComponent.get(context).lokiMessageDatabase().setMessageServerHash(messageID, serverHash) } override fun getGroup(groupID: String): GroupRecord? { - val group = DatabaseFactory.getGroupDatabase(context).getGroup(groupID) + val group = DatabaseComponent.get(context).groupDatabase().getGroup(groupID) return if (group.isPresent) { group.get() } else null } override fun createGroup(groupId: String, title: String?, members: List
, avatar: SignalServiceAttachmentPointer?, relay: String?, admins: List
, formationTimestamp: Long) { - DatabaseFactory.getGroupDatabase(context).create(groupId, title, members, avatar, relay, admins, formationTimestamp) + DatabaseComponent.get(context).groupDatabase().create(groupId, title, members, avatar, relay, admins, formationTimestamp) } override fun isGroupActive(groupPublicKey: String): Boolean { - return DatabaseFactory.getGroupDatabase(context).getGroup(GroupUtil.doubleEncodeGroupID(groupPublicKey)).orNull()?.isActive == true + return DatabaseComponent.get(context).groupDatabase().getGroup(GroupUtil.doubleEncodeGroupID(groupPublicKey)).orNull()?.isActive == true } override fun setActive(groupID: String, value: Boolean) { - DatabaseFactory.getGroupDatabase(context).setActive(groupID, value) + DatabaseComponent.get(context).groupDatabase().setActive(groupID, value) } override fun getZombieMembers(groupID: String): Set { - return DatabaseFactory.getGroupDatabase(context).getGroupZombieMembers(groupID).map { it.address.serialize() }.toHashSet() + return DatabaseComponent.get(context).groupDatabase().getGroupZombieMembers(groupID).map { it.address.serialize() }.toHashSet() } override fun removeMember(groupID: String, member: Address) { - DatabaseFactory.getGroupDatabase(context).removeMember(groupID, member) + DatabaseComponent.get(context).groupDatabase().removeMember(groupID, member) } override fun updateMembers(groupID: String, members: List
) { - DatabaseFactory.getGroupDatabase(context).updateMembers(groupID, members) + DatabaseComponent.get(context).groupDatabase().updateMembers(groupID, members) } override fun setZombieMembers(groupID: String, members: List
) { - DatabaseFactory.getGroupDatabase(context).updateZombieMembers(groupID, members) + DatabaseComponent.get(context).groupDatabase().updateZombieMembers(groupID, members) } override fun insertIncomingInfoMessage(context: Context, senderPublicKey: String, groupID: String, type: SignalServiceGroup.Type, name: String, members: Collection, admins: Collection, sentTimestamp: Long) { @@ -405,7 +406,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, val m = IncomingTextMessage(Address.fromSerialized(senderPublicKey), 1, sentTimestamp, "", Optional.of(group), 0, true) val updateData = UpdateMessageData.buildGroupUpdate(type, name, members)?.toJSON() val infoMessage = IncomingGroupMessage(m, groupID, updateData, true) - val smsDB = DatabaseFactory.getSmsDatabase(context) + val smsDB = DatabaseComponent.get(context).smsDatabase() smsDB.insertMessageInbox(infoMessage) } @@ -415,69 +416,69 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, val updateData = UpdateMessageData.buildGroupUpdate(type, name, members)?.toJSON() ?: "" val infoMessage = OutgoingGroupMediaMessage(recipient, updateData, groupID, null, sentTimestamp, 0, true, null, listOf(), listOf()) - val mmsDB = DatabaseFactory.getMmsDatabase(context) - val mmsSmsDB = DatabaseFactory.getMmsSmsDatabase(context) + val mmsDB = DatabaseComponent.get(context).mmsDatabase() + val mmsSmsDB = DatabaseComponent.get(context).mmsSmsDatabase() if (mmsSmsDB.getMessageFor(sentTimestamp, userPublicKey) != null) return val infoMessageID = mmsDB.insertMessageOutbox(infoMessage, threadID, false, null) mmsDB.markAsSent(infoMessageID, true) } override fun isClosedGroup(publicKey: String): Boolean { - val isClosedGroup = DatabaseFactory.getLokiAPIDatabase(context).isClosedGroup(publicKey) + val isClosedGroup = DatabaseComponent.get(context).lokiAPIDatabase().isClosedGroup(publicKey) val address = Address.fromSerialized(publicKey) return address.isClosedGroup || isClosedGroup } override fun getClosedGroupEncryptionKeyPairs(groupPublicKey: String): MutableList { - return DatabaseFactory.getLokiAPIDatabase(context).getClosedGroupEncryptionKeyPairs(groupPublicKey).toMutableList() + return DatabaseComponent.get(context).lokiAPIDatabase().getClosedGroupEncryptionKeyPairs(groupPublicKey).toMutableList() } override fun getLatestClosedGroupEncryptionKeyPair(groupPublicKey: String): ECKeyPair? { - return DatabaseFactory.getLokiAPIDatabase(context).getLatestClosedGroupEncryptionKeyPair(groupPublicKey) + return DatabaseComponent.get(context).lokiAPIDatabase().getLatestClosedGroupEncryptionKeyPair(groupPublicKey) } override fun getAllClosedGroupPublicKeys(): Set { - return DatabaseFactory.getLokiAPIDatabase(context).getAllClosedGroupPublicKeys() + return DatabaseComponent.get(context).lokiAPIDatabase().getAllClosedGroupPublicKeys() } override fun getAllActiveClosedGroupPublicKeys(): Set { - return DatabaseFactory.getLokiAPIDatabase(context).getAllClosedGroupPublicKeys().filter { + return DatabaseComponent.get(context).lokiAPIDatabase().getAllClosedGroupPublicKeys().filter { getGroup(GroupUtil.doubleEncodeGroupID(it))?.isActive == true }.toSet() } override fun addClosedGroupPublicKey(groupPublicKey: String) { - DatabaseFactory.getLokiAPIDatabase(context).addClosedGroupPublicKey(groupPublicKey) + DatabaseComponent.get(context).lokiAPIDatabase().addClosedGroupPublicKey(groupPublicKey) } override fun removeClosedGroupPublicKey(groupPublicKey: String) { - DatabaseFactory.getLokiAPIDatabase(context).removeClosedGroupPublicKey(groupPublicKey) + DatabaseComponent.get(context).lokiAPIDatabase().removeClosedGroupPublicKey(groupPublicKey) } override fun addClosedGroupEncryptionKeyPair(encryptionKeyPair: ECKeyPair, groupPublicKey: String) { - DatabaseFactory.getLokiAPIDatabase(context).addClosedGroupEncryptionKeyPair(encryptionKeyPair, groupPublicKey) + DatabaseComponent.get(context).lokiAPIDatabase().addClosedGroupEncryptionKeyPair(encryptionKeyPair, groupPublicKey) } override fun removeAllClosedGroupEncryptionKeyPairs(groupPublicKey: String) { - DatabaseFactory.getLokiAPIDatabase(context).removeAllClosedGroupEncryptionKeyPairs(groupPublicKey) + DatabaseComponent.get(context).lokiAPIDatabase().removeAllClosedGroupEncryptionKeyPairs(groupPublicKey) } override fun updateFormationTimestamp(groupID: String, formationTimestamp: Long) { - DatabaseFactory.getGroupDatabase(context) + DatabaseComponent.get(context).groupDatabase() .updateFormationTimestamp(groupID, formationTimestamp) } override fun setExpirationTimer(groupID: String, duration: Int) { val recipient = Recipient.from(context, fromSerialized(groupID), false) - DatabaseFactory.getRecipientDatabase(context).setExpireMessages(recipient, duration); + DatabaseComponent.get(context).recipientDatabase().setExpireMessages(recipient, duration); } override fun getAllV2OpenGroups(): Map { - return DatabaseFactory.getLokiThreadDatabase(context).getAllV2OpenGroups() + return DatabaseComponent.get(context).lokiThreadDatabase().getAllV2OpenGroups() } override fun getAllGroups(): List { - return DatabaseFactory.getGroupDatabase(context).allGroups + return DatabaseComponent.get(context).groupDatabase().allGroups } override fun addOpenGroup(urlAsString: String) { @@ -486,16 +487,16 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, override fun setProfileSharing(address: Address, value: Boolean) { val recipient = Recipient.from(context, address, false) - DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient, value) + DatabaseComponent.get(context).recipientDatabase().setProfileSharing(recipient, value) } override fun getOrCreateThreadIdFor(address: Address): Long { val recipient = Recipient.from(context, address, false) - return DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient) + return DatabaseComponent.get(context).threadDatabase().getOrCreateThreadIdFor(recipient) } override fun getOrCreateThreadIdFor(publicKey: String, groupPublicKey: String?, openGroupID: String?): Long { - val database = DatabaseFactory.getThreadDatabase(context) + val database = DatabaseComponent.get(context).threadDatabase() if (!openGroupID.isNullOrEmpty()) { val recipient = Recipient.from(context, Address.fromSerialized(GroupUtil.getEncodedOpenGroupID(openGroupID.toByteArray())), false) return database.getThreadIdIfExistsFor(recipient) @@ -519,12 +520,12 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, } override fun getThreadId(recipient: Recipient): Long? { - val threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(recipient) + val threadID = DatabaseComponent.get(context).threadDatabase().getThreadIdIfExistsFor(recipient) return if (threadID < 0) null else threadID } override fun getThreadIdForMms(mmsId: Long): Long { - val mmsDb = DatabaseFactory.getMmsDatabase(context) + val mmsDb = DatabaseComponent.get(context).mmsDatabase() val cursor = mmsDb.getMessage(mmsId) val reader = mmsDb.readerFor(cursor) val threadId = reader.next?.threadId @@ -533,29 +534,29 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, } override fun getContactWithSessionID(sessionID: String): Contact? { - return DatabaseFactory.getSessionContactDatabase(context).getContactWithSessionID(sessionID) + return DatabaseComponent.get(context).sessionContactDatabase().getContactWithSessionID(sessionID) } override fun getAllContacts(): Set { - return DatabaseFactory.getSessionContactDatabase(context).getAllContacts() + return DatabaseComponent.get(context).sessionContactDatabase().getAllContacts() } override fun setContact(contact: Contact) { - DatabaseFactory.getSessionContactDatabase(context).setContact(contact) + DatabaseComponent.get(context).sessionContactDatabase().setContact(contact) } override fun getRecipientForThread(threadId: Long): Recipient? { - return DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(threadId) + return DatabaseComponent.get(context).threadDatabase().getRecipientForThreadId(threadId) } override fun getRecipientSettings(address: Address): Recipient.RecipientSettings? { - val recipientSettings = DatabaseFactory.getRecipientDatabase(context).getRecipientSettings(address) + val recipientSettings = DatabaseComponent.get(context).recipientDatabase().getRecipientSettings(address) return if (recipientSettings.isPresent) { recipientSettings.get() } else null } override fun addContacts(contacts: List) { - val recipientDatabase = DatabaseFactory.getRecipientDatabase(context) - val threadDatabase = DatabaseFactory.getThreadDatabase(context) + val recipientDatabase = DatabaseComponent.get(context).recipientDatabase() + val threadDatabase = DatabaseComponent.get(context).threadDatabase() for (contact in contacts) { val address = Address.fromSerialized(contact.publicKey) val recipient = Recipient.from(context, address, true) @@ -579,12 +580,12 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, } override fun getLastUpdated(threadID: Long): Long { - val threadDB = DatabaseFactory.getThreadDatabase(context) + val threadDB = DatabaseComponent.get(context).threadDatabase() return threadDB.getLastUpdated(threadID) } override fun trimThread(threadID: Long, threadLimit: Int) { - val threadDB = DatabaseFactory.getThreadDatabase(context) + val threadDB = DatabaseComponent.get(context).threadDatabase() threadDB.trimThread(threadID, threadLimit) } @@ -597,7 +598,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, } override fun insertDataExtractionNotificationMessage(senderPublicKey: String, message: DataExtractionNotificationInfoMessage, sentTimestamp: Long) { - val database = DatabaseFactory.getMmsDatabase(context) + val database = DatabaseComponent.get(context).mmsDatabase() val address = fromSerialized(senderPublicKey) val recipient = Recipient.from(context, address, false) 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 361d1449e..5f4224c81 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java @@ -49,6 +49,7 @@ import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.database.model.MmsMessageRecord; import org.thoughtcrime.securesms.database.model.ThreadRecord; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import org.thoughtcrime.securesms.mms.Slide; import org.thoughtcrime.securesms.mms.SlideDeck; import org.thoughtcrime.securesms.util.SessionMetaProtocol; @@ -241,7 +242,7 @@ public class ThreadDatabase extends Database { Cursor cursor = null; try { - cursor = DatabaseFactory.getMmsSmsDatabase(context).getConversation(threadId); + cursor = DatabaseComponent.get(context).mmsSmsDatabase().getConversation(threadId); if (cursor != null && length > 0 && cursor.getCount() > length) { Log.w("ThreadDatabase", "Cursor count is greater than length!"); @@ -251,8 +252,8 @@ public class ThreadDatabase extends Database { Log.i("ThreadDatabase", "Cut off tweet date: " + lastTweetDate); - DatabaseFactory.getSmsDatabase(context).deleteMessagesInThreadBeforeDate(threadId, lastTweetDate); - DatabaseFactory.getMmsDatabase(context).deleteMessagesInThreadBeforeDate(threadId, lastTweetDate); + DatabaseComponent.get(context).smsDatabase().deleteMessagesInThreadBeforeDate(threadId, lastTweetDate); + DatabaseComponent.get(context).mmsDatabase().deleteMessagesInThreadBeforeDate(threadId, lastTweetDate); update(threadId, false); notifyConversationListeners(threadId); @@ -275,8 +276,8 @@ public class ThreadDatabase extends Database { SQLiteDatabase db = databaseHelper.getWritableDatabase(); db.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {threadId+""}); - final List smsRecords = DatabaseFactory.getSmsDatabase(context).setMessagesRead(threadId); - final List mmsRecords = DatabaseFactory.getMmsDatabase(context).setMessagesRead(threadId); + final List smsRecords = DatabaseComponent.get(context).smsDatabase().setMessagesRead(threadId); + final List mmsRecords = DatabaseComponent.get(context).mmsDatabase().setMessagesRead(threadId); notifyConversationListListeners(); @@ -428,10 +429,10 @@ public class ThreadDatabase extends Database { } public void deleteConversation(long threadId) { - DatabaseFactory.getSmsDatabase(context).deleteThread(threadId); - DatabaseFactory.getMmsDatabase(context).deleteThread(threadId); - DatabaseFactory.getDraftDatabase(context).clearDrafts(threadId); - DatabaseFactory.getLokiMessageDatabase(context).deleteThread(threadId); + DatabaseComponent.get(context).smsDatabase().deleteThread(threadId); + DatabaseComponent.get(context).mmsDatabase().deleteThread(threadId); + DatabaseComponent.get(context).draftDatabase().clearDrafts(threadId); + DatabaseComponent.get(context).lokiMessageDatabase().deleteThread(threadId); deleteThread(threadId); notifyConversationListeners(threadId); notifyConversationListListeners(); @@ -485,7 +486,7 @@ public class ThreadDatabase extends Database { if (cursor != null && cursor.moveToFirst()) { return cursor.getLong(cursor.getColumnIndexOrThrow(ID)); } else { - DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient, true); + DatabaseComponent.get(context).recipientDatabase().setProfileSharing(recipient, true); return createThreadForRecipient(recipient.getAddress(), recipient.isGroupRecipient(), distributionType); } } finally { @@ -529,7 +530,7 @@ public class ThreadDatabase extends Database { } public boolean update(long threadId, boolean unarchive) { - MmsSmsDatabase mmsSmsDatabase = DatabaseFactory.getMmsSmsDatabase(context); + MmsSmsDatabase mmsSmsDatabase = DatabaseComponent.get(context).mmsSmsDatabase(); long count = mmsSmsDatabase.getConversationCount(threadId); boolean shouldDeleteEmptyThread = deleteThreadOnEmpty(threadId); @@ -657,8 +658,8 @@ public class ThreadDatabase extends Database { Optional groupRecord; if (distributionType != DistributionTypes.ARCHIVE && distributionType != DistributionTypes.INBOX_ZERO) { - settings = DatabaseFactory.getRecipientDatabase(context).getRecipientSettings(cursor); - groupRecord = DatabaseFactory.getGroupDatabase(context).getGroup(cursor); + settings = DatabaseComponent.get(context).recipientDatabase().getRecipientSettings(cursor); + groupRecord = DatabaseComponent.get(context).groupDatabase().getGroup(cursor); } else { settings = Optional.absent(); groupRecord = Optional.absent(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/loaders/BucketedThreadMediaLoader.java b/app/src/main/java/org/thoughtcrime/securesms/database/loaders/BucketedThreadMediaLoader.java index 750b6a7c8..05c13cc55 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/loaders/BucketedThreadMediaLoader.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/loaders/BucketedThreadMediaLoader.java @@ -4,16 +4,16 @@ package org.thoughtcrime.securesms.database.loaders; import android.content.Context; import android.database.ContentObserver; import android.database.Cursor; + import androidx.annotation.NonNull; import androidx.loader.content.AsyncTaskLoader; import com.annimon.stream.Stream; -import network.loki.messenger.R; import org.session.libsession.utilities.Address; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.MediaDatabase; import org.session.libsession.utilities.recipients.Recipient; +import org.thoughtcrime.securesms.database.MediaDatabase; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -26,6 +26,8 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import network.loki.messenger.R; + public class BucketedThreadMediaLoader extends AsyncTaskLoader { @SuppressWarnings("unused") @@ -56,16 +58,18 @@ public class BucketedThreadMediaLoader extends AsyncTaskLoader 0; - } - - public boolean hasOffset() { - return offset > 0; - } - - public int getOffset() { - return offset; - } - - public long getLastSeen() { - return lastSeen; - } - - public boolean hasSent() { - return hasSent; - } - - @Override - public Cursor getCursor() { - Pair lastSeenAndHasSent = DatabaseFactory.getThreadDatabase(context).getLastSeenAndHasSent(threadId); - - this.hasSent = lastSeenAndHasSent.second(); - - if (lastSeen == -1) { - this.lastSeen = lastSeenAndHasSent.first(); - } - - return DatabaseFactory.getMmsSmsDatabase(context).getConversation(threadId, offset, limit); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/loaders/MessageDetailsLoader.java b/app/src/main/java/org/thoughtcrime/securesms/database/loaders/MessageDetailsLoader.java deleted file mode 100644 index 06b45567b..000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/database/loaders/MessageDetailsLoader.java +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Copyright (C) 2015 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.loaders; - -import android.content.Context; -import android.database.Cursor; - -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.MmsSmsDatabase; -import org.thoughtcrime.securesms.util.AbstractCursorLoader; - -public class MessageDetailsLoader extends AbstractCursorLoader { - private final String type; - private final long messageId; - - public MessageDetailsLoader(Context context, String type, long messageId) { - super(context); - this.type = type; - this.messageId = messageId; - } - - @Override - public Cursor getCursor() { - switch (type) { - case MmsSmsDatabase.SMS_TRANSPORT: - return DatabaseFactory.getSmsDatabase(context).getMessageCursor(messageId); - case MmsSmsDatabase.MMS_TRANSPORT: - return DatabaseFactory.getMmsDatabase(context).getMessage(messageId); - default: - throw new AssertionError("no valid message type specified"); - } - } -} 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 0247c54c9..a979da544 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 @@ -4,15 +4,16 @@ package org.thoughtcrime.securesms.database.loaders; import android.content.Context; import android.database.Cursor; import android.net.Uri; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.util.Pair; import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId; -import org.thoughtcrime.securesms.database.AttachmentDatabase; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.mms.PartAuthority; import org.session.libsession.utilities.recipients.Recipient; +import org.thoughtcrime.securesms.database.AttachmentDatabase; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; +import org.thoughtcrime.securesms.mms.PartAuthority; import org.thoughtcrime.securesms.util.AsyncLoader; public class PagingMediaLoader extends AsyncLoader> { @@ -34,8 +35,8 @@ public class PagingMediaLoader extends AsyncLoader> { @Nullable @Override public Pair loadInBackground() { - long threadId = DatabaseFactory.getThreadDatabase(getContext()).getOrCreateThreadIdFor(recipient); - Cursor cursor = DatabaseFactory.getMediaDatabase(getContext()).getGalleryMediaForThread(threadId); + long threadId = DatabaseComponent.get(getContext()).threadDatabase().getOrCreateThreadIdFor(recipient); + Cursor cursor = DatabaseComponent.get(getContext()).mediaDatabase().getGalleryMediaForThread(threadId); while (cursor != null && 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/ThreadMediaLoader.java b/app/src/main/java/org/thoughtcrime/securesms/database/loaders/ThreadMediaLoader.java index 3762c89be..3f5c10835 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 @@ -3,11 +3,12 @@ package org.thoughtcrime.securesms.database.loaders; import android.content.Context; import android.database.Cursor; + import androidx.annotation.NonNull; import org.session.libsession.utilities.Address; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.session.libsession.utilities.recipients.Recipient; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import org.thoughtcrime.securesms.util.AbstractCursorLoader; public class ThreadMediaLoader extends AbstractCursorLoader { @@ -23,10 +24,10 @@ public class ThreadMediaLoader extends AbstractCursorLoader { @Override public Cursor getCursor() { - long threadId = DatabaseFactory.getThreadDatabase(getContext()).getOrCreateThreadIdFor(Recipient.from(getContext(), address, true)); + long threadId = DatabaseComponent.get(context).threadDatabase().getOrCreateThreadIdFor(Recipient.from(getContext(), address, true)); - if (gallery) return DatabaseFactory.getMediaDatabase(getContext()).getGalleryMediaForThread(threadId); - else return DatabaseFactory.getMediaDatabase(getContext()).getDocumentMediaForThread(threadId); + if (gallery) return DatabaseComponent.get(context).mediaDatabase().getGalleryMediaForThread(threadId); + else return DatabaseComponent.get(context).mediaDatabase().getDocumentMediaForThread(threadId); } public Address getAddress() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseComponent.kt b/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseComponent.kt new file mode 100644 index 000000000..382b0f4b7 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseComponent.kt @@ -0,0 +1,45 @@ +package org.thoughtcrime.securesms.dependencies + +import android.content.Context +import dagger.hilt.EntryPoint +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import org.session.libsession.database.MessageDataProvider +import org.thoughtcrime.securesms.ApplicationContext +import org.thoughtcrime.securesms.database.* +import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper + +@EntryPoint +@InstallIn(SingletonComponent::class) +interface DatabaseComponent { + + companion object { + @JvmStatic + fun get(context: Context) = ApplicationContext.getInstance(context).databaseComponent + } + + fun openHelper(): SQLCipherOpenHelper + + fun smsDatabase(): SmsDatabase + fun mmsDatabase(): MmsDatabase + fun attachmentDatabase(): AttachmentDatabase + fun mediaDatabase(): MediaDatabase + fun threadDatabase(): ThreadDatabase + fun mmsSmsDatabase(): MmsSmsDatabase + fun draftDatabase(): DraftDatabase + fun pushDatabase(): PushDatabase + fun groupDatabase(): GroupDatabase + fun recipientDatabase(): RecipientDatabase + fun groupReceiptDatabase(): GroupReceiptDatabase + fun searchDatabase(): SearchDatabase + fun jobDatabase(): JobDatabase + fun lokiAPIDatabase(): LokiAPIDatabase + fun lokiMessageDatabase(): LokiMessageDatabase + fun lokiThreadDatabase(): LokiThreadDatabase + fun lokiUserDatabase(): LokiUserDatabase + fun lokiBackupFilesDatabase(): LokiBackupFilesDatabase + fun sessionJobDatabase(): SessionJobDatabase + fun sessionContactDatabase(): SessionContactDatabase + fun storage(): Storage + fun attachmentProvider(): MessageDataProvider +} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseModule.kt b/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseModule.kt new file mode 100644 index 000000000..0a1171e50 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseModule.kt @@ -0,0 +1,128 @@ +package org.thoughtcrime.securesms.dependencies + +import android.content.Context +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext +import dagger.hilt.components.SingletonComponent +import net.sqlcipher.database.SQLiteDatabase +import org.session.libsession.database.MessageDataProvider +import org.thoughtcrime.securesms.attachments.DatabaseAttachmentProvider +import org.thoughtcrime.securesms.crypto.AttachmentSecret +import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider +import org.thoughtcrime.securesms.crypto.DatabaseSecretProvider +import org.thoughtcrime.securesms.database.* +import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +object DatabaseModule { + + @JvmStatic + fun init(context: Context) { + SQLiteDatabase.loadLibs(context) + } + + @Provides + @Singleton + fun provideAttachmentSecret(@ApplicationContext context: Context) = AttachmentSecretProvider.getInstance(context).orCreateAttachmentSecret + + @Provides + @Singleton + fun provideOpenHelper(@ApplicationContext context: Context): SQLCipherOpenHelper { + val dbSecret = DatabaseSecretProvider(context).orCreateDatabaseSecret + return SQLCipherOpenHelper(context, dbSecret) + } + + @Provides + @Singleton + fun provideSmsDatabase(@ApplicationContext context: Context, openHelper: SQLCipherOpenHelper) = SmsDatabase(context, openHelper) + + @Provides + @Singleton + fun provideMmsDatabase(@ApplicationContext context: Context, openHelper: SQLCipherOpenHelper) = MmsDatabase(context, openHelper) + + @Provides + @Singleton + fun provideAttachmentDatabase(@ApplicationContext context: Context, + openHelper: SQLCipherOpenHelper, + attachmentSecret: AttachmentSecret) = AttachmentDatabase(context, openHelper, attachmentSecret) + @Provides + @Singleton + fun provideMediaDatbase(@ApplicationContext context: Context, openHelper: SQLCipherOpenHelper) = MediaDatabase(context, openHelper) + + @Provides + @Singleton + fun provideThread(@ApplicationContext context: Context, openHelper: SQLCipherOpenHelper) = ThreadDatabase(context,openHelper) + + @Provides + @Singleton + fun provideMmsSms(@ApplicationContext context: Context, openHelper: SQLCipherOpenHelper) = MmsSmsDatabase(context, openHelper) + + @Provides + @Singleton + fun provideDraftDatabase(@ApplicationContext context: Context, openHelper: SQLCipherOpenHelper) = DraftDatabase(context, openHelper) + + @Provides + @Singleton + fun providePushDatabase(@ApplicationContext context: Context, openHelper: SQLCipherOpenHelper) = PushDatabase(context,openHelper) + + @Provides + @Singleton + fun provideGroupDatabase(@ApplicationContext context: Context, openHelper: SQLCipherOpenHelper) = GroupDatabase(context,openHelper) + + @Provides + @Singleton + fun provideRecipientDatabase(@ApplicationContext context: Context, openHelper: SQLCipherOpenHelper) = RecipientDatabase(context,openHelper) + + @Provides + @Singleton + fun provideGroupReceiptDatabase(@ApplicationContext context: Context, openHelper: SQLCipherOpenHelper) = GroupReceiptDatabase(context,openHelper) + + @Provides + @Singleton + fun searchDatabase(@ApplicationContext context: Context, openHelper: SQLCipherOpenHelper) = SearchDatabase(context,openHelper) + + @Provides + @Singleton + fun provideJobDatabase(@ApplicationContext context: Context, openHelper: SQLCipherOpenHelper) = JobDatabase(context, openHelper) + + @Provides + @Singleton + fun provideLokiApiDatabase(@ApplicationContext context: Context, openHelper: SQLCipherOpenHelper) = LokiAPIDatabase(context,openHelper) + + @Provides + @Singleton + fun provideLokiMessageDatabase(@ApplicationContext context: Context, openHelper: SQLCipherOpenHelper) = LokiMessageDatabase(context,openHelper) + + @Provides + @Singleton + fun provideLokiThreadDatabase(@ApplicationContext context: Context, openHelper: SQLCipherOpenHelper) = LokiThreadDatabase(context,openHelper) + + @Provides + @Singleton + fun provideLokiUserDatabase(@ApplicationContext context: Context, openHelper: SQLCipherOpenHelper) = LokiUserDatabase(context,openHelper) + + @Provides + @Singleton + fun provideLokiBackupFilesDatabase(@ApplicationContext context: Context, openHelper: SQLCipherOpenHelper) = LokiBackupFilesDatabase(context,openHelper) + + @Provides + @Singleton + fun provideSessionJobDatabase(@ApplicationContext context: Context, openHelper: SQLCipherOpenHelper) = SessionJobDatabase(context, openHelper) + + @Provides + @Singleton + fun provideSessionContactDatabase(@ApplicationContext context: Context, openHelper: SQLCipherOpenHelper) = SessionContactDatabase(context,openHelper) + + @Provides + @Singleton + fun provideStorage(@ApplicationContext context: Context, openHelper: SQLCipherOpenHelper) = Storage(context,openHelper) + + @Provides + @Singleton + fun provideAttachmentProvider(@ApplicationContext context: Context, openHelper: SQLCipherOpenHelper): MessageDataProvider = DatabaseAttachmentProvider(context, openHelper) + +} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/SignalCommunicationModule.java b/app/src/main/java/org/thoughtcrime/securesms/dependencies/SignalCommunicationModule.java deleted file mode 100644 index 00167232b..000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/SignalCommunicationModule.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.thoughtcrime.securesms.dependencies; - -import android.content.Context; - -import org.thoughtcrime.securesms.jobs.AvatarDownloadJob; -import org.thoughtcrime.securesms.jobs.RetrieveProfileAvatarJob; -import org.thoughtcrime.securesms.linkpreview.LinkPreviewRepository; -import org.thoughtcrime.securesms.preferences.AppProtectionPreferenceFragment; - -import dagger.Module; - -@Module(complete = false, injects = {AvatarDownloadJob.class, - RetrieveProfileAvatarJob.class, - AppProtectionPreferenceFragment.class, - LinkPreviewRepository.class}) - -public class SignalCommunicationModule { - - private final Context context; - - public SignalCommunicationModule(Context context) { - this.context = context; - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/dms/CreatePrivateChatActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/dms/CreatePrivateChatActivity.kt index b374420d9..c1971fa05 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dms/CreatePrivateChatActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/dms/CreatePrivateChatActivity.kt @@ -29,7 +29,7 @@ import org.session.libsignal.utilities.PublicKeyValidation import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2 -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.util.ScanQRCodeWrapperFragment import org.thoughtcrime.securesms.util.ScanQRCodeWrapperFragmentDelegate @@ -113,7 +113,7 @@ class CreatePrivateChatActivity : PassphraseRequiredActionBarActivity(), ScanQRC val intent = Intent(this, ConversationActivityV2::class.java) intent.putExtra(ConversationActivityV2.ADDRESS, recipient.address) intent.setDataAndType(getIntent().data, getIntent().type) - val existingThread = DatabaseFactory.getThreadDatabase(this).getThreadIdIfExistsFor(recipient) + val existingThread = DatabaseComponent.get(this).threadDatabase().getThreadIdIfExistsFor(recipient) intent.putExtra(ConversationActivityV2.THREAD_ID, existingThread) startActivity(intent) finish() diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/CreateClosedGroupActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/groups/CreateClosedGroupActivity.kt index e8ab3c633..85c0bd3dd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/CreateClosedGroupActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/CreateClosedGroupActivity.kt @@ -3,31 +3,30 @@ package org.thoughtcrime.securesms.groups import android.content.Context import android.content.Intent import android.os.Bundle -import androidx.loader.app.LoaderManager -import androidx.loader.content.Loader -import androidx.recyclerview.widget.LinearLayoutManager import android.view.Menu import android.view.MenuItem import android.view.View import android.widget.Toast +import androidx.loader.app.LoaderManager +import androidx.loader.content.Loader +import androidx.recyclerview.widget.LinearLayoutManager import kotlinx.android.synthetic.main.activity_create_closed_group.* import network.loki.messenger.R import nl.komponents.kovenant.ui.failUi import nl.komponents.kovenant.ui.successUi import org.session.libsession.messaging.sending_receiving.MessageSender import org.session.libsession.messaging.sending_receiving.groupSizeLimit -import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity - import org.session.libsession.utilities.Address -import org.thoughtcrime.securesms.database.DatabaseFactory -import org.thoughtcrime.securesms.util.fadeIn -import org.thoughtcrime.securesms.util.fadeOut -import org.thoughtcrime.securesms.mms.GlideApp -import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.TextSecurePreferences -import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2 +import org.session.libsession.utilities.recipients.Recipient +import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.contacts.SelectContactsAdapter import org.thoughtcrime.securesms.contacts.SelectContactsLoader +import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2 +import org.thoughtcrime.securesms.dependencies.DatabaseComponent +import org.thoughtcrime.securesms.mms.GlideApp +import org.thoughtcrime.securesms.util.fadeIn +import org.thoughtcrime.securesms.util.fadeOut //TODO Refactor to avoid using kotlinx.android.synthetic class CreateClosedGroupActivity : PassphraseRequiredActionBarActivity(), LoaderManager.LoaderCallbacks> { @@ -121,7 +120,7 @@ class CreateClosedGroupActivity : PassphraseRequiredActionBarActivity(), LoaderM MessageSender.createClosedGroup(name.toString(), selectedMembers + setOf( userPublicKey )).successUi { groupID -> loaderContainer.fadeOut() isLoading = false - val threadID = DatabaseFactory.getThreadDatabase(this).getOrCreateThreadIdFor(Recipient.from(this, Address.fromSerialized(groupID), false)) + val threadID = DatabaseComponent.get(this).threadDatabase().getOrCreateThreadIdFor(Recipient.from(this, Address.fromSerialized(groupID), false)) if (!isFinishing) { openConversationActivity(this, threadID, Recipient.from(this, Address.fromSerialized(groupID), false)) finish() diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/EditClosedGroupActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/groups/EditClosedGroupActivity.kt index 6f5364419..5ffe42492 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/EditClosedGroupActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/EditClosedGroupActivity.kt @@ -21,18 +21,18 @@ import nl.komponents.kovenant.ui.failUi import nl.komponents.kovenant.ui.successUi import org.session.libsession.messaging.sending_receiving.MessageSender import org.session.libsession.messaging.sending_receiving.groupSizeLimit -import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.session.libsession.utilities.Address -import org.thoughtcrime.securesms.database.DatabaseFactory -import org.thoughtcrime.securesms.util.fadeIn -import org.thoughtcrime.securesms.util.fadeOut -import org.thoughtcrime.securesms.mms.GlideApp -import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.GroupUtil import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.ThemeUtil +import org.session.libsession.utilities.recipients.Recipient import org.session.libsignal.utilities.toHexString +import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.contacts.SelectContactsActivity +import org.thoughtcrime.securesms.dependencies.DatabaseComponent +import org.thoughtcrime.securesms.mms.GlideApp +import org.thoughtcrime.securesms.util.fadeIn +import org.thoughtcrime.securesms.util.fadeOut import java.io.IOException class EditClosedGroupActivity : PassphraseRequiredActionBarActivity() { @@ -90,7 +90,7 @@ class EditClosedGroupActivity : PassphraseRequiredActionBarActivity() { ThemeUtil.getThemedDrawableResId(this, R.attr.actionModeCloseDrawable)) groupID = intent.getStringExtra(groupIDKey)!! - val groupInfo = DatabaseFactory.getGroupDatabase(this).getGroup(groupID).get() + val groupInfo = DatabaseComponent.get(this).groupDatabase().getGroup(groupID).get() originalName = groupInfo.title isSelfAdmin = groupInfo.admins.any{ it.serialize() == TextSecurePreferences.getLocalNumber(this) } @@ -260,7 +260,7 @@ class EditClosedGroupActivity : PassphraseRequiredActionBarActivity() { var groupPublicKey: String? try { groupPublicKey = GroupUtil.doubleDecodeGroupID(groupID).toHexString() - isClosedGroup = DatabaseFactory.getLokiAPIDatabase(this).isClosedGroup(groupPublicKey) + isClosedGroup = DatabaseComponent.get(this).lokiAPIDatabase().isClosedGroup(groupPublicKey) } catch (e: IOException) { groupPublicKey = null isClosedGroup = false diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/EditClosedGroupLoader.kt b/app/src/main/java/org/thoughtcrime/securesms/groups/EditClosedGroupLoader.kt index 5360f4261..b1e0b5e1d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/EditClosedGroupLoader.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/EditClosedGroupLoader.kt @@ -1,13 +1,13 @@ package org.thoughtcrime.securesms.groups import android.content.Context -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.util.AsyncLoader class EditClosedGroupLoader(context: Context, val groupID: String) : AsyncLoader(context) { override fun loadInBackground(): EditClosedGroupActivity.GroupMembers { - val groupDatabase = DatabaseFactory.getGroupDatabase(context) + val groupDatabase = DatabaseComponent.get(context).groupDatabase() val members = groupDatabase.getGroupMembers(groupID, true) val zombieMembers = groupDatabase.getGroupZombieMembers(groupID) return EditClosedGroupActivity.GroupMembers( 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 8f09dbbbc..727c0582c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManager.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManager.java @@ -8,13 +8,12 @@ import androidx.annotation.Nullable; import org.session.libsession.utilities.Address; import org.session.libsession.utilities.DistributionTypes; -import org.session.libsession.utilities.recipients.Recipient; import org.session.libsession.utilities.GroupUtil; import org.session.libsession.utilities.TextSecurePreferences; - -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.session.libsession.utilities.recipients.Recipient; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import org.thoughtcrime.securesms.util.BitmapUtil; import java.util.HashSet; @@ -31,7 +30,7 @@ public class GroupManager { public static long getThreadIDFromGroupID(String groupID, @NonNull Context context) { final Recipient groupRecipient = Recipient.from(context, Address.fromSerialized(groupID), false); - return DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(groupRecipient); + return DatabaseComponent.get(context).threadDatabase().getThreadIdIfExistsFor(groupRecipient); } public static @NonNull GroupActionResult createOpenGroup(@NonNull String id, @@ -49,7 +48,7 @@ public class GroupManager { @Nullable String name) { final byte[] avatarBytes = BitmapUtil.toByteArray(avatar); - final GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); + final GroupDatabase groupDatabase = DatabaseComponent.get(context).groupDatabase(); final Recipient groupRecipient = Recipient.from(context, Address.fromSerialized(groupId), false); final Set
memberAddresses = new HashSet<>(); @@ -58,7 +57,7 @@ public class GroupManager { groupDatabase.updateProfilePicture(groupId, avatarBytes); - long threadID = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor( + long threadID = DatabaseComponent.get(context).threadDatabase().getOrCreateThreadIdFor( groupRecipient, DistributionTypes.CONVERSATION); return new GroupActionResult(groupRecipient, threadID); } @@ -66,8 +65,8 @@ public class GroupManager { public static boolean deleteGroup(@NonNull String groupId, @NonNull Context context) { - final GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); - final ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); + final GroupDatabase groupDatabase = DatabaseComponent.get(context).groupDatabase(); + final ThreadDatabase threadDatabase = DatabaseComponent.get(context).threadDatabase(); final Recipient groupRecipient = Recipient.from(context, Address.fromSerialized(groupId), false); long threadId = threadDatabase.getThreadIdIfExistsFor(groupRecipient); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/OpenGroupManager.kt b/app/src/main/java/org/thoughtcrime/securesms/groups/OpenGroupManager.kt index f25e238b0..3545e2fd2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/OpenGroupManager.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/OpenGroupManager.kt @@ -10,7 +10,7 @@ import org.session.libsession.messaging.open_groups.OpenGroupV2 import org.session.libsession.messaging.sending_receiving.pollers.OpenGroupPollerV2 import org.session.libsession.utilities.Util import org.session.libsignal.utilities.ThreadUtils -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.util.BitmapUtil import java.util.concurrent.Executors @@ -59,7 +59,7 @@ object OpenGroupManager { val openGroupID = "$server.$room" var threadID = GroupManager.getOpenGroupThreadID(openGroupID, context) val storage = MessagingModuleConfiguration.shared.storage - val threadDB = DatabaseFactory.getLokiThreadDatabase(context) + val threadDB = DatabaseComponent.get(context).lokiThreadDatabase() // Check it it's added already val existingOpenGroup = threadDB.getOpenGroupChat(threadID) if (existingOpenGroup != null) { return } @@ -97,7 +97,7 @@ object OpenGroupManager { fun delete(server: String, room: String, context: Context) { val storage = MessagingModuleConfiguration.shared.storage - val threadDB = DatabaseFactory.getThreadDatabase(context) + val threadDB = DatabaseComponent.get(context).threadDatabase() val openGroupID = "$server.$room" val threadID = GroupManager.getOpenGroupThreadID(openGroupID, context) val recipient = threadDB.getRecipientForThreadId(threadID) ?: return @@ -112,7 +112,7 @@ object OpenGroupManager { // Delete storage.removeLastDeletionServerID(room, server) storage.removeLastMessageServerID(room, server) - val lokiThreadDB = DatabaseFactory.getLokiThreadDatabase(context) + val lokiThreadDB = DatabaseComponent.get(context).lokiThreadDatabase() lokiThreadDB.removeOpenGroupChat(threadID) ThreadUtils.queue { threadDB.deleteConversation(threadID) // Must be invoked on a background thread diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/OpenGroupUtilities.kt b/app/src/main/java/org/thoughtcrime/securesms/groups/OpenGroupUtilities.kt index 6729b5ca2..ea4dc038a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/OpenGroupUtilities.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/OpenGroupUtilities.kt @@ -4,9 +4,9 @@ import android.content.Context import androidx.annotation.WorkerThread import org.greenrobot.eventbus.EventBus import org.session.libsession.messaging.open_groups.OpenGroupAPIV2 -import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.GroupUtil -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.session.libsession.utilities.recipients.Recipient +import org.thoughtcrime.securesms.dependencies.DatabaseComponent import java.util.* //TODO Refactor so methods declare specific type of checked exceptions and not generalized Exception. @@ -25,7 +25,7 @@ object OpenGroupUtilities { @Throws(Exception::class) fun updateGroupInfo(context: Context, server: String, room: String) { val groupId = GroupUtil.getEncodedOpenGroupID("$server.$room".toByteArray()) - if (!DatabaseFactory.getGroupDatabase(context).hasGroup(groupId)) { + if (!DatabaseComponent.get(context).groupDatabase().hasGroup(groupId)) { throw IllegalStateException("Attempt to update open group info for non-existent DB record: $groupId") } diff --git a/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt index d9886d2c3..6cf4aeafb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt @@ -19,6 +19,7 @@ import androidx.loader.app.LoaderManager import androidx.loader.content.Loader import androidx.localbroadcastmanager.content.LocalBroadcastManager import androidx.recyclerview.widget.LinearLayoutManager +import dagger.hilt.android.AndroidEntryPoint import kotlinx.android.synthetic.main.activity_home.* import kotlinx.android.synthetic.main.seed_reminder_stub.* import kotlinx.android.synthetic.main.seed_reminder_stub.view.* @@ -42,8 +43,11 @@ import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2 import org.thoughtcrime.securesms.conversation.v2.utilities.NotificationUtils import org.thoughtcrime.securesms.crypto.IdentityKeyUtil -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.database.GroupDatabase +import org.thoughtcrime.securesms.database.RecipientDatabase +import org.thoughtcrime.securesms.database.ThreadDatabase import org.thoughtcrime.securesms.database.model.ThreadRecord +import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.dms.CreatePrivateChatActivity import org.thoughtcrime.securesms.groups.CreateClosedGroupActivity import org.thoughtcrime.securesms.groups.JoinPublicChatActivity @@ -56,11 +60,17 @@ import org.thoughtcrime.securesms.preferences.SettingsActivity import org.thoughtcrime.securesms.util.* import java.io.IOException import java.util.* +import javax.inject.Inject +@AndroidEntryPoint class HomeActivity : PassphraseRequiredActionBarActivity(), ConversationClickListener, SeedReminderViewDelegate, NewConversationButtonSetViewDelegate { private lateinit var glide: GlideRequests private var broadcastReceiver: BroadcastReceiver? = null + @Inject lateinit var threadDb: ThreadDatabase + @Inject lateinit var recipientDatabase: RecipientDatabase + @Inject lateinit var groupDatabase: GroupDatabase + private val publicKey: String get() = TextSecurePreferences.getLocalNumber(this)!! @@ -94,7 +104,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), ConversationClickLis seedReminderStub.isVisible = false } // Set up recycler view - val cursor = DatabaseFactory.getThreadDatabase(this).conversationList + val cursor = threadDb.conversationList val homeAdapter = HomeAdapter(this, cursor) homeAdapter.setHasStableIds(true) homeAdapter.glide = glide @@ -280,7 +290,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), ConversationClickLis .setNegativeButton(android.R.string.cancel, null) .setPositiveButton(R.string.RecipientPreferenceActivity_block) { dialog, _ -> ThreadUtils.queue { - DatabaseFactory.getRecipientDatabase(this).setBlocked(thread.recipient, true) + recipientDatabase.setBlocked(thread.recipient, true) Util.runOnMain { recyclerView.adapter!!.notifyDataSetChanged() dialog.dismiss() @@ -296,7 +306,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), ConversationClickLis .setNegativeButton(android.R.string.cancel, null) .setPositiveButton(R.string.RecipientPreferenceActivity_unblock) { dialog, _ -> ThreadUtils.queue { - DatabaseFactory.getRecipientDatabase(this).setBlocked(thread.recipient, false) + recipientDatabase.setBlocked(thread.recipient, false) Util.runOnMain { recyclerView.adapter!!.notifyDataSetChanged() dialog.dismiss() @@ -308,7 +318,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), ConversationClickLis private fun setConversationMuted(thread: ThreadRecord, isMuted: Boolean) { if (!isMuted) { ThreadUtils.queue { - DatabaseFactory.getRecipientDatabase(this).setMuted(thread.recipient, 0) + recipientDatabase.setMuted(thread.recipient, 0) Util.runOnMain { recyclerView.adapter!!.notifyDataSetChanged() } @@ -316,7 +326,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), ConversationClickLis } else { MuteDialog.show(this) { until: Long -> ThreadUtils.queue { - DatabaseFactory.getRecipientDatabase(this).setMuted(thread.recipient, until) + recipientDatabase.setMuted(thread.recipient, until) Util.runOnMain { recyclerView.adapter!!.notifyDataSetChanged() } @@ -327,7 +337,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), ConversationClickLis private fun setNotifyType(thread: ThreadRecord, newNotifyType: Int) { ThreadUtils.queue { - DatabaseFactory.getRecipientDatabase(this).setNotifyType(thread.recipient, newNotifyType) + recipientDatabase.setNotifyType(thread.recipient, newNotifyType) Util.runOnMain { recyclerView.adapter!!.notifyDataSetChanged() } @@ -337,10 +347,9 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), ConversationClickLis private fun deleteConversation(thread: ThreadRecord) { val threadID = thread.threadId val recipient = thread.recipient - val threadDB = DatabaseFactory.getThreadDatabase(this) val message: String if (recipient.isGroupRecipient) { - val group = DatabaseFactory.getGroupDatabase(this).getGroup(recipient.address.toString()).orNull() + val group = groupDatabase.getGroup(recipient.address.toString()).orNull() if (group != null && group.admins.map { it.toString() }.contains(TextSecurePreferences.getLocalNumber(this))) { message = "Because you are the creator of this group it will be deleted for everyone. This cannot be undone." } else { @@ -355,14 +364,14 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), ConversationClickLis lifecycleScope.launch(Dispatchers.Main) { val context = this@HomeActivity as Context // Cancel any outstanding jobs - DatabaseFactory.getSessionJobDatabase(context).cancelPendingMessageSendJobs(threadID) + DatabaseComponent.get(context).sessionJobDatabase().cancelPendingMessageSendJobs(threadID) // Send a leave group message if this is an active closed group - if (recipient.address.isClosedGroup && DatabaseFactory.getGroupDatabase(context).isActive(recipient.address.toGroupString())) { + if (recipient.address.isClosedGroup && DatabaseComponent.get(context).groupDatabase().isActive(recipient.address.toGroupString())) { var isClosedGroup: Boolean var groupPublicKey: String? try { groupPublicKey = GroupUtil.doubleDecodeGroupID(recipient.address.toString()).toHexString() - isClosedGroup = DatabaseFactory.getLokiAPIDatabase(context).isClosedGroup(groupPublicKey) + isClosedGroup = DatabaseComponent.get(context).lokiAPIDatabase().isClosedGroup(groupPublicKey) } catch (e: IOException) { groupPublicKey = null isClosedGroup = false @@ -372,12 +381,12 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), ConversationClickLis } } // Delete the conversation - val v2OpenGroup = DatabaseFactory.getLokiThreadDatabase(context).getOpenGroupChat(threadID) + val v2OpenGroup = DatabaseComponent.get(this@HomeActivity).lokiThreadDatabase().getOpenGroupChat(threadID) if (v2OpenGroup != null) { OpenGroupManager.delete(v2OpenGroup.server, v2OpenGroup.room, this@HomeActivity) } else { ThreadUtils.queue { - threadDB.deleteConversation(threadID) + threadDb.deleteConversation(threadID) } } // Update the badge count diff --git a/app/src/main/java/org/thoughtcrime/securesms/home/HomeAdapter.kt b/app/src/main/java/org/thoughtcrime/securesms/home/HomeAdapter.kt index 11ae410a9..3adf5f7b0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/HomeAdapter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/HomeAdapter.kt @@ -2,15 +2,15 @@ package org.thoughtcrime.securesms.home import android.content.Context import android.database.Cursor -import androidx.recyclerview.widget.RecyclerView import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView import org.thoughtcrime.securesms.database.CursorRecyclerViewAdapter -import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.model.ThreadRecord +import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.mms.GlideRequests class HomeAdapter(context: Context, cursor: Cursor?) : CursorRecyclerViewAdapter(context, cursor) { - private val threadDatabase = DatabaseFactory.getThreadDatabase(context) + private val threadDatabase = DatabaseComponent.get(context).threadDatabase() lateinit var glide: GlideRequests var typingThreadIDs = setOf() set(value) { field = value; notifyDataSetChanged() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/home/HomeLoader.kt b/app/src/main/java/org/thoughtcrime/securesms/home/HomeLoader.kt index 92e1abacb..921ecfffa 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/HomeLoader.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/HomeLoader.kt @@ -2,12 +2,12 @@ package org.thoughtcrime.securesms.home import android.content.Context import android.database.Cursor -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.util.AbstractCursorLoader class HomeLoader(context: Context) : AbstractCursorLoader(context) { override fun getCursor(): Cursor { - return DatabaseFactory.getThreadDatabase(context).conversationList + return DatabaseComponent.get(context).threadDatabase().conversationList } } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/home/UserDetailsBottomSheet.kt b/app/src/main/java/org/thoughtcrime/securesms/home/UserDetailsBottomSheet.kt index f13c2824d..43a9b432d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/UserDetailsBottomSheet.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/UserDetailsBottomSheet.kt @@ -20,7 +20,7 @@ import org.session.libsession.messaging.contacts.Contact import org.session.libsession.utilities.Address import org.session.libsession.utilities.recipients.Recipient import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2 -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.mms.GlideApp import org.thoughtcrime.securesms.util.UiModeUtilities @@ -103,7 +103,7 @@ class UserDetailsBottomSheet : BottomSheetDialogFragment() { newNickName = nicknameEditText.text.toString() } val publicKey = recipient.address.serialize() - val contactDB = DatabaseFactory.getSessionContactDatabase(context) + val contactDB = DatabaseComponent.get(requireContext()).sessionContactDatabase() val contact = contactDB.getContactWithSessionID(publicKey) ?: Contact(publicKey) contact.nickname = newNickName contactDB.setContact(contact) diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobController.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobController.java index c2a8b4f55..33345a03e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobController.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobController.java @@ -1,6 +1,7 @@ package org.thoughtcrime.securesms.jobmanager; import android.app.Application; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; @@ -8,13 +9,13 @@ import androidx.annotation.WorkerThread; import com.annimon.stream.Stream; import org.session.libsession.messaging.utilities.Data; +import org.session.libsession.utilities.Debouncer; +import org.session.libsignal.utilities.Log; import org.thoughtcrime.securesms.jobmanager.persistence.ConstraintSpec; import org.thoughtcrime.securesms.jobmanager.persistence.DependencySpec; import org.thoughtcrime.securesms.jobmanager.persistence.FullSpec; import org.thoughtcrime.securesms.jobmanager.persistence.JobSpec; import org.thoughtcrime.securesms.jobmanager.persistence.JobStorage; -import org.session.libsignal.utilities.Log; -import org.session.libsession.utilities.Debouncer; import java.util.ArrayList; import java.util.Collections; @@ -37,7 +38,6 @@ class JobController { private final JobInstantiator jobInstantiator; private final ConstraintInstantiator constraintInstantiator; private final Data.Serializer dataSerializer; - private final DependencyInjector dependencyInjector; private final Scheduler scheduler; private final Debouncer debouncer; private final Callback callback; @@ -48,7 +48,6 @@ class JobController { @NonNull JobInstantiator jobInstantiator, @NonNull ConstraintInstantiator constraintInstantiator, @NonNull Data.Serializer dataSerializer, - @NonNull DependencyInjector dependencyInjector, @NonNull Scheduler scheduler, @NonNull Debouncer debouncer, @NonNull Callback callback) @@ -58,7 +57,6 @@ class JobController { this.jobInstantiator = jobInstantiator; this.constraintInstantiator = constraintInstantiator; this.dataSerializer = dataSerializer; - this.dependencyInjector = dependencyInjector; this.scheduler = scheduler; this.debouncer = debouncer; this.callback = callback; @@ -329,8 +327,6 @@ class JobController { job.setNextRunAttemptTime(jobSpec.getNextRunAttemptTime()); job.setContext(application); - dependencyInjector.injectDependencies(job); - return job; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobManager.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobManager.java index 49159ef7e..440f37508 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobManager.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobManager.java @@ -3,14 +3,15 @@ package org.thoughtcrime.securesms.jobmanager; import android.app.Application; import android.content.Intent; import android.os.Build; + import androidx.annotation.NonNull; import org.session.libsession.messaging.utilities.Data; +import org.session.libsession.utilities.Debouncer; +import org.session.libsignal.utilities.Log; import org.thoughtcrime.securesms.jobmanager.impl.DefaultExecutorFactory; import org.thoughtcrime.securesms.jobmanager.impl.JsonDataSerializer; import org.thoughtcrime.securesms.jobmanager.persistence.JobStorage; -import org.session.libsignal.utilities.Log; -import org.session.libsession.utilities.Debouncer; import java.util.ArrayList; import java.util.Collections; @@ -45,7 +46,6 @@ public class JobManager implements ConstraintObserver.Notifier { configuration.getJobInstantiator(), configuration.getConstraintFactories(), configuration.getDataSerializer(), - configuration.getDependencyInjector(), Build.VERSION.SDK_INT < 26 ? new AlarmManagerScheduler(application) : new CompositeScheduler(new InAppScheduler(this), new JobSchedulerScheduler(application)), new Debouncer(500), @@ -203,7 +203,6 @@ public class JobManager implements ConstraintObserver.Notifier { private final List constraintObservers; private final Data.Serializer dataSerializer; private final JobStorage jobStorage; - private final DependencyInjector dependencyInjector; private Configuration(int jobThreadCount, @NonNull ExecutorFactory executorFactory, @@ -211,8 +210,7 @@ public class JobManager implements ConstraintObserver.Notifier { @NonNull ConstraintInstantiator constraintInstantiator, @NonNull List constraintObservers, @NonNull Data.Serializer dataSerializer, - @NonNull JobStorage jobStorage, - @NonNull DependencyInjector dependencyInjector) + @NonNull JobStorage jobStorage) { this.executorFactory = executorFactory; this.jobThreadCount = jobThreadCount; @@ -221,7 +219,6 @@ public class JobManager implements ConstraintObserver.Notifier { this.constraintObservers = constraintObservers; this.dataSerializer = dataSerializer; this.jobStorage = jobStorage; - this.dependencyInjector = dependencyInjector; } int getJobThreadCount() { @@ -253,9 +250,6 @@ public class JobManager implements ConstraintObserver.Notifier { return jobStorage; } - @NonNull DependencyInjector getDependencyInjector() { - return dependencyInjector; - } public static class Builder { @@ -266,7 +260,6 @@ public class JobManager implements ConstraintObserver.Notifier { private List constraintObservers = new ArrayList<>(); private Data.Serializer dataSerializer = new JsonDataSerializer(); private JobStorage jobStorage = null; - private DependencyInjector dependencyInjector = o -> { /*noop*/ }; public @NonNull Builder setJobThreadCount(int jobThreadCount) { this.jobThreadCount = jobThreadCount; @@ -303,11 +296,6 @@ public class JobManager implements ConstraintObserver.Notifier { return this; } - public @NonNull Builder setDependencyInjector(@NonNull DependencyInjector dependencyInjector) { - this.dependencyInjector = dependencyInjector; - return this; - } - public @NonNull Configuration build() { return new Configuration(jobThreadCount, executorFactory, @@ -315,8 +303,7 @@ public class JobManager implements ConstraintObserver.Notifier { new ConstraintInstantiator(constraintFactories), new ArrayList<>(constraintObservers), dataSerializer, - jobStorage, - dependencyInjector); + jobStorage); } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/AvatarDownloadJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/AvatarDownloadJob.java index 3cabdce5d..0bf7ea24e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/AvatarDownloadJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/AvatarDownloadJob.java @@ -1,33 +1,33 @@ package org.thoughtcrime.securesms.jobs; import android.graphics.Bitmap; + import androidx.annotation.NonNull; import org.session.libsession.messaging.utilities.Data; import org.session.libsession.utilities.DownloadUtilities; -import org.session.libsignal.streams.AttachmentCipherInputStream; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.GroupDatabase; import org.session.libsession.utilities.GroupRecord; -import org.thoughtcrime.securesms.dependencies.InjectableType; +import org.session.libsignal.exceptions.InvalidMessageException; +import org.session.libsignal.exceptions.NonSuccessfulResponseCodeException; +import org.session.libsignal.messages.SignalServiceAttachmentPointer; +import org.session.libsignal.streams.AttachmentCipherInputStream; +import org.session.libsignal.utilities.Hex; +import org.session.libsignal.utilities.Log; +import org.session.libsignal.utilities.guava.Optional; +import org.thoughtcrime.securesms.database.GroupDatabase; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; -import org.session.libsignal.utilities.Log; import org.thoughtcrime.securesms.mms.AttachmentStreamUriLoader.AttachmentModel; import org.thoughtcrime.securesms.util.BitmapDecodingException; import org.thoughtcrime.securesms.util.BitmapUtil; -import org.session.libsignal.utilities.Hex; -import org.session.libsignal.exceptions.InvalidMessageException; -import org.session.libsignal.utilities.guava.Optional; -import org.session.libsignal.messages.SignalServiceAttachmentPointer; -import org.session.libsignal.exceptions.NonSuccessfulResponseCodeException; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; -public class AvatarDownloadJob extends BaseJob implements InjectableType { +public class AvatarDownloadJob extends BaseJob { public static final String KEY = "AvatarDownloadJob"; @@ -64,7 +64,7 @@ public class AvatarDownloadJob extends BaseJob implements InjectableType { @Override public void onRun() throws IOException { - GroupDatabase database = DatabaseFactory.getGroupDatabase(context); + GroupDatabase database = DatabaseComponent.get(context).groupDatabase(); Optional record = database.getGroup(groupId); File attachment = null; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PrepareAttachmentAudioExtrasJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/PrepareAttachmentAudioExtrasJob.kt index 017c33571..69794d41b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PrepareAttachmentAudioExtrasJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PrepareAttachmentAudioExtrasJob.kt @@ -1,18 +1,18 @@ package org.thoughtcrime.securesms.jobs import android.os.Build -import org.session.libsignal.utilities.Log import org.greenrobot.eventbus.EventBus -import org.session.libsession.messaging.utilities.Data import org.session.libsession.messaging.sending_receiving.attachments.Attachment import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachmentAudioExtras +import org.session.libsession.messaging.utilities.Data import org.session.libsession.utilities.DecodedAudio import org.session.libsession.utilities.InputStreamMediaDataSource -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.session.libsignal.utilities.Log +import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.jobmanager.Job +import org.thoughtcrime.securesms.jobs.PrepareAttachmentAudioExtrasJob.AudioExtrasUpdatedEvent import org.thoughtcrime.securesms.mms.PartAuthority -import java.lang.IllegalStateException import java.util.* import java.util.concurrent.TimeUnit @@ -68,7 +68,7 @@ class PrepareAttachmentAudioExtrasJob : BaseJob { override fun onRun() { Log.v(TAG, "Processing attachment: $attachmentId") - val attachDb = DatabaseFactory.getAttachmentDatabase(context) + val attachDb = DatabaseComponent.get(context).attachmentDatabase() val attachment = attachDb.getAttachment(attachmentId) if (attachment == null) { 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 34a010000..60232a8e8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileAvatarJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileAvatarJob.java @@ -8,16 +8,15 @@ import androidx.annotation.NonNull; import org.session.libsession.avatars.AvatarHelper; import org.session.libsession.messaging.utilities.Data; import org.session.libsession.utilities.Address; -import org.session.libsession.utilities.recipients.Recipient; import org.session.libsession.utilities.DownloadUtilities; import org.session.libsession.utilities.TextSecurePreferences; import org.session.libsession.utilities.Util; -import org.session.libsignal.streams.ProfileCipherInputStream; +import org.session.libsession.utilities.recipients.Recipient; import org.session.libsignal.exceptions.PushNetworkException; +import org.session.libsignal.streams.ProfileCipherInputStream; import org.session.libsignal.utilities.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.RecipientDatabase; -import org.thoughtcrime.securesms.dependencies.InjectableType; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; @@ -29,7 +28,7 @@ import java.io.InputStream; import java.security.SecureRandom; import java.util.concurrent.TimeUnit; -public class RetrieveProfileAvatarJob extends BaseJob implements InjectableType { +public class RetrieveProfileAvatarJob extends BaseJob { public static final String KEY = "RetrieveProfileAvatarJob"; @@ -77,7 +76,7 @@ public class RetrieveProfileAvatarJob extends BaseJob implements InjectableType @Override public void onRun() throws IOException { - RecipientDatabase database = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase database = DatabaseComponent.get(context).recipientDatabase(); byte[] profileKey = recipient.resolve().getProfileKey(); if (profileKey == null) { 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 45f037d45..9e946f7a7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/TrimThreadJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/TrimThreadJob.java @@ -19,11 +19,10 @@ package org.thoughtcrime.securesms.jobs; import androidx.annotation.NonNull; import org.session.libsession.messaging.utilities.Data; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.session.libsignal.utilities.Log; - import org.session.libsession.utilities.TextSecurePreferences; +import org.session.libsignal.utilities.Log; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; +import org.thoughtcrime.securesms.jobmanager.Job; public class TrimThreadJob extends BaseJob { @@ -63,7 +62,7 @@ public class TrimThreadJob extends BaseJob { if (!trimmingEnabled) return; - DatabaseFactory.getThreadDatabase(context).trimThread(threadId, threadLengthLimit); + DatabaseComponent.get(context).threadDatabase().trimThread(threadId, threadLengthLimit); } @Override 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 dd2bd7735..0b9a37971 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java @@ -4,42 +4,38 @@ import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.google.android.gms.common.util.IOUtils; +import org.session.libsession.messaging.sending_receiving.attachments.Attachment; import org.session.libsession.messaging.sending_receiving.attachments.AttachmentTransferProgress; +import org.session.libsession.messaging.sending_receiving.attachments.UriAttachment; +import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview; import org.session.libsession.utilities.MediaTypes; -import org.thoughtcrime.securesms.ApplicationContext; -import org.thoughtcrime.securesms.dependencies.InjectableType; +import org.session.libsession.utilities.concurrent.SignalExecutors; import org.session.libsignal.utilities.Log; +import org.session.libsignal.utilities.guava.Optional; +import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil.OpenGraph; import org.thoughtcrime.securesms.net.CallRequestController; import org.thoughtcrime.securesms.net.CompositeRequestController; import org.thoughtcrime.securesms.net.ContentProxySafetyInterceptor; import org.thoughtcrime.securesms.net.RequestController; import org.thoughtcrime.securesms.providers.BlobProvider; -import org.session.libsignal.utilities.guava.Optional; -import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil.OpenGraph; - -import org.session.libsession.messaging.sending_receiving.attachments.Attachment; -import org.session.libsession.messaging.sending_receiving.attachments.UriAttachment; -import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview; -import org.session.libsession.utilities.concurrent.SignalExecutors; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import javax.inject.Inject; - import okhttp3.CacheControl; import okhttp3.Call; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; -public class LinkPreviewRepository implements InjectableType { +public class LinkPreviewRepository { private static final String TAG = LinkPreviewRepository.class.getSimpleName(); @@ -52,8 +48,6 @@ public class LinkPreviewRepository implements InjectableType { .addNetworkInterceptor(new ContentProxySafetyInterceptor()) .cache(null) .build(); - - ApplicationContext.getInstance(context).injectDependencies(this); } RequestController getLinkPreview(@NonNull Context context, @NonNull String url, @NonNull Callback> callback) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/logging/LogFile.java b/app/src/main/java/org/thoughtcrime/securesms/logging/LogFile.java index 64702cc98..f0c083ca1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/logging/LogFile.java +++ b/app/src/main/java/org/thoughtcrime/securesms/logging/LogFile.java @@ -123,7 +123,7 @@ class LogFile { return builder.toString(); } - private String readEntry() throws IOException { + String readEntry() throws IOException { try { Util.readFully(inputStream, ivBuffer); Util.readFully(inputStream, intBuffer); diff --git a/app/src/main/java/org/thoughtcrime/securesms/logging/PersistentLogger.java b/app/src/main/java/org/thoughtcrime/securesms/logging/PersistentLogger.java new file mode 100644 index 000000000..9fd5968f6 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/logging/PersistentLogger.java @@ -0,0 +1,250 @@ +package org.thoughtcrime.securesms.logging; + +import android.content.Context; + +import androidx.annotation.AnyThread; +import androidx.annotation.WorkerThread; + +import org.session.libsignal.utilities.ListenableFuture; +import org.session.libsignal.utilities.Log; +import org.session.libsignal.utilities.NoExternalStorageException; +import org.session.libsignal.utilities.SettableFuture; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.PrintStream; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; + +public class PersistentLogger extends Log.Logger { + + private static final String TAG = PersistentLogger.class.getSimpleName(); + + private static final String LOG_V = "V"; + private static final String LOG_D = "D"; + private static final String LOG_I = "I"; + private static final String LOG_W = "W"; + private static final String LOG_E = "E"; + private static final String LOG_WTF = "A"; + + private static final String LOG_DIRECTORY = "log"; + private static final String FILENAME_PREFIX = "log-"; + private static final int MAX_LOG_FILES = 5; + private static final int MAX_LOG_SIZE = 300 * 1024; + private static final int MAX_LOG_EXPORT = 10_000; + private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS zzz"); + + private final Context context; + private final Executor executor; + private final byte[] secret; + + private LogFile.Writer writer; + + public PersistentLogger(Context context) { + this.context = context.getApplicationContext(); + this.secret = LogSecretProvider.getOrCreateAttachmentSecret(context); + this.executor = Executors.newSingleThreadExecutor(r -> { + Thread thread = new Thread(r, "PersistentLogger"); + thread.setPriority(Thread.MIN_PRIORITY); + return thread; + }); + + executor.execute(this::initializeWriter); + } + + @Override + public void v(String tag, String message, Throwable t) { + write(LOG_V, tag, message, t); + } + + @Override + public void d(String tag, String message, Throwable t) { + write(LOG_D, tag, message, t); + } + + @Override + public void i(String tag, String message, Throwable t) { + write(LOG_I, tag, message, t); + } + + @Override + public void w(String tag, String message, Throwable t) { + write(LOG_W, tag, message, t); + } + + @Override + public void e(String tag, String message, Throwable t) { + write(LOG_E, tag, message, t); + } + + @Override + public void wtf(String tag, String message, Throwable t) { + write(LOG_WTF, tag, message, t); + } + + @Override + public void blockUntilAllWritesFinished() { + CountDownLatch latch = new CountDownLatch(1); + + executor.execute(latch::countDown); + + try { + latch.await(); + } catch (InterruptedException e) { + android.util.Log.w(TAG, "Failed to wait for all writes."); + } + } + + @WorkerThread + public ListenableFuture getLogs() { + final SettableFuture future = new SettableFuture<>(); + + executor.execute(() -> { + StringBuilder builder = new StringBuilder(); + long entriesWritten = 0; + + try { + File[] logs = getSortedLogFiles(); + for (int i = logs.length - 1; i >= 0 && entriesWritten <= MAX_LOG_EXPORT; i--) { + try { + LogFile.Reader reader = new LogFile.Reader(secret, logs[i]); + String entry; + while ((entry = reader.readEntry()) != null) { + entriesWritten++; + builder.append(entry).append('\n'); + } + } catch (IOException e) { + android.util.Log.w(TAG, "Failed to read log at index " + i + ". Removing reference."); + logs[i].delete(); + } + } + + future.set(builder.toString()); + } catch (NoExternalStorageException e) { + future.setException(e); + } + }); + + return future; + } + + @WorkerThread + private void initializeWriter() { + try { + writer = new LogFile.Writer(secret, getOrCreateActiveLogFile()); + } catch (NoExternalStorageException | IOException e) { + android.util.Log.e(TAG, "Failed to initialize writer.", e); + } + } + + @AnyThread + private void write(String level, String tag, String message, Throwable t) { + executor.execute(() -> { + try { + if (writer == null) { + return; + } + + if (writer.getLogSize() >= MAX_LOG_SIZE) { + writer.close(); + writer = new LogFile.Writer(secret, createNewLogFile()); + trimLogFilesOverMax(); + } + + for (String entry : buildLogEntries(level, tag, message, t)) { + writer.writeEntry(entry); + } + + } catch (NoExternalStorageException e) { + android.util.Log.w(TAG, "Cannot persist logs.", e); + } catch (IOException e) { + android.util.Log.w(TAG, "Failed to write line. Deleting all logs and starting over."); + deleteAllLogs(); + initializeWriter(); + } + }); + } + + private void trimLogFilesOverMax() throws NoExternalStorageException { + File[] logs = getSortedLogFiles(); + if (logs.length > MAX_LOG_FILES) { + for (int i = MAX_LOG_FILES; i < logs.length; i++) { + logs[i].delete(); + } + } + } + + private void deleteAllLogs() { + try { + File[] logs = getSortedLogFiles(); + for (File log : logs) { + log.delete(); + } + } catch (NoExternalStorageException e) { + android.util.Log.w(TAG, "Was unable to delete logs.", e); + } + } + + private File getOrCreateActiveLogFile() throws NoExternalStorageException { + File[] logs = getSortedLogFiles(); + if (logs.length > 0) { + return logs[0]; + } + + return createNewLogFile(); + } + + private File createNewLogFile() throws NoExternalStorageException { + return new File(getOrCreateLogDirectory(), FILENAME_PREFIX + System.currentTimeMillis()); + } + + private File[] getSortedLogFiles() throws NoExternalStorageException { + File[] logs = getOrCreateLogDirectory().listFiles(); + if (logs != null) { + Arrays.sort(logs, (o1, o2) -> o2.getName().compareTo(o1.getName())); + return logs; + } + return new File[0]; + } + + private File getOrCreateLogDirectory() throws NoExternalStorageException { + File logDir = new File(context.getCacheDir(), LOG_DIRECTORY); + if (!logDir.exists() && !logDir.mkdir()) { + throw new NoExternalStorageException("Unable to create log directory."); + } + + return logDir; + } + + private List buildLogEntries(String level, String tag, String message, Throwable t) { + List entries = new LinkedList<>(); + Date date = new Date(); + + entries.add(buildEntry(level, tag, message, date)); + + if (t != null) { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + t.printStackTrace(new PrintStream(outputStream)); + + String trace = new String(outputStream.toByteArray()); + String[] lines = trace.split("\\n"); + + for (String line : lines) { + entries.add(buildEntry(level, tag, line, date)); + } + } + + return entries; + } + + private String buildEntry(String level, String tag, String message, Date date) { + return DATE_FORMAT.format(date) + ' ' + level + ' ' + tag + ": " + message; + } +} 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 43896d904..4f3e1e6ec 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/longmessage/LongMessageRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/longmessage/LongMessageRepository.java @@ -3,20 +3,21 @@ package org.thoughtcrime.securesms.longmessage; import android.content.Context; import android.database.Cursor; import android.net.Uri; + import androidx.annotation.NonNull; import androidx.annotation.WorkerThread; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.session.libsession.utilities.Util; +import org.session.libsession.utilities.concurrent.SignalExecutors; +import org.session.libsignal.utilities.Log; +import org.session.libsignal.utilities.guava.Optional; import org.thoughtcrime.securesms.database.MmsDatabase; import org.thoughtcrime.securesms.database.SmsDatabase; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.database.model.MmsMessageRecord; -import org.session.libsignal.utilities.Log; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import org.thoughtcrime.securesms.mms.PartAuthority; import org.thoughtcrime.securesms.mms.TextSlide; -import org.session.libsession.utilities.Util; -import org.session.libsession.utilities.concurrent.SignalExecutors; -import org.session.libsignal.utilities.guava.Optional; import java.io.IOException; import java.io.InputStream; @@ -29,8 +30,8 @@ class LongMessageRepository { private final SmsDatabase smsDatabase; LongMessageRepository(@NonNull Context context) { - this.mmsDatabase = DatabaseFactory.getMmsDatabase(context); - this.smsDatabase = DatabaseFactory.getSmsDatabase(context); + this.mmsDatabase = DatabaseComponent.get(context).mmsDatabase(); + this.smsDatabase = DatabaseComponent.get(context).smsDatabase(); } void getMessage(@NonNull Context context, long messageId, boolean isMms, @NonNull Callback> callback) { 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 78397b47c..a6de8db41 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mms/PartAuthority.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mms/PartAuthority.java @@ -4,12 +4,13 @@ import android.content.ContentUris; import android.content.Context; import android.content.UriMatcher; import android.net.Uri; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import org.session.libsession.messaging.sending_receiving.attachments.Attachment; import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import org.thoughtcrime.securesms.providers.BlobProvider; import org.thoughtcrime.securesms.providers.PartProvider; @@ -47,8 +48,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 THUMB_ROW: return DatabaseFactory.getAttachmentDatabase(context).getThumbnailStream(new PartUriParser(uri).getPartId()); + case PART_ROW: return DatabaseComponent.get(context).attachmentDatabase().getAttachmentStream(new PartUriParser(uri).getPartId(), 0); + case THUMB_ROW: return DatabaseComponent.get(context).attachmentDatabase().getThumbnailStream(new PartUriParser(uri).getPartId()); case BLOB_ROW: return BlobProvider.getInstance().getStream(context, uri); default: return context.getContentResolver().openInputStream(uri); } @@ -63,7 +64,7 @@ public class PartAuthority { switch (match) { case THUMB_ROW: case PART_ROW: - Attachment attachment = DatabaseFactory.getAttachmentDatabase(context).getAttachment(new PartUriParser(uri).getPartId()); + Attachment attachment = DatabaseComponent.get(context).attachmentDatabase().getAttachment(new PartUriParser(uri).getPartId()); if (attachment != null) return attachment.getFileName(); else return null; @@ -80,7 +81,7 @@ public class PartAuthority { switch (match) { case THUMB_ROW: case PART_ROW: - Attachment attachment = DatabaseFactory.getAttachmentDatabase(context).getAttachment(new PartUriParser(uri).getPartId()); + Attachment attachment = DatabaseComponent.get(context).attachmentDatabase().getAttachment(new PartUriParser(uri).getPartId()); if (attachment != null) return attachment.getSize(); else return null; @@ -97,7 +98,7 @@ public class PartAuthority { switch (match) { case THUMB_ROW: case PART_ROW: - Attachment attachment = DatabaseFactory.getAttachmentDatabase(context).getAttachment(new PartUriParser(uri).getPartId()); + Attachment attachment = DatabaseComponent.get(context).attachmentDatabase().getAttachment(new PartUriParser(uri).getPartId()); if (attachment != null) return attachment.getContentType(); else return null; diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/AndroidAutoHeardReceiver.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/AndroidAutoHeardReceiver.java index ffe6df439..21157d0f5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/AndroidAutoHeardReceiver.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/AndroidAutoHeardReceiver.java @@ -22,12 +22,13 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.AsyncTask; + import androidx.core.app.NotificationManagerCompat; -import org.thoughtcrime.securesms.ApplicationContext; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo; import org.session.libsignal.utilities.Log; +import org.thoughtcrime.securesms.ApplicationContext; +import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import java.util.LinkedList; import java.util.List; @@ -62,7 +63,7 @@ public class AndroidAutoHeardReceiver extends BroadcastReceiver { for (long threadId : threadIds) { Log.i(TAG, "Marking meassage as read: " + threadId); - List messageIds = DatabaseFactory.getThreadDatabase(context).setRead(threadId, true); + List messageIds = DatabaseComponent.get(context).threadDatabase().setRead(threadId, true); messageIdsCollection.addAll(messageIds); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/AndroidAutoReplyReceiver.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/AndroidAutoReplyReceiver.java index d76071399..3ec26f33c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/AndroidAutoReplyReceiver.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/AndroidAutoReplyReceiver.java @@ -23,19 +23,20 @@ import android.content.Context; import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; + import androidx.core.app.RemoteInput; +import org.session.libsession.messaging.messages.signal.OutgoingMediaMessage; +import org.session.libsession.messaging.messages.signal.OutgoingTextMessage; import org.session.libsession.messaging.messages.visible.VisibleMessage; import org.session.libsession.messaging.sending_receiving.MessageSender; -import org.thoughtcrime.securesms.ApplicationContext; import org.session.libsession.utilities.Address; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo; -import org.thoughtcrime.securesms.mms.MmsException; -import org.session.libsession.messaging.messages.signal.OutgoingMediaMessage; import org.session.libsession.utilities.recipients.Recipient; -import org.session.libsession.messaging.messages.signal.OutgoingTextMessage; import org.session.libsignal.utilities.Log; +import org.thoughtcrime.securesms.ApplicationContext; +import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; +import org.thoughtcrime.securesms.mms.MmsException; import java.util.Collections; import java.util.List; @@ -74,7 +75,7 @@ public class AndroidAutoReplyReceiver extends BroadcastReceiver { long replyThreadId; if (threadId == -1) { - replyThreadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient); + replyThreadId = DatabaseComponent.get(context).threadDatabase().getOrCreateThreadIdFor(recipient); } else { replyThreadId = threadId; } @@ -88,17 +89,17 @@ public class AndroidAutoReplyReceiver extends BroadcastReceiver { Log.w("AndroidAutoReplyReceiver", "GroupRecipient, Sending media message"); OutgoingMediaMessage reply = OutgoingMediaMessage.from(message, recipient, Collections.emptyList(), null, null); try { - DatabaseFactory.getMmsDatabase(context).insertMessageOutbox(reply, replyThreadId, false, null); + DatabaseComponent.get(context).mmsDatabase().insertMessageOutbox(reply, replyThreadId, false, null); } catch (MmsException e) { Log.w(TAG, e); } } else { Log.w("AndroidAutoReplyReceiver", "Sending regular message "); OutgoingTextMessage reply = OutgoingTextMessage.from(message, recipient); - DatabaseFactory.getSmsDatabase(context).insertMessageOutbox(replyThreadId, reply, false, System.currentTimeMillis(), null); + DatabaseComponent.get(context).smsDatabase().insertMessageOutbox(replyThreadId, reply, false, System.currentTimeMillis(), null); } - List messageIds = DatabaseFactory.getThreadDatabase(context).setRead(replyThreadId, true); + List messageIds = DatabaseComponent.get(context).threadDatabase().setRead(replyThreadId, true); ApplicationContext.getInstance(context).messageNotifier.updateNotification(context); MarkReadReceiver.process(context, messageIds); diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/BackgroundPollWorker.kt b/app/src/main/java/org/thoughtcrime/securesms/notifications/BackgroundPollWorker.kt index d6b126752..22a3e037b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/BackgroundPollWorker.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/BackgroundPollWorker.kt @@ -14,7 +14,7 @@ import org.session.libsession.messaging.sending_receiving.pollers.OpenGroupPolle import org.session.libsession.snode.SnodeAPI import org.session.libsession.utilities.TextSecurePreferences import org.session.libsignal.utilities.Log -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.dependencies.DatabaseComponent import java.util.concurrent.TimeUnit class BackgroundPollWorker(val context: Context, params: WorkerParameters) : Worker(context, params) { @@ -63,7 +63,7 @@ class BackgroundPollWorker(val context: Context, params: WorkerParameters) : Wor allGroupPublicKeys.forEach { closedGroupPoller.poll(it) } // Open Groups - val threadDB = DatabaseFactory.getLokiThreadDatabase(context) + val threadDB = DatabaseComponent.get(context).lokiThreadDatabase() val v2OpenGroups = threadDB.getAllV2OpenGroups() val v2OpenGroupServers = v2OpenGroups.map { it.value.server }.toSet() diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java index 936548ecc..eeffdd834 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java @@ -52,7 +52,6 @@ import org.thoughtcrime.securesms.contactshare.ContactUtil; import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2; import org.thoughtcrime.securesms.conversation.v2.utilities.MentionManagerUtilities; import org.thoughtcrime.securesms.conversation.v2.utilities.MentionUtilities; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo; import org.thoughtcrime.securesms.database.MmsSmsDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase; @@ -61,6 +60,7 @@ import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.database.model.MmsMessageRecord; import org.thoughtcrime.securesms.database.model.Quote; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import org.thoughtcrime.securesms.mms.SlideDeck; import org.thoughtcrime.securesms.service.KeyCachingService; import org.thoughtcrime.securesms.util.SessionMetaProtocol; @@ -97,7 +97,7 @@ public class DefaultMessageNotifier implements MessageNotifier { private static final int SUMMARY_NOTIFICATION_ID = 1338; private static final int PENDING_MESSAGES_ID = 1111; private static final String NOTIFICATION_GROUP = "messages"; - private static final long MIN_AUDIBLE_PERIOD_MILLIS = TimeUnit.SECONDS.toMillis(2); + private static final long MIN_AUDIBLE_PERIOD_MILLIS = TimeUnit.SECONDS.toMillis(5); private static final long DESKTOP_ACTIVITY_PERIOD = TimeUnit.MINUTES.toMillis(1); private volatile static long visibleThread = -1; @@ -228,9 +228,8 @@ public class DefaultMessageNotifier implements MessageNotifier { { boolean isVisible = visibleThread == threadId; - ThreadDatabase threads = DatabaseFactory.getThreadDatabase(context); - Recipient recipients = DatabaseFactory.getThreadDatabase(context) - .getRecipientForThreadId(threadId); + ThreadDatabase threads = DatabaseComponent.get(context).threadDatabase(); + Recipient recipients = threads.getRecipientForThreadId(threadId); if (isVisible && recipients != null) { List messageIds = threads.setRead(threadId, false); @@ -257,8 +256,8 @@ public class DefaultMessageNotifier implements MessageNotifier { Cursor pushCursor = null; try { - telcoCursor = DatabaseFactory.getMmsSmsDatabase(context).getUnread(); - pushCursor = DatabaseFactory.getPushDatabase(context).getPending(); + telcoCursor = DatabaseComponent.get(context).mmsSmsDatabase().getUnread(); + pushCursor = DatabaseComponent.get(context).pushDatabase().getPending(); if (((telcoCursor == null || telcoCursor.isAfterLast()) && (pushCursor == null || pushCursor.isAfterLast())) || !TextSecurePreferences.hasSeenWelcomeScreen(context)) @@ -440,9 +439,12 @@ public class DefaultMessageNotifier implements MessageNotifier { private void sendInThreadNotification(Context context, Recipient recipient) { if (!TextSecurePreferences.isInThreadNotifications(context) || - ServiceUtil.getAudioManager(context).getRingerMode() != AudioManager.RINGER_MODE_NORMAL) + ServiceUtil.getAudioManager(context).getRingerMode() != AudioManager.RINGER_MODE_NORMAL || + (System.currentTimeMillis() - lastAudibleNotification) < MIN_AUDIBLE_PERIOD_MILLIS) { return; + } else { + lastAudibleNotification = System.currentTimeMillis(); } Uri uri = null; @@ -481,7 +483,7 @@ public class DefaultMessageNotifier implements MessageNotifier { @NonNull Cursor cursor) { NotificationState notificationState = new NotificationState(); - MmsSmsDatabase.Reader reader = DatabaseFactory.getMmsSmsDatabase(context).readerFor(cursor); + MmsSmsDatabase.Reader reader = DatabaseComponent.get(context).mmsSmsDatabase().readerFor(cursor); MessageRecord record; @@ -498,7 +500,7 @@ public class DefaultMessageNotifier implements MessageNotifier { if (threadId != -1) { - threadRecipients = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(threadId); + threadRecipients = DatabaseComponent.get(context).threadDatabase().getRecipientForThreadId(threadId); } if (KeyCachingService.isLocked(context)) { 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 ed2727f64..4d32a8cda 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/DeleteNotificationReceiver.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/DeleteNotificationReceiver.java @@ -7,7 +7,7 @@ import android.content.Intent; import android.os.AsyncTask; import org.thoughtcrime.securesms.ApplicationContext; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; public class DeleteNotificationReceiver extends BroadcastReceiver { @@ -30,8 +30,8 @@ public class DeleteNotificationReceiver extends BroadcastReceiver { @Override protected Void doInBackground(Void... params) { for (int i=0;i performOperation(context, ClosedGroupOperation.Unsubscribe, closedGroup, userPublicKey) @@ -84,7 +86,7 @@ object LokiPushNotificationManager { } } // Subscribe to all closed groups - val allClosedGroupPublicKeys = DatabaseFactory.getLokiAPIDatabase(context).getAllClosedGroupPublicKeys() + val allClosedGroupPublicKeys = DatabaseComponent.get(context).lokiAPIDatabase().getAllClosedGroupPublicKeys() allClosedGroupPublicKeys.forEach { closedGroup -> performOperation(context, ClosedGroupOperation.Subscribe, closedGroup, publicKey) } 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 068cbac3e..8ba364b7a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/MarkReadReceiver.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/MarkReadReceiver.java @@ -5,6 +5,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.AsyncTask; + import androidx.annotation.NonNull; import androidx.core.app.NotificationManagerCompat; @@ -13,16 +14,16 @@ import com.annimon.stream.Stream; import org.session.libsession.messaging.messages.control.ReadReceipt; import org.session.libsession.messaging.sending_receiving.MessageSender; -import org.session.libsession.utilities.TextSecurePreferences; -import org.thoughtcrime.securesms.ApplicationContext; import org.session.libsession.utilities.Address; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.session.libsession.utilities.TextSecurePreferences; +import org.session.libsignal.utilities.Log; +import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.database.MessagingDatabase.ExpirationInfo; import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo; import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId; -import org.session.libsignal.utilities.Log; -import org.thoughtcrime.securesms.util.SessionMetaProtocol; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import org.thoughtcrime.securesms.service.ExpiringMessageManager; +import org.thoughtcrime.securesms.util.SessionMetaProtocol; import java.util.LinkedList; import java.util.List; @@ -53,7 +54,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 = DatabaseComponent.get(context).threadDatabase().setRead(threadId, true); messageIdsCollection.addAll(messageIds); } @@ -92,8 +93,8 @@ public class MarkReadReceiver extends BroadcastReceiver { if (expirationInfo.getExpiresIn() > 0 && expirationInfo.getExpireStarted() <= 0) { ExpiringMessageManager expirationManager = ApplicationContext.getInstance(context).getExpiringMessageManager(); - if (expirationInfo.isMms()) DatabaseFactory.getMmsDatabase(context).markExpireStarted(expirationInfo.getId()); - else DatabaseFactory.getSmsDatabase(context).markExpireStarted(expirationInfo.getId()); + if (expirationInfo.isMms()) DatabaseComponent.get(context).mmsDatabase().markExpireStarted(expirationInfo.getId()); + else DatabaseComponent.get(context).smsDatabase().markExpireStarted(expirationInfo.getId()); expirationManager.scheduleDeletion(expirationInfo.getId(), expirationInfo.isMms(), expirationInfo.getExpiresIn()); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/MultipleRecipientNotificationBuilder.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/MultipleRecipientNotificationBuilder.java index 15b62df3c..03da0f378 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/MultipleRecipientNotificationBuilder.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/MultipleRecipientNotificationBuilder.java @@ -15,8 +15,8 @@ import org.session.libsession.utilities.NotificationPrivacyPreference; import org.session.libsession.utilities.TextSecurePreferences; import org.session.libsession.utilities.Util; import org.session.libsession.utilities.recipients.Recipient; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.SessionContactDatabase; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import org.thoughtcrime.securesms.home.HomeActivity; import java.util.LinkedList; @@ -116,7 +116,7 @@ public class MultipleRecipientNotificationBuilder extends AbstractNotificationBu * @param recipient the * individual * recipient for which to get the open group display name. */ private String getOpenGroupDisplayName(Recipient recipient) { - SessionContactDatabase contactDB = DatabaseFactory.getSessionContactDatabase(context); + SessionContactDatabase contactDB = DatabaseComponent.get(context).sessionContactDatabase(); String sessionID = recipient.getAddress().serialize(); Contact contact = contactDB.getContactWithSessionID(sessionID); if (contact == null) { return sessionID; } 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 74cb8dd2b..68b69344b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationChannels.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationChannels.java @@ -12,24 +12,23 @@ import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.provider.Settings; +import android.text.TextUtils; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; -import android.text.TextUtils; import com.annimon.stream.Collectors; import com.annimon.stream.Stream; -import network.loki.messenger.BuildConfig; -import network.loki.messenger.R; import org.session.libsession.utilities.Address; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.RecipientDatabase; -import org.session.libsession.utilities.recipients.Recipient; -import org.session.libsession.utilities.recipients.Recipient.*; import org.session.libsession.utilities.ServiceUtil; import org.session.libsession.utilities.TextSecurePreferences; +import org.session.libsession.utilities.recipients.Recipient; +import org.session.libsession.utilities.recipients.Recipient.VibrateState; import org.session.libsignal.utilities.Log; +import org.thoughtcrime.securesms.database.RecipientDatabase; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import java.util.ArrayList; import java.util.Arrays; @@ -37,6 +36,9 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import network.loki.messenger.BuildConfig; +import network.loki.messenger.R; + public class NotificationChannels { private static final String TAG = NotificationChannels.class.getSimpleName(); @@ -90,7 +92,7 @@ public class NotificationChannels { return; } - RecipientDatabase db = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase db = DatabaseComponent.get(context).recipientDatabase(); try (RecipientDatabase.RecipientReader reader = db.getRecipientsWithNotificationChannels()) { Recipient recipient; @@ -292,7 +294,7 @@ public class NotificationChannels { generateChannelIdFor(recipient.getAddress()), channel -> channel.setSound(uri == null ? Settings.System.DEFAULT_NOTIFICATION_URI : uri, getRingtoneAudioAttributes())); - DatabaseFactory.getRecipientDatabase(context).setNotificationChannel(recipient, success ? newChannelId : null); + DatabaseComponent.get(context).recipientDatabase().setNotificationChannel(recipient, success ? newChannelId : null); ensureCustomChannelConsistency(context); } @@ -359,7 +361,7 @@ public class NotificationChannels { newChannelId, channel -> channel.enableVibration(enabled)); - DatabaseFactory.getRecipientDatabase(context).setNotificationChannel(recipient, success ? newChannelId : null); + DatabaseComponent.get(context).recipientDatabase().setNotificationChannel(recipient, success ? newChannelId : null); ensureCustomChannelConsistency(context); } @@ -391,7 +393,7 @@ public class NotificationChannels { @WorkerThread public static synchronized void ensureCustomChannelConsistency(@NonNull Context context) { NotificationManager notificationManager = ServiceUtil.getNotificationManager(context); - RecipientDatabase db = DatabaseFactory.getRecipientDatabase(context); + RecipientDatabase db = DatabaseComponent.get(context).recipientDatabase(); List customRecipients = new ArrayList<>(); Set customChannelIds = new HashSet<>(); Set existingChannelIds = Stream.of(notificationManager.getNotificationChannels()).map(NotificationChannel::getId).collect(Collectors.toSet()); @@ -503,7 +505,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 = DatabaseComponent.get(context).recipientDatabase(); 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 92ef8fd97..c5dd2b9d5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/RemoteReplyReceiver.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/RemoteReplyReceiver.java @@ -23,19 +23,21 @@ import android.content.Context; import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; + import androidx.core.app.RemoteInput; +import org.session.libsession.messaging.messages.signal.OutgoingMediaMessage; import org.session.libsession.messaging.messages.signal.OutgoingTextMessage; import org.session.libsession.messaging.messages.visible.VisibleMessage; import org.session.libsession.messaging.sending_receiving.MessageSender; +import org.session.libsession.utilities.Address; +import org.session.libsession.utilities.recipients.Recipient; import org.session.libsignal.utilities.Log; import org.thoughtcrime.securesms.ApplicationContext; -import org.session.libsession.utilities.Address; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo; +import org.thoughtcrime.securesms.database.ThreadDatabase; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import org.thoughtcrime.securesms.mms.MmsException; -import org.session.libsession.messaging.messages.signal.OutgoingMediaMessage; -import org.session.libsession.utilities.recipients.Recipient; import java.util.Collections; import java.util.List; @@ -71,7 +73,8 @@ public class RemoteReplyReceiver extends BroadcastReceiver { @Override protected Void doInBackground(Void... params) { Recipient recipient = Recipient.from(context, address, false); - long threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient); + ThreadDatabase threadDatabase = DatabaseComponent.get(context).threadDatabase(); + long threadId = threadDatabase.getOrCreateThreadIdFor(recipient); VisibleMessage message = new VisibleMessage(); message.setSentTimestamp(System.currentTimeMillis()); message.setText(responseText.toString()); @@ -80,7 +83,7 @@ public class RemoteReplyReceiver extends BroadcastReceiver { case GroupMessage: { OutgoingMediaMessage reply = OutgoingMediaMessage.from(message, recipient, Collections.emptyList(), null, null); try { - DatabaseFactory.getMmsDatabase(context).insertMessageOutbox(reply, threadId, false, null); + DatabaseComponent.get(context).mmsDatabase().insertMessageOutbox(reply, threadId, false, null); MessageSender.send(message, address); } catch (MmsException e) { Log.w(TAG, e); @@ -89,7 +92,7 @@ public class RemoteReplyReceiver extends BroadcastReceiver { } case SecureMessage: { OutgoingTextMessage reply = OutgoingTextMessage.from(message, recipient); - DatabaseFactory.getSmsDatabase(context).insertMessageOutbox(threadId, reply, false, System.currentTimeMillis(), null); + DatabaseComponent.get(context).smsDatabase().insertMessageOutbox(threadId, reply, false, System.currentTimeMillis(), null); MessageSender.send(message, address); break; } @@ -97,7 +100,7 @@ public class RemoteReplyReceiver extends BroadcastReceiver { throw new AssertionError("Unknown Reply method"); } - List messageIds = DatabaseFactory.getThreadDatabase(context).setRead(threadId, true); + List messageIds = threadDatabase.setRead(threadId, true); ApplicationContext.getInstance(context).messageNotifier.updateNotification(context); MarkReadReceiver.process(context, messageIds); diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/SingleRecipientNotificationBuilder.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/SingleRecipientNotificationBuilder.java index 7bd4ef499..db93b739a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/SingleRecipientNotificationBuilder.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/SingleRecipientNotificationBuilder.java @@ -34,8 +34,8 @@ import org.session.libsession.utilities.TextSecurePreferences; import org.session.libsession.utilities.Util; import org.session.libsession.utilities.recipients.Recipient; import org.session.libsignal.utilities.Log; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.SessionContactDatabase; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader; import org.thoughtcrime.securesms.mms.GlideApp; import org.thoughtcrime.securesms.mms.Slide; @@ -337,7 +337,7 @@ public class SingleRecipientNotificationBuilder extends AbstractNotificationBuil * @param recipient the * individual * recipient for which to get the open group display name. */ private String getOpenGroupDisplayName(Recipient recipient) { - SessionContactDatabase contactDB = DatabaseFactory.getSessionContactDatabase(context); + SessionContactDatabase contactDB = DatabaseComponent.get(context).sessionContactDatabase(); String sessionID = recipient.getAddress().serialize(); Contact contact = contactDB.getContactWithSessionID(sessionID); if (contact == null) { return sessionID; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/AppProtectionPreferenceFragment.java b/app/src/main/java/org/thoughtcrime/securesms/preferences/AppProtectionPreferenceFragment.java index 409b2bb24..2e9e6b846 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/AppProtectionPreferenceFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/AppProtectionPreferenceFragment.java @@ -7,26 +7,23 @@ import android.content.Intent; import android.os.Bundle; import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; import androidx.preference.Preference; +import org.session.libsession.utilities.TextSecurePreferences; import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.components.SwitchPreferenceCompat; -import org.thoughtcrime.securesms.dependencies.InjectableType; import org.thoughtcrime.securesms.service.KeyCachingService; -import org.session.libsession.utilities.TextSecurePreferences; import java.util.concurrent.TimeUnit; import mobi.upod.timedurationpicker.TimeDurationPickerDialog; import network.loki.messenger.R; -public class AppProtectionPreferenceFragment extends CorrectedPreferenceFragment implements InjectableType { +public class AppProtectionPreferenceFragment extends CorrectedPreferenceFragment { @Override public void onAttach(Activity activity) { super.onAttach(activity); - ApplicationContext.getInstance(activity).injectDependencies(this); } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/QRCodeActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/preferences/QRCodeActivity.kt index 07a1d6059..c21470598 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/QRCodeActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/QRCodeActivity.kt @@ -13,19 +13,14 @@ import androidx.fragment.app.FragmentPagerAdapter import kotlinx.android.synthetic.main.activity_qr_code.* import kotlinx.android.synthetic.main.fragment_view_my_qr_code.* import network.loki.messenger.R -import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity - import org.session.libsession.utilities.Address -import org.thoughtcrime.securesms.database.DatabaseFactory -import org.thoughtcrime.securesms.util.ScanQRCodeWrapperFragment -import org.thoughtcrime.securesms.util.ScanQRCodeWrapperFragmentDelegate -import org.thoughtcrime.securesms.util.QRCodeUtilities -import org.thoughtcrime.securesms.util.toPx -import org.session.libsession.utilities.recipients.Recipient -import org.thoughtcrime.securesms.util.FileProviderUtil import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.recipients.Recipient import org.session.libsignal.utilities.PublicKeyValidation +import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2 +import org.thoughtcrime.securesms.dependencies.DatabaseComponent +import org.thoughtcrime.securesms.util.* import java.io.File import java.io.FileOutputStream @@ -56,7 +51,7 @@ class QRCodeActivity : PassphraseRequiredActionBarActivity(), ScanQRCodeWrapperF val intent = Intent(this, ConversationActivityV2::class.java) intent.putExtra(ConversationActivityV2.ADDRESS, recipient.address) intent.setDataAndType(getIntent().data, getIntent().type) - val existingThread = DatabaseFactory.getThreadDatabase(this).getThreadIdIfExistsFor(recipient) + val existingThread = DatabaseComponent.get(this).threadDatabase().getThreadIdIfExistsFor(recipient) intent.putExtra(ConversationActivityV2.THREAD_ID, existingThread) startActivity(intent) finish() diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/SettingsActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/preferences/SettingsActivity.kt index de059b217..a45efbc29 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/SettingsActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/SettingsActivity.kt @@ -85,6 +85,7 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() { helpTranslateButton.setOnClickListener { helpTranslate() } seedButton.setOnClickListener { showSeed() } clearAllDataButton.setOnClickListener { clearAllData() } + supportButton.setOnClickListener { shareLogs() } val isLightMode = UiModeUtilities.isDayUiMode(this) oxenLogoImageView.setImageResource(if (isLightMode) R.drawable.oxen_light_mode else R.drawable.oxen_dark_mode) versionTextView.text = String.format(getString(R.string.version_s), "${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})") @@ -321,6 +322,10 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() { ClearAllDataDialog().show(supportFragmentManager, "Clear All Data Dialog") } + private fun shareLogs() { + ShareLogsDialog().show(supportFragmentManager,"Share Logs Dialog") + } + // endregion private inner class DisplayNameEditActionModeCallback: ActionMode.Callback { diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/ShareLogsDialog.kt b/app/src/main/java/org/thoughtcrime/securesms/preferences/ShareLogsDialog.kt new file mode 100644 index 000000000..9ff7ebbc4 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/ShareLogsDialog.kt @@ -0,0 +1,65 @@ +package org.thoughtcrime.securesms.preferences + +import android.content.Intent +import android.os.Build +import android.view.LayoutInflater +import android.widget.Toast +import androidx.appcompat.app.AlertDialog +import androidx.lifecycle.lifecycleScope +import kotlinx.android.synthetic.main.dialog_share_logs.view.* +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch +import network.loki.messenger.BuildConfig +import network.loki.messenger.R +import org.thoughtcrime.securesms.ApplicationContext +import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog +import org.thoughtcrime.securesms.providers.BlobProvider + +class ShareLogsDialog : BaseDialog() { + + private var shareJob: Job? = null + + override fun setContentView(builder: AlertDialog.Builder) { + val contentView = + LayoutInflater.from(requireContext()).inflate(R.layout.dialog_share_logs, null) + contentView.cancelButton.setOnClickListener { + dismiss() + } + contentView.shareButton.setOnClickListener { + // start the export and share + shareLogs() + } + builder.setView(contentView) + builder.setCancelable(false) + } + + private fun shareLogs() { + shareJob?.cancel() + shareJob = lifecycleScope.launch(Dispatchers.IO) { + val persistentLogger = ApplicationContext.getInstance(context).persistentLogger + try { + val logs = persistentLogger.logs.get() + val fileName = "${Build.MANUFACTURER}-${Build.DEVICE}-API${Build.VERSION.SDK_INT}-v${BuildConfig.VERSION_NAME}.log" + val logUri = BlobProvider().forData(logs.toByteArray()) + .withFileName(fileName) + .withMimeType("text/plain") + .createForSingleSessionOnDisk(requireContext(),null) + + val shareIntent = Intent().apply { + action = Intent.ACTION_SEND + putExtra(Intent.EXTRA_STREAM, logUri) + type = "text/plain" + } + + dismiss() + + startActivity(Intent.createChooser(shareIntent, getString(R.string.share))) + } catch (e: Exception) { + Toast.makeText(context,"Error saving logs", Toast.LENGTH_LONG).show() + dismiss() + } + } + } + +} \ No newline at end of file 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 f49802073..8c65182f5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/providers/PartProvider.java +++ b/app/src/main/java/org/thoughtcrime/securesms/providers/PartProvider.java @@ -26,15 +26,14 @@ import android.net.Uri; import android.os.MemoryFile; import android.os.ParcelFileDescriptor; import android.provider.OpenableColumns; -import androidx.annotation.NonNull; -import org.session.libsignal.utilities.Log; +import androidx.annotation.NonNull; import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId; import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment; import org.session.libsession.utilities.Util; - -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.session.libsignal.utilities.Log; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import org.thoughtcrime.securesms.mms.PartUriParser; import org.thoughtcrime.securesms.service.KeyCachingService; import org.thoughtcrime.securesms.util.MemoryFileUtil; @@ -107,7 +106,7 @@ public class PartProvider extends ContentProvider { switch (uriMatcher.match(uri)) { case SINGLE_ROW: PartUriParser partUriParser = new PartUriParser(uri); - DatabaseAttachment attachment = DatabaseFactory.getAttachmentDatabase(getContext()) + DatabaseAttachment attachment = DatabaseComponent.get(getContext()).attachmentDatabase() .getAttachment(partUriParser.getPartId()); if (attachment != null) { @@ -133,7 +132,7 @@ public class PartProvider extends ContentProvider { switch (uriMatcher.match(url)) { case SINGLE_ROW: PartUriParser partUri = new PartUriParser(url); - DatabaseAttachment attachment = DatabaseFactory.getAttachmentDatabase(getContext()).getAttachment(partUri.getPartId()); + DatabaseAttachment attachment = DatabaseComponent.get(getContext()).attachmentDatabase().getAttachment(partUri.getPartId()); if (attachment == null) return null; @@ -160,10 +159,10 @@ public class PartProvider extends ContentProvider { } private ParcelFileDescriptor getParcelStreamForAttachment(AttachmentId attachmentId) throws IOException { - long plaintextLength = Util.getStreamLength(DatabaseFactory.getAttachmentDatabase(getContext()).getAttachmentStream(attachmentId, 0)); + long plaintextLength = Util.getStreamLength(DatabaseComponent.get(getContext()).attachmentDatabase().getAttachmentStream(attachmentId, 0)); MemoryFile memoryFile = new MemoryFile(attachmentId.toString(), Util.toIntExact(plaintextLength)); - InputStream in = DatabaseFactory.getAttachmentDatabase(getContext()).getAttachmentStream(attachmentId, 0); + InputStream in = DatabaseComponent.get(getContext()).attachmentDatabase().getAttachmentStream(attachmentId, 0); OutputStream out = memoryFile.getOutputStream(); Util.copy(in, out); diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/DirectShareService.java b/app/src/main/java/org/thoughtcrime/securesms/service/DirectShareService.java index ba8d7078f..13701300b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/DirectShareService.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/DirectShareService.java @@ -11,16 +11,17 @@ import android.os.Bundle; import android.os.Parcel; import android.service.chooser.ChooserTarget; import android.service.chooser.ChooserTargetService; + import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; +import org.session.libsession.utilities.recipients.Recipient; +import org.session.libsignal.utilities.Log; import org.thoughtcrime.securesms.ShareActivity; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.database.model.ThreadRecord; -import org.session.libsignal.utilities.Log; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import org.thoughtcrime.securesms.mms.GlideApp; -import org.session.libsession.utilities.recipients.Recipient; import org.thoughtcrime.securesms.util.BitmapUtil; import java.util.LinkedList; @@ -38,7 +39,7 @@ public class DirectShareService extends ChooserTargetService { { List results = new LinkedList<>(); ComponentName componentName = new ComponentName(this, ShareActivity.class); - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(this); + ThreadDatabase threadDatabase = DatabaseComponent.get(this).threadDatabase(); Cursor cursor = threadDatabase.getDirectShareList(); try { 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 59cd5cc0c..6bf41032b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/ExpiringMessageManager.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/ExpiringMessageManager.java @@ -2,24 +2,22 @@ package org.thoughtcrime.securesms.service; import android.content.Context; - import org.jetbrains.annotations.NotNull; import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate; +import org.session.libsession.messaging.messages.signal.IncomingMediaMessage; import org.session.libsession.messaging.messages.signal.OutgoingExpirationUpdateMessage; import org.session.libsession.utilities.Address; -import org.session.libsession.utilities.recipients.Recipient; import org.session.libsession.utilities.GroupUtil; import org.session.libsession.utilities.SSKEnvironment; import org.session.libsession.utilities.TextSecurePreferences; -import org.session.libsignal.utilities.guava.Optional; +import org.session.libsession.utilities.recipients.Recipient; import org.session.libsignal.messages.SignalServiceGroup; import org.session.libsignal.utilities.Log; - -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.session.libsignal.utilities.guava.Optional; import org.thoughtcrime.securesms.database.MmsDatabase; import org.thoughtcrime.securesms.database.SmsDatabase; import org.thoughtcrime.securesms.database.model.MessageRecord; -import org.session.libsession.messaging.messages.signal.IncomingMediaMessage; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import org.thoughtcrime.securesms.mms.MmsException; import java.io.IOException; @@ -41,8 +39,8 @@ public class ExpiringMessageManager implements SSKEnvironment.MessageExpirationM public ExpiringMessageManager(Context context) { this.context = context.getApplicationContext(); - this.smsDatabase = DatabaseFactory.getSmsDatabase(context); - this.mmsDatabase = DatabaseFactory.getMmsDatabase(context); + this.smsDatabase = DatabaseComponent.get(context).smsDatabase(); + this.mmsDatabase = DatabaseComponent.get(context).mmsDatabase(); executor.execute(new LoadTask()); executor.execute(new ProcessTask()); @@ -81,12 +79,12 @@ public class ExpiringMessageManager implements SSKEnvironment.MessageExpirationM } if (message.getId() != null) { - DatabaseFactory.getSmsDatabase(context).deleteMessage(message.getId()); + DatabaseComponent.get(context).smsDatabase().deleteMessage(message.getId()); } } private void insertIncomingExpirationTimerMessage(ExpirationTimerUpdate message) { - MmsDatabase database = DatabaseFactory.getMmsDatabase(context); + MmsDatabase database = DatabaseComponent.get(context).mmsDatabase(); String senderPublicKey = message.getSender(); Long sentTimestamp = message.getSentTimestamp(); @@ -123,7 +121,7 @@ public class ExpiringMessageManager implements SSKEnvironment.MessageExpirationM database.insertSecureDecryptedMessageInbox(mediaMessage, -1); //set the timer to the conversation - DatabaseFactory.getRecipientDatabase(context).setExpireMessages(recipient, duration); + DatabaseComponent.get(context).recipientDatabase().setExpireMessages(recipient, duration); } catch (IOException | MmsException ioe) { Log.e("Loki", "Failed to insert expiration update message."); @@ -131,7 +129,7 @@ public class ExpiringMessageManager implements SSKEnvironment.MessageExpirationM } private void insertOutgoingExpirationTimerMessage(ExpirationTimerUpdate message) { - MmsDatabase database = DatabaseFactory.getMmsDatabase(context); + MmsDatabase database = DatabaseComponent.get(context).mmsDatabase(); Long sentTimestamp = message.getSentTimestamp(); String groupId = message.getGroupPublicKey(); @@ -149,7 +147,7 @@ public class ExpiringMessageManager implements SSKEnvironment.MessageExpirationM recipient = Recipient.from(context, Address.fromSerialized(GroupUtil.doubleEncodeGroupID(groupId)), false); } //set the timer to the conversation - DatabaseFactory.getRecipientDatabase(context).setExpireMessages(recipient, duration); + DatabaseComponent.get(context).recipientDatabase().setExpireMessages(recipient, duration); } catch (MmsException | IOException ioe) { Log.e("Loki", "Failed to insert expiration update message."); @@ -163,7 +161,7 @@ public class ExpiringMessageManager implements SSKEnvironment.MessageExpirationM @Override public void startAnyExpiration(long timestamp, @NotNull String author) { - MessageRecord messageRecord = DatabaseFactory.getMmsSmsDatabase(context).getMessageFor(timestamp, author); + MessageRecord messageRecord = DatabaseComponent.get(context).mmsSmsDatabase().getMessageFor(timestamp, author); if (messageRecord != null) { boolean mms = messageRecord.isMms(); Recipient recipient = messageRecord.getRecipient(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt b/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt index e7fdbc509..ba519fb9c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt @@ -2,20 +2,20 @@ package org.thoughtcrime.securesms.sskenvironment import android.content.Context import org.session.libsession.messaging.contacts.Contact -import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.SSKEnvironment +import org.session.libsession.utilities.recipients.Recipient import org.thoughtcrime.securesms.ApplicationContext -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.jobs.RetrieveProfileAvatarJob class ProfileManager : SSKEnvironment.ProfileManagerProtocol { override fun setNickname(context: Context, recipient: Recipient, nickname: String?) { val sessionID = recipient.address.serialize() - val contactDatabase = DatabaseFactory.getSessionContactDatabase(context) + val contactDatabase = DatabaseComponent.get(context).sessionContactDatabase() var contact = contactDatabase.getContactWithSessionID(sessionID) if (contact == null) contact = Contact(sessionID) - contact.threadID = DatabaseFactory.getStorage(context).getThreadId(recipient.address) + contact.threadID = DatabaseComponent.get(context).storage().getThreadId(recipient.address) if (contact.nickname != nickname) { contact.nickname = nickname contactDatabase.setContact(contact) @@ -25,16 +25,16 @@ class ProfileManager : SSKEnvironment.ProfileManagerProtocol { override fun setName(context: Context, recipient: Recipient, name: String) { // New API val sessionID = recipient.address.serialize() - val contactDatabase = DatabaseFactory.getSessionContactDatabase(context) + val contactDatabase = DatabaseComponent.get(context).sessionContactDatabase() var contact = contactDatabase.getContactWithSessionID(sessionID) if (contact == null) contact = Contact(sessionID) - contact.threadID = DatabaseFactory.getStorage(context).getThreadId(recipient.address) + contact.threadID = DatabaseComponent.get(context).storage().getThreadId(recipient.address) if (contact.name != name) { contact.name = name contactDatabase.setContact(contact) } // Old API - val database = DatabaseFactory.getRecipientDatabase(context) + val database = DatabaseComponent.get(context).recipientDatabase() database.setProfileName(recipient, name) recipient.notifyListeners() } @@ -43,10 +43,10 @@ class ProfileManager : SSKEnvironment.ProfileManagerProtocol { val job = RetrieveProfileAvatarJob(recipient, profilePictureURL) ApplicationContext.getInstance(context).jobManager.add(job) val sessionID = recipient.address.serialize() - val contactDatabase = DatabaseFactory.getSessionContactDatabase(context) + val contactDatabase = DatabaseComponent.get(context).sessionContactDatabase() var contact = contactDatabase.getContactWithSessionID(sessionID) if (contact == null) contact = Contact(sessionID) - contact.threadID = DatabaseFactory.getStorage(context).getThreadId(recipient.address) + contact.threadID = DatabaseComponent.get(context).storage().getThreadId(recipient.address) if (contact.profilePictureURL != profilePictureURL) { contact.profilePictureURL = profilePictureURL contactDatabase.setContact(contact) @@ -56,21 +56,21 @@ class ProfileManager : SSKEnvironment.ProfileManagerProtocol { override fun setProfileKey(context: Context, recipient: Recipient, profileKey: ByteArray) { // New API val sessionID = recipient.address.serialize() - val contactDatabase = DatabaseFactory.getSessionContactDatabase(context) + val contactDatabase = DatabaseComponent.get(context).sessionContactDatabase() var contact = contactDatabase.getContactWithSessionID(sessionID) if (contact == null) contact = Contact(sessionID) - contact.threadID = DatabaseFactory.getStorage(context).getThreadId(recipient.address) + contact.threadID = DatabaseComponent.get(context).storage().getThreadId(recipient.address) if (!contact.profilePictureEncryptionKey.contentEquals(profileKey)) { contact.profilePictureEncryptionKey = profileKey contactDatabase.setContact(contact) } // Old API - val database = DatabaseFactory.getRecipientDatabase(context) + val database = DatabaseComponent.get(context).recipientDatabase() database.setProfileKey(recipient, profileKey) } override fun setUnidentifiedAccessMode(context: Context, recipient: Recipient, unidentifiedAccessMode: Recipient.UnidentifiedAccessMode) { - val database = DatabaseFactory.getRecipientDatabase(context) + val database = DatabaseComponent.get(context).recipientDatabase() database.setUnidentifiedAccessMode(recipient, unidentifiedAccessMode) } } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ReadReceiptManager.kt b/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ReadReceiptManager.kt index 62002c88b..bdf42f0e4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ReadReceiptManager.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ReadReceiptManager.kt @@ -5,8 +5,8 @@ import org.session.libsession.utilities.Address import org.session.libsession.utilities.SSKEnvironment import org.session.libsession.utilities.TextSecurePreferences import org.session.libsignal.utilities.Log -import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId +import org.thoughtcrime.securesms.dependencies.DatabaseComponent class ReadReceiptManager: SSKEnvironment.ReadReceiptManagerProtocol { @@ -17,7 +17,7 @@ class ReadReceiptManager: SSKEnvironment.ReadReceiptManagerProtocol { var address = Address.fromSerialized(fromRecipientId) for (timestamp in sentTimestamps) { Log.i("Loki", "Received encrypted read receipt: (XXXXX, $timestamp)") - DatabaseFactory.getMmsSmsDatabase(context).incrementReadReceiptCount(SyncMessageId(address, timestamp), readTimestamp) + DatabaseComponent.get(context).mmsSmsDatabase().incrementReadReceiptCount(SyncMessageId(address, timestamp), readTimestamp) } } } 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 2697a634c..bda23c037 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/AttachmentUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/AttachmentUtil.java @@ -14,9 +14,8 @@ import org.session.libsession.messaging.sending_receiving.attachments.Attachment import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment; import org.session.libsession.utilities.ServiceUtil; import org.session.libsession.utilities.TextSecurePreferences; - -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.session.libsignal.utilities.Log; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import java.util.Collections; import java.util.Set; @@ -61,14 +60,14 @@ public class AttachmentUtil { { AttachmentId attachmentId = attachment.getAttachmentId(); long mmsId = attachment.getMmsId(); - int attachmentCount = DatabaseFactory.getAttachmentDatabase(context) + int attachmentCount = DatabaseComponent.get(context).attachmentDatabase() .getAttachmentsForMessage(mmsId) .size(); if (attachmentCount <= 1) { - DatabaseFactory.getMmsDatabase(context).deleteMessage(mmsId); + DatabaseComponent.get(context).mmsDatabase().deleteMessage(mmsId); } else { - DatabaseFactory.getAttachmentDatabase(context).deleteAttachment(attachmentId); + DatabaseComponent.get(context).attachmentDatabase().deleteAttachment(attachmentId); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/BackupUtil.kt b/app/src/main/java/org/thoughtcrime/securesms/util/BackupUtil.kt index 74014bc81..3f4867839 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/BackupUtil.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/util/BackupUtil.kt @@ -22,8 +22,8 @@ import org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference import org.thoughtcrime.securesms.backup.FullBackupExporter import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider import org.thoughtcrime.securesms.crypto.IdentityKeyUtil -import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.BackupFileRecord +import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.service.LocalBackupListener import java.io.IOException import java.security.MessageDigest @@ -114,7 +114,7 @@ object BackupUtil { @JvmStatic fun getLastBackupTimeString(context: Context, locale: Locale): String { - val timestamp = DatabaseFactory.getLokiBackupFilesDatabase(context).getLastBackupFileTime() + val timestamp = DatabaseComponent.get(context).lokiBackupFilesDatabase().getLastBackupFileTime() if (timestamp == null) { return context.getString(R.string.BackupUtil_never) } @@ -123,7 +123,7 @@ object BackupUtil { @JvmStatic fun getLastBackup(context: Context): BackupFileRecord? { - return DatabaseFactory.getLokiBackupFilesDatabase(context).getLastBackupFile() + return DatabaseComponent.get(context).lokiBackupFilesDatabase().getLastBackupFile() } @JvmStatic @@ -206,10 +206,10 @@ object BackupUtil { try { FullBackupExporter.export(context, - AttachmentSecretProvider.getInstance(context).getOrCreateAttachmentSecret(), - DatabaseFactory.getBackupDatabase(context), - fileUri, - backupPassword) + AttachmentSecretProvider.getInstance(context).orCreateAttachmentSecret, + DatabaseComponent.get(context).openHelper().readableDatabase, + fileUri, + backupPassword) } catch (e: Exception) { // Delete the backup file on any error. DocumentsContract.deleteDocument(context.contentResolver, fileUri) @@ -217,7 +217,7 @@ object BackupUtil { } //TODO Use real file size. - val record = DatabaseFactory.getLokiBackupFilesDatabase(context) + val record = DatabaseComponent.get(context).lokiBackupFilesDatabase() .insertBackupFile(BackupFileRecord(fileUri, -1, date)) Log.v(TAG, "A backup file was created: $fileUri") @@ -228,7 +228,7 @@ object BackupUtil { @JvmStatic @JvmOverloads fun deleteAllBackupFiles(context: Context, except: Collection? = null) { - val db = DatabaseFactory.getLokiBackupFilesDatabase(context) + val db = DatabaseComponent.get(context).lokiBackupFilesDatabase() db.getBackupFiles().forEach { record -> if (except != null && except.contains(record)) return@forEach 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 9bb71ad5c..7e65e63e8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/CommunicationActions.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/CommunicationActions.java @@ -5,19 +5,18 @@ import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.AsyncTask; +import android.widget.Toast; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.app.TaskStackBuilder; -import android.text.TextUtils; -import android.widget.Toast; +import org.session.libsession.utilities.recipients.Recipient; +import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import network.loki.messenger.R; -import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.session.libsession.utilities.recipients.Recipient; - public class CommunicationActions { public static void startConversation(@NonNull Context context, @@ -28,7 +27,7 @@ public class CommunicationActions { new AsyncTask() { @Override protected Long doInBackground(Void... voids) { - return DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient); + return DatabaseComponent.get(context).threadDatabase().getOrCreateThreadIdFor(recipient); } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/ContactUtilities.kt b/app/src/main/java/org/thoughtcrime/securesms/util/ContactUtilities.kt index 4820d005f..8b0ab5d34 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/ContactUtilities.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/util/ContactUtilities.kt @@ -1,14 +1,14 @@ package org.thoughtcrime.securesms.util import android.content.Context -import org.thoughtcrime.securesms.database.DatabaseFactory import org.session.libsession.utilities.recipients.Recipient +import org.thoughtcrime.securesms.dependencies.DatabaseComponent object ContactUtilities { @JvmStatic fun getAllContacts(context: Context): Set { - val threadDatabase = DatabaseFactory.getThreadDatabase(context) + val threadDatabase = DatabaseComponent.get(context).threadDatabase() val cursor = threadDatabase.conversationList val result = mutableSetOf() threadDatabase.readerFor(cursor).use { reader -> diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/IP2Country.kt b/app/src/main/java/org/thoughtcrime/securesms/util/IP2Country.kt index 5f8678a58..4ff45e8f0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/IP2Country.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/util/IP2Country.kt @@ -99,7 +99,7 @@ class IP2Country private constructor(private val context: Context) { val bestMatchCountry = comps.lastOrNull { it.key <= Ipv4Int(ip) }?.let { (_, code) -> if (code != null) { - countryToNames[code] + countryToNames[code] + " [" + ip + "]" } else { null } @@ -126,4 +126,4 @@ class IP2Country private constructor(private val context: Context) { } } // endregion -} \ No newline at end of file +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/Trimmer.java b/app/src/main/java/org/thoughtcrime/securesms/util/Trimmer.java index df6a69737..dd5e146ed 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/Trimmer.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/Trimmer.java @@ -5,9 +5,10 @@ import android.content.Context; import android.os.AsyncTask; import android.widget.Toast; -import network.loki.messenger.R; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.ThreadDatabase; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; + +import network.loki.messenger.R; public class Trimmer { @@ -37,7 +38,7 @@ public class Trimmer { @Override protected Void doInBackground(Integer... params) { - DatabaseFactory.getThreadDatabase(context).trimAllThreads(params[0], this); + DatabaseComponent.get(context).threadDatabase().trimAllThreads(params[0], this); return null; } 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 6f5be91e9..45e46cf05 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 @@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.video.exo; import android.content.Context; import android.net.Uri; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -12,7 +13,7 @@ import com.google.android.exoplayer2.upstream.TransferListener; import org.session.libsession.messaging.sending_receiving.attachments.Attachment; import org.thoughtcrime.securesms.database.AttachmentDatabase; -import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import org.thoughtcrime.securesms.mms.PartUriParser; import java.io.EOFException; @@ -43,7 +44,7 @@ public class PartDataSource implements DataSource { public long open(DataSpec dataSpec) throws IOException { this.uri = dataSpec.uri; - AttachmentDatabase attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context); + AttachmentDatabase attachmentDatabase = DatabaseComponent.get(context).attachmentDatabase(); PartUriParser partUri = new PartUriParser(uri); Attachment attachment = attachmentDatabase.getAttachment(partUri.getPartId()); diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index 39c229df9..706e4961b 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -227,6 +227,18 @@ android:gravity="center" android:text="@string/activity_settings_survey_feedback" /> + + + + + + + + + + +