Remove Koin

Non static DI is bad
This commit is contained in:
topjohnwu 2021-04-18 04:46:11 -07:00
parent 649b49ff45
commit 038f73a5f7
56 changed files with 194 additions and 306 deletions

View File

@ -209,10 +209,6 @@ dependencies {
implementation("com.github.topjohnwu.libsu:core:${vLibsu}") implementation("com.github.topjohnwu.libsu:core:${vLibsu}")
implementation("com.github.topjohnwu.libsu:io:${vLibsu}") implementation("com.github.topjohnwu.libsu:io:${vLibsu}")
val vKoin = "2.2.2"
implementation("io.insert-koin:koin-android:${vKoin}")
implementation("io.insert-koin:koin-androidx-viewmodel:${vKoin}")
val vRetrofit = "2.9.0" val vRetrofit = "2.9.0"
implementation("com.squareup.retrofit2:retrofit:${vRetrofit}") implementation("com.squareup.retrofit2:retrofit:${vRetrofit}")
implementation("com.squareup.retrofit2:converter-moshi:${vRetrofit}") implementation("com.squareup.retrofit2:converter-moshi:${vRetrofit}")

View File

@ -19,11 +19,10 @@ import com.topjohnwu.magisk.events.*
import com.topjohnwu.magisk.utils.ObservableHost import com.topjohnwu.magisk.utils.ObservableHost
import com.topjohnwu.magisk.utils.set import com.topjohnwu.magisk.utils.set
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import org.koin.core.component.KoinComponent
abstract class BaseViewModel( abstract class BaseViewModel(
initialState: State = State.LOADING initialState: State = State.LOADING
) : ViewModel(), ObservableHost, KoinComponent { ) : ViewModel(), ObservableHost {
override var callbacks: PropertyChangeRegistry? = null override var callbacks: PropertyChangeRegistry? = null

View File

@ -13,11 +13,9 @@ import com.topjohnwu.magisk.core.utils.AppShellInit
import com.topjohnwu.magisk.core.utils.BusyBoxInit import com.topjohnwu.magisk.core.utils.BusyBoxInit
import com.topjohnwu.magisk.core.utils.IODispatcherExecutor import com.topjohnwu.magisk.core.utils.IODispatcherExecutor
import com.topjohnwu.magisk.core.utils.updateConfig import com.topjohnwu.magisk.core.utils.updateConfig
import com.topjohnwu.magisk.di.koinModules import com.topjohnwu.magisk.di.ServiceLocator
import com.topjohnwu.magisk.ktx.unwrap import com.topjohnwu.magisk.ktx.unwrap
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import org.koin.android.ext.koin.androidContext
import org.koin.core.context.startKoin
import timber.log.Timber import timber.log.Timber
import java.io.File import java.io.File
import kotlin.system.exitProcess import kotlin.system.exitProcess
@ -64,11 +62,7 @@ open class App() : Application() {
}.getOrNull() ?: info.nativeLibraryDir }.getOrNull() ?: info.nativeLibraryDir
Const.NATIVE_LIB_DIR = File(libDir) Const.NATIVE_LIB_DIR = File(libDir)
// Normal startup ServiceLocator.context = wrapped
startKoin {
androidContext(wrapped)
modules(koinModules)
}
AssetHack.init(impl) AssetHack.init(impl)
app.registerActivityLifecycleCallbacks(ForegroundTracker) app.registerActivityLifecycleCallbacks(ForegroundTracker)
WorkManager.initialize(impl.wrapJob(), androidx.work.Configuration.Builder().build()) WorkManager.initialize(impl.wrapJob(), androidx.work.Configuration.Builder().build())

View File

@ -1,20 +1,16 @@
package com.topjohnwu.magisk.core package com.topjohnwu.magisk.core
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import android.util.Xml import android.util.Xml
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.core.content.edit import androidx.core.content.edit
import com.topjohnwu.magisk.BuildConfig import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.core.magiskdb.SettingsDao
import com.topjohnwu.magisk.core.magiskdb.StringDao
import com.topjohnwu.magisk.core.utils.BiometricHelper import com.topjohnwu.magisk.core.utils.BiometricHelper
import com.topjohnwu.magisk.core.utils.refreshLocale import com.topjohnwu.magisk.core.utils.refreshLocale
import com.topjohnwu.magisk.data.preference.PreferenceModel import com.topjohnwu.magisk.data.preference.PreferenceModel
import com.topjohnwu.magisk.data.repository.DBConfig import com.topjohnwu.magisk.data.repository.DBConfig
import com.topjohnwu.magisk.di.Protected import com.topjohnwu.magisk.di.ServiceLocator
import com.topjohnwu.magisk.ktx.inject
import com.topjohnwu.magisk.ui.theme.Theme import com.topjohnwu.magisk.ui.theme.Theme
import org.xmlpull.v1.XmlPullParser import org.xmlpull.v1.XmlPullParser
import java.io.File import java.io.File
@ -22,9 +18,9 @@ import java.io.InputStream
object Config : PreferenceModel, DBConfig { object Config : PreferenceModel, DBConfig {
override val stringDao: StringDao by inject() override val stringDB get() = ServiceLocator.stringDB
override val settingsDao: SettingsDao by inject() override val settingsDB get() = ServiceLocator.settingsDB
override val context: Context by inject(Protected) override val context get() = ServiceLocator.deContext
@get:SuppressLint("ApplySharedPref") @get:SuppressLint("ApplySharedPref")
val prefsFile: File get() { val prefsFile: File get() {

View File

@ -6,7 +6,7 @@ import com.topjohnwu.magisk.DynAPK
import com.topjohnwu.magisk.core.model.UpdateInfo import com.topjohnwu.magisk.core.model.UpdateInfo
import com.topjohnwu.magisk.core.utils.net.NetworkObserver import com.topjohnwu.magisk.core.utils.net.NetworkObserver
import com.topjohnwu.magisk.data.repository.NetworkService import com.topjohnwu.magisk.data.repository.NetworkService
import com.topjohnwu.magisk.ktx.get import com.topjohnwu.magisk.di.AppContext
import com.topjohnwu.magisk.ktx.getProperty import com.topjohnwu.magisk.ktx.getProperty
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.ShellUtils.fastCmd import com.topjohnwu.superuser.ShellUtils.fastCmd
@ -43,7 +43,7 @@ object Info {
val isConnected by lazy { val isConnected by lazy {
ObservableBoolean(false).also { field -> ObservableBoolean(false).also { field ->
NetworkObserver.observe(get()) { NetworkObserver.observe(AppContext) {
UiThreadHandler.run { field.set(it) } UiThreadHandler.run { field.set(it) }
} }
} }

View File

@ -4,8 +4,7 @@ import android.annotation.SuppressLint
import android.content.ContextWrapper import android.content.ContextWrapper
import android.content.Intent import android.content.Intent
import com.topjohnwu.magisk.core.base.BaseReceiver import com.topjohnwu.magisk.core.base.BaseReceiver
import com.topjohnwu.magisk.core.magiskdb.PolicyDao import com.topjohnwu.magisk.di.ServiceLocator
import com.topjohnwu.magisk.ktx.inject
import com.topjohnwu.magisk.view.Shortcuts import com.topjohnwu.magisk.view.Shortcuts
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
@ -13,7 +12,7 @@ import kotlinx.coroutines.launch
open class Receiver : BaseReceiver() { open class Receiver : BaseReceiver() {
private val policyDB: PolicyDao by inject() private val policyDB get() = ServiceLocator.policyDB
@SuppressLint("InlinedApi") @SuppressLint("InlinedApi")
private fun getPkg(intent: Intent): String? { private fun getPkg(intent: Intent): String? {

View File

@ -7,8 +7,7 @@ import com.topjohnwu.magisk.BuildConfig.APPLICATION_ID
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.base.BaseActivity import com.topjohnwu.magisk.core.base.BaseActivity
import com.topjohnwu.magisk.core.tasks.HideAPK import com.topjohnwu.magisk.core.tasks.HideAPK
import com.topjohnwu.magisk.data.repository.NetworkService import com.topjohnwu.magisk.di.ServiceLocator
import com.topjohnwu.magisk.ktx.get
import com.topjohnwu.magisk.ui.MainActivity import com.topjohnwu.magisk.ui.MainActivity
import com.topjohnwu.magisk.view.MagiskDialog import com.topjohnwu.magisk.view.MagiskDialog
import com.topjohnwu.magisk.view.Notifications import com.topjohnwu.magisk.view.Notifications
@ -68,7 +67,7 @@ open class SplashActivity : BaseActivity() {
Shortcuts.setupDynamic(this) Shortcuts.setupDynamic(this)
// Pre-fetch network services // Pre-fetch network services
get<NetworkService>() ServiceLocator.networkService
DONE = true DONE = true
startActivity(redirect<MainActivity>()) startActivity(redirect<MainActivity>())

View File

@ -4,16 +4,14 @@ import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import androidx.work.* import androidx.work.*
import com.topjohnwu.magisk.BuildConfig import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.data.repository.NetworkService import com.topjohnwu.magisk.di.ServiceLocator
import com.topjohnwu.magisk.ktx.inject
import com.topjohnwu.magisk.view.Notifications import com.topjohnwu.magisk.view.Notifications
import org.koin.core.component.KoinComponent
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
class UpdateCheckService(context: Context, workerParams: WorkerParameters) class UpdateCheckService(context: Context, workerParams: WorkerParameters)
: CoroutineWorker(context, workerParams), KoinComponent { : CoroutineWorker(context, workerParams) {
private val svc: NetworkService by inject() private val svc get() = ServiceLocator.networkService
override suspend fun doWork(): Result { override suspend fun doWork(): Result {
return svc.fetchUpdate()?.run { return svc.fetchUpdate()?.run {

View File

@ -5,9 +5,8 @@ import android.content.Context
import android.content.ContextWrapper import android.content.ContextWrapper
import android.content.Intent import android.content.Intent
import com.topjohnwu.magisk.core.wrap import com.topjohnwu.magisk.core.wrap
import org.koin.core.component.KoinComponent
abstract class BaseReceiver : BroadcastReceiver(), KoinComponent { abstract class BaseReceiver : BroadcastReceiver() {
final override fun onReceive(context: Context, intent: Intent?) { final override fun onReceive(context: Context, intent: Intent?) {
onReceive(context.wrap() as ContextWrapper, intent) onReceive(context.wrap() as ContextWrapper, intent)

View File

@ -3,9 +3,8 @@ package com.topjohnwu.magisk.core.base
import android.app.Service import android.app.Service
import android.content.Context import android.content.Context
import com.topjohnwu.magisk.core.wrap import com.topjohnwu.magisk.core.wrap
import org.koin.core.component.KoinComponent
abstract class BaseService : Service(), KoinComponent { abstract class BaseService : Service() {
override fun attachBaseContext(base: Context) { override fun attachBaseContext(base: Context) {
super.attachBaseContext(base.wrap()) super.attachBaseContext(base.wrap())
} }

View File

@ -9,15 +9,13 @@ import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.ForegroundTracker import com.topjohnwu.magisk.core.ForegroundTracker
import com.topjohnwu.magisk.core.base.BaseService import com.topjohnwu.magisk.core.base.BaseService
import com.topjohnwu.magisk.core.utils.ProgressInputStream import com.topjohnwu.magisk.core.utils.ProgressInputStream
import com.topjohnwu.magisk.data.repository.NetworkService import com.topjohnwu.magisk.di.ServiceLocator
import com.topjohnwu.magisk.ktx.inject
import com.topjohnwu.magisk.view.Notifications import com.topjohnwu.magisk.view.Notifications
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import okhttp3.ResponseBody import okhttp3.ResponseBody
import org.koin.core.component.KoinComponent
import timber.log.Timber import timber.log.Timber
import java.io.IOException import java.io.IOException
import java.io.InputStream import java.io.InputStream
@ -25,13 +23,13 @@ import java.util.*
import kotlin.collections.HashMap import kotlin.collections.HashMap
import kotlin.random.Random.Default.nextInt import kotlin.random.Random.Default.nextInt
abstract class BaseDownloader : BaseService(), KoinComponent { abstract class BaseDownloader : BaseService() {
private val hasNotifications get() = notifications.isNotEmpty() private val hasNotifications get() = notifications.isNotEmpty()
private val notifications = Collections.synchronizedMap(HashMap<Int, Notification.Builder>()) private val notifications = Collections.synchronizedMap(HashMap<Int, Notification.Builder>())
private val coroutineScope = CoroutineScope(Dispatchers.IO) private val coroutineScope = CoroutineScope(Dispatchers.IO)
val service: NetworkService by inject() val service get() = ServiceLocator.networkService
// -- Service overrides // -- Service overrides
@ -174,7 +172,7 @@ abstract class BaseDownloader : BaseService(), KoinComponent {
// --- // ---
companion object : KoinComponent { companion object {
const val ACTION_KEY = "download_action" const val ACTION_KEY = "download_action"
private val progressBroadcast = MutableLiveData<Pair<Float, Subject>?>() private val progressBroadcast = MutableLiveData<Pair<Float, Subject>?>()

View File

@ -1,6 +1,5 @@
package com.topjohnwu.magisk.core.download package com.topjohnwu.magisk.core.download
import android.content.Context
import android.net.Uri import android.net.Uri
import android.os.Parcelable import android.os.Parcelable
import androidx.core.net.toUri import androidx.core.net.toUri
@ -9,12 +8,12 @@ import com.topjohnwu.magisk.core.model.MagiskJson
import com.topjohnwu.magisk.core.model.StubJson import com.topjohnwu.magisk.core.model.StubJson
import com.topjohnwu.magisk.core.model.module.OnlineModule import com.topjohnwu.magisk.core.model.module.OnlineModule
import com.topjohnwu.magisk.core.utils.MediaStoreUtils import com.topjohnwu.magisk.core.utils.MediaStoreUtils
import com.topjohnwu.magisk.di.AppContext
import com.topjohnwu.magisk.ktx.cachedFile import com.topjohnwu.magisk.ktx.cachedFile
import com.topjohnwu.magisk.ktx.get
import kotlinx.parcelize.IgnoredOnParcel import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
private fun cachedFile(name: String) = get<Context>().cachedFile(name).apply { delete() }.toUri() private fun cachedFile(name: String) = AppContext.cachedFile(name).apply { delete() }.toUri()
sealed class Subject : Parcelable { sealed class Subject : Parcelable {

View File

@ -1,11 +1,11 @@
package com.topjohnwu.magisk.core.magiskdb package com.topjohnwu.magisk.core.magiskdb
import android.content.Context
import android.content.pm.PackageManager import android.content.pm.PackageManager
import com.topjohnwu.magisk.core.Const import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.model.su.SuPolicy import com.topjohnwu.magisk.core.model.su.SuPolicy
import com.topjohnwu.magisk.core.model.su.toMap import com.topjohnwu.magisk.core.model.su.toMap
import com.topjohnwu.magisk.core.model.su.toPolicy import com.topjohnwu.magisk.core.model.su.toPolicy
import com.topjohnwu.magisk.di.AppContext
import com.topjohnwu.magisk.ktx.now import com.topjohnwu.magisk.ktx.now
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -13,9 +13,7 @@ import timber.log.Timber
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
class PolicyDao( class PolicyDao : BaseDao() {
private val context: Context
) : BaseDao() {
override val table: String = Table.POLICY override val table: String = Table.POLICY
@ -56,7 +54,7 @@ class PolicyDao(
} }
private fun Map<String, String>.toPolicyOrNull(): SuPolicy? { private fun Map<String, String>.toPolicyOrNull(): SuPolicy? {
return runCatching { toPolicy(context.packageManager) }.getOrElse { return runCatching { toPolicy(AppContext.packageManager) }.getOrElse {
Timber.e(it) Timber.e(it)
if (it is PackageManager.NameNotFoundException) { if (it is PackageManager.NameNotFoundException) {
val uid = getOrElse("uid") { null } ?: return null val uid = getOrElse("uid") { null } ?: return null

View File

@ -4,8 +4,7 @@ import android.os.Parcelable
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import com.topjohnwu.magisk.core.model.ModuleJson import com.topjohnwu.magisk.core.model.ModuleJson
import com.topjohnwu.magisk.data.repository.NetworkService import com.topjohnwu.magisk.di.ServiceLocator
import com.topjohnwu.magisk.ktx.get
import com.topjohnwu.magisk.ktx.legalFilename import com.topjohnwu.magisk.ktx.legalFilename
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
import java.text.DateFormat import java.text.DateFormat
@ -26,7 +25,7 @@ data class OnlineModule(
val notes_url: String val notes_url: String
) : Module(), Parcelable { ) : Module(), Parcelable {
private val svc: NetworkService get() = get() private val svc get() = ServiceLocator.networkService
constructor(info: ModuleJson) : this( constructor(info: ModuleJson) : this(
id = info.id, id = info.id,

View File

@ -13,8 +13,7 @@ import com.topjohnwu.magisk.core.intent
import com.topjohnwu.magisk.core.model.su.SuPolicy import com.topjohnwu.magisk.core.model.su.SuPolicy
import com.topjohnwu.magisk.core.model.su.toLog import com.topjohnwu.magisk.core.model.su.toLog
import com.topjohnwu.magisk.core.model.su.toPolicy import com.topjohnwu.magisk.core.model.su.toPolicy
import com.topjohnwu.magisk.data.repository.LogRepository import com.topjohnwu.magisk.di.ServiceLocator
import com.topjohnwu.magisk.ktx.get
import com.topjohnwu.magisk.ktx.startActivity import com.topjohnwu.magisk.ktx.startActivity
import com.topjohnwu.magisk.ktx.startActivityWithRoot import com.topjohnwu.magisk.ktx.startActivityWithRoot
import com.topjohnwu.magisk.ui.surequest.SuRequestActivity import com.topjohnwu.magisk.ui.surequest.SuRequestActivity
@ -104,9 +103,8 @@ object SuCallbackHandler {
command = command command = command
) )
val logRepo = get<LogRepository>()
GlobalScope.launch { GlobalScope.launch {
logRepo.insert(log) ServiceLocator.logRepo.insert(log)
} }
} }

View File

@ -1,19 +1,16 @@
package com.topjohnwu.magisk.core.tasks package com.topjohnwu.magisk.core.tasks
import android.content.Context
import android.net.Uri import android.net.Uri
import androidx.core.net.toFile import androidx.core.net.toFile
import com.topjohnwu.magisk.core.Const import com.topjohnwu.magisk.core.Const
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
import com.topjohnwu.magisk.core.utils.unzip import com.topjohnwu.magisk.core.utils.unzip
import com.topjohnwu.magisk.ktx.inject import com.topjohnwu.magisk.di.AppContext
import com.topjohnwu.magisk.ktx.writeTo import com.topjohnwu.magisk.ktx.writeTo
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.koin.core.component.KoinComponent
import timber.log.Timber import timber.log.Timber
import java.io.File import java.io.File
import java.io.FileNotFoundException import java.io.FileNotFoundException
@ -23,10 +20,9 @@ open class FlashZip(
private val mUri: Uri, private val mUri: Uri,
private val console: MutableList<String>, private val console: MutableList<String>,
private val logs: MutableList<String> private val logs: MutableList<String>
): KoinComponent { ) {
private val context: Context by inject() private val installDir = File(AppContext.cacheDir, "flash")
private val installDir = File(context.cacheDir, "flash")
private lateinit var zipFile: File private lateinit var zipFile: File
@Throws(IOException::class) @Throws(IOException::class)

View File

@ -14,8 +14,7 @@ import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.Provider import com.topjohnwu.magisk.core.Provider
import com.topjohnwu.magisk.core.utils.AXML import com.topjohnwu.magisk.core.utils.AXML
import com.topjohnwu.magisk.core.utils.Keygen import com.topjohnwu.magisk.core.utils.Keygen
import com.topjohnwu.magisk.data.repository.NetworkService import com.topjohnwu.magisk.di.ServiceLocator
import com.topjohnwu.magisk.ktx.inject
import com.topjohnwu.magisk.ktx.writeTo import com.topjohnwu.magisk.ktx.writeTo
import com.topjohnwu.magisk.utils.APKInstall import com.topjohnwu.magisk.utils.APKInstall
import com.topjohnwu.magisk.utils.Utils import com.topjohnwu.magisk.utils.Utils
@ -41,7 +40,7 @@ object HideAPK {
// Some arbitrary limit // Some arbitrary limit
const val MAX_LABEL_LENGTH = 32 const val MAX_LABEL_LENGTH = 32
private val svc: NetworkService by inject() private val svc get() = ServiceLocator.networkService
private val Context.APK_URI get() = Provider.APK_URI(packageName) private val Context.APK_URI get() = Provider.APK_URI(packageName)
private val Context.PREFS_URI get() = Provider.PREFS_URI(packageName) private val Context.PREFS_URI get() = Provider.PREFS_URI(packageName)

View File

@ -1,6 +1,5 @@
package com.topjohnwu.magisk.core.tasks package com.topjohnwu.magisk.core.tasks
import android.content.Context
import android.net.Uri import android.net.Uri
import android.widget.Toast import android.widget.Toast
import androidx.annotation.WorkerThread import androidx.annotation.WorkerThread
@ -12,9 +11,11 @@ import com.topjohnwu.magisk.core.*
import com.topjohnwu.magisk.core.utils.MediaStoreUtils import com.topjohnwu.magisk.core.utils.MediaStoreUtils
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.inputStream import com.topjohnwu.magisk.core.utils.MediaStoreUtils.inputStream
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream import com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream
import com.topjohnwu.magisk.data.repository.NetworkService import com.topjohnwu.magisk.di.ServiceLocator
import com.topjohnwu.magisk.di.Protected import com.topjohnwu.magisk.ktx.reboot
import com.topjohnwu.magisk.ktx.* import com.topjohnwu.magisk.ktx.symlink
import com.topjohnwu.magisk.ktx.withStreams
import com.topjohnwu.magisk.ktx.writeTo
import com.topjohnwu.magisk.utils.Utils import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.signing.SignBoot import com.topjohnwu.signing.SignBoot
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
@ -31,7 +32,6 @@ import org.kamranzafar.jtar.TarEntry
import org.kamranzafar.jtar.TarHeader import org.kamranzafar.jtar.TarHeader
import org.kamranzafar.jtar.TarInputStream import org.kamranzafar.jtar.TarInputStream
import org.kamranzafar.jtar.TarOutputStream import org.kamranzafar.jtar.TarOutputStream
import org.koin.core.component.KoinComponent
import timber.log.Timber import timber.log.Timber
import java.io.* import java.io.*
import java.nio.ByteBuffer import java.nio.ByteBuffer
@ -42,14 +42,14 @@ import java.util.zip.ZipFile
abstract class MagiskInstallImpl protected constructor( abstract class MagiskInstallImpl protected constructor(
protected val console: MutableList<String> = NOPList.getInstance(), protected val console: MutableList<String> = NOPList.getInstance(),
private val logs: MutableList<String> = NOPList.getInstance() private val logs: MutableList<String> = NOPList.getInstance()
) : KoinComponent { ) {
protected var installDir = File("xxx") protected var installDir = File("xxx")
private lateinit var srcBoot: File private lateinit var srcBoot: File
private val shell = Shell.getShell() private val shell = Shell.getShell()
private val service: NetworkService by inject() private val service get() = ServiceLocator.networkService
protected val context: Context by inject(Protected) protected val context get() = ServiceLocator.deContext
private val useRootDir = shell.isRoot && Info.noDataExec private val useRootDir = shell.isRoot && Info.noDataExec
private fun findImage(): Boolean { private fun findImage(): Boolean {

View File

@ -6,12 +6,11 @@ import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.ktx.get import com.topjohnwu.magisk.di.AppContext
import org.koin.core.component.KoinComponent
object BiometricHelper: KoinComponent { object BiometricHelper {
private val mgr by lazy { BiometricManager.from(get()) } private val mgr by lazy { BiometricManager.from(AppContext) }
val isSupported get() = when (mgr.canAuthenticate()) { val isSupported get() = when (mgr.canAuthenticate()) {
BiometricManager.BIOMETRIC_SUCCESS -> true BiometricManager.BIOMETRIC_SUCCESS -> true

View File

@ -1,9 +1,7 @@
package com.topjohnwu.magisk.core.utils package com.topjohnwu.magisk.core.utils
import android.content.ContentResolver
import android.content.ContentUris import android.content.ContentUris
import android.content.ContentValues import android.content.ContentValues
import android.content.Context
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Environment import android.os.Environment
@ -13,7 +11,7 @@ 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.Config import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.ktx.get import com.topjohnwu.magisk.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
@ -24,7 +22,7 @@ import kotlin.experimental.and
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
object MediaStoreUtils { object MediaStoreUtils {
private val cr: ContentResolver by lazy { get<Context>().contentResolver } private val cr get() = AppContext.contentResolver
@get:RequiresApi(api = 29) @get:RequiresApi(api = 29)
private val tableUri private val tableUri

View File

@ -9,8 +9,8 @@ import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty import kotlin.reflect.KProperty
interface DBConfig { interface DBConfig {
val settingsDao: SettingsDao val settingsDB: SettingsDao
val stringDao: StringDao val stringDB: StringDao
fun dbSettings( fun dbSettings(
name: String, name: String,
@ -41,7 +41,7 @@ class DBSettingsValue(
override fun getValue(thisRef: DBConfig, property: KProperty<*>): Int { override fun getValue(thisRef: DBConfig, property: KProperty<*>): Int {
if (value == null) if (value == null)
value = runBlocking { value = runBlocking {
thisRef.settingsDao.fetch(name, default) thisRef.settingsDB.fetch(name, default)
} }
return value as Int return value as Int
} }
@ -51,7 +51,7 @@ class DBSettingsValue(
this.value = value this.value = value
} }
GlobalScope.launch { GlobalScope.launch {
thisRef.settingsDao.put(name, value) thisRef.settingsDB.put(name, value)
} }
} }
} }
@ -82,7 +82,7 @@ class DBStringsValue(
override fun getValue(thisRef: DBConfig, property: KProperty<*>): String { override fun getValue(thisRef: DBConfig, property: KProperty<*>): String {
if (value == null) if (value == null)
value = runBlocking { value = runBlocking {
thisRef.stringDao.fetch(name, default) thisRef.stringDB.fetch(name, default)
} }
return value!! return value!!
} }
@ -94,21 +94,21 @@ class DBStringsValue(
if (value.isEmpty()) { if (value.isEmpty()) {
if (sync) { if (sync) {
runBlocking { runBlocking {
thisRef.stringDao.delete(name) thisRef.stringDB.delete(name)
} }
} else { } else {
GlobalScope.launch { GlobalScope.launch {
thisRef.stringDao.delete(name) thisRef.stringDB.delete(name)
} }
} }
} else { } else {
if (sync) { if (sync) {
runBlocking { runBlocking {
thisRef.stringDao.put(name, value) thisRef.stringDB.put(name, value)
} }
} else { } else {
GlobalScope.launch { GlobalScope.launch {
thisRef.stringDao.put(name, value) thisRef.stringDB.put(name, value)
} }
} }
} }

View File

@ -28,12 +28,11 @@ import com.google.android.material.card.MaterialCardView
import com.google.android.material.chip.Chip import com.google.android.material.chip.Chip
import com.google.android.material.textfield.TextInputLayout import com.google.android.material.textfield.TextInputLayout
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.di.ServiceLocator
import com.topjohnwu.magisk.ktx.coroutineScope import com.topjohnwu.magisk.ktx.coroutineScope
import com.topjohnwu.magisk.ktx.get
import com.topjohnwu.magisk.ktx.replaceRandomWithSpecial import com.topjohnwu.magisk.ktx.replaceRandomWithSpecial
import com.topjohnwu.superuser.internal.UiThreadHandler import com.topjohnwu.superuser.internal.UiThreadHandler
import com.topjohnwu.widget.IndeterminateCheckBox import com.topjohnwu.widget.IndeterminateCheckBox
import io.noties.markwon.Markwon
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -60,8 +59,7 @@ fun setInvisibleUnless(view: View, invisibleUnless: Boolean) {
@BindingAdapter("markdownText") @BindingAdapter("markdownText")
fun setMarkdownText(tv: TextView, text: CharSequence) { fun setMarkdownText(tv: TextView, text: CharSequence) {
tv.coroutineScope.launch(Dispatchers.IO) { tv.coroutineScope.launch(Dispatchers.IO) {
val markwon = get<Markwon>() ServiceLocator.markwon.setMarkdown(tv, text.toString())
markwon.setMarkdown(tv, text.toString())
} }
} }

View File

@ -1,19 +0,0 @@
package com.topjohnwu.magisk.di
import android.content.Context
import androidx.preference.PreferenceManager
import com.topjohnwu.magisk.core.AssetHack
import com.topjohnwu.magisk.ktx.deviceProtectedContext
import org.koin.core.qualifier.named
import org.koin.dsl.module
val SUTimeout = named("su_timeout")
val Protected = named("protected")
val applicationModule = module {
factory { AssetHack.resource }
factory { get<Context>().packageManager }
factory(Protected) { get<Context>().deviceProtectedContext }
single(SUTimeout) { get<Context>(Protected).getSharedPreferences("su_timeout", 0) }
single { PreferenceManager.getDefaultSharedPreferences(get(Protected)) }
}

View File

@ -1,32 +0,0 @@
package com.topjohnwu.magisk.di
import android.content.Context
import androidx.room.Room
import com.topjohnwu.magisk.core.magiskdb.PolicyDao
import com.topjohnwu.magisk.core.magiskdb.SettingsDao
import com.topjohnwu.magisk.core.magiskdb.StringDao
import com.topjohnwu.magisk.core.tasks.RepoUpdater
import com.topjohnwu.magisk.data.database.RepoDatabase
import com.topjohnwu.magisk.data.database.SuLogDatabase
import org.koin.dsl.module
val databaseModule = module {
single { PolicyDao(get()) }
single { SettingsDao() }
single { StringDao() }
single { createRepoDatabase(get()) }
single { get<RepoDatabase>().repoDao() }
single { createSuLogDatabase(get(Protected)).suLogDao() }
single { RepoUpdater(get(), get()) }
}
fun createRepoDatabase(context: Context) =
Room.databaseBuilder(context, RepoDatabase::class.java, "repo.db")
.fallbackToDestructiveMigration()
.build()
fun createSuLogDatabase(context: Context) =
Room.databaseBuilder(context, SuLogDatabase::class.java, "sulogs.db")
.fallbackToDestructiveMigration()
.build()

View File

@ -1,9 +0,0 @@
package com.topjohnwu.magisk.di
val koinModules = listOf(
applicationModule,
networkingModule,
databaseModule,
repositoryModule,
viewModelModules
)

View File

@ -4,12 +4,7 @@ import android.content.Context
import com.squareup.moshi.Moshi import com.squareup.moshi.Moshi
import com.topjohnwu.magisk.BuildConfig import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.data.network.GithubApiServices
import com.topjohnwu.magisk.data.network.GithubPageServices
import com.topjohnwu.magisk.data.network.JSDelivrServices
import com.topjohnwu.magisk.data.network.RawServices
import com.topjohnwu.magisk.ktx.precomputedText import com.topjohnwu.magisk.ktx.precomputedText
import com.topjohnwu.magisk.net.Networking import com.topjohnwu.magisk.net.Networking
import com.topjohnwu.magisk.utils.MarkwonImagePlugin import com.topjohnwu.magisk.utils.MarkwonImagePlugin
@ -20,23 +15,12 @@ import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.dnsoverhttps.DnsOverHttps import okhttp3.dnsoverhttps.DnsOverHttps
import okhttp3.logging.HttpLoggingInterceptor import okhttp3.logging.HttpLoggingInterceptor
import org.koin.dsl.module
import retrofit2.Retrofit import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory import retrofit2.converter.moshi.MoshiConverterFactory
import retrofit2.converter.scalars.ScalarsConverterFactory import retrofit2.converter.scalars.ScalarsConverterFactory
import java.net.InetAddress import java.net.InetAddress
import java.net.UnknownHostException import java.net.UnknownHostException
val networkingModule = module {
single { createOkHttpClient(get()) }
single { createRetrofit(get()) }
single { createApiService<RawServices>(get(), Const.Url.GITHUB_RAW_URL) }
single { createApiService<GithubApiServices>(get(), Const.Url.GITHUB_API_URL) }
single { createApiService<GithubPageServices>(get(), Const.Url.GITHUB_PAGE_URL) }
single { createApiService<JSDelivrServices>(get(), Const.Url.JS_DELIVR_URL) }
single { createMarkwon(get(), get()) }
}
private class DnsResolver(client: OkHttpClient) : Dns { private class DnsResolver(client: OkHttpClient) : Dns {
private val doh by lazy { private val doh by lazy {

View File

@ -1,11 +0,0 @@
package com.topjohnwu.magisk.di
import com.topjohnwu.magisk.data.repository.LogRepository
import com.topjohnwu.magisk.data.repository.NetworkService
import org.koin.dsl.module
val repositoryModule = module {
single { LogRepository(get()) }
single { NetworkService(get(), get(), get(), get()) }
}

View File

@ -0,0 +1,86 @@
package com.topjohnwu.magisk.di
import android.content.Context
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelStoreOwner
import androidx.room.Room
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.magiskdb.PolicyDao
import com.topjohnwu.magisk.core.magiskdb.SettingsDao
import com.topjohnwu.magisk.core.magiskdb.StringDao
import com.topjohnwu.magisk.core.tasks.RepoUpdater
import com.topjohnwu.magisk.data.database.RepoDatabase
import com.topjohnwu.magisk.data.database.SuLogDatabase
import com.topjohnwu.magisk.data.repository.LogRepository
import com.topjohnwu.magisk.data.repository.NetworkService
import com.topjohnwu.magisk.ktx.deviceProtectedContext
import com.topjohnwu.magisk.ui.home.HomeViewModel
import com.topjohnwu.magisk.ui.install.InstallViewModel
import com.topjohnwu.magisk.ui.log.LogViewModel
import com.topjohnwu.magisk.ui.module.ModuleViewModel
import com.topjohnwu.magisk.ui.settings.SettingsViewModel
import com.topjohnwu.magisk.ui.superuser.SuperuserViewModel
import com.topjohnwu.magisk.ui.surequest.SuRequestViewModel
val AppContext: Context inline get() = ServiceLocator.context
object ServiceLocator {
lateinit var context: Context
val deContext by lazy { context.deviceProtectedContext }
val timeoutPrefs by lazy { deContext.getSharedPreferences("su_timeout", 0) }
// Database
val policyDB = PolicyDao()
val settingsDB = SettingsDao()
val stringDB = StringDao()
val repoDB by lazy { createRepoDatabase(context).repoDao() }
val sulogDB by lazy { createSuLogDatabase(deContext).suLogDao() }
val repoUpdater by lazy { RepoUpdater(networkService, repoDB) }
val logRepo by lazy { LogRepository(sulogDB) }
// Networking
val okhttp by lazy { createOkHttpClient(context) }
val retrofit by lazy { createRetrofit(okhttp) }
val markwon by lazy { createMarkwon(context, okhttp) }
val networkService by lazy {
NetworkService(
createApiService(retrofit, Const.Url.GITHUB_PAGE_URL),
createApiService(retrofit, Const.Url.GITHUB_RAW_URL),
createApiService(retrofit, Const.Url.JS_DELIVR_URL),
createApiService(retrofit, Const.Url.GITHUB_API_URL)
)
}
object VMFactory : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel?> create(clz: Class<T>): T {
return when (clz) {
HomeViewModel::class.java -> HomeViewModel(networkService)
LogViewModel::class.java -> LogViewModel(logRepo)
ModuleViewModel::class.java -> ModuleViewModel(repoDB, repoUpdater)
SettingsViewModel::class.java -> SettingsViewModel(repoDB)
SuperuserViewModel::class.java -> SuperuserViewModel(policyDB)
InstallViewModel::class.java -> InstallViewModel(networkService)
SuRequestViewModel::class.java -> SuRequestViewModel(policyDB, timeoutPrefs)
else -> clz.newInstance()
} as T
}
}
}
inline fun <reified VM : ViewModel> ViewModelStoreOwner.viewModel() =
lazy(LazyThreadSafetyMode.NONE) {
ViewModelProvider(this, ServiceLocator.VMFactory).get(VM::class.java)
}
private fun createRepoDatabase(context: Context) =
Room.databaseBuilder(context, RepoDatabase::class.java, "repo.db")
.fallbackToDestructiveMigration()
.build()
private fun createSuLogDatabase(context: Context) =
Room.databaseBuilder(context, SuLogDatabase::class.java, "sulogs.db")
.fallbackToDestructiveMigration()
.build()

View File

@ -1,32 +0,0 @@
package com.topjohnwu.magisk.di
import com.topjohnwu.magisk.ui.MainViewModel
import com.topjohnwu.magisk.ui.flash.FlashFragmentArgs
import com.topjohnwu.magisk.ui.flash.FlashViewModel
import com.topjohnwu.magisk.ui.hide.HideViewModel
import com.topjohnwu.magisk.ui.home.HomeViewModel
import com.topjohnwu.magisk.ui.install.InstallViewModel
import com.topjohnwu.magisk.ui.log.LogViewModel
import com.topjohnwu.magisk.ui.module.ModuleViewModel
import com.topjohnwu.magisk.ui.safetynet.SafetynetViewModel
import com.topjohnwu.magisk.ui.settings.SettingsViewModel
import com.topjohnwu.magisk.ui.superuser.SuperuserViewModel
import com.topjohnwu.magisk.ui.surequest.SuRequestViewModel
import com.topjohnwu.magisk.ui.theme.ThemeViewModel
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.module
val viewModelModules = module {
viewModel { HideViewModel() }
viewModel { HomeViewModel(get()) }
viewModel { LogViewModel(get()) }
viewModel { ModuleViewModel(get(), get()) }
viewModel { SafetynetViewModel() }
viewModel { SettingsViewModel(get()) }
viewModel { SuperuserViewModel(get()) }
viewModel { ThemeViewModel() }
viewModel { InstallViewModel(get()) }
viewModel { MainViewModel() }
viewModel { (args: FlashFragmentArgs) -> FlashViewModel(args) }
viewModel { SuRequestViewModel(get(), get(SUTimeout)) }
}

View File

@ -1,28 +1,25 @@
package com.topjohnwu.magisk.events.dialog package com.topjohnwu.magisk.events.dialog
import android.content.Context
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Info import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.download.DownloadService import com.topjohnwu.magisk.core.download.DownloadService
import com.topjohnwu.magisk.core.download.Subject import com.topjohnwu.magisk.core.download.Subject
import com.topjohnwu.magisk.data.repository.NetworkService import com.topjohnwu.magisk.di.AppContext
import com.topjohnwu.magisk.ktx.get import com.topjohnwu.magisk.di.ServiceLocator
import com.topjohnwu.magisk.ktx.inject
import com.topjohnwu.magisk.view.MagiskDialog import com.topjohnwu.magisk.view.MagiskDialog
import java.io.File import java.io.File
class ManagerInstallDialog : MarkDownDialog() { class ManagerInstallDialog : MarkDownDialog() {
private val svc: NetworkService by inject() private val svc get() = ServiceLocator.networkService
override suspend fun getMarkdownText(): String { override suspend fun getMarkdownText(): String {
val text = svc.fetchString(Info.remote.magisk.note) val text = svc.fetchString(Info.remote.magisk.note)
// Cache the changelog // Cache the changelog
val context = get<Context>() AppContext.cacheDir.listFiles { _, name -> name.endsWith(".md") }.orEmpty().forEach {
context.cacheDir.listFiles { _, name -> name.endsWith(".md") }.orEmpty().forEach {
it.delete() it.delete()
} }
File(context.cacheDir, "${Info.remote.magisk.versionCode}.md").writeText(text) File(AppContext.cacheDir, "${Info.remote.magisk.versionCode}.md").writeText(text)
return text return text
} }

View File

@ -6,19 +6,15 @@ import androidx.annotation.CallSuper
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.base.BaseActivity import com.topjohnwu.magisk.core.base.BaseActivity
import com.topjohnwu.magisk.ktx.inject import com.topjohnwu.magisk.di.ServiceLocator
import com.topjohnwu.magisk.view.MagiskDialog import com.topjohnwu.magisk.view.MagiskDialog
import io.noties.markwon.Markwon
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.koin.core.component.KoinComponent
import timber.log.Timber import timber.log.Timber
import kotlin.coroutines.cancellation.CancellationException import kotlin.coroutines.cancellation.CancellationException
abstract class MarkDownDialog : DialogEvent(), KoinComponent { abstract class MarkDownDialog : DialogEvent() {
private val markwon: Markwon by inject()
abstract suspend fun getMarkdownText(): String abstract suspend fun getMarkdownText(): String
@ -31,7 +27,7 @@ abstract class MarkDownDialog : DialogEvent(), KoinComponent {
val tv = view.findViewById<TextView>(R.id.md_txt) val tv = view.findViewById<TextView>(R.id.md_txt)
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
try { try {
markwon.setMarkdown(tv, getMarkdownText()) ServiceLocator.markwon.setMarkdown(tv, getMarkdownText())
} catch (e: Exception) { } catch (e: Exception) {
if (e is CancellationException) if (e is CancellationException)
throw e throw e

View File

@ -60,8 +60,6 @@ import java.io.File
import java.lang.reflect.Method import java.lang.reflect.Method
import java.lang.reflect.Array as JArray import java.lang.reflect.Array as JArray
val packageName: String get() = get<Context>().packageName
private lateinit var osSymlink: Method private lateinit var osSymlink: Method
private lateinit var os: Any private lateinit var os: Any

View File

@ -1,17 +0,0 @@
package com.topjohnwu.magisk.ktx
import org.koin.core.context.GlobalContext
import org.koin.core.parameter.ParametersDefinition
import org.koin.core.qualifier.Qualifier
fun getKoin() = GlobalContext.get()
inline fun <reified T> inject(
qualifier: Qualifier? = null,
noinline parameters: ParametersDefinition? = null
) = lazy { get<T>(qualifier, parameters) }
inline fun <reified T> get(
qualifier: Qualifier? = null,
noinline parameters: ParametersDefinition? = null
): T = getKoin().get(qualifier, parameters)

View File

@ -1,7 +1,5 @@
package com.topjohnwu.magisk.ktx package com.topjohnwu.magisk.ktx
import android.content.res.Resources
val specialChars = arrayOf('!', '@', '#', '$', '%', '&', '?') val specialChars = arrayOf('!', '@', '#', '$', '%', '&', '?')
val fullSpecialChars = arrayOf('', '', '', '', '', '', '') val fullSpecialChars = arrayOf('', '', '', '', '', '', '')
@ -34,11 +32,6 @@ fun String.replaceRandomWithSpecial(): String {
fun StringBuilder.appendIf(condition: Boolean, builder: StringBuilder.() -> Unit) = fun StringBuilder.appendIf(condition: Boolean, builder: StringBuilder.() -> Unit) =
if (condition) apply(builder) else this if (condition) apply(builder) else this
fun Int.res(vararg args: Any): String {
val resources: Resources by inject()
return resources.getString(this, *args)
}
fun String.trimEmptyToNull(): String? = if (isBlank()) null else this fun String.trimEmptyToNull(): String? = if (isBlank()) null else this
fun String.legalFilename() = replace(" ", "_").replace("'", "").replace("\"", "") fun String.legalFilename() = replace(" ", "_").replace("'", "").replace("\"", "")

View File

@ -18,13 +18,13 @@ import com.topjohnwu.magisk.arch.BaseViewModel
import com.topjohnwu.magisk.arch.ReselectionTarget import com.topjohnwu.magisk.arch.ReselectionTarget
import com.topjohnwu.magisk.core.* import com.topjohnwu.magisk.core.*
import com.topjohnwu.magisk.databinding.ActivityMainMd2Binding import com.topjohnwu.magisk.databinding.ActivityMainMd2Binding
import com.topjohnwu.magisk.di.viewModel
import com.topjohnwu.magisk.ktx.startAnimations import com.topjohnwu.magisk.ktx.startAnimations
import com.topjohnwu.magisk.ui.home.HomeFragmentDirections import com.topjohnwu.magisk.ui.home.HomeFragmentDirections
import com.topjohnwu.magisk.utils.HideableBehavior import com.topjohnwu.magisk.utils.HideableBehavior
import com.topjohnwu.magisk.utils.Utils import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.magisk.view.MagiskDialog import com.topjohnwu.magisk.view.MagiskDialog
import com.topjohnwu.magisk.view.Shortcuts import com.topjohnwu.magisk.view.Shortcuts
import org.koin.androidx.viewmodel.ext.android.viewModel
import java.io.File import java.io.File
class MainViewModel : BaseViewModel() class MainViewModel : BaseViewModel()

View File

@ -13,19 +13,21 @@ import com.topjohnwu.magisk.arch.BaseUIFragment
import com.topjohnwu.magisk.core.Const import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.cmp import com.topjohnwu.magisk.core.cmp
import com.topjohnwu.magisk.databinding.FragmentFlashMd2Binding import com.topjohnwu.magisk.databinding.FragmentFlashMd2Binding
import com.topjohnwu.magisk.di.viewModel
import com.topjohnwu.magisk.ui.MainActivity import com.topjohnwu.magisk.ui.MainActivity
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.parameter.parametersOf
class FlashFragment : BaseUIFragment<FlashViewModel, FragmentFlashMd2Binding>() { class FlashFragment : BaseUIFragment<FlashViewModel, FragmentFlashMd2Binding>() {
override val layoutRes = R.layout.fragment_flash_md2 override val layoutRes = R.layout.fragment_flash_md2
override val viewModel by viewModel<FlashViewModel> { override val viewModel by viewModel<FlashViewModel>()
parametersOf(FlashFragmentArgs.fromBundle(requireArguments()))
}
private var defaultOrientation = -1 private var defaultOrientation = -1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel.args = FlashFragmentArgs.fromBundle(requireArguments())
}
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
setHasOptionsMenu(true) setHasOptionsMenu(true)

View File

@ -26,7 +26,7 @@ import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class FlashViewModel(var args: FlashFragmentArgs) : BaseViewModel() { class FlashViewModel : BaseViewModel() {
@get:Bindable @get:Bindable
var showReboot = Shell.rootAccess() var showReboot = Shell.rootAccess()
@ -38,6 +38,7 @@ class FlashViewModel(var args: FlashFragmentArgs) : BaseViewModel() {
val adapter = RvBindingAdapter<ConsoleItem>() val adapter = RvBindingAdapter<ConsoleItem>()
val items = diffListOf<ConsoleItem>() val items = diffListOf<ConsoleItem>()
val itemBinding = itemBindingOf<ConsoleItem>() val itemBinding = itemBindingOf<ConsoleItem>()
lateinit var args: FlashFragmentArgs
private val logItems = mutableListOf<String>().synchronized() private val logItems = mutableListOf<String>().synchronized()
private val outItems = object : CallbackList<String>() { private val outItems = object : CallbackList<String>() {

View File

@ -12,12 +12,12 @@ import androidx.recyclerview.widget.RecyclerView
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseUIFragment import com.topjohnwu.magisk.arch.BaseUIFragment
import com.topjohnwu.magisk.databinding.FragmentHideMd2Binding import com.topjohnwu.magisk.databinding.FragmentHideMd2Binding
import com.topjohnwu.magisk.di.viewModel
import com.topjohnwu.magisk.ktx.addSimpleItemDecoration import com.topjohnwu.magisk.ktx.addSimpleItemDecoration
import com.topjohnwu.magisk.ktx.addVerticalPadding import com.topjohnwu.magisk.ktx.addVerticalPadding
import com.topjohnwu.magisk.ktx.fixEdgeEffect import com.topjohnwu.magisk.ktx.fixEdgeEffect
import com.topjohnwu.magisk.ktx.hideKeyboard import com.topjohnwu.magisk.ktx.hideKeyboard
import com.topjohnwu.magisk.utils.MotionRevealHelper import com.topjohnwu.magisk.utils.MotionRevealHelper
import org.koin.androidx.viewmodel.ext.android.viewModel
class HideFragment : BaseUIFragment<HideViewModel, FragmentHideMd2Binding>() { class HideFragment : BaseUIFragment<HideViewModel, FragmentHideMd2Binding>() {

View File

@ -2,7 +2,6 @@ package com.topjohnwu.magisk.ui.hide
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.pm.ApplicationInfo import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES import android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES
import android.os.Process import android.os.Process
import androidx.databinding.Bindable import androidx.databinding.Bindable
@ -13,8 +12,7 @@ import com.topjohnwu.magisk.arch.Queryable
import com.topjohnwu.magisk.arch.filterableListOf import com.topjohnwu.magisk.arch.filterableListOf
import com.topjohnwu.magisk.arch.itemBindingOf import com.topjohnwu.magisk.arch.itemBindingOf
import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.ktx.get import com.topjohnwu.magisk.di.AppContext
import com.topjohnwu.magisk.ktx.packageName
import com.topjohnwu.magisk.utils.Utils import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.magisk.utils.set import com.topjohnwu.magisk.utils.set
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
@ -61,7 +59,7 @@ class HideViewModel : BaseViewModel(), Queryable {
} }
state = State.LOADING state = State.LOADING
val (apps, diff) = withContext(Dispatchers.Default) { val (apps, diff) = withContext(Dispatchers.Default) {
val pm = get<PackageManager>() val pm = AppContext.packageManager
val hideList = Shell.su("magiskhide ls").exec().out.map { CmdlineHiddenItem(it) } val hideList = Shell.su("magiskhide ls").exec().out.map { CmdlineHiddenItem(it) }
val apps = pm.getInstalledApplications(MATCH_UNINSTALLED_PACKAGES) val apps = pm.getInstalledApplications(MATCH_UNINSTALLED_PACKAGES)
.asSequence() .asSequence()
@ -113,7 +111,7 @@ class HideViewModel : BaseViewModel(), Queryable {
companion object { companion object {
private val blacklist by lazy { listOf( private val blacklist by lazy { listOf(
packageName, AppContext.packageName,
"com.android.chrome", "com.android.chrome",
"com.chrome.beta", "com.chrome.beta",
"com.chrome.dev", "com.chrome.dev",

View File

@ -8,9 +8,9 @@ import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseUIFragment import com.topjohnwu.magisk.arch.BaseUIFragment
import com.topjohnwu.magisk.core.download.BaseDownloader import com.topjohnwu.magisk.core.download.BaseDownloader
import com.topjohnwu.magisk.databinding.FragmentHomeMd2Binding import com.topjohnwu.magisk.databinding.FragmentHomeMd2Binding
import com.topjohnwu.magisk.di.viewModel
import com.topjohnwu.magisk.events.RebootEvent import com.topjohnwu.magisk.events.RebootEvent
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import org.koin.androidx.viewmodel.ext.android.viewModel
class HomeFragment : BaseUIFragment<HomeViewModel, FragmentHomeMd2Binding>() { class HomeFragment : BaseUIFragment<HomeViewModel, FragmentHomeMd2Binding>() {

View File

@ -8,8 +8,8 @@ import androidx.lifecycle.viewModelScope
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseUIFragment import com.topjohnwu.magisk.arch.BaseUIFragment
import com.topjohnwu.magisk.databinding.FragmentInstallMd2Binding import com.topjohnwu.magisk.databinding.FragmentInstallMd2Binding
import com.topjohnwu.magisk.di.viewModel
import com.topjohnwu.magisk.ktx.coroutineScope import com.topjohnwu.magisk.ktx.coroutineScope
import org.koin.androidx.viewmodel.ext.android.viewModel
class InstallFragment : BaseUIFragment<InstallViewModel, FragmentInstallMd2Binding>() { class InstallFragment : BaseUIFragment<InstallViewModel, FragmentInstallMd2Binding>() {

View File

@ -1,7 +1,6 @@
package com.topjohnwu.magisk.ui.install package com.topjohnwu.magisk.ui.install
import android.app.Activity import android.app.Activity
import android.content.Context
import android.net.Uri import android.net.Uri
import androidx.databinding.Bindable import androidx.databinding.Bindable
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
@ -12,9 +11,9 @@ import com.topjohnwu.magisk.arch.BaseViewModel
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.data.repository.NetworkService import com.topjohnwu.magisk.data.repository.NetworkService
import com.topjohnwu.magisk.di.AppContext
import com.topjohnwu.magisk.events.MagiskInstallFileEvent import com.topjohnwu.magisk.events.MagiskInstallFileEvent
import com.topjohnwu.magisk.events.dialog.SecondSlotWarningDialog import com.topjohnwu.magisk.events.dialog.SecondSlotWarningDialog
import com.topjohnwu.magisk.ktx.get
import com.topjohnwu.magisk.ui.flash.FlashFragment import com.topjohnwu.magisk.ui.flash.FlashFragment
import com.topjohnwu.magisk.utils.set import com.topjohnwu.magisk.utils.set
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
@ -65,8 +64,7 @@ class InstallViewModel(
init { init {
viewModelScope.launch { viewModelScope.launch {
try { try {
val context = get<Context>() File(AppContext.cacheDir, "${BuildConfig.VERSION_CODE}.md").run {
File(context.cacheDir, "${BuildConfig.VERSION_CODE}.md").run {
notes = when { notes = when {
exists() -> readText() exists() -> readText()
Const.Url.CHANGELOG_URL.isEmpty() -> "" Const.Url.CHANGELOG_URL.isEmpty() -> ""

View File

@ -9,12 +9,12 @@ import androidx.core.view.isVisible
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseUIFragment import com.topjohnwu.magisk.arch.BaseUIFragment
import com.topjohnwu.magisk.databinding.FragmentLogMd2Binding import com.topjohnwu.magisk.databinding.FragmentLogMd2Binding
import com.topjohnwu.magisk.di.viewModel
import com.topjohnwu.magisk.ktx.addSimpleItemDecoration import com.topjohnwu.magisk.ktx.addSimpleItemDecoration
import com.topjohnwu.magisk.ktx.addVerticalPadding import com.topjohnwu.magisk.ktx.addVerticalPadding
import com.topjohnwu.magisk.ktx.fixEdgeEffect import com.topjohnwu.magisk.ktx.fixEdgeEffect
import com.topjohnwu.magisk.ui.MainActivity import com.topjohnwu.magisk.ui.MainActivity
import com.topjohnwu.magisk.utils.MotionRevealHelper import com.topjohnwu.magisk.utils.MotionRevealHelper
import org.koin.androidx.viewmodel.ext.android.viewModel
class LogFragment : BaseUIFragment<LogViewModel, FragmentLogMd2Binding>() { class LogFragment : BaseUIFragment<LogViewModel, FragmentLogMd2Binding>() {

View File

@ -13,11 +13,11 @@ import com.topjohnwu.magisk.arch.ReselectionTarget
import com.topjohnwu.magisk.arch.ViewEvent import com.topjohnwu.magisk.arch.ViewEvent
import com.topjohnwu.magisk.core.download.BaseDownloader import com.topjohnwu.magisk.core.download.BaseDownloader
import com.topjohnwu.magisk.databinding.FragmentModuleMd2Binding import com.topjohnwu.magisk.databinding.FragmentModuleMd2Binding
import com.topjohnwu.magisk.di.viewModel
import com.topjohnwu.magisk.ktx.* import com.topjohnwu.magisk.ktx.*
import com.topjohnwu.magisk.ui.MainActivity import com.topjohnwu.magisk.ui.MainActivity
import com.topjohnwu.magisk.utils.EndlessRecyclerScrollListener import com.topjohnwu.magisk.utils.EndlessRecyclerScrollListener
import com.topjohnwu.magisk.utils.MotionRevealHelper import com.topjohnwu.magisk.utils.MotionRevealHelper
import org.koin.androidx.viewmodel.ext.android.viewModel
class ModuleFragment : BaseUIFragment<ModuleViewModel, FragmentModuleMd2Binding>(), class ModuleFragment : BaseUIFragment<ModuleViewModel, FragmentModuleMd2Binding>(),
ReselectionTarget { ReselectionTarget {

View File

@ -11,10 +11,9 @@ import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.ContextExecutor import com.topjohnwu.magisk.arch.ContextExecutor
import com.topjohnwu.magisk.arch.ViewEventWithScope import com.topjohnwu.magisk.arch.ViewEventWithScope
import com.topjohnwu.magisk.core.Const import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.data.repository.NetworkService import com.topjohnwu.magisk.di.ServiceLocator
import com.topjohnwu.magisk.ktx.createClassLoader import com.topjohnwu.magisk.ktx.createClassLoader
import com.topjohnwu.magisk.ktx.reflectField import com.topjohnwu.magisk.ktx.reflectField
import com.topjohnwu.magisk.ktx.inject
import com.topjohnwu.magisk.ktx.writeTo import com.topjohnwu.magisk.ktx.writeTo
import com.topjohnwu.magisk.view.MagiskDialog import com.topjohnwu.magisk.view.MagiskDialog
import com.topjohnwu.signing.CryptoUtils import com.topjohnwu.signing.CryptoUtils
@ -27,7 +26,6 @@ import kotlinx.coroutines.withContext
import org.bouncycastle.asn1.ASN1Encoding import org.bouncycastle.asn1.ASN1Encoding
import org.bouncycastle.asn1.ASN1Primitive import org.bouncycastle.asn1.ASN1Primitive
import org.bouncycastle.est.jcajce.JsseDefaultHostnameAuthorizer import org.bouncycastle.est.jcajce.JsseDefaultHostnameAuthorizer
import org.koin.core.component.KoinComponent
import timber.log.Timber import timber.log.Timber
import java.io.ByteArrayInputStream import java.io.ByteArrayInputStream
import java.io.File import java.io.File
@ -40,9 +38,9 @@ import java.security.cert.X509Certificate
class CheckSafetyNetEvent( class CheckSafetyNetEvent(
private val callback: (SafetyNetResult) -> Unit = {} private val callback: (SafetyNetResult) -> Unit = {}
) : ViewEventWithScope(), ContextExecutor, KoinComponent, SafetyNetHelper.Callback { ) : ViewEventWithScope(), ContextExecutor, SafetyNetHelper.Callback {
private val svc by inject<NetworkService>() private val svc get() = ServiceLocator.networkService
private lateinit var apk: File private lateinit var apk: File
private lateinit var dex: File private lateinit var dex: File

View File

@ -7,7 +7,7 @@ import android.view.ViewGroup
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseUIFragment import com.topjohnwu.magisk.arch.BaseUIFragment
import com.topjohnwu.magisk.databinding.FragmentSafetynetMd2Binding import com.topjohnwu.magisk.databinding.FragmentSafetynetMd2Binding
import org.koin.androidx.viewmodel.ext.android.viewModel import com.topjohnwu.magisk.di.viewModel
class SafetynetFragment : BaseUIFragment<SafetynetViewModel, FragmentSafetynetMd2Binding>() { class SafetynetFragment : BaseUIFragment<SafetynetViewModel, FragmentSafetynetMd2Binding>() {

View File

@ -5,11 +5,11 @@ import android.view.View
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseUIFragment import com.topjohnwu.magisk.arch.BaseUIFragment
import com.topjohnwu.magisk.databinding.FragmentSettingsMd2Binding import com.topjohnwu.magisk.databinding.FragmentSettingsMd2Binding
import com.topjohnwu.magisk.di.viewModel
import com.topjohnwu.magisk.ktx.addSimpleItemDecoration import com.topjohnwu.magisk.ktx.addSimpleItemDecoration
import com.topjohnwu.magisk.ktx.addVerticalPadding import com.topjohnwu.magisk.ktx.addVerticalPadding
import com.topjohnwu.magisk.ktx.fixEdgeEffect import com.topjohnwu.magisk.ktx.fixEdgeEffect
import com.topjohnwu.magisk.ktx.setOnViewReadyListener import com.topjohnwu.magisk.ktx.setOnViewReadyListener
import org.koin.androidx.viewmodel.ext.android.viewModel
class SettingsFragment : BaseUIFragment<SettingsViewModel, FragmentSettingsMd2Binding>() { class SettingsFragment : BaseUIFragment<SettingsViewModel, FragmentSettingsMd2Binding>() {

View File

@ -21,7 +21,7 @@ import com.topjohnwu.magisk.core.utils.currentLocale
import com.topjohnwu.magisk.databinding.DialogSettingsAppNameBinding import com.topjohnwu.magisk.databinding.DialogSettingsAppNameBinding
import com.topjohnwu.magisk.databinding.DialogSettingsDownloadPathBinding import com.topjohnwu.magisk.databinding.DialogSettingsDownloadPathBinding
import com.topjohnwu.magisk.databinding.DialogSettingsUpdateChannelBinding import com.topjohnwu.magisk.databinding.DialogSettingsUpdateChannelBinding
import com.topjohnwu.magisk.ktx.get import com.topjohnwu.magisk.di.AppContext
import com.topjohnwu.magisk.utils.Utils import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.magisk.utils.asText import com.topjohnwu.magisk.utils.asText
import com.topjohnwu.magisk.utils.set import com.topjohnwu.magisk.utils.set
@ -194,7 +194,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(get()) UpdateCheckService.schedule(AppContext)
} }
} }

View File

@ -1,6 +1,5 @@
package com.topjohnwu.magisk.ui.settings package com.topjohnwu.magisk.ui.settings
import android.content.Context
import android.os.Build import android.os.Build
import android.view.View import android.view.View
import android.widget.Toast import android.widget.Toast
@ -18,11 +17,11 @@ import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.isRunningAsStub import com.topjohnwu.magisk.core.isRunningAsStub
import com.topjohnwu.magisk.core.tasks.HideAPK import com.topjohnwu.magisk.core.tasks.HideAPK
import com.topjohnwu.magisk.data.database.RepoDao import com.topjohnwu.magisk.data.database.RepoDao
import com.topjohnwu.magisk.di.AppContext
import com.topjohnwu.magisk.events.AddHomeIconEvent import com.topjohnwu.magisk.events.AddHomeIconEvent
import com.topjohnwu.magisk.events.RecreateEvent import com.topjohnwu.magisk.events.RecreateEvent
import com.topjohnwu.magisk.events.dialog.BiometricEvent import com.topjohnwu.magisk.events.dialog.BiometricEvent
import com.topjohnwu.magisk.ktx.activity import com.topjohnwu.magisk.ktx.activity
import com.topjohnwu.magisk.ktx.get
import com.topjohnwu.magisk.utils.Utils import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -42,7 +41,7 @@ class SettingsViewModel(
} }
private fun createItems(): List<BaseSettingsItem> { private fun createItems(): List<BaseSettingsItem> {
val context = get<Context>() val context = AppContext
val hidden = context.packageName != BuildConfig.APPLICATION_ID val hidden = context.packageName != BuildConfig.APPLICATION_ID
// Customization // Customization

View File

@ -5,10 +5,10 @@ import android.view.View
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseUIFragment import com.topjohnwu.magisk.arch.BaseUIFragment
import com.topjohnwu.magisk.databinding.FragmentSuperuserMd2Binding import com.topjohnwu.magisk.databinding.FragmentSuperuserMd2Binding
import com.topjohnwu.magisk.di.viewModel
import com.topjohnwu.magisk.ktx.addSimpleItemDecoration import com.topjohnwu.magisk.ktx.addSimpleItemDecoration
import com.topjohnwu.magisk.ktx.addVerticalPadding import com.topjohnwu.magisk.ktx.addVerticalPadding
import com.topjohnwu.magisk.ktx.fixEdgeEffect import com.topjohnwu.magisk.ktx.fixEdgeEffect
import org.koin.androidx.viewmodel.ext.android.viewModel
class SuperuserFragment : BaseUIFragment<SuperuserViewModel, FragmentSuperuserMd2Binding>() { class SuperuserFragment : BaseUIFragment<SuperuserViewModel, FragmentSuperuserMd2Binding>() {

View File

@ -12,7 +12,7 @@ import com.topjohnwu.magisk.arch.BaseUIActivity
import com.topjohnwu.magisk.core.su.SuCallbackHandler import com.topjohnwu.magisk.core.su.SuCallbackHandler
import com.topjohnwu.magisk.core.su.SuCallbackHandler.REQUEST import com.topjohnwu.magisk.core.su.SuCallbackHandler.REQUEST
import com.topjohnwu.magisk.databinding.ActivityRequestBinding import com.topjohnwu.magisk.databinding.ActivityRequestBinding
import org.koin.androidx.viewmodel.ext.android.viewModel import com.topjohnwu.magisk.di.viewModel
open class SuRequestActivity : BaseUIActivity<SuRequestViewModel, ActivityRequestBinding>() { open class SuRequestActivity : BaseUIActivity<SuRequestViewModel, ActivityRequestBinding>() {

View File

@ -1,7 +1,6 @@
package com.topjohnwu.magisk.ui.surequest package com.topjohnwu.magisk.ui.surequest
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.content.res.Resources import android.content.res.Resources
@ -27,10 +26,10 @@ import com.topjohnwu.magisk.core.model.su.SuPolicy.Companion.ALLOW
import com.topjohnwu.magisk.core.model.su.SuPolicy.Companion.DENY import com.topjohnwu.magisk.core.model.su.SuPolicy.Companion.DENY
import com.topjohnwu.magisk.core.su.SuRequestHandler import com.topjohnwu.magisk.core.su.SuRequestHandler
import com.topjohnwu.magisk.core.utils.BiometricHelper import com.topjohnwu.magisk.core.utils.BiometricHelper
import com.topjohnwu.magisk.di.AppContext
import com.topjohnwu.magisk.events.DieEvent import com.topjohnwu.magisk.events.DieEvent
import com.topjohnwu.magisk.events.ShowUIEvent import com.topjohnwu.magisk.events.ShowUIEvent
import com.topjohnwu.magisk.events.dialog.BiometricEvent import com.topjohnwu.magisk.events.dialog.BiometricEvent
import com.topjohnwu.magisk.ktx.get
import com.topjohnwu.magisk.utils.TextHolder import com.topjohnwu.magisk.utils.TextHolder
import com.topjohnwu.magisk.utils.Utils import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.magisk.utils.set import com.topjohnwu.magisk.utils.set
@ -73,7 +72,7 @@ class SuRequestViewModel(
val itemBinding = ItemBinding.of<String>(BR.item, R.layout.item_spinner) val itemBinding = ItemBinding.of<String>(BR.item, R.layout.item_spinner)
private val handler = SuRequestHandler(get<Context>().packageManager, policyDB) private val handler = SuRequestHandler(AppContext.packageManager, policyDB)
private lateinit var timer: CountDownTimer private lateinit var timer: CountDownTimer
fun grantPressed() { fun grantPressed() {
@ -160,8 +159,6 @@ class SuRequestViewModel(
var seconds = 0 var seconds = 0
set(value) = set(value, field, { field = it }, BR.denyText) set(value) = set(value, field, { field = it }, BR.denyText)
override val isEmpty get() = false
override fun getText(resources: Resources): CharSequence { override fun getText(resources: Resources): CharSequence {
return if (seconds != 0) return if (seconds != 0)
"${resources.getString(R.string.deny)} ($seconds)" "${resources.getString(R.string.deny)} ($seconds)"

View File

@ -11,7 +11,7 @@ import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseUIFragment import com.topjohnwu.magisk.arch.BaseUIFragment
import com.topjohnwu.magisk.databinding.FragmentThemeMd2Binding import com.topjohnwu.magisk.databinding.FragmentThemeMd2Binding
import com.topjohnwu.magisk.databinding.ItemThemeBindingImpl import com.topjohnwu.magisk.databinding.ItemThemeBindingImpl
import org.koin.androidx.viewmodel.ext.android.viewModel import com.topjohnwu.magisk.di.viewModel
class ThemeFragment : BaseUIFragment<ThemeViewModel, FragmentThemeMd2Binding>() { class ThemeFragment : BaseUIFragment<ThemeViewModel, FragmentThemeMd2Binding>() {

View File

@ -6,7 +6,7 @@ import androidx.databinding.BindingAdapter
abstract class TextHolder { abstract class TextHolder {
abstract val isEmpty: Boolean open val isEmpty: Boolean get() = false
abstract fun getText(resources: Resources): CharSequence abstract fun getText(resources: Resources): CharSequence
// --- // ---

View File

@ -8,17 +8,17 @@ 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.ktx.get import com.topjohnwu.magisk.di.AppContext
import com.topjohnwu.superuser.internal.UiThreadHandler import com.topjohnwu.superuser.internal.UiThreadHandler
object Utils { object Utils {
fun toast(msg: CharSequence, duration: Int) { fun toast(msg: CharSequence, duration: Int) {
UiThreadHandler.run { Toast.makeText(get(), msg, duration).show() } UiThreadHandler.run { Toast.makeText(AppContext, msg, duration).show() }
} }
fun toast(resId: Int, duration: Int) { fun toast(resId: Int, duration: Int) {
UiThreadHandler.run { Toast.makeText(get(), resId, duration).show() } UiThreadHandler.run { Toast.makeText(AppContext, resId, duration).show() }
} }
fun showSuperUser(): Boolean { fun showSuperUser(): Boolean {

View File

@ -13,13 +13,13 @@ import com.topjohnwu.magisk.core.Const.ID.PROGRESS_NOTIFICATION_CHANNEL
import com.topjohnwu.magisk.core.Const.ID.UPDATE_NOTIFICATION_CHANNEL import com.topjohnwu.magisk.core.Const.ID.UPDATE_NOTIFICATION_CHANNEL
import com.topjohnwu.magisk.core.download.DownloadService import com.topjohnwu.magisk.core.download.DownloadService
import com.topjohnwu.magisk.core.download.Subject import com.topjohnwu.magisk.core.download.Subject
import com.topjohnwu.magisk.ktx.get import com.topjohnwu.magisk.di.AppContext
import com.topjohnwu.magisk.ktx.getBitmap import com.topjohnwu.magisk.ktx.getBitmap
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
object Notifications { object Notifications {
val mgr by lazy { get<Context>().getSystemService<NotificationManager>()!! } val mgr by lazy { AppContext.getSystemService<NotificationManager>()!! }
fun setup(context: Context) { fun setup(context: Context) {
if (SDK_INT >= 26) { if (SDK_INT >= 26) {