Improve reliability of launching FCM foreground service.

We were getting weird errors around the service not calling
startForeground() that I couldn't reproduce. I figure it must be
something with how we only sometimes start the FcmFetchService in the
foreground. So I think the safest thing to do is to just use
GenericForegroundService.
fork-5.53.8
Greyson Parrelli 2022-04-26 11:22:01 -04:00 zatwierdzone przez GitHub
rodzic 65372e547a
commit 797c02e893
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
4 zmienionych plików z 38 dodań i 30 usunięć

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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