Try handling ForegroundServiceStartNotAllowedException better (#6483)
* Try handling `ForegroundServiceStartNotAllowedException` better The docs mention starting a foreground service when the app is on background is allowed when FCM receives a high priority notification, so we don't do it if the priority is not high. Also, we handle the case where starting the foreground service fails so it doesn't crash the app.
This commit is contained in:
parent
c89fc2b6b1
commit
4725148919
3 changed files with 71 additions and 10 deletions
|
|
@ -10,6 +10,7 @@ package io.element.android.libraries.pushproviders.firebase
|
|||
|
||||
import com.google.firebase.messaging.FirebaseMessagingService
|
||||
import com.google.firebase.messaging.RemoteMessage
|
||||
import com.google.firebase.messaging.RemoteMessage.PRIORITY_HIGH
|
||||
import dev.zacsweers.metro.Inject
|
||||
import io.element.android.libraries.architecture.bindings
|
||||
import io.element.android.libraries.core.log.logger.LoggerTag
|
||||
|
|
@ -45,8 +46,11 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
|
|||
override fun onMessageReceived(message: RemoteMessage) {
|
||||
Timber.tag(loggerTag.value).w("New Firebase message. Priority: ${message.priority}/${message.originalPriority}")
|
||||
|
||||
// Acquire wakelock to ensure the device stays awake while we handle the push and schedule and run the work
|
||||
pushHandlingWakeLock.lock()
|
||||
val isHighPriority = message.priority == PRIORITY_HIGH
|
||||
if (isHighPriority) {
|
||||
// Acquire wakelock to ensure the device stays awake while we handle the push and schedule and run the work
|
||||
pushHandlingWakeLock.lock()
|
||||
}
|
||||
|
||||
coroutineScope.launch {
|
||||
val pushData = pushParser.parse(message.data)
|
||||
|
|
@ -58,7 +62,9 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
|
|||
"$it: ${message.data[it]}"
|
||||
},
|
||||
)
|
||||
pushHandlingWakeLock.unlock()
|
||||
if (isHighPriority) {
|
||||
pushHandlingWakeLock.unlock()
|
||||
}
|
||||
} else {
|
||||
val handled = pushHandler.handle(
|
||||
pushData = pushData,
|
||||
|
|
@ -66,7 +72,7 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
|
|||
)
|
||||
|
||||
// If we failed to handle the push, we should release the wakelock early to avoid keeping the device awake for too long.
|
||||
if (!handled) {
|
||||
if (!handled && isHighPriority) {
|
||||
pushHandlingWakeLock.unlock()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ class VectorFirebaseMessagingServiceTest {
|
|||
putString("event_id", AN_EVENT_ID.value)
|
||||
putString("room_id", A_ROOM_ID.value)
|
||||
putString("cs", A_SECRET)
|
||||
putString("google.priority", "high")
|
||||
},
|
||||
)
|
||||
)
|
||||
|
|
@ -127,6 +128,7 @@ class VectorFirebaseMessagingServiceTest {
|
|||
putString("event_id", AN_EVENT_ID.value)
|
||||
putString("room_id", A_ROOM_ID.value)
|
||||
putString("cs", A_SECRET)
|
||||
putString("google.priority", "high")
|
||||
},
|
||||
)
|
||||
)
|
||||
|
|
@ -141,6 +143,33 @@ class VectorFirebaseMessagingServiceTest {
|
|||
unlockLambda.assertions().isCalledOnce()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test pushHandler with a remote message with normal priority won't lock the wakelock`() = runTest {
|
||||
val lockLambda = lambdaRecorder<Duration, Unit> { _ -> }
|
||||
val unlockLambda = lambdaRecorder<Unit> { }
|
||||
val vectorFirebaseMessagingService = createVectorFirebaseMessagingService(
|
||||
pushHandler = FakePushHandler(handleResult = { _, _ -> false }),
|
||||
pushHandlingWakeLock = FakePushHandlingWakeLock(
|
||||
lock = lockLambda,
|
||||
unlock = unlockLambda
|
||||
)
|
||||
)
|
||||
vectorFirebaseMessagingService.onMessageReceived(
|
||||
message = RemoteMessage(
|
||||
Bundle().apply {
|
||||
putString("event_id", AN_EVENT_ID.value)
|
||||
putString("room_id", A_ROOM_ID.value)
|
||||
putString("cs", A_SECRET)
|
||||
putString("google.priority", "normal")
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
// The wakelock should not be locked
|
||||
lockLambda.assertions().isNeverCalled()
|
||||
unlockLambda.assertions().isNeverCalled()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test new token is forwarded to the handler`() = runTest {
|
||||
val lambda = lambdaRecorder<String, Unit> { }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue