Skip to content

Commit 307a0e3

Browse files
Wait for activity to be set rather than immediately return in waitUntilSystemConditionsAvailable (#1926)
* Wait for activity to be set rather than immediately return * Fix linting problems --------- Co-authored-by: jinliu9508 <jinliu9508@gmail.com>
1 parent 4263539 commit 307a0e3

File tree

2 files changed

+77
-4
lines changed

2 files changed

+77
-4
lines changed

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/application/impl/ApplicationService.kt

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import com.onesignal.core.internal.application.IActivityLifecycleHandler
2323
import com.onesignal.core.internal.application.IApplicationLifecycleHandler
2424
import com.onesignal.core.internal.application.IApplicationService
2525
import com.onesignal.debug.internal.logging.Logging
26+
import kotlinx.coroutines.delay
2627
import java.lang.ref.WeakReference
2728

2829
class ApplicationService() : IApplicationService, ActivityLifecycleCallbacks, OnGlobalLayoutListener {
@@ -208,10 +209,27 @@ class ApplicationService() : IApplicationService, ActivityLifecycleCallbacks, On
208209
}
209210

210211
override suspend fun waitUntilSystemConditionsAvailable(): Boolean {
211-
val currentActivity = current
212-
if (currentActivity == null) {
213-
Logging.warn("ApplicationService.waitUntilSystemConditionsAvailable: current is null")
214-
return false
212+
var currentActivity = current
213+
214+
// if this is called just after focusing, it's possible the current activity has not yet
215+
// been set up. So we check for up to 5 seconds, then bail if it doesn't happen. We only
216+
// do this when called on a non-main thread, if we're running on the main thread the
217+
// activity cannot be setup, so we don't wait around.
218+
var waitForActivityRetryCount =
219+
if (AndroidUtils.isRunningOnMainThread()) {
220+
50
221+
} else {
222+
0
223+
}
224+
while (currentActivity == null) {
225+
waitForActivityRetryCount++
226+
if (waitForActivityRetryCount > 50) {
227+
Logging.warn("ApplicationService.waitUntilSystemConditionsAvailable: current is null")
228+
return false
229+
}
230+
delay(100)
231+
232+
currentActivity = current
215233
}
216234

217235
try {

OneSignalSDK/onesignal/core/src/test/java/com/onesignal/core/internal/application/ApplicationServiceTests.kt

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package com.onesignal.core.internal.application
33
import android.app.Activity
44
import android.content.Context
55
import androidx.test.core.app.ApplicationProvider
6+
import com.onesignal.common.threading.WaiterWithValue
7+
import com.onesignal.common.threading.suspendifyOnThread
68
import com.onesignal.core.internal.application.impl.ApplicationService
79
import com.onesignal.debug.LogLevel
810
import com.onesignal.debug.internal.logging.Logging
@@ -12,6 +14,7 @@ import io.kotest.matchers.shouldBe
1214
import io.kotest.runner.junit4.KotestTestRunner
1315
import io.mockk.spyk
1416
import io.mockk.verify
17+
import kotlinx.coroutines.delay
1518
import org.junit.runner.RunWith
1619
import org.robolectric.Robolectric
1720

@@ -189,6 +192,58 @@ class ApplicationServiceTests : FunSpec({
189192
response shouldBe false
190193
}
191194

195+
test("wait until system condition returns false if activity not started within 5 seconds") {
196+
// Given
197+
val activity: Activity
198+
Robolectric.buildActivity(Activity::class.java).use { controller ->
199+
controller.setup() // Moves Activity to RESUMED state
200+
activity = controller.get()
201+
}
202+
val applicationService = ApplicationService()
203+
204+
val waiter = WaiterWithValue<Boolean>()
205+
206+
// When
207+
suspendifyOnThread {
208+
val response = applicationService.waitUntilSystemConditionsAvailable()
209+
waiter.wake(response)
210+
}
211+
212+
delay(7000)
213+
214+
applicationService.onActivityStarted(activity)
215+
val response = waiter.waitForWake()
216+
217+
// Then
218+
response shouldBe false
219+
}
220+
221+
test("wait until system condition returns true when an activity is started within 5 seconds") {
222+
// Given
223+
val activity: Activity
224+
Robolectric.buildActivity(Activity::class.java).use { controller ->
225+
controller.setup() // Moves Activity to RESUMED state
226+
activity = controller.get()
227+
}
228+
val applicationService = ApplicationService()
229+
230+
val waiter = WaiterWithValue<Boolean>()
231+
232+
// When
233+
suspendifyOnThread {
234+
val response = applicationService.waitUntilSystemConditionsAvailable()
235+
waiter.wake(response)
236+
}
237+
238+
delay(3000)
239+
240+
applicationService.onActivityStarted(activity)
241+
val response = waiter.waitForWake()
242+
243+
// Then
244+
response shouldBe true
245+
}
246+
192247
test("wait until system condition returns true when there is no system condition") {
193248
// Given
194249
val activity: Activity

0 commit comments

Comments
 (0)