From e47fd129057b19862e94b89f9ba413b5ceaca498 Mon Sep 17 00:00:00 2001 From: Adam Lesinski Date: Fri, 15 Aug 2014 22:25:36 -0700 Subject: [PATCH] AAPT: Output only 64-bit arch when multiArch is true When android:multiArch="true" in the tag, aapt dump badging should only output the 64-bit architecture under the 'native-code' entry. Other architectures will be emitted under the 'alt-native-code' entry. Bug:17061929 Change-Id: I8310b2388b06a2ed571e5e121e4989403082ba68 --- tools/aapt/Command.cpp | 68 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 4 deletions(-) diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp index fe0a601f8f9c..5d146d65bded 100644 --- a/tools/aapt/Command.cpp +++ b/tools/aapt/Command.cpp @@ -989,6 +989,10 @@ int doDump(Bundle* bundle) bool hasReadCallLogPermission = false; bool hasWriteCallLogPermission = false; + // If an app declares itself as multiArch, we report the + // native libraries differently. + bool hasMultiArch = false; + // This next group of variables is used to implement a group of // backward-compatibility heuristics necessitated by the addition of // some new uses-feature constants in 2.1 and 2.2. In most cases, the @@ -1233,6 +1237,20 @@ int doDump(Bundle* bundle) if (debuggable != 0) { printf("application-debuggable\n"); } + + // We must search by name because the multiArch flag hasn't been API + // frozen yet. + int32_t multiArchIndex = tree.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, + "multiArch"); + if (multiArchIndex >= 0) { + Res_value value; + if (tree.getAttributeValue(multiArchIndex, &value) != NO_ERROR) { + if (value.dataType >= Res_value::TYPE_FIRST_INT && + value.dataType <= Res_value::TYPE_LAST_INT) { + hasMultiArch = value.data; + } + } + } } else if (tag == "uses-sdk") { int32_t code = getIntegerAttribute(tree, MIN_SDK_VERSION_ATTR, &error); if (error != "") { @@ -2044,12 +2062,54 @@ int doDump(Bundle* bundle) AssetDir* dir = assets.openNonAssetDir(assetsCookie, "lib"); if (dir != NULL) { if (dir->getFileCount() > 0) { - printf("native-code:"); + SortedVector architectures; for (size_t i=0; igetFileCount(); i++) { - printf(" '%s'", ResTable::normalizeForOutput( - dir->getFileName(i).string()).string()); + architectures.add(ResTable::normalizeForOutput( + dir->getFileName(i).string())); + } + + bool outputAltNativeCode = false; + // A multiArch package is one that contains 64-bit and + // 32-bit versions of native code and expects 3rd-party + // apps to load these native code libraries. Since most + // 64-bit systems also support 32-bit apps, the apps + // loading this multiArch package's code may be either + // 32-bit or 64-bit. + if (hasMultiArch) { + // If this is a multiArch package, report the 64-bit + // version only. Then as a separate entry, report the + // rest. + // + // If we report the 32-bit architecture, this APK will + // be installed on a 32-bit device, causing a large waste + // of bandwidth and disk space. This assumes that + // the developer of the multiArch package has also + // made a version that is 32-bit only. + String8 intel64("x86_64"); + String8 arm64("arm64-v8a"); + ssize_t index = architectures.indexOf(intel64); + if (index < 0) { + index = architectures.indexOf(arm64); + } + + if (index >= 0) { + printf("native-code: '%s'\n", architectures[index].string()); + architectures.removeAt(index); + outputAltNativeCode = true; + } + } + + const size_t archCount = architectures.size(); + if (archCount > 0) { + if (outputAltNativeCode) { + printf("alt-"); + } + printf("native-code:"); + for (size_t i = 0; i < archCount; i++) { + printf(" '%s'", architectures[i].string()); + } + printf("\n"); } - printf("\n"); } delete dir; } -- 2.11.0