mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-23 18:15: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.* { *; }
|
||||
|
||||
# Snet
|
||||
-keepclassmembers class com.topjohnwu.magisk.core.utils.SafetyNetHelper { *; }
|
||||
-keep,allowobfuscation interface com.topjohnwu.magisk.core.utils.SafetyNetHelper$Callback
|
||||
-keepclassmembers class * implements com.topjohnwu.magisk.core.utils.SafetyNetHelper$Callback {
|
||||
-keepclassmembers class com.topjohnwu.magisk.ui.safetynet.SafetyNetHelper { *; }
|
||||
-keep,allowobfuscation interface com.topjohnwu.magisk.ui.safetynet.SafetyNetHelper$Callback
|
||||
-keepclassmembers class * implements com.topjohnwu.magisk.ui.safetynet.SafetyNetHelper$Callback {
|
||||
void onResponse(int);
|
||||
}
|
||||
|
||||
|
@ -15,10 +15,10 @@ import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.core.Info
|
||||
import com.topjohnwu.magisk.core.base.BaseActivity
|
||||
import com.topjohnwu.magisk.model.events.BackPressEvent
|
||||
import com.topjohnwu.magisk.model.events.PermissionEvent
|
||||
import com.topjohnwu.magisk.model.events.SnackbarEvent
|
||||
import com.topjohnwu.magisk.model.events.ViewActionEvent
|
||||
import com.topjohnwu.magisk.events.BackPressEvent
|
||||
import com.topjohnwu.magisk.events.PermissionEvent
|
||||
import com.topjohnwu.magisk.events.SnackbarEvent
|
||||
import com.topjohnwu.magisk.events.ViewActionEvent
|
||||
import com.topjohnwu.magisk.model.navigation.NavigationWrapper
|
||||
import com.topjohnwu.magisk.utils.ObservableHost
|
||||
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.su.SuCallbackHandler
|
||||
import com.topjohnwu.magisk.ktx.reboot
|
||||
import com.topjohnwu.magisk.model.entity.internal.Configuration
|
||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
||||
import com.topjohnwu.magisk.model.internal.Configuration
|
||||
import com.topjohnwu.magisk.model.internal.DownloadSubject
|
||||
import com.topjohnwu.magisk.view.Shortcuts
|
||||
import com.topjohnwu.superuser.Shell
|
||||
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.exists
|
||||
import com.topjohnwu.magisk.ktx.provide
|
||||
import com.topjohnwu.magisk.model.entity.internal.Configuration.*
|
||||
import com.topjohnwu.magisk.model.entity.internal.Configuration.Flash.Secondary
|
||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.*
|
||||
import com.topjohnwu.magisk.model.internal.Configuration.*
|
||||
import com.topjohnwu.magisk.model.internal.Configuration.Flash.Secondary
|
||||
import com.topjohnwu.magisk.model.internal.DownloadSubject
|
||||
import com.topjohnwu.magisk.model.internal.DownloadSubject.*
|
||||
import com.topjohnwu.magisk.ui.flash.FlashFragment
|
||||
import com.topjohnwu.magisk.utils.APKInstall
|
||||
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.utils.PatchAPK
|
||||
import com.topjohnwu.magisk.ktx.writeTo
|
||||
import com.topjohnwu.magisk.model.entity.internal.Configuration.APK.Restore
|
||||
import com.topjohnwu.magisk.model.entity.internal.Configuration.APK.Upgrade
|
||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
||||
import com.topjohnwu.magisk.model.internal.Configuration.APK.Restore
|
||||
import com.topjohnwu.magisk.model.internal.Configuration.APK.Upgrade
|
||||
import com.topjohnwu.magisk.model.internal.DownloadSubject
|
||||
import com.topjohnwu.superuser.Shell
|
||||
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.ktx.checkSum
|
||||
import com.topjohnwu.magisk.ktx.writeTo
|
||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.Magisk
|
||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.Module
|
||||
import com.topjohnwu.magisk.model.internal.DownloadSubject
|
||||
import com.topjohnwu.magisk.model.internal.DownloadSubject.Magisk
|
||||
import com.topjohnwu.magisk.model.internal.DownloadSubject.Module
|
||||
import com.topjohnwu.magisk.view.Notifications
|
||||
import kotlinx.coroutines.launch
|
||||
import okhttp3.ResponseBody
|
||||
|
@ -3,9 +3,9 @@ package com.topjohnwu.magisk.core.magiskdb
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import com.topjohnwu.magisk.core.Const
|
||||
import com.topjohnwu.magisk.core.model.MagiskPolicy
|
||||
import com.topjohnwu.magisk.core.model.toMap
|
||||
import com.topjohnwu.magisk.core.model.toPolicy
|
||||
import com.topjohnwu.magisk.core.model.su.SuPolicy
|
||||
import com.topjohnwu.magisk.core.model.su.toMap
|
||||
import com.topjohnwu.magisk.core.model.su.toPolicy
|
||||
import com.topjohnwu.magisk.ktx.now
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
@ -49,11 +49,11 @@ class PolicyDao(
|
||||
}
|
||||
}.query().first().toPolicyOrNull()
|
||||
|
||||
suspend fun update(policy: MagiskPolicy) = buildQuery<Replace> {
|
||||
suspend fun update(policy: SuPolicy) = buildQuery<Replace> {
|
||||
values(policy.toMap())
|
||||
}.commit()
|
||||
|
||||
suspend fun <R: Any> fetchAll(mapper: (MagiskPolicy) -> R) = buildQuery<Select> {
|
||||
suspend fun <R: Any> fetchAll(mapper: (SuPolicy) -> R) = buildQuery<Select> {
|
||||
condition {
|
||||
equals("uid/100000", Const.USER_ID)
|
||||
}
|
||||
@ -61,7 +61,7 @@ class PolicyDao(
|
||||
it.toPolicyOrNull()?.let(mapper)
|
||||
}
|
||||
|
||||
private fun Map<String, String>.toPolicyOrNull(): MagiskPolicy? {
|
||||
private fun Map<String, String>.toPolicyOrNull(): SuPolicy? {
|
||||
return runCatching { toPolicy(context.packageManager) }.getOrElse {
|
||||
Timber.e(it)
|
||||
if (it is PackageManager.NameNotFoundException) {
|
||||
|
@ -59,6 +59,6 @@ data class Repo(
|
||||
class IllegalRepoException(message: String) : Exception(message)
|
||||
|
||||
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.Ignore
|
||||
import androidx.room.PrimaryKey
|
||||
import com.topjohnwu.magisk.core.model.MagiskPolicy
|
||||
import com.topjohnwu.magisk.core.model.MagiskPolicy.Companion.ALLOW
|
||||
import com.topjohnwu.magisk.core.model.su.SuPolicy.Companion.ALLOW
|
||||
import com.topjohnwu.magisk.ktx.now
|
||||
import com.topjohnwu.magisk.ktx.timeFormatTime
|
||||
import com.topjohnwu.magisk.ktx.toTime
|
||||
|
||||
@Entity(tableName = "logs")
|
||||
data class MagiskLog(
|
||||
data class SuLog(
|
||||
val fromUid: Int,
|
||||
val toUid: Int,
|
||||
val fromPid: Int,
|
||||
@ -24,8 +23,8 @@ data class MagiskLog(
|
||||
@Ignore val timeString = time.toTime(timeFormatTime)
|
||||
}
|
||||
|
||||
fun MagiskPolicy.toLog(
|
||||
fun SuPolicy.toLog(
|
||||
toUid: Int,
|
||||
fromPid: Int,
|
||||
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.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
|
||||
|
||||
|
||||
data class MagiskPolicy(
|
||||
data class SuPolicy(
|
||||
var uid: Int,
|
||||
val packageName: String,
|
||||
val appName: String,
|
||||
@ -25,7 +25,7 @@ data class MagiskPolicy(
|
||||
|
||||
}
|
||||
|
||||
fun MagiskPolicy.toMap() = mapOf(
|
||||
fun SuPolicy.toMap() = mapOf(
|
||||
"uid" to uid,
|
||||
"package_name" to packageName,
|
||||
"policy" to policy,
|
||||
@ -35,7 +35,7 @@ fun MagiskPolicy.toMap() = mapOf(
|
||||
)
|
||||
|
||||
@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 packageName = get("package_name").orEmpty()
|
||||
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)
|
||||
throw PackageManager.NameNotFoundException()
|
||||
|
||||
return MagiskPolicy(
|
||||
return SuPolicy(
|
||||
uid = uid,
|
||||
packageName = packageName,
|
||||
policy = get("policy")?.toIntOrNull() ?: INTERACTIVE,
|
||||
@ -56,11 +56,11 @@ fun Map<String, String>.toPolicy(pm: PackageManager): MagiskPolicy {
|
||||
}
|
||||
|
||||
@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()
|
||||
?: throw PackageManager.NameNotFoundException()
|
||||
val info = pm.getApplicationInfo(pkg, PackageManager.GET_UNINSTALLED_PACKAGES)
|
||||
return MagiskPolicy(
|
||||
return SuPolicy(
|
||||
uid = info.uid,
|
||||
packageName = pkg,
|
||||
policy = policy,
|
@ -11,14 +11,14 @@ import com.topjohnwu.magisk.ProviderCallHandler
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.core.Config
|
||||
import com.topjohnwu.magisk.core.intent
|
||||
import com.topjohnwu.magisk.core.model.MagiskPolicy
|
||||
import com.topjohnwu.magisk.core.model.toPolicy
|
||||
import com.topjohnwu.magisk.core.model.su.SuPolicy
|
||||
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.data.repository.LogRepository
|
||||
import com.topjohnwu.magisk.ktx.get
|
||||
import com.topjohnwu.magisk.ktx.startActivity
|
||||
import com.topjohnwu.magisk.ktx.startActivityWithRoot
|
||||
import com.topjohnwu.magisk.model.entity.toLog
|
||||
import com.topjohnwu.magisk.ui.surequest.SuRequestActivity
|
||||
import com.topjohnwu.magisk.utils.Utils
|
||||
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) {
|
||||
val resId = if (policy.policy == MagiskPolicy.ALLOW)
|
||||
val resId = if (policy.policy == SuPolicy.ALLOW)
|
||||
R.string.su_allow_toast
|
||||
else
|
||||
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.Const
|
||||
import com.topjohnwu.magisk.core.magiskdb.PolicyDao
|
||||
import com.topjohnwu.magisk.core.model.MagiskPolicy
|
||||
import com.topjohnwu.magisk.core.model.toPolicy
|
||||
import com.topjohnwu.magisk.core.model.su.SuPolicy
|
||||
import com.topjohnwu.magisk.core.model.su.toPolicy
|
||||
import com.topjohnwu.magisk.ktx.now
|
||||
import kotlinx.coroutines.*
|
||||
import timber.log.Timber
|
||||
@ -27,7 +27,7 @@ abstract class SuRequestHandler(
|
||||
private lateinit var output: DataOutputStream
|
||||
private lateinit var input: DataInputStream
|
||||
|
||||
protected lateinit var policy: MagiskPolicy
|
||||
protected lateinit var policy: SuPolicy
|
||||
private set
|
||||
|
||||
abstract fun onStart()
|
||||
@ -44,11 +44,11 @@ abstract class SuRequestHandler(
|
||||
|
||||
when (Config.suAutoReponse) {
|
||||
Config.Value.SU_AUTO_DENY -> {
|
||||
respond(MagiskPolicy.DENY, 0)
|
||||
respond(SuPolicy.DENY, 0)
|
||||
return true
|
||||
}
|
||||
Config.Value.SU_AUTO_ALLOW -> {
|
||||
respond(MagiskPolicy.ALLOW, 0)
|
||||
respond(SuPolicy.ALLOW, 0)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -14,10 +14,10 @@ import com.topjohnwu.magisk.core.Config
|
||||
import com.topjohnwu.magisk.core.Info
|
||||
import com.topjohnwu.magisk.data.network.GithubRawServices
|
||||
import com.topjohnwu.magisk.di.Protected
|
||||
import com.topjohnwu.magisk.events.dialog.EnvFixDialog
|
||||
import com.topjohnwu.magisk.ktx.readUri
|
||||
import com.topjohnwu.magisk.ktx.reboot
|
||||
import com.topjohnwu.magisk.ktx.withStreams
|
||||
import com.topjohnwu.magisk.model.events.dialog.EnvFixDialog
|
||||
import com.topjohnwu.magisk.utils.Utils
|
||||
import com.topjohnwu.signing.SignBoot
|
||||
import com.topjohnwu.superuser.Shell
|
||||
@ -100,6 +100,7 @@ abstract class MagiskInstallImpl : KoinComponent {
|
||||
return true
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
private fun extractZip(): Boolean {
|
||||
val arch: String
|
||||
arch = if (Build.VERSION.SDK_INT >= 21) {
|
||||
@ -130,14 +131,14 @@ abstract class MagiskInstallImpl : KoinComponent {
|
||||
}
|
||||
if (name == null && ze.name.startsWith("chromeos/"))
|
||||
name = ze.name
|
||||
if (name == null)
|
||||
continue
|
||||
val dest = if (installDir is SuFile)
|
||||
SuFile(installDir, name)
|
||||
else
|
||||
File(installDir, name)
|
||||
dest.parentFile!!.mkdirs()
|
||||
SuFileOutputStream(dest).use { zi.copyTo(it) }
|
||||
name?.also {
|
||||
val dest = if (installDir is SuFile)
|
||||
SuFile(installDir, it)
|
||||
else
|
||||
File(installDir, it)
|
||||
dest.parentFile!!.mkdirs()
|
||||
SuFileOutputStream(dest).use { s -> zi.copyTo(s) }
|
||||
} ?: continue
|
||||
}
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
|
@ -1,12 +1,12 @@
|
||||
package com.topjohnwu.magisk.data.database
|
||||
|
||||
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.withContext
|
||||
import java.util.*
|
||||
|
||||
@Database(version = 1, entities = [MagiskLog::class], exportSchema = false)
|
||||
@Database(version = 1, entities = [SuLog::class], exportSchema = false)
|
||||
abstract class SuLogDatabase : RoomDatabase() {
|
||||
|
||||
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 fetchAll(): MutableList<MagiskLog> {
|
||||
suspend fun fetchAll(): MutableList<SuLog> {
|
||||
deleteOutdated()
|
||||
return fetch()
|
||||
}
|
||||
|
||||
@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")
|
||||
protected abstract suspend fun deleteOutdated(timeout: Long = twoWeeksAgo)
|
||||
|
||||
@Insert
|
||||
abstract suspend fun insert(log: MagiskLog)
|
||||
abstract suspend fun insert(log: SuLog)
|
||||
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
package com.topjohnwu.magisk.data.repository
|
||||
|
||||
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.ktx.await
|
||||
import com.topjohnwu.magisk.model.entity.MagiskLog
|
||||
import com.topjohnwu.superuser.Shell
|
||||
|
||||
|
||||
@ -36,6 +36,6 @@ class LogRepository(
|
||||
fun clearMagiskLogs(cb: (Shell.Result) -> Unit) =
|
||||
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.getLabel
|
||||
import com.topjohnwu.magisk.ktx.packageName
|
||||
import com.topjohnwu.magisk.model.entity.HideAppInfo
|
||||
import com.topjohnwu.magisk.model.entity.HideTarget
|
||||
import com.topjohnwu.magisk.ui.hide.HideAppInfo
|
||||
import com.topjohnwu.magisk.ui.hide.HideTarget
|
||||
import com.topjohnwu.superuser.Shell
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
@ -3,6 +3,7 @@ package com.topjohnwu.magisk.databinding
|
||||
import androidx.annotation.CallSuper
|
||||
import androidx.databinding.PropertyChangeRegistry
|
||||
import androidx.databinding.ViewDataBinding
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.utils.DiffObservableList
|
||||
import com.topjohnwu.magisk.utils.ObservableHost
|
||||
@ -52,3 +53,13 @@ abstract class ComparableRvItem<in T> : RvItem() {
|
||||
abstract class ObservableItem<T> : ComparableRvItem<T>(), ObservableHost {
|
||||
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.recyclerview.widget.RecyclerView
|
||||
import com.topjohnwu.magisk.model.entity.recycler.LenientRvItem
|
||||
import me.tatarka.bindingcollectionadapter2.BindingRecyclerViewAdapter
|
||||
|
||||
class RvBindingAdapter<T : RvItem> : BindingRecyclerViewAdapter<T>() {
|
||||
@ -19,7 +18,7 @@ class RvBindingAdapter<T : RvItem> : BindingRecyclerViewAdapter<T>() {
|
||||
super.onBindBinding(binding, variableId, layoutRes, position, item)
|
||||
|
||||
when (item) {
|
||||
is LenientRvItem<*> -> {
|
||||
is LenientRvItem -> {
|
||||
val recycler = recyclerView ?: return
|
||||
item.onBindingBound(binding)
|
||||
item.onBindingBound(binding, recycler)
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.topjohnwu.magisk.model.events
|
||||
package com.topjohnwu.magisk.events
|
||||
|
||||
import android.Manifest
|
||||
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.res.Resources
|
@ -1,4 +1,4 @@
|
||||
package com.topjohnwu.magisk.model.events
|
||||
package com.topjohnwu.magisk.events
|
||||
|
||||
import android.view.ContextThemeWrapper
|
||||
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.ViewEvent
|
@ -1,4 +1,4 @@
|
||||
package com.topjohnwu.magisk.model.events.dialog
|
||||
package com.topjohnwu.magisk.events.dialog
|
||||
|
||||
import android.app.Activity
|
||||
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 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.Context
|
||||
@ -7,8 +7,8 @@ import android.content.IntentFilter
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.core.download.DownloadService
|
||||
import com.topjohnwu.magisk.model.entity.internal.Configuration.EnvFix
|
||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.Magisk
|
||||
import com.topjohnwu.magisk.model.internal.Configuration.EnvFix
|
||||
import com.topjohnwu.magisk.model.internal.DownloadSubject.Magisk
|
||||
import com.topjohnwu.magisk.view.MagiskDialog
|
||||
|
||||
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.core.Info
|
||||
import com.topjohnwu.magisk.core.download.DownloadService
|
||||
import com.topjohnwu.magisk.ktx.res
|
||||
import com.topjohnwu.magisk.model.entity.internal.Configuration
|
||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
||||
import com.topjohnwu.magisk.model.internal.Configuration
|
||||
import com.topjohnwu.magisk.model.internal.DownloadSubject
|
||||
import com.topjohnwu.magisk.view.MagiskDialog
|
||||
import com.topjohnwu.magisk.view.MarkDownWindow
|
||||
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.core.download.DownloadService
|
||||
import com.topjohnwu.magisk.core.model.module.Repo
|
||||
import com.topjohnwu.magisk.model.entity.internal.Configuration
|
||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
||||
import com.topjohnwu.magisk.model.internal.Configuration
|
||||
import com.topjohnwu.magisk.model.internal.DownloadSubject
|
||||
import com.topjohnwu.magisk.view.MagiskDialog
|
||||
|
||||
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.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.view.MagiskDialog
|
||||
@ -30,4 +30,4 @@ class SuperuserRevokeDialog(
|
||||
listenerOnSuccess = listener
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
package com.topjohnwu.magisk.model.events.dialog
|
||||
package com.topjohnwu.magisk.events.dialog
|
||||
|
||||
import android.widget.Toast
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.core.Info
|
||||
import com.topjohnwu.magisk.core.download.DownloadService
|
||||
import com.topjohnwu.magisk.model.entity.internal.Configuration
|
||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
||||
import com.topjohnwu.magisk.model.internal.Configuration
|
||||
import com.topjohnwu.magisk.model.internal.DownloadSubject
|
||||
import com.topjohnwu.magisk.utils.Utils
|
||||
import com.topjohnwu.magisk.view.MagiskDialog
|
||||
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.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.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.widget.TextView
|
||||
@ -6,9 +6,11 @@ import androidx.core.view.updateLayoutParams
|
||||
import androidx.databinding.ViewDataBinding
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||
import com.topjohnwu.magisk.databinding.LenientRvItem
|
||||
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
|
||||
|
||||
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.MagiskInstaller
|
||||
import com.topjohnwu.magisk.databinding.RvBindingAdapter
|
||||
import com.topjohnwu.magisk.events.SnackbarEvent
|
||||
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.view.Notifications
|
||||
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.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.ViewGroup
|
||||
@ -7,9 +7,6 @@ import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.databinding.ObservableItem
|
||||
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.set
|
||||
import kotlin.math.roundToInt
|
@ -1,4 +1,4 @@
|
||||
package com.topjohnwu.magisk.model.entity
|
||||
package com.topjohnwu.magisk.ui.hide
|
||||
|
||||
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.utils.currentLocale
|
||||
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 kotlinx.coroutines.Dispatchers
|
||||
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.core.Const
|
@ -5,7 +5,7 @@ import android.view.*
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.arch.BaseUIFragment
|
||||
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 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.ManagerJson
|
||||
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.packageName
|
||||
import com.topjohnwu.magisk.ktx.res
|
||||
import com.topjohnwu.magisk.model.entity.IconLink
|
||||
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.model.internal.DownloadSubject.Manager
|
||||
import com.topjohnwu.magisk.utils.set
|
||||
import com.topjohnwu.superuser.Shell
|
||||
import kotlinx.coroutines.launch
|
||||
|
@ -5,7 +5,7 @@ import androidx.lifecycle.viewModelScope
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.arch.BaseUIFragment
|
||||
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
|
||||
|
||||
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.RemoteFileService
|
||||
import com.topjohnwu.magisk.data.repository.StringRepository
|
||||
import com.topjohnwu.magisk.model.entity.internal.Configuration
|
||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
||||
import com.topjohnwu.magisk.model.events.RequestFileEvent
|
||||
import com.topjohnwu.magisk.model.events.dialog.SecondSlotWarningDialog
|
||||
import com.topjohnwu.magisk.events.RequestFileEvent
|
||||
import com.topjohnwu.magisk.events.dialog.SecondSlotWarningDialog
|
||||
import com.topjohnwu.magisk.model.internal.Configuration
|
||||
import com.topjohnwu.magisk.model.internal.DownloadSubject
|
||||
import com.topjohnwu.magisk.utils.Utils
|
||||
import com.topjohnwu.magisk.utils.set
|
||||
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 com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.core.model.su.SuLog
|
||||
import com.topjohnwu.magisk.databinding.ObservableItem
|
||||
import com.topjohnwu.magisk.ktx.timeDateFormat
|
||||
import com.topjohnwu.magisk.ktx.toTime
|
||||
import com.topjohnwu.magisk.model.entity.MagiskLog
|
||||
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
|
||||
|
||||
@ -23,9 +23,9 @@ class LogItem(val item: MagiskLog) : ObservableItem<LogItem>() {
|
||||
var isBottom = false
|
||||
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.fromPid == other.item.fromPid &&
|
||||
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.Const
|
||||
import com.topjohnwu.magisk.data.repository.LogRepository
|
||||
import com.topjohnwu.magisk.model.entity.recycler.LogItem
|
||||
import com.topjohnwu.magisk.model.entity.recycler.TextItem
|
||||
import com.topjohnwu.magisk.model.events.SnackbarEvent
|
||||
import com.topjohnwu.magisk.events.SnackbarEvent
|
||||
import com.topjohnwu.magisk.utils.set
|
||||
import com.topjohnwu.magisk.view.TextItem
|
||||
import com.topjohnwu.superuser.Shell
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
@ -34,8 +33,8 @@ class LogViewModel(
|
||||
|
||||
// --- su log
|
||||
|
||||
val items = diffListOf<LogItem>()
|
||||
val itemBinding = itemBindingOf<LogItem> {
|
||||
val items = diffListOf<LogRvItem>()
|
||||
val itemBinding = itemBindingOf<LogRvItem> {
|
||||
it.bindExtra(BR.viewModel, this)
|
||||
}
|
||||
|
||||
@ -47,7 +46,7 @@ class LogViewModel(
|
||||
override fun refresh() = viewModelScope.launch {
|
||||
consoleText = repo.fetchMagiskLogs()
|
||||
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)
|
||||
}
|
||||
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.ViewEvent
|
||||
import com.topjohnwu.magisk.databinding.FragmentModuleMd2Binding
|
||||
import com.topjohnwu.magisk.events.InstallExternalModuleEvent
|
||||
import com.topjohnwu.magisk.ktx.hideKeyboard
|
||||
import com.topjohnwu.magisk.model.events.InstallExternalModuleEvent
|
||||
import com.topjohnwu.magisk.ui.MainActivity
|
||||
import com.topjohnwu.magisk.utils.EndlessRecyclerScrollListener
|
||||
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 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.databinding.ComparableRvItem
|
||||
import com.topjohnwu.magisk.databinding.ObservableItem
|
||||
import com.topjohnwu.magisk.ui.module.ModuleViewModel
|
||||
import com.topjohnwu.magisk.utils.set
|
||||
|
||||
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.RepoByUpdatedDao
|
||||
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.reboot
|
||||
import com.topjohnwu.magisk.model.entity.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.model.internal.DownloadSubject
|
||||
import com.topjohnwu.magisk.utils.EndlessRecyclerScrollListener
|
||||
import com.topjohnwu.magisk.utils.set
|
||||
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.Intent
|
||||
import com.topjohnwu.magisk.R
|
||||
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.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.ktx.DynamicClassLoader
|
||||
import com.topjohnwu.magisk.ktx.writeTo
|
||||
import com.topjohnwu.magisk.ui.safetynet.SafetyNetResult
|
||||
import com.topjohnwu.magisk.view.MagiskDialog
|
||||
import com.topjohnwu.magisk.view.MarkDownWindow
|
||||
import com.topjohnwu.superuser.Shell
|
||||
import dalvik.system.DexFile
|
||||
import kotlinx.coroutines.CancellationException
|
||||
@ -32,6 +23,7 @@ import java.io.File
|
||||
import java.io.IOException
|
||||
import java.lang.reflect.InvocationHandler
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
class CheckSafetyNetEvent(
|
||||
private val callback: (SafetyNetResult) -> Unit = {}
|
||||
) : ViewEventWithScope(), ContextExecutor, KoinComponent, SafetyNetHelper.Callback {
|
||||
@ -78,8 +70,10 @@ class CheckSafetyNetEvent(
|
||||
|
||||
val helper = helperClass
|
||||
.getMethod("get", Class::class.java, Context::class.java, Any::class.java)
|
||||
.invoke(null, SafetyNetHelper::class.java,
|
||||
context, this@CheckSafetyNetEvent) as SafetyNetHelper
|
||||
.invoke(
|
||||
null, SafetyNetHelper::class.java,
|
||||
context, this@CheckSafetyNetEvent
|
||||
) as SafetyNetHelper
|
||||
|
||||
if (helper.version < Const.SNET_EXT_VER)
|
||||
throw Exception()
|
||||
@ -136,66 +130,3 @@ class CheckSafetyNetEvent(
|
||||
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
|
||||
|
@ -4,7 +4,6 @@ import androidx.databinding.Bindable
|
||||
import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.arch.BaseViewModel
|
||||
import com.topjohnwu.magisk.model.events.CheckSafetyNetEvent
|
||||
import com.topjohnwu.magisk.ui.safetynet.SafetyNetState.*
|
||||
import com.topjohnwu.magisk.utils.set
|
||||
import org.json.JSONObject
|
||||
@ -54,7 +53,7 @@ class SafetynetViewModel : BaseViewModel() {
|
||||
|
||||
private fun attest() {
|
||||
currentState = LOADING
|
||||
CheckSafetyNetEvent() {
|
||||
CheckSafetyNetEvent {
|
||||
resolveResponse(it)
|
||||
}.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.res.Resources
|
||||
@ -16,7 +16,7 @@ import com.topjohnwu.magisk.view.MagiskDialog
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.get
|
||||
|
||||
sealed class SettingsItem : ObservableItem<SettingsItem>() {
|
||||
sealed class BaseSettingsItem : ObservableItem<BaseSettingsItem>() {
|
||||
|
||||
override val layoutRes get() = R.layout.item_settings
|
||||
|
||||
@ -46,19 +46,19 @@ sealed class SettingsItem : ObservableItem<SettingsItem>() {
|
||||
|
||||
open fun refresh() {}
|
||||
|
||||
override fun itemSameAs(other: SettingsItem) = this === other
|
||||
override fun contentSameAs(other: SettingsItem) = itemSameAs(other)
|
||||
override fun itemSameAs(other: BaseSettingsItem) = this === other
|
||||
override fun contentSameAs(other: BaseSettingsItem) = itemSameAs(other)
|
||||
|
||||
// ---
|
||||
|
||||
interface Callback {
|
||||
fun onItemPressed(view: View, item: SettingsItem, callback: () -> Unit = {})
|
||||
fun onItemChanged(view: View, item: SettingsItem)
|
||||
fun onItemPressed(view: View, item: BaseSettingsItem, callback: () -> Unit = {})
|
||||
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
|
||||
@ -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
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ import com.topjohnwu.magisk.databinding.DialogSettingsAppNameBinding
|
||||
import com.topjohnwu.magisk.databinding.DialogSettingsDownloadPathBinding
|
||||
import com.topjohnwu.magisk.databinding.DialogSettingsUpdateChannelBinding
|
||||
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.asTransitive
|
||||
import com.topjohnwu.magisk.utils.set
|
||||
@ -30,11 +29,11 @@ import java.io.File
|
||||
|
||||
// --- Customization
|
||||
|
||||
object Customization : SettingsItem.Section() {
|
||||
object Customization : BaseSettingsItem.Section() {
|
||||
override val title = R.string.settings_customization.asTransitive()
|
||||
}
|
||||
|
||||
object Language : SettingsItem.Selector() {
|
||||
object Language : BaseSettingsItem.Selector() {
|
||||
override var value = -1
|
||||
set(value) = setV(value, field, { field = 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 title = R.string.section_theme.asTransitive()
|
||||
}
|
||||
|
||||
// --- Manager
|
||||
|
||||
object Manager : SettingsItem.Section() {
|
||||
object Manager : BaseSettingsItem.Section() {
|
||||
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 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 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 description = R.string.settings_restore_manager_summary.asTransitive()
|
||||
}
|
||||
@ -108,7 +107,7 @@ object Restore : SettingsItem.Blank() {
|
||||
fun HideOrRestore() =
|
||||
if (get<Context>().packageName == BuildConfig.APPLICATION_ID) Hide else Restore
|
||||
|
||||
object DownloadPath : SettingsItem.Input() {
|
||||
object DownloadPath : BaseSettingsItem.Input() {
|
||||
override var value = Config.downloadPath
|
||||
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
|
||||
}
|
||||
|
||||
object UpdateChannel : SettingsItem.Selector() {
|
||||
object UpdateChannel : BaseSettingsItem.Selector() {
|
||||
override var value = Config.updateChannel
|
||||
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
|
||||
}
|
||||
|
||||
object UpdateChannelUrl : SettingsItem.Input() {
|
||||
object UpdateChannelUrl : BaseSettingsItem.Input() {
|
||||
override val title = R.string.settings_update_custom.asTransitive()
|
||||
override var value = Config.customChannelUrl
|
||||
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
|
||||
}
|
||||
|
||||
object UpdateChecker : SettingsItem.Toggle() {
|
||||
object UpdateChecker : BaseSettingsItem.Toggle() {
|
||||
override val title = R.string.settings_check_update_title.asTransitive()
|
||||
override val description = R.string.settings_check_update_summary.asTransitive()
|
||||
override var value = Config.checkUpdate
|
||||
@ -173,12 +172,12 @@ object UpdateChecker : SettingsItem.Toggle() {
|
||||
}
|
||||
|
||||
// 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 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 var value = Config.suBiometric
|
||||
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 description = R.string.settings_su_reauth_summary.asTransitive()
|
||||
override var value = Config.suReAuth
|
||||
@ -206,11 +205,11 @@ object Reauthenticate : SettingsItem.Toggle() {
|
||||
|
||||
// --- Magisk
|
||||
|
||||
object Magisk : SettingsItem.Section() {
|
||||
object Magisk : BaseSettingsItem.Section() {
|
||||
override val title = R.string.magisk.asTransitive()
|
||||
}
|
||||
|
||||
object MagiskHide : SettingsItem.Toggle() {
|
||||
object MagiskHide : BaseSettingsItem.Toggle() {
|
||||
override val title = R.string.magiskhide.asTransitive()
|
||||
override val description = R.string.settings_magiskhide_summary.asTransitive()
|
||||
override var value = Config.magiskHide
|
||||
@ -225,11 +224,11 @@ object MagiskHide : SettingsItem.Toggle() {
|
||||
|
||||
// --- Superuser
|
||||
|
||||
object Superuser : SettingsItem.Section() {
|
||||
object Superuser : BaseSettingsItem.Section() {
|
||||
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 entryRes = R.array.su_access
|
||||
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 entryRes = R.array.multiuser_mode
|
||||
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 entryRes = R.array.namespace
|
||||
override val entryValRes = R.array.value_array
|
||||
@ -272,7 +271,7 @@ object MountNamespaceMode : SettingsItem.Selector() {
|
||||
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 entryRes = R.array.auto_response
|
||||
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 entryRes = R.array.request_timeout
|
||||
override val entryValRes = R.array.request_timeout_value
|
||||
@ -297,7 +296,7 @@ object RequestTimeout : SettingsItem.Selector() {
|
||||
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 entryRes = R.array.su_notification
|
||||
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.utils.PatchAPK
|
||||
import com.topjohnwu.magisk.data.database.RepoDao
|
||||
import com.topjohnwu.magisk.model.entity.internal.Configuration
|
||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
||||
import com.topjohnwu.magisk.model.entity.recycler.SettingsItem
|
||||
import com.topjohnwu.magisk.model.events.RecreateEvent
|
||||
import com.topjohnwu.magisk.model.events.dialog.BiometricDialog
|
||||
import com.topjohnwu.magisk.events.RecreateEvent
|
||||
import com.topjohnwu.magisk.events.dialog.BiometricDialog
|
||||
import com.topjohnwu.magisk.model.internal.Configuration
|
||||
import com.topjohnwu.magisk.model.internal.DownloadSubject
|
||||
import com.topjohnwu.magisk.utils.Utils
|
||||
import com.topjohnwu.superuser.Shell
|
||||
import kotlinx.coroutines.launch
|
||||
@ -27,10 +26,10 @@ import org.koin.core.get
|
||||
|
||||
class SettingsViewModel(
|
||||
private val repositoryDao: RepoDao
|
||||
) : BaseViewModel(), SettingsItem.Callback {
|
||||
) : BaseViewModel(), BaseSettingsItem.Callback {
|
||||
|
||||
val adapter = adapterOf<SettingsItem>()
|
||||
val itemBinding = itemBindingOf<SettingsItem> { it.bindExtra(BR.callback, this) }
|
||||
val adapter = adapterOf<BaseSettingsItem>()
|
||||
val itemBinding = itemBindingOf<BaseSettingsItem> { it.bindExtra(BR.callback, this) }
|
||||
val items = diffListOf(createItems())
|
||||
|
||||
init {
|
||||
@ -39,7 +38,7 @@ class SettingsViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
private fun createItems(): List<SettingsItem> {
|
||||
private fun createItems(): List<BaseSettingsItem> {
|
||||
// Customization
|
||||
val list = mutableListOf(
|
||||
Customization,
|
||||
@ -90,7 +89,7 @@ class SettingsViewModel(
|
||||
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 Biometrics -> authenticate(callback)
|
||||
is Theme -> SettingsFragmentDirections.actionSettingsFragmentToThemeFragment().publish()
|
||||
@ -100,7 +99,7 @@ class SettingsViewModel(
|
||||
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 UpdateChannel -> openUrlIfNecessary(view)
|
||||
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 androidx.databinding.Bindable
|
||||
import com.topjohnwu.magisk.BR
|
||||
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.ui.superuser.SuperuserViewModel
|
||||
import com.topjohnwu.magisk.utils.set
|
||||
|
||||
class PolicyItem(
|
||||
val item: MagiskPolicy,
|
||||
class PolicyRvItem(
|
||||
val item: SuPolicy,
|
||||
val icon: Drawable,
|
||||
val viewModel: SuperuserViewModel
|
||||
) : ObservableItem<PolicyItem>() {
|
||||
) : ObservableItem<PolicyRvItem>() {
|
||||
override val layoutRes = R.layout.item_policy_md2
|
||||
|
||||
@get:Bindable
|
||||
@ -21,7 +20,7 @@ class PolicyItem(
|
||||
set(value) = set(value, field, { field = it }, BR.expanded)
|
||||
|
||||
// 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)
|
||||
|
||||
// This property binds with the UI state
|
||||
@ -44,7 +43,7 @@ class PolicyItem(
|
||||
|
||||
private val updatedPolicy
|
||||
get() = item.copy(
|
||||
policy = if (policyState) MagiskPolicy.ALLOW else MagiskPolicy.DENY,
|
||||
policy = if (policyState) SuPolicy.ALLOW else SuPolicy.DENY,
|
||||
notification = shouldNotify,
|
||||
logging = shouldLog
|
||||
)
|
||||
@ -65,7 +64,7 @@ class PolicyItem(
|
||||
viewModel.deletePressed(this)
|
||||
}
|
||||
|
||||
override fun contentSameAs(other: PolicyItem) = itemSameAs(other)
|
||||
override fun itemSameAs(other: PolicyItem) = item.uid == other.item.uid
|
||||
override fun contentSameAs(other: PolicyRvItem) = itemSameAs(other)
|
||||
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.databinding.ComparableRvItem
|
||||
@ -10,4 +10,4 @@ class SpinnerRvItem(val item: String) : ComparableRvItem<SpinnerRvItem>() {
|
||||
override fun contentSameAs(other: SpinnerRvItem) = itemSameAs(other)
|
||||
override fun itemSameAs(other: SpinnerRvItem) = item == other.item
|
||||
|
||||
}
|
||||
}
|
@ -11,16 +11,15 @@ import com.topjohnwu.magisk.arch.adapterOf
|
||||
import com.topjohnwu.magisk.arch.diffListOf
|
||||
import com.topjohnwu.magisk.arch.itemBindingOf
|
||||
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.currentLocale
|
||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||
import com.topjohnwu.magisk.model.entity.recycler.PolicyItem
|
||||
import com.topjohnwu.magisk.model.entity.recycler.TappableHeadlineItem
|
||||
import com.topjohnwu.magisk.model.entity.recycler.TextItem
|
||||
import com.topjohnwu.magisk.model.events.SnackbarEvent
|
||||
import com.topjohnwu.magisk.model.events.dialog.BiometricDialog
|
||||
import com.topjohnwu.magisk.model.events.dialog.SuperuserRevokeDialog
|
||||
import com.topjohnwu.magisk.events.SnackbarEvent
|
||||
import com.topjohnwu.magisk.events.dialog.BiometricDialog
|
||||
import com.topjohnwu.magisk.events.dialog.SuperuserRevokeDialog
|
||||
import com.topjohnwu.magisk.view.TappableHeadlineItem
|
||||
import com.topjohnwu.magisk.view.TextItem
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
@ -34,7 +33,7 @@ class SuperuserViewModel(
|
||||
|
||||
private val itemNoData = TextItem(R.string.superuser_policy_none)
|
||||
|
||||
private val itemsPolicies = diffListOf<PolicyItem>()
|
||||
private val itemsPolicies = diffListOf<PolicyRvItem>()
|
||||
private val itemsHelpers = ObservableArrayList<TextItem>()
|
||||
|
||||
val adapter = adapterOf<ComparableRvItem<*>>()
|
||||
@ -52,7 +51,7 @@ class SuperuserViewModel(
|
||||
state = State.LOADING
|
||||
val (policies, diff) = withContext(Dispatchers.Default) {
|
||||
val policies = db.fetchAll {
|
||||
PolicyItem(it, it.applicationInfo.loadIcon(packageManager), this@SuperuserViewModel)
|
||||
PolicyRvItem(it, it.applicationInfo.loadIcon(packageManager), this@SuperuserViewModel)
|
||||
}.sortedWith(compareBy(
|
||||
{ it.item.appName.toLowerCase(currentLocale) },
|
||||
{ it.item.packageName }
|
||||
@ -77,7 +76,7 @@ class SuperuserViewModel(
|
||||
private fun hidePressed() =
|
||||
SuperuserFragmentDirections.actionSuperuserFragmentToHideFragment().publish()
|
||||
|
||||
fun deletePressed(item: PolicyItem) {
|
||||
fun deletePressed(item: PolicyRvItem) {
|
||||
fun updateState() = viewModelScope.launch {
|
||||
db.delete(item.item.uid)
|
||||
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)
|
||||
val str = when {
|
||||
isLogging -> when {
|
||||
@ -115,16 +114,16 @@ class SuperuserViewModel(
|
||||
SnackbarEvent(resources.getString(str, policy.appName)).publish()
|
||||
}
|
||||
|
||||
fun togglePolicy(item: PolicyItem, enable: Boolean) {
|
||||
fun togglePolicy(item: PolicyRvItem, enable: Boolean) {
|
||||
fun updateState() {
|
||||
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)
|
||||
|
||||
viewModelScope.launch {
|
||||
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
|
||||
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.core.Config
|
||||
import com.topjohnwu.magisk.core.magiskdb.PolicyDao
|
||||
import com.topjohnwu.magisk.core.model.MagiskPolicy.Companion.ALLOW
|
||||
import com.topjohnwu.magisk.core.model.MagiskPolicy.Companion.DENY
|
||||
import com.topjohnwu.magisk.core.model.su.SuPolicy.Companion.ALLOW
|
||||
import com.topjohnwu.magisk.core.model.su.SuPolicy.Companion.DENY
|
||||
import com.topjohnwu.magisk.core.su.SuRequestHandler
|
||||
import com.topjohnwu.magisk.core.utils.BiometricHelper
|
||||
import com.topjohnwu.magisk.model.entity.recycler.SpinnerRvItem
|
||||
import com.topjohnwu.magisk.model.events.DieEvent
|
||||
import com.topjohnwu.magisk.events.DieEvent
|
||||
import com.topjohnwu.magisk.ui.superuser.SpinnerRvItem
|
||||
import com.topjohnwu.magisk.utils.set
|
||||
import com.topjohnwu.superuser.internal.UiThreadHandler
|
||||
import kotlinx.coroutines.launch
|
||||
|
@ -1,9 +1,9 @@
|
||||
package com.topjohnwu.magisk.ui.theme
|
||||
|
||||
import com.topjohnwu.magisk.arch.BaseViewModel
|
||||
import com.topjohnwu.magisk.model.entity.recycler.TappableHeadlineItem
|
||||
import com.topjohnwu.magisk.model.events.RecreateEvent
|
||||
import com.topjohnwu.magisk.model.events.dialog.DarkThemeDialog
|
||||
import com.topjohnwu.magisk.events.RecreateEvent
|
||||
import com.topjohnwu.magisk.events.dialog.DarkThemeDialog
|
||||
import com.topjohnwu.magisk.view.TappableHeadlineItem
|
||||
|
||||
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.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.databinding.ComparableRvItem
|
@ -9,7 +9,7 @@
|
||||
|
||||
<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
|
||||
name="viewModel"
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
<variable
|
||||
name="item"
|
||||
type="com.topjohnwu.magisk.model.entity.recycler.ConsoleItem" />
|
||||
type="com.topjohnwu.magisk.ui.flash.ConsoleItem" />
|
||||
|
||||
</data>
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
<variable
|
||||
name="item"
|
||||
type="com.topjohnwu.magisk.model.entity.DeveloperItem" />
|
||||
type="com.topjohnwu.magisk.ui.home.DeveloperItem" />
|
||||
|
||||
<variable
|
||||
name="viewModel"
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
<variable
|
||||
name="item"
|
||||
type="com.topjohnwu.magisk.model.entity.recycler.HideItem" />
|
||||
type="com.topjohnwu.magisk.ui.hide.HideItem" />
|
||||
|
||||
<variable
|
||||
name="viewModel"
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
<variable
|
||||
name="item"
|
||||
type="com.topjohnwu.magisk.model.entity.recycler.HideProcessItem" />
|
||||
type="com.topjohnwu.magisk.ui.hide.HideProcessItem" />
|
||||
|
||||
<variable
|
||||
name="viewModel"
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
<variable
|
||||
name="item"
|
||||
type="com.topjohnwu.magisk.model.entity.IconLink" />
|
||||
type="com.topjohnwu.magisk.ui.home.IconLink" />
|
||||
|
||||
<variable
|
||||
name="viewModel"
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
<variable
|
||||
name="item"
|
||||
type="com.topjohnwu.magisk.model.entity.recycler.LogItem" />
|
||||
type="com.topjohnwu.magisk.ui.log.LogRvItem" />
|
||||
|
||||
<variable
|
||||
name="viewModel"
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
<variable
|
||||
name="item"
|
||||
type="com.topjohnwu.magisk.model.entity.recycler.InstallModule" />
|
||||
type="com.topjohnwu.magisk.ui.module.InstallModule" />
|
||||
|
||||
<variable
|
||||
name="viewModel"
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
<variable
|
||||
name="item"
|
||||
type="com.topjohnwu.magisk.model.entity.recycler.ModuleItem" />
|
||||
type="com.topjohnwu.magisk.ui.module.ModuleItem" />
|
||||
|
||||
<variable
|
||||
name="viewModel"
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
<variable
|
||||
name="item"
|
||||
type="com.topjohnwu.magisk.model.entity.recycler.PolicyItem" />
|
||||
type="com.topjohnwu.magisk.ui.superuser.PolicyRvItem" />
|
||||
|
||||
</data>
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
<variable
|
||||
name="item"
|
||||
type="com.topjohnwu.magisk.model.entity.recycler.RepoItem" />
|
||||
type="com.topjohnwu.magisk.ui.module.RepoItem" />
|
||||
|
||||
<variable
|
||||
name="viewModel"
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
<variable
|
||||
name="item"
|
||||
type="com.topjohnwu.magisk.model.entity.recycler.SectionTitle" />
|
||||
type="com.topjohnwu.magisk.ui.module.SectionTitle" />
|
||||
|
||||
<variable
|
||||
name="viewModel"
|
||||
|
@ -7,11 +7,11 @@
|
||||
|
||||
<variable
|
||||
name="item"
|
||||
type="com.topjohnwu.magisk.model.entity.recycler.SettingsItem" />
|
||||
type="com.topjohnwu.magisk.ui.settings.BaseSettingsItem" />
|
||||
|
||||
<variable
|
||||
name="callback"
|
||||
type="com.topjohnwu.magisk.model.entity.recycler.SettingsItem.Callback" />
|
||||
type="com.topjohnwu.magisk.ui.settings.BaseSettingsItem.Callback" />
|
||||
|
||||
</data>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
<variable
|
||||
name="item"
|
||||
type="com.topjohnwu.magisk.model.entity.recycler.SettingsItem" />
|
||||
type="com.topjohnwu.magisk.ui.settings.BaseSettingsItem" />
|
||||
|
||||
</data>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
<variable
|
||||
name="item"
|
||||
type="com.topjohnwu.magisk.model.entity.recycler.SpinnerRvItem" />
|
||||
type="com.topjohnwu.magisk.ui.superuser.SpinnerRvItem" />
|
||||
|
||||
</data>
|
||||
|
||||
@ -25,4 +25,4 @@
|
||||
android:textAlignment="inherit"
|
||||
tools:text="Forever" />
|
||||
|
||||
</layout>
|
||||
</layout>
|
||||
|
@ -7,11 +7,11 @@
|
||||
|
||||
<variable
|
||||
name="item"
|
||||
type="com.topjohnwu.magisk.model.entity.recycler.TappableHeadlineItem" />
|
||||
type="com.topjohnwu.magisk.view.TappableHeadlineItem" />
|
||||
|
||||
<variable
|
||||
name="listener"
|
||||
type="com.topjohnwu.magisk.model.entity.recycler.TappableHeadlineItem.Listener" />
|
||||
type="com.topjohnwu.magisk.view.TappableHeadlineItem.Listener" />
|
||||
|
||||
</data>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
<variable
|
||||
name="item"
|
||||
type="com.topjohnwu.magisk.model.entity.recycler.TextItem" />
|
||||
type="com.topjohnwu.magisk.view.TextItem" />
|
||||
|
||||
</data>
|
||||
|
||||
@ -19,4 +19,4 @@
|
||||
android:textAppearance="@style/AppearanceFoundation.Tiny.Variant"
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
|
||||
</layout>
|
||||
</layout>
|
||||
|
Loading…
Reference in New Issue
Block a user