Don't hold resources in ViewModels

This commit is contained in:
topjohnwu 2021-04-18 02:12:53 -07:00
parent 29cc372bfa
commit 1418bc454d
7 changed files with 33 additions and 41 deletions

View File

@ -28,5 +28,5 @@ val viewModelModules = module {
viewModel { InstallViewModel(get()) }
viewModel { MainViewModel() }
viewModel { (args: FlashFragmentArgs) -> FlashViewModel(args) }
viewModel { SuRequestViewModel(get(), get(), get(SUTimeout), get()) }
viewModel { SuRequestViewModel(get(), get(SUTimeout)) }
}

View File

@ -26,7 +26,7 @@ import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class FlashViewModel(private val args: FlashFragmentArgs) : BaseViewModel() {
class FlashViewModel(var args: FlashFragmentArgs) : BaseViewModel() {
@get:Bindable
var showReboot = Shell.rootAccess()

View File

@ -1,13 +0,0 @@
package com.topjohnwu.magisk.ui.superuser
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.databinding.ComparableRvItem
class SpinnerRvItem(val item: String) : ComparableRvItem<SpinnerRvItem>() {
override val layoutRes: Int = R.layout.item_spinner
override fun contentSameAs(other: SpinnerRvItem) = itemSameAs(other)
override fun itemSameAs(other: SpinnerRvItem) = item == other.item
}

View File

@ -1,9 +1,9 @@
package com.topjohnwu.magisk.ui.surequest
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.content.pm.PackageManager
import android.content.res.Resources
import android.graphics.drawable.Drawable
import android.os.Bundle
@ -30,19 +30,17 @@ import com.topjohnwu.magisk.core.utils.BiometricHelper
import com.topjohnwu.magisk.events.DieEvent
import com.topjohnwu.magisk.events.ShowUIEvent
import com.topjohnwu.magisk.events.dialog.BiometricEvent
import com.topjohnwu.magisk.ui.superuser.SpinnerRvItem
import com.topjohnwu.magisk.ktx.get
import com.topjohnwu.magisk.utils.TextHolder
import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.magisk.utils.set
import kotlinx.coroutines.launch
import me.tatarka.bindingcollectionadapter2.BindingListViewAdapter
import me.tatarka.bindingcollectionadapter2.ItemBinding
import java.util.concurrent.TimeUnit.SECONDS
class SuRequestViewModel(
pm: PackageManager,
policyDB: PolicyDao,
private val timeoutPrefs: SharedPreferences,
private val res: Resources
private val timeoutPrefs: SharedPreferences
) : BaseViewModel() {
lateinit var icon: Drawable
@ -50,8 +48,7 @@ class SuRequestViewModel(
lateinit var packageName: String
@get:Bindable
var denyText = res.getString(R.string.deny)
set(value) = set(value, field, { field = it }, BR.denyText)
val denyText = DenyText()
@get:Bindable
var selectedItemPosition = 0
@ -74,15 +71,9 @@ class SuRequestViewModel(
false
}
private val items = res.getStringArray(R.array.allow_timeout).map { SpinnerRvItem(it) }
val adapter = BindingListViewAdapter<SpinnerRvItem>(1).apply {
itemBinding = ItemBinding.of { binding, _, item ->
item.bind(binding)
}
setItems(items)
}
val itemBinding = ItemBinding.of<String>(BR.item, R.layout.item_spinner)
private val handler = SuRequestHandler(pm, policyDB)
private val handler = SuRequestHandler(get<Context>().packageManager, policyDB)
private lateinit var timer: CountDownTimer
fun grantPressed() {
@ -143,7 +134,7 @@ class SuRequestViewModel(
private fun cancelTimer() {
timer.cancel()
denyText = res.getString(R.string.deny)
denyText.seconds = 0
}
private inner class SuTimer(
@ -155,16 +146,30 @@ class SuRequestViewModel(
if (!grantEnabled && remains <= millis - 1000) {
grantEnabled = true
}
denyText = "${res.getString(R.string.deny)} (${(remains / 1000) + 1})"
denyText.seconds = (remains / 1000).toInt() + 1
}
override fun onFinish() {
denyText = res.getString(R.string.deny)
denyText.seconds = 0
respond(DENY)
}
}
inner class DenyText : TextHolder() {
var seconds = 0
set(value) = set(value, field, { field = it }, BR.denyText)
override val isEmpty get() = false
override fun getText(resources: Resources): CharSequence {
return if (seconds != 0)
"${resources.getString(R.string.deny)} ($seconds)"
else
resources.getString(R.string.deny)
}
}
// Invisible for accessibility services
object EmptyAccessibilityDelegate : View.AccessibilityDelegate() {
override fun sendAccessibilityEvent(host: View?, eventType: Int) {}

View File

@ -4,7 +4,7 @@ import android.content.res.Resources
import android.widget.TextView
import androidx.databinding.BindingAdapter
sealed class TextHolder {
abstract class TextHolder {
abstract val isEmpty: Boolean
abstract fun getText(resources: Resources): CharSequence

View File

@ -5,6 +5,8 @@
<data>
<import type="java.util.Arrays"/>
<variable
name="viewModel"
type="com.topjohnwu.magisk.ui.surequest.SuRequestViewModel" />
@ -99,7 +101,8 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:enabled="@{viewModel.grantEnabled}"
android:adapter="@{viewModel.adapter}"
app:items="@{Arrays.asList(@stringArray/allow_timeout)}"
app:itemBinding="@{viewModel.itemBinding}"
android:selection="@={viewModel.selectedItemPosition}" />
<TextView

View File

@ -4,14 +4,11 @@
<data>
<variable
name="item"
type="com.topjohnwu.magisk.ui.superuser.SpinnerRvItem" />
<variable name="item" type="String" />
</data>
<TextView
android:id="@android:id/text1"
style="?android:attr/spinnerItemStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -21,7 +18,7 @@
android:gravity="center_vertical"
android:minHeight="?attr/listPreferredItemHeightSmall"
android:singleLine="true"
android:text="@{item.item}"
android:text="@{item}"
android:textAlignment="inherit"
tools:text="Forever" />