Updated policy items so listeners are not indirectly set to them and kept out of the instance of the parent object
This commit is contained in:
parent
ad80804461
commit
ce693aa5e9
@ -11,6 +11,6 @@ import org.koin.dsl.module
|
|||||||
val viewModelModules = module {
|
val viewModelModules = module {
|
||||||
viewModel { MainViewModel() }
|
viewModel { MainViewModel() }
|
||||||
viewModel { HomeViewModel(get(), get()) }
|
viewModel { HomeViewModel(get(), get()) }
|
||||||
viewModel { SuperuserViewModel(get(), get(), get()) }
|
viewModel { SuperuserViewModel(get(), get(), get(), get()) }
|
||||||
viewModel { HideViewModel(get(), get()) }
|
viewModel { HideViewModel(get(), get()) }
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,14 @@ package com.topjohnwu.magisk.model.entity.recycler
|
|||||||
|
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import com.skoumal.teanity.databinding.ComparableRvItem
|
import com.skoumal.teanity.databinding.ComparableRvItem
|
||||||
|
import com.skoumal.teanity.extensions.addOnPropertyChangedCallback
|
||||||
|
import com.skoumal.teanity.rxbus.RxBus
|
||||||
import com.skoumal.teanity.util.KObservableField
|
import com.skoumal.teanity.util.KObservableField
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.model.entity.Policy
|
import com.topjohnwu.magisk.model.entity.Policy
|
||||||
|
import com.topjohnwu.magisk.model.events.PolicyEnableEvent
|
||||||
|
import com.topjohnwu.magisk.model.events.PolicyUpdateEvent
|
||||||
|
import com.topjohnwu.magisk.utils.inject
|
||||||
import com.topjohnwu.magisk.utils.toggle
|
import com.topjohnwu.magisk.utils.toggle
|
||||||
|
|
||||||
class PolicyRvItem(val item: Policy, val icon: Drawable) : ComparableRvItem<PolicyRvItem>() {
|
class PolicyRvItem(val item: Policy, val icon: Drawable) : ComparableRvItem<PolicyRvItem>() {
|
||||||
@ -18,6 +23,25 @@ class PolicyRvItem(val item: Policy, val icon: Drawable) : ComparableRvItem<Poli
|
|||||||
|
|
||||||
fun toggle() = isExpanded.toggle()
|
fun toggle() = isExpanded.toggle()
|
||||||
|
|
||||||
|
private val rxBus: RxBus by inject()
|
||||||
|
|
||||||
|
init {
|
||||||
|
isEnabled.addOnPropertyChangedCallback {
|
||||||
|
it ?: return@addOnPropertyChangedCallback
|
||||||
|
rxBus.post(PolicyEnableEvent(this@PolicyRvItem, it))
|
||||||
|
}
|
||||||
|
shouldNotify.addOnPropertyChangedCallback {
|
||||||
|
it ?: return@addOnPropertyChangedCallback
|
||||||
|
item.notification = it
|
||||||
|
rxBus.post(PolicyUpdateEvent.Notification(this@PolicyRvItem))
|
||||||
|
}
|
||||||
|
shouldLog.addOnPropertyChangedCallback {
|
||||||
|
it ?: return@addOnPropertyChangedCallback
|
||||||
|
item.logging = it
|
||||||
|
rxBus.post(PolicyUpdateEvent.Log(this@PolicyRvItem))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun contentSameAs(other: PolicyRvItem): Boolean = itemSameAs(other)
|
override fun contentSameAs(other: PolicyRvItem): Boolean = itemSameAs(other)
|
||||||
override fun itemSameAs(other: PolicyRvItem): Boolean = item.uid == other.item.uid
|
override fun itemSameAs(other: PolicyRvItem): Boolean = item.uid == other.item.uid
|
||||||
}
|
}
|
@ -2,5 +2,12 @@ package com.topjohnwu.magisk.model.events
|
|||||||
|
|
||||||
import com.skoumal.teanity.rxbus.RxBus
|
import com.skoumal.teanity.rxbus.RxBus
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.HideProcessRvItem
|
import com.topjohnwu.magisk.model.entity.recycler.HideProcessRvItem
|
||||||
|
import com.topjohnwu.magisk.model.entity.recycler.PolicyRvItem
|
||||||
|
|
||||||
class HideProcessEvent(val item: HideProcessRvItem) : RxBus.Event
|
class HideProcessEvent(val item: HideProcessRvItem) : RxBus.Event
|
||||||
|
|
||||||
|
class PolicyEnableEvent(val item: PolicyRvItem, val enable: Boolean) : RxBus.Event
|
||||||
|
sealed class PolicyUpdateEvent(val item: PolicyRvItem) : RxBus.Event {
|
||||||
|
class Notification(item: PolicyRvItem) : PolicyUpdateEvent(item)
|
||||||
|
class Log(item: PolicyRvItem) : PolicyUpdateEvent(item)
|
||||||
|
}
|
||||||
|
@ -3,9 +3,9 @@ package com.topjohnwu.magisk.ui.superuser
|
|||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import com.skoumal.teanity.databinding.ComparableRvItem
|
import com.skoumal.teanity.databinding.ComparableRvItem
|
||||||
import com.skoumal.teanity.extensions.addOnPropertyChangedCallback
|
|
||||||
import com.skoumal.teanity.extensions.applySchedulers
|
import com.skoumal.teanity.extensions.applySchedulers
|
||||||
import com.skoumal.teanity.extensions.subscribeK
|
import com.skoumal.teanity.extensions.subscribeK
|
||||||
|
import com.skoumal.teanity.rxbus.RxBus
|
||||||
import com.skoumal.teanity.util.DiffObservableList
|
import com.skoumal.teanity.util.DiffObservableList
|
||||||
import com.skoumal.teanity.viewevents.SnackbarEvent
|
import com.skoumal.teanity.viewevents.SnackbarEvent
|
||||||
import com.topjohnwu.magisk.BR
|
import com.topjohnwu.magisk.BR
|
||||||
@ -13,6 +13,8 @@ import com.topjohnwu.magisk.R
|
|||||||
import com.topjohnwu.magisk.data.database.MagiskDB
|
import com.topjohnwu.magisk.data.database.MagiskDB
|
||||||
import com.topjohnwu.magisk.model.entity.Policy
|
import com.topjohnwu.magisk.model.entity.Policy
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.PolicyRvItem
|
import com.topjohnwu.magisk.model.entity.recycler.PolicyRvItem
|
||||||
|
import com.topjohnwu.magisk.model.events.PolicyEnableEvent
|
||||||
|
import com.topjohnwu.magisk.model.events.PolicyUpdateEvent
|
||||||
import com.topjohnwu.magisk.ui.base.MagiskViewModel
|
import com.topjohnwu.magisk.ui.base.MagiskViewModel
|
||||||
import com.topjohnwu.magisk.utils.FingerprintHelper
|
import com.topjohnwu.magisk.utils.FingerprintHelper
|
||||||
import com.topjohnwu.magisk.utils.toggle
|
import com.topjohnwu.magisk.utils.toggle
|
||||||
@ -24,7 +26,8 @@ import me.tatarka.bindingcollectionadapter2.ItemBinding
|
|||||||
class SuperuserViewModel(
|
class SuperuserViewModel(
|
||||||
private val database: MagiskDB,
|
private val database: MagiskDB,
|
||||||
private val packageManager: PackageManager,
|
private val packageManager: PackageManager,
|
||||||
private val resources: Resources
|
private val resources: Resources,
|
||||||
|
rxBus: RxBus
|
||||||
) : MagiskViewModel() {
|
) : MagiskViewModel() {
|
||||||
|
|
||||||
val items = DiffObservableList(ComparableRvItem.callback)
|
val items = DiffObservableList(ComparableRvItem.callback)
|
||||||
@ -36,13 +39,20 @@ class SuperuserViewModel(
|
|||||||
private var ignoreNext: PolicyRvItem? = null
|
private var ignoreNext: PolicyRvItem? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
rxBus.register<PolicyEnableEvent>()
|
||||||
|
.subscribeK { togglePolicy(it.item, it.enable) }
|
||||||
|
.add()
|
||||||
|
rxBus.register<PolicyUpdateEvent>()
|
||||||
|
.subscribeK { updatePolicy(it) }
|
||||||
|
.add()
|
||||||
|
|
||||||
updatePolicies()
|
updatePolicies()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updatePolicies() {
|
fun updatePolicies() {
|
||||||
Single.fromCallable { database.policyList }
|
Single.fromCallable { database.policyList }
|
||||||
.flattenAsFlowable { it }
|
.flattenAsFlowable { it }
|
||||||
.map { PolicyRvItem(it, it.info.loadIcon(packageManager)).setListeners() }
|
.map { PolicyRvItem(it, it.info.loadIcon(packageManager)) }
|
||||||
.toList()
|
.toList()
|
||||||
.applySchedulers()
|
.applySchedulers()
|
||||||
.applyViewModel(this)
|
.applyViewModel(this)
|
||||||
@ -70,64 +80,48 @@ class SuperuserViewModel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun PolicyRvItem.setListeners() = apply {
|
private fun updatePolicy(it: PolicyUpdateEvent) = when (it) {
|
||||||
isEnabled.addOnPropertyChangedCallback {
|
is PolicyUpdateEvent.Notification -> updatePolicy(it.item) {
|
||||||
it ?: return@addOnPropertyChangedCallback
|
val textId = if (it.logging) R.string.su_snack_notif_on else R.string.su_snack_notif_off
|
||||||
|
val text = resources.getString(textId).format(it.appName)
|
||||||
if (ignoreNext == this) {
|
SnackbarEvent(text).publish()
|
||||||
ignoreNext = null
|
|
||||||
return@addOnPropertyChangedCallback
|
|
||||||
}
|
|
||||||
|
|
||||||
fun updateState() {
|
|
||||||
item.policy = if (it) Policy.ALLOW else Policy.DENY
|
|
||||||
|
|
||||||
updatePolicy(item)
|
|
||||||
.map { it.policy == Policy.ALLOW }
|
|
||||||
.subscribeK {
|
|
||||||
val textId = if (it) R.string.su_snack_grant else R.string.su_snack_deny
|
|
||||||
val text = resources.getString(textId).format(item.appName)
|
|
||||||
SnackbarEvent(text).publish()
|
|
||||||
}
|
|
||||||
.add()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FingerprintHelper.useFingerprint()) {
|
|
||||||
withView {
|
|
||||||
FingerprintAuthDialog(this, { updateState() }, {
|
|
||||||
ignoreNext = this@setListeners
|
|
||||||
isEnabled.toggle()
|
|
||||||
}).show()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
updateState()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
shouldNotify.addOnPropertyChangedCallback {
|
is PolicyUpdateEvent.Log -> updatePolicy(it.item) {
|
||||||
it ?: return@addOnPropertyChangedCallback
|
val textId =
|
||||||
item.notification = it
|
if (it.notification) R.string.su_snack_log_on else R.string.su_snack_log_off
|
||||||
|
val text = resources.getString(textId).format(it.appName)
|
||||||
|
SnackbarEvent(text).publish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
updatePolicy(item)
|
private fun updatePolicy(item: PolicyRvItem, onSuccess: (Policy) -> Unit) =
|
||||||
.map { it.notification }
|
updatePolicy(item.item)
|
||||||
|
.subscribeK { onSuccess(it) }
|
||||||
|
.add()
|
||||||
|
|
||||||
|
private fun togglePolicy(item: PolicyRvItem, enable: Boolean) {
|
||||||
|
fun updateState() {
|
||||||
|
item.item.policy = if (enable) Policy.ALLOW else Policy.DENY
|
||||||
|
|
||||||
|
updatePolicy(item.item)
|
||||||
|
.map { it.policy == Policy.ALLOW }
|
||||||
.subscribeK {
|
.subscribeK {
|
||||||
val textId = if (it) R.string.su_snack_notif_on else R.string.su_snack_notif_off
|
val textId = if (it) R.string.su_snack_grant else R.string.su_snack_deny
|
||||||
val text = resources.getString(textId).format(item.appName)
|
val text = resources.getString(textId).format(item.item.appName)
|
||||||
SnackbarEvent(text).publish()
|
SnackbarEvent(text).publish()
|
||||||
}
|
}
|
||||||
.add()
|
.add()
|
||||||
}
|
}
|
||||||
shouldLog.addOnPropertyChangedCallback {
|
|
||||||
it ?: return@addOnPropertyChangedCallback
|
|
||||||
item.logging = it
|
|
||||||
|
|
||||||
updatePolicy(item)
|
if (FingerprintHelper.useFingerprint()) {
|
||||||
.map { it.logging }
|
withView {
|
||||||
.subscribeK {
|
FingerprintAuthDialog(this, { updateState() }, {
|
||||||
val textId = if (it) R.string.su_snack_log_on else R.string.su_snack_log_off
|
ignoreNext = item
|
||||||
val text = resources.getString(textId).format(item.appName)
|
item.isEnabled.toggle()
|
||||||
SnackbarEvent(text).publish()
|
}).show()
|
||||||
}
|
}
|
||||||
.add()
|
} else {
|
||||||
|
updateState()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user