mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-10-27 16:22:15 +00:00
app: support config restrict policy
This commit is contained in:
@@ -24,6 +24,7 @@ import androidx.core.widget.ImageViewCompat
|
||||
import androidx.databinding.BindingAdapter
|
||||
import androidx.databinding.InverseBindingAdapter
|
||||
import androidx.databinding.InverseBindingListener
|
||||
import androidx.databinding.InverseMethod
|
||||
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
@@ -33,9 +34,11 @@ import androidx.recyclerview.widget.StaggeredGridLayoutManager
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
import com.google.android.material.chip.Chip
|
||||
import com.google.android.material.slider.Slider
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.core.di.ServiceLocator
|
||||
import com.topjohnwu.magisk.core.model.su.SuPolicy
|
||||
import com.topjohnwu.magisk.utils.TextHolder
|
||||
import com.topjohnwu.superuser.internal.UiThreadHandler
|
||||
import com.topjohnwu.widget.IndeterminateCheckBox
|
||||
@@ -306,3 +309,38 @@ fun TextView.setText(text: TextHolder) {
|
||||
fun Spinner.setAdapter(items: Array<Any>, layoutRes: Int) {
|
||||
adapter = ArrayAdapter(context, layoutRes, items)
|
||||
}
|
||||
|
||||
@BindingAdapter("labelFormatter")
|
||||
fun Slider.setLabelFormatter(formatter: (Float) -> Int) {
|
||||
setLabelFormatter { value -> resources.getString(formatter(value)) }
|
||||
}
|
||||
|
||||
@InverseBindingAdapter(attribute = "android:value")
|
||||
fun Slider.getValueBinding() = value
|
||||
|
||||
@BindingAdapter("android:valueAttrChanged")
|
||||
fun Slider.setListener(attrChange: InverseBindingListener) {
|
||||
addOnSliderTouchListener(object : Slider.OnSliderTouchListener {
|
||||
override fun onStartTrackingTouch(slider: Slider) = Unit
|
||||
override fun onStopTrackingTouch(slider: Slider) = attrChange.onChange()
|
||||
})
|
||||
}
|
||||
|
||||
@InverseMethod("sliderValueToPolicy")
|
||||
fun policyToSliderValue(policy: Int): Float {
|
||||
return when (policy) {
|
||||
SuPolicy.DENY -> 1f
|
||||
SuPolicy.RESTRICT -> 2f
|
||||
SuPolicy.ALLOW -> 3f
|
||||
else -> 1f
|
||||
}
|
||||
}
|
||||
|
||||
fun sliderValueToPolicy(value: Float): Int {
|
||||
return when (value) {
|
||||
1f -> SuPolicy.DENY
|
||||
2f -> SuPolicy.RESTRICT
|
||||
3f -> SuPolicy.ALLOW
|
||||
else -> SuPolicy.DENY
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,6 +322,12 @@ object Reauthenticate : BaseSettingsItem.Toggle() {
|
||||
override var value by Config::suReAuth
|
||||
|
||||
override fun refresh() {
|
||||
isEnabled = Build.VERSION.SDK_INT < Build.VERSION_CODES.O && Info.showSuperUser
|
||||
isEnabled = Build.VERSION.SDK_INT < Build.VERSION_CODES.O
|
||||
}
|
||||
}
|
||||
|
||||
object Restrict : BaseSettingsItem.Toggle() {
|
||||
override val title = CoreR.string.settings_su_restrict_title.asText()
|
||||
override val description = CoreR.string.settings_su_restrict_summary.asText()
|
||||
override var value by Config::suRestrict
|
||||
}
|
||||
|
||||
@@ -83,6 +83,9 @@ class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler {
|
||||
// Can hide overlay windows on 12.0+
|
||||
list.remove(Tapjack)
|
||||
}
|
||||
if (Const.Version.isCanary()) {
|
||||
list.add(Restrict)
|
||||
}
|
||||
}
|
||||
|
||||
return list
|
||||
|
||||
@@ -4,11 +4,13 @@ import android.graphics.drawable.Drawable
|
||||
import androidx.databinding.Bindable
|
||||
import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.core.Config
|
||||
import com.topjohnwu.magisk.core.model.su.SuPolicy
|
||||
import com.topjohnwu.magisk.databinding.DiffItem
|
||||
import com.topjohnwu.magisk.databinding.ItemWrapper
|
||||
import com.topjohnwu.magisk.databinding.ObservableRvItem
|
||||
import com.topjohnwu.magisk.databinding.set
|
||||
import com.topjohnwu.magisk.core.R as CoreR
|
||||
|
||||
class PolicyRvItem(
|
||||
private val viewModel: SuperuserViewModel,
|
||||
@@ -33,14 +35,34 @@ class PolicyRvItem(
|
||||
var isExpanded = false
|
||||
set(value) = set(value, field, { field = it }, BR.expanded)
|
||||
|
||||
val showSlider = Config.suRestrict || item.policy == SuPolicy.RESTRICT
|
||||
|
||||
@get:Bindable
|
||||
var isEnabled
|
||||
get() = item.policy == SuPolicy.ALLOW
|
||||
get() = item.policy >= SuPolicy.ALLOW
|
||||
set(value) = setImpl(value, isEnabled) {
|
||||
notifyPropertyChanged(BR.enabled)
|
||||
viewModel.togglePolicy(this, value)
|
||||
viewModel.updatePolicy(this, if (it) SuPolicy.ALLOW else SuPolicy.DENY)
|
||||
}
|
||||
|
||||
@get:Bindable
|
||||
var sliderValue
|
||||
get() = item.policy
|
||||
set(value) = setImpl(value, sliderValue) {
|
||||
notifyPropertyChanged(BR.sliderValue)
|
||||
notifyPropertyChanged(BR.enabled)
|
||||
viewModel.updatePolicy(this, it)
|
||||
}
|
||||
|
||||
val sliderValueToPolicyString: (Float) -> Int = { value ->
|
||||
when (value.toInt()) {
|
||||
1 -> CoreR.string.deny
|
||||
2 -> CoreR.string.restrict
|
||||
3 -> CoreR.string.grant
|
||||
else -> CoreR.string.deny
|
||||
}
|
||||
}
|
||||
|
||||
@get:Bindable
|
||||
var shouldNotify
|
||||
get() = item.notification
|
||||
|
||||
@@ -156,15 +156,16 @@ class SuperuserViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
fun togglePolicy(item: PolicyRvItem, enable: Boolean) {
|
||||
fun updatePolicy(item: PolicyRvItem, policy: Int) {
|
||||
val items = itemsPolicies.filter { it.item.uid == item.item.uid }
|
||||
fun updateState() {
|
||||
viewModelScope.launch {
|
||||
val res = if (enable) R.string.su_snack_grant else R.string.su_snack_deny
|
||||
item.item.policy = if (enable) SuPolicy.ALLOW else SuPolicy.DENY
|
||||
val res = if (policy >= SuPolicy.ALLOW) R.string.su_snack_grant else R.string.su_snack_deny
|
||||
item.item.policy = policy
|
||||
db.update(item.item)
|
||||
items.forEach {
|
||||
it.notifyPropertyChanged(BR.enabled)
|
||||
it.notifyPropertyChanged(BR.sliderValue)
|
||||
}
|
||||
SnackbarEvent(res.asText(item.appName)).publish()
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
<include
|
||||
android:id="@+id/log_track_container"
|
||||
bullet="@{item.log.action == 2 ? R.drawable.ic_check_md2 : R.drawable.ic_close_md2}"
|
||||
bullet="@{item.log.action >= 2 ? R.drawable.ic_check_md2 : R.drawable.ic_close_md2}"
|
||||
isBottom="@{item.isBottom}"
|
||||
isSelected="@{item.log.action != 2}"
|
||||
isTop="@{item.isTop}"
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
<data>
|
||||
|
||||
<import type="com.topjohnwu.magisk.databinding.DataBindingAdaptersKt" />
|
||||
|
||||
<variable
|
||||
name="item"
|
||||
type="com.topjohnwu.magisk.ui.superuser.PolicyRvItem" />
|
||||
@@ -85,16 +87,32 @@
|
||||
app:layout_constraintVertical_bias="0"
|
||||
tools:text="com.topjohnwu.magisk" />
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
<FrameLayout
|
||||
android:id="@+id/policy_indicator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/l1"
|
||||
android:checked="@={item.enabled}"
|
||||
android:nextFocusLeft="@id/policy"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
gone="@{item.showSlider}"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="@={item.enabled}" />
|
||||
|
||||
<com.google.android.material.slider.Slider
|
||||
goneUnless="@{item.showSlider}"
|
||||
labelFormatter="@{item.sliderValueToPolicyString}"
|
||||
android:layout_width="96dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:stepSize="1"
|
||||
android:value="@={DataBindingAdaptersKt.policyToSliderValue(item.sliderValue)}"
|
||||
android:valueFrom="1"
|
||||
android:valueTo="3" />
|
||||
</FrameLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user