Commit c7e30ac6 authored by topjohnwu's avatar topjohnwu

Update superuser list

parent f5e54794
......@@ -9,53 +9,60 @@ import com.topjohnwu.magisk.databinding.ObservableItem
import com.topjohnwu.magisk.ui.superuser.SuperuserViewModel
import com.topjohnwu.magisk.utils.set
class PolicyItem(val item: MagiskPolicy, val icon: Drawable) : ObservableItem<PolicyItem>() {
class PolicyItem(
val item: MagiskPolicy,
val icon: Drawable,
val viewModel: SuperuserViewModel
) : ObservableItem<PolicyItem>() {
override val layoutRes = R.layout.item_policy_md2
@get:Bindable
var isExpanded = false
set(value) = set(value, field, { field = it }, BR.expanded)
@get:Bindable
var isEnabled = item.policy == MagiskPolicy.ALLOW
// This property hosts the policy state
var policyState = item.policy == MagiskPolicy.ALLOW
set(value) = set(value, field, { field = it }, BR.enabled)
// This property binds with the UI state
@get:Bindable
var isEnabled
get() = policyState
set(value) = set(value, policyState, { viewModel.togglePolicy(this, it) }, BR.enabled)
@get:Bindable
var shouldNotify = item.notification
set(value) = set(value, field, { field = it }, BR.shouldNotify)
set(value) = set(value, field, { field = it }, BR.shouldNotify) {
viewModel.updatePolicy(updatedPolicy, isLogging = false)
}
@get:Bindable
var shouldLog = item.logging
set(value) = set(value, field, { field = it }, BR.shouldLog)
set(value) = set(value, field, { field = it }, BR.shouldLog) {
viewModel.updatePolicy(updatedPolicy, isLogging = true)
}
private val updatedPolicy
get() = item.copy(
policy = if (isEnabled) MagiskPolicy.ALLOW else MagiskPolicy.DENY,
policy = if (policyState) MagiskPolicy.ALLOW else MagiskPolicy.DENY,
notification = shouldNotify,
logging = shouldLog
)
fun toggle(viewModel: SuperuserViewModel) {
if (isExpanded) {
toggle()
return
}
isEnabled = !isEnabled
viewModel.togglePolicy(this, isEnabled)
}
fun toggle() {
fun toggleExpand() {
isExpanded = !isExpanded
}
fun toggleNotify(viewModel: SuperuserViewModel) {
fun toggleNotify() {
shouldNotify = !shouldNotify
viewModel.updatePolicy(updatedPolicy, isLogging = false)
}
fun toggleLog(viewModel: SuperuserViewModel) {
fun toggleLog() {
shouldLog = !shouldLog
viewModel.updatePolicy(updatedPolicy, isLogging = true)
}
fun revoke() {
viewModel.deletePressed(this)
}
override fun contentSameAs(other: PolicyItem) = itemSameAs(other)
......
......@@ -35,9 +35,7 @@ class SuperuserViewModel(
private val itemNoData = TextItem(R.string.superuser_policy_none)
private val itemsPolicies = diffListOf<PolicyItem>()
private val itemsHelpers = ObservableArrayList<TextItem>().also {
it.add(itemNoData)
}
private val itemsHelpers = ObservableArrayList<TextItem>()
val adapter = adapterOf<ComparableRvItem<*>>()
val items = MergeObservableList<ComparableRvItem<*>>()
......@@ -45,7 +43,6 @@ class SuperuserViewModel(
.insertList(itemsHelpers)
.insertList(itemsPolicies)
val itemBinding = itemBindingOf<ComparableRvItem<*>> {
it.bindExtra(BR.viewModel, this)
it.bindExtra(BR.listener, this)
}
......@@ -55,7 +52,7 @@ class SuperuserViewModel(
state = State.LOADING
val (policies, diff) = withContext(Dispatchers.Default) {
val policies = db.fetchAll {
PolicyItem(it, it.applicationInfo.loadIcon(packageManager))
PolicyItem(it, it.applicationInfo.loadIcon(packageManager), this@SuperuserViewModel)
}.sortedWith(compareBy(
{ it.item.appName.toLowerCase(currentLocale) },
{ it.item.packageName }
......@@ -63,15 +60,15 @@ class SuperuserViewModel(
policies to itemsPolicies.calculateDiff(policies)
}
itemsPolicies.update(policies, diff)
if (itemsPolicies.isNotEmpty()) {
itemsHelpers.remove(itemNoData)
}
if (itemsPolicies.isNotEmpty())
itemsHelpers.clear()
else if (itemsHelpers.isEmpty())
itemsHelpers.add(itemNoData)
state = State.LOADED
}
// ---
@Suppress("REDUNDANT_ELSE_IN_WHEN")
override fun onItemPressed(item: TappableHeadlineItem) = when (item) {
TappableHeadlineItem.Hide -> hidePressed()
else -> Unit
......@@ -120,6 +117,8 @@ class SuperuserViewModel(
fun togglePolicy(item: PolicyItem, enable: Boolean) {
fun updateState() {
item.policyState = enable
val policy = if (enable) MagiskPolicy.ALLOW else MagiskPolicy.DENY
val app = item.item.copy(policy = policy)
......@@ -127,14 +126,13 @@ class SuperuserViewModel(
db.update(app)
val res = if (app.policy == MagiskPolicy.ALLOW) R.string.su_snack_grant
else R.string.su_snack_deny
SnackbarEvent(resources.getString(res).format(item.item.appName))
SnackbarEvent(resources.getString(res).format(item.item.appName)).publish()
}
}
if (BiometricHelper.isEnabled) {
BiometricDialog {
onSuccess { updateState() }
onFailure { item.isEnabled = !item.isEnabled }
}.publish()
} else {
updateState()
......
......@@ -37,6 +37,11 @@ fun setImageResource(view: ImageView, @DrawableRes resId: Int) {
view.setImageResource(resId)
}
@BindingAdapter("srcCompat")
fun setImageResource(view: ImageView, drawable: Drawable) {
view.setImageDrawable(drawable)
}
@BindingAdapter("movieBehavior", "movieBehaviorText")
fun setMovieBehavior(view: TextView, isMovieBehavior: Boolean, text: String) {
(view.tag as? Job)?.cancel()
......
......@@ -21,7 +21,7 @@
android:id="@+id/superuser_list"
adapter="@{viewModel.adapter}"
dividerHorizontal="@{@drawable/divider_l1}"
dividerVertical="@{@drawable/divider_l1}"
dividerVertical="@{@drawable/divider_l_50}"
goneUnless="@{viewModel.loaded || !viewModel.items.empty}"
itemBinding="@{viewModel.itemBinding}"
items="@{viewModel.items}"
......@@ -33,10 +33,7 @@
android:paddingTop="@{viewModel.insets.top + (int) @dimen/internal_action_bar_size + (int) @dimen/l1}"
android:paddingBottom="@{viewModel.insets.bottom + (int) @dimen/l2}"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:spanCount="2"
tools:layout_marginTop="24dp"
tools:listitem="@layout/item_policy_md2"
tools:paddingTop="@dimen/l1" />
tools:listitem="@layout/item_policy_md2" />
<LinearLayout
goneUnless="@{viewModel.loading &amp;&amp; viewModel.items.empty}"
......@@ -44,9 +41,10 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical">
android:orientation="vertical"
tools:visibility="gone">
<androidx.appcompat.widget.AppCompatTextView
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/safetynet_attest_loading"
......
This diff is collapsed.
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