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

Fix for WorkManager not Initialized Crash #2052

Merged
merged 2 commits into from
Apr 12, 2024
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
@@ -0,0 +1,51 @@
package com.onesignal.notifications.internal.common

import android.annotation.SuppressLint
import android.content.Context
import androidx.work.Configuration
import androidx.work.WorkManager
import androidx.work.impl.WorkManagerImpl
import com.onesignal.debug.internal.logging.Logging

object OSWorkManagerHelper {
/**
* Helper method to provide a way to check if WorkManager is initialized in this process.
* The purpose of this helper is to work around this bug - https://issuetracker.google.com/issues/258176803
*
* This is effectively the `WorkManager.isInitialized()` public method introduced in androidx.work:work-*:2.8.0-alpha02.
* Please see https://android-review.googlesource.com/c/platform/frameworks/support/+/1941186.
*
* @return `true` if WorkManager has been initialized in this process.
*/
@SuppressWarnings("deprecation")
@SuppressLint("RestrictedApi")
private fun isInitialized(): Boolean {
return WorkManagerImpl.getInstance() != null
}

/**
* If there is an instance of WorkManager available, use it. Else, in rare cases, initialize it ourselves.
*
* Calling `WorkManager.getInstance(context)` directly can cause an exception if it is null.
*
* @return an instance of WorkManager
*/
@JvmStatic
@Synchronized
fun getInstance(context: Context): WorkManager {
if (!isInitialized()) {
try {
WorkManager.initialize(context, Configuration.Builder().build())
} catch (e: IllegalStateException) {
/*
This catch is meant for the exception -
https://android.googlesource.com/platform/frameworks/support/+/60ae0eec2a32396c22ad92502cde952c80d514a0/work/workmanager/src/main/java/androidx/work/impl/WorkManagerImpl.java#177
1. We lost the race with another call to WorkManager.initialize outside of OneSignal.
2. It is possible for some other unexpected error is thrown from WorkManager.
*/
Logging.error("OSWorkManagerHelper initializing WorkManager failed: ", e)
}
}
return WorkManager.getInstance(context)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import androidx.work.CoroutineWorker
import androidx.work.Data
import androidx.work.ExistingWorkPolicy
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkManager
import androidx.work.WorkerParameters
import com.onesignal.OneSignal
import com.onesignal.common.AndroidUtils
import com.onesignal.debug.internal.logging.Logging
import com.onesignal.notifications.internal.common.NotificationFormatHelper
import com.onesignal.notifications.internal.common.OSWorkManagerHelper
import com.onesignal.notifications.internal.generation.INotificationGenerationProcessor
import com.onesignal.notifications.internal.generation.INotificationGenerationWorkManager
import org.json.JSONException
Expand Down Expand Up @@ -55,7 +55,7 @@ internal class NotificationGenerationWorkManager : INotificationGenerationWorkMa
Logging.debug(
"NotificationWorkManager enqueueing notification work with notificationId: $osNotificationId and jsonPayload: $jsonPayload",
)
WorkManager.getInstance(context)
OSWorkManagerHelper.getInstance(context)
.enqueueUniqueWork(osNotificationId, ExistingWorkPolicy.KEEP, workRequest)

return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import androidx.work.Data
import androidx.work.ExistingWorkPolicy
import androidx.work.NetworkType
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkManager
import androidx.work.WorkerParameters
import com.onesignal.OneSignal
import com.onesignal.common.AndroidUtils
import com.onesignal.core.internal.application.IApplicationService
import com.onesignal.core.internal.config.ConfigModelStore
import com.onesignal.debug.internal.logging.Logging
import com.onesignal.notifications.internal.common.OSWorkManagerHelper
import com.onesignal.notifications.internal.receivereceipt.IReceiveReceiptProcessor
import com.onesignal.notifications.internal.receivereceipt.IReceiveReceiptWorkManager
import com.onesignal.user.internal.subscriptions.ISubscriptionManager
Expand Down Expand Up @@ -57,7 +57,7 @@ internal class ReceiveReceiptWorkManager(
Logging.debug(
"OSReceiveReceiptController enqueueing send receive receipt work with notificationId: $notificationId and delay: $delay seconds",
)
WorkManager.getInstance(_applicationService.appContext)
OSWorkManagerHelper.getInstance(_applicationService.appContext)
.enqueueUniqueWork(
notificationId + "_receive_receipt",
ExistingWorkPolicy.KEEP,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import android.content.Context
import androidx.work.CoroutineWorker
import androidx.work.ExistingWorkPolicy
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkManager
import androidx.work.WorkerParameters
import com.onesignal.OneSignal
import com.onesignal.notifications.internal.common.NotificationHelper
import com.onesignal.notifications.internal.common.OSWorkManagerHelper
import com.onesignal.notifications.internal.restoration.INotificationRestoreProcessor
import com.onesignal.notifications.internal.restoration.INotificationRestoreWorkManager
import java.util.concurrent.TimeUnit
Expand Down Expand Up @@ -36,7 +36,7 @@ internal class NotificationRestoreWorkManager : INotificationRestoreWorkManager
OneTimeWorkRequest.Builder(NotificationRestoreWorker::class.java)
.setInitialDelay(restoreDelayInSeconds.toLong(), TimeUnit.SECONDS)
.build()
WorkManager.getInstance(context!!)
OSWorkManagerHelper.getInstance(context!!)
.enqueueUniqueWork(
NOTIFICATION_RESTORE_WORKER_IDENTIFIER,
ExistingWorkPolicy.KEEP,
Expand Down
Loading