Skip to content

Commit

Permalink
Merge pull request #2123 from OneSignal/player_model_work_manager_use…
Browse files Browse the repository at this point in the history
…s_context

[Player Model] The getter for WorkManager considers the app context
  • Loading branch information
nan-li authored Jun 13, 2024
2 parents 8a36a32 + baf9213 commit f54094a
Showing 1 changed file with 37 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,40 +27,58 @@

package com.onesignal

import android.annotation.SuppressLint
import android.content.Context
import androidx.work.Configuration
import androidx.work.WorkManager
import androidx.work.impl.WorkManagerImpl

object OSWorkManagerHelper {
/**
* Helper method to provide a way to check if WorkManager is initialized in this process.
*
* 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.
* However, this is the appropriate way to check as the non-throwing `WorkManager.getInstance()`
* method does not allow the opportunity for on-demand initialization with custom WorkManager.
*
* The purpose of this helper is to work around this bug - https://issuetracker.google.com/issues/258176803
*
* @return an instance of WorkManager
*/
@JvmStatic
@Synchronized
fun getInstance(context: Context): WorkManager {
if (!isInitialized()) {
WorkManager.initialize(context, Configuration.Builder().build())
return try {
WorkManager.getInstance(context)
} catch (e: IllegalStateException) {
/*
This aims to catch the IllegalStateException "WorkManager is not initialized properly..." -
https://androidx.tech/artifacts/work/work-runtime/2.8.1-source/androidx/work/impl/WorkManagerImpl.java.html
*/
OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "OSWorkManagerHelper.getInstance failed, attempting to initialize: ", e)
initializeWorkManager(context)
WorkManager.getInstance(context)
}
}

/**
* This method is called in rare cases to initialize WorkManager ourselves.
*/
private fun initializeWorkManager(context: Context) {
try {
/*
Note: `WorkManager.getInstance(context)` should already initialize WorkManager when the
application implements Configuration.Provider. However, as a further safeguard, let's detect
for this when we attempt to initialize WorkManager.
*/
val configuration = (context.applicationContext as? Configuration.Provider)?.workManagerConfiguration ?: Configuration.Builder().build()
WorkManager.initialize(context, configuration)
} 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.
*/
OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "OSWorkManagerHelper initializing WorkManager failed: ", e)
}
return WorkManager.getInstance(context)
}
}

0 comments on commit f54094a

Please sign in to comment.