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

[Player Model] The getter for WorkManager considers the app context #2123

Merged
merged 1 commit into from
Jun 13, 2024
Merged
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 @@ -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)
}
}
Loading