Reduce number of calls to getApplicationInfo
Converted PrivacyApplication calls to PackageManager#getApplicationInfo to lazy and removed sort by app name in PrivacyDialogBuilder (only the actual dialog needs that sort). This makes it so the calls to getApplicationInfo are only realized when needed. Test: manual using trace-ipc. In one minute of usage, calls are reduced from ~6000 to 7. Test: atest Test: manual, no change in observed behavior Bug: 122878595 Change-Id: Iff4d2b27b8210687079cb12d1bbae83ba33f8392
This commit is contained in:
@@ -51,6 +51,10 @@ class OngoingPrivacyDialog constructor(
|
||||
private val MAX_ITEMS = context.resources.getInteger(R.integer.ongoing_appops_dialog_max_apps)
|
||||
private val iconFactory = IconDrawableFactory.newInstance(context, true)
|
||||
private var dismissDialog: (() -> Unit)? = null
|
||||
private val appsAndTypes = dialogBuilder.appsAndTypes
|
||||
.sortedWith(compareBy({ -it.second.size }, // Sort by number of AppOps
|
||||
{ it.second.min() },
|
||||
{ it.first }))
|
||||
|
||||
init {
|
||||
val a = context.theme.obtainStyledAttributes(
|
||||
@@ -89,10 +93,10 @@ class OngoingPrivacyDialog constructor(
|
||||
|
||||
title.setText(dialogBuilder.getDialogTitle())
|
||||
|
||||
val numItems = dialogBuilder.appsAndTypes.size
|
||||
val numItems = appsAndTypes.size
|
||||
for (i in 0..(numItems - 1)) {
|
||||
if (i >= MAX_ITEMS) break
|
||||
val item = dialogBuilder.appsAndTypes[i]
|
||||
val item = appsAndTypes[i]
|
||||
addAppItem(appsList, item.first, item.second, dialogBuilder.types.size > 1)
|
||||
}
|
||||
|
||||
|
||||
@@ -30,8 +30,7 @@ class PrivacyDialogBuilder(val context: Context, itemsList: List<PrivacyItem>) {
|
||||
appsAndTypes = itemsList.groupBy({ it.application }, { it.privacyType })
|
||||
.toList()
|
||||
.sortedWith(compareBy({ -it.second.size }, // Sort by number of AppOps
|
||||
{ it.second.min() }, // Sort by "smallest" AppOpp (Location is largest)
|
||||
{ it.first })) // Sort alphabetically bt App Name
|
||||
{ it.second.min() })) // Sort by "smallest" AppOpp (Location is largest)
|
||||
types = itemsList.map { it.privacyType }.distinct().sorted()
|
||||
val singleApp = appsAndTypes.size == 1
|
||||
app = if (singleApp) appsAndTypes[0].first else null
|
||||
|
||||
@@ -44,17 +44,22 @@ data class PrivacyApplication(val packageName: String, val uid: Int, val context
|
||||
return applicationName.compareTo(other.applicationName)
|
||||
}
|
||||
|
||||
var icon: Drawable = context.getDrawable(android.R.drawable.sym_def_app_icon)
|
||||
var applicationName: String
|
||||
|
||||
init {
|
||||
private val applicationInfo: ApplicationInfo? by lazy {
|
||||
try {
|
||||
val app: ApplicationInfo = context.packageManager
|
||||
.getApplicationInfo(packageName, 0)
|
||||
icon = context.packageManager.getApplicationIcon(app)
|
||||
applicationName = context.packageManager.getApplicationLabel(app) as String
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
applicationName = packageName
|
||||
context.packageManager.getApplicationInfo(packageName, 0)
|
||||
} catch (_: PackageManager.NameNotFoundException) {
|
||||
null
|
||||
}
|
||||
}
|
||||
val icon: Drawable by lazy {
|
||||
applicationInfo?.let {
|
||||
context.packageManager.getApplicationIcon(it)
|
||||
} ?: context.getDrawable(android.R.drawable.sym_def_app_icon)
|
||||
}
|
||||
|
||||
val applicationName: String by lazy {
|
||||
applicationInfo?.let {
|
||||
context.packageManager.getApplicationLabel(it) as String
|
||||
} ?: packageName
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ class PrivacyDialogBuilderTest : SysuiTestCase() {
|
||||
"Bar", TEST_UID, context))
|
||||
val bar3 = PrivacyItem(Privacy.TYPE_LOCATION, PrivacyApplication(
|
||||
"Bar", TEST_UID, context))
|
||||
val foo0 = PrivacyItem(Privacy.TYPE_CAMERA, PrivacyApplication(
|
||||
val foo0 = PrivacyItem(Privacy.TYPE_MICROPHONE, PrivacyApplication(
|
||||
"Foo", TEST_UID, context))
|
||||
val baz1 = PrivacyItem(Privacy.TYPE_CAMERA, PrivacyApplication(
|
||||
"Baz", TEST_UID, context))
|
||||
@@ -50,10 +50,11 @@ class PrivacyDialogBuilderTest : SysuiTestCase() {
|
||||
assertEquals(3, list.size)
|
||||
val appsList = list.map { it.first }
|
||||
val typesList = list.map { it.second }
|
||||
// List is sorted by number of types and then by types
|
||||
assertEquals(listOf("Bar", "Baz", "Foo"), appsList.map { it.packageName })
|
||||
assertEquals(listOf(Privacy.TYPE_CAMERA, Privacy.TYPE_LOCATION), typesList[0])
|
||||
assertEquals(listOf(Privacy.TYPE_CAMERA), typesList[1])
|
||||
assertEquals(listOf(Privacy.TYPE_CAMERA), typesList[2])
|
||||
assertEquals(listOf(Privacy.TYPE_MICROPHONE), typesList[2])
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user