diff options
author | Adam Lesinski <adamlesinski@google.com> | 2014-08-15 22:25:36 -0700 |
---|---|---|
committer | Adam Lesinski <adamlesinski@google.com> | 2014-08-15 22:25:36 -0700 |
commit | e47fd129057b19862e94b89f9ba413b5ceaca498 (patch) | |
tree | cc4e27b791f08340760046ab3b7f189ff980740d /tools/aapt | |
parent | e364aecf17124e0ae443bf9fe0e1b7c588a0d25a (diff) | |
download | frameworks_base-e47fd129057b19862e94b89f9ba413b5ceaca498.zip frameworks_base-e47fd129057b19862e94b89f9ba413b5ceaca498.tar.gz frameworks_base-e47fd129057b19862e94b89f9ba413b5ceaca498.tar.bz2 |
AAPT: Output only 64-bit arch when multiArch is true
When android:multiArch="true" in the <application> 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
Diffstat (limited to 'tools/aapt')
-rw-r--r-- | tools/aapt/Command.cpp | 68 |
1 files changed, 64 insertions, 4 deletions
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp index fe0a601..5d146d6 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<String8> architectures; for (size_t i=0; i<dir->getFileCount(); 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; } |