Moved fetch/toggle logic for hiding to repo
Fixed sorting
This commit is contained in:
parent
a6e7680212
commit
21be2f46f3
@ -1,17 +1,27 @@
|
|||||||
package com.topjohnwu.magisk.data.repository
|
package com.topjohnwu.magisk.data.repository
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import com.topjohnwu.magisk.App
|
||||||
import com.topjohnwu.magisk.KConfig
|
import com.topjohnwu.magisk.KConfig
|
||||||
|
import com.topjohnwu.magisk.data.database.base.su
|
||||||
import com.topjohnwu.magisk.data.database.base.suRaw
|
import com.topjohnwu.magisk.data.database.base.suRaw
|
||||||
import com.topjohnwu.magisk.data.network.GithubRawApiServices
|
import com.topjohnwu.magisk.data.network.GithubRawApiServices
|
||||||
|
import com.topjohnwu.magisk.model.entity.HideAppInfo
|
||||||
|
import com.topjohnwu.magisk.model.entity.HideTarget
|
||||||
import com.topjohnwu.magisk.model.entity.Version
|
import com.topjohnwu.magisk.model.entity.Version
|
||||||
|
import com.topjohnwu.magisk.utils.Utils
|
||||||
|
import com.topjohnwu.magisk.utils.inject
|
||||||
|
import com.topjohnwu.magisk.utils.toSingle
|
||||||
import com.topjohnwu.magisk.utils.writeToFile
|
import com.topjohnwu.magisk.utils.writeToFile
|
||||||
|
import com.topjohnwu.superuser.Shell
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import io.reactivex.functions.BiFunction
|
import io.reactivex.functions.BiFunction
|
||||||
|
|
||||||
class MagiskRepository(
|
class MagiskRepository(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val apiRaw: GithubRawApiServices
|
private val apiRaw: GithubRawApiServices,
|
||||||
|
private val packageManager: PackageManager
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private val config = apiRaw.fetchConfig()
|
private val config = apiRaw.fetchConfig()
|
||||||
@ -57,6 +67,25 @@ class MagiskRepository(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
fun fetchApps() =
|
||||||
|
Single.fromCallable { packageManager.getInstalledApplications(0) }
|
||||||
|
.flattenAsFlowable { it }
|
||||||
|
.filter { it.enabled && !blacklist.contains(it.packageName) }
|
||||||
|
.map {
|
||||||
|
val label = Utils.getAppLabel(it, packageManager)
|
||||||
|
val icon = it.loadIcon(packageManager)
|
||||||
|
HideAppInfo(it, label, icon)
|
||||||
|
}
|
||||||
|
.filter { it.processes.isNotEmpty() }
|
||||||
|
.toList()
|
||||||
|
|
||||||
|
fun fetchHideTargets() = Shell.su("magiskhide --ls").toSingle()
|
||||||
|
.map { it.exec().out }
|
||||||
|
.flattenAsFlowable { it }
|
||||||
|
.map { HideTarget(it) }
|
||||||
|
.toList()
|
||||||
|
|
||||||
private fun fetchMagiskVersionName() = "magisk -v".suRaw()
|
private fun fetchMagiskVersionName() = "magisk -v".suRaw()
|
||||||
.map { it.first() }
|
.map { it.first() }
|
||||||
.map { it.substring(0 until it.indexOf(":")) }
|
.map { it.substring(0 until it.indexOf(":")) }
|
||||||
@ -67,12 +96,28 @@ class MagiskRepository(
|
|||||||
.map { it.toIntOrNull() ?: -1 }
|
.map { it.toIntOrNull() ?: -1 }
|
||||||
.onErrorReturn { -1 }
|
.onErrorReturn { -1 }
|
||||||
|
|
||||||
|
fun toggleHide(isEnabled: Boolean, packageName: String, process: String) =
|
||||||
|
"magiskhide --%s %s %s".format(isEnabled.state, packageName, process).su().ignoreElement()
|
||||||
|
|
||||||
|
private val Boolean.state get() = if (this) "add" else "rm"
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val FILE_MAGISK_ZIP = "magisk.zip"
|
const val FILE_MAGISK_ZIP = "magisk.zip"
|
||||||
const val FILE_MAGISK_APK = "magisk.apk"
|
const val FILE_MAGISK_APK = "magisk.apk"
|
||||||
const val FILE_UNINSTALLER_ZIP = "uninstaller.zip"
|
const val FILE_UNINSTALLER_ZIP = "uninstaller.zip"
|
||||||
const val FILE_SAFETY_NET_APK = "safetynet.apk"
|
const val FILE_SAFETY_NET_APK = "safetynet.apk"
|
||||||
const val FILE_BOOTCTL_SH = "bootctl"
|
const val FILE_BOOTCTL_SH = "bootctl"
|
||||||
|
|
||||||
|
private val blacklist = listOf(
|
||||||
|
let { val app: App by inject(); app }.packageName,
|
||||||
|
"android",
|
||||||
|
"com.android.chrome",
|
||||||
|
"com.chrome.beta",
|
||||||
|
"com.chrome.dev",
|
||||||
|
"com.chrome.canary",
|
||||||
|
"com.android.webview",
|
||||||
|
"com.google.android.webview"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -7,7 +7,7 @@ import org.koin.dsl.module
|
|||||||
|
|
||||||
|
|
||||||
val repositoryModule = module {
|
val repositoryModule = module {
|
||||||
single { MagiskRepository(get(), get()) }
|
single { MagiskRepository(get(), get(), get()) }
|
||||||
single { ModuleRepository(get(), get(), get(), get()) }
|
single { ModuleRepository(get(), get(), get(), get()) }
|
||||||
single { LogRepository(get()) }
|
single { LogRepository(get()) }
|
||||||
}
|
}
|
||||||
|
@ -1,32 +1,26 @@
|
|||||||
package com.topjohnwu.magisk.ui.hide
|
package com.topjohnwu.magisk.ui.hide
|
||||||
|
|
||||||
import android.content.pm.ApplicationInfo
|
import android.content.pm.ApplicationInfo
|
||||||
import android.content.pm.PackageManager
|
|
||||||
import com.skoumal.teanity.databinding.ComparableRvItem
|
import com.skoumal.teanity.databinding.ComparableRvItem
|
||||||
import com.skoumal.teanity.extensions.addOnPropertyChangedCallback
|
import com.skoumal.teanity.extensions.addOnPropertyChangedCallback
|
||||||
import com.skoumal.teanity.extensions.subscribeK
|
import com.skoumal.teanity.extensions.subscribeK
|
||||||
import com.skoumal.teanity.rxbus.RxBus
|
import com.skoumal.teanity.rxbus.RxBus
|
||||||
import com.skoumal.teanity.util.DiffObservableList
|
import com.skoumal.teanity.util.DiffObservableList
|
||||||
import com.skoumal.teanity.util.KObservableField
|
import com.skoumal.teanity.util.KObservableField
|
||||||
import com.topjohnwu.magisk.App
|
|
||||||
import com.topjohnwu.magisk.BR
|
import com.topjohnwu.magisk.BR
|
||||||
import com.topjohnwu.magisk.model.entity.HideAppInfo
|
import com.topjohnwu.magisk.data.repository.MagiskRepository
|
||||||
import com.topjohnwu.magisk.model.entity.HideTarget
|
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.HideProcessRvItem
|
import com.topjohnwu.magisk.model.entity.recycler.HideProcessRvItem
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.HideRvItem
|
import com.topjohnwu.magisk.model.entity.recycler.HideRvItem
|
||||||
import com.topjohnwu.magisk.model.entity.state.IndeterminateState
|
import com.topjohnwu.magisk.model.entity.state.IndeterminateState
|
||||||
import com.topjohnwu.magisk.model.events.HideProcessEvent
|
import com.topjohnwu.magisk.model.events.HideProcessEvent
|
||||||
import com.topjohnwu.magisk.ui.base.MagiskViewModel
|
import com.topjohnwu.magisk.ui.base.MagiskViewModel
|
||||||
import com.topjohnwu.magisk.utils.Utils
|
|
||||||
import com.topjohnwu.magisk.utils.toSingle
|
import com.topjohnwu.magisk.utils.toSingle
|
||||||
import com.topjohnwu.magisk.utils.update
|
import com.topjohnwu.magisk.utils.update
|
||||||
import com.topjohnwu.superuser.Shell
|
|
||||||
import io.reactivex.Single
|
|
||||||
import me.tatarka.bindingcollectionadapter2.OnItemBind
|
import me.tatarka.bindingcollectionadapter2.OnItemBind
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
class HideViewModel(
|
class HideViewModel(
|
||||||
private val packageManager: PackageManager,
|
private val magiskRepo: MagiskRepository,
|
||||||
rxBus: RxBus
|
rxBus: RxBus
|
||||||
) : MagiskViewModel() {
|
) : MagiskViewModel() {
|
||||||
|
|
||||||
@ -55,26 +49,19 @@ class HideViewModel(
|
|||||||
// fetching this for every item is nonsensical, so we add .cache() so the response is all
|
// fetching this for every item is nonsensical, so we add .cache() so the response is all
|
||||||
// the same for every single mapped item, it only actually executes the whole thing the
|
// the same for every single mapped item, it only actually executes the whole thing the
|
||||||
// first time around.
|
// first time around.
|
||||||
val hideTargets = Shell.su("magiskhide --ls").toSingle()
|
val hideTargets = magiskRepo.fetchHideTargets().cache()
|
||||||
.map { it.exec().out }
|
|
||||||
.flattenAsFlowable { it }
|
|
||||||
.map { HideTarget(it) }
|
|
||||||
.toList()
|
|
||||||
.cache()
|
|
||||||
|
|
||||||
Single.fromCallable { packageManager.getInstalledApplications(0) }
|
magiskRepo.fetchApps()
|
||||||
.flattenAsFlowable { it }
|
.flattenAsFlowable { it }
|
||||||
.filter { it.enabled && !blacklist.contains(it.packageName) }
|
|
||||||
.map {
|
|
||||||
val label = Utils.getAppLabel(it, packageManager)
|
|
||||||
val icon = it.loadIcon(packageManager)
|
|
||||||
HideAppInfo(it, label, icon)
|
|
||||||
}
|
|
||||||
.filter { it.processes.isNotEmpty() }
|
|
||||||
.map { HideRvItem(it, hideTargets.blockingGet()) }
|
.map { HideRvItem(it, hideTargets.blockingGet()) }
|
||||||
.toList()
|
.toList()
|
||||||
.map { it.sortWith(compareBy(
|
.map {
|
||||||
{it.isHiddenState.value}, {it.item.info.name}, {it.packageName})); it }
|
it.sortedWith(compareBy(
|
||||||
|
{ it.isHiddenState.value },
|
||||||
|
{ it.item.name.toLowerCase() },
|
||||||
|
{ it.packageName }
|
||||||
|
))
|
||||||
|
}
|
||||||
.doOnSuccess { allItems.update(it) }
|
.doOnSuccess { allItems.update(it) }
|
||||||
.flatMap { queryRaw() }
|
.flatMap { queryRaw() }
|
||||||
.applyViewModel(this)
|
.applyViewModel(this)
|
||||||
@ -103,26 +90,9 @@ class HideViewModel(
|
|||||||
.toList()
|
.toList()
|
||||||
.map { it to items.calculateDiff(it) }
|
.map { it to items.calculateDiff(it) }
|
||||||
|
|
||||||
private fun toggleItem(item: HideProcessRvItem) {
|
private fun toggleItem(item: HideProcessRvItem) = magiskRepo
|
||||||
val state = if (item.isHidden.value) "add" else "rm"
|
.toggleHide(item.isHidden.value, item.packageName, item.process)
|
||||||
"magiskhide --%s %s %s".format(state, item.packageName, item.process)
|
|
||||||
.let { Shell.su(it) }
|
|
||||||
.toSingle()
|
|
||||||
.map { it.submit() }
|
|
||||||
.subscribeK()
|
.subscribeK()
|
||||||
}
|
.add()
|
||||||
|
|
||||||
companion object {
|
|
||||||
private val blacklist = listOf(
|
|
||||||
App.self.packageName,
|
|
||||||
"android",
|
|
||||||
"com.android.chrome",
|
|
||||||
"com.chrome.beta",
|
|
||||||
"com.chrome.dev",
|
|
||||||
"com.chrome.canary",
|
|
||||||
"com.android.webview",
|
|
||||||
"com.google.android.webview"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user