Improve and streamline Application#onCreate.

This commit is contained in:
Greyson Parrelli 2020-12-20 14:45:51 -05:00 committed by Alan Evans
parent c27300c19d
commit cdd7b2deb9
13 changed files with 205 additions and 117 deletions

View file

@ -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() {

View file

@ -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<>();
} }

View file

@ -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;

View file

@ -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;
} }

View file

@ -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

View file

@ -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

View file

@ -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);
});
} }
} }

View file

@ -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);

View file

@ -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);

View file

@ -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<>();

View file

@ -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();
} }

View file

@ -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;
}
}
}

View file

@ -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();
} }