Commit ce693aa5 authored by Viktor De Pasquale's avatar Viktor De Pasquale

Updated policy items so listeners are not indirectly set to them and kept out...

Updated policy items so listeners are not indirectly set to them and kept out of the instance of the parent object
parent ad808044
......@@ -11,6 +11,6 @@ import org.koin.dsl.module
val viewModelModules = module {
viewModel { MainViewModel() }
viewModel { HomeViewModel(get(), get()) }
viewModel { SuperuserViewModel(get(), get(), get()) }
viewModel { SuperuserViewModel(get(), get(), get(), get()) }
viewModel { HideViewModel(get(), get()) }
}
......@@ -2,9 +2,14 @@ package com.topjohnwu.magisk.model.entity.recycler
import android.graphics.drawable.Drawable
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.topjohnwu.magisk.R
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
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()
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 itemSameAs(other: PolicyRvItem): Boolean = item.uid == other.item.uid
}
\ No newline at end of file
......@@ -2,5 +2,12 @@ package com.topjohnwu.magisk.model.events
import com.skoumal.teanity.rxbus.RxBus
import com.topjohnwu.magisk.model.entity.recycler.HideProcessRvItem
import com.topjohnwu.magisk.model.entity.recycler.PolicyRvItem
class HideProcessEvent(val item: HideProcessRvItem) : RxBus.Event
\ No newline at end of file
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.res.Resources
import com.skoumal.teanity.databinding.ComparableRvItem
import com.skoumal.teanity.extensions.addOnPropertyChangedCallback
import com.skoumal.teanity.extensions.applySchedulers
import com.skoumal.teanity.extensions.subscribeK
import com.skoumal.teanity.rxbus.RxBus
import com.skoumal.teanity.util.DiffObservableList
import com.skoumal.teanity.viewevents.SnackbarEvent
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.model.entity.Policy
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.utils.FingerprintHelper
import com.topjohnwu.magisk.utils.toggle
......@@ -24,7 +26,8 @@ import me.tatarka.bindingcollectionadapter2.ItemBinding
class SuperuserViewModel(
private val database: MagiskDB,
private val packageManager: PackageManager,
private val resources: Resources
private val resources: Resources,
rxBus: RxBus
) : MagiskViewModel() {
val items = DiffObservableList(ComparableRvItem.callback)
......@@ -36,13 +39,20 @@ class SuperuserViewModel(
private var ignoreNext: PolicyRvItem? = null
init {
rxBus.register<PolicyEnableEvent>()
.subscribeK { togglePolicy(it.item, it.enable) }
.add()
rxBus.register<PolicyUpdateEvent>()
.subscribeK { updatePolicy(it) }
.add()
updatePolicies()
}
fun updatePolicies() {
Single.fromCallable { database.policyList }
.flattenAsFlowable { it }
.map { PolicyRvItem(it, it.info.loadIcon(packageManager)).setListeners() }
.map { PolicyRvItem(it, it.info.loadIcon(packageManager)) }
.toList()
.applySchedulers()
.applyViewModel(this)
......@@ -70,64 +80,48 @@ class SuperuserViewModel(
}
}
private fun PolicyRvItem.setListeners() = apply {
isEnabled.addOnPropertyChangedCallback {
it ?: return@addOnPropertyChangedCallback
if (ignoreNext == this) {
ignoreNext = null
return@addOnPropertyChangedCallback
}
private fun updatePolicy(it: PolicyUpdateEvent) = when (it) {
is PolicyUpdateEvent.Notification -> updatePolicy(it.item) {
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)
SnackbarEvent(text).publish()
}
is PolicyUpdateEvent.Log -> updatePolicy(it.item) {
val textId =
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()
}
}
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()
}
private fun updatePolicy(item: PolicyRvItem, onSuccess: (Policy) -> Unit) =
updatePolicy(item.item)
.subscribeK { onSuccess(it) }
.add()
if (FingerprintHelper.useFingerprint()) {
withView {
FingerprintAuthDialog(this, { updateState() }, {
ignoreNext = this@setListeners
isEnabled.toggle()
}).show()
}
} else {
updateState()
}
}
shouldNotify.addOnPropertyChangedCallback {
it ?: return@addOnPropertyChangedCallback
item.notification = it
private fun togglePolicy(item: PolicyRvItem, enable: Boolean) {
fun updateState() {
item.item.policy = if (enable) Policy.ALLOW else Policy.DENY
updatePolicy(item)
.map { it.notification }
updatePolicy(item.item)
.map { it.policy == Policy.ALLOW }
.subscribeK {
val textId = if (it) R.string.su_snack_notif_on else R.string.su_snack_notif_off
val text = resources.getString(textId).format(item.appName)
val textId = if (it) R.string.su_snack_grant else R.string.su_snack_deny
val text = resources.getString(textId).format(item.item.appName)
SnackbarEvent(text).publish()
}
.add()
}
shouldLog.addOnPropertyChangedCallback {
it ?: return@addOnPropertyChangedCallback
item.logging = it
updatePolicy(item)
.map { it.logging }
.subscribeK {
val textId = if (it) R.string.su_snack_log_on else R.string.su_snack_log_off
val text = resources.getString(textId).format(item.appName)
SnackbarEvent(text).publish()
}
.add()
if (FingerprintHelper.useFingerprint()) {
withView {
FingerprintAuthDialog(this, { updateState() }, {
ignoreNext = item
item.isEnabled.toggle()
}).show()
}
} else {
updateState()
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment