mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-24 21:15:48 +00:00
Increase FCM push websocket timeout.
This commit is contained in:
@@ -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? {
|
||||
|
||||
@@ -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.")
|
||||
|
||||
@@ -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!");
|
||||
|
||||
Reference in New Issue
Block a user