Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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 @@ -263,7 +263,6 @@ internal class OneSignalImp(
suspendifyOnIO {
internalInit(context, appId)
}
initState = InitState.SUCCESS
return true
}

Expand Down Expand Up @@ -306,22 +305,48 @@ internal class OneSignalImp(
) {
Logging.log(LogLevel.DEBUG, "Calling deprecated login(externalId: $externalId, jwtBearerToken: $jwtBearerToken)")

if (!initState.isSDKAccessible()) {
throw IllegalStateException("Must call 'initWithContext' before 'login'")
// Check state and provide appropriate error messages
when (initState) {
InitState.FAILED -> {
throw IllegalStateException("Initialization failed. Cannot proceed.")
}
InitState.NOT_STARTED -> {
throw IllegalStateException("Must call 'initWithContext' before 'login'")
}
InitState.IN_PROGRESS, InitState.SUCCESS -> {
// Continue - these states allow proceeding (will wait if needed)
}
}

waitForInit()
// Re-check state after waiting - init might have failed during the wait
if (initState == InitState.FAILED) {
throw IllegalStateException("Initialization failed. Cannot proceed.")
}
suspendifyOnIO { loginHelper.login(externalId, jwtBearerToken) }
}

override fun logout() {
Logging.log(LogLevel.DEBUG, "Calling deprecated logout()")

if (!initState.isSDKAccessible()) {
throw IllegalStateException("Must call 'initWithContext' before 'logout'")
// Check state and provide appropriate error messages
when (initState) {
InitState.FAILED -> {
throw IllegalStateException("Initialization failed. Cannot proceed.")
}
InitState.NOT_STARTED -> {
throw IllegalStateException("Must call 'initWithContext' before 'logout'")
}
InitState.IN_PROGRESS, InitState.SUCCESS -> {
// Continue - these states allow proceeding (will wait if needed)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate code, can we make a function for this?

}

waitForInit()
// Re-check state after waiting - init might have failed during the wait
if (initState == InitState.FAILED) {
throw IllegalStateException("Initialization failed. Cannot proceed.")
}
suspendifyOnIO { logoutHelper.logout() }
}

Expand Down Expand Up @@ -358,6 +383,10 @@ internal class OneSignalImp(
withTimeout(MAX_TIMEOUT_TO_INIT) {
initAwaiter.awaitSuspend()
}
// Re-check state after waiting - init might have failed during the wait
if (initState == InitState.FAILED) {
throw IllegalStateException("Initialization failed. Cannot proceed.")
}
} catch (e: TimeoutCancellationException) {
throw IllegalStateException("initWithContext was timed out after $MAX_TIMEOUT_TO_INIT ms")
}
Expand All @@ -384,13 +413,21 @@ internal class OneSignalImp(
InitState.IN_PROGRESS -> {
Logging.debug("Waiting for init to complete...")
waitForInit()
// Re-check state after waiting - init might have failed during the wait
if (initState == InitState.FAILED) {
throw IllegalStateException("Initialization failed. Cannot proceed.")
}
}
InitState.FAILED -> {
throw IllegalStateException("Initialization failed. Cannot proceed.")
}
else -> {
// SUCCESS
waitForInit()
// Re-check state after waiting - init might have failed during the wait
if (initState == InitState.FAILED) {
throw IllegalStateException("Initialization failed. Cannot proceed.")
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,19 @@ class SDKInitTests : FunSpec({
accessorThread.join(500)

// Then
// should complete even SharedPreferences is unavailable
// should complete even SharedPreferences is unavailable (non-blocking)
accessorThread.isAlive shouldBe false

// Release the SharedPreferences lock so internalInit can complete
trigger.complete()

// Wait for initialization to complete (internalInit runs asynchronously)
var attempts = 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: the wait mechanism for the initialization seems repetitive in the test. Can we clean this up?

while (!os.isInitialized && attempts < 50) {
Thread.sleep(20)
attempts++
}

os.isInitialized shouldBe true
}

Expand Down Expand Up @@ -224,12 +235,23 @@ class SDKInitTests : FunSpec({
accessorThread.start()
accessorThread.join(500)

os.isInitialized shouldBe true
// initWithContext should return immediately (non-blocking)
// but isInitialized won't be true until internalInit completes
// which requires SharedPreferences to be unblocked
accessorThread.isAlive shouldBe true

// release the lock on SharedPreferences
// release the lock on SharedPreferences so internalInit can complete
trigger.complete()

// Wait for initialization to complete (internalInit runs asynchronously)
var initAttempts = 0
while (!os.isInitialized && initAttempts < 50) {
Thread.sleep(20)
initAttempts++
}

os.isInitialized shouldBe true

accessorThread.join(500)
accessorThread.isAlive shouldBe false
os.user.externalId shouldBe externalId
Expand Down