Increase FCM push websocket timeout.

This commit is contained in:
Clark
2023-06-30 12:41:00 -04:00
committed by GitHub
parent 3aa0fd1937
commit 13470fb0c3
3 changed files with 35 additions and 4 deletions

View File

@@ -5,6 +5,7 @@ import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.IBinder
import android.os.PowerManager
import androidx.core.app.NotificationCompat
import org.signal.core.util.PendingIntentFlags
import org.signal.core.util.logging.Log
@@ -12,16 +13,23 @@ import org.thoughtcrime.securesms.MainActivity
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.notifications.NotificationChannels
import org.thoughtcrime.securesms.notifications.NotificationIds
import org.thoughtcrime.securesms.util.WakeLockUtil
/**
* Works with {@link FcmFetchManager} to exists as a service that will keep the app process running in the foreground while we fetch messages.
*/
class FcmFetchForegroundService : Service() {
private var wakeLock: PowerManager.WakeLock? = null
companion object {
private val TAG = Log.tag(FcmFetchForegroundService::class.java)
private const val WAKELOCK_TAG = "FcmForegroundService"
private const val KEY_STOP_SELF = "stop_self"
private val WAKELOCK_TIMEOUT = FcmFetchManager.WEBSOCKET_DRAIN_TIMEOUT
/**
* Android's requirement for calling [startForeground] is enforced _even if your service was stopped before it started_.
* That means we can't just stop it normally, since we don't know if it got to start yet.
@@ -44,10 +52,14 @@ class FcmFetchForegroundService : Service() {
postForegroundNotification()
return if (intent != null && intent.getBooleanExtra(KEY_STOP_SELF, false)) {
WakeLockUtil.release(wakeLock, WAKELOCK_TAG)
stopForeground(true)
stopSelf()
START_NOT_STICKY
} else {
if (wakeLock == null) {
wakeLock = WakeLockUtil.acquire(this, PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TIMEOUT, WAKELOCK_TAG)
}
START_STICKY
}
}
@@ -68,7 +80,10 @@ class FcmFetchForegroundService : Service() {
override fun onDestroy() {
Log.i(TAG, "onDestroy()")
WakeLockUtil.release(wakeLock, WAKELOCK_TAG)
FcmFetchManager.onDestroyForegroundFetchService()
wakeLock = null
}
override fun onBind(intent: Intent?): IBinder? {

View File

@@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.gcm
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.PowerManager
import org.signal.core.util.concurrent.SignalExecutors
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
@@ -11,6 +12,7 @@ import org.thoughtcrime.securesms.jobs.PushNotificationReceiveJob
import org.thoughtcrime.securesms.messages.WebSocketStrategy
import org.thoughtcrime.securesms.util.SignalLocalMetrics
import org.thoughtcrime.securesms.util.concurrent.SerialMonoLifoExecutor
import kotlin.time.Duration.Companion.minutes
/**
* Our goals with FCM processing are as follows:
@@ -34,6 +36,8 @@ object FcmFetchManager {
private const val MAX_BLOCKING_TIME_MS = 500L
private val EXECUTOR = SerialMonoLifoExecutor(SignalExecutors.UNBOUNDED)
val WEBSOCKET_DRAIN_TIMEOUT = 5.minutes.inWholeMilliseconds
@Volatile
private var activeCount = 0
@@ -46,6 +50,8 @@ object FcmFetchManager {
@Volatile
private var startForegroundOnDestroy = false
private var wakeLock: PowerManager.WakeLock? = null
/**
* @return True if a service was successfully started, otherwise false.
*/
@@ -140,7 +146,7 @@ object FcmFetchManager {
@JvmStatic
fun retrieveMessages(context: Context): Boolean {
val success = ApplicationDependencies.getBackgroundMessageRetriever().retrieveMessages(context, WebSocketStrategy())
val success = ApplicationDependencies.getBackgroundMessageRetriever().retrieveMessages(context, WebSocketStrategy(WEBSOCKET_DRAIN_TIMEOUT))
if (success) {
Log.i(TAG, "Successfully retrieved messages.")

View File

@@ -4,6 +4,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.WorkerThread;
import org.signal.core.util.Stopwatch;
import org.signal.core.util.ThreadUtil;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.jobmanager.JobManager;
@@ -26,6 +27,15 @@ public class WebSocketStrategy extends MessageRetrievalStrategy {
private static final String KEEP_ALIVE_TOKEN = "WebsocketStrategy";
private static final long QUEUE_TIMEOUT = TimeUnit.SECONDS.toMillis(30);
private final long websocketDrainTimeoutMs;
public WebSocketStrategy() {
this(TimeUnit.MINUTES.toMillis(1));
}
public WebSocketStrategy(long websocketDrainTimeoutMs) {
this.websocketDrainTimeoutMs = websocketDrainTimeoutMs;
}
@WorkerThread
@Override
public boolean execute() {
@@ -39,7 +49,7 @@ public class WebSocketStrategy extends MessageRetrievalStrategy {
jobManager.addListener(job -> job.getParameters().getQueue() != null && job.getParameters().getQueue().startsWith(PushProcessMessageJob.QUEUE_PREFIX), queueListener);
if (!blockUntilWebsocketDrained(observer)) {
if (!blockUntilWebsocketDrained(observer, websocketDrainTimeoutMs)) {
return false;
}
@@ -63,7 +73,7 @@ public class WebSocketStrategy extends MessageRetrievalStrategy {
}
}
private static boolean blockUntilWebsocketDrained(IncomingMessageObserver observer) {
private static boolean blockUntilWebsocketDrained(IncomingMessageObserver observer, long timeoutMs) {
CountDownLatch latch = new CountDownLatch(1);
observer.addDecryptionDrainedListener(new Runnable() {
@@ -74,7 +84,7 @@ public class WebSocketStrategy extends MessageRetrievalStrategy {
});
try {
if (latch.await(1, TimeUnit.MINUTES)) {
if (latch.await(timeoutMs, TimeUnit.MILLISECONDS)) {
return true;
} else {
Log.w(TAG, "Hit timeout while waiting for decryptions to drain!");