Skip to content

Commit

Permalink
Merge pull request #69 from infinum/fix/investigate-initializer-errors
Browse files Browse the repository at this point in the history
Fix: Investigate initializer errors
  • Loading branch information
KCeh authored Jul 18, 2024
2 parents 3527381 + bbd0d8a commit 0aa90fa
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 48 deletions.
17 changes: 3 additions & 14 deletions sentinel/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
android:name=".ui.main.SentinelActivity"
android:exported="true"
android:label="@string/sentinel_name"
android:permission="com.infinum.sentinel.permission.ACCESS_SENTINEL"
android:taskAffinity="com.infinum.sentinel"
android:theme="@style/Sentinel.Theme"
android:permission="com.infinum.sentinel.permission.ACCESS_SENTINEL">
<meta-data
android:theme="@style/Sentinel.Theme">
<meta-data
android:name="@string/sentinel_infinum_monitored"
android:value="false" />
</activity>
Expand Down Expand Up @@ -119,17 +119,6 @@
android:value="androidx.startup" />
</provider>

<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<meta-data
android:name="androidx.work.WorkManagerInitializer"
android:value="androidx.startup"
tools:node="remove" />
</provider>

</application>

</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ internal object LibraryComponents {
tools.filterIsInstance<CertificateTool>().firstOrNull()?.userCertificates.orEmpty(),
onTriggered
)
WorkManagerInitializer.init(domainComponent)
domainComponent.setup()
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.infinum.sentinel.di

import com.infinum.sentinel.di.component.DomainComponent
import com.infinum.sentinel.ui.certificates.observer.CertificateCheckWorker
import com.infinum.sentinel.ui.certificates.observer.DelegateWorker
import com.infinum.sentinel.ui.certificates.observer.SentinelWorkerFactory

internal object WorkManagerInitializer {

fun init(domainComponent: DomainComponent) {
DelegateWorker.workerFactories[CertificateCheckWorker.NAME] =
SentinelWorkerFactory(domainComponent.collectors, domainComponent.notificationFactory)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ import com.infinum.sentinel.ui.bundles.callbacks.BundleMonitorNotificationCallba
import com.infinum.sentinel.ui.bundles.details.BundleDetailsActivity
import com.infinum.sentinel.ui.certificates.observer.CertificatesObserver
import com.infinum.sentinel.ui.certificates.observer.SentinelWorkManager
import com.infinum.sentinel.ui.certificates.observer.SentinelWorkerFactory
import com.infinum.sentinel.ui.crash.anr.SentinelAnrObserver
import com.infinum.sentinel.ui.crash.anr.SentinelAnrObserverRunnable
import com.infinum.sentinel.ui.crash.anr.SentinelUiAnrObserver
Expand Down Expand Up @@ -91,8 +90,6 @@ internal abstract class DomainComponent(

abstract val sentinelAnrObserver: SentinelAnrObserver

abstract val sentinelWorkerFactory: SentinelWorkerFactory

abstract val sentinelWorkManager: SentinelWorkManager

abstract val sentinelAnrObserverRunnable: SentinelAnrObserverRunnable
Expand Down Expand Up @@ -157,15 +154,10 @@ internal abstract class DomainComponent(
fun sentinelAnrObserverRunnable(dao: CrashesDao): SentinelAnrObserverRunnable =
SentinelAnrObserverRunnable(context, notificationFactory, dao)

@Provides
@DomainScope
fun sentinelWorkerFactory(): SentinelWorkerFactory =
SentinelWorkerFactory(collectors, notificationFactory)

@Provides
@DomainScope
fun sentinelWorkManager(): SentinelWorkManager =
SentinelWorkManager(context, sentinelWorkerFactory)
SentinelWorkManager(context)

@Provides
@DomainScope
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.infinum.sentinel.ui.certificates.observer

import android.content.Context
import androidx.annotation.UiThread
import androidx.work.ListenableWorker
import androidx.work.WorkerFactory
import androidx.work.WorkerParameters
import com.google.common.util.concurrent.ListenableFuture
import com.infinum.sentinel.ui.shared.Constants.Keys.WORKER_CLASS_NAME
import com.infinum.sentinel.ui.shared.Constants.Keys.WORKER_ID

/**
* A worker to delegate work requests from within the library to workers
* that require factories with custom dependencies.
*/
internal class DelegateWorker(
appContext: Context,
parameters: WorkerParameters,
) : ListenableWorker(appContext, parameters) {

private val workerClassName =
parameters.inputData.getString(WORKER_CLASS_NAME) ?: ""
private val workerId = parameters.inputData.getString(WORKER_ID)
private val delegateWorkerFactory = workerFactories[workerId]
private val delegatedWorker = delegateWorkerFactory?.createWorker(appContext, workerClassName, parameters)

override fun startWork(): ListenableFuture<Result> {
return if (delegatedWorker != null) {
delegatedWorker.startWork()
} else {
val errorMessage = "No delegateWorker available for $workerId" +
" with workerClassName of $workerClassName. Is the " +
"DelegateWorker.workerFactories populated correctly?"
throw IllegalStateException(errorMessage)
}
}

companion object {
const val DELEGATE_WORKER_ID = "com.infinum.sentinel.ui.certificates.observer.CertificateCheckWorker"

val workerFactories = object : AbstractMutableMap<String, WorkerFactory>() {

private val backingWorkerMap = mutableMapOf<String, WorkerFactory>()

@UiThread
override fun put(key: String, value: WorkerFactory): WorkerFactory? {
return backingWorkerMap.put(key, value)
}

override val entries: MutableSet<MutableMap.MutableEntry<String, WorkerFactory>>
get() = backingWorkerMap.entries
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@ import android.content.Context
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.lifecycle.asFlow
import androidx.work.Configuration
import androidx.work.Constraints
import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.NetworkType
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkInfo
import androidx.work.WorkManager
import androidx.work.WorkerFactory
import androidx.work.workDataOf
import com.infinum.sentinel.BuildConfig
import com.infinum.sentinel.data.models.local.CertificateMonitorEntity
import com.infinum.sentinel.ui.shared.Constants.Keys.EXPIRE_IN_AMOUNT
import com.infinum.sentinel.ui.shared.Constants.Keys.EXPIRE_IN_UNIT
import com.infinum.sentinel.ui.shared.Constants.Keys.NOTIFY_INVALID_NOW
import com.infinum.sentinel.ui.shared.Constants.Keys.NOTIFY_TO_EXPIRE
import com.infinum.sentinel.ui.shared.Constants.Keys.WORKER_CLASS_NAME
import com.infinum.sentinel.ui.shared.Constants.Keys.WORKER_ID
import java.time.Duration
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
Expand All @@ -28,44 +28,34 @@ import me.tatarka.inject.annotations.Inject
@Inject
internal class SentinelWorkManager(
private val context: Context,
private val workerFactory: WorkerFactory
) {

companion object {
private const val DEBUG_INTERVAL = 15L
private const val RELEASE_INTERVAL = 1440L
}

init {
WorkManager.initialize(
context,
Configuration.Builder()
.setMinimumLoggingLevel(android.util.Log.INFO)
.setWorkerFactory(workerFactory)
.build()
)
}

@RequiresApi(Build.VERSION_CODES.O)
fun startCertificatesCheck(entity: CertificateMonitorEntity) =
fun startCertificatesCheck(entity: CertificateMonitorEntity) {

val delegatedWorkData = workDataOf(
WORKER_CLASS_NAME to CertificateCheckWorker::class.qualifiedName,
WORKER_ID to CertificateCheckWorker.NAME,
NOTIFY_INVALID_NOW to entity.notifyInvalidNow,
NOTIFY_TO_EXPIRE to entity.notifyToExpire,
EXPIRE_IN_AMOUNT to entity.expireInAmount,
EXPIRE_IN_UNIT to entity.expireInUnit.name
)
WorkManager.getInstance(context)
.enqueueUniquePeriodicWork(
CertificateCheckWorker.NAME,
DelegateWorker.DELEGATE_WORKER_ID,
ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<CertificateCheckWorker>(
PeriodicWorkRequestBuilder<DelegateWorker>(
when (BuildConfig.DEBUG) {
true -> Duration.ofMinutes(DEBUG_INTERVAL)
false -> Duration.ofMinutes(RELEASE_INTERVAL)
}
)
.setInputData(
workDataOf(
NOTIFY_INVALID_NOW to entity.notifyInvalidNow,
NOTIFY_TO_EXPIRE to entity.notifyToExpire,
EXPIRE_IN_AMOUNT to entity.expireInAmount,
EXPIRE_IN_UNIT to entity.expireInUnit.name
)
)
).setInputData(delegatedWorkData)
.setConstraints(
Constraints.Builder()
.setRequiredNetworkType(NetworkType.NOT_REQUIRED)
Expand All @@ -80,6 +70,7 @@ internal class SentinelWorkManager(
)
.build()
)
}

fun certificatesCheckState(): Flow<Boolean> =
WorkManager.getInstance(context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,7 @@ internal object Constants {
const val NOTIFY_TO_EXPIRE: String = "KEY_NOTIFY_TO_EXPIRE"
const val EXPIRE_IN_AMOUNT: String = "KEY_EXPIRE_IN_AMOUNT"
const val EXPIRE_IN_UNIT: String = "KEY_EXPIRE_IN_UNIT"
const val WORKER_CLASS_NAME = "WORKER_CLASS_NAME"
const val WORKER_ID = "WORKER_ID"
}
}

0 comments on commit 0aa90fa

Please sign in to comment.