diff --git a/app/src/main/java/org/thoughtcrime/securesms/messageprocessingalarm/MessageProcessReceiver.java b/app/src/main/java/org/thoughtcrime/securesms/messageprocessingalarm/MessageProcessReceiver.java index b65ca28828..4e9bf28d67 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messageprocessingalarm/MessageProcessReceiver.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messageprocessingalarm/MessageProcessReceiver.java @@ -20,7 +20,7 @@ import org.thoughtcrime.securesms.jobs.PushNotificationReceiveJob; import org.thoughtcrime.securesms.util.FeatureFlags; import org.whispersystems.libsignal.util.guava.Optional; -import java.util.concurrent.TimeUnit; +import java.util.Locale; /** * On received message, runs a job to poll for messages. @@ -29,10 +29,6 @@ public final class MessageProcessReceiver extends BroadcastReceiver { private static final String TAG = Log.tag(MessageProcessReceiver.class); - private static final long FIRST_RUN_DELAY = TimeUnit.MINUTES.toMillis(3); - private static final long FOREGROUND_DELAY = 300; - private static final long JOB_TIMEOUT = FOREGROUND_DELAY + 200; - public static final String BROADCAST_ACTION = "org.thoughtcrime.securesms.action.PROCESS_MESSAGES"; @Override @@ -44,15 +40,26 @@ public final class MessageProcessReceiver extends BroadcastReceiver { Log.i(TAG, "Starting Alarm because of boot receiver"); startOrUpdateAlarm(context); } else if (BROADCAST_ACTION.equals(intent.getAction())) { + + if (ApplicationDependencies.getAppForegroundObserver().isForegrounded()) { + Log.i(TAG, "App is foregrounded"); + return; + } + + long foregroundDelayMs = FeatureFlags.getBackgroundMessageProcessForegroundDelay(); + long jobTimeout = foregroundDelayMs + 200; + + Log.i(TAG, String.format(Locale.US, "Starting PushNotificationReceiveJob asynchronously with %d delay before foreground shown", foregroundDelayMs)); + PendingResult pendingResult = goAsync(); - new Handler(Looper.getMainLooper()).postDelayed(pendingResult::finish, JOB_TIMEOUT); + new Handler(Looper.getMainLooper()).postDelayed(pendingResult::finish, jobTimeout); SignalExecutors.BOUNDED.submit(() -> { Log.i(TAG, "Running PushNotificationReceiveJob"); Optional jobState = ApplicationDependencies.getJobManager() - .runSynchronously(PushNotificationReceiveJob.withDelayedForegroundService(FOREGROUND_DELAY), JOB_TIMEOUT); + .runSynchronously(PushNotificationReceiveJob.withDelayedForegroundService(foregroundDelayMs), jobTimeout); Log.i(TAG, "PushNotificationReceiveJob ended: " + (jobState.isPresent() ? jobState.get().toString() : "Job did not complete")); }); @@ -67,14 +74,14 @@ public final class MessageProcessReceiver extends BroadcastReceiver { PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 123, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT); AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - long interval = FeatureFlags.getBackgroundMessageProcessDelay(); + long interval = FeatureFlags.getBackgroundMessageProcessInterval(); if (interval < 0) { alarmManager.cancel(pendingIntent); Log.i(TAG, "Alarm cancelled"); } else { alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, - SystemClock.elapsedRealtime() + FIRST_RUN_DELAY, + SystemClock.elapsedRealtime() + interval, interval, pendingIntent); Log.i(TAG, "Alarm scheduled to repeat at interval " + interval); diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java b/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java index 8d01218f7c..018e620f53 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java @@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.util; import android.os.Build; import android.text.TextUtils; -import android.util.TimeUtils; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; @@ -75,6 +74,7 @@ public final class FeatureFlags { private static final String ANIMATED_STICKER_MIN_MEMORY = "android.animatedStickerMinMemory"; private static final String ANIMATED_STICKER_MIN_TOTAL_MEMORY = "android.animatedStickerMinTotalMemory"; private static final String MESSAGE_PROCESSOR_ALARM_INTERVAL = "android.messageProcessor.alarmIntervalMins"; + private static final String MESSAGE_PROCESSOR_DELAY = "android.messageProcessor.foregroundDelayMs"; /** * We will only store remote values for flags in this set. If you want a flag to be controllable @@ -104,7 +104,8 @@ public final class FeatureFlags { SHARE_SELECTION_LIMIT, ANIMATED_STICKER_MIN_MEMORY, ANIMATED_STICKER_MIN_TOTAL_MEMORY, - MESSAGE_PROCESSOR_ALARM_INTERVAL + MESSAGE_PROCESSOR_ALARM_INTERVAL, + MESSAGE_PROCESSOR_DELAY ); @VisibleForTesting @@ -146,7 +147,8 @@ public final class FeatureFlags { SHARE_SELECTION_LIMIT, ANIMATED_STICKER_MIN_MEMORY, ANIMATED_STICKER_MIN_TOTAL_MEMORY, - MESSAGE_PROCESSOR_ALARM_INTERVAL + MESSAGE_PROCESSOR_ALARM_INTERVAL, + MESSAGE_PROCESSOR_DELAY ); /** @@ -463,11 +465,18 @@ public final class FeatureFlags { } } - public static long getBackgroundMessageProcessDelay() { + public static long getBackgroundMessageProcessInterval() { int delayMinutes = getInteger(MESSAGE_PROCESSOR_ALARM_INTERVAL, (int) TimeUnit.HOURS.toMinutes(6)); return TimeUnit.MINUTES.toMillis(delayMinutes); } + /** + * How long before a "Checking messages" foreground notification is shown to the user. + */ + public static long getBackgroundMessageProcessForegroundDelay() { + return getInteger(MESSAGE_PROCESSOR_DELAY, 300); + } + private enum VersionFlag { /** The flag is no set */ OFF,