More DI fixes

This commit is contained in:
ThomasSession 2024-10-02 15:38:46 +10:00 committed by SessionHero01
parent 7f008b5f1b
commit 2523975462
No known key found for this signature in database
10 changed files with 118 additions and 73 deletions

View File

@ -113,6 +113,7 @@ import javax.inject.Inject;
import dagger.hilt.EntryPoints; import dagger.hilt.EntryPoints;
import dagger.hilt.android.HiltAndroidApp; import dagger.hilt.android.HiltAndroidApp;
import kotlin.Deprecated;
import kotlin.Unit; import kotlin.Unit;
import network.loki.messenger.BuildConfig; import network.loki.messenger.BuildConfig;
import network.loki.messenger.R; import network.loki.messenger.R;
@ -132,11 +133,6 @@ public class ApplicationContext extends Application implements DefaultLifecycleO
private static final String TAG = ApplicationContext.class.getSimpleName(); private static final String TAG = ApplicationContext.class.getSimpleName();
private ExpiringMessageManager expiringMessageManager;
private TypingStatusRepository typingStatusRepository;
private TypingStatusSender typingStatusSender;
private ReadReceiptManager readReceiptManager;
public MessageNotifier messageNotifier = null; public MessageNotifier messageNotifier = null;
public Poller poller = null; public Poller poller = null;
public Broadcaster broadcaster = null; public Broadcaster broadcaster = null;
@ -154,8 +150,7 @@ public class ApplicationContext extends Application implements DefaultLifecycleO
@Inject PollerFactory pollerFactory; @Inject PollerFactory pollerFactory;
@Inject LastSentTimestampCache lastSentTimestampCache; @Inject LastSentTimestampCache lastSentTimestampCache;
@Inject VersionDataFetcher versionDataFetcher; @Inject VersionDataFetcher versionDataFetcher;
@Inject @Inject PushRegistrationHandler pushRegistrationHandler;
PushRegistrationHandler pushRegistrationHandler;
@Inject TokenFetcher tokenFetcher; @Inject TokenFetcher tokenFetcher;
@Inject GroupManagerV2 groupManagerV2; @Inject GroupManagerV2 groupManagerV2;
@Inject SSKEnvironment.ProfileManagerProtocol profileManager; @Inject SSKEnvironment.ProfileManagerProtocol profileManager;
@ -165,6 +160,11 @@ public class ApplicationContext extends Application implements DefaultLifecycleO
@Inject ConfigToDatabaseSync configToDatabaseSync; @Inject ConfigToDatabaseSync configToDatabaseSync;
@Inject RemoveGroupMemberHandler removeGroupMemberHandler; @Inject RemoveGroupMemberHandler removeGroupMemberHandler;
@Inject SnodeClock snodeClock; @Inject SnodeClock snodeClock;
@Inject ExpiringMessageManager expiringMessageManager;
@Inject TypingStatusRepository typingStatusRepository;
@Inject TypingStatusSender typingStatusSender;
@Inject ReadReceiptManager readReceiptManager;
private volatile boolean isAppVisible; private volatile boolean isAppVisible;
@ -253,12 +253,8 @@ public class ApplicationContext extends Application implements DefaultLifecycleO
LokiAPIDatabase apiDB = getDatabaseComponent().lokiAPIDatabase(); LokiAPIDatabase apiDB = getDatabaseComponent().lokiAPIDatabase();
boolean useTestNet = textSecurePreferences.getEnvironment() == Environment.TEST_NET; boolean useTestNet = textSecurePreferences.getEnvironment() == Environment.TEST_NET;
SnodeModule.Companion.configure(apiDB, broadcaster, useTestNet); SnodeModule.Companion.configure(apiDB, broadcaster, useTestNet);
initializeExpiringMessageManager();
initializeTypingStatusRepository();
initializeTypingStatusSender();
initializeReadReceiptManager();
initializePeriodicTasks(); initializePeriodicTasks();
SSKEnvironment.Companion.configure(getTypingStatusRepository(), getReadReceiptManager(), profileManager, messageNotifier, getExpiringMessageManager()); SSKEnvironment.Companion.configure(typingStatusRepository, readReceiptManager, profileManager, messageNotifier, expiringMessageManager);
initializeWebRtc(); initializeWebRtc();
initializeBlobProvider(); initializeBlobProvider();
resubmitProfilePictureIfNeeded(); resubmitProfilePictureIfNeeded();
@ -341,22 +337,27 @@ public class ApplicationContext extends Application implements DefaultLifecycleO
super.onTerminate(); super.onTerminate();
} }
@Deprecated(message = "Use proper DI to inject this component")
public ExpiringMessageManager getExpiringMessageManager() { public ExpiringMessageManager getExpiringMessageManager() {
return expiringMessageManager; return expiringMessageManager;
} }
@Deprecated(message = "Use proper DI to inject this component")
public TypingStatusRepository getTypingStatusRepository() { public TypingStatusRepository getTypingStatusRepository() {
return typingStatusRepository; return typingStatusRepository;
} }
@Deprecated(message = "Use proper DI to inject this component")
public TypingStatusSender getTypingStatusSender() { public TypingStatusSender getTypingStatusSender() {
return typingStatusSender; return typingStatusSender;
} }
@Deprecated(message = "Use proper DI to inject this component")
public TextSecurePreferences getTextSecurePreferences() { public TextSecurePreferences getTextSecurePreferences() {
return textSecurePreferences; return textSecurePreferences;
} }
@Deprecated(message = "Use proper DI to inject this component")
public ReadReceiptManager getReadReceiptManager() { public ReadReceiptManager getReadReceiptManager() {
return readReceiptManager; return readReceiptManager;
} }
@ -404,22 +405,6 @@ public class ApplicationContext extends Application implements DefaultLifecycleO
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionLogger(originalHandler)); Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionLogger(originalHandler));
} }
private void initializeExpiringMessageManager() {
this.expiringMessageManager = new ExpiringMessageManager(this);
}
private void initializeTypingStatusRepository() {
this.typingStatusRepository = new TypingStatusRepository();
}
private void initializeReadReceiptManager() {
this.readReceiptManager = new ReadReceiptManager();
}
private void initializeTypingStatusSender() {
this.typingStatusSender = new TypingStatusSender(this);
}
private void initializePeriodicTasks() { private void initializePeriodicTasks() {
BackgroundPollWorker.schedulePeriodic(this); BackgroundPollWorker.schedulePeriodic(this);
} }

View File

@ -3,32 +3,35 @@ package org.thoughtcrime.securesms.components;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import androidx.annotation.NonNull;
import org.session.libsession.messaging.messages.control.TypingIndicator; import org.session.libsession.messaging.messages.control.TypingIndicator;
import org.session.libsession.messaging.sending_receiving.MessageSender; import org.session.libsession.messaging.sending_receiving.MessageSender;
import org.session.libsession.utilities.Util; import org.session.libsession.utilities.Util;
import org.session.libsession.utilities.recipients.Recipient; import org.session.libsession.utilities.recipients.Recipient;
import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase;
import org.thoughtcrime.securesms.dependencies.DatabaseComponent;
import org.thoughtcrime.securesms.util.SessionMetaProtocol; import org.thoughtcrime.securesms.util.SessionMetaProtocol;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.inject.Singleton;
@SuppressLint("UseSparseArrays") @SuppressLint("UseSparseArrays")
@Singleton
public class TypingStatusSender { public class TypingStatusSender {
private static final long REFRESH_TYPING_TIMEOUT = TimeUnit.SECONDS.toMillis(10); private static final long REFRESH_TYPING_TIMEOUT = TimeUnit.SECONDS.toMillis(10);
private static final long PAUSE_TYPING_TIMEOUT = TimeUnit.SECONDS.toMillis(3); private static final long PAUSE_TYPING_TIMEOUT = TimeUnit.SECONDS.toMillis(3);
private final Context context;
private final Map<Long, TimerPair> selfTypingTimers; private final Map<Long, TimerPair> selfTypingTimers;
private final ThreadDatabase threadDatabase;
public TypingStatusSender(@NonNull Context context) { @Inject
this.context = context; public TypingStatusSender(ThreadDatabase threadDatabase) {
this.selfTypingTimers = new HashMap<>(); this.threadDatabase = threadDatabase;
this.selfTypingTimers = new HashMap<>();
} }
public synchronized void onTypingStarted(long threadId) { public synchronized void onTypingStarted(long threadId) {
@ -77,7 +80,6 @@ public class TypingStatusSender {
} }
private void sendTyping(long threadId, boolean typingStarted) { private void sendTyping(long threadId, boolean typingStarted) {
ThreadDatabase threadDatabase = DatabaseComponent.get(context).threadDatabase();
Recipient recipient = threadDatabase.getRecipientForThreadId(threadId); Recipient recipient = threadDatabase.getRecipientForThreadId(threadId);
if (recipient == null) { return; } if (recipient == null) { return; }
if (!SessionMetaProtocol.shouldSendTypingIndicator(recipient)) { return; } if (!SessionMetaProtocol.shouldSendTypingIndicator(recipient)) { return; }

View File

@ -45,6 +45,7 @@ import org.thoughtcrime.securesms.database.ThreadDatabase
import org.thoughtcrime.securesms.dependencies.PollerFactory import org.thoughtcrime.securesms.dependencies.PollerFactory
import org.thoughtcrime.securesms.groups.ClosedGroupManager import org.thoughtcrime.securesms.groups.ClosedGroupManager
import org.thoughtcrime.securesms.groups.OpenGroupManager import org.thoughtcrime.securesms.groups.OpenGroupManager
import org.thoughtcrime.securesms.util.asSequence
import javax.inject.Inject import javax.inject.Inject
private const val TAG = "ConfigToDatabaseSync" private const val TAG = "ConfigToDatabaseSync"
@ -237,27 +238,39 @@ class ConfigToDatabaseSync @Inject constructor(
} }
val newClosedGroups = userGroups.allClosedGroupInfo() val newClosedGroups = userGroups.allClosedGroupInfo()
val existingClosedGroups = storage.getAllGroups(includeInactive = true).filter { it.isClosedGroupV2 } val existingClosedGroupThreads: Map<AccountId, Long> = threadDatabase.readerFor(threadDatabase.conversationList).use { reader ->
buildMap(reader.count) {
var current = reader.next
while (current != null) {
if (current.recipient?.isClosedGroupV2Recipient == true) {
put(AccountId(current.recipient.address.serialize()), current.threadId)
}
current = reader.next
}
}
}
val groupThreadsToKeep = hashMapOf<AccountId, Long>()
for (closedGroup in newClosedGroups) { for (closedGroup in newClosedGroups) {
val recipient = Recipient.from(context, fromSerialized(closedGroup.groupAccountId.hexString), false) val recipient = Recipient.from(context, fromSerialized(closedGroup.groupAccountId.hexString), false)
storage.setRecipientApprovedMe(recipient, true) storage.setRecipientApprovedMe(recipient, true)
storage.setRecipientApproved(recipient, !closedGroup.invited) storage.setRecipientApproved(recipient, !closedGroup.invited)
val threadId = storage.getOrCreateThreadIdFor(recipient.address) val threadId = storage.getOrCreateThreadIdFor(recipient.address)
groupThreadsToKeep[closedGroup.groupAccountId] = threadId
storage.setPinned(threadId, closedGroup.priority == PRIORITY_PINNED) storage.setPinned(threadId, closedGroup.priority == PRIORITY_PINNED)
if (!closedGroup.invited) { if (!closedGroup.invited) {
pollerFactory.pollerFor(closedGroup.groupAccountId)?.start() pollerFactory.pollerFor(closedGroup.groupAccountId)?.start()
} }
} }
val toRemove = existingClosedGroups.mapTo(hashSetOf()) { it.encodedId } - newClosedGroups.mapTo(hashSetOf()) { it.groupAccountId.hexString } val toRemove = existingClosedGroupThreads - groupThreadsToKeep.keys
Log.d(TAG, "Removing ${toRemove.size} closed groups") Log.d(TAG, "Removing ${toRemove.size} closed groups")
toRemove.forEach { encodedId -> toRemove.forEach { (groupId, threadId) ->
val threadId = storage.getThreadId(encodedId) pollerFactory.pollerFor(groupId)?.stop()
if (threadId != null) { storage.removeClosedGroupThread(threadId)
storage.removeClosedGroupThread(threadId)
}
pollerFactory.pollerFor(AccountId(encodedId))?.stop()
} }
for (group in lgc) { for (group in lgc) {

View File

@ -2,12 +2,16 @@ package org.thoughtcrime.securesms.dependencies
import dagger.Binds import dagger.Binds
import dagger.Module import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent import dagger.hilt.components.SingletonComponent
import org.session.libsession.database.StorageProtocol import org.session.libsession.database.StorageProtocol
import org.session.libsession.utilities.SSKEnvironment
import org.session.libsignal.database.LokiAPIDatabaseProtocol import org.session.libsignal.database.LokiAPIDatabaseProtocol
import org.thoughtcrime.securesms.database.LokiAPIDatabase import org.thoughtcrime.securesms.database.LokiAPIDatabase
import org.thoughtcrime.securesms.database.Storage import org.thoughtcrime.securesms.database.Storage
import org.thoughtcrime.securesms.service.ExpiringMessageManager
import javax.inject.Singleton
@Module @Module
@InstallIn(SingletonComponent::class) @InstallIn(SingletonComponent::class)
@ -18,4 +22,8 @@ abstract class DatabaseBindings {
@Binds @Binds
abstract fun bindLokiAPIDatabaseProtocol(lokiAPIDatabase: LokiAPIDatabase): LokiAPIDatabaseProtocol abstract fun bindLokiAPIDatabaseProtocol(lokiAPIDatabase: LokiAPIDatabase): LokiAPIDatabaseProtocol
@Binds
abstract fun bindMessageExpirationManagerProtocol(manager: ExpiringMessageManager): SSKEnvironment.MessageExpirationManagerProtocol
} }

View File

@ -7,14 +7,36 @@ import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent import dagger.hilt.components.SingletonComponent
import org.session.libsession.database.MessageDataProvider import org.session.libsession.database.MessageDataProvider
import org.session.libsession.utilities.SSKEnvironment
import org.thoughtcrime.securesms.attachments.DatabaseAttachmentProvider import org.thoughtcrime.securesms.attachments.DatabaseAttachmentProvider
import org.thoughtcrime.securesms.crypto.AttachmentSecret import org.thoughtcrime.securesms.crypto.AttachmentSecret
import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider
import org.thoughtcrime.securesms.crypto.DatabaseSecretProvider import org.thoughtcrime.securesms.crypto.DatabaseSecretProvider
import org.thoughtcrime.securesms.database.* import org.thoughtcrime.securesms.database.AttachmentDatabase
import org.thoughtcrime.securesms.database.BlindedIdMappingDatabase
import org.thoughtcrime.securesms.database.ConfigDatabase
import org.thoughtcrime.securesms.database.DraftDatabase
import org.thoughtcrime.securesms.database.EmojiSearchDatabase
import org.thoughtcrime.securesms.database.ExpirationConfigurationDatabase
import org.thoughtcrime.securesms.database.GroupDatabase
import org.thoughtcrime.securesms.database.GroupMemberDatabase
import org.thoughtcrime.securesms.database.GroupReceiptDatabase
import org.thoughtcrime.securesms.database.LokiAPIDatabase
import org.thoughtcrime.securesms.database.LokiBackupFilesDatabase
import org.thoughtcrime.securesms.database.LokiMessageDatabase
import org.thoughtcrime.securesms.database.LokiThreadDatabase
import org.thoughtcrime.securesms.database.LokiUserDatabase
import org.thoughtcrime.securesms.database.MediaDatabase
import org.thoughtcrime.securesms.database.MmsDatabase
import org.thoughtcrime.securesms.database.MmsSmsDatabase
import org.thoughtcrime.securesms.database.PushDatabase
import org.thoughtcrime.securesms.database.ReactionDatabase
import org.thoughtcrime.securesms.database.RecipientDatabase
import org.thoughtcrime.securesms.database.SearchDatabase
import org.thoughtcrime.securesms.database.SessionContactDatabase
import org.thoughtcrime.securesms.database.SessionJobDatabase
import org.thoughtcrime.securesms.database.SmsDatabase
import org.thoughtcrime.securesms.database.ThreadDatabase
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
import org.thoughtcrime.securesms.service.ExpiringMessageManager
import javax.inject.Singleton import javax.inject.Singleton
@Module @Module
@ -26,10 +48,6 @@ object DatabaseModule {
System.loadLibrary("sqlcipher") System.loadLibrary("sqlcipher")
} }
@Provides
@Singleton
fun provideMessageExpirationManagerProtocol(@ApplicationContext context: Context): SSKEnvironment.MessageExpirationManagerProtocol = ExpiringMessageManager(context)
@Provides @Provides
@Singleton @Singleton
fun provideAttachmentSecret(@ApplicationContext context: Context) = AttachmentSecretProvider.getInstance(context).orCreateAttachmentSecret fun provideAttachmentSecret(@ApplicationContext context: Context) = AttachmentSecretProvider.getInstance(context).orCreateAttachmentSecret

View File

@ -6,6 +6,7 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.AsyncTask import android.os.AsyncTask
import androidx.core.app.NotificationManagerCompat import androidx.core.app.NotificationManagerCompat
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.session.libsession.database.userAuth import org.session.libsession.database.userAuth
@ -27,6 +28,7 @@ import org.thoughtcrime.securesms.database.MarkedMessageInfo
import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.dependencies.DatabaseComponent
import org.thoughtcrime.securesms.util.SessionMetaProtocol.shouldSendReadReceipt import org.thoughtcrime.securesms.util.SessionMetaProtocol.shouldSendReadReceipt
@AndroidEntryPoint
class MarkReadReceiver : BroadcastReceiver() { class MarkReadReceiver : BroadcastReceiver() {
@SuppressLint("StaticFieldLeak") @SuppressLint("StaticFieldLeak")
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {

View File

@ -1,13 +1,13 @@
package org.thoughtcrime.securesms.service package org.thoughtcrime.securesms.service
import android.content.Context import android.content.Context
import dagger.hilt.android.qualifiers.ApplicationContext
import network.loki.messenger.libsession_util.util.ExpiryMode import network.loki.messenger.libsession_util.util.ExpiryMode
import network.loki.messenger.libsession_util.util.ExpiryMode.AfterSend import network.loki.messenger.libsession_util.util.ExpiryMode.AfterSend
import org.session.libsession.messaging.MessagingModuleConfiguration.Companion.shared
import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate
import org.session.libsession.messaging.messages.signal.IncomingMediaMessage import org.session.libsession.messaging.messages.signal.IncomingMediaMessage
import org.session.libsession.messaging.messages.signal.OutgoingExpirationUpdateMessage import org.session.libsession.messaging.messages.signal.OutgoingExpirationUpdateMessage
import org.session.libsession.snode.SnodeAPI.nowWithOffset import org.session.libsession.snode.SnodeClock
import org.session.libsession.utilities.Address import org.session.libsession.utilities.Address
import org.session.libsession.utilities.Address.Companion.fromSerialized import org.session.libsession.utilities.Address.Companion.fromSerialized
import org.session.libsession.utilities.GroupUtil import org.session.libsession.utilities.GroupUtil
@ -23,27 +23,30 @@ import org.session.libsignal.utilities.guava.Optional
import org.thoughtcrime.securesms.database.MmsDatabase import org.thoughtcrime.securesms.database.MmsDatabase
import org.thoughtcrime.securesms.database.MmsSmsDatabase import org.thoughtcrime.securesms.database.MmsSmsDatabase
import org.thoughtcrime.securesms.database.SmsDatabase import org.thoughtcrime.securesms.database.SmsDatabase
import org.thoughtcrime.securesms.dependencies.DatabaseComponent.Companion.get import org.thoughtcrime.securesms.database.Storage
import org.thoughtcrime.securesms.mms.MmsException import org.thoughtcrime.securesms.mms.MmsException
import java.io.IOException import java.io.IOException
import java.util.TreeSet import java.util.TreeSet
import java.util.concurrent.Executor import java.util.concurrent.Executor
import java.util.concurrent.Executors import java.util.concurrent.Executors
import javax.inject.Inject
import javax.inject.Singleton
private val TAG = ExpiringMessageManager::class.java.simpleName private val TAG = ExpiringMessageManager::class.java.simpleName
class ExpiringMessageManager(context: Context) : MessageExpirationManagerProtocol {
@Singleton
class ExpiringMessageManager @Inject constructor(
@ApplicationContext private val context: Context,
private val smsDatabase: SmsDatabase,
private val mmsDatabase: MmsDatabase,
private val mmsSmsDatabase: MmsSmsDatabase,
private val clock: SnodeClock,
private val storage: Storage,
) : MessageExpirationManagerProtocol {
private val expiringMessageReferences = TreeSet<ExpiringMessageReference>() private val expiringMessageReferences = TreeSet<ExpiringMessageReference>()
private val executor: Executor = Executors.newSingleThreadExecutor() private val executor: Executor = Executors.newSingleThreadExecutor()
private val smsDatabase: SmsDatabase
private val mmsDatabase: MmsDatabase
private val mmsSmsDatabase: MmsSmsDatabase
private val context: Context
init { init {
this.context = context.applicationContext
smsDatabase = get(context).smsDatabase()
mmsDatabase = get(context).mmsDatabase()
mmsSmsDatabase = get(context).mmsSmsDatabase()
executor.execute(LoadTask()) executor.execute(LoadTask())
executor.execute(ProcessTask()) executor.execute(ProcessTask())
} }
@ -94,7 +97,7 @@ class ExpiringMessageManager(context: Context) : MessageExpirationManagerProtoco
} }
recipient = Recipient.from(context, groupAddress, false) recipient = Recipient.from(context, groupAddress, false)
} }
val threadId = shared.storage.getThreadId(recipient) ?: return val threadId = storage.getThreadId(recipient) ?: return
val mediaMessage = IncomingMediaMessage( val mediaMessage = IncomingMediaMessage(
address, sentTimestamp!!, -1, address, sentTimestamp!!, -1,
expiresInMillis, expireStartedAt, true, expiresInMillis, expireStartedAt, true,
@ -134,7 +137,7 @@ class ExpiringMessageManager(context: Context) : MessageExpirationManagerProtoco
val address = fromSerialized(serializedAddress) val address = fromSerialized(serializedAddress)
val recipient = Recipient.from(context, address, false) val recipient = Recipient.from(context, address, false)
message.threadID = shared.storage.getOrCreateThreadIdFor(address) message.threadID = storage.getOrCreateThreadIdFor(address)
val timerUpdateMessage = OutgoingExpirationUpdateMessage( val timerUpdateMessage = OutgoingExpirationUpdateMessage(
recipient, recipient,
sentTimestamp!!, sentTimestamp!!,
@ -206,7 +209,7 @@ class ExpiringMessageManager(context: Context) : MessageExpirationManagerProtoco
try { try {
while (expiringMessageReferences.isEmpty()) (expiringMessageReferences as Object).wait() while (expiringMessageReferences.isEmpty()) (expiringMessageReferences as Object).wait()
val nextReference = expiringMessageReferences.first() val nextReference = expiringMessageReferences.first()
val waitTime = nextReference.expiresAtMillis - nowWithOffset val waitTime = nextReference.expiresAtMillis - clock.currentTimeMills()
if (waitTime > 0) { if (waitTime > 0) {
ExpirationListener.setAlarm(context, waitTime) ExpirationListener.setAlarm(context, waitTime)
(expiringMessageReferences as Object).wait(waitTime) (expiringMessageReferences as Object).wait(waitTime)

View File

@ -6,18 +6,24 @@ import org.session.libsession.utilities.SSKEnvironment
import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.Log
import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId
import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.database.MmsSmsDatabase
import javax.inject.Inject
import javax.inject.Singleton
class ReadReceiptManager: SSKEnvironment.ReadReceiptManagerProtocol { @Singleton
class ReadReceiptManager @Inject constructor(
private val textSecurePreferences: TextSecurePreferences,
private val mmsSmsDatabase: MmsSmsDatabase,
): SSKEnvironment.ReadReceiptManagerProtocol {
override fun processReadReceipts(context: Context, fromRecipientId: String, sentTimestamps: List<Long>, readTimestamp: Long) { override fun processReadReceipts(context: Context, fromRecipientId: String, sentTimestamps: List<Long>, readTimestamp: Long) {
if (TextSecurePreferences.isReadReceiptsEnabled(context)) { if (textSecurePreferences.isReadReceiptsEnabled()) {
// Redirect message to master device conversation // Redirect message to master device conversation
var address = Address.fromSerialized(fromRecipientId) var address = Address.fromSerialized(fromRecipientId)
for (timestamp in sentTimestamps) { for (timestamp in sentTimestamps) {
Log.i("Loki", "Received encrypted read receipt: (XXXXX, $timestamp)") Log.i("Loki", "Received encrypted read receipt: (XXXXX, $timestamp)")
DatabaseComponent.get(context).mmsSmsDatabase().incrementReadReceiptCount(SyncMessageId(address, timestamp), readTimestamp) mmsSmsDatabase.incrementReadReceiptCount(SyncMessageId(address, timestamp), readTimestamp)
} }
} }
} }

View File

@ -27,7 +27,11 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.inject.Singleton;
@SuppressLint("UseSparseArrays") @SuppressLint("UseSparseArrays")
@Singleton
public class TypingStatusRepository implements SSKEnvironment.TypingIndicatorsProtocol { public class TypingStatusRepository implements SSKEnvironment.TypingIndicatorsProtocol {
private static final String TAG = TypingStatusRepository.class.getSimpleName(); private static final String TAG = TypingStatusRepository.class.getSimpleName();
@ -38,17 +42,20 @@ public class TypingStatusRepository implements SSKEnvironment.TypingIndicatorsPr
private final Map<Typist, Runnable> timers; private final Map<Typist, Runnable> timers;
private final Map<Long, MutableLiveData<TypingState>> notifiers; private final Map<Long, MutableLiveData<TypingState>> notifiers;
private final MutableLiveData<Set<Long>> threadsNotifier; private final MutableLiveData<Set<Long>> threadsNotifier;
private final TextSecurePreferences preferences;
public TypingStatusRepository() { @Inject
public TypingStatusRepository(TextSecurePreferences preferences) {
this.typistMap = new HashMap<>(); this.typistMap = new HashMap<>();
this.timers = new HashMap<>(); this.timers = new HashMap<>();
this.notifiers = new HashMap<>(); this.notifiers = new HashMap<>();
this.threadsNotifier = new MutableLiveData<>(); this.threadsNotifier = new MutableLiveData<>();
this.preferences = preferences;
} }
@Override @Override
public synchronized void didReceiveTypingStartedMessage(@NotNull Context context, long threadId, @NotNull Address author, int device) { public synchronized void didReceiveTypingStartedMessage(@NotNull Context context, long threadId, @NotNull Address author, int device) {
if (author.serialize().equals(TextSecurePreferences.getLocalNumber(context))) { if (author.serialize().equals(preferences.getLocalNumber())) {
return; return;
} }
@ -77,7 +84,7 @@ public class TypingStatusRepository implements SSKEnvironment.TypingIndicatorsPr
@Override @Override
public synchronized void didReceiveTypingStoppedMessage(@NotNull Context context, long threadId, @NotNull Address author, int device, boolean isReplacedByIncomingMessage) { public synchronized void didReceiveTypingStoppedMessage(@NotNull Context context, long threadId, @NotNull Address author, int device, boolean isReplacedByIncomingMessage) {
if (author.serialize().equals(TextSecurePreferences.getLocalNumber(context))) { if (author.serialize().equals(preferences.getLocalNumber())) {
return; return;
} }

View File

@ -75,6 +75,7 @@ class SSKEnvironment(
} }
companion object { companion object {
@Deprecated("Use Hilt to inject your dependencies instead")
lateinit var shared: SSKEnvironment lateinit var shared: SSKEnvironment
fun configure(typingIndicators: TypingIndicatorsProtocol, fun configure(typingIndicators: TypingIndicatorsProtocol,