Improve and streamline Application#onCreate.
This commit is contained in:
parent
c27300c19d
commit
cdd7b2deb9
13 changed files with 205 additions and 117 deletions
|
@ -16,12 +16,12 @@
|
||||||
*/
|
*/
|
||||||
package org.thoughtcrime.securesms;
|
package org.thoughtcrime.securesms;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.WorkerThread;
|
||||||
import androidx.appcompat.app.AppCompatDelegate;
|
import androidx.appcompat.app.AppCompatDelegate;
|
||||||
import androidx.lifecycle.DefaultLifecycleObserver;
|
import androidx.lifecycle.DefaultLifecycleObserver;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
|
@ -44,6 +44,7 @@ import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
|
||||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencyProvider;
|
import org.thoughtcrime.securesms.dependencies.ApplicationDependencyProvider;
|
||||||
import org.thoughtcrime.securesms.gcm.FcmJobService;
|
import org.thoughtcrime.securesms.gcm.FcmJobService;
|
||||||
|
import org.thoughtcrime.securesms.jobmanager.JobManager;
|
||||||
import org.thoughtcrime.securesms.jobs.CreateSignedPreKeyJob;
|
import org.thoughtcrime.securesms.jobs.CreateSignedPreKeyJob;
|
||||||
import org.thoughtcrime.securesms.jobs.FcmRefreshJob;
|
import org.thoughtcrime.securesms.jobs.FcmRefreshJob;
|
||||||
import org.thoughtcrime.securesms.jobs.GroupV1MigrationJob;
|
import org.thoughtcrime.securesms.jobs.GroupV1MigrationJob;
|
||||||
|
@ -69,6 +70,7 @@ import org.thoughtcrime.securesms.service.RotateSenderCertificateListener;
|
||||||
import org.thoughtcrime.securesms.service.RotateSignedPreKeyListener;
|
import org.thoughtcrime.securesms.service.RotateSignedPreKeyListener;
|
||||||
import org.thoughtcrime.securesms.service.UpdateApkRefreshListener;
|
import org.thoughtcrime.securesms.service.UpdateApkRefreshListener;
|
||||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper;
|
import org.thoughtcrime.securesms.storage.StorageSyncHelper;
|
||||||
|
import org.thoughtcrime.securesms.util.AppStartup;
|
||||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||||
import org.thoughtcrime.securesms.util.SignalUncaughtExceptionHandler;
|
import org.thoughtcrime.securesms.util.SignalUncaughtExceptionHandler;
|
||||||
|
@ -118,40 +120,42 @@ public class ApplicationContext extends MultiDexApplication implements DefaultLi
|
||||||
|
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
|
||||||
initializeSecurityProvider();
|
new AppStartup().addBlocking("security-provider", this::initializeSecurityProvider)
|
||||||
|
.addBlocking("logging", () -> {
|
||||||
initializeLogging();
|
initializeLogging();
|
||||||
Log.i(TAG, "onCreate()");
|
Log.i(TAG, "onCreate()");
|
||||||
initializeCrashHandling();
|
})
|
||||||
initializeAppDependencies();
|
.addBlocking("crash-handling", this::initializeCrashHandling)
|
||||||
initializeFirstEverAppLaunch();
|
.addBlocking("eat-db", () -> DatabaseFactory.getInstance(this))
|
||||||
initializeApplicationMigrations();
|
.addBlocking("app-dependencies", this::initializeAppDependencies)
|
||||||
initializeMessageRetrieval();
|
.addBlocking("first-launch", this::initializeFirstEverAppLaunch)
|
||||||
initializeExpiringMessageManager();
|
.addBlocking("app-migrations", this::initializeApplicationMigrations)
|
||||||
initializeRevealableMessageManager();
|
.addBlocking("ring-rtc", this::initializeRingRtc)
|
||||||
initializeGcmCheck();
|
.addBlocking("mark-registration", () -> RegistrationUtil.maybeMarkRegistrationComplete(this))
|
||||||
initializeSignedPreKeyCheck();
|
.addBlocking("lifecycle-observer", () -> ProcessLifecycleOwner.get().getLifecycle().addObserver(this))
|
||||||
initializePeriodicTasks();
|
.addBlocking("dynamic-theme", () -> DynamicTheme.setDefaultDayNightMode(this))
|
||||||
initializeCircumvention();
|
.addBlocking("vector-compat", () -> {
|
||||||
initializeRingRtc();
|
|
||||||
initializePendingMessages();
|
|
||||||
initializeBlobProvider();
|
|
||||||
initializeCleanup();
|
|
||||||
initializeGlideCodecs();
|
|
||||||
|
|
||||||
FeatureFlags.init();
|
|
||||||
NotificationChannels.create(this);
|
|
||||||
RefreshPreKeysJob.scheduleIfNecessary();
|
|
||||||
StorageSyncHelper.scheduleRoutineSync();
|
|
||||||
RegistrationUtil.maybeMarkRegistrationComplete(this);
|
|
||||||
ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
|
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT < 21) {
|
if (Build.VERSION.SDK_INT < 21) {
|
||||||
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
|
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
|
||||||
}
|
}
|
||||||
|
})
|
||||||
ApplicationDependencies.getJobManager().beginJobLoop();
|
.addDeferred(this::initializeMessageRetrieval)
|
||||||
|
.addDeferred(this::initializeExpiringMessageManager)
|
||||||
DynamicTheme.setDefaultDayNightMode(this);
|
.addDeferred(this::initializeRevealableMessageManager)
|
||||||
|
.addDeferred(this::initializeGcmCheck)
|
||||||
|
.addDeferred(this::initializeSignedPreKeyCheck)
|
||||||
|
.addDeferred(this::initializePeriodicTasks)
|
||||||
|
.addDeferred(this::initializeCircumvention)
|
||||||
|
.addDeferred(this::initializePendingMessages)
|
||||||
|
.addDeferred(this::initializeBlobProvider)
|
||||||
|
.addDeferred(this::initializeCleanup)
|
||||||
|
.addDeferred(this::initializeGlideCodecs)
|
||||||
|
.addDeferred(FeatureFlags::init)
|
||||||
|
.addDeferred(() -> NotificationChannels.create(this))
|
||||||
|
.addDeferred(RefreshPreKeysJob::scheduleIfNecessary)
|
||||||
|
.addDeferred(StorageSyncHelper::scheduleRoutineSync)
|
||||||
|
.addDeferred(() -> ApplicationDependencies.getJobManager().beginJobLoop())
|
||||||
|
.execute();
|
||||||
|
|
||||||
Log.d(TAG, "onCreate() took " + (System.currentTimeMillis() - startTime) + " ms");
|
Log.d(TAG, "onCreate() took " + (System.currentTimeMillis() - startTime) + " ms");
|
||||||
Tracer.getInstance().end("Application#onCreate()");
|
Tracer.getInstance().end("Application#onCreate()");
|
||||||
|
@ -159,17 +163,24 @@ public class ApplicationContext extends MultiDexApplication implements DefaultLi
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStart(@NonNull LifecycleOwner owner) {
|
public void onStart(@NonNull LifecycleOwner owner) {
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
isAppVisible = true;
|
isAppVisible = true;
|
||||||
Log.i(TAG, "App is now visible.");
|
Log.i(TAG, "App is now visible.");
|
||||||
|
|
||||||
|
ApplicationDependencies.getFrameRateTracker().begin();
|
||||||
|
|
||||||
|
SignalExecutors.BOUNDED.execute(() -> {
|
||||||
FeatureFlags.refreshIfNecessary();
|
FeatureFlags.refreshIfNecessary();
|
||||||
ApplicationDependencies.getRecipientCache().warmUp();
|
ApplicationDependencies.getRecipientCache().warmUp();
|
||||||
RetrieveProfileJob.enqueueRoutineFetchIfNecessary(this);
|
RetrieveProfileJob.enqueueRoutineFetchIfNecessary(this);
|
||||||
GroupV1MigrationJob.enqueueRoutineMigrationsIfNecessary(this);
|
GroupV1MigrationJob.enqueueRoutineMigrationsIfNecessary(this);
|
||||||
executePendingContactSync();
|
executePendingContactSync();
|
||||||
KeyCachingService.onAppForegrounded(this);
|
KeyCachingService.onAppForegrounded(this);
|
||||||
ApplicationDependencies.getFrameRateTracker().begin();
|
|
||||||
ApplicationDependencies.getMegaphoneRepository().onAppForegrounded();
|
ApplicationDependencies.getMegaphoneRepository().onAppForegrounded();
|
||||||
checkBuildExpiration();
|
checkBuildExpiration();
|
||||||
|
});
|
||||||
|
|
||||||
|
Log.d(TAG, "onStart() took " + (System.currentTimeMillis() - startTime) + " ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -335,9 +346,8 @@ public class ApplicationContext extends MultiDexApplication implements DefaultLi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("StaticFieldLeak")
|
@WorkerThread
|
||||||
private void initializeCircumvention() {
|
private void initializeCircumvention() {
|
||||||
SignalExecutors.BOUNDED.execute(() -> {
|
|
||||||
if (new SignalServiceNetworkAccess(ApplicationContext.this).isCensored(ApplicationContext.this)) {
|
if (new SignalServiceNetworkAccess(ApplicationContext.this).isCensored(ApplicationContext.this)) {
|
||||||
try {
|
try {
|
||||||
ProviderInstaller.installIfNeeded(ApplicationContext.this);
|
ProviderInstaller.installIfNeeded(ApplicationContext.this);
|
||||||
|
@ -345,7 +355,6 @@ public class ApplicationContext extends MultiDexApplication implements DefaultLi
|
||||||
Log.w(TAG, t);
|
Log.w(TAG, t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void executePendingContactSync() {
|
private void executePendingContactSync() {
|
||||||
|
@ -366,17 +375,15 @@ public class ApplicationContext extends MultiDexApplication implements DefaultLi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@WorkerThread
|
||||||
private void initializeBlobProvider() {
|
private void initializeBlobProvider() {
|
||||||
SignalExecutors.BOUNDED.execute(() -> {
|
|
||||||
BlobProvider.getInstance().onSessionStart(this);
|
BlobProvider.getInstance().onSessionStart(this);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@WorkerThread
|
||||||
private void initializeCleanup() {
|
private void initializeCleanup() {
|
||||||
SignalExecutors.BOUNDED.execute(() -> {
|
|
||||||
int deleted = DatabaseFactory.getAttachmentDatabase(this).deleteAbandonedPreuploadedAttachments();
|
int deleted = DatabaseFactory.getAttachmentDatabase(this).deleteAbandonedPreuploadedAttachments();
|
||||||
Log.i(TAG, "Deleted " + deleted + " abandoned attachments.");
|
Log.i(TAG, "Deleted " + deleted + " abandoned attachments.");
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeGlideCodecs() {
|
private void initializeGlideCodecs() {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package org.thoughtcrime.securesms.components;
|
package org.thoughtcrime.securesms.components;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
|
import android.app.Application;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
@ -21,11 +22,9 @@ 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;
|
||||||
|
|
||||||
public TypingStatusSender(@NonNull Context context) {
|
public TypingStatusSender() {
|
||||||
this.context = context;
|
|
||||||
this.selfTypingTimers = new HashMap<>();
|
this.selfTypingTimers = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ public class DatabaseFactory {
|
||||||
|
|
||||||
private static final Object lock = new Object();
|
private static final Object lock = new Object();
|
||||||
|
|
||||||
private static DatabaseFactory instance;
|
private static volatile DatabaseFactory instance;
|
||||||
|
|
||||||
private final SQLCipherOpenHelper databaseHelper;
|
private final SQLCipherOpenHelper databaseHelper;
|
||||||
private final SmsDatabase sms;
|
private final SmsDatabase sms;
|
||||||
|
@ -67,13 +67,15 @@ public class DatabaseFactory {
|
||||||
private final MentionDatabase mentionDatabase;
|
private final MentionDatabase mentionDatabase;
|
||||||
|
|
||||||
public static DatabaseFactory getInstance(Context context) {
|
public static DatabaseFactory getInstance(Context context) {
|
||||||
|
if (instance == null) {
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
if (instance == null)
|
if (instance == null) {
|
||||||
instance = new DatabaseFactory(context.getApplicationContext());
|
instance = new DatabaseFactory(context.getApplicationContext());
|
||||||
|
|
||||||
return instance;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
public static MmsSmsDatabase getMmsSmsDatabase(Context context) {
|
public static MmsSmsDatabase getMmsSmsDatabase(Context context) {
|
||||||
return getInstance(context).mmsSmsDatabase;
|
return getInstance(context).mmsSmsDatabase;
|
||||||
|
|
|
@ -5,7 +5,6 @@ import android.app.Application;
|
||||||
import androidx.annotation.MainThread;
|
import androidx.annotation.MainThread;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import org.signal.core.util.tracing.Tracer;
|
|
||||||
import org.thoughtcrime.securesms.KbsEnclave;
|
import org.thoughtcrime.securesms.KbsEnclave;
|
||||||
import org.thoughtcrime.securesms.components.TypingStatusRepository;
|
import org.thoughtcrime.securesms.components.TypingStatusRepository;
|
||||||
import org.thoughtcrime.securesms.components.TypingStatusSender;
|
import org.thoughtcrime.securesms.components.TypingStatusSender;
|
||||||
|
@ -24,7 +23,6 @@ import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess;
|
||||||
import org.thoughtcrime.securesms.recipients.LiveRecipientCache;
|
import org.thoughtcrime.securesms.recipients.LiveRecipientCache;
|
||||||
import org.thoughtcrime.securesms.service.TrimThreadsByDateManager;
|
import org.thoughtcrime.securesms.service.TrimThreadsByDateManager;
|
||||||
import org.thoughtcrime.securesms.util.EarlyMessageCache;
|
import org.thoughtcrime.securesms.util.EarlyMessageCache;
|
||||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
|
||||||
import org.thoughtcrime.securesms.util.FrameRateTracker;
|
import org.thoughtcrime.securesms.util.FrameRateTracker;
|
||||||
import org.thoughtcrime.securesms.util.Hex;
|
import org.thoughtcrime.securesms.util.Hex;
|
||||||
import org.thoughtcrime.securesms.util.IasKeyStore;
|
import org.thoughtcrime.securesms.util.IasKeyStore;
|
||||||
|
@ -47,11 +45,11 @@ public class ApplicationDependencies {
|
||||||
|
|
||||||
private static final Object LOCK = new Object();
|
private static final Object LOCK = new Object();
|
||||||
private static final Object FRAME_RATE_TRACKER_LOCK = new Object();
|
private static final Object FRAME_RATE_TRACKER_LOCK = new Object();
|
||||||
|
private static final Object JOB_MANAGER_LOCK = new Object();
|
||||||
|
|
||||||
private static Application application;
|
private static Application application;
|
||||||
private static Provider provider;
|
private static Provider provider;
|
||||||
private static MessageNotifier messageNotifier;
|
private static MessageNotifier messageNotifier;
|
||||||
private static TrimThreadsByDateManager trimThreadsByDateManager;
|
|
||||||
|
|
||||||
private static volatile SignalServiceAccountManager accountManager;
|
private static volatile SignalServiceAccountManager accountManager;
|
||||||
private static volatile SignalServiceMessageSender messageSender;
|
private static volatile SignalServiceMessageSender messageSender;
|
||||||
|
@ -70,7 +68,7 @@ public class ApplicationDependencies {
|
||||||
private static volatile TypingStatusRepository typingStatusRepository;
|
private static volatile TypingStatusRepository typingStatusRepository;
|
||||||
private static volatile TypingStatusSender typingStatusSender;
|
private static volatile TypingStatusSender typingStatusSender;
|
||||||
private static volatile DatabaseObserver databaseObserver;
|
private static volatile DatabaseObserver databaseObserver;
|
||||||
private static volatile Tracer tracer;
|
private static volatile TrimThreadsByDateManager trimThreadsByDateManager;
|
||||||
|
|
||||||
@MainThread
|
@MainThread
|
||||||
public static void init(@NonNull Application application, @NonNull Provider provider) {
|
public static void init(@NonNull Application application, @NonNull Provider provider) {
|
||||||
|
@ -82,7 +80,6 @@ public class ApplicationDependencies {
|
||||||
ApplicationDependencies.application = application;
|
ApplicationDependencies.application = application;
|
||||||
ApplicationDependencies.provider = provider;
|
ApplicationDependencies.provider = provider;
|
||||||
ApplicationDependencies.messageNotifier = provider.provideMessageNotifier();
|
ApplicationDependencies.messageNotifier = provider.provideMessageNotifier();
|
||||||
ApplicationDependencies.trimThreadsByDateManager = provider.provideTrimThreadsByDateManager();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,7 +219,7 @@ public class ApplicationDependencies {
|
||||||
|
|
||||||
public static @NonNull JobManager getJobManager() {
|
public static @NonNull JobManager getJobManager() {
|
||||||
if (jobManager == null) {
|
if (jobManager == null) {
|
||||||
synchronized (LOCK) {
|
synchronized (JOB_MANAGER_LOCK) {
|
||||||
if (jobManager == null) {
|
if (jobManager == null) {
|
||||||
jobManager = provider.provideJobManager();
|
jobManager = provider.provideJobManager();
|
||||||
}
|
}
|
||||||
|
@ -285,6 +282,14 @@ public class ApplicationDependencies {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static @NonNull TrimThreadsByDateManager getTrimThreadsByDateManager() {
|
public static @NonNull TrimThreadsByDateManager getTrimThreadsByDateManager() {
|
||||||
|
if (trimThreadsByDateManager == null) {
|
||||||
|
synchronized (LOCK) {
|
||||||
|
if (trimThreadsByDateManager == null) {
|
||||||
|
trimThreadsByDateManager = provider.provideTrimThreadsByDateManager();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return trimThreadsByDateManager;
|
return trimThreadsByDateManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,10 +15,14 @@ import org.thoughtcrime.securesms.crypto.storage.SignalProtocolStoreImpl;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseObserver;
|
import org.thoughtcrime.securesms.database.DatabaseObserver;
|
||||||
import org.thoughtcrime.securesms.events.ReminderUpdateEvent;
|
import org.thoughtcrime.securesms.events.ReminderUpdateEvent;
|
||||||
|
import org.thoughtcrime.securesms.jobmanager.Constraint;
|
||||||
|
import org.thoughtcrime.securesms.jobmanager.ConstraintObserver;
|
||||||
|
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||||
import org.thoughtcrime.securesms.jobmanager.JobManager;
|
import org.thoughtcrime.securesms.jobmanager.JobManager;
|
||||||
import org.thoughtcrime.securesms.jobmanager.JobMigrator;
|
import org.thoughtcrime.securesms.jobmanager.JobMigrator;
|
||||||
import org.thoughtcrime.securesms.jobmanager.impl.FactoryJobPredicate;
|
import org.thoughtcrime.securesms.jobmanager.impl.FactoryJobPredicate;
|
||||||
import org.thoughtcrime.securesms.jobmanager.impl.JsonDataSerializer;
|
import org.thoughtcrime.securesms.jobmanager.impl.JsonDataSerializer;
|
||||||
|
import org.thoughtcrime.securesms.jobmanager.persistence.JobStorage;
|
||||||
import org.thoughtcrime.securesms.jobs.FastJobStorage;
|
import org.thoughtcrime.securesms.jobs.FastJobStorage;
|
||||||
import org.thoughtcrime.securesms.jobs.GroupCallUpdateSendJob;
|
import org.thoughtcrime.securesms.jobs.GroupCallUpdateSendJob;
|
||||||
import org.thoughtcrime.securesms.jobs.JobManagerFactories;
|
import org.thoughtcrime.securesms.jobs.JobManagerFactories;
|
||||||
|
@ -140,7 +144,7 @@ public class ApplicationDependencyProvider implements ApplicationDependencies.Pr
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull JobManager provideJobManager() {
|
public @NonNull JobManager provideJobManager() {
|
||||||
return new JobManager(context, new JobManager.Configuration.Builder()
|
JobManager.Configuration config = new JobManager.Configuration.Builder()
|
||||||
.setDataSerializer(new JsonDataSerializer())
|
.setDataSerializer(new JsonDataSerializer())
|
||||||
.setJobFactories(JobManagerFactories.getJobFactories(context))
|
.setJobFactories(JobManagerFactories.getJobFactories(context))
|
||||||
.setConstraintFactories(JobManagerFactories.getConstraintFactories(context))
|
.setConstraintFactories(JobManagerFactories.getConstraintFactories(context))
|
||||||
|
@ -149,7 +153,8 @@ public class ApplicationDependencyProvider implements ApplicationDependencies.Pr
|
||||||
.setJobMigrator(new JobMigrator(TextSecurePreferences.getJobManagerVersion(context), JobManager.CURRENT_VERSION, JobManagerFactories.getJobMigrations(context)))
|
.setJobMigrator(new JobMigrator(TextSecurePreferences.getJobManagerVersion(context), JobManager.CURRENT_VERSION, JobManagerFactories.getJobMigrations(context)))
|
||||||
.addReservedJobRunner(new FactoryJobPredicate(PushDecryptMessageJob.KEY, PushProcessMessageJob.KEY, MarkerJob.KEY))
|
.addReservedJobRunner(new FactoryJobPredicate(PushDecryptMessageJob.KEY, PushProcessMessageJob.KEY, MarkerJob.KEY))
|
||||||
.addReservedJobRunner(new FactoryJobPredicate(PushTextSendJob.KEY, PushMediaSendJob.KEY, PushGroupSendJob.KEY, ReactionSendJob.KEY, TypingSendJob.KEY, GroupCallUpdateSendJob.KEY))
|
.addReservedJobRunner(new FactoryJobPredicate(PushTextSendJob.KEY, PushMediaSendJob.KEY, PushGroupSendJob.KEY, ReactionSendJob.KEY, TypingSendJob.KEY, GroupCallUpdateSendJob.KEY))
|
||||||
.build());
|
.build();
|
||||||
|
return new JobManager(context, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -188,7 +193,7 @@ public class ApplicationDependencyProvider implements ApplicationDependencies.Pr
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull TypingStatusSender provideTypingStatusSender() {
|
public @NonNull TypingStatusSender provideTypingStatusSender() {
|
||||||
return new TypingStatusSender(context);
|
return new TypingStatusSender();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -8,6 +8,7 @@ import android.telephony.TelephonyManager;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import org.signal.core.util.concurrent.SignalExecutors;
|
||||||
import org.thoughtcrime.securesms.jobmanager.ConstraintObserver;
|
import org.thoughtcrime.securesms.jobmanager.ConstraintObserver;
|
||||||
|
|
||||||
public class CellServiceConstraintObserver implements ConstraintObserver {
|
public class CellServiceConstraintObserver implements ConstraintObserver {
|
||||||
|
@ -17,12 +18,16 @@ public class CellServiceConstraintObserver implements ConstraintObserver {
|
||||||
private volatile Notifier notifier;
|
private volatile Notifier notifier;
|
||||||
private volatile ServiceState lastKnownState;
|
private volatile ServiceState lastKnownState;
|
||||||
|
|
||||||
private static CellServiceConstraintObserver instance;
|
private static volatile CellServiceConstraintObserver instance;
|
||||||
|
|
||||||
public static synchronized CellServiceConstraintObserver getInstance(@NonNull Application application) {
|
public static CellServiceConstraintObserver getInstance(@NonNull Application application) {
|
||||||
|
if (instance == null) {
|
||||||
|
synchronized (CellServiceConstraintObserver.class) {
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
instance = new CellServiceConstraintObserver(application);
|
instance = new CellServiceConstraintObserver(application);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +35,9 @@ public class CellServiceConstraintObserver implements ConstraintObserver {
|
||||||
TelephonyManager telephonyManager = (TelephonyManager) application.getSystemService(Context.TELEPHONY_SERVICE);
|
TelephonyManager telephonyManager = (TelephonyManager) application.getSystemService(Context.TELEPHONY_SERVICE);
|
||||||
ServiceStateListener serviceStateListener = new ServiceStateListener();
|
ServiceStateListener serviceStateListener = new ServiceStateListener();
|
||||||
|
|
||||||
|
SignalExecutors.BOUNDED.execute(() -> {
|
||||||
telephonyManager.listen(serviceStateListener, PhoneStateListener.LISTEN_SERVICE_STATE);
|
telephonyManager.listen(serviceStateListener, PhoneStateListener.LISTEN_SERVICE_STATE);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -13,18 +13,10 @@ public class DecryptionsDrainedConstraintObserver implements ConstraintObserver
|
||||||
|
|
||||||
private static final String REASON = DecryptionsDrainedConstraintObserver.class.getSimpleName();
|
private static final String REASON = DecryptionsDrainedConstraintObserver.class.getSimpleName();
|
||||||
|
|
||||||
private volatile Notifier notifier;
|
|
||||||
|
|
||||||
public DecryptionsDrainedConstraintObserver() {
|
|
||||||
ApplicationDependencies.getIncomingMessageObserver().addDecryptionDrainedListener(() -> {
|
|
||||||
if (notifier != null) {
|
|
||||||
notifier.onConstraintMet(REASON);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void register(@NonNull Notifier notifier) {
|
public void register(@NonNull Notifier notifier) {
|
||||||
this.notifier = notifier;
|
ApplicationDependencies.getIncomingMessageObserver().addDecryptionDrainedListener(() -> {
|
||||||
|
notifier.onConstraintMet(REASON);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,8 +173,7 @@ public final class PushGroupSilentUpdateSendJob extends BaseJob {
|
||||||
|
|
||||||
public static class Factory implements Job.Factory<PushGroupSilentUpdateSendJob> {
|
public static class Factory implements Job.Factory<PushGroupSilentUpdateSendJob> {
|
||||||
@Override
|
@Override
|
||||||
public @NonNull
|
public @NonNull PushGroupSilentUpdateSendJob create(@NonNull Parameters parameters, @NonNull Data data) {
|
||||||
PushGroupSilentUpdateSendJob create(@NonNull Parameters parameters, @NonNull Data data) {
|
|
||||||
List<RecipientId> recipients = RecipientId.fromSerializedList(data.getString(KEY_RECIPIENTS));
|
List<RecipientId> recipients = RecipientId.fromSerializedList(data.getString(KEY_RECIPIENTS));
|
||||||
int initialRecipientCount = data.getInt(KEY_INITIAL_RECIPIENT_COUNT);
|
int initialRecipientCount = data.getInt(KEY_INITIAL_RECIPIENT_COUNT);
|
||||||
long timestamp = data.getLong(KEY_TIMESTAMP);
|
long timestamp = data.getLong(KEY_TIMESTAMP);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.thoughtcrime.securesms.megaphone;
|
package org.thoughtcrime.securesms.megaphone;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import androidx.annotation.AnyThread;
|
import androidx.annotation.AnyThread;
|
||||||
|
@ -28,14 +29,14 @@ import java.util.concurrent.Executor;
|
||||||
*/
|
*/
|
||||||
public class MegaphoneRepository {
|
public class MegaphoneRepository {
|
||||||
|
|
||||||
private final Context context;
|
private final Application context;
|
||||||
private final Executor executor;
|
private final Executor executor;
|
||||||
private final MegaphoneDatabase database;
|
private final MegaphoneDatabase database;
|
||||||
private final Map<Event, MegaphoneRecord> databaseCache;
|
private final Map<Event, MegaphoneRecord> databaseCache;
|
||||||
|
|
||||||
private boolean enabled;
|
private boolean enabled;
|
||||||
|
|
||||||
public MegaphoneRepository(@NonNull Context context) {
|
public MegaphoneRepository(@NonNull Application context) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.executor = SignalExecutors.SERIAL;
|
this.executor = SignalExecutors.SERIAL;
|
||||||
this.database = DatabaseFactory.getMegaphoneDatabase(context);
|
this.database = DatabaseFactory.getMegaphoneDatabase(context);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.thoughtcrime.securesms.messages;
|
package org.thoughtcrime.securesms.messages;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
@ -47,7 +48,7 @@ public class IncomingMessageObserver {
|
||||||
private static SignalServiceMessagePipe pipe = null;
|
private static SignalServiceMessagePipe pipe = null;
|
||||||
private static SignalServiceMessagePipe unidentifiedPipe = null;
|
private static SignalServiceMessagePipe unidentifiedPipe = null;
|
||||||
|
|
||||||
private final Context context;
|
private final Application context;
|
||||||
private final SignalServiceNetworkAccess networkAccess;
|
private final SignalServiceNetworkAccess networkAccess;
|
||||||
private final List<Runnable> decryptionDrainedListeners;
|
private final List<Runnable> decryptionDrainedListeners;
|
||||||
|
|
||||||
|
@ -56,7 +57,7 @@ public class IncomingMessageObserver {
|
||||||
private volatile boolean networkDrained;
|
private volatile boolean networkDrained;
|
||||||
private volatile boolean decryptionDrained;
|
private volatile boolean decryptionDrained;
|
||||||
|
|
||||||
public IncomingMessageObserver(@NonNull Context context) {
|
public IncomingMessageObserver(@NonNull Application context) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.networkAccess = ApplicationDependencies.getSignalServiceNetworkAccess();
|
this.networkAccess = ApplicationDependencies.getSignalServiceNetworkAccess();
|
||||||
this.decryptionDrainedListeners = new CopyOnWriteArrayList<>();
|
this.decryptionDrainedListeners = new CopyOnWriteArrayList<>();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.thoughtcrime.securesms.messages;
|
package org.thoughtcrime.securesms.messages;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
@ -27,10 +28,10 @@ public class IncomingMessageProcessor {
|
||||||
|
|
||||||
private static final String TAG = Log.tag(IncomingMessageProcessor.class);
|
private static final String TAG = Log.tag(IncomingMessageProcessor.class);
|
||||||
|
|
||||||
private final Context context;
|
private final Application context;
|
||||||
private final ReentrantLock lock;
|
private final ReentrantLock lock;
|
||||||
|
|
||||||
public IncomingMessageProcessor(@NonNull Context context) {
|
public IncomingMessageProcessor(@NonNull Application context) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.lock = new ReentrantLock();
|
this.lock = new ReentrantLock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
package org.thoughtcrime.securesms.util;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import org.signal.core.util.concurrent.SignalExecutors;
|
||||||
|
import org.signal.core.util.logging.Log;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public final class AppStartup {
|
||||||
|
|
||||||
|
private static final String TAG = Log.tag(AppStartup.class);
|
||||||
|
|
||||||
|
private final List<Task> blocking;
|
||||||
|
private final List<Task> deferred;
|
||||||
|
|
||||||
|
public AppStartup() {
|
||||||
|
this.blocking = new LinkedList<>();
|
||||||
|
this.deferred = new LinkedList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NonNull
|
||||||
|
AppStartup addBlocking(@NonNull String name, @NonNull Runnable task) {
|
||||||
|
blocking.add(new Task(name, task));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NonNull
|
||||||
|
AppStartup addDeferred(@NonNull Runnable task) {
|
||||||
|
deferred.add(new Task("", task));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void execute() {
|
||||||
|
Stopwatch stopwatch = new Stopwatch("init");
|
||||||
|
|
||||||
|
for (Task task : blocking) {
|
||||||
|
task.getRunnable().run();
|
||||||
|
stopwatch.split(task.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Task task : deferred) {
|
||||||
|
SignalExecutors.BOUNDED.execute(task.getRunnable());
|
||||||
|
}
|
||||||
|
|
||||||
|
stopwatch.split("schedule-deferred");
|
||||||
|
stopwatch.stop(TAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Task {
|
||||||
|
private final String name;
|
||||||
|
private final Runnable runnable;
|
||||||
|
|
||||||
|
protected Task(@NonNull String name, @NonNull Runnable runnable) {
|
||||||
|
this.name = name;
|
||||||
|
this.runnable = runnable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NonNull Runnable getRunnable() {
|
||||||
|
return runnable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package org.thoughtcrime.securesms.util;
|
package org.thoughtcrime.securesms.util;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.view.Choreographer;
|
import android.view.Choreographer;
|
||||||
import android.view.Display;
|
import android.view.Display;
|
||||||
|
@ -23,7 +24,7 @@ public class FrameRateTracker {
|
||||||
|
|
||||||
private static final int MAX_CONSECUTIVE_FRAME_LOGS = 10;
|
private static final int MAX_CONSECUTIVE_FRAME_LOGS = 10;
|
||||||
|
|
||||||
private final Context context;
|
private final Application context;
|
||||||
|
|
||||||
private double refreshRate;
|
private double refreshRate;
|
||||||
private long idealTimePerFrameNanos;
|
private long idealTimePerFrameNanos;
|
||||||
|
@ -33,8 +34,8 @@ public class FrameRateTracker {
|
||||||
|
|
||||||
private long consecutiveFrameWarnings;
|
private long consecutiveFrameWarnings;
|
||||||
|
|
||||||
public FrameRateTracker(@NonNull Context context) {
|
public FrameRateTracker(@NonNull Application application) {
|
||||||
this.context = context;
|
this.context = application;
|
||||||
|
|
||||||
updateRefreshRate();
|
updateRefreshRate();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue