Commit 81f57949 authored by topjohnwu's avatar topjohnwu

Remove WorkManager as a dependency

parent fca5eb08
...@@ -123,12 +123,11 @@ dependencies { ...@@ -123,12 +123,11 @@ dependencies {
implementation("androidx.biometric:biometric:1.1.0") implementation("androidx.biometric:biometric:1.1.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.1") implementation("androidx.constraintlayout:constraintlayout:2.1.1")
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0") implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
implementation("androidx.browser:browser:1.3.0") implementation("androidx.browser:browser:1.4.0")
implementation("androidx.preference:preference:1.1.1") implementation("androidx.preference:preference:1.1.1")
implementation("androidx.recyclerview:recyclerview:1.2.1") implementation("androidx.recyclerview:recyclerview:1.2.1")
implementation("androidx.fragment:fragment-ktx:1.3.6") implementation("androidx.fragment:fragment-ktx:1.3.6")
implementation("androidx.work:work-runtime-ktx:2.7.0")
implementation("androidx.transition:transition:1.4.1") implementation("androidx.transition:transition:1.4.1")
implementation("androidx.core:core-ktx:1.6.0") implementation("androidx.core:core-ktx:1.7.0")
implementation("com.google.android.material:material:1.4.0") implementation("com.google.android.material:material:1.4.0")
} }
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
android:multiArch="true" android:multiArch="true"
tools:ignore="UnusedAttribute,GoogleAppIndexingWarning"> tools:ignore="UnusedAttribute,GoogleAppIndexingWarning">
<!-- Splash -->
<activity <activity
android:name=".core.SplashActivity" android:name=".core.SplashActivity"
android:exported="true" android:exported="true"
...@@ -27,10 +26,10 @@ ...@@ -27,10 +26,10 @@
</intent-filter> </intent-filter>
</activity> </activity>
<!-- Main --> <activity
<activity android:name=".ui.MainActivity" /> android:name=".ui.MainActivity"
android:exported="false" />
<!-- Superuser -->
<activity <activity
android:name=".ui.surequest.SuRequestActivity" android:name=".ui.surequest.SuRequestActivity"
android:directBootAware="true" android:directBootAware="true"
...@@ -43,7 +42,6 @@ ...@@ -43,7 +42,6 @@
</intent-filter> </intent-filter>
</activity> </activity>
<!-- Receiver -->
<receiver <receiver
android:name=".core.Receiver" android:name=".core.Receiver"
android:directBootAware="true" android:directBootAware="true"
...@@ -60,10 +58,15 @@ ...@@ -60,10 +58,15 @@
</intent-filter> </intent-filter>
</receiver> </receiver>
<!-- DownloadService --> <service
<service android:name=".core.download.DownloadService" /> android:name=".core.download.DownloadService"
android:exported="false" />
<service
android:name=".core.JobService"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE" />
<!-- FileProvider -->
<provider <provider
android:name=".core.Provider" android:name=".core.Provider"
android:authorities="${applicationId}.provider" android:authorities="${applicationId}.provider"
...@@ -71,13 +74,6 @@ ...@@ -71,13 +74,6 @@
android:exported="false" android:exported="false"
android:grantUriPermissions="true" /> android:grantUriPermissions="true" />
<!-- Initialize WorkManager on-demand -->
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
tools:node="remove">
</provider>
<!-- We don't invalidate Room --> <!-- We don't invalidate Room -->
<service <service
android:name="androidx.room.MultiInstanceInvalidationService" android:name="androidx.room.MultiInstanceInvalidationService"
......
...@@ -7,7 +7,6 @@ import android.content.Context ...@@ -7,7 +7,6 @@ import android.content.Context
import android.content.res.Configuration import android.content.res.Configuration
import android.os.Bundle import android.os.Bundle
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.work.WorkManager
import com.topjohnwu.magisk.DynAPK import com.topjohnwu.magisk.DynAPK
import com.topjohnwu.magisk.core.utils.AppShellInit import com.topjohnwu.magisk.core.utils.AppShellInit
import com.topjohnwu.magisk.core.utils.BusyBoxInit import com.topjohnwu.magisk.core.utils.BusyBoxInit
...@@ -58,7 +57,6 @@ open class App() : Application() { ...@@ -58,7 +57,6 @@ open class App() : Application() {
ServiceLocator.context = wrapped ServiceLocator.context = wrapped
AssetHack.init(impl) AssetHack.init(impl)
app.registerActivityLifecycleCallbacks(ForegroundTracker) app.registerActivityLifecycleCallbacks(ForegroundTracker)
WorkManager.initialize(impl.wrapJob(), androidx.work.Configuration.Builder().build())
} }
// This is required as some platforms expect ContextImpl // This is required as some platforms expect ContextImpl
......
...@@ -41,9 +41,9 @@ object Const { ...@@ -41,9 +41,9 @@ object Const {
object ID { object ID {
// notifications // notifications
const val APK_UPDATE_NOTIFICATION_ID = 5 const val APK_UPDATE_NOTIFICATION_ID = 5
const val JOB_SERVICE_ID = 7
const val UPDATE_NOTIFICATION_CHANNEL = "update" const val UPDATE_NOTIFICATION_CHANNEL = "update"
const val PROGRESS_NOTIFICATION_CHANNEL = "progress" const val PROGRESS_NOTIFICATION_CHANNEL = "progress"
const val CHECK_MAGISK_UPDATE_WORKER_ID = "magisk_update"
} }
object Url { object Url {
......
...@@ -2,11 +2,7 @@ ...@@ -2,11 +2,7 @@
package com.topjohnwu.magisk.core package com.topjohnwu.magisk.core
import android.annotation.SuppressLint
import android.app.Activity import android.app.Activity
import android.app.job.JobInfo
import android.app.job.JobScheduler
import android.app.job.JobWorkItem
import android.content.ComponentName import android.content.ComponentName
import android.content.Context import android.content.Context
import android.content.ContextWrapper import android.content.ContextWrapper
...@@ -15,7 +11,6 @@ import android.content.res.AssetManager ...@@ -15,7 +11,6 @@ import android.content.res.AssetManager
import android.content.res.Configuration import android.content.res.Configuration
import android.content.res.Resources import android.content.res.Resources
import android.util.DisplayMetrics import android.util.DisplayMetrics
import androidx.annotation.RequiresApi
import com.topjohnwu.magisk.DynAPK import com.topjohnwu.magisk.DynAPK
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.utils.refreshLocale import com.topjohnwu.magisk.core.utils.refreshLocale
...@@ -28,22 +23,6 @@ fun AssetManager.addAssetPath(path: String) { ...@@ -28,22 +23,6 @@ fun AssetManager.addAssetPath(path: String) {
fun Context.wrap(inject: Boolean = false): Context = fun Context.wrap(inject: Boolean = false): Context =
if (inject) ReInjectedContext(this) else InjectedContext(this) if (inject) ReInjectedContext(this) else InjectedContext(this)
fun Context.wrapJob(): Context = object : InjectedContext(this) {
override fun getApplicationContext() = this
@SuppressLint("NewApi")
override fun getSystemService(name: String): Any? {
return super.getSystemService(name).let {
when {
!isRunningAsStub -> it
name == JOB_SCHEDULER_SERVICE -> JobSchedulerWrapper(it as JobScheduler)
else -> it
}
}
}
}
fun Class<*>.cmp(pkg: String) = fun Class<*>.cmp(pkg: String) =
ComponentName(pkg, Info.stub?.classToComponent?.get(name) ?: name) ComponentName(pkg, Info.stub?.classToComponent?.get(name) ?: name)
...@@ -99,28 +78,6 @@ object AssetHack { ...@@ -99,28 +78,6 @@ object AssetHack {
} }
} }
@RequiresApi(28)
private class JobSchedulerWrapper(private val base: JobScheduler) : JobScheduler() {
override fun schedule(job: JobInfo) = base.schedule(job.patch())
override fun enqueue(job: JobInfo, work: JobWorkItem) = base.enqueue(job.patch(), work)
override fun cancel(jobId: Int) = base.cancel(jobId)
override fun cancelAll() = base.cancelAll()
override fun getAllPendingJobs(): List<JobInfo> = base.allPendingJobs
override fun getPendingJob(jobId: Int) = base.getPendingJob(jobId)
private fun JobInfo.patch(): JobInfo {
// Swap out the service of JobInfo
val component = service.run {
ComponentName(packageName,
Info.stub?.classToComponent?.get(className) ?: className)
}
javaClass.getDeclaredField("service").apply {
isAccessible = true
}.set(this, component)
return this
}
}
// Keep a reference to these resources to prevent it from // Keep a reference to these resources to prevent it from
// being removed when running "remove unused resources" // being removed when running "remove unused resources"
val shouldKeepResources = listOf( val shouldKeepResources = listOf(
......
package com.topjohnwu.magisk.core
import android.app.job.JobInfo
import android.app.job.JobParameters
import android.app.job.JobScheduler
import android.content.Context
import androidx.core.content.getSystemService
import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.core.base.BaseJobService
import com.topjohnwu.magisk.di.ServiceLocator
import com.topjohnwu.magisk.view.Notifications
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import java.util.concurrent.TimeUnit
class JobService : BaseJobService() {
private val job = Job()
private val svc get() = ServiceLocator.networkService
override fun onStartJob(params: JobParameters): Boolean {
val coroutineScope = CoroutineScope(Dispatchers.IO + job)
coroutineScope.launch {
svc.fetchUpdate()?.run {
if (Info.env.isActive && BuildConfig.VERSION_CODE < magisk.versionCode)
Notifications.managerUpdate(this@JobService)
}
jobFinished(params, false)
}
return false
}
override fun onStopJob(params: JobParameters): Boolean {
job.cancel()
return false
}
companion object {
fun schedule(context: Context) {
val svc = context.getSystemService<JobScheduler>() ?: return
if (Config.checkUpdate) {
val cmp = JobService::class.java.cmp(context.packageName)
val info = JobInfo.Builder(Const.ID.JOB_SERVICE_ID, cmp)
.setPeriodic(TimeUnit.HOURS.toMillis(12))
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.setRequiresDeviceIdle(true)
.build()
svc.schedule(info)
} else {
svc.cancel(Const.ID.JOB_SERVICE_ID)
}
}
}
}
...@@ -15,7 +15,7 @@ import com.topjohnwu.magisk.view.Shortcuts ...@@ -15,7 +15,7 @@ import com.topjohnwu.magisk.view.Shortcuts
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import java.util.concurrent.CountDownLatch import java.util.concurrent.CountDownLatch
open class SplashActivity : BaseActivity() { class SplashActivity : BaseActivity() {
private val latch = CountDownLatch(1) private val latch = CountDownLatch(1)
...@@ -63,7 +63,7 @@ open class SplashActivity : BaseActivity() { ...@@ -63,7 +63,7 @@ open class SplashActivity : BaseActivity() {
Config.load(prevPkg) Config.load(prevPkg)
handleRepackage(prevPkg) handleRepackage(prevPkg)
Notifications.setup(this) Notifications.setup(this)
UpdateCheckService.schedule(this) JobService.schedule(this)
Shortcuts.setupDynamic(this) Shortcuts.setupDynamic(this)
// Pre-fetch network services // Pre-fetch network services
......
package com.topjohnwu.magisk.core
import android.annotation.SuppressLint
import android.content.Context
import androidx.work.*
import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.di.ServiceLocator
import com.topjohnwu.magisk.view.Notifications
import java.util.concurrent.TimeUnit
class UpdateCheckService(context: Context, workerParams: WorkerParameters)
: CoroutineWorker(context, workerParams) {
private val svc get() = ServiceLocator.networkService
override suspend fun doWork(): Result {
return svc.fetchUpdate()?.run {
if (Info.env.isActive && BuildConfig.VERSION_CODE < magisk.versionCode)
Notifications.managerUpdate(applicationContext)
Result.success()
} ?: Result.failure()
}
companion object {
@SuppressLint("NewApi")
fun schedule(context: Context) {
if (Config.checkUpdate) {
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresDeviceIdle(true)
.build()
val request = PeriodicWorkRequestBuilder<UpdateCheckService>(12, TimeUnit.HOURS)
.setConstraints(constraints)
.build()
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
Const.ID.CHECK_MAGISK_UPDATE_WORKER_ID,
ExistingPeriodicWorkPolicy.REPLACE, request)
} else {
WorkManager.getInstance(context)
.cancelUniqueWork(Const.ID.CHECK_MAGISK_UPDATE_WORKER_ID)
}
}
}
}
package com.topjohnwu.magisk.core.base
import android.app.job.JobService
import android.content.Context
import com.topjohnwu.magisk.core.wrap
abstract class BaseJobService : JobService() {
override fun attachBaseContext(base: Context) {
super.attachBaseContext(base.wrap())
}
}
package com.topjohnwu.magisk.core.base
import android.content.Context
import android.net.Network
import android.net.Uri
import androidx.annotation.MainThread
import androidx.annotation.RequiresApi
import androidx.work.Data
import androidx.work.ListenableWorker
import com.google.common.util.concurrent.ListenableFuture
import java.util.*
abstract class BaseWorkerWrapper {
private lateinit var worker: ListenableWorker
val applicationContext: Context
get() = worker.applicationContext
val id: UUID
get() = worker.id
val inputData: Data
get() = worker.inputData
val tags: Set<String>
get() = worker.tags
val triggeredContentUris: List<Uri>
@RequiresApi(24)
get() = worker.triggeredContentUris
val triggeredContentAuthorities: List<String>
@RequiresApi(24)
get() = worker.triggeredContentAuthorities
val network: Network?
@RequiresApi(28)
get() = worker.network
val runAttemptCount: Int
get() = worker.runAttemptCount
val isStopped: Boolean
get() = worker.isStopped
abstract fun doWork(): ListenableWorker.Result
fun onStopped() {}
fun attachWorker(w: ListenableWorker) {
worker = w
}
@MainThread
fun startWork(): ListenableFuture<ListenableWorker.Result> {
return worker.startWork()
}
}
...@@ -12,7 +12,7 @@ import com.topjohnwu.magisk.R ...@@ -12,7 +12,7 @@ import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Const import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.UpdateCheckService import com.topjohnwu.magisk.core.JobService
import com.topjohnwu.magisk.core.tasks.HideAPK import com.topjohnwu.magisk.core.tasks.HideAPK
import com.topjohnwu.magisk.core.utils.BiometricHelper import com.topjohnwu.magisk.core.utils.BiometricHelper
import com.topjohnwu.magisk.core.utils.MediaStoreUtils import com.topjohnwu.magisk.core.utils.MediaStoreUtils
...@@ -185,7 +185,7 @@ object UpdateChecker : BaseSettingsItem.Toggle() { ...@@ -185,7 +185,7 @@ object UpdateChecker : BaseSettingsItem.Toggle() {
override var value = Config.checkUpdate override var value = Config.checkUpdate
set(value) = setV(value, field, { field = it }) { set(value) = setV(value, field, { field = it }) {
Config.checkUpdate = it Config.checkUpdate = it
UpdateCheckService.schedule(AppContext) JobService.schedule(AppContext)
} }
} }
......
...@@ -153,7 +153,10 @@ fun genStubManifest(srcDir: File, outDir: File): String { ...@@ -153,7 +153,10 @@ fun genStubManifest(srcDir: File, outDir: File): String {
cmpList.add(Component( cmpList.add(Component(
"com.topjohnwu.magisk.ui.MainActivity", "com.topjohnwu.magisk.ui.MainActivity",
"", "",
"""|<activity android:name="%s" />""".ind(2) """
|<activity
| android:name="%s"
| android:exported="false" />""".ind(2)
)) ))
cmpList.add(Component( cmpList.add(Component(
...@@ -176,18 +179,19 @@ fun genStubManifest(srcDir: File, outDir: File): String { ...@@ -176,18 +179,19 @@ fun genStubManifest(srcDir: File, outDir: File): String {
cmpList.add(Component( cmpList.add(Component(
"com.topjohnwu.magisk.core.download.DownloadService", "com.topjohnwu.magisk.core.download.DownloadService",
"", "",
"""|<service android:name="%s" />""".ind(2) """
|<service
| android:name="%s"
| android:exported="false" />""".trimIndent().ind(2)
)) ))
cmpList.add(Component( cmpList.add(Component(
"androidx.work.impl.background.systemjob.SystemJobService", "com.topjohnwu.magisk.core.JobService",
"", "",
""" """
|<service |<service
| android:name="%s" | android:name="%s"
| android:directBootAware="false" | android:exported="false"
| android:enabled="true"
| android:exported="true"
| android:permission="android.permission.BIND_JOB_SERVICE" />""".ind(2) | android:permission="android.permission.BIND_JOB_SERVICE" />""".ind(2)
)) ))
......
...@@ -30,7 +30,7 @@ android.injected.testOnly=false ...@@ -30,7 +30,7 @@ android.injected.testOnly=false
kapt.incremental.apt=true kapt.incremental.apt=true
# Magisk # Magisk
magisk.stubVersion=21 magisk.stubVersion=22
magisk.versionCode=23012 magisk.versionCode=23012
magisk.ndkVersion=21e magisk.ndkVersion=21e
magisk.fullNdkVersion=21.4.7075529 magisk.fullNdkVersion=21.4.7075529
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment