Apply better strategy for dependency init.

This commit is contained in:
Alex Hart 2020-11-30 16:09:48 -04:00
parent dcb16378c8
commit 4ae0f3999c

View file

@ -12,7 +12,6 @@ import org.thoughtcrime.securesms.groups.GroupsV2Authorization;
import org.thoughtcrime.securesms.groups.GroupsV2AuthorizationMemoryValueCache; import org.thoughtcrime.securesms.groups.GroupsV2AuthorizationMemoryValueCache;
import org.thoughtcrime.securesms.groups.v2.processing.GroupsV2StateProcessor; import org.thoughtcrime.securesms.groups.v2.processing.GroupsV2StateProcessor;
import org.thoughtcrime.securesms.jobmanager.JobManager; import org.thoughtcrime.securesms.jobmanager.JobManager;
import org.thoughtcrime.securesms.keyvalue.KeyValueStore;
import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.megaphone.MegaphoneRepository; import org.thoughtcrime.securesms.megaphone.MegaphoneRepository;
import org.thoughtcrime.securesms.messages.BackgroundMessageRetriever; import org.thoughtcrime.securesms.messages.BackgroundMessageRetriever;
@ -43,31 +42,34 @@ import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations;
*/ */
public class ApplicationDependencies { public class ApplicationDependencies {
private static final Object LOCK = new Object();
private static final Object FRAME_RATE_TRACKER_LOCK = new Object();
private static Application application; private static Application application;
private static Provider provider; private static Provider provider;
private static SignalServiceAccountManager accountManager;
private static SignalServiceMessageSender messageSender;
private static SignalServiceMessageReceiver messageReceiver;
private static IncomingMessageObserver incomingMessageObserver;
private static IncomingMessageProcessor incomingMessageProcessor;
private static BackgroundMessageRetriever backgroundMessageRetriever;
private static LiveRecipientCache recipientCache;
private static JobManager jobManager;
private static FrameRateTracker frameRateTracker;
private static KeyValueStore keyValueStore;
private static MegaphoneRepository megaphoneRepository;
private static GroupsV2Authorization groupsV2Authorization;
private static GroupsV2StateProcessor groupsV2StateProcessor;
private static GroupsV2Operations groupsV2Operations;
private static EarlyMessageCache earlyMessageCache;
private static MessageNotifier messageNotifier; private static MessageNotifier messageNotifier;
private static TrimThreadsByDateManager trimThreadsByDateManager; private static TrimThreadsByDateManager trimThreadsByDateManager;
private static TypingStatusRepository typingStatusRepository;
private static TypingStatusSender typingStatusSender; private static volatile SignalServiceAccountManager accountManager;
private static volatile SignalServiceMessageSender messageSender;
private static volatile SignalServiceMessageReceiver messageReceiver;
private static volatile IncomingMessageObserver incomingMessageObserver;
private static volatile IncomingMessageProcessor incomingMessageProcessor;
private static volatile BackgroundMessageRetriever backgroundMessageRetriever;
private static volatile LiveRecipientCache recipientCache;
private static volatile JobManager jobManager;
private static volatile FrameRateTracker frameRateTracker;
private static volatile MegaphoneRepository megaphoneRepository;
private static volatile GroupsV2Authorization groupsV2Authorization;
private static volatile GroupsV2StateProcessor groupsV2StateProcessor;
private static volatile GroupsV2Operations groupsV2Operations;
private static volatile EarlyMessageCache earlyMessageCache;
private static volatile TypingStatusRepository typingStatusRepository;
private static volatile TypingStatusSender typingStatusSender;
@MainThread @MainThread
public static synchronized void init(@NonNull Application application, @NonNull Provider provider) { public static void init(@NonNull Application application, @NonNull Provider provider) {
synchronized (LOCK) {
if (ApplicationDependencies.application != null || ApplicationDependencies.provider != null) { if (ApplicationDependencies.application != null || ApplicationDependencies.provider != null) {
throw new IllegalStateException("Already initialized!"); throw new IllegalStateException("Already initialized!");
} }
@ -77,44 +79,50 @@ public class ApplicationDependencies {
ApplicationDependencies.messageNotifier = provider.provideMessageNotifier(); ApplicationDependencies.messageNotifier = provider.provideMessageNotifier();
ApplicationDependencies.trimThreadsByDateManager = provider.provideTrimThreadsByDateManager(); ApplicationDependencies.trimThreadsByDateManager = provider.provideTrimThreadsByDateManager();
} }
}
public static @NonNull Application getApplication() { public static @NonNull Application getApplication() {
assertInitialization();
return application; return application;
} }
public static synchronized @NonNull SignalServiceAccountManager getSignalServiceAccountManager() { public static @NonNull SignalServiceAccountManager getSignalServiceAccountManager() {
assertInitialization(); if (accountManager == null) {
synchronized (LOCK) {
if (accountManager == null) { if (accountManager == null) {
accountManager = provider.provideSignalServiceAccountManager(); accountManager = provider.provideSignalServiceAccountManager();
} }
}
}
return accountManager; return accountManager;
} }
public static synchronized @NonNull GroupsV2Authorization getGroupsV2Authorization() { public static @NonNull GroupsV2Authorization getGroupsV2Authorization() {
assertInitialization(); if (groupsV2Authorization == null) {
synchronized (LOCK) {
if (groupsV2Authorization == null) { if (groupsV2Authorization == null) {
GroupsV2Authorization.ValueCache authCache = new GroupsV2AuthorizationMemoryValueCache(SignalStore.groupsV2AuthorizationCache()); GroupsV2Authorization.ValueCache authCache = new GroupsV2AuthorizationMemoryValueCache(SignalStore.groupsV2AuthorizationCache());
groupsV2Authorization = new GroupsV2Authorization(getSignalServiceAccountManager().getGroupsV2Api(), authCache); groupsV2Authorization = new GroupsV2Authorization(getSignalServiceAccountManager().getGroupsV2Api(), authCache);
} }
}
}
return groupsV2Authorization; return groupsV2Authorization;
} }
public static synchronized @NonNull GroupsV2Operations getGroupsV2Operations() { public static @NonNull GroupsV2Operations getGroupsV2Operations() {
assertInitialization(); if (groupsV2Operations == null) {
synchronized (LOCK) {
if (groupsV2Operations == null) { if (groupsV2Operations == null) {
groupsV2Operations = provider.provideGroupsV2Operations(); groupsV2Operations = provider.provideGroupsV2Operations();
} }
}
}
return groupsV2Operations; return groupsV2Operations;
} }
public static synchronized @NonNull KeyBackupService getKeyBackupService(@NonNull KbsEnclave enclave) { public static @NonNull KeyBackupService getKeyBackupService(@NonNull KbsEnclave enclave) {
return getSignalServiceAccountManager().getKeyBackupService(IasKeyStore.getIasKeyStore(application), return getSignalServiceAccountManager().getKeyBackupService(IasKeyStore.getIasKeyStore(application),
enclave.getEnclaveName(), enclave.getEnclaveName(),
Hex.fromStringOrThrow(enclave.getServiceId()), Hex.fromStringOrThrow(enclave.getServiceId()),
@ -122,19 +130,20 @@ public class ApplicationDependencies {
10); 10);
} }
public static synchronized @NonNull GroupsV2StateProcessor getGroupsV2StateProcessor() { public static @NonNull GroupsV2StateProcessor getGroupsV2StateProcessor() {
assertInitialization(); if (groupsV2StateProcessor == null) {
synchronized (LOCK) {
if (groupsV2StateProcessor == null) { if (groupsV2StateProcessor == null) {
groupsV2StateProcessor = new GroupsV2StateProcessor(application); groupsV2StateProcessor = new GroupsV2StateProcessor(application);
} }
}
}
return groupsV2StateProcessor; return groupsV2StateProcessor;
} }
public static synchronized @NonNull SignalServiceMessageSender getSignalServiceMessageSender() { public static @NonNull SignalServiceMessageSender getSignalServiceMessageSender() {
assertInitialization(); synchronized (LOCK) {
if (messageSender == null) { if (messageSender == null) {
messageSender = provider.provideSignalServiceMessageSender(); messageSender = provider.provideSignalServiceMessageSender();
} else { } else {
@ -143,123 +152,138 @@ public class ApplicationDependencies {
IncomingMessageObserver.getUnidentifiedPipe(), IncomingMessageObserver.getUnidentifiedPipe(),
TextSecurePreferences.isMultiDevice(application)); TextSecurePreferences.isMultiDevice(application));
} }
}
return messageSender; return messageSender;
} }
public static synchronized @NonNull SignalServiceMessageReceiver getSignalServiceMessageReceiver() { public static @NonNull SignalServiceMessageReceiver getSignalServiceMessageReceiver() {
assertInitialization(); if (messageReceiver == null) {
synchronized (LOCK) {
if (messageReceiver == null) { if (messageReceiver == null) {
messageReceiver = provider.provideSignalServiceMessageReceiver(); messageReceiver = provider.provideSignalServiceMessageReceiver();
} }
}
}
return messageReceiver; return messageReceiver;
} }
public static synchronized void resetSignalServiceMessageReceiver() { public static void resetSignalServiceMessageReceiver() {
assertInitialization(); synchronized (LOCK) {
messageReceiver = null; messageReceiver = null;
} }
}
public static synchronized @NonNull SignalServiceNetworkAccess getSignalServiceNetworkAccess() { public static @NonNull SignalServiceNetworkAccess getSignalServiceNetworkAccess() {
assertInitialization();
return provider.provideSignalServiceNetworkAccess(); return provider.provideSignalServiceNetworkAccess();
} }
public static synchronized @NonNull IncomingMessageProcessor getIncomingMessageProcessor() { public static @NonNull IncomingMessageProcessor getIncomingMessageProcessor() {
assertInitialization(); if (incomingMessageProcessor == null) {
synchronized (LOCK) {
if (incomingMessageProcessor == null) { if (incomingMessageProcessor == null) {
incomingMessageProcessor = provider.provideIncomingMessageProcessor(); incomingMessageProcessor = provider.provideIncomingMessageProcessor();
} }
}
}
return incomingMessageProcessor; return incomingMessageProcessor;
} }
public static synchronized @NonNull BackgroundMessageRetriever getBackgroundMessageRetriever() { public static @NonNull BackgroundMessageRetriever getBackgroundMessageRetriever() {
assertInitialization(); if (backgroundMessageRetriever == null) {
synchronized (LOCK) {
if (backgroundMessageRetriever == null) { if (backgroundMessageRetriever == null) {
backgroundMessageRetriever = provider.provideBackgroundMessageRetriever(); backgroundMessageRetriever = provider.provideBackgroundMessageRetriever();
} }
}
}
return backgroundMessageRetriever; return backgroundMessageRetriever;
} }
public static synchronized @NonNull LiveRecipientCache getRecipientCache() { public static @NonNull LiveRecipientCache getRecipientCache() {
assertInitialization(); if (recipientCache == null) {
synchronized (LOCK) {
if (recipientCache == null) { if (recipientCache == null) {
recipientCache = provider.provideRecipientCache(); recipientCache = provider.provideRecipientCache();
} }
}
}
return recipientCache; return recipientCache;
} }
public static synchronized @NonNull JobManager getJobManager() { public static @NonNull JobManager getJobManager() {
assertInitialization(); if (jobManager == null) {
synchronized (LOCK) {
if (jobManager == null) { if (jobManager == null) {
jobManager = provider.provideJobManager(); jobManager = provider.provideJobManager();
} }
}
}
return jobManager; return jobManager;
} }
public static synchronized @NonNull FrameRateTracker getFrameRateTracker() { public static @NonNull FrameRateTracker getFrameRateTracker() {
assertInitialization(); if (frameRateTracker == null) {
synchronized (FRAME_RATE_TRACKER_LOCK) {
if (frameRateTracker == null) { if (frameRateTracker == null) {
frameRateTracker = provider.provideFrameRateTracker(); frameRateTracker = provider.provideFrameRateTracker();
} }
}
}
return frameRateTracker; return frameRateTracker;
} }
public static synchronized @NonNull MegaphoneRepository getMegaphoneRepository() { public static @NonNull MegaphoneRepository getMegaphoneRepository() {
assertInitialization(); if (megaphoneRepository == null) {
synchronized (LOCK) {
if (megaphoneRepository == null) { if (megaphoneRepository == null) {
megaphoneRepository = provider.provideMegaphoneRepository(); megaphoneRepository = provider.provideMegaphoneRepository();
} }
}
}
return megaphoneRepository; return megaphoneRepository;
} }
public static synchronized @NonNull EarlyMessageCache getEarlyMessageCache() { public static @NonNull EarlyMessageCache getEarlyMessageCache() {
assertInitialization(); if (earlyMessageCache == null) {
synchronized (LOCK) {
if (earlyMessageCache == null) { if (earlyMessageCache == null) {
earlyMessageCache = provider.provideEarlyMessageCache(); earlyMessageCache = provider.provideEarlyMessageCache();
} }
}
}
return earlyMessageCache; return earlyMessageCache;
} }
public static synchronized @NonNull MessageNotifier getMessageNotifier() { public static @NonNull MessageNotifier getMessageNotifier() {
assertInitialization();
return messageNotifier; return messageNotifier;
} }
public static synchronized @NonNull IncomingMessageObserver getIncomingMessageObserver() { public static @NonNull IncomingMessageObserver getIncomingMessageObserver() {
assertInitialization(); if (incomingMessageObserver == null) {
synchronized (LOCK) {
if (incomingMessageObserver == null) { if (incomingMessageObserver == null) {
incomingMessageObserver = provider.provideIncomingMessageObserver(); incomingMessageObserver = provider.provideIncomingMessageObserver();
} }
}
}
return incomingMessageObserver; return incomingMessageObserver;
} }
public static synchronized @NonNull TrimThreadsByDateManager getTrimThreadsByDateManager() { public static @NonNull TrimThreadsByDateManager getTrimThreadsByDateManager() {
assertInitialization();
return trimThreadsByDateManager; return trimThreadsByDateManager;
} }
public static TypingStatusRepository getTypingStatusRepository() { public static TypingStatusRepository getTypingStatusRepository() {
assertInitialization();
if (typingStatusRepository == null) { if (typingStatusRepository == null) {
typingStatusRepository = provider.provideTypingStatusRepository(); typingStatusRepository = provider.provideTypingStatusRepository();
} }
@ -268,8 +292,6 @@ public class ApplicationDependencies {
} }
public static TypingStatusSender getTypingStatusSender() { public static TypingStatusSender getTypingStatusSender() {
assertInitialization();
if (typingStatusSender == null) { if (typingStatusSender == null) {
typingStatusSender = provider.provideTypingStatusSender(); typingStatusSender = provider.provideTypingStatusSender();
} }
@ -277,12 +299,6 @@ public class ApplicationDependencies {
return typingStatusSender; return typingStatusSender;
} }
private static void assertInitialization() {
if (application == null || provider == null) {
throw new UninitializedException();
}
}
public interface Provider { public interface Provider {
@NonNull GroupsV2Operations provideGroupsV2Operations(); @NonNull GroupsV2Operations provideGroupsV2Operations();
@NonNull SignalServiceAccountManager provideSignalServiceAccountManager(); @NonNull SignalServiceAccountManager provideSignalServiceAccountManager();
@ -302,10 +318,4 @@ public class ApplicationDependencies {
@NonNull TypingStatusRepository provideTypingStatusRepository(); @NonNull TypingStatusRepository provideTypingStatusRepository();
@NonNull TypingStatusSender provideTypingStatusSender(); @NonNull TypingStatusSender provideTypingStatusSender();
} }
private static class UninitializedException extends IllegalStateException {
private UninitializedException() {
super("You must call init() first!");
}
}
} }