Moved fetch/toggle logic for hiding to repo

Fixed sorting
This commit is contained in:
Viktor De Pasquale 2019-05-09 18:21:38 +02:00
parent a6e7680212
commit 21be2f46f3
3 changed files with 62 additions and 47 deletions

View File

@ -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"
)
} }
} }

View File

@ -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()) }
} }

View File

@ -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"
)
}
} }