From 0de1885f77ae8e6fcd66b1b8169495e0ee846805 Mon Sep 17 00:00:00 2001 From: jinliu9508 Date: Fri, 13 Dec 2024 12:52:59 -0500 Subject: [PATCH] fix: ANR caused by operationRepo.enqueue while loading is not complete Making the enqueue logic to be done in the background --- .../threading/OSPrimaryCoroutineScope.kt | 19 +++++++++++++++++++ .../internal/session/impl/SessionListener.kt | 15 +++++++++++---- .../internal/service/UserRefreshService.kt | 15 +++++++++------ 3 files changed, 39 insertions(+), 10 deletions(-) create mode 100644 OneSignalSDK/onesignal/core/src/main/java/com/onesignal/common/threading/OSPrimaryCoroutineScope.kt diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/common/threading/OSPrimaryCoroutineScope.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/common/threading/OSPrimaryCoroutineScope.kt new file mode 100644 index 0000000000..4977c54ff2 --- /dev/null +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/common/threading/OSPrimaryCoroutineScope.kt @@ -0,0 +1,19 @@ +package com.onesignal.common.threading + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.newSingleThreadContext + +object OSPrimaryCoroutineScope { + // CoroutineScope tied to the main thread + private val mainScope = CoroutineScope(newSingleThreadContext(name = "OSPrimaryCoroutineScope")) + + /** + * Executes the given [block] on the OS primary coroutine scope. + */ + fun execute(block: suspend () -> Unit) { + mainScope.launch { + block() + } + } +} diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/session/internal/session/impl/SessionListener.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/session/internal/session/impl/SessionListener.kt index 8d2161aa65..07481ca8f0 100644 --- a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/session/internal/session/impl/SessionListener.kt +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/session/internal/session/impl/SessionListener.kt @@ -1,5 +1,6 @@ package com.onesignal.session.internal.session.impl +import com.onesignal.common.threading.OSPrimaryCoroutineScope import com.onesignal.common.threading.suspendifyOnThread import com.onesignal.core.internal.config.ConfigModelStore import com.onesignal.core.internal.operations.IOperationRepo @@ -40,7 +41,10 @@ internal class SessionListener( } override fun onSessionStarted() { - _operationRepo.enqueue(TrackSessionStartOperation(_configModelStore.model.appId, _identityModelStore.model.onesignalId), true) + // enqueue the operation in background + OSPrimaryCoroutineScope.execute { + _operationRepo.enqueue(TrackSessionStartOperation(_configModelStore.model.appId, _identityModelStore.model.onesignalId), true) + } } override fun onSessionActive() { @@ -54,9 +58,12 @@ internal class SessionListener( Logging.error("SessionListener.onSessionEnded sending duration of $durationInSeconds seconds") } - _operationRepo.enqueue( - TrackSessionEndOperation(_configModelStore.model.appId, _identityModelStore.model.onesignalId, durationInSeconds), - ) + // enqueue the operation in background + OSPrimaryCoroutineScope.execute { + _operationRepo.enqueue( + TrackSessionEndOperation(_configModelStore.model.appId, _identityModelStore.model.onesignalId, durationInSeconds), + ) + } suspendifyOnThread { _outcomeEventsController.sendSessionEndOutcomeEvent(durationInSeconds) diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/service/UserRefreshService.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/service/UserRefreshService.kt index 7b04d7981e..dbf86d5434 100644 --- a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/service/UserRefreshService.kt +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/service/UserRefreshService.kt @@ -1,6 +1,7 @@ package com.onesignal.user.internal.service import com.onesignal.common.IDManager +import com.onesignal.common.threading.OSPrimaryCoroutineScope import com.onesignal.core.internal.application.IApplicationService import com.onesignal.core.internal.config.ConfigModelStore import com.onesignal.core.internal.operations.IOperationRepo @@ -28,12 +29,14 @@ class UserRefreshService( return } - _operationRepo.enqueue( - RefreshUserOperation( - _configModelStore.model.appId, - _identityModelStore.model.onesignalId, - ), - ) + OSPrimaryCoroutineScope.execute { + _operationRepo.enqueue( + RefreshUserOperation( + _configModelStore.model.appId, + _identityModelStore.model.onesignalId, + ), + ) + } } override fun start() = _sessionService.subscribe(this)