2020-01-12 17:43:09 +01:00
|
|
|
package com.topjohnwu.magisk.ui.hide
|
2019-10-18 17:04:41 +02:00
|
|
|
|
2019-10-30 21:58:42 +01:00
|
|
|
import android.content.pm.ApplicationInfo
|
2019-11-02 18:12:22 +01:00
|
|
|
import androidx.databinding.Bindable
|
2020-07-08 15:14:32 +02:00
|
|
|
import androidx.databinding.ObservableField
|
2019-10-30 21:58:42 +01:00
|
|
|
import com.topjohnwu.magisk.BR
|
2020-01-13 15:01:46 +01:00
|
|
|
import com.topjohnwu.magisk.core.utils.currentLocale
|
2019-10-30 21:58:42 +01:00
|
|
|
import com.topjohnwu.magisk.data.repository.MagiskRepository
|
|
|
|
import com.topjohnwu.magisk.extensions.subscribeK
|
2020-07-08 15:14:32 +02:00
|
|
|
import com.topjohnwu.magisk.extensions.value
|
2019-10-30 21:58:42 +01:00
|
|
|
import com.topjohnwu.magisk.model.entity.HideAppInfo
|
|
|
|
import com.topjohnwu.magisk.model.entity.HideTarget
|
|
|
|
import com.topjohnwu.magisk.model.entity.ProcessHideApp
|
|
|
|
import com.topjohnwu.magisk.model.entity.StatefulProcess
|
|
|
|
import com.topjohnwu.magisk.model.entity.recycler.HideItem
|
|
|
|
import com.topjohnwu.magisk.model.entity.recycler.HideProcessItem
|
2020-01-13 15:01:46 +01:00
|
|
|
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
|
2019-10-18 17:04:41 +02:00
|
|
|
|
2019-10-30 21:58:42 +01:00
|
|
|
class HideViewModel(
|
2019-10-31 20:34:07 +01:00
|
|
|
private val magiskRepo: MagiskRepository
|
2020-07-08 10:26:45 +02:00
|
|
|
) : BaseViewModel(), Queryable {
|
2019-10-30 21:58:42 +01:00
|
|
|
|
2020-07-08 10:26:45 +02:00
|
|
|
override val queryDelay = 1000L
|
2019-11-02 18:12:22 +01:00
|
|
|
|
2019-10-31 20:34:07 +01:00
|
|
|
var isShowSystem = false
|
2019-11-02 18:12:22 +01:00
|
|
|
@Bindable get
|
2019-10-30 21:58:42 +01:00
|
|
|
set(value) {
|
|
|
|
field = value
|
2019-11-02 18:12:22 +01:00
|
|
|
notifyPropertyChanged(BR.showSystem)
|
2020-07-08 10:26:45 +02:00
|
|
|
submitQuery()
|
2019-10-30 21:58:42 +01:00
|
|
|
}
|
|
|
|
|
2019-11-02 18:12:22 +01:00
|
|
|
var query = ""
|
|
|
|
@Bindable get
|
|
|
|
set(value) {
|
|
|
|
field = value
|
|
|
|
notifyPropertyChanged(BR.query)
|
|
|
|
submitQuery()
|
|
|
|
}
|
2019-10-31 20:34:07 +01:00
|
|
|
val items = filterableListOf<HideItem>()
|
2019-10-30 21:58:42 +01:00
|
|
|
val itemBinding = itemBindingOf<HideItem> {
|
|
|
|
it.bindExtra(BR.viewModel, this)
|
|
|
|
}
|
|
|
|
val itemInternalBinding = itemBindingOf<HideProcessItem> {
|
|
|
|
it.bindExtra(BR.viewModel, this)
|
|
|
|
}
|
|
|
|
|
2020-07-08 15:14:32 +02:00
|
|
|
val isFilterExpanded = ObservableField(false)
|
2019-11-02 18:12:22 +01:00
|
|
|
|
2020-07-08 10:50:28 +02:00
|
|
|
override fun rxRefresh() = magiskRepo.fetchApps()
|
2019-10-30 21:58:42 +01:00
|
|
|
.map { it to magiskRepo.fetchHideTargets().blockingGet() }
|
|
|
|
.map { pair -> pair.first.map { mergeAppTargets(it, pair.second) } }
|
|
|
|
.flattenAsFlowable { it }
|
|
|
|
.map { HideItem(it) }
|
|
|
|
.toList()
|
|
|
|
.map { it.sort() }
|
2019-10-31 20:34:07 +01:00
|
|
|
.map { it to items.calculateDiff(it) }
|
2019-10-31 20:53:37 +01:00
|
|
|
.applyViewModel(this)
|
2019-10-30 21:58:42 +01:00
|
|
|
.subscribeK {
|
2019-10-31 20:34:07 +01:00
|
|
|
items.update(it.first, it.second)
|
2019-11-14 18:56:03 +01:00
|
|
|
submitQuery()
|
2019-10-30 21:58:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// ---
|
|
|
|
|
|
|
|
private fun mergeAppTargets(a: HideAppInfo, ts: List<HideTarget>): ProcessHideApp {
|
|
|
|
val relevantTargets = ts.filter { it.packageName == a.info.packageName }
|
2019-10-31 20:34:07 +01:00
|
|
|
val packageName = a.info.packageName
|
2019-10-30 21:58:42 +01:00
|
|
|
val processes = a.processes
|
2019-10-31 20:34:07 +01:00
|
|
|
.map { StatefulProcess(it, packageName, relevantTargets.any { i -> it == i.process }) }
|
2019-10-30 21:58:42 +01:00
|
|
|
return ProcessHideApp(a, processes)
|
|
|
|
}
|
|
|
|
|
2019-10-31 20:34:07 +01:00
|
|
|
private fun List<HideItem>.sort() = compareByDescending<HideItem> { it.itemsChecked.value }
|
|
|
|
.thenBy { it.item.info.name.toLowerCase(currentLocale) }
|
|
|
|
.thenBy { it.item.info.info.packageName }
|
|
|
|
.let { sortedWith(it) }
|
2019-10-30 21:58:42 +01:00
|
|
|
|
|
|
|
// ---
|
|
|
|
|
2020-07-08 10:26:45 +02:00
|
|
|
override fun query() = items.filter {
|
2019-10-31 20:34:07 +01:00
|
|
|
fun filterSystem(): Boolean {
|
2020-07-08 10:26:45 +02:00
|
|
|
return isShowSystem || it.item.info.info.flags and ApplicationInfo.FLAG_SYSTEM == 0
|
2019-10-31 20:34:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
fun filterQuery(): Boolean {
|
2019-10-30 21:58:42 +01:00
|
|
|
val inName = it.item.info.name.contains(query, true)
|
|
|
|
val inPackage = it.item.info.info.packageName.contains(query, true)
|
|
|
|
val inProcesses = it.item.processes.any { it.name.contains(query, true) }
|
2019-10-31 20:34:07 +01:00
|
|
|
return inName || inPackage || inProcesses
|
2019-10-30 21:58:42 +01:00
|
|
|
}
|
2019-10-31 20:34:07 +01:00
|
|
|
|
|
|
|
filterSystem() && filterQuery()
|
|
|
|
}
|
2019-10-30 21:58:42 +01:00
|
|
|
|
|
|
|
// ---
|
|
|
|
|
2019-10-31 20:34:07 +01:00
|
|
|
fun toggleItem(item: HideProcessItem) = magiskRepo
|
|
|
|
.toggleHide(item.isHidden.value, item.item.packageName, item.item.name)
|
2019-10-30 21:58:42 +01:00
|
|
|
|
2019-11-02 18:12:22 +01:00
|
|
|
fun resetQuery() {
|
|
|
|
query = ""
|
|
|
|
}
|
|
|
|
|
|
|
|
fun hideFilter() {
|
|
|
|
isFilterExpanded.value = false
|
|
|
|
}
|
|
|
|
|
2019-10-31 20:34:07 +01:00
|
|
|
}
|
|
|
|
|