diff --git a/app/src/main/java/org/thoughtcrime/securesms/gcm/FcmFetchService.java b/app/src/main/java/org/thoughtcrime/securesms/gcm/FcmFetchService.java index b54c1fa08a35fbe6333676b48f1c351a14ee1dfe..ea9bca75909458e9eb1baa185ab3605f1cb0b240 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/gcm/FcmFetchService.java +++ b/app/src/main/java/org/thoughtcrime/securesms/gcm/FcmFetchService.java @@ -24,9 +24,12 @@ import org.thoughtcrime.securesms.messages.BackgroundMessageRetriever; import org.thoughtcrime.securesms.messages.RestStrategy; import org.thoughtcrime.securesms.notifications.NotificationChannels; import org.thoughtcrime.securesms.notifications.NotificationIds; +import org.thoughtcrime.securesms.service.GenericForegroundService; +import org.thoughtcrime.securesms.service.NotificationController; import org.thoughtcrime.securesms.util.concurrent.SerialMonoLifoExecutor; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; /** * This service does the actual network fetch in response to an FCM message. @@ -54,7 +57,8 @@ public class FcmFetchService extends Service { private static final SerialMonoLifoExecutor EXECUTOR = new SerialMonoLifoExecutor(SignalExecutors.UNBOUNDED); - private final AtomicInteger activeCount = new AtomicInteger(0); + private final AtomicInteger activeCount = new AtomicInteger(0); + private final AtomicReference<NotificationController> foregroundController = new AtomicReference<>(); public static @NonNull Intent buildIntent(@NonNull Context context, boolean foreground) { Intent intent = new Intent(context, FcmFetchService.class); @@ -73,16 +77,18 @@ public class FcmFetchService extends Service { Log.i(TAG, "Incrementing active count to " + count); } - if (intent.getBooleanExtra(KEY_FOREGROUND, false)) { - Log.i(TAG, "Launching in the foreground."); - startForeground(NotificationIds.FCM_FETCH, new NotificationCompat.Builder(this, NotificationChannels.OTHER) - .setSmallIcon(R.drawable.ic_notification) - .setContentTitle(getString(R.string.BackgroundMessageRetriever_checking_for_messages)) - .setCategory(NotificationCompat.CATEGORY_SERVICE) - .setProgress(0, 0, true) - .setContentIntent(PendingIntent.getActivity(this, 0, MainActivity.clearTop(this), 0)) - .setVibrate(new long[] { 0 }) - .build()); + synchronized (foregroundController) { + boolean useForeground = intent.getBooleanExtra(KEY_FOREGROUND, false); + boolean hasController = foregroundController.get() != null; + + if (useForeground && !hasController) { + Log.i(TAG, "Launching in the foreground."); + NotificationController controller = GenericForegroundService.startForegroundTask(this, getString(R.string.BackgroundMessageRetriever_checking_for_messages), NotificationChannels.OTHER); + controller.setIndeterminateProgress(); + foregroundController.set(controller); + } else { + Log.i(TAG, "Launching in the background. (useForeground: " + useForeground + ", hasController: " + hasController + ")"); + } } return START_NOT_STICKY; @@ -104,6 +110,15 @@ public class FcmFetchService extends Service { if (activeCount.decrementAndGet() == 0) { Log.d(TAG, "No more active. Stopping."); stopSelf(); + + synchronized (foregroundController) { + NotificationController activeController = foregroundController.get(); + if (activeController != null) { + Log.d(TAG, "Stopping foreground notification."); + activeController.close(); + foregroundController.set(null); + } + } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/gcm/FcmReceiveService.java b/app/src/main/java/org/thoughtcrime/securesms/gcm/FcmReceiveService.java index fe57f237cec27e51aaa39eefa6a9dff4d65f7dc1..44a78f518708f469ba596c9eaefb28f8a963ba21 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/gcm/FcmReceiveService.java +++ b/app/src/main/java/org/thoughtcrime/securesms/gcm/FcmReceiveService.java @@ -17,6 +17,7 @@ import org.thoughtcrime.securesms.jobs.FcmRefreshJob; import org.thoughtcrime.securesms.jobs.SubmitRateLimitPushChallengeJob; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.registration.PushChallengeRequest; +import org.thoughtcrime.securesms.util.FeatureFlags; import java.util.Locale; import java.util.concurrent.TimeUnit; @@ -79,8 +80,8 @@ public class FcmReceiveService extends FirebaseMessagingService { private static void handleReceivedNotification(Context context, @Nullable RemoteMessage remoteMessage) { try { long timeSinceLastRefresh = System.currentTimeMillis() - SignalStore.misc().getLastFcmForegroundServiceTime(); - if (Build.VERSION.SDK_INT >= 31 && remoteMessage != null && remoteMessage.getPriority() == RemoteMessage.PRIORITY_HIGH && timeSinceLastRefresh > FCM_FOREGROUND_INTERVAL) { - ContextCompat.startForegroundService(context, FcmFetchService.buildIntent(context, true)); + if (FeatureFlags.useFcmForegroundService() && Build.VERSION.SDK_INT >= 31 && remoteMessage != null && remoteMessage.getPriority() == RemoteMessage.PRIORITY_HIGH && timeSinceLastRefresh > FCM_FOREGROUND_INTERVAL) { + context.startService(FcmFetchService.buildIntent(context, true)); SignalStore.misc().setLastFcmForegroundServiceTime(System.currentTimeMillis()); } else { context.startService(FcmFetchService.buildIntent(context, false)); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushReceivedJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushReceivedJob.java deleted file mode 100644 index 1341b760db0ad8564b2137fac6ec9064f8025a0a..0000000000000000000000000000000000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushReceivedJob.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - -import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.jobmanager.Job; - -public abstract class PushReceivedJob extends BaseJob { - - private static final String TAG = Log.tag(PushReceivedJob.class); - - - protected PushReceivedJob(Job.Parameters parameters) { - super(parameters); - } - -} 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 1912ceb1246c9268fed7d5bde474c092c9bc1906..83315ce06eb4e7d30713be24183aa8847eae6ae4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java @@ -96,6 +96,7 @@ public final class FeatureFlags { private static final String USE_AEC3 = "android.calling.useAec3"; private static final String PAYMENTS_COUNTRY_BLOCKLIST = "android.payments.blocklist"; private static final String PNP_CDS = "android.pnp.cds"; + private static final String USE_FCM_FOREGROUND_SERVICE = "android.useFcmForegroundService"; /** * We will only store remote values for flags in this set. If you want a flag to be controllable @@ -143,7 +144,8 @@ public final class FeatureFlags { SOFTWARE_AEC_BLOCKLIST_MODELS, USE_HARDWARE_AEC_IF_OLD, USE_AEC3, - PAYMENTS_COUNTRY_BLOCKLIST + PAYMENTS_COUNTRY_BLOCKLIST, + USE_FCM_FOREGROUND_SERVICE ); @VisibleForTesting @@ -203,7 +205,8 @@ public final class FeatureFlags { SOFTWARE_AEC_BLOCKLIST_MODELS, USE_HARDWARE_AEC_IF_OLD, USE_AEC3, - PAYMENTS_COUNTRY_BLOCKLIST + PAYMENTS_COUNTRY_BLOCKLIST, + USE_FCM_FOREGROUND_SERVICE ); /** @@ -505,6 +508,10 @@ public final class FeatureFlags { return Environment.IS_STAGING && getBoolean(PNP_CDS, false); } + public static boolean useFcmForegroundService() { + return getBoolean(USE_FCM_FOREGROUND_SERVICE, false); + } + /** Only for rendering debug info. */ public static synchronized @NonNull Map<String, Object> getMemoryValues() { return new TreeMap<>(REMOTE_VALUES);