Don't copy ApplicationInfo

This commit is contained in:
topjohnwu 2021-11-06 23:34:46 -07:00
parent 6dbd8baa7e
commit 3d3bfb42e5
2 changed files with 21 additions and 24 deletions

View File

@ -8,6 +8,7 @@ import android.content.pm.PackageManager.*
import android.content.pm.ServiceInfo import android.content.pm.ServiceInfo
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.os.Build.VERSION.SDK_INT import android.os.Build.VERSION.SDK_INT
import android.os.Process
import com.topjohnwu.magisk.core.utils.currentLocale import com.topjohnwu.magisk.core.utils.currentLocale
import com.topjohnwu.magisk.ktx.getLabel import com.topjohnwu.magisk.ktx.getLabel
import java.util.* import java.util.*
@ -27,22 +28,27 @@ const val ISOLATED_MAGIC = "isolated"
@SuppressLint("InlinedApi") @SuppressLint("InlinedApi")
class AppProcessInfo( class AppProcessInfo(
info: ApplicationInfo, private val info: ApplicationInfo,
pm: PackageManager, pm: PackageManager,
denyList: List<CmdlineListItem> denyList: List<CmdlineListItem>
) : ApplicationInfo(info), Comparable<AppProcessInfo> { ) : Comparable<AppProcessInfo> {
private val denyList = denyList.filter { private val denyList = denyList.filter {
it.packageName == packageName || it.packageName == ISOLATED_MAGIC it.packageName == info.packageName || it.packageName == ISOLATED_MAGIC
} }
val label = getLabel(pm) val label = info.getLabel(pm)
val iconImage: Drawable = loadIcon(pm) val iconImage: Drawable = info.loadIcon(pm)
val packageName: String get() = info.packageName
val processes = fetchProcesses(pm) val processes = fetchProcesses(pm)
override fun compareTo(other: AppProcessInfo) = comparator.compare(this, other) override fun compareTo(other: AppProcessInfo) = comparator.compare(this, other)
private fun createProcess(name: String, pkg: String = packageName) = fun isSystemApp() = info.flags and ApplicationInfo.FLAG_SYSTEM != 0
fun isApp() = Process.isApplicationUid(info.uid)
private fun createProcess(name: String, pkg: String = info.packageName) =
ProcessInfo(name, pkg, denyList.any { it.process == name && it.packageName == pkg }) ProcessInfo(name, pkg, denyList.any { it.process == name && it.packageName == pkg })
private fun ComponentInfo.getProcName(): String = processName private fun ComponentInfo.getProcName(): String = processName
@ -53,12 +59,12 @@ class AppProcessInfo(
private val ServiceInfo.useAppZygote get() = (flags and ServiceInfo.FLAG_USE_APP_ZYGOTE) != 0 private val ServiceInfo.useAppZygote get() = (flags and ServiceInfo.FLAG_USE_APP_ZYGOTE) != 0
private fun Array<out ComponentInfo>?.toProcessList() = private fun Array<out ComponentInfo>?.toProcessList() =
this?.map { createProcess(it.getProcName()) }.orEmpty() orEmpty().map { createProcess(it.getProcName()) }
private fun Array<ServiceInfo>?.toProcessList() = this?.map { private fun Array<ServiceInfo>?.toProcessList() = orEmpty().map {
if (it.isIsolated) { if (it.isIsolated) {
if (it.useAppZygote) { if (it.useAppZygote) {
val proc = processName ?: packageName val proc = info.processName ?: info.packageName
createProcess("${proc}_zygote") createProcess("${proc}_zygote")
} else { } else {
val proc = if (SDK_INT >= 29) "${it.getProcName()}:${it.name}" else it.getProcName() val proc = if (SDK_INT >= 29) "${it.getProcName()}:${it.name}" else it.getProcName()
@ -67,16 +73,16 @@ class AppProcessInfo(
} else { } else {
createProcess(it.getProcName()) createProcess(it.getProcName())
} }
}.orEmpty() }
private fun fetchProcesses(pm: PackageManager): Collection<ProcessInfo> { private fun fetchProcesses(pm: PackageManager): Collection<ProcessInfo> {
val flag = MATCH_DISABLED_COMPONENTS or MATCH_UNINSTALLED_PACKAGES or val flag = MATCH_DISABLED_COMPONENTS or MATCH_UNINSTALLED_PACKAGES or
GET_ACTIVITIES or GET_SERVICES or GET_RECEIVERS or GET_PROVIDERS GET_ACTIVITIES or GET_SERVICES or GET_RECEIVERS or GET_PROVIDERS
val packageInfo = try { val packageInfo = try {
pm.getPackageInfo(packageName, flag) pm.getPackageInfo(info.packageName, flag)
} catch (e: Exception) { } catch (e: Exception) {
// Exceed binder data transfer limit, parse the package locally // Exceed binder data transfer limit, parse the package locally
pm.getPackageArchiveInfo(sourceDir, flag) ?: return emptyList() pm.getPackageArchiveInfo(info.sourceDir, flag) ?: return emptyList()
} }
val processSet = TreeSet<ProcessInfo>(compareBy{ it.name }) val processSet = TreeSet<ProcessInfo>(compareBy{ it.name })
@ -90,7 +96,7 @@ class AppProcessInfo(
companion object { companion object {
private val comparator = compareBy<AppProcessInfo>( private val comparator = compareBy<AppProcessInfo>(
{ it.label.lowercase(currentLocale) }, { it.label.lowercase(currentLocale) },
{ it.packageName } { it.info.packageName }
) )
} }
} }

View File

@ -1,9 +1,7 @@
package com.topjohnwu.magisk.ui.deny package com.topjohnwu.magisk.ui.deny
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES import android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES
import android.os.Process
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.arch.BaseViewModel import com.topjohnwu.magisk.arch.BaseViewModel
@ -75,17 +73,10 @@ class DenyListViewModel : BaseViewModel(), Queryable {
} }
override fun query() { override fun query() {
fun isApp(uid: Int) = run {
val appId: Int = uid % 100000
appId >= Process.FIRST_APPLICATION_UID && appId <= Process.LAST_APPLICATION_UID
}
fun isSystemApp(flag: Int) = flag and ApplicationInfo.FLAG_SYSTEM != 0
items.filter { items.filter {
fun filterSystem() = isShowSystem || !isSystemApp(it.info.flags) fun filterSystem() = isShowSystem || !it.info.isSystemApp()
fun filterOS() = (isShowSystem && isShowOS) || isApp(it.info.uid) fun filterOS() = (isShowSystem && isShowOS) || it.info.isApp()
fun filterQuery(): Boolean { fun filterQuery(): Boolean {
fun inName() = it.info.label.contains(query, true) fun inName() = it.info.label.contains(query, true)