From b8b04ee2338fc6f9e9c5c81d281bf06e962d0a86 Mon Sep 17 00:00:00 2001 From: Jamie Rothfeder Date: Thu, 19 Oct 2023 11:11:42 -0400 Subject: [PATCH 1/4] Looper on a different thread for the `SessionLifecycleClient`'s callbacks --- .../com/google/firebase/sessions/SessionLifecycleClient.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/SessionLifecycleClient.kt b/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/SessionLifecycleClient.kt index bbdcd3e55d27..4c51a536c65f 100644 --- a/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/SessionLifecycleClient.kt +++ b/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/SessionLifecycleClient.kt @@ -21,6 +21,7 @@ import android.content.Context import android.content.Intent import android.content.ServiceConnection import android.os.Handler +import android.os.HandlerThread import android.os.IBinder import android.os.Looper import android.os.Message @@ -54,13 +55,14 @@ internal object SessionLifecycleClient { private var serviceBound: Boolean = false private val queuedMessages = LinkedBlockingDeque(MAX_QUEUED_MESSAGES) private var curSessionId: String = "" + private var handlerThread: HandlerThread = HandlerThread("FirebaseSessionsClient_HandlerThread") /** * The callback class that will be used to receive updated session events from the * [SessionLifecycleService]. */ // TODO(rothbutter) should we use the main looper or is there one available in this SDK? - internal class ClientUpdateHandler : Handler(Looper.getMainLooper()) { + internal class ClientUpdateHandler : Handler(handlerThread.looper) { override fun handleMessage(msg: Message) { when (msg.what) { SessionLifecycleService.SESSION_UPDATED -> From 54cffa0e23d747fba09e0f15ae50980dfdcd3f43 Mon Sep 17 00:00:00 2001 From: Jamie Rothfeder Date: Thu, 19 Oct 2023 11:28:07 -0400 Subject: [PATCH 2/4] Start the looper thread --- .../com/google/firebase/sessions/SessionLifecycleClient.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/SessionLifecycleClient.kt b/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/SessionLifecycleClient.kt index 4c51a536c65f..72755946c9f1 100644 --- a/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/SessionLifecycleClient.kt +++ b/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/SessionLifecycleClient.kt @@ -57,6 +57,10 @@ internal object SessionLifecycleClient { private var curSessionId: String = "" private var handlerThread: HandlerThread = HandlerThread("FirebaseSessionsClient_HandlerThread") + init { + handlerThread.start() + } + /** * The callback class that will be used to receive updated session events from the * [SessionLifecycleService]. From ab462aee211214eb31688b4a538bc316f3b87ff4 Mon Sep 17 00:00:00 2001 From: jrothfeder Date: Thu, 19 Oct 2023 11:32:30 -0400 Subject: [PATCH 3/4] Start the looper thread --- .../com/google/firebase/sessions/SessionLifecycleClient.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/SessionLifecycleClient.kt b/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/SessionLifecycleClient.kt index 4c51a536c65f..72755946c9f1 100644 --- a/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/SessionLifecycleClient.kt +++ b/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/SessionLifecycleClient.kt @@ -57,6 +57,10 @@ internal object SessionLifecycleClient { private var curSessionId: String = "" private var handlerThread: HandlerThread = HandlerThread("FirebaseSessionsClient_HandlerThread") + init { + handlerThread.start() + } + /** * The callback class that will be used to receive updated session events from the * [SessionLifecycleService]. From dcce14399151a8c3240c0ceae780ddc1a15a9255 Mon Sep 17 00:00:00 2001 From: jrothfeder Date: Fri, 20 Oct 2023 15:21:36 -0400 Subject: [PATCH 4/4] Fix lifecycle of looper thread --- .../firebase/sessions/SessionLifecycleClient.kt | 14 ++++++++++++++ .../sessions/SessionsActivityLifecycleCallbacks.kt | 4 ++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/SessionLifecycleClient.kt b/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/SessionLifecycleClient.kt index 72755946c9f1..eb1bb66ca2cb 100644 --- a/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/SessionLifecycleClient.kt +++ b/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/SessionLifecycleClient.kt @@ -150,6 +150,20 @@ internal object SessionLifecycleClient { sendLifecycleEvent(SessionLifecycleService.BACKGROUNDED) } + /** + * Perform initialization that requires cleanup + */ + fun started() { + if (!handlerThread.isAlive) { handlerThread.start() } + } + + /** + * Cleanup initialization + */ + fun stopped() { + handlerThread.quit() + } + /** * Sends a message to the [SessionLifecycleService] with the given event code. This will * potentially also send any messages that have been queued up but not successfully delivered to diff --git a/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/SessionsActivityLifecycleCallbacks.kt b/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/SessionsActivityLifecycleCallbacks.kt index c6f91d597b2a..6729f902dfd0 100644 --- a/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/SessionsActivityLifecycleCallbacks.kt +++ b/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/SessionsActivityLifecycleCallbacks.kt @@ -31,9 +31,9 @@ internal object SessionsActivityLifecycleCallbacks : ActivityLifecycleCallbacks override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) = Unit - override fun onActivityStarted(activity: Activity) = Unit + override fun onActivityStarted(activity: Activity) = SessionLifecycleClient.started() - override fun onActivityStopped(activity: Activity) = Unit + override fun onActivityStopped(activity: Activity) = SessionLifecycleClient.stopped() override fun onActivityDestroyed(activity: Activity) = Unit