mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-18 05:58:30 +00:00
More refactoring
Cleanups, move classes to sane locations, etc.
This commit is contained in:
parent
846bbb4da1
commit
34450cdddd
6
app/proguard-rules.pro
vendored
6
app/proguard-rules.pro
vendored
@ -29,9 +29,9 @@
|
|||||||
-keep class a.* { *; }
|
-keep class a.* { *; }
|
||||||
|
|
||||||
# Snet
|
# Snet
|
||||||
-keepclassmembers class com.topjohnwu.magisk.core.utils.SafetyNetHelper { *; }
|
-keepclassmembers class com.topjohnwu.magisk.ui.safetynet.SafetyNetHelper { *; }
|
||||||
-keep,allowobfuscation interface com.topjohnwu.magisk.core.utils.SafetyNetHelper$Callback
|
-keep,allowobfuscation interface com.topjohnwu.magisk.ui.safetynet.SafetyNetHelper$Callback
|
||||||
-keepclassmembers class * implements com.topjohnwu.magisk.core.utils.SafetyNetHelper$Callback {
|
-keepclassmembers class * implements com.topjohnwu.magisk.ui.safetynet.SafetyNetHelper$Callback {
|
||||||
void onResponse(int);
|
void onResponse(int);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,10 +15,10 @@ import com.topjohnwu.magisk.BR
|
|||||||
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.base.BaseActivity
|
import com.topjohnwu.magisk.core.base.BaseActivity
|
||||||
import com.topjohnwu.magisk.model.events.BackPressEvent
|
import com.topjohnwu.magisk.events.BackPressEvent
|
||||||
import com.topjohnwu.magisk.model.events.PermissionEvent
|
import com.topjohnwu.magisk.events.PermissionEvent
|
||||||
import com.topjohnwu.magisk.model.events.SnackbarEvent
|
import com.topjohnwu.magisk.events.SnackbarEvent
|
||||||
import com.topjohnwu.magisk.model.events.ViewActionEvent
|
import com.topjohnwu.magisk.events.ViewActionEvent
|
||||||
import com.topjohnwu.magisk.model.navigation.NavigationWrapper
|
import com.topjohnwu.magisk.model.navigation.NavigationWrapper
|
||||||
import com.topjohnwu.magisk.utils.ObservableHost
|
import com.topjohnwu.magisk.utils.ObservableHost
|
||||||
import com.topjohnwu.magisk.utils.set
|
import com.topjohnwu.magisk.utils.set
|
||||||
|
@ -8,8 +8,8 @@ import com.topjohnwu.magisk.core.magiskdb.PolicyDao
|
|||||||
import com.topjohnwu.magisk.core.model.ManagerJson
|
import com.topjohnwu.magisk.core.model.ManagerJson
|
||||||
import com.topjohnwu.magisk.core.su.SuCallbackHandler
|
import com.topjohnwu.magisk.core.su.SuCallbackHandler
|
||||||
import com.topjohnwu.magisk.ktx.reboot
|
import com.topjohnwu.magisk.ktx.reboot
|
||||||
import com.topjohnwu.magisk.model.entity.internal.Configuration
|
import com.topjohnwu.magisk.model.internal.Configuration
|
||||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
import com.topjohnwu.magisk.model.internal.DownloadSubject
|
||||||
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,10 +13,10 @@ import com.topjohnwu.magisk.core.tasks.EnvFixTask
|
|||||||
import com.topjohnwu.magisk.ktx.chooser
|
import com.topjohnwu.magisk.ktx.chooser
|
||||||
import com.topjohnwu.magisk.ktx.exists
|
import com.topjohnwu.magisk.ktx.exists
|
||||||
import com.topjohnwu.magisk.ktx.provide
|
import com.topjohnwu.magisk.ktx.provide
|
||||||
import com.topjohnwu.magisk.model.entity.internal.Configuration.*
|
import com.topjohnwu.magisk.model.internal.Configuration.*
|
||||||
import com.topjohnwu.magisk.model.entity.internal.Configuration.Flash.Secondary
|
import com.topjohnwu.magisk.model.internal.Configuration.Flash.Secondary
|
||||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
import com.topjohnwu.magisk.model.internal.DownloadSubject
|
||||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.*
|
import com.topjohnwu.magisk.model.internal.DownloadSubject.*
|
||||||
import com.topjohnwu.magisk.ui.flash.FlashFragment
|
import com.topjohnwu.magisk.ui.flash.FlashFragment
|
||||||
import com.topjohnwu.magisk.utils.APKInstall
|
import com.topjohnwu.magisk.utils.APKInstall
|
||||||
import org.koin.core.get
|
import org.koin.core.get
|
||||||
|
@ -10,9 +10,9 @@ import com.topjohnwu.magisk.core.intent
|
|||||||
import com.topjohnwu.magisk.core.isRunningAsStub
|
import com.topjohnwu.magisk.core.isRunningAsStub
|
||||||
import com.topjohnwu.magisk.core.utils.PatchAPK
|
import com.topjohnwu.magisk.core.utils.PatchAPK
|
||||||
import com.topjohnwu.magisk.ktx.writeTo
|
import com.topjohnwu.magisk.ktx.writeTo
|
||||||
import com.topjohnwu.magisk.model.entity.internal.Configuration.APK.Restore
|
import com.topjohnwu.magisk.model.internal.Configuration.APK.Restore
|
||||||
import com.topjohnwu.magisk.model.entity.internal.Configuration.APK.Upgrade
|
import com.topjohnwu.magisk.model.internal.Configuration.APK.Upgrade
|
||||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
import com.topjohnwu.magisk.model.internal.DownloadSubject
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
@ -10,9 +10,9 @@ import com.topjohnwu.magisk.core.utils.ProgressInputStream
|
|||||||
import com.topjohnwu.magisk.data.network.GithubRawServices
|
import com.topjohnwu.magisk.data.network.GithubRawServices
|
||||||
import com.topjohnwu.magisk.ktx.checkSum
|
import com.topjohnwu.magisk.ktx.checkSum
|
||||||
import com.topjohnwu.magisk.ktx.writeTo
|
import com.topjohnwu.magisk.ktx.writeTo
|
||||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
import com.topjohnwu.magisk.model.internal.DownloadSubject
|
||||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.Magisk
|
import com.topjohnwu.magisk.model.internal.DownloadSubject.Magisk
|
||||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.Module
|
import com.topjohnwu.magisk.model.internal.DownloadSubject.Module
|
||||||
import com.topjohnwu.magisk.view.Notifications
|
import com.topjohnwu.magisk.view.Notifications
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import okhttp3.ResponseBody
|
import okhttp3.ResponseBody
|
||||||
|
@ -3,9 +3,9 @@ package com.topjohnwu.magisk.core.magiskdb
|
|||||||
import android.content.Context
|
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.MagiskPolicy
|
import com.topjohnwu.magisk.core.model.su.SuPolicy
|
||||||
import com.topjohnwu.magisk.core.model.toMap
|
import com.topjohnwu.magisk.core.model.su.toMap
|
||||||
import com.topjohnwu.magisk.core.model.toPolicy
|
import com.topjohnwu.magisk.core.model.su.toPolicy
|
||||||
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
|
||||||
@ -49,11 +49,11 @@ class PolicyDao(
|
|||||||
}
|
}
|
||||||
}.query().first().toPolicyOrNull()
|
}.query().first().toPolicyOrNull()
|
||||||
|
|
||||||
suspend fun update(policy: MagiskPolicy) = buildQuery<Replace> {
|
suspend fun update(policy: SuPolicy) = buildQuery<Replace> {
|
||||||
values(policy.toMap())
|
values(policy.toMap())
|
||||||
}.commit()
|
}.commit()
|
||||||
|
|
||||||
suspend fun <R: Any> fetchAll(mapper: (MagiskPolicy) -> R) = buildQuery<Select> {
|
suspend fun <R: Any> fetchAll(mapper: (SuPolicy) -> R) = buildQuery<Select> {
|
||||||
condition {
|
condition {
|
||||||
equals("uid/100000", Const.USER_ID)
|
equals("uid/100000", Const.USER_ID)
|
||||||
}
|
}
|
||||||
@ -61,7 +61,7 @@ class PolicyDao(
|
|||||||
it.toPolicyOrNull()?.let(mapper)
|
it.toPolicyOrNull()?.let(mapper)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Map<String, String>.toPolicyOrNull(): MagiskPolicy? {
|
private fun Map<String, String>.toPolicyOrNull(): SuPolicy? {
|
||||||
return runCatching { toPolicy(context.packageManager) }.getOrElse {
|
return runCatching { toPolicy(context.packageManager) }.getOrElse {
|
||||||
Timber.e(it)
|
Timber.e(it)
|
||||||
if (it is PackageManager.NameNotFoundException) {
|
if (it is PackageManager.NameNotFoundException) {
|
||||||
|
@ -59,6 +59,6 @@ data class Repo(
|
|||||||
class IllegalRepoException(message: String) : Exception(message)
|
class IllegalRepoException(message: String) : Exception(message)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val dateFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM)!!
|
val dateFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
package com.topjohnwu.magisk.model.entity
|
package com.topjohnwu.magisk.core.model.su
|
||||||
|
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.Ignore
|
import androidx.room.Ignore
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
import com.topjohnwu.magisk.core.model.MagiskPolicy
|
import com.topjohnwu.magisk.core.model.su.SuPolicy.Companion.ALLOW
|
||||||
import com.topjohnwu.magisk.core.model.MagiskPolicy.Companion.ALLOW
|
|
||||||
import com.topjohnwu.magisk.ktx.now
|
import com.topjohnwu.magisk.ktx.now
|
||||||
import com.topjohnwu.magisk.ktx.timeFormatTime
|
import com.topjohnwu.magisk.ktx.timeFormatTime
|
||||||
import com.topjohnwu.magisk.ktx.toTime
|
import com.topjohnwu.magisk.ktx.toTime
|
||||||
|
|
||||||
@Entity(tableName = "logs")
|
@Entity(tableName = "logs")
|
||||||
data class MagiskLog(
|
data class SuLog(
|
||||||
val fromUid: Int,
|
val fromUid: Int,
|
||||||
val toUid: Int,
|
val toUid: Int,
|
||||||
val fromPid: Int,
|
val fromPid: Int,
|
||||||
@ -24,8 +23,8 @@ data class MagiskLog(
|
|||||||
@Ignore val timeString = time.toTime(timeFormatTime)
|
@Ignore val timeString = time.toTime(timeFormatTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun MagiskPolicy.toLog(
|
fun SuPolicy.toLog(
|
||||||
toUid: Int,
|
toUid: Int,
|
||||||
fromPid: Int,
|
fromPid: Int,
|
||||||
command: String
|
command: String
|
||||||
) = MagiskLog(uid, toUid, fromPid, packageName, appName, command, policy == ALLOW, now)
|
) = SuLog(uid, toUid, fromPid, packageName, appName, command, policy == ALLOW, now)
|
@ -1,12 +1,12 @@
|
|||||||
package com.topjohnwu.magisk.core.model
|
package com.topjohnwu.magisk.core.model.su
|
||||||
|
|
||||||
import android.content.pm.ApplicationInfo
|
import android.content.pm.ApplicationInfo
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import com.topjohnwu.magisk.core.model.MagiskPolicy.Companion.INTERACTIVE
|
import com.topjohnwu.magisk.core.model.su.SuPolicy.Companion.INTERACTIVE
|
||||||
import com.topjohnwu.magisk.ktx.getLabel
|
import com.topjohnwu.magisk.ktx.getLabel
|
||||||
|
|
||||||
|
|
||||||
data class MagiskPolicy(
|
data class SuPolicy(
|
||||||
var uid: Int,
|
var uid: Int,
|
||||||
val packageName: String,
|
val packageName: String,
|
||||||
val appName: String,
|
val appName: String,
|
||||||
@ -25,7 +25,7 @@ data class MagiskPolicy(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun MagiskPolicy.toMap() = mapOf(
|
fun SuPolicy.toMap() = mapOf(
|
||||||
"uid" to uid,
|
"uid" to uid,
|
||||||
"package_name" to packageName,
|
"package_name" to packageName,
|
||||||
"policy" to policy,
|
"policy" to policy,
|
||||||
@ -35,7 +35,7 @@ fun MagiskPolicy.toMap() = mapOf(
|
|||||||
)
|
)
|
||||||
|
|
||||||
@Throws(PackageManager.NameNotFoundException::class)
|
@Throws(PackageManager.NameNotFoundException::class)
|
||||||
fun Map<String, String>.toPolicy(pm: PackageManager): MagiskPolicy {
|
fun Map<String, String>.toPolicy(pm: PackageManager): SuPolicy {
|
||||||
val uid = get("uid")?.toIntOrNull() ?: -1
|
val uid = get("uid")?.toIntOrNull() ?: -1
|
||||||
val packageName = get("package_name").orEmpty()
|
val packageName = get("package_name").orEmpty()
|
||||||
val info = pm.getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES)
|
val info = pm.getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES)
|
||||||
@ -43,7 +43,7 @@ fun Map<String, String>.toPolicy(pm: PackageManager): MagiskPolicy {
|
|||||||
if (info.uid != uid)
|
if (info.uid != uid)
|
||||||
throw PackageManager.NameNotFoundException()
|
throw PackageManager.NameNotFoundException()
|
||||||
|
|
||||||
return MagiskPolicy(
|
return SuPolicy(
|
||||||
uid = uid,
|
uid = uid,
|
||||||
packageName = packageName,
|
packageName = packageName,
|
||||||
policy = get("policy")?.toIntOrNull() ?: INTERACTIVE,
|
policy = get("policy")?.toIntOrNull() ?: INTERACTIVE,
|
||||||
@ -56,11 +56,11 @@ fun Map<String, String>.toPolicy(pm: PackageManager): MagiskPolicy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Throws(PackageManager.NameNotFoundException::class)
|
@Throws(PackageManager.NameNotFoundException::class)
|
||||||
fun Int.toPolicy(pm: PackageManager, policy: Int = INTERACTIVE): MagiskPolicy {
|
fun Int.toPolicy(pm: PackageManager, policy: Int = INTERACTIVE): SuPolicy {
|
||||||
val pkg = pm.getPackagesForUid(this)?.firstOrNull()
|
val pkg = pm.getPackagesForUid(this)?.firstOrNull()
|
||||||
?: throw PackageManager.NameNotFoundException()
|
?: throw PackageManager.NameNotFoundException()
|
||||||
val info = pm.getApplicationInfo(pkg, PackageManager.GET_UNINSTALLED_PACKAGES)
|
val info = pm.getApplicationInfo(pkg, PackageManager.GET_UNINSTALLED_PACKAGES)
|
||||||
return MagiskPolicy(
|
return SuPolicy(
|
||||||
uid = info.uid,
|
uid = info.uid,
|
||||||
packageName = pkg,
|
packageName = pkg,
|
||||||
policy = policy,
|
policy = policy,
|
@ -11,14 +11,14 @@ import com.topjohnwu.magisk.ProviderCallHandler
|
|||||||
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.core.intent
|
import com.topjohnwu.magisk.core.intent
|
||||||
import com.topjohnwu.magisk.core.model.MagiskPolicy
|
import com.topjohnwu.magisk.core.model.su.SuPolicy
|
||||||
import com.topjohnwu.magisk.core.model.toPolicy
|
import com.topjohnwu.magisk.core.model.su.toLog
|
||||||
|
import com.topjohnwu.magisk.core.model.su.toPolicy
|
||||||
import com.topjohnwu.magisk.core.wrap
|
import com.topjohnwu.magisk.core.wrap
|
||||||
import com.topjohnwu.magisk.data.repository.LogRepository
|
import com.topjohnwu.magisk.data.repository.LogRepository
|
||||||
import com.topjohnwu.magisk.ktx.get
|
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.model.entity.toLog
|
|
||||||
import com.topjohnwu.magisk.ui.surequest.SuRequestActivity
|
import com.topjohnwu.magisk.ui.surequest.SuRequestActivity
|
||||||
import com.topjohnwu.magisk.utils.Utils
|
import com.topjohnwu.magisk.utils.Utils
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
@ -132,9 +132,9 @@ object SuCallbackHandler : ProviderCallHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun notify(context: Context, policy: MagiskPolicy) {
|
private fun notify(context: Context, policy: SuPolicy) {
|
||||||
if (policy.notification && Config.suNotification == Config.Value.NOTIFICATION_TOAST) {
|
if (policy.notification && Config.suNotification == Config.Value.NOTIFICATION_TOAST) {
|
||||||
val resId = if (policy.policy == MagiskPolicy.ALLOW)
|
val resId = if (policy.policy == SuPolicy.ALLOW)
|
||||||
R.string.su_allow_toast
|
R.string.su_allow_toast
|
||||||
else
|
else
|
||||||
R.string.su_deny_toast
|
R.string.su_deny_toast
|
||||||
|
@ -10,8 +10,8 @@ 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.Const
|
||||||
import com.topjohnwu.magisk.core.magiskdb.PolicyDao
|
import com.topjohnwu.magisk.core.magiskdb.PolicyDao
|
||||||
import com.topjohnwu.magisk.core.model.MagiskPolicy
|
import com.topjohnwu.magisk.core.model.su.SuPolicy
|
||||||
import com.topjohnwu.magisk.core.model.toPolicy
|
import com.topjohnwu.magisk.core.model.su.toPolicy
|
||||||
import com.topjohnwu.magisk.ktx.now
|
import com.topjohnwu.magisk.ktx.now
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
@ -27,7 +27,7 @@ abstract class SuRequestHandler(
|
|||||||
private lateinit var output: DataOutputStream
|
private lateinit var output: DataOutputStream
|
||||||
private lateinit var input: DataInputStream
|
private lateinit var input: DataInputStream
|
||||||
|
|
||||||
protected lateinit var policy: MagiskPolicy
|
protected lateinit var policy: SuPolicy
|
||||||
private set
|
private set
|
||||||
|
|
||||||
abstract fun onStart()
|
abstract fun onStart()
|
||||||
@ -44,11 +44,11 @@ abstract class SuRequestHandler(
|
|||||||
|
|
||||||
when (Config.suAutoReponse) {
|
when (Config.suAutoReponse) {
|
||||||
Config.Value.SU_AUTO_DENY -> {
|
Config.Value.SU_AUTO_DENY -> {
|
||||||
respond(MagiskPolicy.DENY, 0)
|
respond(SuPolicy.DENY, 0)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
Config.Value.SU_AUTO_ALLOW -> {
|
Config.Value.SU_AUTO_ALLOW -> {
|
||||||
respond(MagiskPolicy.ALLOW, 0)
|
respond(SuPolicy.ALLOW, 0)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,10 @@ import com.topjohnwu.magisk.core.Config
|
|||||||
import com.topjohnwu.magisk.core.Info
|
import com.topjohnwu.magisk.core.Info
|
||||||
import com.topjohnwu.magisk.data.network.GithubRawServices
|
import com.topjohnwu.magisk.data.network.GithubRawServices
|
||||||
import com.topjohnwu.magisk.di.Protected
|
import com.topjohnwu.magisk.di.Protected
|
||||||
|
import com.topjohnwu.magisk.events.dialog.EnvFixDialog
|
||||||
import com.topjohnwu.magisk.ktx.readUri
|
import com.topjohnwu.magisk.ktx.readUri
|
||||||
import com.topjohnwu.magisk.ktx.reboot
|
import com.topjohnwu.magisk.ktx.reboot
|
||||||
import com.topjohnwu.magisk.ktx.withStreams
|
import com.topjohnwu.magisk.ktx.withStreams
|
||||||
import com.topjohnwu.magisk.model.events.dialog.EnvFixDialog
|
|
||||||
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
|
||||||
@ -100,6 +100,7 @@ abstract class MagiskInstallImpl : KoinComponent {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
private fun extractZip(): Boolean {
|
private fun extractZip(): Boolean {
|
||||||
val arch: String
|
val arch: String
|
||||||
arch = if (Build.VERSION.SDK_INT >= 21) {
|
arch = if (Build.VERSION.SDK_INT >= 21) {
|
||||||
@ -130,14 +131,14 @@ abstract class MagiskInstallImpl : KoinComponent {
|
|||||||
}
|
}
|
||||||
if (name == null && ze.name.startsWith("chromeos/"))
|
if (name == null && ze.name.startsWith("chromeos/"))
|
||||||
name = ze.name
|
name = ze.name
|
||||||
if (name == null)
|
name?.also {
|
||||||
continue
|
val dest = if (installDir is SuFile)
|
||||||
val dest = if (installDir is SuFile)
|
SuFile(installDir, it)
|
||||||
SuFile(installDir, name)
|
else
|
||||||
else
|
File(installDir, it)
|
||||||
File(installDir, name)
|
dest.parentFile!!.mkdirs()
|
||||||
dest.parentFile!!.mkdirs()
|
SuFileOutputStream(dest).use { s -> zi.copyTo(s) }
|
||||||
SuFileOutputStream(dest).use { zi.copyTo(it) }
|
} ?: continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
package com.topjohnwu.magisk.data.database
|
package com.topjohnwu.magisk.data.database
|
||||||
|
|
||||||
import androidx.room.*
|
import androidx.room.*
|
||||||
import com.topjohnwu.magisk.model.entity.MagiskLog
|
import com.topjohnwu.magisk.core.model.su.SuLog
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@Database(version = 1, entities = [MagiskLog::class], exportSchema = false)
|
@Database(version = 1, entities = [SuLog::class], exportSchema = false)
|
||||||
abstract class SuLogDatabase : RoomDatabase() {
|
abstract class SuLogDatabase : RoomDatabase() {
|
||||||
|
|
||||||
abstract fun suLogDao(): SuLogDao
|
abstract fun suLogDao(): SuLogDao
|
||||||
@ -20,18 +20,18 @@ abstract class SuLogDao(private val db: SuLogDatabase) {
|
|||||||
|
|
||||||
suspend fun deleteAll() = withContext(Dispatchers.IO) { db.clearAllTables() }
|
suspend fun deleteAll() = withContext(Dispatchers.IO) { db.clearAllTables() }
|
||||||
|
|
||||||
suspend fun fetchAll(): MutableList<MagiskLog> {
|
suspend fun fetchAll(): MutableList<SuLog> {
|
||||||
deleteOutdated()
|
deleteOutdated()
|
||||||
return fetch()
|
return fetch()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Query("SELECT * FROM logs ORDER BY time DESC")
|
@Query("SELECT * FROM logs ORDER BY time DESC")
|
||||||
protected abstract suspend fun fetch(): MutableList<MagiskLog>
|
protected abstract suspend fun fetch(): MutableList<SuLog>
|
||||||
|
|
||||||
@Query("DELETE FROM logs WHERE time < :timeout")
|
@Query("DELETE FROM logs WHERE time < :timeout")
|
||||||
protected abstract suspend fun deleteOutdated(timeout: Long = twoWeeksAgo)
|
protected abstract suspend fun deleteOutdated(timeout: Long = twoWeeksAgo)
|
||||||
|
|
||||||
@Insert
|
@Insert
|
||||||
abstract suspend fun insert(log: MagiskLog)
|
abstract suspend fun insert(log: SuLog)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package com.topjohnwu.magisk.data.repository
|
package com.topjohnwu.magisk.data.repository
|
||||||
|
|
||||||
import com.topjohnwu.magisk.core.Const
|
import com.topjohnwu.magisk.core.Const
|
||||||
|
import com.topjohnwu.magisk.core.model.su.SuLog
|
||||||
import com.topjohnwu.magisk.data.database.SuLogDao
|
import com.topjohnwu.magisk.data.database.SuLogDao
|
||||||
import com.topjohnwu.magisk.ktx.await
|
import com.topjohnwu.magisk.ktx.await
|
||||||
import com.topjohnwu.magisk.model.entity.MagiskLog
|
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
|
|
||||||
|
|
||||||
@ -36,6 +36,6 @@ class LogRepository(
|
|||||||
fun clearMagiskLogs(cb: (Shell.Result) -> Unit) =
|
fun clearMagiskLogs(cb: (Shell.Result) -> Unit) =
|
||||||
Shell.su("echo -n > ${Const.MAGISK_LOG}").submit(cb)
|
Shell.su("echo -n > ${Const.MAGISK_LOG}").submit(cb)
|
||||||
|
|
||||||
suspend fun insert(log: MagiskLog) = logDao.insert(log)
|
suspend fun insert(log: SuLog) = logDao.insert(log)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,8 @@ import com.topjohnwu.magisk.data.network.GithubRawServices
|
|||||||
import com.topjohnwu.magisk.ktx.await
|
import com.topjohnwu.magisk.ktx.await
|
||||||
import com.topjohnwu.magisk.ktx.getLabel
|
import com.topjohnwu.magisk.ktx.getLabel
|
||||||
import com.topjohnwu.magisk.ktx.packageName
|
import com.topjohnwu.magisk.ktx.packageName
|
||||||
import com.topjohnwu.magisk.model.entity.HideAppInfo
|
import com.topjohnwu.magisk.ui.hide.HideAppInfo
|
||||||
import com.topjohnwu.magisk.model.entity.HideTarget
|
import com.topjohnwu.magisk.ui.hide.HideTarget
|
||||||
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
|
||||||
|
@ -3,6 +3,7 @@ package com.topjohnwu.magisk.databinding
|
|||||||
import androidx.annotation.CallSuper
|
import androidx.annotation.CallSuper
|
||||||
import androidx.databinding.PropertyChangeRegistry
|
import androidx.databinding.PropertyChangeRegistry
|
||||||
import androidx.databinding.ViewDataBinding
|
import androidx.databinding.ViewDataBinding
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.topjohnwu.magisk.BR
|
import com.topjohnwu.magisk.BR
|
||||||
import com.topjohnwu.magisk.utils.DiffObservableList
|
import com.topjohnwu.magisk.utils.DiffObservableList
|
||||||
import com.topjohnwu.magisk.utils.ObservableHost
|
import com.topjohnwu.magisk.utils.ObservableHost
|
||||||
@ -52,3 +53,13 @@ abstract class ComparableRvItem<in T> : RvItem() {
|
|||||||
abstract class ObservableItem<T> : ComparableRvItem<T>(), ObservableHost {
|
abstract class ObservableItem<T> : ComparableRvItem<T>(), ObservableHost {
|
||||||
override var callbacks: PropertyChangeRegistry? = null
|
override var callbacks: PropertyChangeRegistry? = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This item addresses issues where enclosing recycler has to be invalidated or generally
|
||||||
|
* manipulated with. This shouldn't be however necessary for 99.9% of use-cases. Refrain from using
|
||||||
|
* this item as it provides virtually no additional functionality. Stick with ComparableRvItem.
|
||||||
|
* */
|
||||||
|
|
||||||
|
interface LenientRvItem {
|
||||||
|
fun onBindingBound(binding: ViewDataBinding, recyclerView: RecyclerView)
|
||||||
|
}
|
||||||
|
@ -2,7 +2,6 @@ package com.topjohnwu.magisk.databinding
|
|||||||
|
|
||||||
import androidx.databinding.ViewDataBinding
|
import androidx.databinding.ViewDataBinding
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.LenientRvItem
|
|
||||||
import me.tatarka.bindingcollectionadapter2.BindingRecyclerViewAdapter
|
import me.tatarka.bindingcollectionadapter2.BindingRecyclerViewAdapter
|
||||||
|
|
||||||
class RvBindingAdapter<T : RvItem> : BindingRecyclerViewAdapter<T>() {
|
class RvBindingAdapter<T : RvItem> : BindingRecyclerViewAdapter<T>() {
|
||||||
@ -19,7 +18,7 @@ class RvBindingAdapter<T : RvItem> : BindingRecyclerViewAdapter<T>() {
|
|||||||
super.onBindBinding(binding, variableId, layoutRes, position, item)
|
super.onBindBinding(binding, variableId, layoutRes, position, item)
|
||||||
|
|
||||||
when (item) {
|
when (item) {
|
||||||
is LenientRvItem<*> -> {
|
is LenientRvItem -> {
|
||||||
val recycler = recyclerView ?: return
|
val recycler = recyclerView ?: return
|
||||||
item.onBindingBound(binding)
|
item.onBindingBound(binding)
|
||||||
item.onBindingBound(binding, recycler)
|
item.onBindingBound(binding, recycler)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package com.topjohnwu.magisk.model.events
|
package com.topjohnwu.magisk.events
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.app.Activity
|
import android.app.Activity
|
@ -1,4 +1,4 @@
|
|||||||
package com.topjohnwu.magisk.model.events
|
package com.topjohnwu.magisk.events
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
@ -1,4 +1,4 @@
|
|||||||
package com.topjohnwu.magisk.model.events
|
package com.topjohnwu.magisk.events
|
||||||
|
|
||||||
import android.view.ContextThemeWrapper
|
import android.view.ContextThemeWrapper
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
@ -0,0 +1,46 @@
|
|||||||
|
package com.topjohnwu.magisk.events
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import androidx.annotation.StringRes
|
||||||
|
import com.google.android.material.snackbar.Snackbar
|
||||||
|
import com.topjohnwu.magisk.arch.ActivityExecutor
|
||||||
|
import com.topjohnwu.magisk.arch.BaseUIActivity
|
||||||
|
import com.topjohnwu.magisk.arch.ViewEvent
|
||||||
|
import com.topjohnwu.magisk.core.base.BaseActivity
|
||||||
|
import com.topjohnwu.magisk.utils.TransitiveText
|
||||||
|
|
||||||
|
class SnackbarEvent private constructor(
|
||||||
|
private val msg: TransitiveText,
|
||||||
|
private val length: Int,
|
||||||
|
private val builder: Snackbar.() -> Unit
|
||||||
|
) : ViewEvent(), ActivityExecutor {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@StringRes res: Int,
|
||||||
|
length: Int = Snackbar.LENGTH_SHORT,
|
||||||
|
builder: Snackbar.() -> Unit = {}
|
||||||
|
) : this(TransitiveText.Res(res), length, builder)
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
message: String,
|
||||||
|
length: Int = Snackbar.LENGTH_SHORT,
|
||||||
|
builder: Snackbar.() -> Unit = {}
|
||||||
|
) : this(TransitiveText.String(message), length, builder)
|
||||||
|
|
||||||
|
|
||||||
|
private fun snackbar(
|
||||||
|
view: View,
|
||||||
|
message: String,
|
||||||
|
length: Int = Snackbar.LENGTH_SHORT,
|
||||||
|
builder: Snackbar.() -> Unit = {}
|
||||||
|
) = Snackbar.make(view, message, length).apply(builder).show()
|
||||||
|
|
||||||
|
override fun invoke(activity: BaseActivity) {
|
||||||
|
if (activity is BaseUIActivity<*, *>) {
|
||||||
|
snackbar(activity.snackbarView,
|
||||||
|
msg.getText(activity.resources).toString(),
|
||||||
|
length, builder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
76
app/src/main/java/com/topjohnwu/magisk/events/ViewEvents.kt
Normal file
76
app/src/main/java/com/topjohnwu/magisk/events/ViewEvents.kt
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
package com.topjohnwu.magisk.events
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import com.topjohnwu.magisk.arch.ActivityExecutor
|
||||||
|
import com.topjohnwu.magisk.arch.ContextExecutor
|
||||||
|
import com.topjohnwu.magisk.arch.ViewEvent
|
||||||
|
import com.topjohnwu.magisk.arch.ViewEventWithScope
|
||||||
|
import com.topjohnwu.magisk.core.base.BaseActivity
|
||||||
|
import com.topjohnwu.magisk.core.model.module.Repo
|
||||||
|
import com.topjohnwu.magisk.view.MarkDownWindow
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class ViewActionEvent(val action: BaseActivity.() -> Unit) : ViewEvent(), ActivityExecutor {
|
||||||
|
override fun invoke(activity: BaseActivity) = action(activity)
|
||||||
|
}
|
||||||
|
|
||||||
|
class OpenChangelogEvent(val item: Repo) : ViewEventWithScope(), ContextExecutor {
|
||||||
|
override fun invoke(context: Context) {
|
||||||
|
scope.launch {
|
||||||
|
MarkDownWindow.show(context, null, item::readme)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PermissionEvent(
|
||||||
|
private val permissions: List<String>,
|
||||||
|
private val callback: (Boolean) -> Unit
|
||||||
|
) : ViewEvent(), ActivityExecutor {
|
||||||
|
|
||||||
|
override fun invoke(activity: BaseActivity) =
|
||||||
|
activity.withPermissions(*permissions.toTypedArray()) {
|
||||||
|
onSuccess {
|
||||||
|
callback(true)
|
||||||
|
}
|
||||||
|
onFailure {
|
||||||
|
callback(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BackPressEvent : ViewEvent(), ActivityExecutor {
|
||||||
|
override fun invoke(activity: BaseActivity) {
|
||||||
|
activity.onBackPressed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DieEvent : ViewEvent(), ActivityExecutor {
|
||||||
|
override fun invoke(activity: BaseActivity) {
|
||||||
|
activity.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RecreateEvent : ViewEvent(), ActivityExecutor {
|
||||||
|
override fun invoke(activity: BaseActivity) {
|
||||||
|
activity.recreate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RequestFileEvent : ViewEvent(), ActivityExecutor {
|
||||||
|
override fun invoke(activity: BaseActivity) {
|
||||||
|
Intent(Intent.ACTION_GET_CONTENT)
|
||||||
|
.setType("*/*")
|
||||||
|
.addCategory(Intent.CATEGORY_OPENABLE)
|
||||||
|
.also { activity.startActivityForResult(it, REQUEST_CODE) }
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val REQUEST_CODE = 10
|
||||||
|
fun resolve(requestCode: Int, resultCode: Int, data: Intent?) = data
|
||||||
|
?.takeIf { resultCode == Activity.RESULT_OK }
|
||||||
|
?.takeIf { requestCode == REQUEST_CODE }
|
||||||
|
?.data
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.topjohnwu.magisk.model.events.dialog
|
package com.topjohnwu.magisk.events.dialog
|
||||||
|
|
||||||
import com.topjohnwu.magisk.arch.ActivityExecutor
|
import com.topjohnwu.magisk.arch.ActivityExecutor
|
||||||
import com.topjohnwu.magisk.arch.ViewEvent
|
import com.topjohnwu.magisk.arch.ViewEvent
|
@ -1,4 +1,4 @@
|
|||||||
package com.topjohnwu.magisk.model.events.dialog
|
package com.topjohnwu.magisk.events.dialog
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
@ -1,4 +1,4 @@
|
|||||||
package com.topjohnwu.magisk.model.events.dialog
|
package com.topjohnwu.magisk.events.dialog
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.topjohnwu.magisk.arch.ContextExecutor
|
import com.topjohnwu.magisk.arch.ContextExecutor
|
@ -1,4 +1,4 @@
|
|||||||
package com.topjohnwu.magisk.model.events.dialog
|
package com.topjohnwu.magisk.events.dialog
|
||||||
|
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
@ -7,8 +7,8 @@ import android.content.IntentFilter
|
|||||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.core.download.DownloadService
|
import com.topjohnwu.magisk.core.download.DownloadService
|
||||||
import com.topjohnwu.magisk.model.entity.internal.Configuration.EnvFix
|
import com.topjohnwu.magisk.model.internal.Configuration.EnvFix
|
||||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.Magisk
|
import com.topjohnwu.magisk.model.internal.DownloadSubject.Magisk
|
||||||
import com.topjohnwu.magisk.view.MagiskDialog
|
import com.topjohnwu.magisk.view.MagiskDialog
|
||||||
|
|
||||||
class EnvFixDialog : DialogEvent() {
|
class EnvFixDialog : DialogEvent() {
|
@ -1,11 +1,11 @@
|
|||||||
package com.topjohnwu.magisk.model.events.dialog
|
package com.topjohnwu.magisk.events.dialog
|
||||||
|
|
||||||
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.ktx.res
|
import com.topjohnwu.magisk.ktx.res
|
||||||
import com.topjohnwu.magisk.model.entity.internal.Configuration
|
import com.topjohnwu.magisk.model.internal.Configuration
|
||||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
import com.topjohnwu.magisk.model.internal.DownloadSubject
|
||||||
import com.topjohnwu.magisk.view.MagiskDialog
|
import com.topjohnwu.magisk.view.MagiskDialog
|
||||||
import com.topjohnwu.magisk.view.MarkDownWindow
|
import com.topjohnwu.magisk.view.MarkDownWindow
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
@ -1,10 +1,10 @@
|
|||||||
package com.topjohnwu.magisk.model.events.dialog
|
package com.topjohnwu.magisk.events.dialog
|
||||||
|
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.core.download.DownloadService
|
import com.topjohnwu.magisk.core.download.DownloadService
|
||||||
import com.topjohnwu.magisk.core.model.module.Repo
|
import com.topjohnwu.magisk.core.model.module.Repo
|
||||||
import com.topjohnwu.magisk.model.entity.internal.Configuration
|
import com.topjohnwu.magisk.model.internal.Configuration
|
||||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
import com.topjohnwu.magisk.model.internal.DownloadSubject
|
||||||
import com.topjohnwu.magisk.view.MagiskDialog
|
import com.topjohnwu.magisk.view.MagiskDialog
|
||||||
|
|
||||||
class ModuleInstallDialog(private val item: Repo) : DialogEvent() {
|
class ModuleInstallDialog(private val item: Repo) : DialogEvent() {
|
@ -1,4 +1,4 @@
|
|||||||
package com.topjohnwu.magisk.model.events.dialog
|
package com.topjohnwu.magisk.events.dialog
|
||||||
|
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.view.MagiskDialog
|
import com.topjohnwu.magisk.view.MagiskDialog
|
@ -1,4 +1,4 @@
|
|||||||
package com.topjohnwu.magisk.model.events.dialog
|
package com.topjohnwu.magisk.events.dialog
|
||||||
|
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.view.MagiskDialog
|
import com.topjohnwu.magisk.view.MagiskDialog
|
@ -1,11 +1,11 @@
|
|||||||
package com.topjohnwu.magisk.model.events.dialog
|
package com.topjohnwu.magisk.events.dialog
|
||||||
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
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.model.entity.internal.Configuration
|
import com.topjohnwu.magisk.model.internal.Configuration
|
||||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
import com.topjohnwu.magisk.model.internal.DownloadSubject
|
||||||
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.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
@ -1,126 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.ktx
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.res.ColorStateList
|
|
||||||
import android.view.View
|
|
||||||
import android.widget.TextView
|
|
||||||
import androidx.annotation.ColorInt
|
|
||||||
import androidx.annotation.ColorRes
|
|
||||||
import androidx.annotation.StringRes
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import androidx.core.view.ViewCompat
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import com.google.android.material.snackbar.Snackbar
|
|
||||||
|
|
||||||
fun AppCompatActivity.snackbar(
|
|
||||||
view: View,
|
|
||||||
@StringRes messageRes: Int,
|
|
||||||
length: Int = Snackbar.LENGTH_SHORT,
|
|
||||||
f: Snackbar.() -> Unit = {}
|
|
||||||
) {
|
|
||||||
snackbar(view, getString(messageRes), length, f)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun AppCompatActivity.snackbar(
|
|
||||||
view: View,
|
|
||||||
message: String,
|
|
||||||
length: Int = Snackbar.LENGTH_SHORT,
|
|
||||||
f: Snackbar.() -> Unit = {}
|
|
||||||
) = Snackbar.make(view, message, length)
|
|
||||||
.apply(f)
|
|
||||||
.show()
|
|
||||||
|
|
||||||
fun Fragment.snackbar(
|
|
||||||
view: View,
|
|
||||||
@StringRes messageRes: Int,
|
|
||||||
length: Int = Snackbar.LENGTH_SHORT,
|
|
||||||
f: Snackbar.() -> Unit = {}
|
|
||||||
) {
|
|
||||||
snackbar(view, getString(messageRes), length, f)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Fragment.snackbar(
|
|
||||||
view: View,
|
|
||||||
message: String,
|
|
||||||
length: Int = Snackbar.LENGTH_SHORT,
|
|
||||||
f: Snackbar.() -> Unit = {}
|
|
||||||
) = Snackbar.make(view, message, length)
|
|
||||||
.apply(f)
|
|
||||||
.show()
|
|
||||||
|
|
||||||
fun Snackbar.action(init: KSnackbar.() -> Unit) = apply {
|
|
||||||
val config = KSnackbar().apply(init)
|
|
||||||
|
|
||||||
setAction(config.title(context), config.onClickListener)
|
|
||||||
|
|
||||||
when {
|
|
||||||
config.hasValidColor -> setActionTextColor(config.color(context) ?: return@apply)
|
|
||||||
config.hasValidColorStateList -> setActionTextColor(config.colorStateList(context) ?: return@apply)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class KSnackbar {
|
|
||||||
var colorRes: Int = -1
|
|
||||||
var colorStateListRes: Int = -1
|
|
||||||
|
|
||||||
var title: CharSequence = ""
|
|
||||||
var titleRes: Int = -1
|
|
||||||
|
|
||||||
internal var onClickListener: (View) -> Unit = {}
|
|
||||||
internal val hasValidColor get() = colorRes != -1
|
|
||||||
internal val hasValidColorStateList get() = colorStateListRes != -1
|
|
||||||
|
|
||||||
fun onClicked(listener: (View) -> Unit) {
|
|
||||||
onClickListener = listener
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun title(context: Context) = if (title.isBlank()) context.getString(titleRes) else title
|
|
||||||
internal fun colorStateList(context: Context) = context.colorStateListCompat(colorStateListRes)
|
|
||||||
internal fun color(context: Context) = context.colorCompat(colorRes)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated("Kotlin DSL version is preferred", ReplaceWith("action {}"))
|
|
||||||
fun Snackbar.action(
|
|
||||||
@StringRes actionRes: Int,
|
|
||||||
@ColorRes colorRes: Int? = null,
|
|
||||||
listener: (View) -> Unit
|
|
||||||
) {
|
|
||||||
view.resources.getString(actionRes)
|
|
||||||
colorRes?.let { ContextCompat.getColor(view.context, colorRes) }
|
|
||||||
action {}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated("Kotlin DSL version is preferred", ReplaceWith("action {}"))
|
|
||||||
fun Snackbar.action(action: String, @ColorInt color: Int? = null, listener: (View) -> Unit) {
|
|
||||||
setAction(action, listener)
|
|
||||||
color?.let { setActionTextColor(color) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Snackbar.textColorRes(@ColorRes colorRes: Int) {
|
|
||||||
textColor(context.colorCompat(colorRes) ?: return)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Snackbar.textColor(@ColorInt color: Int) {
|
|
||||||
val tv = view.findViewById<TextView>(com.google.android.material.R.id.snackbar_text)
|
|
||||||
tv.setTextColor(color)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Snackbar.backgroundColorRes(@ColorRes colorRes: Int) {
|
|
||||||
backgroundColor(context.colorCompat(colorRes) ?: return)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Snackbar.backgroundColor(@ColorInt color: Int) {
|
|
||||||
ViewCompat.setBackgroundTintList(
|
|
||||||
view,
|
|
||||||
ColorStateList.valueOf(color)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Snackbar.alert() {
|
|
||||||
textColor(0xF44336)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Snackbar.success() {
|
|
||||||
textColor(0x4CAF50)
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.model.entity.recycler
|
|
||||||
|
|
||||||
import androidx.databinding.ViewDataBinding
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This item addresses issues where enclosing recycler has to be invalidated or generally
|
|
||||||
* manipulated with. This shouldn't be however necessary for 99.9% of use-cases. Refrain from using
|
|
||||||
* this item as it provides virtually no additional functionality. Stick with ComparableRvItem.
|
|
||||||
* */
|
|
||||||
abstract class LenientRvItem<in T> : ComparableRvItem<T>() {
|
|
||||||
|
|
||||||
open fun onBindingBound(binding: ViewDataBinding, recyclerView: RecyclerView) {}
|
|
||||||
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.model.entity.recycler
|
|
||||||
|
|
||||||
import com.topjohnwu.magisk.R
|
|
||||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
|
||||||
import com.topjohnwu.magisk.ui.theme.Theme
|
|
||||||
|
|
||||||
class ThemeItem(val theme: Theme) : ComparableRvItem<ThemeItem>() {
|
|
||||||
|
|
||||||
override val layoutRes = R.layout.item_theme
|
|
||||||
|
|
||||||
override fun contentSameAs(other: ThemeItem) = itemSameAs(other)
|
|
||||||
override fun itemSameAs(other: ThemeItem) = theme == other.theme
|
|
||||||
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.model.entity.state
|
|
||||||
|
|
||||||
enum class IndeterminateState {
|
|
||||||
CHECKED, INDETERMINATE, UNCHECKED
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.model.events
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import androidx.annotation.StringRes
|
|
||||||
import com.google.android.material.snackbar.Snackbar
|
|
||||||
import com.topjohnwu.magisk.arch.ActivityExecutor
|
|
||||||
import com.topjohnwu.magisk.arch.BaseUIActivity
|
|
||||||
import com.topjohnwu.magisk.arch.ViewEvent
|
|
||||||
import com.topjohnwu.magisk.core.base.BaseActivity
|
|
||||||
import com.topjohnwu.magisk.ktx.snackbar
|
|
||||||
|
|
||||||
class SnackbarEvent private constructor(
|
|
||||||
@StringRes private val messageRes: Int,
|
|
||||||
private val messageString: String?,
|
|
||||||
val length: Int,
|
|
||||||
val f: Snackbar.() -> Unit
|
|
||||||
) : ViewEvent(), ActivityExecutor {
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
@StringRes messageRes: Int,
|
|
||||||
length: Int = Snackbar.LENGTH_SHORT,
|
|
||||||
f: Snackbar.() -> Unit = {}
|
|
||||||
) : this(messageRes, null, length, f)
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
message: String,
|
|
||||||
length: Int = Snackbar.LENGTH_SHORT,
|
|
||||||
f: Snackbar.() -> Unit = {}
|
|
||||||
) : this(-1, message, length, f)
|
|
||||||
|
|
||||||
fun message(context: Context): String = messageString ?: context.getString(messageRes)
|
|
||||||
|
|
||||||
override fun invoke(activity: BaseActivity) {
|
|
||||||
if (activity is BaseUIActivity<*, *>) {
|
|
||||||
activity.snackbar(activity.snackbarView, message(activity), length, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
package com.topjohnwu.magisk.model.entity.internal
|
package com.topjohnwu.magisk.model.internal
|
||||||
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
@ -1,4 +1,4 @@
|
|||||||
package com.topjohnwu.magisk.model.entity.internal
|
package com.topjohnwu.magisk.model.internal
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
@ -1,4 +1,4 @@
|
|||||||
package com.topjohnwu.magisk.model.entity.recycler
|
package com.topjohnwu.magisk.ui.flash
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
@ -6,9 +6,11 @@ import androidx.core.view.updateLayoutParams
|
|||||||
import androidx.databinding.ViewDataBinding
|
import androidx.databinding.ViewDataBinding
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
|
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||||
|
import com.topjohnwu.magisk.databinding.LenientRvItem
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
|
|
||||||
class ConsoleItem(val item: String) : LenientRvItem<ConsoleItem>() {
|
class ConsoleItem(val item: String) : ComparableRvItem<ConsoleItem>(), LenientRvItem {
|
||||||
override val layoutRes = R.layout.item_console_md2
|
override val layoutRes = R.layout.item_console_md2
|
||||||
|
|
||||||
private var parentWidth = -1
|
private var parentWidth = -1
|
@ -15,9 +15,8 @@ import com.topjohnwu.magisk.core.Const
|
|||||||
import com.topjohnwu.magisk.core.tasks.FlashZip
|
import com.topjohnwu.magisk.core.tasks.FlashZip
|
||||||
import com.topjohnwu.magisk.core.tasks.MagiskInstaller
|
import com.topjohnwu.magisk.core.tasks.MagiskInstaller
|
||||||
import com.topjohnwu.magisk.databinding.RvBindingAdapter
|
import com.topjohnwu.magisk.databinding.RvBindingAdapter
|
||||||
|
import com.topjohnwu.magisk.events.SnackbarEvent
|
||||||
import com.topjohnwu.magisk.ktx.*
|
import com.topjohnwu.magisk.ktx.*
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.ConsoleItem
|
|
||||||
import com.topjohnwu.magisk.model.events.SnackbarEvent
|
|
||||||
import com.topjohnwu.magisk.utils.set
|
import com.topjohnwu.magisk.utils.set
|
||||||
import com.topjohnwu.magisk.view.Notifications
|
import com.topjohnwu.magisk.view.Notifications
|
||||||
import com.topjohnwu.superuser.CallbackList
|
import com.topjohnwu.superuser.CallbackList
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package com.topjohnwu.magisk.model.entity
|
package com.topjohnwu.magisk.ui.hide
|
||||||
|
|
||||||
import android.content.pm.ApplicationInfo
|
import android.content.pm.ApplicationInfo
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
@ -1,4 +1,4 @@
|
|||||||
package com.topjohnwu.magisk.model.entity.recycler
|
package com.topjohnwu.magisk.ui.hide
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
@ -7,9 +7,6 @@ import com.topjohnwu.magisk.BR
|
|||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.databinding.ObservableItem
|
import com.topjohnwu.magisk.databinding.ObservableItem
|
||||||
import com.topjohnwu.magisk.ktx.startAnimations
|
import com.topjohnwu.magisk.ktx.startAnimations
|
||||||
import com.topjohnwu.magisk.model.entity.HideAppTarget
|
|
||||||
import com.topjohnwu.magisk.model.entity.StatefulProcess
|
|
||||||
import com.topjohnwu.magisk.ui.hide.HideViewModel
|
|
||||||
import com.topjohnwu.magisk.utils.addOnPropertyChangedCallback
|
import com.topjohnwu.magisk.utils.addOnPropertyChangedCallback
|
||||||
import com.topjohnwu.magisk.utils.set
|
import com.topjohnwu.magisk.utils.set
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
@ -1,4 +1,4 @@
|
|||||||
package com.topjohnwu.magisk.model.entity
|
package com.topjohnwu.magisk.ui.hide
|
||||||
|
|
||||||
class HideTarget(line: String) {
|
class HideTarget(line: String) {
|
||||||
|
|
@ -11,12 +11,6 @@ import com.topjohnwu.magisk.arch.itemBindingOf
|
|||||||
import com.topjohnwu.magisk.core.Config
|
import com.topjohnwu.magisk.core.Config
|
||||||
import com.topjohnwu.magisk.core.utils.currentLocale
|
import com.topjohnwu.magisk.core.utils.currentLocale
|
||||||
import com.topjohnwu.magisk.data.repository.MagiskRepository
|
import com.topjohnwu.magisk.data.repository.MagiskRepository
|
||||||
import com.topjohnwu.magisk.model.entity.HideAppInfo
|
|
||||||
import com.topjohnwu.magisk.model.entity.HideAppTarget
|
|
||||||
import com.topjohnwu.magisk.model.entity.HideTarget
|
|
||||||
import com.topjohnwu.magisk.model.entity.StatefulProcess
|
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.HideItem
|
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.HideProcessItem
|
|
||||||
import com.topjohnwu.magisk.utils.set
|
import com.topjohnwu.magisk.utils.set
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package com.topjohnwu.magisk.model.entity
|
package com.topjohnwu.magisk.ui.home
|
||||||
|
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.core.Const
|
import com.topjohnwu.magisk.core.Const
|
@ -5,7 +5,7 @@ import android.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.FragmentHomeMd2Binding
|
import com.topjohnwu.magisk.databinding.FragmentHomeMd2Binding
|
||||||
import com.topjohnwu.magisk.model.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
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
|
|
||||||
|
@ -16,15 +16,14 @@ import com.topjohnwu.magisk.core.download.RemoteFileService
|
|||||||
import com.topjohnwu.magisk.core.model.MagiskJson
|
import com.topjohnwu.magisk.core.model.MagiskJson
|
||||||
import com.topjohnwu.magisk.core.model.ManagerJson
|
import com.topjohnwu.magisk.core.model.ManagerJson
|
||||||
import com.topjohnwu.magisk.data.repository.MagiskRepository
|
import com.topjohnwu.magisk.data.repository.MagiskRepository
|
||||||
|
import com.topjohnwu.magisk.events.OpenInappLinkEvent
|
||||||
|
import com.topjohnwu.magisk.events.dialog.EnvFixDialog
|
||||||
|
import com.topjohnwu.magisk.events.dialog.ManagerInstallDialog
|
||||||
|
import com.topjohnwu.magisk.events.dialog.UninstallDialog
|
||||||
import com.topjohnwu.magisk.ktx.await
|
import com.topjohnwu.magisk.ktx.await
|
||||||
import com.topjohnwu.magisk.ktx.packageName
|
import com.topjohnwu.magisk.ktx.packageName
|
||||||
import com.topjohnwu.magisk.ktx.res
|
import com.topjohnwu.magisk.ktx.res
|
||||||
import com.topjohnwu.magisk.model.entity.IconLink
|
import com.topjohnwu.magisk.model.internal.DownloadSubject.Manager
|
||||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.Manager
|
|
||||||
import com.topjohnwu.magisk.model.events.OpenInappLinkEvent
|
|
||||||
import com.topjohnwu.magisk.model.events.dialog.EnvFixDialog
|
|
||||||
import com.topjohnwu.magisk.model.events.dialog.ManagerInstallDialog
|
|
||||||
import com.topjohnwu.magisk.model.events.dialog.UninstallDialog
|
|
||||||
import com.topjohnwu.magisk.utils.set
|
import com.topjohnwu.magisk.utils.set
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
@ -5,7 +5,7 @@ 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.model.events.RequestFileEvent
|
import com.topjohnwu.magisk.events.RequestFileEvent
|
||||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
|
|
||||||
class InstallFragment : BaseUIFragment<InstallViewModel, FragmentInstallMd2Binding>() {
|
class InstallFragment : BaseUIFragment<InstallViewModel, FragmentInstallMd2Binding>() {
|
||||||
|
@ -11,10 +11,10 @@ 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.RemoteFileService
|
import com.topjohnwu.magisk.core.download.RemoteFileService
|
||||||
import com.topjohnwu.magisk.data.repository.StringRepository
|
import com.topjohnwu.magisk.data.repository.StringRepository
|
||||||
import com.topjohnwu.magisk.model.entity.internal.Configuration
|
import com.topjohnwu.magisk.events.RequestFileEvent
|
||||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
import com.topjohnwu.magisk.events.dialog.SecondSlotWarningDialog
|
||||||
import com.topjohnwu.magisk.model.events.RequestFileEvent
|
import com.topjohnwu.magisk.model.internal.Configuration
|
||||||
import com.topjohnwu.magisk.model.events.dialog.SecondSlotWarningDialog
|
import com.topjohnwu.magisk.model.internal.DownloadSubject
|
||||||
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
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
package com.topjohnwu.magisk.model.entity.recycler
|
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.model.su.SuLog
|
||||||
import com.topjohnwu.magisk.databinding.ObservableItem
|
import com.topjohnwu.magisk.databinding.ObservableItem
|
||||||
import com.topjohnwu.magisk.ktx.timeDateFormat
|
import com.topjohnwu.magisk.ktx.timeDateFormat
|
||||||
import com.topjohnwu.magisk.ktx.toTime
|
import com.topjohnwu.magisk.ktx.toTime
|
||||||
import com.topjohnwu.magisk.model.entity.MagiskLog
|
|
||||||
import com.topjohnwu.magisk.utils.set
|
import com.topjohnwu.magisk.utils.set
|
||||||
|
|
||||||
class LogItem(val item: MagiskLog) : ObservableItem<LogItem>() {
|
class LogRvItem(val item: SuLog) : ObservableItem<LogRvItem>() {
|
||||||
|
|
||||||
override val layoutRes = R.layout.item_log_access_md2
|
override val layoutRes = R.layout.item_log_access_md2
|
||||||
|
|
||||||
@ -23,9 +23,9 @@ class LogItem(val item: MagiskLog) : ObservableItem<LogItem>() {
|
|||||||
var isBottom = false
|
var isBottom = false
|
||||||
set(value) = set(value, field, { field = it }, BR.bottom)
|
set(value) = set(value, field, { field = it }, BR.bottom)
|
||||||
|
|
||||||
override fun itemSameAs(other: LogItem) = item.appName == other.item.appName
|
override fun itemSameAs(other: LogRvItem) = item.appName == other.item.appName
|
||||||
|
|
||||||
override fun contentSameAs(other: LogItem) = item.fromUid == other.item.fromUid &&
|
override fun contentSameAs(other: LogRvItem) = item.fromUid == other.item.fromUid &&
|
||||||
item.toUid == other.item.toUid &&
|
item.toUid == other.item.toUid &&
|
||||||
item.fromPid == other.item.fromPid &&
|
item.fromPid == other.item.fromPid &&
|
||||||
item.packageName == other.item.packageName &&
|
item.packageName == other.item.packageName &&
|
@ -10,10 +10,9 @@ import com.topjohnwu.magisk.arch.itemBindingOf
|
|||||||
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.data.repository.LogRepository
|
import com.topjohnwu.magisk.data.repository.LogRepository
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.LogItem
|
import com.topjohnwu.magisk.events.SnackbarEvent
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.TextItem
|
|
||||||
import com.topjohnwu.magisk.model.events.SnackbarEvent
|
|
||||||
import com.topjohnwu.magisk.utils.set
|
import com.topjohnwu.magisk.utils.set
|
||||||
|
import com.topjohnwu.magisk.view.TextItem
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -34,8 +33,8 @@ class LogViewModel(
|
|||||||
|
|
||||||
// --- su log
|
// --- su log
|
||||||
|
|
||||||
val items = diffListOf<LogItem>()
|
val items = diffListOf<LogRvItem>()
|
||||||
val itemBinding = itemBindingOf<LogItem> {
|
val itemBinding = itemBindingOf<LogRvItem> {
|
||||||
it.bindExtra(BR.viewModel, this)
|
it.bindExtra(BR.viewModel, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,7 +46,7 @@ class LogViewModel(
|
|||||||
override fun refresh() = viewModelScope.launch {
|
override fun refresh() = viewModelScope.launch {
|
||||||
consoleText = repo.fetchMagiskLogs()
|
consoleText = repo.fetchMagiskLogs()
|
||||||
val (suLogs, diff) = withContext(Dispatchers.Default) {
|
val (suLogs, diff) = withContext(Dispatchers.Default) {
|
||||||
val suLogs = repo.fetchSuLogs().map { LogItem(it) }
|
val suLogs = repo.fetchSuLogs().map { LogRvItem(it) }
|
||||||
suLogs to items.calculateDiff(suLogs)
|
suLogs to items.calculateDiff(suLogs)
|
||||||
}
|
}
|
||||||
items.firstOrNull()?.isTop = false
|
items.firstOrNull()?.isTop = false
|
||||||
|
@ -13,8 +13,8 @@ import com.topjohnwu.magisk.arch.BaseUIFragment
|
|||||||
import com.topjohnwu.magisk.arch.ReselectionTarget
|
import com.topjohnwu.magisk.arch.ReselectionTarget
|
||||||
import com.topjohnwu.magisk.arch.ViewEvent
|
import com.topjohnwu.magisk.arch.ViewEvent
|
||||||
import com.topjohnwu.magisk.databinding.FragmentModuleMd2Binding
|
import com.topjohnwu.magisk.databinding.FragmentModuleMd2Binding
|
||||||
|
import com.topjohnwu.magisk.events.InstallExternalModuleEvent
|
||||||
import com.topjohnwu.magisk.ktx.hideKeyboard
|
import com.topjohnwu.magisk.ktx.hideKeyboard
|
||||||
import com.topjohnwu.magisk.model.events.InstallExternalModuleEvent
|
|
||||||
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
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package com.topjohnwu.magisk.model.entity.recycler
|
package com.topjohnwu.magisk.ui.module
|
||||||
|
|
||||||
import androidx.databinding.Bindable
|
import androidx.databinding.Bindable
|
||||||
import com.topjohnwu.magisk.BR
|
import com.topjohnwu.magisk.BR
|
||||||
@ -7,7 +7,6 @@ import com.topjohnwu.magisk.core.model.module.Module
|
|||||||
import com.topjohnwu.magisk.core.model.module.Repo
|
import com.topjohnwu.magisk.core.model.module.Repo
|
||||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||||
import com.topjohnwu.magisk.databinding.ObservableItem
|
import com.topjohnwu.magisk.databinding.ObservableItem
|
||||||
import com.topjohnwu.magisk.ui.module.ModuleViewModel
|
|
||||||
import com.topjohnwu.magisk.utils.set
|
import com.topjohnwu.magisk.utils.set
|
||||||
|
|
||||||
object InstallModule : ComparableRvItem<InstallModule>() {
|
object InstallModule : ComparableRvItem<InstallModule>() {
|
@ -14,16 +14,12 @@ import com.topjohnwu.magisk.core.tasks.RepoUpdater
|
|||||||
import com.topjohnwu.magisk.data.database.RepoByNameDao
|
import com.topjohnwu.magisk.data.database.RepoByNameDao
|
||||||
import com.topjohnwu.magisk.data.database.RepoByUpdatedDao
|
import com.topjohnwu.magisk.data.database.RepoByUpdatedDao
|
||||||
import com.topjohnwu.magisk.databinding.RvItem
|
import com.topjohnwu.magisk.databinding.RvItem
|
||||||
|
import com.topjohnwu.magisk.events.InstallExternalModuleEvent
|
||||||
|
import com.topjohnwu.magisk.events.OpenChangelogEvent
|
||||||
|
import com.topjohnwu.magisk.events.dialog.ModuleInstallDialog
|
||||||
import com.topjohnwu.magisk.ktx.addOnListChangedCallback
|
import com.topjohnwu.magisk.ktx.addOnListChangedCallback
|
||||||
import com.topjohnwu.magisk.ktx.reboot
|
import com.topjohnwu.magisk.ktx.reboot
|
||||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
import com.topjohnwu.magisk.model.internal.DownloadSubject
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.InstallModule
|
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.ModuleItem
|
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.RepoItem
|
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.SectionTitle
|
|
||||||
import com.topjohnwu.magisk.model.events.InstallExternalModuleEvent
|
|
||||||
import com.topjohnwu.magisk.model.events.OpenChangelogEvent
|
|
||||||
import com.topjohnwu.magisk.model.events.dialog.ModuleInstallDialog
|
|
||||||
import com.topjohnwu.magisk.utils.EndlessRecyclerScrollListener
|
import com.topjohnwu.magisk.utils.EndlessRecyclerScrollListener
|
||||||
import com.topjohnwu.magisk.utils.set
|
import com.topjohnwu.magisk.utils.set
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
@ -1,23 +1,14 @@
|
|||||||
package com.topjohnwu.magisk.model.events
|
package com.topjohnwu.magisk.ui.safetynet
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.arch.ActivityExecutor
|
|
||||||
import com.topjohnwu.magisk.arch.ContextExecutor
|
import com.topjohnwu.magisk.arch.ContextExecutor
|
||||||
import com.topjohnwu.magisk.arch.ViewEvent
|
|
||||||
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.core.base.BaseActivity
|
|
||||||
import com.topjohnwu.magisk.core.model.module.Repo
|
|
||||||
import com.topjohnwu.magisk.core.utils.SafetyNetHelper
|
|
||||||
import com.topjohnwu.magisk.data.network.GithubRawServices
|
import com.topjohnwu.magisk.data.network.GithubRawServices
|
||||||
import com.topjohnwu.magisk.ktx.DynamicClassLoader
|
import com.topjohnwu.magisk.ktx.DynamicClassLoader
|
||||||
import com.topjohnwu.magisk.ktx.writeTo
|
import com.topjohnwu.magisk.ktx.writeTo
|
||||||
import com.topjohnwu.magisk.ui.safetynet.SafetyNetResult
|
|
||||||
import com.topjohnwu.magisk.view.MagiskDialog
|
import com.topjohnwu.magisk.view.MagiskDialog
|
||||||
import com.topjohnwu.magisk.view.MarkDownWindow
|
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
import dalvik.system.DexFile
|
import dalvik.system.DexFile
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
@ -32,6 +23,7 @@ import java.io.File
|
|||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.lang.reflect.InvocationHandler
|
import java.lang.reflect.InvocationHandler
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
class CheckSafetyNetEvent(
|
class CheckSafetyNetEvent(
|
||||||
private val callback: (SafetyNetResult) -> Unit = {}
|
private val callback: (SafetyNetResult) -> Unit = {}
|
||||||
) : ViewEventWithScope(), ContextExecutor, KoinComponent, SafetyNetHelper.Callback {
|
) : ViewEventWithScope(), ContextExecutor, KoinComponent, SafetyNetHelper.Callback {
|
||||||
@ -78,8 +70,10 @@ class CheckSafetyNetEvent(
|
|||||||
|
|
||||||
val helper = helperClass
|
val helper = helperClass
|
||||||
.getMethod("get", Class::class.java, Context::class.java, Any::class.java)
|
.getMethod("get", Class::class.java, Context::class.java, Any::class.java)
|
||||||
.invoke(null, SafetyNetHelper::class.java,
|
.invoke(
|
||||||
context, this@CheckSafetyNetEvent) as SafetyNetHelper
|
null, SafetyNetHelper::class.java,
|
||||||
|
context, this@CheckSafetyNetEvent
|
||||||
|
) as SafetyNetHelper
|
||||||
|
|
||||||
if (helper.version < Const.SNET_EXT_VER)
|
if (helper.version < Const.SNET_EXT_VER)
|
||||||
throw Exception()
|
throw Exception()
|
||||||
@ -136,66 +130,3 @@ class CheckSafetyNetEvent(
|
|||||||
callback(SafetyNetResult(response))
|
callback(SafetyNetResult(response))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ViewActionEvent(val action: BaseActivity.() -> Unit) : ViewEvent(), ActivityExecutor {
|
|
||||||
override fun invoke(activity: BaseActivity) = action(activity)
|
|
||||||
}
|
|
||||||
|
|
||||||
class OpenChangelogEvent(val item: Repo) : ViewEventWithScope(), ContextExecutor {
|
|
||||||
override fun invoke(context: Context) {
|
|
||||||
scope.launch {
|
|
||||||
MarkDownWindow.show(context, null, item::readme)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class PermissionEvent(
|
|
||||||
private val permissions: List<String>,
|
|
||||||
private val callback: (Boolean) -> Unit
|
|
||||||
) : ViewEvent(), ActivityExecutor {
|
|
||||||
|
|
||||||
override fun invoke(activity: BaseActivity) =
|
|
||||||
activity.withPermissions(*permissions.toTypedArray()) {
|
|
||||||
onSuccess {
|
|
||||||
callback(true)
|
|
||||||
}
|
|
||||||
onFailure {
|
|
||||||
callback(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class BackPressEvent : ViewEvent(), ActivityExecutor {
|
|
||||||
override fun invoke(activity: BaseActivity) {
|
|
||||||
activity.onBackPressed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class DieEvent : ViewEvent(), ActivityExecutor {
|
|
||||||
override fun invoke(activity: BaseActivity) {
|
|
||||||
activity.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class RecreateEvent : ViewEvent(), ActivityExecutor {
|
|
||||||
override fun invoke(activity: BaseActivity) {
|
|
||||||
activity.recreate()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class RequestFileEvent : ViewEvent(), ActivityExecutor {
|
|
||||||
override fun invoke(activity: BaseActivity) {
|
|
||||||
Intent(Intent.ACTION_GET_CONTENT)
|
|
||||||
.setType("*/*")
|
|
||||||
.addCategory(Intent.CATEGORY_OPENABLE)
|
|
||||||
.also { activity.startActivityForResult(it, REQUEST_CODE) }
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private const val REQUEST_CODE = 10
|
|
||||||
fun resolve(requestCode: Int, resultCode: Int, data: Intent?) = data
|
|
||||||
?.takeIf { resultCode == Activity.RESULT_OK }
|
|
||||||
?.takeIf { requestCode == REQUEST_CODE }
|
|
||||||
?.data
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
package com.topjohnwu.magisk.core.utils
|
package com.topjohnwu.magisk.ui.safetynet
|
||||||
|
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
|
@ -4,7 +4,6 @@ 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.arch.BaseViewModel
|
import com.topjohnwu.magisk.arch.BaseViewModel
|
||||||
import com.topjohnwu.magisk.model.events.CheckSafetyNetEvent
|
|
||||||
import com.topjohnwu.magisk.ui.safetynet.SafetyNetState.*
|
import com.topjohnwu.magisk.ui.safetynet.SafetyNetState.*
|
||||||
import com.topjohnwu.magisk.utils.set
|
import com.topjohnwu.magisk.utils.set
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
@ -54,7 +53,7 @@ class SafetynetViewModel : BaseViewModel() {
|
|||||||
|
|
||||||
private fun attest() {
|
private fun attest() {
|
||||||
currentState = LOADING
|
currentState = LOADING
|
||||||
CheckSafetyNetEvent() {
|
CheckSafetyNetEvent {
|
||||||
resolveResponse(it)
|
resolveResponse(it)
|
||||||
}.publish()
|
}.publish()
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package com.topjohnwu.magisk.model.entity.recycler
|
package com.topjohnwu.magisk.ui.settings
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
@ -16,7 +16,7 @@ import com.topjohnwu.magisk.view.MagiskDialog
|
|||||||
import org.koin.core.KoinComponent
|
import org.koin.core.KoinComponent
|
||||||
import org.koin.core.get
|
import org.koin.core.get
|
||||||
|
|
||||||
sealed class SettingsItem : ObservableItem<SettingsItem>() {
|
sealed class BaseSettingsItem : ObservableItem<BaseSettingsItem>() {
|
||||||
|
|
||||||
override val layoutRes get() = R.layout.item_settings
|
override val layoutRes get() = R.layout.item_settings
|
||||||
|
|
||||||
@ -46,19 +46,19 @@ sealed class SettingsItem : ObservableItem<SettingsItem>() {
|
|||||||
|
|
||||||
open fun refresh() {}
|
open fun refresh() {}
|
||||||
|
|
||||||
override fun itemSameAs(other: SettingsItem) = this === other
|
override fun itemSameAs(other: BaseSettingsItem) = this === other
|
||||||
override fun contentSameAs(other: SettingsItem) = itemSameAs(other)
|
override fun contentSameAs(other: BaseSettingsItem) = itemSameAs(other)
|
||||||
|
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
interface Callback {
|
interface Callback {
|
||||||
fun onItemPressed(view: View, item: SettingsItem, callback: () -> Unit = {})
|
fun onItemPressed(view: View, item: BaseSettingsItem, callback: () -> Unit = {})
|
||||||
fun onItemChanged(view: View, item: SettingsItem)
|
fun onItemChanged(view: View, item: BaseSettingsItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
abstract class Value<T> : SettingsItem() {
|
abstract class Value<T> : BaseSettingsItem() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents last agreed-upon value by the validation process and the user for current
|
* Represents last agreed-upon value by the validation process and the user for current
|
||||||
@ -176,9 +176,9 @@ sealed class SettingsItem : ObservableItem<SettingsItem>() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class Blank : SettingsItem()
|
abstract class Blank : BaseSettingsItem()
|
||||||
|
|
||||||
abstract class Section : SettingsItem() {
|
abstract class Section : BaseSettingsItem() {
|
||||||
override val layoutRes = R.layout.item_settings_section
|
override val layoutRes = R.layout.item_settings_section
|
||||||
}
|
}
|
||||||
|
|
@ -19,7 +19,6 @@ 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.ktx.get
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.SettingsItem
|
|
||||||
import com.topjohnwu.magisk.utils.Utils
|
import com.topjohnwu.magisk.utils.Utils
|
||||||
import com.topjohnwu.magisk.utils.asTransitive
|
import com.topjohnwu.magisk.utils.asTransitive
|
||||||
import com.topjohnwu.magisk.utils.set
|
import com.topjohnwu.magisk.utils.set
|
||||||
@ -30,11 +29,11 @@ import java.io.File
|
|||||||
|
|
||||||
// --- Customization
|
// --- Customization
|
||||||
|
|
||||||
object Customization : SettingsItem.Section() {
|
object Customization : BaseSettingsItem.Section() {
|
||||||
override val title = R.string.settings_customization.asTransitive()
|
override val title = R.string.settings_customization.asTransitive()
|
||||||
}
|
}
|
||||||
|
|
||||||
object Language : SettingsItem.Selector() {
|
object Language : BaseSettingsItem.Selector() {
|
||||||
override var value = -1
|
override var value = -1
|
||||||
set(value) = setV(value, field, { field = it }) {
|
set(value) = setV(value, field, { field = it }) {
|
||||||
Config.locale = entryValues[it]
|
Config.locale = entryValues[it]
|
||||||
@ -56,18 +55,18 @@ object Language : SettingsItem.Selector() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object Theme : SettingsItem.Blank() {
|
object Theme : BaseSettingsItem.Blank() {
|
||||||
override val icon = R.drawable.ic_paint
|
override val icon = R.drawable.ic_paint
|
||||||
override val title = R.string.section_theme.asTransitive()
|
override val title = R.string.section_theme.asTransitive()
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Manager
|
// --- Manager
|
||||||
|
|
||||||
object Manager : SettingsItem.Section() {
|
object Manager : BaseSettingsItem.Section() {
|
||||||
override val title = R.string.manager.asTransitive()
|
override val title = R.string.manager.asTransitive()
|
||||||
}
|
}
|
||||||
|
|
||||||
object ClearRepoCache : SettingsItem.Blank() {
|
object ClearRepoCache : BaseSettingsItem.Blank() {
|
||||||
override val title = R.string.settings_clear_cache_title.asTransitive()
|
override val title = R.string.settings_clear_cache_title.asTransitive()
|
||||||
override val description = R.string.settings_clear_cache_summary.asTransitive()
|
override val description = R.string.settings_clear_cache_summary.asTransitive()
|
||||||
|
|
||||||
@ -76,7 +75,7 @@ object ClearRepoCache : SettingsItem.Blank() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object Hide : SettingsItem.Input() {
|
object Hide : BaseSettingsItem.Input() {
|
||||||
override val title = R.string.settings_hide_manager_title.asTransitive()
|
override val title = R.string.settings_hide_manager_title.asTransitive()
|
||||||
override val description = R.string.settings_hide_manager_summary.asTransitive()
|
override val description = R.string.settings_hide_manager_summary.asTransitive()
|
||||||
|
|
||||||
@ -99,7 +98,7 @@ object Hide : SettingsItem.Input() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object Restore : SettingsItem.Blank() {
|
object Restore : BaseSettingsItem.Blank() {
|
||||||
override val title = R.string.settings_restore_manager_title.asTransitive()
|
override val title = R.string.settings_restore_manager_title.asTransitive()
|
||||||
override val description = R.string.settings_restore_manager_summary.asTransitive()
|
override val description = R.string.settings_restore_manager_summary.asTransitive()
|
||||||
}
|
}
|
||||||
@ -108,7 +107,7 @@ object Restore : SettingsItem.Blank() {
|
|||||||
fun HideOrRestore() =
|
fun HideOrRestore() =
|
||||||
if (get<Context>().packageName == BuildConfig.APPLICATION_ID) Hide else Restore
|
if (get<Context>().packageName == BuildConfig.APPLICATION_ID) Hide else Restore
|
||||||
|
|
||||||
object DownloadPath : SettingsItem.Input() {
|
object DownloadPath : BaseSettingsItem.Input() {
|
||||||
override var value = Config.downloadPath
|
override var value = Config.downloadPath
|
||||||
set(value) = setV(value, field, { field = it }) { Config.downloadPath = it }
|
set(value) = setV(value, field, { field = it }) { Config.downloadPath = it }
|
||||||
|
|
||||||
@ -130,7 +129,7 @@ object DownloadPath : SettingsItem.Input() {
|
|||||||
.inflate(LayoutInflater.from(context)).also { it.data = this }.root
|
.inflate(LayoutInflater.from(context)).also { it.data = this }.root
|
||||||
}
|
}
|
||||||
|
|
||||||
object UpdateChannel : SettingsItem.Selector() {
|
object UpdateChannel : BaseSettingsItem.Selector() {
|
||||||
override var value = Config.updateChannel
|
override var value = Config.updateChannel
|
||||||
set(value) = setV(value, field, { field = it }) { Config.updateChannel = it }
|
set(value) = setV(value, field, { field = it }) { Config.updateChannel = it }
|
||||||
|
|
||||||
@ -142,7 +141,7 @@ object UpdateChannel : SettingsItem.Selector() {
|
|||||||
override val entryValRes = R.array.value_array
|
override val entryValRes = R.array.value_array
|
||||||
}
|
}
|
||||||
|
|
||||||
object UpdateChannelUrl : SettingsItem.Input() {
|
object UpdateChannelUrl : BaseSettingsItem.Input() {
|
||||||
override val title = R.string.settings_update_custom.asTransitive()
|
override val title = R.string.settings_update_custom.asTransitive()
|
||||||
override var value = Config.customChannelUrl
|
override var value = Config.customChannelUrl
|
||||||
set(value) = setV(value, field, { field = it }) { Config.customChannelUrl = it }
|
set(value) = setV(value, field, { field = it }) { Config.customChannelUrl = it }
|
||||||
@ -162,7 +161,7 @@ object UpdateChannelUrl : SettingsItem.Input() {
|
|||||||
.inflate(LayoutInflater.from(context)).also { it.data = this }.root
|
.inflate(LayoutInflater.from(context)).also { it.data = this }.root
|
||||||
}
|
}
|
||||||
|
|
||||||
object UpdateChecker : SettingsItem.Toggle() {
|
object UpdateChecker : BaseSettingsItem.Toggle() {
|
||||||
override val title = R.string.settings_check_update_title.asTransitive()
|
override val title = R.string.settings_check_update_title.asTransitive()
|
||||||
override val description = R.string.settings_check_update_summary.asTransitive()
|
override val description = R.string.settings_check_update_summary.asTransitive()
|
||||||
override var value = Config.checkUpdate
|
override var value = Config.checkUpdate
|
||||||
@ -173,12 +172,12 @@ object UpdateChecker : SettingsItem.Toggle() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check whether is module already installed beforehand?
|
// check whether is module already installed beforehand?
|
||||||
object SystemlessHosts : SettingsItem.Blank() {
|
object SystemlessHosts : BaseSettingsItem.Blank() {
|
||||||
override val title = R.string.settings_hosts_title.asTransitive()
|
override val title = R.string.settings_hosts_title.asTransitive()
|
||||||
override val description = R.string.settings_hosts_summary.asTransitive()
|
override val description = R.string.settings_hosts_summary.asTransitive()
|
||||||
}
|
}
|
||||||
|
|
||||||
object Biometrics : SettingsItem.Toggle() {
|
object Biometrics : BaseSettingsItem.Toggle() {
|
||||||
override val title = R.string.settings_su_biometric_title.asTransitive()
|
override val title = R.string.settings_su_biometric_title.asTransitive()
|
||||||
override var value = Config.suBiometric
|
override var value = Config.suBiometric
|
||||||
set(value) = setV(value, field, { field = it }) { Config.suBiometric = it }
|
set(value) = setV(value, field, { field = it }) { Config.suBiometric = it }
|
||||||
@ -193,7 +192,7 @@ object Biometrics : SettingsItem.Toggle() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object Reauthenticate : SettingsItem.Toggle() {
|
object Reauthenticate : BaseSettingsItem.Toggle() {
|
||||||
override val title = R.string.settings_su_reauth_title.asTransitive()
|
override val title = R.string.settings_su_reauth_title.asTransitive()
|
||||||
override val description = R.string.settings_su_reauth_summary.asTransitive()
|
override val description = R.string.settings_su_reauth_summary.asTransitive()
|
||||||
override var value = Config.suReAuth
|
override var value = Config.suReAuth
|
||||||
@ -206,11 +205,11 @@ object Reauthenticate : SettingsItem.Toggle() {
|
|||||||
|
|
||||||
// --- Magisk
|
// --- Magisk
|
||||||
|
|
||||||
object Magisk : SettingsItem.Section() {
|
object Magisk : BaseSettingsItem.Section() {
|
||||||
override val title = R.string.magisk.asTransitive()
|
override val title = R.string.magisk.asTransitive()
|
||||||
}
|
}
|
||||||
|
|
||||||
object MagiskHide : SettingsItem.Toggle() {
|
object MagiskHide : BaseSettingsItem.Toggle() {
|
||||||
override val title = R.string.magiskhide.asTransitive()
|
override val title = R.string.magiskhide.asTransitive()
|
||||||
override val description = R.string.settings_magiskhide_summary.asTransitive()
|
override val description = R.string.settings_magiskhide_summary.asTransitive()
|
||||||
override var value = Config.magiskHide
|
override var value = Config.magiskHide
|
||||||
@ -225,11 +224,11 @@ object MagiskHide : SettingsItem.Toggle() {
|
|||||||
|
|
||||||
// --- Superuser
|
// --- Superuser
|
||||||
|
|
||||||
object Superuser : SettingsItem.Section() {
|
object Superuser : BaseSettingsItem.Section() {
|
||||||
override val title = R.string.superuser.asTransitive()
|
override val title = R.string.superuser.asTransitive()
|
||||||
}
|
}
|
||||||
|
|
||||||
object AccessMode : SettingsItem.Selector() {
|
object AccessMode : BaseSettingsItem.Selector() {
|
||||||
override val title = R.string.superuser_access.asTransitive()
|
override val title = R.string.superuser_access.asTransitive()
|
||||||
override val entryRes = R.array.su_access
|
override val entryRes = R.array.su_access
|
||||||
override val entryValRes = R.array.value_array
|
override val entryValRes = R.array.value_array
|
||||||
@ -240,7 +239,7 @@ object AccessMode : SettingsItem.Selector() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object MultiuserMode : SettingsItem.Selector() {
|
object MultiuserMode : BaseSettingsItem.Selector() {
|
||||||
override val title = R.string.multiuser_mode.asTransitive()
|
override val title = R.string.multiuser_mode.asTransitive()
|
||||||
override val entryRes = R.array.multiuser_mode
|
override val entryRes = R.array.multiuser_mode
|
||||||
override val entryValRes = R.array.value_array
|
override val entryValRes = R.array.value_array
|
||||||
@ -258,7 +257,7 @@ object MultiuserMode : SettingsItem.Selector() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object MountNamespaceMode : SettingsItem.Selector() {
|
object MountNamespaceMode : BaseSettingsItem.Selector() {
|
||||||
override val title = R.string.mount_namespace_mode.asTransitive()
|
override val title = R.string.mount_namespace_mode.asTransitive()
|
||||||
override val entryRes = R.array.namespace
|
override val entryRes = R.array.namespace
|
||||||
override val entryValRes = R.array.value_array
|
override val entryValRes = R.array.value_array
|
||||||
@ -272,7 +271,7 @@ object MountNamespaceMode : SettingsItem.Selector() {
|
|||||||
get() = resources.getStringArray(R.array.namespace_summary)[value].asTransitive()
|
get() = resources.getStringArray(R.array.namespace_summary)[value].asTransitive()
|
||||||
}
|
}
|
||||||
|
|
||||||
object AutomaticResponse : SettingsItem.Selector() {
|
object AutomaticResponse : BaseSettingsItem.Selector() {
|
||||||
override val title = R.string.auto_response.asTransitive()
|
override val title = R.string.auto_response.asTransitive()
|
||||||
override val entryRes = R.array.auto_response
|
override val entryRes = R.array.auto_response
|
||||||
override val entryValRes = R.array.value_array
|
override val entryValRes = R.array.value_array
|
||||||
@ -283,7 +282,7 @@ object AutomaticResponse : SettingsItem.Selector() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object RequestTimeout : SettingsItem.Selector() {
|
object RequestTimeout : BaseSettingsItem.Selector() {
|
||||||
override val title = R.string.request_timeout.asTransitive()
|
override val title = R.string.request_timeout.asTransitive()
|
||||||
override val entryRes = R.array.request_timeout
|
override val entryRes = R.array.request_timeout
|
||||||
override val entryValRes = R.array.request_timeout_value
|
override val entryValRes = R.array.request_timeout_value
|
||||||
@ -297,7 +296,7 @@ object RequestTimeout : SettingsItem.Selector() {
|
|||||||
get() = entryValues.indexOfFirst { it.toInt() == Config.suDefaultTimeout }
|
get() = entryValues.indexOfFirst { it.toInt() == Config.suDefaultTimeout }
|
||||||
}
|
}
|
||||||
|
|
||||||
object SUNotification : SettingsItem.Selector() {
|
object SUNotification : BaseSettingsItem.Selector() {
|
||||||
override val title = R.string.superuser_notification.asTransitive()
|
override val title = R.string.superuser_notification.asTransitive()
|
||||||
override val entryRes = R.array.su_notification
|
override val entryRes = R.array.su_notification
|
||||||
override val entryValRes = R.array.value_array
|
override val entryValRes = R.array.value_array
|
||||||
|
@ -15,11 +15,10 @@ 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.utils.PatchAPK
|
import com.topjohnwu.magisk.core.utils.PatchAPK
|
||||||
import com.topjohnwu.magisk.data.database.RepoDao
|
import com.topjohnwu.magisk.data.database.RepoDao
|
||||||
import com.topjohnwu.magisk.model.entity.internal.Configuration
|
import com.topjohnwu.magisk.events.RecreateEvent
|
||||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
import com.topjohnwu.magisk.events.dialog.BiometricDialog
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.SettingsItem
|
import com.topjohnwu.magisk.model.internal.Configuration
|
||||||
import com.topjohnwu.magisk.model.events.RecreateEvent
|
import com.topjohnwu.magisk.model.internal.DownloadSubject
|
||||||
import com.topjohnwu.magisk.model.events.dialog.BiometricDialog
|
|
||||||
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
|
||||||
@ -27,10 +26,10 @@ import org.koin.core.get
|
|||||||
|
|
||||||
class SettingsViewModel(
|
class SettingsViewModel(
|
||||||
private val repositoryDao: RepoDao
|
private val repositoryDao: RepoDao
|
||||||
) : BaseViewModel(), SettingsItem.Callback {
|
) : BaseViewModel(), BaseSettingsItem.Callback {
|
||||||
|
|
||||||
val adapter = adapterOf<SettingsItem>()
|
val adapter = adapterOf<BaseSettingsItem>()
|
||||||
val itemBinding = itemBindingOf<SettingsItem> { it.bindExtra(BR.callback, this) }
|
val itemBinding = itemBindingOf<BaseSettingsItem> { it.bindExtra(BR.callback, this) }
|
||||||
val items = diffListOf(createItems())
|
val items = diffListOf(createItems())
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -39,7 +38,7 @@ class SettingsViewModel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createItems(): List<SettingsItem> {
|
private fun createItems(): List<BaseSettingsItem> {
|
||||||
// Customization
|
// Customization
|
||||||
val list = mutableListOf(
|
val list = mutableListOf(
|
||||||
Customization,
|
Customization,
|
||||||
@ -90,7 +89,7 @@ class SettingsViewModel(
|
|||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemPressed(view: View, item: SettingsItem, callback: () -> Unit) = when (item) {
|
override fun onItemPressed(view: View, item: BaseSettingsItem, callback: () -> Unit) = when (item) {
|
||||||
is DownloadPath -> withExternalRW(callback)
|
is DownloadPath -> withExternalRW(callback)
|
||||||
is Biometrics -> authenticate(callback)
|
is Biometrics -> authenticate(callback)
|
||||||
is Theme -> SettingsFragmentDirections.actionSettingsFragmentToThemeFragment().publish()
|
is Theme -> SettingsFragmentDirections.actionSettingsFragmentToThemeFragment().publish()
|
||||||
@ -100,7 +99,7 @@ class SettingsViewModel(
|
|||||||
else -> callback()
|
else -> callback()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemChanged(view: View, item: SettingsItem) = when (item) {
|
override fun onItemChanged(view: View, item: BaseSettingsItem) = when (item) {
|
||||||
is Language -> RecreateEvent().publish()
|
is Language -> RecreateEvent().publish()
|
||||||
is UpdateChannel -> openUrlIfNecessary(view)
|
is UpdateChannel -> openUrlIfNecessary(view)
|
||||||
is Hide -> PatchAPK.hideManager(view.context, item.value)
|
is Hide -> PatchAPK.hideManager(view.context, item.value)
|
||||||
|
@ -1,19 +1,18 @@
|
|||||||
package com.topjohnwu.magisk.model.entity.recycler
|
package com.topjohnwu.magisk.ui.superuser
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
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.model.MagiskPolicy
|
import com.topjohnwu.magisk.core.model.su.SuPolicy
|
||||||
import com.topjohnwu.magisk.databinding.ObservableItem
|
import com.topjohnwu.magisk.databinding.ObservableItem
|
||||||
import com.topjohnwu.magisk.ui.superuser.SuperuserViewModel
|
|
||||||
import com.topjohnwu.magisk.utils.set
|
import com.topjohnwu.magisk.utils.set
|
||||||
|
|
||||||
class PolicyItem(
|
class PolicyRvItem(
|
||||||
val item: MagiskPolicy,
|
val item: SuPolicy,
|
||||||
val icon: Drawable,
|
val icon: Drawable,
|
||||||
val viewModel: SuperuserViewModel
|
val viewModel: SuperuserViewModel
|
||||||
) : ObservableItem<PolicyItem>() {
|
) : ObservableItem<PolicyRvItem>() {
|
||||||
override val layoutRes = R.layout.item_policy_md2
|
override val layoutRes = R.layout.item_policy_md2
|
||||||
|
|
||||||
@get:Bindable
|
@get:Bindable
|
||||||
@ -21,7 +20,7 @@ class PolicyItem(
|
|||||||
set(value) = set(value, field, { field = it }, BR.expanded)
|
set(value) = set(value, field, { field = it }, BR.expanded)
|
||||||
|
|
||||||
// This property hosts the policy state
|
// This property hosts the policy state
|
||||||
var policyState = item.policy == MagiskPolicy.ALLOW
|
var policyState = item.policy == SuPolicy.ALLOW
|
||||||
set(value) = set(value, field, { field = it }, BR.enabled)
|
set(value) = set(value, field, { field = it }, BR.enabled)
|
||||||
|
|
||||||
// This property binds with the UI state
|
// This property binds with the UI state
|
||||||
@ -44,7 +43,7 @@ class PolicyItem(
|
|||||||
|
|
||||||
private val updatedPolicy
|
private val updatedPolicy
|
||||||
get() = item.copy(
|
get() = item.copy(
|
||||||
policy = if (policyState) MagiskPolicy.ALLOW else MagiskPolicy.DENY,
|
policy = if (policyState) SuPolicy.ALLOW else SuPolicy.DENY,
|
||||||
notification = shouldNotify,
|
notification = shouldNotify,
|
||||||
logging = shouldLog
|
logging = shouldLog
|
||||||
)
|
)
|
||||||
@ -65,7 +64,7 @@ class PolicyItem(
|
|||||||
viewModel.deletePressed(this)
|
viewModel.deletePressed(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun contentSameAs(other: PolicyItem) = itemSameAs(other)
|
override fun contentSameAs(other: PolicyRvItem) = itemSameAs(other)
|
||||||
override fun itemSameAs(other: PolicyItem) = item.uid == other.item.uid
|
override fun itemSameAs(other: PolicyRvItem) = item.uid == other.item.uid
|
||||||
|
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.topjohnwu.magisk.model.entity.recycler
|
package com.topjohnwu.magisk.ui.superuser
|
||||||
|
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
@ -11,16 +11,15 @@ import com.topjohnwu.magisk.arch.adapterOf
|
|||||||
import com.topjohnwu.magisk.arch.diffListOf
|
import com.topjohnwu.magisk.arch.diffListOf
|
||||||
import com.topjohnwu.magisk.arch.itemBindingOf
|
import com.topjohnwu.magisk.arch.itemBindingOf
|
||||||
import com.topjohnwu.magisk.core.magiskdb.PolicyDao
|
import com.topjohnwu.magisk.core.magiskdb.PolicyDao
|
||||||
import com.topjohnwu.magisk.core.model.MagiskPolicy
|
import com.topjohnwu.magisk.core.model.su.SuPolicy
|
||||||
import com.topjohnwu.magisk.core.utils.BiometricHelper
|
import com.topjohnwu.magisk.core.utils.BiometricHelper
|
||||||
import com.topjohnwu.magisk.core.utils.currentLocale
|
import com.topjohnwu.magisk.core.utils.currentLocale
|
||||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.PolicyItem
|
import com.topjohnwu.magisk.events.SnackbarEvent
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.TappableHeadlineItem
|
import com.topjohnwu.magisk.events.dialog.BiometricDialog
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.TextItem
|
import com.topjohnwu.magisk.events.dialog.SuperuserRevokeDialog
|
||||||
import com.topjohnwu.magisk.model.events.SnackbarEvent
|
import com.topjohnwu.magisk.view.TappableHeadlineItem
|
||||||
import com.topjohnwu.magisk.model.events.dialog.BiometricDialog
|
import com.topjohnwu.magisk.view.TextItem
|
||||||
import com.topjohnwu.magisk.model.events.dialog.SuperuserRevokeDialog
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
@ -34,7 +33,7 @@ class SuperuserViewModel(
|
|||||||
|
|
||||||
private val itemNoData = TextItem(R.string.superuser_policy_none)
|
private val itemNoData = TextItem(R.string.superuser_policy_none)
|
||||||
|
|
||||||
private val itemsPolicies = diffListOf<PolicyItem>()
|
private val itemsPolicies = diffListOf<PolicyRvItem>()
|
||||||
private val itemsHelpers = ObservableArrayList<TextItem>()
|
private val itemsHelpers = ObservableArrayList<TextItem>()
|
||||||
|
|
||||||
val adapter = adapterOf<ComparableRvItem<*>>()
|
val adapter = adapterOf<ComparableRvItem<*>>()
|
||||||
@ -52,7 +51,7 @@ class SuperuserViewModel(
|
|||||||
state = State.LOADING
|
state = State.LOADING
|
||||||
val (policies, diff) = withContext(Dispatchers.Default) {
|
val (policies, diff) = withContext(Dispatchers.Default) {
|
||||||
val policies = db.fetchAll {
|
val policies = db.fetchAll {
|
||||||
PolicyItem(it, it.applicationInfo.loadIcon(packageManager), this@SuperuserViewModel)
|
PolicyRvItem(it, it.applicationInfo.loadIcon(packageManager), this@SuperuserViewModel)
|
||||||
}.sortedWith(compareBy(
|
}.sortedWith(compareBy(
|
||||||
{ it.item.appName.toLowerCase(currentLocale) },
|
{ it.item.appName.toLowerCase(currentLocale) },
|
||||||
{ it.item.packageName }
|
{ it.item.packageName }
|
||||||
@ -77,7 +76,7 @@ class SuperuserViewModel(
|
|||||||
private fun hidePressed() =
|
private fun hidePressed() =
|
||||||
SuperuserFragmentDirections.actionSuperuserFragmentToHideFragment().publish()
|
SuperuserFragmentDirections.actionSuperuserFragmentToHideFragment().publish()
|
||||||
|
|
||||||
fun deletePressed(item: PolicyItem) {
|
fun deletePressed(item: PolicyRvItem) {
|
||||||
fun updateState() = viewModelScope.launch {
|
fun updateState() = viewModelScope.launch {
|
||||||
db.delete(item.item.uid)
|
db.delete(item.item.uid)
|
||||||
itemsPolicies.removeAll { it.genericItemSameAs(item) }
|
itemsPolicies.removeAll { it.genericItemSameAs(item) }
|
||||||
@ -100,7 +99,7 @@ class SuperuserViewModel(
|
|||||||
|
|
||||||
//---
|
//---
|
||||||
|
|
||||||
fun updatePolicy(policy: MagiskPolicy, isLogging: Boolean) = viewModelScope.launch {
|
fun updatePolicy(policy: SuPolicy, isLogging: Boolean) = viewModelScope.launch {
|
||||||
db.update(policy)
|
db.update(policy)
|
||||||
val str = when {
|
val str = when {
|
||||||
isLogging -> when {
|
isLogging -> when {
|
||||||
@ -115,16 +114,16 @@ class SuperuserViewModel(
|
|||||||
SnackbarEvent(resources.getString(str, policy.appName)).publish()
|
SnackbarEvent(resources.getString(str, policy.appName)).publish()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun togglePolicy(item: PolicyItem, enable: Boolean) {
|
fun togglePolicy(item: PolicyRvItem, enable: Boolean) {
|
||||||
fun updateState() {
|
fun updateState() {
|
||||||
item.policyState = enable
|
item.policyState = enable
|
||||||
|
|
||||||
val policy = if (enable) MagiskPolicy.ALLOW else MagiskPolicy.DENY
|
val policy = if (enable) SuPolicy.ALLOW else SuPolicy.DENY
|
||||||
val app = item.item.copy(policy = policy)
|
val app = item.item.copy(policy = policy)
|
||||||
|
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
db.update(app)
|
db.update(app)
|
||||||
val res = if (app.policy == MagiskPolicy.ALLOW) R.string.su_snack_grant
|
val res = if (app.policy == SuPolicy.ALLOW) R.string.su_snack_grant
|
||||||
else R.string.su_snack_deny
|
else R.string.su_snack_deny
|
||||||
SnackbarEvent(resources.getString(res).format(item.item.appName)).publish()
|
SnackbarEvent(resources.getString(res).format(item.item.appName)).publish()
|
||||||
}
|
}
|
||||||
|
@ -13,12 +13,12 @@ import com.topjohnwu.magisk.R
|
|||||||
import com.topjohnwu.magisk.arch.BaseViewModel
|
import com.topjohnwu.magisk.arch.BaseViewModel
|
||||||
import com.topjohnwu.magisk.core.Config
|
import com.topjohnwu.magisk.core.Config
|
||||||
import com.topjohnwu.magisk.core.magiskdb.PolicyDao
|
import com.topjohnwu.magisk.core.magiskdb.PolicyDao
|
||||||
import com.topjohnwu.magisk.core.model.MagiskPolicy.Companion.ALLOW
|
import com.topjohnwu.magisk.core.model.su.SuPolicy.Companion.ALLOW
|
||||||
import com.topjohnwu.magisk.core.model.MagiskPolicy.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.model.entity.recycler.SpinnerRvItem
|
import com.topjohnwu.magisk.events.DieEvent
|
||||||
import com.topjohnwu.magisk.model.events.DieEvent
|
import com.topjohnwu.magisk.ui.superuser.SpinnerRvItem
|
||||||
import com.topjohnwu.magisk.utils.set
|
import com.topjohnwu.magisk.utils.set
|
||||||
import com.topjohnwu.superuser.internal.UiThreadHandler
|
import com.topjohnwu.superuser.internal.UiThreadHandler
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package com.topjohnwu.magisk.ui.theme
|
package com.topjohnwu.magisk.ui.theme
|
||||||
|
|
||||||
import com.topjohnwu.magisk.arch.BaseViewModel
|
import com.topjohnwu.magisk.arch.BaseViewModel
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.TappableHeadlineItem
|
import com.topjohnwu.magisk.events.RecreateEvent
|
||||||
import com.topjohnwu.magisk.model.events.RecreateEvent
|
import com.topjohnwu.magisk.events.dialog.DarkThemeDialog
|
||||||
import com.topjohnwu.magisk.model.events.dialog.DarkThemeDialog
|
import com.topjohnwu.magisk.view.TappableHeadlineItem
|
||||||
|
|
||||||
class ThemeViewModel : BaseViewModel(), TappableHeadlineItem.Listener {
|
class ThemeViewModel : BaseViewModel(), TappableHeadlineItem.Listener {
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package com.topjohnwu.magisk.model.entity.recycler
|
package com.topjohnwu.magisk.view
|
||||||
|
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
@ -1,4 +1,4 @@
|
|||||||
package com.topjohnwu.magisk.model.entity.recycler
|
package com.topjohnwu.magisk.view
|
||||||
|
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
<import type="com.topjohnwu.magisk.ui.home.MagiskState" />
|
<import type="com.topjohnwu.magisk.ui.home.MagiskState" />
|
||||||
|
|
||||||
<import type="com.topjohnwu.magisk.model.entity.DeveloperItem"/>
|
<import type="com.topjohnwu.magisk.ui.home.DeveloperItem"/>
|
||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="viewModel"
|
name="viewModel"
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="item"
|
name="item"
|
||||||
type="com.topjohnwu.magisk.model.entity.recycler.ConsoleItem" />
|
type="com.topjohnwu.magisk.ui.flash.ConsoleItem" />
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="item"
|
name="item"
|
||||||
type="com.topjohnwu.magisk.model.entity.DeveloperItem" />
|
type="com.topjohnwu.magisk.ui.home.DeveloperItem" />
|
||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="viewModel"
|
name="viewModel"
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="item"
|
name="item"
|
||||||
type="com.topjohnwu.magisk.model.entity.recycler.HideItem" />
|
type="com.topjohnwu.magisk.ui.hide.HideItem" />
|
||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="viewModel"
|
name="viewModel"
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="item"
|
name="item"
|
||||||
type="com.topjohnwu.magisk.model.entity.recycler.HideProcessItem" />
|
type="com.topjohnwu.magisk.ui.hide.HideProcessItem" />
|
||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="viewModel"
|
name="viewModel"
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="item"
|
name="item"
|
||||||
type="com.topjohnwu.magisk.model.entity.IconLink" />
|
type="com.topjohnwu.magisk.ui.home.IconLink" />
|
||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="viewModel"
|
name="viewModel"
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="item"
|
name="item"
|
||||||
type="com.topjohnwu.magisk.model.entity.recycler.LogItem" />
|
type="com.topjohnwu.magisk.ui.log.LogRvItem" />
|
||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="viewModel"
|
name="viewModel"
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="item"
|
name="item"
|
||||||
type="com.topjohnwu.magisk.model.entity.recycler.InstallModule" />
|
type="com.topjohnwu.magisk.ui.module.InstallModule" />
|
||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="viewModel"
|
name="viewModel"
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="item"
|
name="item"
|
||||||
type="com.topjohnwu.magisk.model.entity.recycler.ModuleItem" />
|
type="com.topjohnwu.magisk.ui.module.ModuleItem" />
|
||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="viewModel"
|
name="viewModel"
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="item"
|
name="item"
|
||||||
type="com.topjohnwu.magisk.model.entity.recycler.PolicyItem" />
|
type="com.topjohnwu.magisk.ui.superuser.PolicyRvItem" />
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="item"
|
name="item"
|
||||||
type="com.topjohnwu.magisk.model.entity.recycler.RepoItem" />
|
type="com.topjohnwu.magisk.ui.module.RepoItem" />
|
||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="viewModel"
|
name="viewModel"
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="item"
|
name="item"
|
||||||
type="com.topjohnwu.magisk.model.entity.recycler.SectionTitle" />
|
type="com.topjohnwu.magisk.ui.module.SectionTitle" />
|
||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="viewModel"
|
name="viewModel"
|
||||||
|
@ -7,11 +7,11 @@
|
|||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="item"
|
name="item"
|
||||||
type="com.topjohnwu.magisk.model.entity.recycler.SettingsItem" />
|
type="com.topjohnwu.magisk.ui.settings.BaseSettingsItem" />
|
||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="callback"
|
name="callback"
|
||||||
type="com.topjohnwu.magisk.model.entity.recycler.SettingsItem.Callback" />
|
type="com.topjohnwu.magisk.ui.settings.BaseSettingsItem.Callback" />
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="item"
|
name="item"
|
||||||
type="com.topjohnwu.magisk.model.entity.recycler.SettingsItem" />
|
type="com.topjohnwu.magisk.ui.settings.BaseSettingsItem" />
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="item"
|
name="item"
|
||||||
type="com.topjohnwu.magisk.model.entity.recycler.SpinnerRvItem" />
|
type="com.topjohnwu.magisk.ui.superuser.SpinnerRvItem" />
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
|
|
||||||
|
@ -7,11 +7,11 @@
|
|||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="item"
|
name="item"
|
||||||
type="com.topjohnwu.magisk.model.entity.recycler.TappableHeadlineItem" />
|
type="com.topjohnwu.magisk.view.TappableHeadlineItem" />
|
||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="listener"
|
name="listener"
|
||||||
type="com.topjohnwu.magisk.model.entity.recycler.TappableHeadlineItem.Listener" />
|
type="com.topjohnwu.magisk.view.TappableHeadlineItem.Listener" />
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="item"
|
name="item"
|
||||||
type="com.topjohnwu.magisk.model.entity.recycler.TextItem" />
|
type="com.topjohnwu.magisk.view.TextItem" />
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user