Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wait for activity to be set rather than immediately return in waitUntilSystemConditionsAvailable #1926

Merged
merged 2 commits into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import com.onesignal.core.internal.application.IActivityLifecycleHandler
import com.onesignal.core.internal.application.IApplicationLifecycleHandler
import com.onesignal.core.internal.application.IApplicationService
import com.onesignal.debug.internal.logging.Logging
import kotlinx.coroutines.delay
import java.lang.ref.WeakReference

class ApplicationService() : IApplicationService, ActivityLifecycleCallbacks, OnGlobalLayoutListener {
Expand Down Expand Up @@ -208,10 +209,27 @@ class ApplicationService() : IApplicationService, ActivityLifecycleCallbacks, On
}

override suspend fun waitUntilSystemConditionsAvailable(): Boolean {
val currentActivity = current
if (currentActivity == null) {
Logging.warn("ApplicationService.waitUntilSystemConditionsAvailable: current is null")
return false
var currentActivity = current

// if this is called just after focusing, it's possible the current activity has not yet
// been set up. So we check for up to 5 seconds, then bail if it doesn't happen. We only
// do this when called on a non-main thread, if we're running on the main thread the
// activity cannot be setup, so we don't wait around.
var waitForActivityRetryCount =
if (AndroidUtils.isRunningOnMainThread()) {
50
} else {
0
}
while (currentActivity == null) {
waitForActivityRetryCount++
if (waitForActivityRetryCount > 50) {
Logging.warn("ApplicationService.waitUntilSystemConditionsAvailable: current is null")
return false
}
delay(100)

currentActivity = current
}

try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package com.onesignal.core.internal.application
import android.app.Activity
import android.content.Context
import androidx.test.core.app.ApplicationProvider
import com.onesignal.common.threading.WaiterWithValue
import com.onesignal.common.threading.suspendifyOnThread
import com.onesignal.core.internal.application.impl.ApplicationService
import com.onesignal.debug.LogLevel
import com.onesignal.debug.internal.logging.Logging
Expand All @@ -12,6 +14,7 @@ import io.kotest.matchers.shouldBe
import io.kotest.runner.junit4.KotestTestRunner
import io.mockk.spyk
import io.mockk.verify
import kotlinx.coroutines.delay
import org.junit.runner.RunWith
import org.robolectric.Robolectric

Expand Down Expand Up @@ -189,6 +192,58 @@ class ApplicationServiceTests : FunSpec({
response shouldBe false
}

test("wait until system condition returns false if activity not started within 5 seconds") {
// Given
val activity: Activity
Robolectric.buildActivity(Activity::class.java).use { controller ->
controller.setup() // Moves Activity to RESUMED state
activity = controller.get()
}
val applicationService = ApplicationService()

val waiter = WaiterWithValue<Boolean>()

// When
suspendifyOnThread {
val response = applicationService.waitUntilSystemConditionsAvailable()
waiter.wake(response)
}

delay(7000)

applicationService.onActivityStarted(activity)
val response = waiter.waitForWake()

// Then
response shouldBe false
}

test("wait until system condition returns true when an activity is started within 5 seconds") {
// Given
val activity: Activity
Robolectric.buildActivity(Activity::class.java).use { controller ->
controller.setup() // Moves Activity to RESUMED state
activity = controller.get()
}
val applicationService = ApplicationService()

val waiter = WaiterWithValue<Boolean>()

// When
suspendifyOnThread {
val response = applicationService.waitUntilSystemConditionsAvailable()
waiter.wake(response)
}

delay(3000)

applicationService.onActivityStarted(activity)
val response = waiter.waitForWake()

// Then
response shouldBe true
}

test("wait until system condition returns true when there is no system condition") {
// Given
val activity: Activity
Expand Down
Loading