Rename TransitiveText

This commit is contained in:
topjohnwu 2021-04-09 01:32:37 -07:00
parent 0f95a7babe
commit 706d53065b
9 changed files with 112 additions and 121 deletions

View File

@ -5,7 +5,6 @@ import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.graphics.Insets
import androidx.databinding.DataBindingUtil
import androidx.databinding.OnRebindCallback
import androidx.databinding.ViewDataBinding

View File

@ -6,11 +6,11 @@ import com.google.android.material.snackbar.Snackbar
import com.topjohnwu.magisk.arch.ActivityExecutor
import com.topjohnwu.magisk.arch.BaseUIActivity
import com.topjohnwu.magisk.arch.ViewEvent
import com.topjohnwu.magisk.utils.TransitiveText
import com.topjohnwu.magisk.utils.asTransitive
import com.topjohnwu.magisk.utils.TextHolder
import com.topjohnwu.magisk.utils.asText
class SnackbarEvent constructor(
private val msg: TransitiveText,
private val msg: TextHolder,
private val length: Int = Snackbar.LENGTH_SHORT,
private val builder: Snackbar.() -> Unit = {}
) : ViewEvent(), ActivityExecutor {
@ -19,13 +19,13 @@ class SnackbarEvent constructor(
@StringRes res: Int,
length: Int = Snackbar.LENGTH_SHORT,
builder: Snackbar.() -> Unit = {}
) : this(res.asTransitive(), length, builder)
) : this(res.asText(), length, builder)
constructor(
msg: String,
length: Int = Snackbar.LENGTH_SHORT,
builder: Snackbar.() -> Unit = {}
) : this(msg.asTransitive(), length, builder)
) : this(msg.asText(), length, builder)
private fun snackbar(

View File

@ -16,7 +16,7 @@ import com.topjohnwu.magisk.events.dialog.EnvFixDialog
import com.topjohnwu.magisk.events.dialog.ManagerInstallDialog
import com.topjohnwu.magisk.events.dialog.UninstallDialog
import com.topjohnwu.magisk.ktx.await
import com.topjohnwu.magisk.utils.asTransitive
import com.topjohnwu.magisk.utils.asText
import com.topjohnwu.magisk.utils.set
import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.launch
@ -54,13 +54,13 @@ class HomeViewModel(
val magiskInstalledVersion get() = Info.env.run {
if (isActive)
"$magiskVersionString ($magiskVersionCode)".asTransitive()
"$magiskVersionString ($magiskVersionCode)".asText()
else
R.string.not_available.asTransitive()
R.string.not_available.asText()
}
@get:Bindable
var managerRemoteVersion = R.string.loading.asTransitive()
var managerRemoteVersion = R.string.loading.asText()
set(value) = set(value, field, { field = it }, BR.managerRemoteVersion)
val managerInstalledVersion = Info.stub?.let {
@ -92,14 +92,14 @@ class HomeViewModel(
}
managerRemoteVersion =
"${magisk.version} (${magisk.versionCode}) (${stub.versionCode})".asTransitive()
"${magisk.version} (${magisk.versionCode}) (${stub.versionCode})".asText()
launch {
ensureEnv()
}
} ?: {
state = State.LOADING_FAILED
managerRemoteVersion = R.string.not_available.asTransitive()
managerRemoteVersion = R.string.not_available.asText()
}()
}

View File

@ -9,8 +9,8 @@ import androidx.databinding.Bindable
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.databinding.ObservableItem
import com.topjohnwu.magisk.utils.TransitiveText
import com.topjohnwu.magisk.utils.asTransitive
import com.topjohnwu.magisk.utils.TextHolder
import com.topjohnwu.magisk.utils.asText
import com.topjohnwu.magisk.utils.set
import com.topjohnwu.magisk.view.MagiskDialog
import org.koin.core.KoinComponent
@ -21,9 +21,9 @@ sealed class BaseSettingsItem : ObservableItem<BaseSettingsItem>() {
override val layoutRes get() = R.layout.item_settings
open val icon: Int get() = 0
open val title: TransitiveText get() = TransitiveText.EMPTY
open val title: TextHolder get() = TextHolder.EMPTY
@get:Bindable
open val description: TransitiveText get() = TransitiveText.EMPTY
open val description: TextHolder get() = TextHolder.EMPTY
// ---
@ -151,8 +151,8 @@ sealed class BaseSettingsItem : ObservableItem<BaseSettingsItem>() {
open val entries get() = resources.getArrayOrEmpty(entryRes)
open val entryValues get() = resources.getArrayOrEmpty(entryValRes)
override val description: TransitiveText
get() = entries.getOrNull(value)?.asTransitive() ?: TransitiveText.EMPTY
override val description: TextHolder
get() = entries.getOrNull(value)?.asText() ?: TextHolder.EMPTY
private fun Resources.getArrayOrEmpty(id: Int): Array<String> =
runCatching { getStringArray(id) }.getOrDefault(emptyArray())

View File

@ -20,9 +20,9 @@ import com.topjohnwu.magisk.databinding.DialogSettingsAppNameBinding
import com.topjohnwu.magisk.databinding.DialogSettingsDownloadPathBinding
import com.topjohnwu.magisk.databinding.DialogSettingsUpdateChannelBinding
import com.topjohnwu.magisk.ktx.get
import com.topjohnwu.magisk.utils.TransitiveText
import com.topjohnwu.magisk.utils.TextHolder
import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.magisk.utils.asTransitive
import com.topjohnwu.magisk.utils.asText
import com.topjohnwu.magisk.utils.set
import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.CoroutineScope
@ -31,7 +31,7 @@ import kotlinx.coroutines.launch
// --- Customization
object Customization : BaseSettingsItem.Section() {
override val title = R.string.settings_customization.asTransitive()
override val title = R.string.settings_customization.asText()
}
object Language : BaseSettingsItem.Selector() {
@ -40,7 +40,7 @@ object Language : BaseSettingsItem.Selector() {
Config.locale = entryValues[it]
}
override val title = R.string.language.asTransitive()
override val title = R.string.language.asText()
override var entries = emptyArray<String>()
override var entryValues = emptyArray<String>()
@ -58,18 +58,18 @@ object Language : BaseSettingsItem.Selector() {
object Theme : BaseSettingsItem.Blank() {
override val icon = R.drawable.ic_paint
override val title = R.string.section_theme.asTransitive()
override val title = R.string.section_theme.asText()
}
// --- App
object AppSettings : BaseSettingsItem.Section() {
override val title = R.string.home_app_title.asTransitive()
override val title = R.string.home_app_title.asText()
}
object ClearRepoCache : BaseSettingsItem.Blank() {
override val title = R.string.settings_clear_cache_title.asTransitive()
override val description = R.string.settings_clear_cache_summary.asTransitive()
override val title = R.string.settings_clear_cache_title.asText()
override val description = R.string.settings_clear_cache_summary.asText()
override fun refresh() {
isEnabled = Info.env.isActive
@ -77,8 +77,8 @@ object ClearRepoCache : BaseSettingsItem.Blank() {
}
object Hide : BaseSettingsItem.Input() {
override val title = R.string.settings_hide_app_title.asTransitive()
override val description = R.string.settings_hide_app_summary.asTransitive()
override val title = R.string.settings_hide_app_title.asText()
override val description = R.string.settings_hide_app_summary.asText()
override var value = ""
set(value) = setV(value, field, { field = it })
@ -106,21 +106,21 @@ object Hide : BaseSettingsItem.Input() {
}
object Restore : BaseSettingsItem.Blank() {
override val title = R.string.settings_restore_app_title.asTransitive()
override val description = R.string.settings_restore_app_summary.asTransitive()
override val title = R.string.settings_restore_app_title.asText()
override val description = R.string.settings_restore_app_summary.asText()
}
object AddShortcut : BaseSettingsItem.Blank() {
override val title = R.string.add_shortcut_title.asTransitive()
override val description = R.string.setting_add_shortcut_summary.asTransitive()
override val title = R.string.add_shortcut_title.asText()
override val description = R.string.setting_add_shortcut_summary.asText()
}
object DownloadPath : BaseSettingsItem.Input() {
override var value = Config.downloadDir
set(value) = setV(value, field, { field = it }) { Config.downloadDir = it }
override val title = R.string.settings_download_path_title.asTransitive()
override val description get() = path.asTransitive()
override val title = R.string.settings_download_path_title.asText()
override val description get() = path.asText()
override val inputResult: String get() = result
@ -143,24 +143,24 @@ object UpdateChannel : BaseSettingsItem.Selector() {
Info.remote = Info.EMPTY_REMOTE
}
override val title = R.string.settings_update_channel_title.asTransitive()
override val title = R.string.settings_update_channel_title.asText()
override val entries: Array<String> = resources.getStringArray(R.array.update_channel).let {
if (BuildConfig.VERSION_CODE % 100 == 0)
it.toMutableList().apply { removeAt(Config.Value.CANARY_CHANNEL) }.toTypedArray()
else it
}
override val description
get() = entries.getOrNull(value)?.asTransitive() ?: TransitiveText.String(entries[0])
get() = entries.getOrNull(value)?.asText() ?: TextHolder.String(entries[0])
}
object UpdateChannelUrl : BaseSettingsItem.Input() {
override val title = R.string.settings_update_custom.asTransitive()
override val title = R.string.settings_update_custom.asText()
override var value = Config.customChannelUrl
set(value) = setV(value, field, { field = it }) {
Config.customChannelUrl = it
Info.remote = Info.EMPTY_REMOTE
}
override val description get() = value.asTransitive()
override val description get() = value.asText()
override val inputResult get() = result
@ -177,8 +177,8 @@ object UpdateChannelUrl : BaseSettingsItem.Input() {
}
object UpdateChecker : BaseSettingsItem.Toggle() {
override val title = R.string.settings_check_update_title.asTransitive()
override val description = R.string.settings_check_update_summary.asTransitive()
override val title = R.string.settings_check_update_title.asText()
override val description = R.string.settings_check_update_summary.asText()
override var value = Config.checkUpdate
set(value) = setV(value, field, { field = it }) {
Config.checkUpdate = it
@ -187,8 +187,8 @@ object UpdateChecker : BaseSettingsItem.Toggle() {
}
object DoHToggle : BaseSettingsItem.Toggle() {
override val title = R.string.settings_doh_title.asTransitive()
override val description = R.string.settings_doh_description.asTransitive()
override val title = R.string.settings_doh_title.asText()
override val description = R.string.settings_doh_description.asText()
override var value = Config.doh
set(value) = setV(value, field, { field = it }) {
Config.doh = it
@ -197,35 +197,35 @@ object DoHToggle : BaseSettingsItem.Toggle() {
// check whether is module already installed beforehand?
object SystemlessHosts : BaseSettingsItem.Blank() {
override val title = R.string.settings_hosts_title.asTransitive()
override val description = R.string.settings_hosts_summary.asTransitive()
override val title = R.string.settings_hosts_title.asText()
override val description = R.string.settings_hosts_summary.asText()
}
object Tapjack : BaseSettingsItem.Toggle() {
override val title = R.string.settings_su_tapjack_title.asTransitive()
override var description = R.string.settings_su_tapjack_summary.asTransitive()
override val title = R.string.settings_su_tapjack_title.asText()
override var description = R.string.settings_su_tapjack_summary.asText()
override var value = Config.suTapjack
set(value) = setV(value, field, { field = it }) { Config.suTapjack = it }
}
object Biometrics : BaseSettingsItem.Toggle() {
override val title = R.string.settings_su_biometric_title.asTransitive()
override val title = R.string.settings_su_biometric_title.asText()
override var value = Config.suBiometric
set(value) = setV(value, field, { field = it }) { Config.suBiometric = it }
override var description = R.string.settings_su_biometric_summary.asTransitive()
override var description = R.string.settings_su_biometric_summary.asText()
override fun refresh() {
isEnabled = BiometricHelper.isSupported
if (!isEnabled) {
value = false
description = R.string.no_biometric.asTransitive()
description = R.string.no_biometric.asText()
}
}
}
object Reauthenticate : BaseSettingsItem.Toggle() {
override val title = R.string.settings_su_reauth_title.asTransitive()
override val description = R.string.settings_su_reauth_summary.asTransitive()
override val title = R.string.settings_su_reauth_title.asText()
override val description = R.string.settings_su_reauth_summary.asText()
override var value = Config.suReAuth
set(value) = setV(value, field, { field = it }) { Config.suReAuth = it }
@ -237,12 +237,12 @@ object Reauthenticate : BaseSettingsItem.Toggle() {
// --- Magisk
object Magisk : BaseSettingsItem.Section() {
override val title = R.string.magisk.asTransitive()
override val title = R.string.magisk.asText()
}
object MagiskHide : BaseSettingsItem.Toggle() {
override val title = R.string.magiskhide.asTransitive()
override val description = R.string.settings_magiskhide_summary.asTransitive()
override val title = R.string.magiskhide.asText()
override val description = R.string.settings_magiskhide_summary.asText()
override var value = Config.magiskHide
set(value) = setV(value, field, { field = it }) {
val cmd = if (it) "enable" else "disable"
@ -256,11 +256,11 @@ object MagiskHide : BaseSettingsItem.Toggle() {
// --- Superuser
object Superuser : BaseSettingsItem.Section() {
override val title = R.string.superuser.asTransitive()
override val title = R.string.superuser.asText()
}
object AccessMode : BaseSettingsItem.Selector() {
override val title = R.string.superuser_access.asTransitive()
override val title = R.string.superuser_access.asText()
override val entryRes = R.array.su_access
override var value = Config.rootMode
@ -270,7 +270,7 @@ object AccessMode : BaseSettingsItem.Selector() {
}
object MultiuserMode : BaseSettingsItem.Selector() {
override val title = R.string.multiuser_mode.asTransitive()
override val title = R.string.multiuser_mode.asText()
override val entryRes = R.array.multiuser_mode
override var value = Config.suMultiuserMode
@ -279,7 +279,7 @@ object MultiuserMode : BaseSettingsItem.Selector() {
}
override val description
get() = resources.getStringArray(R.array.multiuser_summary)[value].asTransitive()
get() = resources.getStringArray(R.array.multiuser_summary)[value].asText()
override fun refresh() {
isEnabled = Const.USER_ID == 0
@ -287,7 +287,7 @@ object MultiuserMode : BaseSettingsItem.Selector() {
}
object MountNamespaceMode : BaseSettingsItem.Selector() {
override val title = R.string.mount_namespace_mode.asTransitive()
override val title = R.string.mount_namespace_mode.asText()
override val entryRes = R.array.namespace
override var value = Config.suMntNamespaceMode
@ -296,11 +296,11 @@ object MountNamespaceMode : BaseSettingsItem.Selector() {
}
override val description
get() = resources.getStringArray(R.array.namespace_summary)[value].asTransitive()
get() = resources.getStringArray(R.array.namespace_summary)[value].asText()
}
object AutomaticResponse : BaseSettingsItem.Selector() {
override val title = R.string.auto_response.asTransitive()
override val title = R.string.auto_response.asText()
override val entryRes = R.array.auto_response
override var value = Config.suAutoResponse
@ -310,7 +310,7 @@ object AutomaticResponse : BaseSettingsItem.Selector() {
}
object RequestTimeout : BaseSettingsItem.Selector() {
override val title = R.string.request_timeout.asTransitive()
override val title = R.string.request_timeout.asText()
override val entryRes = R.array.request_timeout
override val entryValRes = R.array.request_timeout_value
@ -324,7 +324,7 @@ object RequestTimeout : BaseSettingsItem.Selector() {
}
object SUNotification : BaseSettingsItem.Selector() {
override val title = R.string.superuser_notification.asTransitive()
override val title = R.string.superuser_notification.asText()
override val entryRes = R.array.su_notification
override var value = Config.suNotification

View File

@ -18,7 +18,7 @@ import com.topjohnwu.magisk.events.SnackbarEvent
import com.topjohnwu.magisk.events.dialog.BiometricEvent
import com.topjohnwu.magisk.events.dialog.SuperuserRevokeDialog
import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.magisk.utils.asTransitive
import com.topjohnwu.magisk.utils.asText
import com.topjohnwu.magisk.view.TappableHeadlineItem
import com.topjohnwu.magisk.view.TextItem
import kotlinx.coroutines.Dispatchers
@ -116,7 +116,7 @@ class SuperuserViewModel(
else -> R.string.su_snack_notif_off
}
}
SnackbarEvent(res.asTransitive(policy.appName)).publish()
SnackbarEvent(res.asText(policy.appName)).publish()
}
fun togglePolicy(item: PolicyRvItem, enable: Boolean) {
@ -130,7 +130,7 @@ class SuperuserViewModel(
db.update(app)
val res = if (app.policy == SuPolicy.ALLOW) R.string.su_snack_grant
else R.string.su_snack_deny
SnackbarEvent(res.asTransitive(item.item.appName)).publish()
SnackbarEvent(res.asText(item.item.appName)).publish()
}
}

View File

@ -0,0 +1,47 @@
package com.topjohnwu.magisk.utils
import android.content.res.Resources
import android.widget.TextView
import androidx.databinding.BindingAdapter
sealed class TextHolder {
abstract val isEmpty: Boolean
abstract fun getText(resources: Resources): CharSequence
// ---
class String(
private val value: CharSequence
) : TextHolder() {
override val isEmpty get() = value.isEmpty()
override fun getText(resources: Resources) = value
}
class Resource(
private val value: Int,
private vararg val params: Any
) : TextHolder() {
override val isEmpty get() = value == 0
override fun getText(resources: Resources) = resources.getString(value, *params)
}
// ---
companion object {
val EMPTY = String("")
}
}
fun Int.asText(vararg params: Any): TextHolder = TextHolder.Resource(this, *params)
fun CharSequence.asText(): TextHolder = TextHolder.String(this)
@BindingAdapter("android:text")
fun TextView.setText(text: TextHolder) {
this.text = text.getText(context.resources)
}

View File

@ -1,53 +0,0 @@
package com.topjohnwu.magisk.utils
import android.content.res.Resources
import android.widget.TextView
import androidx.databinding.BindingAdapter
import androidx.databinding.InverseBindingAdapter
sealed class TransitiveText {
abstract val isEmpty: Boolean
abstract fun getText(resources: Resources): CharSequence
// ---
class String(
private val value: CharSequence
) : TransitiveText() {
override val isEmpty = value.isEmpty()
override fun getText(resources: Resources) = value
}
class Res(
private val value: Int,
private vararg val params: Any
) : TransitiveText() {
override val isEmpty = value == 0
override fun getText(resources: Resources) =
resources.getString(value, *params)
}
// ---
companion object {
val EMPTY = String("")
}
}
fun Int.asTransitive(vararg params: Any): TransitiveText = TransitiveText.Res(this, *params)
fun CharSequence.asTransitive(): TransitiveText = TransitiveText.String(this)
@BindingAdapter("android:text")
fun TextView.setText(text: TransitiveText) {
this.text = text.getText(context.resources)
}
@InverseBindingAdapter(attribute = "android:text", event = "android:textAttrChanged")
fun TextView.getTransitiveText() = text.asTransitive()

View File

@ -10,7 +10,6 @@ import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.CMSSignedDataGenerator;
import org.bouncycastle.cms.CMSTypedData;
import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
@ -31,7 +30,6 @@ import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;