Create singleton AppContext

This commit is contained in:
topjohnwu 2024-07-09 17:19:26 -07:00
parent 69181a6b72
commit 88e8e15607
19 changed files with 148 additions and 134 deletions

View File

@ -1,8 +1,8 @@
package com.topjohnwu.magisk.dialog package com.topjohnwu.magisk.dialog
import com.topjohnwu.magisk.core.AppContext
import com.topjohnwu.magisk.core.Info import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.R import com.topjohnwu.magisk.core.R
import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.core.di.ServiceLocator import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.download.DownloadEngine import com.topjohnwu.magisk.core.download.DownloadEngine
import com.topjohnwu.magisk.core.download.Subject import com.topjohnwu.magisk.core.download.Subject

View File

@ -6,7 +6,7 @@ import androidx.databinding.Bindable
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.arch.AsyncLoadViewModel import com.topjohnwu.magisk.arch.AsyncLoadViewModel
import com.topjohnwu.magisk.core.di.AppContext import com.topjohnwu.magisk.core.AppContext
import com.topjohnwu.magisk.core.ktx.concurrentMap import com.topjohnwu.magisk.core.ktx.concurrentMap
import com.topjohnwu.magisk.databinding.bindExtra import com.topjohnwu.magisk.databinding.bindExtra
import com.topjohnwu.magisk.databinding.filterList import com.topjohnwu.magisk.databinding.filterList

View File

@ -13,12 +13,12 @@ import androidx.lifecycle.viewModelScope
import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseViewModel import com.topjohnwu.magisk.arch.BaseViewModel
import com.topjohnwu.magisk.core.AppContext
import com.topjohnwu.magisk.core.BuildConfig import com.topjohnwu.magisk.core.BuildConfig
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.base.ContentResultCallback import com.topjohnwu.magisk.core.base.ContentResultCallback
import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.core.ktx.toast import com.topjohnwu.magisk.core.ktx.toast
import com.topjohnwu.magisk.core.repository.NetworkService import com.topjohnwu.magisk.core.repository.NetworkService
import com.topjohnwu.magisk.databinding.set import com.topjohnwu.magisk.databinding.set

View File

@ -3,7 +3,7 @@ package com.topjohnwu.magisk.ui.log
import androidx.databinding.Bindable import androidx.databinding.Bindable
import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.di.AppContext import com.topjohnwu.magisk.core.AppContext
import com.topjohnwu.magisk.core.ktx.timeDateFormat import com.topjohnwu.magisk.core.ktx.timeDateFormat
import com.topjohnwu.magisk.core.ktx.toTime import com.topjohnwu.magisk.core.ktx.toTime
import com.topjohnwu.magisk.core.model.su.SuLog import com.topjohnwu.magisk.core.model.su.SuLog

View File

@ -7,11 +7,11 @@ import androidx.core.content.pm.ShortcutManagerCompat
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.arch.BaseViewModel import com.topjohnwu.magisk.arch.BaseViewModel
import com.topjohnwu.magisk.core.AppContext
import com.topjohnwu.magisk.core.BuildConfig import com.topjohnwu.magisk.core.BuildConfig
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.R import com.topjohnwu.magisk.core.R
import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.core.isRunningAsStub import com.topjohnwu.magisk.core.isRunningAsStub
import com.topjohnwu.magisk.core.ktx.activity import com.topjohnwu.magisk.core.ktx.activity
import com.topjohnwu.magisk.core.ktx.toast import com.topjohnwu.magisk.core.ktx.toast

View File

@ -9,11 +9,11 @@ import androidx.databinding.ObservableArrayList
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.arch.AsyncLoadViewModel import com.topjohnwu.magisk.arch.AsyncLoadViewModel
import com.topjohnwu.magisk.core.AppContext
import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Info import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.R import com.topjohnwu.magisk.core.R
import com.topjohnwu.magisk.core.data.magiskdb.PolicyDao import com.topjohnwu.magisk.core.data.magiskdb.PolicyDao
import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.core.ktx.getLabel import com.topjohnwu.magisk.core.ktx.getLabel
import com.topjohnwu.magisk.core.model.su.SuPolicy import com.topjohnwu.magisk.core.model.su.SuPolicy
import com.topjohnwu.magisk.core.utils.currentLocale import com.topjohnwu.magisk.core.utils.currentLocale

View File

@ -18,10 +18,10 @@ import androidx.databinding.Bindable
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.arch.BaseViewModel import com.topjohnwu.magisk.arch.BaseViewModel
import com.topjohnwu.magisk.core.AppContext
import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.R import com.topjohnwu.magisk.core.R
import com.topjohnwu.magisk.core.data.magiskdb.PolicyDao import com.topjohnwu.magisk.core.data.magiskdb.PolicyDao
import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.core.ktx.getLabel import com.topjohnwu.magisk.core.ktx.getLabel
import com.topjohnwu.magisk.core.ktx.toast import com.topjohnwu.magisk.core.ktx.toast
import com.topjohnwu.magisk.core.model.su.SuPolicy.Companion.ALLOW import com.topjohnwu.magisk.core.model.su.SuPolicy.Companion.ALLOW

View File

@ -1,32 +1,9 @@
package com.topjohnwu.magisk.core package com.topjohnwu.magisk.core
import android.app.Activity
import android.app.Application import android.app.Application
import android.content.Context import android.content.Context
import android.content.res.Configuration
import android.os.Bundle
import android.system.Os
import androidx.profileinstaller.ProfileInstaller
import com.topjohnwu.magisk.StubApk import com.topjohnwu.magisk.StubApk
import com.topjohnwu.magisk.core.base.UntrackedActivity
import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.utils.NetworkObserver
import com.topjohnwu.magisk.core.utils.ProcessLifecycle
import com.topjohnwu.magisk.core.utils.RootUtils import com.topjohnwu.magisk.core.utils.RootUtils
import com.topjohnwu.magisk.core.utils.ShellInit
import com.topjohnwu.magisk.core.utils.refreshLocale
import com.topjohnwu.magisk.core.utils.setConfig
import com.topjohnwu.magisk.view.Notifications
import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.internal.UiThreadHandler
import com.topjohnwu.superuser.ipc.RootService
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.asExecutor
import kotlinx.coroutines.launch
import timber.log.Timber
import java.lang.ref.WeakReference
import kotlin.system.exitProcess
open class App() : Application() { open class App() : Application() {
@ -39,94 +16,12 @@ open class App() : Application() {
Info.stub = data Info.stub = data
} }
init {
// Always log full stack trace with Timber
Timber.plant(Timber.DebugTree())
Thread.setDefaultUncaughtExceptionHandler { _, e ->
Timber.e(e)
exitProcess(1)
}
Os.setenv("PATH", "${Os.getenv("PATH")}:/debug_ramdisk:/sbin", true)
}
override fun attachBaseContext(context: Context) { override fun attachBaseContext(context: Context) {
// Get the actual ContextImpl
val app: Application
val base: Context
if (context is Application) { if (context is Application) {
app = context AppContext.attachApplication(context)
base = context.baseContext
AppApkPath = StubApk.current(base).path
} else { } else {
app = this super.attachBaseContext(context)
base = context AppContext.attachApplication(this)
AppApkPath = base.packageResourcePath
} }
super.attachBaseContext(base)
ServiceLocator.context = base
app.registerActivityLifecycleCallbacks(ActivityTracker)
val shellBuilder = Shell.Builder.create()
.setFlags(Shell.FLAG_MOUNT_MASTER)
.setInitializers(ShellInit::class.java)
.setContext(base)
.setTimeout(2)
Shell.setDefaultBuilder(shellBuilder)
Shell.EXECUTOR = Dispatchers.IO.asExecutor()
RootUtils.bindTask = RootService.bindOrTask(
intent<RootUtils>(),
UiThreadHandler.executor,
RootUtils.Connection
)
// Pre-heat the shell ASAP
Shell.getShell(null) {}
refreshLocale()
resources.patch()
Notifications.setup()
}
override fun onCreate() {
super.onCreate()
ProcessLifecycle.init(this)
NetworkObserver.init(this)
if (!BuildConfig.DEBUG && !isRunningAsStub) {
GlobalScope.launch(Dispatchers.IO) {
ProfileInstaller.writeProfile(this@App)
}
}
}
override fun onConfigurationChanged(newConfig: Configuration) {
if (resources.configuration.diff(newConfig) != 0) {
resources.setConfig(newConfig)
}
if (!isRunningAsStub)
super.onConfigurationChanged(newConfig)
} }
} }
object ActivityTracker : Application.ActivityLifecycleCallbacks {
val foreground: Activity? get() = ref.get()
@Volatile
private var ref = WeakReference<Activity>(null)
override fun onActivityResumed(activity: Activity) {
if (activity is UntrackedActivity) return
ref = WeakReference(activity)
}
override fun onActivityPaused(activity: Activity) {
if (activity is UntrackedActivity) return
ref.clear()
}
override fun onActivityCreated(activity: Activity, bundle: Bundle?) {}
override fun onActivityStarted(activity: Activity) {}
override fun onActivityStopped(activity: Activity) {}
override fun onActivitySaveInstanceState(activity: Activity, bundle: Bundle) {}
override fun onActivityDestroyed(activity: Activity) {}
}

View File

@ -0,0 +1,125 @@
package com.topjohnwu.magisk.core
import android.app.Activity
import android.app.Application
import android.content.ComponentCallbacks2
import android.content.Context
import android.content.ContextWrapper
import android.content.res.Configuration
import android.os.Build
import android.os.Build.VERSION.SDK_INT
import android.os.Bundle
import android.system.Os
import androidx.profileinstaller.ProfileInstaller
import com.topjohnwu.magisk.StubApk
import com.topjohnwu.magisk.core.base.UntrackedActivity
import com.topjohnwu.magisk.core.utils.NetworkObserver
import com.topjohnwu.magisk.core.utils.ProcessLifecycle
import com.topjohnwu.magisk.core.utils.RootUtils
import com.topjohnwu.magisk.core.utils.ShellInit
import com.topjohnwu.magisk.core.utils.refreshLocale
import com.topjohnwu.magisk.core.utils.setConfig
import com.topjohnwu.magisk.view.Notifications
import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.internal.UiThreadHandler
import com.topjohnwu.superuser.ipc.RootService
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.asExecutor
import kotlinx.coroutines.launch
import timber.log.Timber
import java.lang.ref.WeakReference
import kotlin.system.exitProcess
object AppContext : ContextWrapper(null),
Application.ActivityLifecycleCallbacks, ComponentCallbacks2 {
val foregroundActivity: Activity? get() = ref.get()
@Volatile
private var ref = WeakReference<Activity>(null)
private lateinit var application: Application
init {
// Always log full stack trace with Timber
Timber.plant(Timber.DebugTree())
Thread.setDefaultUncaughtExceptionHandler { _, e ->
Timber.e(e)
exitProcess(1)
}
Os.setenv("PATH", "${Os.getenv("PATH")}:/debug_ramdisk:/sbin", true)
}
override fun onConfigurationChanged(newConfig: Configuration) {
resources.setConfig(newConfig)
}
override fun onActivityResumed(activity: Activity) {
if (activity is UntrackedActivity) return
ref = WeakReference(activity)
}
override fun onActivityPaused(activity: Activity) {
if (activity is UntrackedActivity) return
ref.clear()
}
override fun getApplicationContext() = application
fun attachApplication(app: Application) {
application = app
val base = app.baseContext
attachBaseContext(base)
app.registerActivityLifecycleCallbacks(this)
app.registerComponentCallbacks(this)
AppApkPath = if (isRunningAsStub) {
StubApk.current(base).path
} else {
base.packageResourcePath
}
refreshLocale()
resources.patch()
val shellBuilder = Shell.Builder.create()
.setFlags(Shell.FLAG_MOUNT_MASTER)
.setInitializers(ShellInit::class.java)
.setContext(this)
.setTimeout(2)
Shell.setDefaultBuilder(shellBuilder)
Shell.EXECUTOR = Dispatchers.IO.asExecutor()
RootUtils.bindTask = RootService.bindOrTask(
intent<RootUtils>(),
UiThreadHandler.executor,
RootUtils.Connection
)
// Pre-heat the shell ASAP
Shell.getShell(null) {}
Notifications.setup()
ProcessLifecycle.init(this)
NetworkObserver.init(this)
if (!BuildConfig.DEBUG && !isRunningAsStub) {
GlobalScope.launch(Dispatchers.IO) {
ProfileInstaller.writeProfile(this@AppContext)
}
}
}
override fun createDeviceProtectedStorageContext(): Context {
return if (SDK_INT >= Build.VERSION_CODES.N) {
super.createDeviceProtectedStorageContext()
} else {
this
}
}
override fun onActivityCreated(activity: Activity, bundle: Bundle?) {}
override fun onActivityStarted(activity: Activity) {}
override fun onActivityStopped(activity: Activity) {}
override fun onActivitySaveInstanceState(activity: Activity, bundle: Bundle) {}
override fun onActivityDestroyed(activity: Activity) {}
override fun onLowMemory() {}
override fun onTrimMemory(level: Int) {}
}

View File

@ -2,7 +2,6 @@ package com.topjohnwu.magisk.core
import android.annotation.SuppressLint import android.annotation.SuppressLint
import androidx.core.content.edit import androidx.core.content.edit
import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.core.di.ServiceLocator import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.ktx.writeTo import com.topjohnwu.magisk.core.ktx.writeTo
import com.topjohnwu.magisk.core.repository.DBConfig import com.topjohnwu.magisk.core.repository.DBConfig

View File

@ -11,7 +11,6 @@ import android.content.res.Configuration
import android.content.res.Resources import android.content.res.Resources
import android.util.DisplayMetrics import android.util.DisplayMetrics
import com.topjohnwu.magisk.StubApk import com.topjohnwu.magisk.StubApk
import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.core.ktx.unwrap import com.topjohnwu.magisk.core.ktx.unwrap
import com.topjohnwu.magisk.core.utils.syncLocale import com.topjohnwu.magisk.core.utils.syncLocale

View File

@ -3,7 +3,6 @@ package com.topjohnwu.magisk.core
import android.app.KeyguardManager import android.app.KeyguardManager
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.topjohnwu.magisk.StubApk import com.topjohnwu.magisk.StubApk
import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.core.ktx.getProperty import com.topjohnwu.magisk.core.ktx.getProperty
import com.topjohnwu.magisk.core.model.UpdateInfo import com.topjohnwu.magisk.core.model.UpdateInfo
import com.topjohnwu.magisk.core.repository.NetworkService import com.topjohnwu.magisk.core.repository.NetworkService

View File

@ -1,7 +1,7 @@
package com.topjohnwu.magisk.core.data.magiskdb package com.topjohnwu.magisk.core.data.magiskdb
import com.topjohnwu.magisk.core.AppContext
import com.topjohnwu.magisk.core.Const import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.core.model.su.SuPolicy import com.topjohnwu.magisk.core.model.su.SuPolicy
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit

View File

@ -4,6 +4,7 @@ import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.text.method.LinkMovementMethod import android.text.method.LinkMovementMethod
import androidx.room.Room import androidx.room.Room
import com.topjohnwu.magisk.core.AppContext
import com.topjohnwu.magisk.core.Const import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.data.SuLogDatabase import com.topjohnwu.magisk.core.data.SuLogDatabase
import com.topjohnwu.magisk.core.data.magiskdb.PolicyDao import com.topjohnwu.magisk.core.data.magiskdb.PolicyDao
@ -15,13 +16,10 @@ import com.topjohnwu.magisk.core.repository.NetworkService
import io.noties.markwon.Markwon import io.noties.markwon.Markwon
import io.noties.markwon.utils.NoCopySpannableFactory import io.noties.markwon.utils.NoCopySpannableFactory
val AppContext: Context inline get() = ServiceLocator.context
@SuppressLint("StaticFieldLeak") @SuppressLint("StaticFieldLeak")
object ServiceLocator { object ServiceLocator {
lateinit var context: Context val deContext by lazy { AppContext.deviceProtectedContext }
val deContext by lazy { context.deviceProtectedContext }
val timeoutPrefs by lazy { deContext.getSharedPreferences("su_timeout", 0) } val timeoutPrefs by lazy { deContext.getSharedPreferences("su_timeout", 0) }
// Database // Database
@ -32,9 +30,9 @@ object ServiceLocator {
val logRepo by lazy { LogRepository(sulogDB) } val logRepo by lazy { LogRepository(sulogDB) }
// Networking // Networking
val okhttp by lazy { createOkHttpClient(context) } val okhttp by lazy { createOkHttpClient(AppContext) }
val retrofit by lazy { createRetrofit(okhttp) } val retrofit by lazy { createRetrofit(okhttp) }
val markwon by lazy { createMarkwon(context) } val markwon by lazy { createMarkwon(AppContext) }
val networkService by lazy { val networkService by lazy {
NetworkService( NetworkService(
createApiService(retrofit, Const.Url.GITHUB_PAGE_URL), createApiService(retrofit, Const.Url.GITHUB_PAGE_URL),

View File

@ -17,7 +17,7 @@ import androidx.core.content.getSystemService
import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.topjohnwu.magisk.StubApk import com.topjohnwu.magisk.StubApk
import com.topjohnwu.magisk.core.ActivityTracker import com.topjohnwu.magisk.core.AppContext
import com.topjohnwu.magisk.core.Const import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.JobService import com.topjohnwu.magisk.core.JobService
import com.topjohnwu.magisk.core.R import com.topjohnwu.magisk.core.R
@ -170,7 +170,7 @@ class DownloadEngine(
is Subject.Module -> handleModule(stream, subject.file) is Subject.Module -> handleModule(stream, subject.file)
else -> stream.copyAndClose(subject.file.outputStream()) else -> stream.copyAndClose(subject.file.outputStream())
} }
val activity = ActivityTracker.foreground val activity = AppContext.foregroundActivity
if (activity != null && subject.autoLaunch) { if (activity != null && subject.autoLaunch) {
notifyRemove(subject.notifyId) notifyRemove(subject.notifyId)
subject.pendingIntent(activity)?.send() subject.pendingIntent(activity)?.send()

View File

@ -2,8 +2,8 @@ package com.topjohnwu.magisk.core.tasks
import android.net.Uri import android.net.Uri
import androidx.core.net.toFile import androidx.core.net.toFile
import com.topjohnwu.magisk.core.AppContext
import com.topjohnwu.magisk.core.Const import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.core.ktx.writeTo import com.topjohnwu.magisk.core.ktx.writeTo
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.displayName import com.topjohnwu.magisk.core.utils.MediaStoreUtils.displayName
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.inputStream import com.topjohnwu.magisk.core.utils.MediaStoreUtils.inputStream

View File

@ -5,12 +5,11 @@ package com.topjohnwu.magisk.core.utils
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.res.Configuration import android.content.res.Configuration
import android.content.res.Resources import android.content.res.Resources
import com.topjohnwu.magisk.core.ActivityTracker import com.topjohnwu.magisk.core.AppContext
import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.R import com.topjohnwu.magisk.core.R
import com.topjohnwu.magisk.core.base.relaunch import com.topjohnwu.magisk.core.base.relaunch
import com.topjohnwu.magisk.core.createNewResources import com.topjohnwu.magisk.core.createNewResources
import com.topjohnwu.magisk.core.di.AppContext
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.util.Locale import java.util.Locale
@ -72,7 +71,7 @@ withContext(Dispatchers.Default) {
fun Resources.setConfig(config: Configuration) { fun Resources.setConfig(config: Configuration) {
config.setLocale(currentLocale) config.setLocale(currentLocale)
updateConfiguration(config, displayMetrics) updateConfiguration(config, null)
} }
fun Resources.syncLocale() = setConfig(configuration) fun Resources.syncLocale() = setConfig(configuration)
@ -85,5 +84,5 @@ fun refreshLocale() {
} }
Locale.setDefault(currentLocale) Locale.setDefault(currentLocale)
AppContext.resources.syncLocale() AppContext.resources.syncLocale()
ActivityTracker.foreground?.relaunch() AppContext.foregroundActivity?.relaunch()
} }

View File

@ -10,8 +10,8 @@ import android.provider.OpenableColumns
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.core.net.toFile import androidx.core.net.toFile
import androidx.core.net.toUri import androidx.core.net.toUri
import com.topjohnwu.magisk.core.AppContext
import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.di.AppContext
import java.io.File import java.io.File
import java.io.FileNotFoundException import java.io.FileNotFoundException
import java.io.IOException import java.io.IOException

View File

@ -9,8 +9,8 @@ import android.os.Build
import android.os.Build.VERSION.SDK_INT import android.os.Build.VERSION.SDK_INT
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
import androidx.core.graphics.drawable.toIcon import androidx.core.graphics.drawable.toIcon
import com.topjohnwu.magisk.core.AppContext
import com.topjohnwu.magisk.core.R import com.topjohnwu.magisk.core.R
import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.core.download.DownloadEngine import com.topjohnwu.magisk.core.download.DownloadEngine
import com.topjohnwu.magisk.core.download.Subject import com.topjohnwu.magisk.core.download.Subject
import com.topjohnwu.magisk.core.ktx.getBitmap import com.topjohnwu.magisk.core.ktx.getBitmap