Remove usage of KObservableField

This commit is contained in:
topjohnwu 2020-07-08 06:14:32 -07:00
parent 8ffbffddb3
commit 18dab28c32
27 changed files with 93 additions and 172 deletions

View File

@ -21,8 +21,8 @@ import com.topjohnwu.magisk.core.download.DownloadService
import com.topjohnwu.magisk.core.utils.refreshLocale
import com.topjohnwu.magisk.core.utils.updateConfig
import com.topjohnwu.magisk.extensions.forceGetDeclaredField
import com.topjohnwu.magisk.ui.surequest.SuRequestActivity
import com.topjohnwu.magisk.ui.MainActivity
import com.topjohnwu.magisk.ui.surequest.SuRequestActivity
fun AssetManager.addAssetPath(path: String) {
DynAPK.addAssetPath(this, path)

View File

@ -1,12 +1,13 @@
package com.topjohnwu.magisk.core
import androidx.databinding.ObservableField
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.topjohnwu.magisk.DynAPK
import com.topjohnwu.magisk.core.model.UpdateInfo
import com.topjohnwu.magisk.extensions.get
import com.topjohnwu.magisk.extensions.subscribeK
import com.topjohnwu.magisk.extensions.value
import com.topjohnwu.magisk.utils.CachedValue
import com.topjohnwu.magisk.utils.KObservableField
import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.ShellUtils.fastCmd
import java.io.FileInputStream
@ -35,7 +36,7 @@ object Info {
@JvmStatic var ramdisk = false
val isConnected by lazy {
KObservableField(false).also { field ->
ObservableField(false).also { field ->
ReactiveNetwork.observeNetworkConnectivity(get())
.subscribeK {
field.value = it.available()

View File

@ -5,7 +5,6 @@ import android.content.pm.PackageManager
import android.util.Base64
import android.util.Base64OutputStream
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.utils.PatchAPK.ALPHANUM
import com.topjohnwu.signing.CryptoUtils.readCertificate
import com.topjohnwu.signing.CryptoUtils.readPrivateKey
import org.bouncycastle.asn1.x500.X500Name

View File

@ -11,7 +11,10 @@ import androidx.core.content.getSystemService
import androidx.core.graphics.drawable.toAdaptiveIcon
import androidx.core.graphics.drawable.toIcon
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.*
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.SplashActivity
import com.topjohnwu.magisk.core.intent
import com.topjohnwu.magisk.core.utils.Utils
import com.topjohnwu.magisk.extensions.getBitmap

View File

@ -54,4 +54,12 @@ inline fun <T> ObservableField<T>.updateNonNull(block: (T) -> Unit) {
inline fun ObservableInt.update(block: (Int) -> Unit) {
set(get().apply(block))
}
}
inline var <T> ObservableField<T>.value
get() = get() as T
set(value) {
// Use Kotlin comparision (Any.equals)
if (value != get())
set(value)
}

View File

@ -1,7 +1,6 @@
package com.topjohnwu.magisk.extensions
import androidx.databinding.ObservableField
import com.topjohnwu.magisk.utils.KObservableField
import com.topjohnwu.superuser.internal.UiThreadHandler
import io.reactivex.*
import io.reactivex.android.schedulers.AndroidSchedulers
@ -76,34 +75,6 @@ fun Completable.subscribeK(
) = applySchedulers()
.subscribe(onComplete, onError)
fun <T> Observable<out T>.updateBy(
field: KObservableField<T?>
) = doOnNextUi { field.value = it }
.doOnErrorUi { field.value = null }
fun <T> Single<out T>.updateBy(
field: KObservableField<T?>
) = doOnSuccessUi { field.value = it }
.doOnErrorUi { field.value = null }
fun <T> Maybe<out T>.updateBy(
field: KObservableField<T?>
) = doOnSuccessUi { field.value = it }
.doOnErrorUi { field.value = null }
.doOnComplete { field.value = field.value }
fun <T> Flowable<out T>.updateBy(
field: KObservableField<T?>
) = doOnNextUi { field.value = it }
.doOnErrorUi { field.value = null }
fun Completable.updateBy(
field: KObservableField<Boolean>
) = doOnCompleteUi { field.value = true }
.doOnErrorUi { field.value = false }
fun <T> Observable<T>.doOnSubscribeUi(body: () -> Unit) =
doOnSubscribe { UiThreadHandler.run { body() } }
@ -202,4 +173,4 @@ inline fun <T1, T2, R> zip(
t1: Single<T1>,
t2: Single<T2>,
crossinline zipper: (T1, T2) -> R
) = Single.zip(t1, t2, BiFunction<T1, T2, R> { rt1, rt2 -> zipper(rt1, rt2) })
) = Single.zip(t1, t2, BiFunction<T1, T2, R> { rt1, rt2 -> zipper(rt1, rt2) })

View File

@ -1,10 +1,10 @@
package com.topjohnwu.magisk.extensions
import androidx.databinding.ObservableField
import androidx.databinding.ObservableList
import com.topjohnwu.magisk.utils.KObservableField
fun KObservableField<Boolean>.toggle() {
fun ObservableField<Boolean>.toggle() {
value = !value
}
@ -68,4 +68,4 @@ fun <T> ObservableList<T>.addOnListChangedCallback(
itemCount
)
}
})
})

View File

@ -2,16 +2,17 @@ package com.topjohnwu.magisk.model.entity.recycler
import android.view.View
import android.view.ViewGroup
import androidx.databinding.ObservableField
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.databinding.ComparableRvItem
import com.topjohnwu.magisk.extensions.addOnPropertyChangedCallback
import com.topjohnwu.magisk.extensions.startAnimations
import com.topjohnwu.magisk.extensions.toggle
import com.topjohnwu.magisk.extensions.value
import com.topjohnwu.magisk.model.entity.ProcessHideApp
import com.topjohnwu.magisk.model.entity.StatefulProcess
import com.topjohnwu.magisk.model.observer.Observer
import com.topjohnwu.magisk.ui.hide.HideViewModel
import com.topjohnwu.magisk.utils.KObservableField
import kotlin.math.roundToInt
class HideItem(val item: ProcessHideApp) : ComparableRvItem<HideItem>() {
@ -21,8 +22,8 @@ class HideItem(val item: ProcessHideApp) : ComparableRvItem<HideItem>() {
val packageName = item.info.info.packageName.orEmpty()
val items = item.processes.map { HideProcessItem(it) }
val isExpanded = KObservableField(false)
val itemsChecked = KObservableField(0)
val isExpanded = ObservableField(false)
val itemsChecked = ObservableField(0)
val itemsCheckedPercent = Observer(itemsChecked) {
(itemsChecked.value.toFloat() / items.size * 100).roundToInt()
}
@ -68,7 +69,7 @@ class HideProcessItem(val item: StatefulProcess) : ComparableRvItem<HideProcessI
override val layoutRes = R.layout.item_hide_process_md2
val isHidden = KObservableField(item.isHidden)
val isHidden = ObservableField(item.isHidden)
fun toggle(viewModel: HideViewModel) {
isHidden.toggle()

View File

@ -1,9 +1,6 @@
package com.topjohnwu.magisk.model.entity.recycler
import androidx.databinding.Bindable
import androidx.databinding.Observable
import androidx.databinding.PropertyChangeRegistry
import androidx.databinding.ViewDataBinding
import androidx.databinding.*
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.R
@ -11,7 +8,6 @@ import com.topjohnwu.magisk.core.model.module.Module
import com.topjohnwu.magisk.core.model.module.Repo
import com.topjohnwu.magisk.databinding.ComparableRvItem
import com.topjohnwu.magisk.ui.module.ModuleViewModel
import com.topjohnwu.magisk.utils.KObservableField
object InstallModule : ComparableRvItem<InstallModule>() {
override val layoutRes = R.layout.item_module_download
@ -65,7 +61,7 @@ class SectionTitle(
sealed class RepoItem(val item: Repo) : ObservableItem<RepoItem>() {
override val layoutRes: Int = R.layout.item_repo_md2
val progress = KObservableField(0)
val progress = ObservableField(0)
var isUpdate = false
@Bindable get
protected set(value) {

View File

@ -1,23 +1,24 @@
package com.topjohnwu.magisk.model.entity.recycler
import android.graphics.drawable.Drawable
import androidx.databinding.ObservableField
import androidx.databinding.ViewDataBinding
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.model.MagiskPolicy
import com.topjohnwu.magisk.databinding.ComparableRvItem
import com.topjohnwu.magisk.extensions.toggle
import com.topjohnwu.magisk.extensions.value
import com.topjohnwu.magisk.model.events.PolicyUpdateEvent
import com.topjohnwu.magisk.ui.superuser.SuperuserViewModel
import com.topjohnwu.magisk.utils.KObservableField
class PolicyItem(val item: MagiskPolicy, val icon: Drawable) : ComparableRvItem<PolicyItem>() {
override val layoutRes = R.layout.item_policy_md2
val isExpanded = KObservableField(false)
val isEnabled = KObservableField(item.policy == MagiskPolicy.ALLOW)
val shouldNotify = KObservableField(item.notification)
val shouldLog = KObservableField(item.logging)
val isExpanded = ObservableField(false)
val isEnabled = ObservableField(item.policy == MagiskPolicy.ALLOW)
val shouldNotify = ObservableField(item.notification)
val shouldLog = ObservableField(item.logging)
private val updatedPolicy
get() = item.copy(

View File

@ -6,7 +6,6 @@ import android.view.View
import android.view.ViewTreeObserver
import android.view.WindowManager
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.graphics.Insets
import androidx.core.view.forEach
import androidx.core.view.setPadding
import androidx.core.view.updateLayoutParams
@ -138,10 +137,6 @@ open class MainActivity : BaseUIActivity<MainViewModel, ActivityMainMd2Binding>(
return true
}
override fun peekSystemWindowInsets(insets: Insets) {
viewModel.insets.value = insets
}
fun setDisplayHomeAsUpEnabled(isEnabled: Boolean) {
binding.mainToolbar.startAnimations()
when {

View File

@ -20,6 +20,7 @@ import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.base.BaseActivity
import com.topjohnwu.magisk.extensions.snackbar
import com.topjohnwu.magisk.extensions.startAnimations
import com.topjohnwu.magisk.extensions.value
import com.topjohnwu.magisk.model.events.EventHandler
import com.topjohnwu.magisk.model.events.SnackbarEvent
import com.topjohnwu.magisk.model.events.ViewEvent

View File

@ -4,6 +4,7 @@ import android.Manifest
import androidx.annotation.CallSuper
import androidx.core.graphics.Insets
import androidx.databinding.Bindable
import androidx.databinding.ObservableField
import androidx.databinding.PropertyChangeRegistry
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
@ -13,10 +14,10 @@ import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.base.BaseActivity
import com.topjohnwu.magisk.extensions.doOnSubscribeUi
import com.topjohnwu.magisk.extensions.value
import com.topjohnwu.magisk.model.events.*
import com.topjohnwu.magisk.model.navigation.NavigationWrapper
import com.topjohnwu.magisk.model.observer.Observer
import com.topjohnwu.magisk.utils.KObservableField
import io.reactivex.*
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
@ -40,7 +41,7 @@ abstract class BaseViewModel(
val isConnected = Observer(Info.isConnected) { Info.isConnected.value }
val viewEvents: LiveData<ViewEvent> get() = _viewEvents
val insets = KObservableField(Insets.NONE)
val insets = ObservableField(Insets.NONE)
var state: State = initialState
set(value) {

View File

@ -5,6 +5,7 @@ import androidx.core.graphics.Insets
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.fragment.app.Fragment
import com.topjohnwu.magisk.extensions.value
import com.topjohnwu.magisk.model.events.ActivityExecutor
import com.topjohnwu.magisk.model.events.ContextExecutor
import com.topjohnwu.magisk.model.events.FragmentExecutor

View File

@ -5,11 +5,7 @@ import android.content.Context
import android.content.pm.ActivityInfo
import android.net.Uri
import android.os.Bundle
import android.view.KeyEvent
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.*
import androidx.core.net.toUri
import androidx.navigation.NavDeepLinkBuilder
import com.topjohnwu.magisk.R

View File

@ -5,6 +5,7 @@ import android.content.res.Resources
import android.net.Uri
import android.view.MenuItem
import androidx.databinding.ObservableArrayList
import androidx.databinding.ObservableField
import androidx.lifecycle.viewModelScope
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Config
@ -19,7 +20,6 @@ import com.topjohnwu.magisk.model.events.SnackbarEvent
import com.topjohnwu.magisk.ui.base.BaseViewModel
import com.topjohnwu.magisk.ui.base.diffListOf
import com.topjohnwu.magisk.ui.base.itemBindingOf
import com.topjohnwu.magisk.utils.KObservableField
import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.launch
import java.io.File
@ -30,8 +30,8 @@ class FlashViewModel(
private val resources: Resources
) : BaseViewModel() {
val showReboot = KObservableField(Shell.rootAccess())
val behaviorText = KObservableField(resources.getString(R.string.flashing))
val showReboot = ObservableField(Shell.rootAccess())
val behaviorText = ObservableField(resources.getString(R.string.flashing))
val adapter = BindingAdapter<ConsoleItem>()
val items = diffListOf<ConsoleItem>()

View File

@ -2,11 +2,12 @@ package com.topjohnwu.magisk.ui.hide
import android.content.pm.ApplicationInfo
import androidx.databinding.Bindable
import androidx.databinding.ObservableField
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.core.utils.currentLocale
import com.topjohnwu.magisk.data.repository.MagiskRepository
import com.topjohnwu.magisk.extensions.subscribeK
import com.topjohnwu.magisk.extensions.toggle
import com.topjohnwu.magisk.extensions.value
import com.topjohnwu.magisk.model.entity.HideAppInfo
import com.topjohnwu.magisk.model.entity.HideTarget
import com.topjohnwu.magisk.model.entity.ProcessHideApp
@ -17,7 +18,6 @@ import com.topjohnwu.magisk.ui.base.BaseViewModel
import com.topjohnwu.magisk.ui.base.Queryable
import com.topjohnwu.magisk.ui.base.filterableListOf
import com.topjohnwu.magisk.ui.base.itemBindingOf
import com.topjohnwu.magisk.utils.KObservableField
class HideViewModel(
private val magiskRepo: MagiskRepository
@ -48,7 +48,7 @@ class HideViewModel(
it.bindExtra(BR.viewModel, this)
}
val isFilterExpanded = KObservableField(false)
val isFilterExpanded = ObservableField(false)
override fun rxRefresh() = magiskRepo.fetchApps()
.map { it to magiskRepo.fetchHideTargets().blockingGet() }
@ -101,8 +101,6 @@ class HideViewModel(
fun toggleItem(item: HideProcessItem) = magiskRepo
.toggleHide(item.isHidden.value, item.item.packageName, item.item.name)
fun toggle(item: KObservableField<Boolean>) = item.toggle()
fun resetQuery() {
query = ""
}

View File

@ -2,6 +2,7 @@ package com.topjohnwu.magisk.ui.home
import android.Manifest
import android.os.Build
import androidx.databinding.ObservableField
import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Config
@ -24,7 +25,6 @@ import com.topjohnwu.magisk.model.events.dialog.ManagerInstallDialog
import com.topjohnwu.magisk.model.events.dialog.UninstallDialog
import com.topjohnwu.magisk.ui.base.BaseViewModel
import com.topjohnwu.magisk.ui.base.itemBindingOf
import com.topjohnwu.magisk.utils.KObservableField
import com.topjohnwu.superuser.Shell
import me.tatarka.bindingcollectionadapter2.BR
import kotlin.math.roundToInt
@ -37,22 +37,22 @@ class HomeViewModel(
private val repoMagisk: MagiskRepository
) : BaseViewModel() {
val isNoticeVisible = KObservableField(Config.safetyNotice)
val isNoticeVisible = ObservableField(Config.safetyNotice)
val stateMagisk = KObservableField(MagiskState.LOADING)
val stateManager = KObservableField(MagiskState.LOADING)
val stateMagisk = ObservableField(MagiskState.LOADING)
val stateManager = ObservableField(MagiskState.LOADING)
val stateMagiskRemoteVersion = KObservableField(R.string.loading.res())
val stateMagiskRemoteVersion = ObservableField(R.string.loading.res())
val stateMagiskInstalledVersion get() =
"${Info.env.magiskVersionString} (${Info.env.magiskVersionCode})"
val stateMagiskMode get() = R.string.home_status_normal.res()
val stateManagerRemoteVersion = KObservableField(R.string.loading.res())
val stateManagerRemoteVersion = ObservableField(R.string.loading.res())
val stateManagerInstalledVersion = Info.stub?.let {
"${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE}) (${it.version})"
} ?: "${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})"
val statePackageName = packageName
val stateManagerProgress = KObservableField(0)
val stateManagerProgress = ObservableField(0)
val items = listOf(DeveloperItem.Mainline, DeveloperItem.App, DeveloperItem.Project)
val itemBinding = itemBindingOf<HomeItem> {
@ -116,8 +116,6 @@ class HomeViewModel(
.subscribeK { HomeFragmentDirections.actionHomeFragmentToInstallFragment().publish() }
.add()
fun toggle(kof: KObservableField<Boolean>) = kof.toggle()
fun hideNotice() {
Config.safetyNotice = false
isNoticeVisible.value = false

View File

@ -3,6 +3,7 @@ package com.topjohnwu.magisk.ui.install
import android.content.Intent
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.databinding.FragmentInstallMd2Binding
import com.topjohnwu.magisk.extensions.value
import com.topjohnwu.magisk.model.events.RequestFileEvent
import com.topjohnwu.magisk.ui.base.BaseUIFragment
import org.koin.androidx.viewmodel.ext.android.viewModel

View File

@ -4,6 +4,7 @@ import android.net.Uri
import android.text.SpannableString
import android.text.Spanned
import android.widget.Toast
import androidx.databinding.ObservableField
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.download.DownloadService
@ -12,12 +13,12 @@ import com.topjohnwu.magisk.core.utils.Utils
import com.topjohnwu.magisk.data.repository.StringRepository
import com.topjohnwu.magisk.extensions.addOnPropertyChangedCallback
import com.topjohnwu.magisk.extensions.subscribeK
import com.topjohnwu.magisk.extensions.value
import com.topjohnwu.magisk.model.entity.internal.Configuration
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
import com.topjohnwu.magisk.model.events.RequestFileEvent
import com.topjohnwu.magisk.model.events.dialog.SecondSlotWarningDialog
import com.topjohnwu.magisk.ui.base.BaseViewModel
import com.topjohnwu.magisk.utils.KObservableField
import com.topjohnwu.superuser.Shell
import io.noties.markwon.Markwon
import org.koin.core.get
@ -31,11 +32,11 @@ class InstallViewModel(
val isRooted get() = Shell.rootAccess()
val isAB get() = Info.isAB
val step = KObservableField(0)
val method = KObservableField(-1)
val progress = KObservableField(0)
val data = KObservableField<Uri?>(null)
val notes = KObservableField<Spanned>(SpannableString(""))
val step = ObservableField(0)
val method = ObservableField(-1)
val progress = ObservableField(0)
val data = ObservableField<Uri?>(null)
val notes = ObservableField<Spanned>(SpannableString(""))
init {
RemoteFileService.reset()

View File

@ -1,18 +1,19 @@
package com.topjohnwu.magisk.ui.log
import androidx.databinding.ObservableField
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.data.repository.LogRepository
import com.topjohnwu.magisk.extensions.subscribeK
import com.topjohnwu.magisk.extensions.value
import com.topjohnwu.magisk.model.entity.recycler.LogItem
import com.topjohnwu.magisk.model.entity.recycler.TextItem
import com.topjohnwu.magisk.model.events.SnackbarEvent
import com.topjohnwu.magisk.ui.base.BaseViewModel
import com.topjohnwu.magisk.ui.base.diffListOf
import com.topjohnwu.magisk.ui.base.itemBindingOf
import com.topjohnwu.magisk.utils.KObservableField
import com.topjohnwu.superuser.Shell
import io.reactivex.Completable
import io.reactivex.android.schedulers.AndroidSchedulers
@ -40,7 +41,7 @@ class LogViewModel(
// --- magisk log
val consoleText = KObservableField(" ")
val consoleText = ObservableField(" ")
override fun rxRefresh(): Disposable {
val logs = repo.fetchLogs()

View File

@ -2,6 +2,7 @@ package com.topjohnwu.magisk.ui.module
import androidx.databinding.Bindable
import androidx.databinding.ObservableArrayList
import androidx.databinding.ObservableField
import androidx.lifecycle.viewModelScope
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.R
@ -15,6 +16,7 @@ import com.topjohnwu.magisk.data.database.RepoByUpdatedDao
import com.topjohnwu.magisk.databinding.ComparableRvItem
import com.topjohnwu.magisk.extensions.addOnListChangedCallback
import com.topjohnwu.magisk.extensions.reboot
import com.topjohnwu.magisk.extensions.value
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
import com.topjohnwu.magisk.model.entity.recycler.*
import com.topjohnwu.magisk.model.events.InstallExternalModuleEvent
@ -23,7 +25,6 @@ import com.topjohnwu.magisk.model.events.SnackbarEvent
import com.topjohnwu.magisk.model.events.dialog.ModuleInstallDialog
import com.topjohnwu.magisk.ui.base.*
import com.topjohnwu.magisk.utils.EndlessRecyclerScrollListener
import com.topjohnwu.magisk.utils.KObservableField
import kotlinx.coroutines.*
import me.tatarka.bindingcollectionadapter2.collections.MergeObservableList
import kotlin.math.roundToInt
@ -63,7 +64,7 @@ class ModuleViewModel(
searchLoading.value = true
}
val searchLoading = KObservableField(false)
val searchLoading = ObservableField(false)
val itemsSearch = diffListOf<RepoItem>()
val itemSearchBinding = itemBindingOf<RepoItem> {
it.bindExtra(BR.viewModel, this)

View File

@ -1,14 +1,15 @@
package com.topjohnwu.magisk.ui.safetynet
import androidx.databinding.Bindable
import androidx.databinding.ObservableField
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.extensions.subscribeK
import com.topjohnwu.magisk.extensions.value
import com.topjohnwu.magisk.model.events.SafetyNetResult
import com.topjohnwu.magisk.model.events.UpdateSafetyNetEvent
import com.topjohnwu.magisk.ui.base.BaseViewModel
import com.topjohnwu.magisk.ui.safetynet.SafetyNetState.*
import com.topjohnwu.magisk.utils.KObservableField
import com.topjohnwu.magisk.utils.RxBus
import org.json.JSONObject
@ -25,10 +26,10 @@ class SafetynetViewModel(
field = value
notifyStateChanged()
}
val safetyNetTitle = KObservableField(R.string.empty)
val ctsState = KObservableField(false)
val basicIntegrityState = KObservableField(false)
val evalType = KObservableField("")
val safetyNetTitle = ObservableField(R.string.empty)
val ctsState = ObservableField(false)
val basicIntegrityState = ObservableField(false)
val evalType = ObservableField("")
val isChecking @Bindable get() = currentState == LOADING
val isFailed @Bindable get() = currentState == FAILED

View File

@ -13,11 +13,12 @@ import com.topjohnwu.magisk.core.utils.PatchAPK
import com.topjohnwu.magisk.core.utils.Utils
import com.topjohnwu.magisk.data.database.RepoDao
import com.topjohnwu.magisk.extensions.subscribeK
import com.topjohnwu.magisk.extensions.value
import com.topjohnwu.magisk.model.entity.internal.Configuration
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
import com.topjohnwu.magisk.model.entity.recycler.SettingsItem
import com.topjohnwu.magisk.model.events.RxPermissionEvent
import com.topjohnwu.magisk.model.events.RecreateEvent
import com.topjohnwu.magisk.model.events.RxPermissionEvent
import com.topjohnwu.magisk.model.events.dialog.BiometricDialog
import com.topjohnwu.magisk.ui.base.BaseViewModel
import com.topjohnwu.magisk.ui.base.adapterOf

View File

@ -6,6 +6,7 @@ import android.content.pm.PackageManager
import android.content.res.Resources
import android.graphics.drawable.Drawable
import android.os.CountDownTimer
import androidx.databinding.ObservableField
import androidx.lifecycle.viewModelScope
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Config
@ -14,10 +15,10 @@ import com.topjohnwu.magisk.core.model.MagiskPolicy.Companion.ALLOW
import com.topjohnwu.magisk.core.model.MagiskPolicy.Companion.DENY
import com.topjohnwu.magisk.core.su.SuRequestHandler
import com.topjohnwu.magisk.core.utils.BiometricHelper
import com.topjohnwu.magisk.extensions.value
import com.topjohnwu.magisk.model.entity.recycler.SpinnerRvItem
import com.topjohnwu.magisk.model.events.DieEvent
import com.topjohnwu.magisk.ui.base.BaseViewModel
import com.topjohnwu.magisk.utils.KObservableField
import com.topjohnwu.superuser.internal.UiThreadHandler
import kotlinx.coroutines.launch
import me.tatarka.bindingcollectionadapter2.BindingListViewAdapter
@ -31,16 +32,16 @@ class SuRequestViewModel(
private val res: Resources
) : BaseViewModel() {
val icon = KObservableField<Drawable?>(null)
val title = KObservableField("")
val packageName = KObservableField("")
val icon = ObservableField<Drawable?>(null)
val title = ObservableField("")
val packageName = ObservableField("")
val denyText = KObservableField(res.getString(R.string.deny))
val warningText = KObservableField<CharSequence>(res.getString(R.string.su_warning))
val denyText = ObservableField(res.getString(R.string.deny))
val warningText = ObservableField<CharSequence>(res.getString(R.string.su_warning))
val selectedItemPosition = KObservableField(0)
val selectedItemPosition = ObservableField(0)
val grantEnabled = KObservableField(false)
val grantEnabled = ObservableField(false)
private val items = res.getStringArray(R.array.allow_timeout).map { SpinnerRvItem(it) }
val adapter = BindingListViewAdapter<SpinnerRvItem>(1).apply {

View File

@ -1,57 +0,0 @@
package com.topjohnwu.magisk.utils
import androidx.databinding.Observable
import androidx.databinding.ObservableField
import com.topjohnwu.magisk.model.observer.Observer
import java.io.Serializable
/**
* Kotlin version of [ObservableField].
* You can define if wrapped type is Nullable or not.
* You can use kotlin get/set syntax for value
*
* ## Notes
* This stays final for fuck's sake. Too many things depend on it, so you just cannot go around and
* change it randomly. Even though you think you're improving the design, you might be fucking this
* up in unimaginable ways. So DON'T TOUCH THIS.
*
* In order to have value-less observer you need - you guessed it - **a fucking [Observer]**!
*/
class KObservableField<T> : ObservableField<T>, Serializable {
var value: T
set(value) {
if (field != value) {
field = value
notifyChange()
}
}
constructor(init: T) {
value = init
}
constructor(init: T, vararg dependencies: Observable) : super(*dependencies) {
value = init
}
@Deprecated(
message = "Needed for data binding, use KObservableField.value syntax from code",
replaceWith = ReplaceWith("value")
)
override fun get(): T {
return value
}
@Deprecated(
message = "Needed for data binding, use KObservableField.value = ... syntax from code",
replaceWith = ReplaceWith("value = newValue")
)
override fun set(newValue: T) {
value = newValue
}
override fun toString(): String {
return "KObservableField(value=$value)"
}
}

View File

@ -15,6 +15,7 @@ import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatDialog
import androidx.core.view.ViewCompat
import androidx.core.view.updatePadding
import androidx.databinding.ObservableField
import androidx.databinding.ViewDataBinding
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
@ -22,8 +23,8 @@ import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.databinding.ComparableRvItem
import com.topjohnwu.magisk.databinding.DialogMagiskBaseBinding
import com.topjohnwu.magisk.extensions.value
import com.topjohnwu.magisk.ui.base.itemBindingOf
import com.topjohnwu.magisk.utils.KObservableField
import me.tatarka.bindingcollectionadapter2.BindingRecyclerViewAdapters
import me.tatarka.bindingcollectionadapter2.ItemBinding
@ -71,10 +72,10 @@ class MagiskDialog @JvmOverloads constructor(
}
inner class Data {
val icon = KObservableField(0)
val iconRaw = KObservableField<Drawable?>(null)
val title = KObservableField<CharSequence>("")
val message = KObservableField<CharSequence>("")
val icon = ObservableField(0)
val iconRaw = ObservableField<Drawable?>(null)
val title = ObservableField<CharSequence>("")
val message = ObservableField<CharSequence>("")
val buttonPositive = Button()
val buttonNeutral = Button()
@ -87,9 +88,9 @@ class MagiskDialog @JvmOverloads constructor(
}
inner class Button {
val icon = KObservableField(0)
val title = KObservableField<CharSequence>("")
val isEnabled = KObservableField(true)
val icon = ObservableField(0)
val title = ObservableField<CharSequence>("")
val isEnabled = ObservableField(true)
var onClickAction: OnDialogButtonClickListener = {}
var preventDismiss = false