Merge "Fix up discrepancies between v1 and v2 package parsing" into rvc-dev-plus-aosp
This commit is contained in:
@@ -302,7 +302,14 @@ public class ParsedActivityUtils {
|
||||
}
|
||||
|
||||
String permission = array.getNonConfigurationString(permissionAttr, 0);
|
||||
activity.setPermission(permission != null ? permission : pkg.getPermission());
|
||||
if (isAlias) {
|
||||
// An alias will override permissions to allow referencing an Activity through its alias
|
||||
// without needing the original permission. If an alias needs the same permission,
|
||||
// it must be re-declared.
|
||||
activity.setPermission(permission);
|
||||
} else {
|
||||
activity.setPermission(permission != null ? permission : pkg.getPermission());
|
||||
}
|
||||
|
||||
final boolean setExported = array.hasValue(exportedAttr);
|
||||
if (setExported) {
|
||||
|
||||
@@ -20,7 +20,10 @@ import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.parsing.ParsingPackage;
|
||||
import android.content.pm.parsing.ParsingPackageUtils;
|
||||
import android.content.pm.parsing.ParsingUtils;
|
||||
import android.content.pm.parsing.result.ParseInput;
|
||||
import android.content.pm.parsing.result.ParseResult;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.content.res.XmlResourceParser;
|
||||
@@ -29,9 +32,6 @@ import android.text.TextUtils;
|
||||
import android.util.TypedValue;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import android.content.pm.parsing.ParsingPackageUtils;
|
||||
import android.content.pm.parsing.result.ParseInput;
|
||||
import android.content.pm.parsing.result.ParseResult;
|
||||
|
||||
/** @hide */
|
||||
class ParsedComponentUtils {
|
||||
@@ -60,16 +60,27 @@ class ParsedComponentUtils {
|
||||
component.setName(className);
|
||||
component.setPackageName(packageName);
|
||||
|
||||
if (useRoundIcon) {
|
||||
component.icon = array.getResourceId(roundIconAttr, 0);
|
||||
int roundIconVal = useRoundIcon ? array.getResourceId(roundIconAttr, 0) : 0;
|
||||
if (roundIconVal != 0) {
|
||||
component.icon = roundIconVal;
|
||||
component.nonLocalizedLabel = null;
|
||||
} else {
|
||||
int iconVal = array.getResourceId(iconAttr, 0);
|
||||
if (iconVal != 0) {
|
||||
component.icon = iconVal;
|
||||
component.nonLocalizedLabel = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (component.icon == 0) {
|
||||
component.icon = array.getResourceId(iconAttr, 0);
|
||||
int logoVal = array.getResourceId(logoAttr, 0);
|
||||
if (logoVal != 0) {
|
||||
component.logo = logoVal;
|
||||
}
|
||||
|
||||
component.logo = array.getResourceId(logoAttr, 0);
|
||||
component.banner = array.getResourceId(bannerAttr, 0);
|
||||
int bannerVal = array.getResourceId(bannerAttr, 0);
|
||||
if (bannerVal != 0) {
|
||||
component.banner = bannerVal;
|
||||
}
|
||||
|
||||
if (descriptionAttr != null) {
|
||||
component.descriptionRes = array.getResourceId(descriptionAttr, 0);
|
||||
|
||||
@@ -18,9 +18,9 @@ package com.android.server.pm.parsing
|
||||
|
||||
import android.content.pm.PackageManager
|
||||
import android.platform.test.annotations.Presubmit
|
||||
import androidx.test.filters.LargeTest
|
||||
import com.google.common.truth.Expect
|
||||
import com.google.common.truth.Truth.assertWithMessage
|
||||
import org.junit.Ignore
|
||||
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
@@ -35,7 +35,6 @@ class AndroidPackageParsingEquivalenceTest : AndroidPackageParsingTestBase() {
|
||||
val expect = Expect.create()
|
||||
|
||||
@Test
|
||||
@Ignore("b/155935153")
|
||||
fun applicationInfoEquality() {
|
||||
val flags = PackageManager.GET_META_DATA or PackageManager.GET_SHARED_LIBRARY_FILES
|
||||
val oldAppInfo = oldPackages.asSequence().map { oldAppInfo(it, flags) }
|
||||
@@ -54,8 +53,8 @@ class AndroidPackageParsingEquivalenceTest : AndroidPackageParsingTestBase() {
|
||||
}
|
||||
}
|
||||
|
||||
@LargeTest
|
||||
@Test
|
||||
@Ignore("b/155935153")
|
||||
fun packageInfoEquality() {
|
||||
val flags = PackageManager.GET_ACTIVITIES or
|
||||
PackageManager.GET_CONFIGURATIONS or
|
||||
@@ -68,7 +67,9 @@ class AndroidPackageParsingEquivalenceTest : AndroidPackageParsingTestBase() {
|
||||
PackageManager.GET_SERVICES or
|
||||
PackageManager.GET_SHARED_LIBRARY_FILES or
|
||||
PackageManager.GET_SIGNATURES or
|
||||
PackageManager.GET_SIGNING_CERTIFICATES
|
||||
PackageManager.GET_SIGNING_CERTIFICATES or
|
||||
PackageManager.MATCH_DIRECT_BOOT_UNAWARE or
|
||||
PackageManager.MATCH_DIRECT_BOOT_AWARE
|
||||
val oldPackageInfo = oldPackages.asSequence().map { oldPackageInfo(it, flags) }
|
||||
val newPackageInfo = newPackages.asSequence().map { newPackageInfo(it, flags) }
|
||||
|
||||
@@ -80,11 +81,79 @@ class AndroidPackageParsingEquivalenceTest : AndroidPackageParsingTestBase() {
|
||||
} else {
|
||||
"$firstName | $secondName"
|
||||
}
|
||||
expect.withMessage("${it.first?.applicationInfo?.sourceDir} $packageName")
|
||||
.that(it.first?.dumpToString())
|
||||
.isEqualTo(it.second?.dumpToString())
|
||||
|
||||
// Main components are asserted independently to separate the failures. Otherwise the
|
||||
// comparison would include every component in one massive string.
|
||||
|
||||
val prefix = "${it.first?.applicationInfo?.sourceDir} $packageName"
|
||||
|
||||
expect.withMessage("$prefix PackageInfo")
|
||||
.that(it.second?.dumpToString())
|
||||
.isEqualTo(it.first?.dumpToString())
|
||||
|
||||
expect.withMessage("$prefix ApplicationInfo")
|
||||
.that(it.second?.applicationInfo?.dumpToString())
|
||||
.isEqualTo(it.first?.applicationInfo?.dumpToString())
|
||||
|
||||
val firstActivityNames = it.first?.activities?.map { it.name } ?: emptyList()
|
||||
val secondActivityNames = it.second?.activities?.map { it.name } ?: emptyList()
|
||||
expect.withMessage("$prefix activities")
|
||||
.that(secondActivityNames)
|
||||
.containsExactlyElementsIn(firstActivityNames)
|
||||
.inOrder()
|
||||
|
||||
if (!it.first?.activities.isNullOrEmpty() && !it.second?.activities.isNullOrEmpty()) {
|
||||
it.first?.activities?.zip(it.second?.activities!!)?.forEach {
|
||||
expect.withMessage("$prefix ${it.first.name}")
|
||||
.that(it.second.dumpToString())
|
||||
.isEqualTo(it.first.dumpToString())
|
||||
}
|
||||
}
|
||||
|
||||
val firstReceiverNames = it.first?.receivers?.map { it.name } ?: emptyList()
|
||||
val secondReceiverNames = it.second?.receivers?.map { it.name } ?: emptyList()
|
||||
expect.withMessage("$prefix receivers")
|
||||
.that(secondReceiverNames)
|
||||
.containsExactlyElementsIn(firstReceiverNames)
|
||||
.inOrder()
|
||||
|
||||
if (!it.first?.receivers.isNullOrEmpty() && !it.second?.receivers.isNullOrEmpty()) {
|
||||
it.first?.receivers?.zip(it.second?.receivers!!)?.forEach {
|
||||
expect.withMessage("$prefix ${it.first.name}")
|
||||
.that(it.second.dumpToString())
|
||||
.isEqualTo(it.first.dumpToString())
|
||||
}
|
||||
}
|
||||
|
||||
val firstProviderNames = it.first?.providers?.map { it.name } ?: emptyList()
|
||||
val secondProviderNames = it.second?.providers?.map { it.name } ?: emptyList()
|
||||
expect.withMessage("$prefix providers")
|
||||
.that(secondProviderNames)
|
||||
.containsExactlyElementsIn(firstProviderNames)
|
||||
.inOrder()
|
||||
|
||||
if (!it.first?.providers.isNullOrEmpty() && !it.second?.providers.isNullOrEmpty()) {
|
||||
it.first?.providers?.zip(it.second?.providers!!)?.forEach {
|
||||
expect.withMessage("$prefix ${it.first.name}")
|
||||
.that(it.second.dumpToString())
|
||||
.isEqualTo(it.first.dumpToString())
|
||||
}
|
||||
}
|
||||
|
||||
val firstServiceNames = it.first?.services?.map { it.name } ?: emptyList()
|
||||
val secondServiceNames = it.second?.services?.map { it.name } ?: emptyList()
|
||||
expect.withMessage("$prefix services")
|
||||
.that(secondServiceNames)
|
||||
.containsExactlyElementsIn(firstServiceNames)
|
||||
.inOrder()
|
||||
|
||||
if (!it.first?.services.isNullOrEmpty() && !it.second?.services.isNullOrEmpty()) {
|
||||
it.first?.services?.zip(it.second?.services!!)?.forEach {
|
||||
expect.withMessage("$prefix ${it.first.name}")
|
||||
.that(it.second.dumpToString())
|
||||
.isEqualTo(it.first.dumpToString())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.server.pm.parsing
|
||||
import android.content.Context
|
||||
import android.content.pm.ActivityInfo
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.content.pm.ComponentInfo
|
||||
import android.content.pm.ConfigurationInfo
|
||||
import android.content.pm.FeatureInfo
|
||||
import android.content.pm.InstrumentationInfo
|
||||
@@ -27,6 +28,8 @@ import android.content.pm.PackageParser
|
||||
import android.content.pm.PackageUserState
|
||||
import android.content.pm.PermissionInfo
|
||||
import android.content.pm.ProviderInfo
|
||||
import android.content.pm.ServiceInfo
|
||||
import android.os.Bundle
|
||||
import android.os.Debug
|
||||
import android.os.Environment
|
||||
import android.util.SparseArray
|
||||
@@ -38,8 +41,10 @@ import com.android.server.pm.pkg.PackageStateUnserialized
|
||||
import com.android.server.testutils.mockThrowOnUnmocked
|
||||
import com.android.server.testutils.whenever
|
||||
import org.junit.BeforeClass
|
||||
import org.mockito.Mockito
|
||||
import org.mockito.Mockito.any
|
||||
import org.mockito.Mockito.anyBoolean
|
||||
import org.mockito.Mockito.anyInt
|
||||
import org.mockito.Mockito.anyString
|
||||
import org.mockito.Mockito.mock
|
||||
import java.io.File
|
||||
|
||||
@@ -47,7 +52,7 @@ open class AndroidPackageParsingTestBase {
|
||||
|
||||
companion object {
|
||||
|
||||
private const val VERIFY_ALL_APKS = false
|
||||
private const val VERIFY_ALL_APKS = true
|
||||
|
||||
/** For auditing memory usage differences */
|
||||
private const val DUMP_HPROF_TO_EXTERNAL = false
|
||||
@@ -81,10 +86,14 @@ open class AndroidPackageParsingTestBase {
|
||||
.filter { file -> file.name.endsWith(".apk") }
|
||||
.toList()
|
||||
}
|
||||
.distinct()
|
||||
|
||||
private val dummyUserState = mock(PackageUserState::class.java).apply {
|
||||
installed = true
|
||||
Mockito.`when`(isAvailable(anyInt())).thenReturn(true)
|
||||
whenever(isAvailable(anyInt())) { true }
|
||||
whenever(isMatch(any<ComponentInfo>(), anyInt())) { true }
|
||||
whenever(isMatch(anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean(),
|
||||
anyString(), anyInt())) { true }
|
||||
}
|
||||
|
||||
lateinit var oldPackages: List<PackageParser.Package>
|
||||
@@ -145,6 +154,7 @@ open class AndroidPackageParsingTestBase {
|
||||
private fun mockPkgSetting(aPkg: AndroidPackage) = mockThrowOnUnmocked<PackageSetting> {
|
||||
this.pkg = aPkg
|
||||
whenever(pkgState) { PackageStateUnserialized() }
|
||||
whenever(readUserState(anyInt())) { dummyUserState }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,19 +166,10 @@ open class AndroidPackageParsingTestBase {
|
||||
// The following methods prepend "this." because @hide APIs can cause an IDE to auto-import
|
||||
// the R.attr constant instead of referencing the field in an attempt to fix the error.
|
||||
|
||||
/**
|
||||
* Known exclusions:
|
||||
* - [ApplicationInfo.credentialProtectedDataDir]
|
||||
* - [ApplicationInfo.dataDir]
|
||||
* - [ApplicationInfo.deviceProtectedDataDir]
|
||||
* - [ApplicationInfo.processName]
|
||||
* - [ApplicationInfo.publicSourceDir]
|
||||
* - [ApplicationInfo.scanPublicSourceDir]
|
||||
* - [ApplicationInfo.scanSourceDir]
|
||||
* - [ApplicationInfo.sourceDir]
|
||||
* These attributes used to be assigned post-package-parsing as part of another component,
|
||||
* but are now adjusted directly inside [PackageImpl].
|
||||
*/
|
||||
// It's difficult to comment out a line in a triple quoted string, so this is used instead
|
||||
// to ignore specific fields. A comment is required to explain why a field was ignored.
|
||||
private fun Any?.ignored(comment: String): String = "IGNORED"
|
||||
|
||||
protected fun ApplicationInfo.dumpToString() = """
|
||||
appComponentFactory=${this.appComponentFactory}
|
||||
backupAgentName=${this.backupAgentName}
|
||||
@@ -179,22 +180,31 @@ open class AndroidPackageParsingTestBase {
|
||||
compatibleWidthLimitDp=${this.compatibleWidthLimitDp}
|
||||
compileSdkVersion=${this.compileSdkVersion}
|
||||
compileSdkVersionCodename=${this.compileSdkVersionCodename}
|
||||
credentialProtectedDataDir=${this.credentialProtectedDataDir
|
||||
.ignored("Deferred pre-R, but assigned immediately in R")}
|
||||
crossProfile=${this.crossProfile.ignored("Added in R")}
|
||||
dataDir=${this.dataDir.ignored("Deferred pre-R, but assigned immediately in R")}
|
||||
descriptionRes=${this.descriptionRes}
|
||||
deviceProtectedDataDir=${this.deviceProtectedDataDir
|
||||
.ignored("Deferred pre-R, but assigned immediately in R")}
|
||||
enabled=${this.enabled}
|
||||
enabledSetting=${this.enabledSetting}
|
||||
flags=${Integer.toBinaryString(this.flags)}
|
||||
fullBackupContent=${this.fullBackupContent}
|
||||
gwpAsanMode=${this.gwpAsanMode.ignored("Added in R")}
|
||||
hiddenUntilInstalled=${this.hiddenUntilInstalled}
|
||||
icon=${this.icon}
|
||||
iconRes=${this.iconRes}
|
||||
installLocation=${this.installLocation}
|
||||
labelRes=${this.labelRes}
|
||||
largestWidthLimitDp=${this.largestWidthLimitDp}
|
||||
logo=${this.logo}
|
||||
longVersionCode=${this.longVersionCode}
|
||||
${"".ignored("mHiddenApiPolicy is a private field")}
|
||||
manageSpaceActivityName=${this.manageSpaceActivityName}
|
||||
maxAspectRatio.compareTo(that.maxAspectRatio)=${this.maxAspectRatio}
|
||||
metaData=${this.metaData}
|
||||
minAspectRatio.compareTo(that.minAspectRatio)=${this.minAspectRatio}
|
||||
maxAspectRatio=${this.maxAspectRatio}
|
||||
metaData=${this.metaData.dumpToString()}
|
||||
minAspectRatio=${this.minAspectRatio}
|
||||
minSdkVersion=${this.minSdkVersion}
|
||||
name=${this.name}
|
||||
nativeLibraryDir=${this.nativeLibraryDir}
|
||||
@@ -206,18 +216,27 @@ open class AndroidPackageParsingTestBase {
|
||||
permission=${this.permission}
|
||||
primaryCpuAbi=${this.primaryCpuAbi}
|
||||
privateFlags=${Integer.toBinaryString(this.privateFlags)}
|
||||
processName=${this.processName.ignored("Deferred pre-R, but assigned immediately in R")}
|
||||
publicSourceDir=${this.publicSourceDir
|
||||
.ignored("Deferred pre-R, but assigned immediately in R")}
|
||||
requiresSmallestWidthDp=${this.requiresSmallestWidthDp}
|
||||
resourceDirs=${this.resourceDirs?.contentToString()}
|
||||
roundIconRes=${this.roundIconRes}
|
||||
secondaryCpuAbi=${this.secondaryCpuAbi}
|
||||
secondaryNativeLibraryDir=${this.secondaryNativeLibraryDir}
|
||||
scanPublicSourceDir=${this.scanPublicSourceDir
|
||||
.ignored("Deferred pre-R, but assigned immediately in R")}
|
||||
scanSourceDir=${this.scanSourceDir
|
||||
.ignored("Deferred pre-R, but assigned immediately in R")}
|
||||
seInfo=${this.seInfo}
|
||||
seInfoUser=${this.seInfoUser}
|
||||
secondaryCpuAbi=${this.secondaryCpuAbi}
|
||||
secondaryNativeLibraryDir=${this.secondaryNativeLibraryDir}
|
||||
sharedLibraryFiles=${this.sharedLibraryFiles?.contentToString()}
|
||||
sharedLibraryInfos=${this.sharedLibraryInfos}
|
||||
showUserIcon=${this.showUserIcon}
|
||||
sourceDir=${this.sourceDir
|
||||
.ignored("Deferred pre-R, but assigned immediately in R")}
|
||||
splitClassLoaderNames=${this.splitClassLoaderNames?.contentToString()}
|
||||
splitDependencies=${this.splitDependencies}
|
||||
splitDependencies=${this.splitDependencies.dumpToString()}
|
||||
splitNames=${this.splitNames?.contentToString()}
|
||||
splitPublicSourceDirs=${this.splitPublicSourceDirs?.contentToString()}
|
||||
splitSourceDirs=${this.splitSourceDirs?.contentToString()}
|
||||
@@ -226,8 +245,8 @@ open class AndroidPackageParsingTestBase {
|
||||
targetSdkVersion=${this.targetSdkVersion}
|
||||
taskAffinity=${this.taskAffinity}
|
||||
theme=${this.theme}
|
||||
uid=${this.uid}
|
||||
uiOptions=${this.uiOptions}
|
||||
uid=${this.uid}
|
||||
versionCode=${this.versionCode}
|
||||
volumeUuid=${this.volumeUuid}
|
||||
zygotePreloadName=${this.zygotePreloadName}
|
||||
@@ -241,19 +260,27 @@ open class AndroidPackageParsingTestBase {
|
||||
""".trimIndent()
|
||||
|
||||
protected fun InstrumentationInfo.dumpToString() = """
|
||||
banner=${this.banner}
|
||||
credentialProtectedDataDir=${this.credentialProtectedDataDir}
|
||||
dataDir=${this.dataDir}
|
||||
deviceProtectedDataDir=${this.deviceProtectedDataDir}
|
||||
functionalTest=${this.functionalTest}
|
||||
handleProfiling=${this.handleProfiling}
|
||||
icon=${this.icon}
|
||||
labelRes=${this.labelRes}
|
||||
logo=${this.logo}
|
||||
metaData=${this.metaData}
|
||||
name=${this.name}
|
||||
nativeLibraryDir=${this.nativeLibraryDir}
|
||||
nonLocalizedLabel=${this.nonLocalizedLabel}
|
||||
packageName=${this.packageName}
|
||||
primaryCpuAbi=${this.primaryCpuAbi}
|
||||
publicSourceDir=${this.publicSourceDir}
|
||||
secondaryCpuAbi=${this.secondaryCpuAbi}
|
||||
secondaryNativeLibraryDir=${this.secondaryNativeLibraryDir}
|
||||
showUserIcon=${this.showUserIcon}
|
||||
sourceDir=${this.sourceDir}
|
||||
splitDependencies=${this.splitDependencies.sequence()
|
||||
.map { it.first to it.second?.contentToString() }.joinToString()}
|
||||
splitDependencies=${this.splitDependencies.dumpToString()}
|
||||
splitNames=${this.splitNames?.contentToString()}
|
||||
splitPublicSourceDirs=${this.splitPublicSourceDirs?.contentToString()}
|
||||
splitSourceDirs=${this.splitSourceDirs?.contentToString()}
|
||||
@@ -262,25 +289,40 @@ open class AndroidPackageParsingTestBase {
|
||||
""".trimIndent()
|
||||
|
||||
protected fun ActivityInfo.dumpToString() = """
|
||||
banner=${this.banner}
|
||||
colorMode=${this.colorMode}
|
||||
configChanges=${this.configChanges}
|
||||
descriptionRes=${this.descriptionRes}
|
||||
directBootAware=${this.directBootAware}
|
||||
documentLaunchMode=${this.documentLaunchMode}
|
||||
enabled=${this.enabled}
|
||||
exported=${this.exported}
|
||||
flags=${Integer.toBinaryString(this.flags)}
|
||||
icon=${this.icon}
|
||||
labelRes=${this.labelRes}
|
||||
launchMode=${this.launchMode}
|
||||
launchToken=${this.launchToken}
|
||||
lockTaskLaunchMode=${this.lockTaskLaunchMode}
|
||||
logo=${this.logo}
|
||||
maxAspectRatio=${this.maxAspectRatio}
|
||||
maxRecents=${this.maxRecents}
|
||||
metaData=${this.metaData.dumpToString()}
|
||||
minAspectRatio=${this.minAspectRatio}
|
||||
name=${this.name}
|
||||
nonLocalizedLabel=${this.nonLocalizedLabel}
|
||||
packageName=${this.packageName}
|
||||
parentActivityName=${this.parentActivityName}
|
||||
permission=${this.permission}
|
||||
persistableMode=${this.persistableMode}
|
||||
privateFlags=${Integer.toBinaryString(this.privateFlags)}
|
||||
persistableMode=${this.persistableMode.ignored("Could be dropped pre-R, fixed in R")}
|
||||
privateFlags=${this.privateFlags}
|
||||
processName=${this.processName.ignored("Deferred pre-R, but assigned immediately in R")}
|
||||
requestedVrComponent=${this.requestedVrComponent}
|
||||
resizeMode=${this.resizeMode}
|
||||
rotationAnimation=${this.rotationAnimation}
|
||||
screenOrientation=${this.screenOrientation}
|
||||
showUserIcon=${this.showUserIcon}
|
||||
softInputMode=${this.softInputMode}
|
||||
splitName=${this.splitName}
|
||||
targetActivity=${this.targetActivity}
|
||||
taskAffinity=${this.taskAffinity}
|
||||
theme=${this.theme}
|
||||
@@ -300,30 +342,77 @@ open class AndroidPackageParsingTestBase {
|
||||
|
||||
protected fun PermissionInfo.dumpToString() = """
|
||||
backgroundPermission=${this.backgroundPermission}
|
||||
banner=${this.banner}
|
||||
descriptionRes=${this.descriptionRes}
|
||||
flags=${Integer.toBinaryString(this.flags)}
|
||||
group=${this.group}
|
||||
icon=${this.icon}
|
||||
labelRes=${this.labelRes}
|
||||
logo=${this.logo}
|
||||
metaData=${this.metaData.dumpToString()}
|
||||
name=${this.name}
|
||||
nonLocalizedDescription=${this.nonLocalizedDescription}
|
||||
nonLocalizedLabel=${this.nonLocalizedLabel}
|
||||
packageName=${this.packageName}
|
||||
protectionLevel=${this.protectionLevel}
|
||||
requestRes=${this.requestRes}
|
||||
showUserIcon=${this.showUserIcon}
|
||||
""".trimIndent()
|
||||
|
||||
protected fun ProviderInfo.dumpToString() = """
|
||||
applicationInfo=${this.applicationInfo.ignored("Already checked")}
|
||||
authority=${this.authority}
|
||||
banner=${this.banner}
|
||||
descriptionRes=${this.descriptionRes}
|
||||
directBootAware=${this.directBootAware}
|
||||
enabled=${this.enabled}
|
||||
exported=${this.exported}
|
||||
flags=${Integer.toBinaryString(this.flags)}
|
||||
forceUriPermissions=${this.forceUriPermissions}
|
||||
grantUriPermissions=${this.grantUriPermissions}
|
||||
icon=${this.icon}
|
||||
initOrder=${this.initOrder}
|
||||
isSyncable=${this.isSyncable}
|
||||
labelRes=${this.labelRes}
|
||||
logo=${this.logo}
|
||||
metaData=${this.metaData.dumpToString()}
|
||||
multiprocess=${this.multiprocess}
|
||||
name=${this.name}
|
||||
nonLocalizedLabel=${this.nonLocalizedLabel}
|
||||
packageName=${this.packageName}
|
||||
pathPermissions=${this.pathPermissions?.joinToString {
|
||||
"readPermission=${it.readPermission}\nwritePermission=${it.writePermission}"
|
||||
}}
|
||||
processName=${this.processName.ignored("Deferred pre-R, but assigned immediately in R")}
|
||||
readPermission=${this.readPermission}
|
||||
showUserIcon=${this.showUserIcon}
|
||||
splitName=${this.splitName}
|
||||
uriPermissionPatterns=${this.uriPermissionPatterns?.contentToString()}
|
||||
writePermission=${this.writePermission}
|
||||
""".trimIndent()
|
||||
|
||||
protected fun ServiceInfo.dumpToString() = """
|
||||
applicationInfo=${this.applicationInfo.ignored("Already checked")}
|
||||
banner=${this.banner}
|
||||
descriptionRes=${this.descriptionRes}
|
||||
directBootAware=${this.directBootAware}
|
||||
enabled=${this.enabled}
|
||||
exported=${this.exported}
|
||||
flags=${Integer.toBinaryString(this.flags)}
|
||||
icon=${this.icon}
|
||||
labelRes=${this.labelRes}
|
||||
logo=${this.logo}
|
||||
mForegroundServiceType"${this.mForegroundServiceType}
|
||||
metaData=${this.metaData.dumpToString()}
|
||||
name=${this.name}
|
||||
nonLocalizedLabel=${this.nonLocalizedLabel}
|
||||
packageName=${this.packageName}
|
||||
permission=${this.permission}
|
||||
processName=${this.processName.ignored("Deferred pre-R, but assigned immediately in R")}
|
||||
showUserIcon=${this.showUserIcon}
|
||||
splitName=${this.splitName}
|
||||
""".trimIndent()
|
||||
|
||||
protected fun ConfigurationInfo.dumpToString() = """
|
||||
reqGlEsVersion=${this.reqGlEsVersion}
|
||||
reqInputFeatures=${this.reqInputFeatures}
|
||||
@@ -333,8 +422,10 @@ open class AndroidPackageParsingTestBase {
|
||||
""".trimIndent()
|
||||
|
||||
protected fun PackageInfo.dumpToString() = """
|
||||
activities=${this.activities?.joinToString { it.dumpToString() }}
|
||||
applicationInfo=${this.applicationInfo.dumpToString()}
|
||||
activities=${this.activities?.joinToString { it.dumpToString() }
|
||||
.ignored("Checked separately in test")}
|
||||
applicationInfo=${this.applicationInfo.dumpToString()
|
||||
.ignored("Checked separately in test")}
|
||||
baseRevisionCode=${this.baseRevisionCode}
|
||||
compileSdkVersion=${this.compileSdkVersion}
|
||||
compileSdkVersionCodename=${this.compileSdkVersionCodename}
|
||||
@@ -356,15 +447,18 @@ open class AndroidPackageParsingTestBase {
|
||||
overlayTarget=${this.overlayTarget}
|
||||
packageName=${this.packageName}
|
||||
permissions=${this.permissions?.joinToString { it.dumpToString() }}
|
||||
providers=${this.providers?.joinToString { it.dumpToString() }}
|
||||
receivers=${this.receivers?.joinToString { it.dumpToString() }}
|
||||
providers=${this.providers?.joinToString { it.dumpToString() }
|
||||
.ignored("Checked separately in test")}
|
||||
receivers=${this.receivers?.joinToString { it.dumpToString() }
|
||||
.ignored("Checked separately in test")}
|
||||
reqFeatures=${this.reqFeatures?.joinToString { it.dumpToString() }}
|
||||
requestedPermissions=${this.requestedPermissions?.contentToString()}
|
||||
requestedPermissionsFlags=${this.requestedPermissionsFlags?.contentToString()}
|
||||
requiredAccountType=${this.requiredAccountType}
|
||||
requiredForAllUsers=${this.requiredForAllUsers}
|
||||
restrictedAccountType=${this.restrictedAccountType}
|
||||
services=${this.services?.contentToString()}
|
||||
services=${this.services?.joinToString { it.dumpToString() }
|
||||
.ignored("Checked separately in test")}
|
||||
sharedUserId=${this.sharedUserId}
|
||||
sharedUserLabel=${this.sharedUserLabel}
|
||||
signatures=${this.signatures?.joinToString { it.toCharsString() }}
|
||||
@@ -378,11 +472,17 @@ open class AndroidPackageParsingTestBase {
|
||||
versionName=${this.versionName}
|
||||
""".trimIndent()
|
||||
|
||||
@Suppress("unused")
|
||||
private fun <T> SparseArray<T>.sequence(): Sequence<Pair<Int, T>> {
|
||||
var index = 0
|
||||
return generateSequence {
|
||||
index++.takeIf { it < size() }?.let { keyAt(it) to valueAt(index) }
|
||||
private fun Bundle?.dumpToString() = this?.keySet()?.associateWith { get(it) }?.toString()
|
||||
|
||||
private fun <T> SparseArray<T>?.dumpToString(): String {
|
||||
if (this == null) {
|
||||
return "EMPTY"
|
||||
}
|
||||
|
||||
val list = mutableListOf<Pair<Int, T>>()
|
||||
for (index in (0 until size())) {
|
||||
list += keyAt(index) to valueAt(index)
|
||||
}
|
||||
return list.toString()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user