Command.cpp revision 2cb761e3ddb9d68ab430013e9cd15ecaab9fbc62
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Copyright 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Android Asset Packaging Tool main entry point. 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "ApkBuilder.h" 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "Bundle.h" 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "Images.h" 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "Main.h" 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "ResourceFilter.h" 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "ResourceTable.h" 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "XMLNode.h" 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Errors.h> 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/KeyedVector.h> 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/List.h> 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Log.h> 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/SortedVector.h> 19788717ca599c714d58b2cb5deea1d37b4a711c07Eino-Ville Talvala#include <utils/threads.h> 2010e09c69d659bf54d6efbe1a3660add7f8a39d6eWu-cheng Li#include <utils/Vector.h> 2110e09c69d659bf54d6efbe1a3660add7f8a39d6eWu-cheng Li 224f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala#include <errno.h> 23a696f5d667227365da732481770767dcb330dd23Mathias Agopian#include <fcntl.h> 244c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li 2530771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Liusing namespace android; 26fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis 274f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala/* 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Show version info. All the cool kids do it. 294f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala */ 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint doVersion(Bundle* bundle) 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 324f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala if (bundle->getFileSpecCount() != 0) { 334f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala printf("(ignoring extra arguments)\n"); 347005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala } 357005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala printf("Android Asset Packaging Tool, v0.2\n"); 367005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala 377005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala return 0; 387005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala} 39bde61a5731cdfef76a0691f8bd53b880606f5f6eWu-cheng Li 400a12018e4cd6eaaeaec795f6b2af4499fe3a8bcdAli Utku Selen 41bde61a5731cdfef76a0691f8bd53b880606f5f6eWu-cheng Li/* 42bde61a5731cdfef76a0691f8bd53b880606f5f6eWu-cheng Li * Open the file read only. The call fails if the file doesn't exist. 43bde61a5731cdfef76a0691f8bd53b880606f5f6eWu-cheng Li * 44bde61a5731cdfef76a0691f8bd53b880606f5f6eWu-cheng Li * Returns NULL on failure. 45bde61a5731cdfef76a0691f8bd53b880606f5f6eWu-cheng Li */ 46bde61a5731cdfef76a0691f8bd53b880606f5f6eWu-cheng LiZipFile* openReadOnly(const char* fileName) 47bde61a5731cdfef76a0691f8bd53b880606f5f6eWu-cheng Li{ 487d9a8ffd08fa950eb14f8224f6090fe46ab4aa9fIgor Murashkin ZipFile* zip; 49bde61a5731cdfef76a0691f8bd53b880606f5f6eWu-cheng Li status_t result; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zip = new ZipFile; 52bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor result = zip->open(fileName, ZipFile::kOpenReadOnly); 53bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (result != NO_ERROR) { 54bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (result == NAME_NOT_FOUND) { 55df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main fprintf(stderr, "ERROR: '%s' not found\n", fileName); 56bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } else if (result == PERMISSION_DENIED) { 577478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li fprintf(stderr, "ERROR: '%s' access denied\n", fileName); 58df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main } else { 59df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main fprintf(stderr, "ERROR: failed opening '%s' as Zip file\n", 60bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor fileName); 617478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li } 62df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main delete zip; 63df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main return NULL; 64df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main } 65df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main 66df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main return zip; 67bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor} 68bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor 69bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor/* 70341ff13689dfe822b598e626272ac2e80041b482Dan Egnor * Open the file read-write. The file will be created if it doesn't 71bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor * already exist and "okayToCreate" is set. 72bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor * 73bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor * Returns NULL on failure. 74bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor */ 75bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan EgnorZipFile* openReadWrite(const char* fileName, bool okayToCreate) 76bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor{ 77bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor ZipFile* zip = NULL; 78bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor status_t result; 79bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor int flags; 80bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor 81bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor flags = ZipFile::kOpenReadWrite; 82bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (okayToCreate) { 83bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor flags |= ZipFile::kOpenCreate; 84bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } 85bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor 86bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor zip = new ZipFile; 87bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor result = zip->open(fileName, flags); 88bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (result != NO_ERROR) { 89bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor delete zip; 90bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor zip = NULL; 91bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor goto bail; 92bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } 93bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor 94bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnorbail: 95bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor return zip; 96bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor} 97bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor 98bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor 99bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor/* 100bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor * Return a short string describing the compression method. 101bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor */ 102bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnorconst char* compressionName(int method) 103bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor{ 104bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (method == ZipEntry::kCompressStored) { 105bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor return "Stored"; 106bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } else if (method == ZipEntry::kCompressDeflated) { 107bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor return "Deflated"; 108bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } else { 109bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor return "Unknown"; 110bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } 111bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor} 112bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor 113bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor/* 114bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor * Return the percent reduction in size (0% == no compression). 115bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor */ 116bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnorint calcPercent(long uncompressedLen, long compressedLen) 117bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor{ 118bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (!uncompressedLen) { 119bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor return 0; 120bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } else { 121bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor return (int) (100.0 - (compressedLen * 100.0) / uncompressedLen + 0.5); 122341ff13689dfe822b598e626272ac2e80041b482Dan Egnor } 123bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor} 124bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor 125df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main/* 126df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main * Handle the "list" command, which can be a simple file dump or 127df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main * a verbose listing. 1287478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li * 129df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main * The verbose listing closely matches the output of the Info-ZIP "unzip" 1306c5c3c392b8abce93fd2d366f12449c713ed0016Joe Fernandez * command. 1316c5c3c392b8abce93fd2d366f12449c713ed0016Joe Fernandez */ 1326c5c3c392b8abce93fd2d366f12449c713ed0016Joe Fernandezint doList(Bundle* bundle) 1336c5c3c392b8abce93fd2d366f12449c713ed0016Joe Fernandez{ 1346c5c3c392b8abce93fd2d366f12449c713ed0016Joe Fernandez int result = 1; 1356c5c3c392b8abce93fd2d366f12449c713ed0016Joe Fernandez ZipFile* zip = NULL; 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ZipEntry* entry; 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long totalUncLen, totalCompLen; 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* zipFileName; 1399b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 140d2c2929c94bec68741b85f4174e11307fb65157fWu-cheng Li if (bundle->getFileSpecCount() != 1) { 141da83f4674a564007baac03db062a289c8158d940Benny Wong fprintf(stderr, "ERROR: specify zip file name (only)\n"); 142da83f4674a564007baac03db062a289c8158d940Benny Wong goto bail; 143da83f4674a564007baac03db062a289c8158d940Benny Wong } 144da83f4674a564007baac03db062a289c8158d940Benny Wong zipFileName = bundle->getFileSpecEntry(0); 145da83f4674a564007baac03db062a289c8158d940Benny Wong 146da83f4674a564007baac03db062a289c8158d940Benny Wong zip = openReadOnly(zipFileName); 147da83f4674a564007baac03db062a289c8158d940Benny Wong if (zip == NULL) { 148da83f4674a564007baac03db062a289c8158d940Benny Wong goto bail; 149da83f4674a564007baac03db062a289c8158d940Benny Wong } 1504c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li 151bb1e275c0e684dd213f124da77110cdd9d6f090cWu-cheng Li int count, i; 1529d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getVerbose()) { 1544838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat printf("Archive: %s\n", zipFileName); 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf( 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " Length Method Size Ratio Offset Date Time CRC-32 Name\n"); 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf( 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "-------- ------ ------- ----- ------- ---- ---- ------ ----\n"); 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1607005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala 161e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks totalUncLen = totalCompLen = 0; 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1639d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li count = zip->getNumEntries(); 1643f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li for (i = 0; i < count; i++) { 1654c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li entry = zip->getEntryByIndex(i); 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getVerbose()) { 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char dateBuf[32]; 16894927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp time_t when; 1694c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li 170f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li when = entry->getModWhen(); 1719b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li strftime(dateBuf, sizeof(dateBuf), "%m-%d-%y %H:%M", 172feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk localtime(&when)); 173feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 174feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk printf("%8ld %-7.7s %7ld %3d%% %8zd %s %08lx %s\n", 175feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (long) entry->getUncompressedLen(), 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project compressionName(entry->getCompressionMethod()), 17710e09c69d659bf54d6efbe1a3660add7f8a39d6eWu-cheng Li (long) entry->getCompressedLen(), 17810e09c69d659bf54d6efbe1a3660add7f8a39d6eWu-cheng Li calcPercent(entry->getUncompressedLen(), 17910e09c69d659bf54d6efbe1a3660add7f8a39d6eWu-cheng Li entry->getCompressedLen()), 18010e09c69d659bf54d6efbe1a3660add7f8a39d6eWu-cheng Li (size_t) entry->getLFHOffset(), 18110e09c69d659bf54d6efbe1a3660add7f8a39d6eWu-cheng Li dateBuf, 18210e09c69d659bf54d6efbe1a3660add7f8a39d6eWu-cheng Li entry->getCRC32(), 18310e09c69d659bf54d6efbe1a3660add7f8a39d6eWu-cheng Li entry->getFileName()); 18410e09c69d659bf54d6efbe1a3660add7f8a39d6eWu-cheng Li } else { 18510e09c69d659bf54d6efbe1a3660add7f8a39d6eWu-cheng Li printf("%s\n", entry->getFileName()); 18610e09c69d659bf54d6efbe1a3660add7f8a39d6eWu-cheng Li } 18710e09c69d659bf54d6efbe1a3660add7f8a39d6eWu-cheng Li 18810e09c69d659bf54d6efbe1a3660add7f8a39d6eWu-cheng Li totalUncLen += entry->getUncompressedLen(); 18910e09c69d659bf54d6efbe1a3660add7f8a39d6eWu-cheng Li totalCompLen += entry->getCompressedLen(); 19010e09c69d659bf54d6efbe1a3660add7f8a39d6eWu-cheng Li } 19110e09c69d659bf54d6efbe1a3660add7f8a39d6eWu-cheng Li 19210e09c69d659bf54d6efbe1a3660add7f8a39d6eWu-cheng Li if (bundle->getVerbose()) { 1934c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li printf( 1944c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li "-------- ------- --- -------\n"); 195c0c683b3344c67700882f8059e7d18266366daa9Wu-cheng Li printf("%8ld %7ld %2d%% %d files\n", 1964c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li totalUncLen, 1974c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li totalCompLen, 198c0c683b3344c67700882f8059e7d18266366daa9Wu-cheng Li calcPercent(totalUncLen, totalCompLen), 1994c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li zip->getNumEntries()); 200c0c683b3344c67700882f8059e7d18266366daa9Wu-cheng Li } 2014c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li 2024c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li if (bundle->getAndroidList()) { 203341ff13689dfe822b598e626272ac2e80041b482Dan Egnor AssetManager assets; 204e25cc656392d8866e163f78b60c7791455d0fb44Chih-Chung Chang if (!assets.addAssetPath(String8(zipFileName), NULL)) { 205e25cc656392d8866e163f78b60c7791455d0fb44Chih-Chung Chang fprintf(stderr, "ERROR: list -a failed because assets could not be loaded\n"); 206e25cc656392d8866e163f78b60c7791455d0fb44Chih-Chung Chang goto bail; 207e25cc656392d8866e163f78b60c7791455d0fb44Chih-Chung Chang } 208341ff13689dfe822b598e626272ac2e80041b482Dan Egnor 209b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang const ResTable& res = assets.getResources(false); 210b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang if (&res == NULL) { 2114f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala printf("\nNo resource table found.\n"); 2124f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala } else { 2134f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala#ifndef HAVE_ANDROID_OS 2144f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala printf("\nResource table:\n"); 2154f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala res.print(false); 2164f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala#endif 2174f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala } 2184f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala 2194f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala Asset* manifestAsset = assets.openNonAsset("AndroidManifest.xml", 2204f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala Asset::ACCESS_BUFFER); 2214f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala if (manifestAsset == NULL) { 2224f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala printf("\nNo AndroidManifest.xml found.\n"); 2234f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala } else { 2244f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala printf("\nAndroid manifest:\n"); 2254f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala ResXMLTree tree; 226b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang tree.setTo(manifestAsset->getBuffer(true), 227b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang manifestAsset->getLength()); 228b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang printXMLBlock(&tree); 229b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang } 230b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang delete manifestAsset; 2317836660f5eb45b7b7e1f5119face65c80e2ade17Wu-cheng Li } 2327836660f5eb45b7b7e1f5119face65c80e2ade17Wu-cheng Li 2337836660f5eb45b7b7e1f5119face65c80e2ade17Wu-cheng Li result = 0; 234b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang 2357836660f5eb45b7b7e1f5119face65c80e2ade17Wu-cheng Libail: 2367836660f5eb45b7b7e1f5119face65c80e2ade17Wu-cheng Li delete zip; 2377836660f5eb45b7b7e1f5119face65c80e2ade17Wu-cheng Li return result; 2387836660f5eb45b7b7e1f5119face65c80e2ade17Wu-cheng Li} 239b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang 240b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Changstatic ssize_t indexOfAttribute(const ResXMLTree& tree, uint32_t attrRes) 241b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang{ 242464cb21e2aaa448072449b82156f18bd64c0e613Joe Fernandez size_t N = tree.getAttributeCount(); 243b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang for (size_t i=0; i<N; i++) { 244b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang if (tree.getAttributeNameResID(i) == attrRes) { 2457836660f5eb45b7b7e1f5119face65c80e2ade17Wu-cheng Li return (ssize_t)i; 246b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang } 247b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang } 24832a972c693400db50717435139fa292a63bc937aEino-Ville Talvala return -1; 249b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang} 25032a972c693400db50717435139fa292a63bc937aEino-Ville Talvala 251b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung ChangString8 getAttribute(const ResXMLTree& tree, const char* ns, 25232a972c693400db50717435139fa292a63bc937aEino-Ville Talvala const char* attr, String8* outError) 2532fe6fcaff4bdab45484055d6c18dd96d1b7b7be1Wu-cheng Li{ 2542fe6fcaff4bdab45484055d6c18dd96d1b7b7be1Wu-cheng Li ssize_t idx = tree.indexOfAttribute(ns, attr); 2552fe6fcaff4bdab45484055d6c18dd96d1b7b7be1Wu-cheng Li if (idx < 0) { 2562fe6fcaff4bdab45484055d6c18dd96d1b7b7be1Wu-cheng Li return String8(); 25732a972c693400db50717435139fa292a63bc937aEino-Ville Talvala } 258b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang Res_value value; 259b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 26069ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick if (value.dataType != Res_value::TYPE_STRING) { 26169ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick if (outError != NULL) { 26269ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick *outError = "attribute is not a string value"; 26369ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick } 264b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang return String8(); 2657836660f5eb45b7b7e1f5119face65c80e2ade17Wu-cheng Li } 266f7c6c5ad64c8e5d20e1806cc98b9919334c69614Eino-Ville Talvala } 267f7c6c5ad64c8e5d20e1806cc98b9919334c69614Eino-Ville Talvala size_t len; 268f7c6c5ad64c8e5d20e1806cc98b9919334c69614Eino-Ville Talvala const uint16_t* str = tree.getAttributeStringValue(idx, &len); 269f7c6c5ad64c8e5d20e1806cc98b9919334c69614Eino-Ville Talvala return str ? String8(str, len) : String8(); 270f7c6c5ad64c8e5d20e1806cc98b9919334c69614Eino-Ville Talvala} 271f7c6c5ad64c8e5d20e1806cc98b9919334c69614Eino-Ville Talvala 272f7c6c5ad64c8e5d20e1806cc98b9919334c69614Eino-Ville Talvalastatic String8 getAttribute(const ResXMLTree& tree, uint32_t attrRes, String8* outError) 273f7c6c5ad64c8e5d20e1806cc98b9919334c69614Eino-Ville Talvala{ 274f7c6c5ad64c8e5d20e1806cc98b9919334c69614Eino-Ville Talvala ssize_t idx = indexOfAttribute(tree, attrRes); 275f7c6c5ad64c8e5d20e1806cc98b9919334c69614Eino-Ville Talvala if (idx < 0) { 276f7c6c5ad64c8e5d20e1806cc98b9919334c69614Eino-Ville Talvala return String8(); 277f7c6c5ad64c8e5d20e1806cc98b9919334c69614Eino-Ville Talvala } 278f7c6c5ad64c8e5d20e1806cc98b9919334c69614Eino-Ville Talvala Res_value value; 279f7c6c5ad64c8e5d20e1806cc98b9919334c69614Eino-Ville Talvala if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 280f7c6c5ad64c8e5d20e1806cc98b9919334c69614Eino-Ville Talvala if (value.dataType != Res_value::TYPE_STRING) { 281b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang if (outError != NULL) { 282b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang *outError = "attribute is not a string value"; 283b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang } 284a1c41e13b521cdd611a8fc46e43b5ae0a2c00238Wu-cheng Li return String8(); 285a1c41e13b521cdd611a8fc46e43b5ae0a2c00238Wu-cheng Li } 286a1c41e13b521cdd611a8fc46e43b5ae0a2c00238Wu-cheng Li } 287a1c41e13b521cdd611a8fc46e43b5ae0a2c00238Wu-cheng Li size_t len; 288bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor const uint16_t* str = tree.getAttributeStringValue(idx, &len); 289bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor return str ? String8(str, len) : String8(); 290bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor} 291341ff13689dfe822b598e626272ac2e80041b482Dan Egnor 292341ff13689dfe822b598e626272ac2e80041b482Dan Egnorstatic int32_t getIntegerAttribute(const ResXMLTree& tree, uint32_t attrRes, 293bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor String8* outError, int32_t defValue = -1) 294bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor{ 295bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor ssize_t idx = indexOfAttribute(tree, attrRes); 296bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (idx < 0) { 297bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor return defValue; 298bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } 299bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor Res_value value; 300bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 301bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (value.dataType < Res_value::TYPE_FIRST_INT 302bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor || value.dataType > Res_value::TYPE_LAST_INT) { 303bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (outError != NULL) { 304341ff13689dfe822b598e626272ac2e80041b482Dan Egnor *outError = "attribute is not an integer value"; 305a48b70fa8ff6363d1e5282be70f6be12bc0688dcWu-cheng Li } 306bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor return defValue; 307a1c41e13b521cdd611a8fc46e43b5ae0a2c00238Wu-cheng Li } 308a1c41e13b521cdd611a8fc46e43b5ae0a2c00238Wu-cheng Li } 309a1c41e13b521cdd611a8fc46e43b5ae0a2c00238Wu-cheng Li return value.data; 310facc8ce116bd92f7ba7e8ecb76cbda3953260ef9Wu-cheng Li} 311e25cc656392d8866e163f78b60c7791455d0fb44Chih-Chung Chang 312e25cc656392d8866e163f78b60c7791455d0fb44Chih-Chung Changstatic int32_t getResolvedIntegerAttribute(const ResTable* resTable, const ResXMLTree& tree, 3137bc1b21a5217c3737ae82edd3ff2d901c69a51adWu-cheng Li uint32_t attrRes, String8* outError, int32_t defValue = -1) 314e25cc656392d8866e163f78b60c7791455d0fb44Chih-Chung Chang{ 315e25cc656392d8866e163f78b60c7791455d0fb44Chih-Chung Chang ssize_t idx = indexOfAttribute(tree, attrRes); 316e25cc656392d8866e163f78b60c7791455d0fb44Chih-Chung Chang if (idx < 0) { 317a48b70fa8ff6363d1e5282be70f6be12bc0688dcWu-cheng Li return defValue; 318a48b70fa8ff6363d1e5282be70f6be12bc0688dcWu-cheng Li } 319a48b70fa8ff6363d1e5282be70f6be12bc0688dcWu-cheng Li Res_value value; 3207836660f5eb45b7b7e1f5119face65c80e2ade17Wu-cheng Li if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value.dataType == Res_value::TYPE_REFERENCE) { 3229b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li resTable->resolveReference(&value, 0); 323a48b70fa8ff6363d1e5282be70f6be12bc0688dcWu-cheng Li } 324a48b70fa8ff6363d1e5282be70f6be12bc0688dcWu-cheng Li if (value.dataType < Res_value::TYPE_FIRST_INT 325a48b70fa8ff6363d1e5282be70f6be12bc0688dcWu-cheng Li || value.dataType > Res_value::TYPE_LAST_INT) { 326a48b70fa8ff6363d1e5282be70f6be12bc0688dcWu-cheng Li if (outError != NULL) { 327a48b70fa8ff6363d1e5282be70f6be12bc0688dcWu-cheng Li *outError = "attribute is not an integer value"; 3287bc1b21a5217c3737ae82edd3ff2d901c69a51adWu-cheng Li } 329a48b70fa8ff6363d1e5282be70f6be12bc0688dcWu-cheng Li return defValue; 330a48b70fa8ff6363d1e5282be70f6be12bc0688dcWu-cheng Li } 331a48b70fa8ff6363d1e5282be70f6be12bc0688dcWu-cheng Li } 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return value.data; 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3347bc1b21a5217c3737ae82edd3ff2d901c69a51adWu-cheng Li 335feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic String8 getResolvedAttribute(const ResTable* resTable, const ResXMLTree& tree, 336feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint32_t attrRes, String8* outError) 337feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk{ 338feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ssize_t idx = indexOfAttribute(tree, attrRes); 339feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (idx < 0) { 340feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return String8(); 341feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 342feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Res_value value; 343feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 344feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (value.dataType == Res_value::TYPE_STRING) { 345feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t len; 346feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk const uint16_t* str = tree.getAttributeStringValue(idx, &len); 347feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return str ? String8(str, len) : String8(); 348feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 349feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk resTable->resolveReference(&value, 0); 350feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (value.dataType != Res_value::TYPE_STRING) { 351feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (outError != NULL) { 352feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *outError = "attribute is not a string value"; 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return String8(); 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 357e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks size_t len; 3587005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala const Res_value* value2 = &value; 3593f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li const char16_t* str = const_cast<ResTable*>(resTable)->valueToString(value2, 0, NULL, &len); 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return str ? String8(str, len) : String8(); 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void getResolvedResourceAttribute(Res_value* value, const ResTable* resTable, 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree& tree, uint32_t attrRes, String8* outError) 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t idx = indexOfAttribute(tree, attrRes); 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx < 0) { 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outError != NULL) { 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outError = "attribute could not be found"; 370788717ca599c714d58b2cb5deea1d37b4a711c07Eino-Ville Talvala } 371788717ca599c714d58b2cb5deea1d37b4a711c07Eino-Ville Talvala return; 372feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 373feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (tree.getAttributeValue(idx, value) != NO_ERROR) { 374feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (value->dataType == Res_value::TYPE_REFERENCE) { 375feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk resTable->resolveReference(value, 0); 376feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 377feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // The attribute was found and was resolved if need be. 378feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return; 379feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 380feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (outError != NULL) { 381feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *outError = "error getting resolved resource attribute"; 382feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 383feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 384feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 385feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic void printResolvedResourceAttribute(const ResTable* resTable, const ResXMLTree& tree, 386feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint32_t attrRes, String8 attrLabel, String8* outError) 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3889b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li Res_value value; 3891c04a33c040dfb610952d62da9c93a53c291b2d7Wu-cheng Li getResolvedResourceAttribute(&value, resTable, tree, attrRes, outError); 3901c04a33c040dfb610952d62da9c93a53c291b2d7Wu-cheng Li if (*outError != "") { 3911c04a33c040dfb610952d62da9c93a53c291b2d7Wu-cheng Li *outError = "error print resolved resource attribute"; 3921c04a33c040dfb610952d62da9c93a53c291b2d7Wu-cheng Li return; 3931c04a33c040dfb610952d62da9c93a53c291b2d7Wu-cheng Li } 3941c04a33c040dfb610952d62da9c93a53c291b2d7Wu-cheng Li if (value.dataType == Res_value::TYPE_STRING) { 3959b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li String8 result = getResolvedAttribute(resTable, tree, attrRes, outError); 396e0cc55ac725feec88c77b482d1990221c9a80f74Eino-Ville Talvala printf("%s='%s'", attrLabel.string(), 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResTable::normalizeForOutput(result.string()).string()); 3989b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } else if (Res_value::TYPE_FIRST_INT <= value.dataType && 399feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk value.dataType <= Res_value::TYPE_LAST_INT) { 400788717ca599c714d58b2cb5deea1d37b4a711c07Eino-Ville Talvala printf("%s='%d'", attrLabel.string(), value.data); 401788717ca599c714d58b2cb5deea1d37b4a711c07Eino-Ville Talvala } else { 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("%s='0x%x'", attrLabel.string(), (int)value.data); 4039b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// These are attribute resource constants for the platform, as found 407bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor// in android.R.attr 408bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnorenum { 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LABEL_ATTR = 0x01010001, 4109b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li ICON_ATTR = 0x01010002, 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NAME_ATTR = 0x01010003, 4124c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li PERMISSION_ATTR = 0x01010006, 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EXPORTED_ATTR = 0x01010010, 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GRANT_URI_PERMISSIONS_ATTR = 0x0101001b, 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RESOURCE_ATTR = 0x01010025, 416bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor DEBUGGABLE_ATTR = 0x0101000f, 417bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor VALUE_ATTR = 0x01010024, 418bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor VERSION_CODE_ATTR = 0x0101021b, 419bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor VERSION_NAME_ATTR = 0x0101021c, 420bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor SCREEN_ORIENTATION_ATTR = 0x0101001e, 421bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor MIN_SDK_VERSION_ATTR = 0x0101020c, 422bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor MAX_SDK_VERSION_ATTR = 0x01010271, 423bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor REQ_TOUCH_SCREEN_ATTR = 0x01010227, 42442419ce28a09eb63e29a8fef87e6f5534f41902fWu-cheng Li REQ_KEYBOARD_TYPE_ATTR = 0x01010228, 42542419ce28a09eb63e29a8fef87e6f5534f41902fWu-cheng Li REQ_HARD_KEYBOARD_ATTR = 0x01010229, 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project REQ_NAVIGATION_ATTR = 0x0101022a, 427bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor REQ_FIVE_WAY_NAV_ATTR = 0x01010232, 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TARGET_SDK_VERSION_ATTR = 0x01010270, 429bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor TEST_ONLY_ATTR = 0x01010272, 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ANY_DENSITY_ATTR = 0x0101026c, 431bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor GL_ES_VERSION_ATTR = 0x01010281, 4329b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li SMALL_SCREEN_ATTR = 0x01010284, 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NORMAL_SCREEN_ATTR = 0x01010285, 434bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor LARGE_SCREEN_ATTR = 0x01010286, 435bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor XLARGE_SCREEN_ATTR = 0x010102bf, 436bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor REQUIRED_ATTR = 0x0101028e, 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SCREEN_SIZE_ATTR = 0x010102ca, 43853b30912d3e8598c05e47308981971e958e98db2Wu-cheng Li SCREEN_DENSITY_ATTR = 0x010102cb, 43942419ce28a09eb63e29a8fef87e6f5534f41902fWu-cheng Li REQUIRES_SMALLEST_WIDTH_DP_ATTR = 0x01010364, 44042419ce28a09eb63e29a8fef87e6f5534f41902fWu-cheng Li COMPATIBLE_WIDTH_LIMIT_DP_ATTR = 0x01010365, 44142419ce28a09eb63e29a8fef87e6f5534f41902fWu-cheng Li LARGEST_WIDTH_LIMIT_DP_ATTR = 0x01010366, 44242419ce28a09eb63e29a8fef87e6f5534f41902fWu-cheng Li PUBLIC_KEY_ATTR = 0x010103a6, 443bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor CATEGORY_ATTR = 0x010103e8, 444bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor BANNER_ATTR = 0x10103f2, 445bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor}; 446bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectString8 getComponentName(String8 &pkgName, String8 &componentName) { 448ffe1cf251a4f8469695b8acfa37270684dc1b70cWu-cheng Li ssize_t idx = componentName.find("."); 4499b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li String8 retStr(pkgName); 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx == 0) { 451bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor retStr += componentName; 452bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } else if (idx < 0) { 453bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor retStr += "."; 454bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor retStr += componentName; 455bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } else { 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return componentName; 45753b30912d3e8598c05e47308981971e958e98db2Wu-cheng Li } 45842419ce28a09eb63e29a8fef87e6f5534f41902fWu-cheng Li return retStr; 45942419ce28a09eb63e29a8fef87e6f5534f41902fWu-cheng Li} 46042419ce28a09eb63e29a8fef87e6f5534f41902fWu-cheng Li 461bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnorstatic void printCompatibleScreens(ResXMLTree& tree, String8* outError) { 462bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor size_t len; 463bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor ResXMLTree::event_code_t code; 464bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor int depth = 0; 465bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor bool first = true; 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("compatible-screens:"); 467bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 4689b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (code == ResXMLTree::END_TAG) { 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project depth--; 470bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (depth < 0) { 471fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis break; 472fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis } 473fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis continue; 474fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis } 4759b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (code != ResXMLTree::START_TAG) { 476bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor continue; 477bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } 478bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor depth++; 479bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor const char16_t* ctag16 = tree.getElementName(&len); 480bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (ctag16 == NULL) { 481bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor *outError = "failed to get XML element name (bad string pool)"; 482bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor return; 483bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } 484bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor String8 tag(ctag16); 485bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (tag == "screen") { 486bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor int32_t screenSize = getIntegerAttribute(tree, 487bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor SCREEN_SIZE_ATTR, NULL, -1); 488bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor int32_t screenDensity = getIntegerAttribute(tree, 4899b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li SCREEN_DENSITY_ATTR, NULL, -1); 490bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (screenSize > 0 && screenDensity > 0) { 491bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (!first) { 492bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor printf(","); 493bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project first = false; 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("'%d/%d'", screenSize, screenDensity); 496b8a10fe45657f2dcc50cae8a06805f8438a6937eWu-cheng Li } 497feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 498b8a10fe45657f2dcc50cae8a06805f8438a6937eWu-cheng Li } 499feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk printf("\n"); 500b8a10fe45657f2dcc50cae8a06805f8438a6937eWu-cheng Li} 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void printUsesPermission(const String8& name, bool optional=false, int maxSdkVersion=-1) { 503feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk printf("uses-permission: name='%s'", ResTable::normalizeForOutput(name.string()).string()); 504feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (maxSdkVersion != -1) { 505feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk printf(" maxSdkVersion='%d'", maxSdkVersion); 506feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("\n"); 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 509fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis if (optional) { 510fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis printf("optional-permission: name='%s'", 511fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis ResTable::normalizeForOutput(name.string()).string()); 512fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis if (maxSdkVersion != -1) { 513fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis printf(" maxSdkVersion='%d'", maxSdkVersion); 514fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis } 515fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis printf("\n"); 516fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis } 517fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis} 518fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis 519fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennisstatic void printUsesImpliedPermission(const String8& name, const String8& reason) { 520fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis printf("uses-implied-permission: name='%s' reason='%s'\n", 521fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis ResTable::normalizeForOutput(name.string()).string(), 522fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis ResTable::normalizeForOutput(reason.string()).string()); 52332a972c693400db50717435139fa292a63bc937aEino-Ville Talvala} 524e309a0fd2e528039b3c1f1372a9a7095bcd852ccEino-Ville Talvala 525e309a0fd2e528039b3c1f1372a9a7095bcd852ccEino-Ville TalvalaVector<String8> getNfcAidCategories(AssetManager& assets, String8 xmlPath, bool offHost, 526e309a0fd2e528039b3c1f1372a9a7095bcd852ccEino-Ville Talvala String8 *outError = NULL) 527e309a0fd2e528039b3c1f1372a9a7095bcd852ccEino-Ville Talvala{ 528e309a0fd2e528039b3c1f1372a9a7095bcd852ccEino-Ville Talvala Asset* aidAsset = assets.openNonAsset(xmlPath, Asset::ACCESS_BUFFER); 529108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala if (aidAsset == NULL) { 530108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala if (outError != NULL) *outError = "xml resource does not exist"; 531108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala return Vector<String8>(); 532108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala } 533108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala 534108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala const String8 serviceTagName(offHost ? "offhost-apdu-service" : "host-apdu-service"); 535108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala 536fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis bool withinApduService = false; 537fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis Vector<String8> categories; 538fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis 539fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis String8 error; 540fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis ResXMLTree tree; 541fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis tree.setTo(aidAsset->getBuffer(true), aidAsset->getLength()); 542dbc289d6c27968bd05cc547ca73579347c3adc99Glenn Kasten 543fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis size_t len; 544fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis int depth = 0; 545bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor ResXMLTree::event_code_t code; 546bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 547bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (code == ResXMLTree::END_TAG) { 548bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor depth--; 549bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor const char16_t* ctag16 = tree.getElementName(&len); 550bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (ctag16 == NULL) { 551bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor *outError = "failed to get XML element name (bad string pool)"; 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Vector<String8>(); 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 tag(ctag16); 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 556bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (depth == 0 && tag == serviceTagName) { 557341ff13689dfe822b598e626272ac2e80041b482Dan Egnor withinApduService = false; 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 559951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 560951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala } else if (code == ResXMLTree::START_TAG) { 561951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala depth++; 562951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala const char16_t* ctag16 = tree.getElementName(&len); 563951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala if (ctag16 == NULL) { 564bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor *outError = "failed to get XML element name (bad string pool)"; 565a696f5d667227365da732481770767dcb330dd23Mathias Agopian return Vector<String8>(); 566df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main } 567da0a56df963353a1f1bd1914fa31f870d982dd5aScott Main String8 tag(ctag16); 5689b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 5699b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (depth == 1) { 570bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (tag == serviceTagName) { 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project withinApduService = true; 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (depth == 2 && withinApduService) { 5749b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (tag == "aid-group") { 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 category = getAttribute(tree, CATEGORY_ATTR, &error); 576bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (error != "") { 577c5f94d8a4779050125145396ca83fbc862c7ed6bEino-Ville Talvala if (outError != NULL) *outError = error; 578c5f94d8a4779050125145396ca83fbc862c7ed6bEino-Ville Talvala return Vector<String8>(); 579c5f94d8a4779050125145396ca83fbc862c7ed6bEino-Ville Talvala } 580bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor 581bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor categories.add(category); 582bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } 583bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } 584bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } 585bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project aidAsset->close(); 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return categories; 5889b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li} 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 590bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnorstatic void printComponentPresence(const char* componentName) { 591bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor printf("provides-component:'%s'\n", componentName); 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5934c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li 5944c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li/** 5954c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li * Represents a feature that has been automatically added due to 596664d72e6630522589cc013b25f5c9cdd5d949fa3Chih-yu Huang * a pre-requisite or some other reason. 597664d72e6630522589cc013b25f5c9cdd5d949fa3Chih-yu Huang */ 598664d72e6630522589cc013b25f5c9cdd5d949fa3Chih-yu Huangstruct ImpliedFeature { 599664d72e6630522589cc013b25f5c9cdd5d949fa3Chih-yu Huang /** 600664d72e6630522589cc013b25f5c9cdd5d949fa3Chih-yu Huang * Name of the implied feature. 601f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li */ 602f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li String8 name; 603f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li 6049d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li /** 6054c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li * List of human-readable reasons for why this feature was implied. 6064c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li */ 6074c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li SortedVector<String8> reasons; 6089b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li}; 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Represents a <feature-group> tag in the AndroidManifest.xml 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct FeatureGroup { 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FeatureGroup() : openGLESVersion(-1) {} 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6169b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li /** 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Human readable label 618108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala */ 619bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor String8 label; 620bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor 621108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala /** 622108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala * Explicit features defined in the group 623108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala */ 624108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala KeyedVector<String8, bool> features; 625108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala 626108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala /** 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * OpenGL ES version required 628bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor */ 629bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor int openGLESVersion; 630108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala}; 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void addImpliedFeature(KeyedVector<String8, ImpliedFeature>* impliedFeatures, 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* name, const char* reason) { 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 name8(name); 63594927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp ssize_t idx = impliedFeatures->indexOfKey(name8); 6367005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala if (idx < 0) { 6377005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala idx = impliedFeatures->add(name8, ImpliedFeature()); 6387005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala impliedFeatures->editValueAt(idx).name = name8; 639a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks } 640a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks impliedFeatures->editValueAt(idx).reasons.add(String8(reason)); 64194927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp} 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void printFeatureGroup(const FeatureGroup& grp, 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const KeyedVector<String8, ImpliedFeature>* impliedFeatures = NULL) { 645108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala printf("feature-group: label='%s'\n", grp.label.string()); 646108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala 647108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala if (grp.openGLESVersion > 0) { 648108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala printf(" uses-gl-es: '0x%x'\n", grp.openGLESVersion); 649108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala } 650108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala 651108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala const size_t numFeatures = grp.features.size(); 652108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala for (size_t i = 0; i < numFeatures; i++) { 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!grp.features[i]) { 654bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor continue; 655bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } 656108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const String8& featureName = grp.features.keyAt(i); 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf(" uses-feature: name='%s'\n", 65994927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp ResTable::normalizeForOutput(featureName.string()).string()); 66094927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp } 66194927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp 6627005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala const size_t numImpliedFeatures = 6637005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala (impliedFeatures != NULL) ? impliedFeatures->size() : 0; 6647005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala for (size_t i = 0; i < numImpliedFeatures; i++) { 66594927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp const ImpliedFeature& impliedFeature = impliedFeatures->valueAt(i); 66694927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp if (grp.features.indexOfKey(impliedFeature.name) >= 0) { 66794927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp // The feature is explicitly set, no need to use implied 66894927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp // definition. 66994927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp continue; 67094927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp } 671108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala 672108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala String8 printableFeatureName(ResTable::normalizeForOutput( 673bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor impliedFeature.name.string())); 674108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala printf(" uses-feature: name='%s'\n", printableFeatureName.string()); 675108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala printf(" uses-implied-feature: name='%s' reason='", 67694927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp printableFeatureName.string()); 677bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor const size_t numReasons = impliedFeature.reasons.size(); 678bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor for (size_t j = 0; j < numReasons; j++) { 679bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor printf("%s", impliedFeature.reasons[j].string()); 680108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala if (j + 2 < numReasons) { 68194927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp printf(", "); 682108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala } else if (j + 1 < numReasons) { 683bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor printf(", and "); 684108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala } 685108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala } 686108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala printf("'\n"); 687108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala } 688108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala} 689108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala 69094927dffce1626898b59579dfc5af53b5de8cef6Andrew Harpstatic void addParentFeatures(FeatureGroup* grp, const String8& name) { 691bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (name == "android.hardware.camera.autofocus" || 692bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor name == "android.hardware.camera.flash") { 693bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor grp->features.add(String8("android.hardware.camera"), true); 694108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala } else if (name == "android.hardware.location.gps" || 69594927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp name == "android.hardware.location.network") { 69694927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp grp->features.add(String8("android.hardware.location"), true); 69794927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp } else if (name == "android.hardware.touchscreen.multitouch") { 69894927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp grp->features.add(String8("android.hardware.touchscreen"), true); 69994927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp } else if (name == "android.hardware.touchscreen.multitouch.distinct") { 7007005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala grp->features.add(String8("android.hardware.touchscreen.multitouch"), true); 7017005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala grp->features.add(String8("android.hardware.touchscreen"), true); 7027005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala } else if (name == "android.hardware.opengles.aep") { 70394927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp const int openGLESVersion31 = 0x00030001; 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (openGLESVersion31 > grp->openGLESVersion) { 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project grp->openGLESVersion = openGLESVersion31; 70694927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp } 7073f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li } 7083f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li} 709bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor 710bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor/* 711bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor * Handle the "dump" command, to extract select data from an archive. 712bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor */ 713bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnorextern char CONSOLE_DATA[2925]; // see EOF 714c10275abd6a494c93a025f683dde104a5d4f2793Wu-cheng Liint doDump(Bundle* bundle) 715951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala{ 716951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala status_t result = UNKNOWN_ERROR; 717951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 718951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala if (bundle->getFileSpecCount() < 1) { 719951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala fprintf(stderr, "ERROR: no dump option specified\n"); 720951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala return 1; 721951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala } 722951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 723951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala if (bundle->getFileSpecCount() < 2) { 724951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala fprintf(stderr, "ERROR: no dump file specified\n"); 725951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala return 1; 72694927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp } 727bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor 728e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong const char* option = bundle->getFileSpecEntry(0); 729bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor const char* filename = bundle->getFileSpecEntry(1); 730bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor 731e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong AssetManager assets; 732e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong int32_t assetsCookie; 733e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong if (!assets.addAssetPath(String8(filename), &assetsCookie)) { 73494927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp fprintf(stderr, "ERROR: dump failed because assets could not be loaded\n"); 735951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala return 1; 736951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala } 7375b9bcda3a26e9b1f9b1eff28a2be8853d69614f0Wu-cheng Li 73894927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp // Make a dummy config for retrieving resources... we need to supply 739e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong // non-default values for some configs so that we can retrieve resources 740e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong // in the app that don't have a default. The most important of these is 741e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong // the API version because key resources like icons will have an implicit 742e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong // version if they are using newer config types like density. 743e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong ResTable_config config; 744e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong memset(&config, 0, sizeof(ResTable_config)); 745e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong config.language[0] = 'e'; 746e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong config.language[1] = 'n'; 747e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong config.country[0] = 'U'; 748e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong config.country[1] = 'S'; 749e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong config.orientation = ResTable_config::ORIENTATION_PORT; 750e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong config.density = ResTable_config::DENSITY_MEDIUM; 751e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong config.sdkVersion = 10000; // Very high. 752e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong config.screenWidthDp = 320; 753e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong config.screenHeightDp = 480; 754e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong config.smallestScreenWidthDp = 320; 755e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong config.screenLayout |= ResTable_config::SCREENSIZE_NORMAL; 756e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong assets.setConfiguration(config); 757e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong 758e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong const ResTable& res = assets.getResources(false); 759e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong if (&res == NULL) { 760e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong fprintf(stderr, "ERROR: dump failed because no resource table was found\n"); 761e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong return 1; 762e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong } else if (res.getError() != NO_ERROR) { 763e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong fprintf(stderr, "ERROR: dump failed because the resource table is invalid/corrupt.\n"); 764e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong return 1; 765e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong } 76632a972c693400db50717435139fa292a63bc937aEino-Ville Talvala 76732a972c693400db50717435139fa292a63bc937aEino-Ville Talvala // The dynamicRefTable can be null if there are no resources for this asset cookie. 76832a972c693400db50717435139fa292a63bc937aEino-Ville Talvala // This fine. 76932a972c693400db50717435139fa292a63bc937aEino-Ville Talvala const DynamicRefTable* dynamicRefTable = res.getDynamicRefTableForCookie(assetsCookie); 77032a972c693400db50717435139fa292a63bc937aEino-Ville Talvala 77132a972c693400db50717435139fa292a63bc937aEino-Ville Talvala Asset* asset = NULL; 772e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong 773e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong if (strcmp("resources", option) == 0) { 774e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong#ifndef HAVE_ANDROID_OS 775e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong res.print(bundle->getValues()); 776e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong#endif 777e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong 778e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong } else if (strcmp("strings", option) == 0) { 779e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong const ResStringPool* pool = res.getTableStringBlock(0); 780e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong printStringPool(pool); 781e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong 782e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong } else if (strcmp("xmltree", option) == 0) { 783e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong if (bundle->getFileSpecCount() < 3) { 784e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong fprintf(stderr, "ERROR: no dump xmltree resource file specified\n"); 785e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong goto bail; 786e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong } 787e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong 788e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong for (int i=2; i<bundle->getFileSpecCount(); i++) { 789e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong const char* resname = bundle->getFileSpecEntry(i); 790e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong ResXMLTree tree(dynamicRefTable); 791e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong asset = assets.openNonAsset(assetsCookie, resname, Asset::ACCESS_BUFFER); 792e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong if (asset == NULL) { 793e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong fprintf(stderr, "ERROR: dump failed because resource %s found\n", resname); 794e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong goto bail; 795e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong } 796e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong 797e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong if (tree.setTo(asset->getBuffer(true), 798e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong asset->getLength()) != NO_ERROR) { 799e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong fprintf(stderr, "ERROR: Resource %s is corrupt\n", resname); 800e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong goto bail; 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8027005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala tree.restart(); 8037005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala printXMLBlock(&tree); 8047005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala tree.uninit(); 8057005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala delete asset; 8067005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala asset = NULL; 8077005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala } 8087005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala 8097005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala } else if (strcmp("xmlstrings", option) == 0) { 8107005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala if (bundle->getFileSpecCount() < 3) { 8117005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala fprintf(stderr, "ERROR: no dump xmltree resource file specified\n"); 8127005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala goto bail; 8137005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala } 8147005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala 8157005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala for (int i=2; i<bundle->getFileSpecCount(); i++) { 8167005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala const char* resname = bundle->getFileSpecEntry(i); 8177005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala asset = assets.openNonAsset(assetsCookie, resname, Asset::ACCESS_BUFFER); 8187005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala if (asset == NULL) { 8197005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala fprintf(stderr, "ERROR: dump failed because resource %s found\n", resname); 8207005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala goto bail; 8217005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala } 8227005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala 8237005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala ResXMLTree tree(dynamicRefTable); 8247005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala if (tree.setTo(asset->getBuffer(true), 8257005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala asset->getLength()) != NO_ERROR) { 8267005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala fprintf(stderr, "ERROR: Resource %s is corrupt\n", resname); 8277005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala goto bail; 8287005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala } 8297005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala printStringPool(&tree.getStrings()); 8307005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala delete asset; 8317005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala asset = NULL; 8327005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala } 8337005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala 8347005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala } else { 8357005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala asset = assets.openNonAsset(assetsCookie, "AndroidManifest.xml", Asset::ACCESS_BUFFER); 8367005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala if (asset == NULL) { 8377005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala fprintf(stderr, "ERROR: dump failed because no AndroidManifest.xml found\n"); 8387005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala goto bail; 8397005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala } 8407005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala 8417005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala ResXMLTree tree(dynamicRefTable); 8427005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala if (tree.setTo(asset->getBuffer(true), 8437005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala asset->getLength()) != NO_ERROR) { 8447005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala fprintf(stderr, "ERROR: AndroidManifest.xml is corrupt\n"); 8457005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala goto bail; 8467005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala } 8477005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala tree.restart(); 8487005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala 8497005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala if (strcmp("permissions", option) == 0) { 8507005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala size_t len; 8517005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala ResXMLTree::event_code_t code; 8527005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala int depth = 0; 8537005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 8547005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala if (code == ResXMLTree::END_TAG) { 8557005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala depth--; 8567005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala continue; 8577005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala } 8587005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala if (code != ResXMLTree::START_TAG) { 8597005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala continue; 8607005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala } 8617005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala depth++; 8627005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala const char16_t* ctag16 = tree.getElementName(&len); 8637005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala if (ctag16 == NULL) { 8647005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala fprintf(stderr, "ERROR: failed to get XML element name (bad string pool)\n"); 8657005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala goto bail; 8667005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala } 8677005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala String8 tag(ctag16); 8687005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala //printf("Depth %d tag %s\n", depth, tag.string()); 8697005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala if (depth == 1) { 8707005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala if (tag != "manifest") { 8717005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala fprintf(stderr, "ERROR: manifest does not start with <manifest> tag\n"); 8727005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala goto bail; 8737005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala } 8747005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala String8 pkg = getAttribute(tree, NULL, "package", NULL); 8757005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala printf("package: %s\n", ResTable::normalizeForOutput(pkg.string()).string()); 8767005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala } else if (depth == 2 && tag == "permission") { 8777005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala String8 error; 8787005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala String8 name = getAttribute(tree, NAME_ATTR, &error); 8797005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala if (error != "") { 8807005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala fprintf(stderr, "ERROR: %s\n", error.string()); 8817005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala goto bail; 8827005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala } 8837005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala printf("permission: %s\n", 8847005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala ResTable::normalizeForOutput(name.string()).string()); 8857005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala } else if (depth == 2 && tag == "uses-permission") { 8867005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala String8 error; 8877005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala String8 name = getAttribute(tree, NAME_ATTR, &error); 8887005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala if (error != "") { 8897005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala fprintf(stderr, "ERROR: %s\n", error.string()); 8907005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala goto bail; 8917005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala } 8927005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala printUsesPermission(name, 8937005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala getIntegerAttribute(tree, REQUIRED_ATTR, NULL, 1) == 0, 8947005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR, NULL, -1)); 8957005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala } 8967005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala } 8977005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala } else if (strcmp("badging", option) == 0) { 8987005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala Vector<String8> locales; 8997005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala res.getLocales(&locales); 9007005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala 9017005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala Vector<ResTable_config> configs; 9027005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala res.getConfigurations(&configs); 9037005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala SortedVector<int> densities; 9047005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala const size_t NC = configs.size(); 9057005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala for (size_t i=0; i<NC; i++) { 9067005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala int dens = configs[i].density; 9077005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala if (dens == 0) { 9087005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala dens = 160; 9097005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala } 9107005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala densities.add(dens); 9117005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala } 9127005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala 9137005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala size_t len; 9147005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala ResXMLTree::event_code_t code; 9157005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala int depth = 0; 9167005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala String8 error; 9177005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala bool withinActivity = false; 9187005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala bool isMainActivity = false; 9197005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala bool isLauncherActivity = false; 9207005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala bool isLeanbackLauncherActivity = false; 9217005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala bool isSearchable = false; 9227005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala bool withinApplication = false; 9237005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala bool withinSupportsInput = false; 9247005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala bool withinFeatureGroup = false; 9257005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala bool withinReceiver = false; 9267005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala bool withinService = false; 9277005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala bool withinProvider = false; 9287005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala bool withinIntentFilter = false; 9297005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala bool hasMainActivity = false; 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool hasOtherActivities = false; 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool hasOtherReceivers = false; 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool hasOtherServices = false; 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool hasIntentFilter = false; 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool hasWallpaperService = false; 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool hasImeService = false; 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool hasAccessibilityService = false; 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool hasPrintService = false; 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool hasWidgetReceivers = false; 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool hasDeviceAdminReceiver = false; 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool hasPaymentService = false; 942c62f9bd13327937aa2d2f20b44215397120634c1Dave Sparks bool hasDocumentsProvider = false; 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool hasCameraActivity = false; 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool hasCameraSecureActivity = false; 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool hasLauncher = false; 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool hasNotificationListenerService = false; 947c62f9bd13327937aa2d2f20b44215397120634c1Dave Sparks bool hasDreamService = false; 948c62f9bd13327937aa2d2f20b44215397120634c1Dave Sparks 949e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks bool actMainActivity = false; 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool actWidgetReceivers = false; 951e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks bool actDeviceAdminEnabled = false; 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool actImeService = false; 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool actWallpaperService = false; 954c62f9bd13327937aa2d2f20b44215397120634c1Dave Sparks bool actAccessibilityService = false; 955e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks bool actPrintService = false; 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool actHostApduService = false; 957e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks bool actOffHostApduService = false; 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool actDocumentsProvider = false; 9599b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li bool actNotificationListenerService = false; 960c62f9bd13327937aa2d2f20b44215397120634c1Dave Sparks bool actDreamService = false; 961ca367b717806c4c69190641c3361d3520a44ad08Eino-Ville Talvala bool actCamera = false; 962ca367b717806c4c69190641c3361d3520a44ad08Eino-Ville Talvala bool actCameraSecure = false; 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool catLauncher = false; 964a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks bool hasMetaHostPaymentCategory = false; 965a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks bool hasMetaOffHostPaymentCategory = false; 966a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // These permissions are required by services implementing services 96894927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp // the system binds to (IME, Accessibility, PrintServices, etc.) 969a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks bool hasBindDeviceAdminPermission = false; 970a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks bool hasBindInputMethodPermission = false; 971a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks bool hasBindAccessibilityServicePermission = false; 97294927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp bool hasBindPrintServicePermission = false; 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool hasBindNfcServicePermission = false; 974ca367b717806c4c69190641c3361d3520a44ad08Eino-Ville Talvala bool hasRequiredSafAttributes = false; 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool hasBindNotificationListenerServicePermission = false; 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool hasBindDreamServicePermission = false; 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 978e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks // These two implement the implicit permissions that are granted 979e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks // to pre-1.6 applications. 980e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks bool hasWriteExternalStoragePermission = false; 981e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks bool hasReadPhoneStatePermission = false; 982e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks 983e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks // If an app requests write storage, they will also get read storage. 984c62f9bd13327937aa2d2f20b44215397120634c1Dave Sparks bool hasReadExternalStoragePermission = false; 985f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li 986f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li // Implement transition to read and write call log. 987f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li bool hasReadContactsPermission = false; 988f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li bool hasWriteContactsPermission = false; 989f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li bool hasReadCallLogPermission = false; 990f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li bool hasWriteCallLogPermission = false; 991f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li 992e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks // This next group of variables is used to implement a group of 993e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks // backward-compatibility heuristics necessitated by the addition of 994e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks // some new uses-feature constants in 2.1 and 2.2. In most cases, the 995e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks // heuristic is "if an app requests a permission but doesn't explicitly 9963f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li // request the corresponding <uses-feature>, presume it's there anyway". 9973f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li 998e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks // 2.2 also added some other features that apps can request, but that 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // have no corresponding permission, so we cannot implement any 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // back-compatibility heuristic for them. The below are thus unnecessary 1001bb1e275c0e684dd213f124da77110cdd9d6f090cWu-cheng Li // (but are retained here for documentary purposes.) 10024c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li //bool specCompassFeature = false; 1003f0d6a48c6ad852b84687127f14b1ffde02416dc4Wu-cheng Li //bool specAccelerometerFeature = false; 10044c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li //bool specProximityFeature = false; 10054c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li //bool specAmbientLightFeature = false; 10064c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li //bool specLiveWallpaperFeature = false; 1007c62f9bd13327937aa2d2f20b44215397120634c1Dave Sparks 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int targetSdk = 0; 1009e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks int smallScreen = 1; 10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int normalScreen = 1; 1011e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks int largeScreen = 1; 10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int xlargeScreen = 1; 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int anyDensity = 1; 10149d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li int requiresSmallestWidthDp = 0; 10159d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li int compatibleWidthLimitDp = 0; 10169d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li int largestWidthLimitDp = 0; 10179d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li String8 pkg; 10189d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li String8 activityName; 10199d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li String8 activityLabel; 10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 activityIcon; 10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 activityBanner; 10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 receiverName; 10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 serviceName; 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Vector<String8> supportedInput; 10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FeatureGroup commonFeatures; 10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Vector<FeatureGroup> featureGroups; 10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project KeyedVector<String8, ImpliedFeature> impliedFeatures; 10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (code == ResXMLTree::END_TAG) { 10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project depth--; 10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (depth < 2) { 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (withinSupportsInput && !supportedInput.isEmpty()) { 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("supports-input: '"); 10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t N = supportedInput.size(); 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<N; i++) { 10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("%s", ResTable::normalizeForOutput( 10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project supportedInput[i].string()).string()); 10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i != N - 1) { 1041bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor printf("' '"); 1042bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } else { 10437478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li printf("'\n"); 10447478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li } 1045df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main } 1046df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main supportedInput.clear(); 10477478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li } 1048df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main withinApplication = false; 1049df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main withinSupportsInput = false; 1050bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor withinFeatureGroup = false; 1051bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } else if (depth < 3) { 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (withinActivity && isMainActivity) { 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 aName(getComponentName(pkg, activityName)); 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isLauncherActivity) { 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("launchable-activity:"); 105669ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick if (aName.length() > 0) { 105769ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick printf(" name='%s' ", 105869ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick ResTable::normalizeForOutput(aName.string()).string()); 105969ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick } 10609b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li printf(" label='%s' icon='%s'\n", 1061b4f95be03e018df825356fe2cd363797c66303f1Wu-cheng Li ResTable::normalizeForOutput(activityLabel.string()).string(), 1062b4f95be03e018df825356fe2cd363797c66303f1Wu-cheng Li ResTable::normalizeForOutput(activityIcon.string()).string()); 106383d3352cf7a67efd60732c0d40e5928f642f6808Eino-Ville Talvala } 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isLeanbackLauncherActivity) { 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("leanback-launchable-activity:"); 106683d3352cf7a67efd60732c0d40e5928f642f6808Eino-Ville Talvala if (aName.length() > 0) { 106783d3352cf7a67efd60732c0d40e5928f642f6808Eino-Ville Talvala printf(" name='%s' ", 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResTable::normalizeForOutput(aName.string()).string()); 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 107053b30912d3e8598c05e47308981971e958e98db2Wu-cheng Li printf(" label='%s' icon='%s' banner='%s'\n", 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResTable::normalizeForOutput(activityLabel.string()).string(), 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResTable::normalizeForOutput(activityIcon.string()).string(), 1073bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor ResTable::normalizeForOutput(activityBanner.string()).string()); 1074bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } 1075bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } 1076bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (!hasIntentFilter) { 1077bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor hasOtherActivities |= withinActivity; 1078bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor hasOtherReceivers |= withinReceiver; 1079bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor hasOtherServices |= withinService; 1080bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } else { 108136322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li if (withinService) { 1082bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor hasPaymentService |= (actHostApduService && hasMetaHostPaymentCategory && 1083da0a56df963353a1f1bd1914fa31f870d982dd5aScott Main hasBindNfcServicePermission); 10847478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li hasPaymentService |= (actOffHostApduService && hasMetaOffHostPaymentCategory && 10857478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li hasBindNfcServicePermission); 1086df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main } 1087df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main } 1088bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor withinActivity = false; 1089068ef42c3ffe1eccec10f97f08541304f679fe67Wu-cheng Li withinService = false; 1090068ef42c3ffe1eccec10f97f08541304f679fe67Wu-cheng Li withinReceiver = false; 1091bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor withinProvider = false; 10927478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li hasIntentFilter = false; 109353b30912d3e8598c05e47308981971e958e98db2Wu-cheng Li isMainActivity = isLauncherActivity = isLeanbackLauncherActivity = false; 1094b4f95be03e018df825356fe2cd363797c66303f1Wu-cheng Li } else if (depth < 4) { 1095b4f95be03e018df825356fe2cd363797c66303f1Wu-cheng Li if (withinIntentFilter) { 1096b4f95be03e018df825356fe2cd363797c66303f1Wu-cheng Li if (withinActivity) { 109783d3352cf7a67efd60732c0d40e5928f642f6808Eino-Ville Talvala hasMainActivity |= actMainActivity; 109853b30912d3e8598c05e47308981971e958e98db2Wu-cheng Li hasLauncher |= catLauncher; 109953b30912d3e8598c05e47308981971e958e98db2Wu-cheng Li hasCameraActivity |= actCamera; 110053b30912d3e8598c05e47308981971e958e98db2Wu-cheng Li hasCameraSecureActivity |= actCameraSecure; 110153b30912d3e8598c05e47308981971e958e98db2Wu-cheng Li hasOtherActivities |= !actMainActivity && !actCamera && !actCameraSecure; 110253b30912d3e8598c05e47308981971e958e98db2Wu-cheng Li } else if (withinReceiver) { 110353b30912d3e8598c05e47308981971e958e98db2Wu-cheng Li hasWidgetReceivers |= actWidgetReceivers; 1104108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala hasDeviceAdminReceiver |= (actDeviceAdminEnabled && 1105108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala hasBindDeviceAdminPermission); 1106108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala hasOtherReceivers |= (!actWidgetReceivers && !actDeviceAdminEnabled); 1107108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala } else if (withinService) { 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hasImeService |= actImeService; 1109bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor hasWallpaperService |= actWallpaperService; 111083d3352cf7a67efd60732c0d40e5928f642f6808Eino-Ville Talvala hasAccessibilityService |= (actAccessibilityService && 111183d3352cf7a67efd60732c0d40e5928f642f6808Eino-Ville Talvala hasBindAccessibilityServicePermission); 1112108708b4873fb05cb029b5bcb29a4e917004ca30Eino-Ville Talvala hasPrintService |= (actPrintService && hasBindPrintServicePermission); 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hasNotificationListenerService |= actNotificationListenerService && 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hasBindNotificationListenerServicePermission; 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hasDreamService |= actDreamService && hasBindDreamServicePermission; 1116f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li hasOtherServices |= (!actImeService && !actWallpaperService && 1117248ba23ad28c1f8fb69904663204df08c5818700James Dong !actAccessibilityService && !actPrintService && 1118248ba23ad28c1f8fb69904663204df08c5818700James Dong !actHostApduService && !actOffHostApduService && 1119f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li !actNotificationListenerService); 11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (withinProvider) { 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hasDocumentsProvider |= actDocumentsProvider && hasRequiredSafAttributes; 11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1124bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor withinIntentFilter = false; 1125bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } 1126bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor continue; 1127244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang } 1128bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (code != ResXMLTree::START_TAG) { 1129bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor continue; 1130244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang } 1131244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang depth++; 1132244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang 1133f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li const char16_t* ctag16 = tree.getElementName(&len); 1134248ba23ad28c1f8fb69904663204df08c5818700James Dong if (ctag16 == NULL) { 1135248ba23ad28c1f8fb69904663204df08c5818700James Dong fprintf(stderr, "ERROR: failed to get XML element name (bad string pool)\n"); 1136f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li goto bail; 1137f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li } 1138f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li String8 tag(ctag16); 1139f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li //printf("Depth %d, %s\n", depth, tag.string()); 1140f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li if (depth == 1) { 1141f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li if (tag != "manifest") { 1142f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li fprintf(stderr, "ERROR: manifest does not start with <manifest> tag\n"); 1143f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li goto bail; 1144f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li } 1145f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li pkg = getAttribute(tree, NULL, "package", NULL); 1146f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li printf("package: name='%s' ", 1147f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li ResTable::normalizeForOutput(pkg.string()).string()); 1148f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li int32_t versionCode = getIntegerAttribute(tree, VERSION_CODE_ATTR, &error); 1149f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li if (error != "") { 1150f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li fprintf(stderr, "ERROR getting 'android:versionCode' attribute: %s\n", error.string()); 1151f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li goto bail; 1152f05c1d63d16e790ac78c5854bb12374f45d6118eWu-cheng Li } 1153244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang if (versionCode > 0) { 1154244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang printf("versionCode='%d' ", versionCode); 1155244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang } else { 1156244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang printf("versionCode='' "); 11579d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li } 11589d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li String8 versionName = getResolvedAttribute(&res, tree, VERSION_NAME_ATTR, &error); 11596574539baecc8610529596554b7bca0f21b334b8Wu-cheng Li if (error != "") { 11606574539baecc8610529596554b7bca0f21b334b8Wu-cheng Li fprintf(stderr, "ERROR getting 'android:versionName' attribute: %s\n", error.string()); 11616574539baecc8610529596554b7bca0f21b334b8Wu-cheng Li goto bail; 11626574539baecc8610529596554b7bca0f21b334b8Wu-cheng Li } 11639d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li printf("versionName='%s'", 11649d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li ResTable::normalizeForOutput(versionName.string()).string()); 11659d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li 11669d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li String8 splitName = getAttribute(tree, NULL, "split", NULL); 11679d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li if (!splitName.isEmpty()) { 11689d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li printf(" split='%s'", ResTable::normalizeForOutput( 11699d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li splitName.string()).string()); 11706574539baecc8610529596554b7bca0f21b334b8Wu-cheng Li } 11719d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li printf("\n"); 11729d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li } else if (depth == 2) { 11739d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li withinApplication = false; 11749d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li if (tag == "application") { 11759d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li withinApplication = true; 11769d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li 11779d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li String8 label; 11789d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li const size_t NL = locales.size(); 11799d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li for (size_t i=0; i<NL; i++) { 11809d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li const char* localeStr = locales[i].string(); 11819d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li assets.setLocale(localeStr != NULL ? localeStr : ""); 11829d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li String8 llabel = getResolvedAttribute(&res, tree, LABEL_ATTR, &error); 11839d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li if (llabel != "") { 11849d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li if (localeStr == NULL || strlen(localeStr) == 0) { 11859d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li label = llabel; 11869d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li printf("application-label:'%s'\n", 11879d062cfe94dcd24b1d61fc83e5de565cb67965b1Wu-cheng Li ResTable::normalizeForOutput(llabel.string()).string()); 1188bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } else { 1189bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (label == "") { 1190bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor label = llabel; 11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("application-label-%s:'%s'\n", localeStr, 11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResTable::normalizeForOutput(llabel.string()).string()); 11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1195bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } 1196bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } 1197bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor 1198bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor ResTable_config tmpConfig = config; 1199bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor const size_t ND = densities.size(); 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<ND; i++) { 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmpConfig.density = densities[i]; 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assets.setConfiguration(tmpConfig); 12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 icon = getResolvedAttribute(&res, tree, ICON_ATTR, &error); 12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (icon != "") { 1205bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor printf("application-icon-%d:'%s'\n", densities[i], 1206bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor ResTable::normalizeForOutput(icon.string()).string()); 1207bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } 12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assets.setConfiguration(config); 12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1211bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor String8 icon = getResolvedAttribute(&res, tree, ICON_ATTR, &error); 1212bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (error != "") { 1213bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n", error.string()); 12149b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li goto bail; 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t testOnly = getIntegerAttribute(tree, TEST_ONLY_ATTR, &error, 0); 12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (error != "") { 12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR getting 'android:testOnly' attribute: %s\n", error.string()); 12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("application: label='%s' ", 1222bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor ResTable::normalizeForOutput(label.string()).string()); 12239b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li printf("icon='%s'\n", ResTable::normalizeForOutput(icon.string()).string()); 1224bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (testOnly != 0) { 12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("testOnly='%d'\n", testOnly); 12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1228e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks int32_t debuggable = getResolvedIntegerAttribute(&res, tree, DEBUGGABLE_ATTR, &error, 0); 1229e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks if (error != "") { 1230e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong fprintf(stderr, "ERROR getting 'android:debuggable' attribute: %s\n", error.string()); 1231e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks goto bail; 1232e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks } 12339b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (debuggable != 0) { 12349b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li printf("application-debuggable\n"); 12359b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 12369b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } else if (tag == "uses-sdk") { 12379b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li int32_t code = getIntegerAttribute(tree, MIN_SDK_VERSION_ATTR, &error); 1238e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong if (error != "") { 1239e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong error = ""; 12409b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li String8 name = getResolvedAttribute(&res, tree, MIN_SDK_VERSION_ATTR, &error); 12419b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (error != "") { 12429b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li fprintf(stderr, "ERROR getting 'android:minSdkVersion' attribute: %s\n", 12439b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li error.string()); 12449b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li goto bail; 1245e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks } 1246bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (name == "Donut") targetSdk = 4; 1247bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor printf("sdkVersion:'%s'\n", 1248bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor ResTable::normalizeForOutput(name.string()).string()); 124942419ce28a09eb63e29a8fef87e6f5534f41902fWu-cheng Li } else if (code != -1) { 125042419ce28a09eb63e29a8fef87e6f5534f41902fWu-cheng Li targetSdk = code; 125142419ce28a09eb63e29a8fef87e6f5534f41902fWu-cheng Li printf("sdkVersion:'%d'\n", code); 125240057ce749c8c4d274db0352a2af4344bda92dbaWu-cheng Li } 1253bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor code = getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR, NULL, -1); 1254bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (code != -1) { 125540057ce749c8c4d274db0352a2af4344bda92dbaWu-cheng Li printf("maxSdkVersion:'%d'\n", code); 1256bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } 1257bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor code = getIntegerAttribute(tree, TARGET_SDK_VERSION_ATTR, &error); 1258e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks if (error != "") { 1259bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor error = ""; 1260e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks String8 name = getResolvedAttribute(&res, tree, TARGET_SDK_VERSION_ATTR, &error); 1261e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks if (error != "") { 1262e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks fprintf(stderr, "ERROR getting 'android:targetSdkVersion' attribute: %s\n", 12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project error.string()); 12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 1265e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks } 12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (name == "Donut" && targetSdk < 4) targetSdk = 4; 1267e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong printf("targetSdkVersion:'%s'\n", 1268e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong ResTable::normalizeForOutput(name.string()).string()); 1269e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong } else if (code != -1) { 1270e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong if (targetSdk < code) { 1271e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong targetSdk = code; 1272e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong } 1273e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong printf("targetSdkVersion:'%d'\n", code); 1274e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong } 1275e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong } else if (tag == "uses-configuration") { 1276e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong int32_t reqTouchScreen = getIntegerAttribute(tree, 1277e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong REQ_TOUCH_SCREEN_ATTR, NULL, 0); 1278e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong int32_t reqKeyboardType = getIntegerAttribute(tree, 1279e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong REQ_KEYBOARD_TYPE_ATTR, NULL, 0); 1280e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong int32_t reqHardKeyboard = getIntegerAttribute(tree, 1281e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong REQ_HARD_KEYBOARD_ATTR, NULL, 0); 1282e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong int32_t reqNavigation = getIntegerAttribute(tree, 1283e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong REQ_NAVIGATION_ATTR, NULL, 0); 1284e9c6c9ccfde7a642a4c0554e2d066f3dbbea98ceWu-cheng Li int32_t reqFiveWayNav = getIntegerAttribute(tree, 12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project REQ_FIVE_WAY_NAV_ATTR, NULL, 0); 12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("uses-configuration:"); 1287e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks if (reqTouchScreen != 0) { 1288bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor printf(" reqTouchScreen='%d'", reqTouchScreen); 12893f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li } 12903f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li if (reqKeyboardType != 0) { 1291bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor printf(" reqKeyboardType='%d'", reqKeyboardType); 1292bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } 1293bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (reqHardKeyboard != 0) { 1294bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor printf(" reqHardKeyboard='%d'", reqHardKeyboard); 1295bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } 1296bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (reqNavigation != 0) { 1297bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor printf(" reqNavigation='%d'", reqNavigation); 1298bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } 1299bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (reqFiveWayNav != 0) { 130036f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li printf(" reqFiveWayNav='%d'", reqFiveWayNav); 130136f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li } 130236f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li printf("\n"); 13030ca25191c663ef229f1f475b17899f2017ed6980Wu-cheng Li } else if (tag == "supports-input") { 13040ca25191c663ef229f1f475b17899f2017ed6980Wu-cheng Li withinSupportsInput = true; 1305bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } else if (tag == "supports-screens") { 130636f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li smallScreen = getIntegerAttribute(tree, 130736f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li SMALL_SCREEN_ATTR, NULL, 1); 130836f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li normalScreen = getIntegerAttribute(tree, 130936f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li NORMAL_SCREEN_ATTR, NULL, 1); 1310bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor largeScreen = getIntegerAttribute(tree, 13113f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li LARGE_SCREEN_ATTR, NULL, 1); 13123f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li xlargeScreen = getIntegerAttribute(tree, 13138cbb8f5e1f939b03515cb4d5942c3fcb226efb9eWu-cheng Li XLARGE_SCREEN_ATTR, NULL, 1); 13140ca25191c663ef229f1f475b17899f2017ed6980Wu-cheng Li anyDensity = getIntegerAttribute(tree, 13150ca25191c663ef229f1f475b17899f2017ed6980Wu-cheng Li ANY_DENSITY_ATTR, NULL, 1); 131636f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li requiresSmallestWidthDp = getIntegerAttribute(tree, 131736f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li REQUIRES_SMALLEST_WIDTH_DP_ATTR, NULL, 0); 131836f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li compatibleWidthLimitDp = getIntegerAttribute(tree, 131936f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li COMPATIBLE_WIDTH_LIMIT_DP_ATTR, NULL, 0); 13202fe6fcaff4bdab45484055d6c18dd96d1b7b7be1Wu-cheng Li largestWidthLimitDp = getIntegerAttribute(tree, 13212fe6fcaff4bdab45484055d6c18dd96d1b7b7be1Wu-cheng Li LARGEST_WIDTH_LIMIT_DP_ATTR, NULL, 0); 13222fe6fcaff4bdab45484055d6c18dd96d1b7b7be1Wu-cheng Li } else if (tag == "feature-group") { 1323b982fb4fd36a3cd24a0bb17c964139fe4c9cbb47Wu-cheng Li withinFeatureGroup = true; 1324b982fb4fd36a3cd24a0bb17c964139fe4c9cbb47Wu-cheng Li FeatureGroup group; 1325b982fb4fd36a3cd24a0bb17c964139fe4c9cbb47Wu-cheng Li group.label = getResolvedAttribute(&res, tree, LABEL_ATTR, &error); 1326d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang if (error != "") { 132769ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick fprintf(stderr, "ERROR getting 'android:label' attribute:" 13282fe6fcaff4bdab45484055d6c18dd96d1b7b7be1Wu-cheng Li " %s\n", error.string()); 13292fe6fcaff4bdab45484055d6c18dd96d1b7b7be1Wu-cheng Li goto bail; 1330d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang } 133169ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick featureGroups.add(group); 133269ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick 1333b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang } else if (tag == "uses-feature") { 1334724c52244423feced2677fbd1f905e0b8b0639f2Chih-Chung Chang String8 name = getAttribute(tree, NAME_ATTR, &error); 1335724c52244423feced2677fbd1f905e0b8b0639f2Chih-Chung Chang if (name != "" && error == "") { 1336724c52244423feced2677fbd1f905e0b8b0639f2Chih-Chung Chang int req = getIntegerAttribute(tree, 1337724c52244423feced2677fbd1f905e0b8b0639f2Chih-Chung Chang REQUIRED_ATTR, NULL, 1); 1338724c52244423feced2677fbd1f905e0b8b0639f2Chih-Chung Chang 1339724c52244423feced2677fbd1f905e0b8b0639f2Chih-Chung Chang commonFeatures.features.add(name, req); 1340724c52244423feced2677fbd1f905e0b8b0639f2Chih-Chung Chang if (req) { 1341724c52244423feced2677fbd1f905e0b8b0639f2Chih-Chung Chang addParentFeatures(&commonFeatures, name); 1342724c52244423feced2677fbd1f905e0b8b0639f2Chih-Chung Chang } 1343724c52244423feced2677fbd1f905e0b8b0639f2Chih-Chung Chang } else { 1344724c52244423feced2677fbd1f905e0b8b0639f2Chih-Chung Chang int vers = getIntegerAttribute(tree, 1345724c52244423feced2677fbd1f905e0b8b0639f2Chih-Chung Chang GL_ES_VERSION_ATTR, &error); 1346724c52244423feced2677fbd1f905e0b8b0639f2Chih-Chung Chang if (error == "") { 1347724c52244423feced2677fbd1f905e0b8b0639f2Chih-Chung Chang if (vers > commonFeatures.openGLESVersion) { 1348b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang commonFeatures.openGLESVersion = vers; 13492fe6fcaff4bdab45484055d6c18dd96d1b7b7be1Wu-cheng Li } 13502fe6fcaff4bdab45484055d6c18dd96d1b7b7be1Wu-cheng Li } 13512fe6fcaff4bdab45484055d6c18dd96d1b7b7be1Wu-cheng Li } 13522fe6fcaff4bdab45484055d6c18dd96d1b7b7be1Wu-cheng Li } else if (tag == "uses-permission") { 13532fe6fcaff4bdab45484055d6c18dd96d1b7b7be1Wu-cheng Li String8 name = getAttribute(tree, NAME_ATTR, &error); 13542fe6fcaff4bdab45484055d6c18dd96d1b7b7be1Wu-cheng Li if (name != "" && error == "") { 13552fe6fcaff4bdab45484055d6c18dd96d1b7b7be1Wu-cheng Li if (name == "android.permission.CAMERA") { 1356724c52244423feced2677fbd1f905e0b8b0639f2Chih-Chung Chang addImpliedFeature(&impliedFeatures, "android.hardware.camera", 1357724c52244423feced2677fbd1f905e0b8b0639f2Chih-Chung Chang String8::format("requested %s permission", name.string()) 1358b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang .string()); 1359d303362ac21fb9de40f2f2366cbe7ecaa113dc12Wu-cheng Li } else if (name == "android.permission.ACCESS_FINE_LOCATION") { 1360d303362ac21fb9de40f2f2366cbe7ecaa113dc12Wu-cheng Li addImpliedFeature(&impliedFeatures, "android.hardware.location.gps", 1361d303362ac21fb9de40f2f2366cbe7ecaa113dc12Wu-cheng Li String8::format("requested %s permission", name.string()) 1362d303362ac21fb9de40f2f2366cbe7ecaa113dc12Wu-cheng Li .string()); 1363d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang addImpliedFeature(&impliedFeatures, "android.hardware.location", 1364e7bd22a9d9441916aa9c67d80ee9f02a2d3e10e5Chih-Chung Chang String8::format("requested %s permission", name.string()) 1365e7bd22a9d9441916aa9c67d80ee9f02a2d3e10e5Chih-Chung Chang .string()); 13662fe6fcaff4bdab45484055d6c18dd96d1b7b7be1Wu-cheng Li } else if (name == "android.permission.ACCESS_MOCK_LOCATION") { 1367d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang addImpliedFeature(&impliedFeatures, "android.hardware.location", 1368d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang String8::format("requested %s permission", name.string()) 1369d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang .string()); 1370d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang } else if (name == "android.permission.ACCESS_COARSE_LOCATION") { 1371487acdfb4eca3859fd688a1ff0a32fe6314b68f6Eino-Ville Talvala addImpliedFeature(&impliedFeatures, "android.hardware.location.network", 137269fe527bea12f262bfb1a5838f40e3433ad3cb78Eino-Ville Talvala String8::format("requested %s permission", name.string()) 1373487acdfb4eca3859fd688a1ff0a32fe6314b68f6Eino-Ville Talvala .string()); 1374487acdfb4eca3859fd688a1ff0a32fe6314b68f6Eino-Ville Talvala addImpliedFeature(&impliedFeatures, "android.hardware.location", 1375487acdfb4eca3859fd688a1ff0a32fe6314b68f6Eino-Ville Talvala String8::format("requested %s permission", name.string()) 1376487acdfb4eca3859fd688a1ff0a32fe6314b68f6Eino-Ville Talvala .string()); 1377487acdfb4eca3859fd688a1ff0a32fe6314b68f6Eino-Ville Talvala } else if (name == "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" || 137869fe527bea12f262bfb1a5838f40e3433ad3cb78Eino-Ville Talvala name == "android.permission.INSTALL_LOCATION_PROVIDER") { 1379487acdfb4eca3859fd688a1ff0a32fe6314b68f6Eino-Ville Talvala addImpliedFeature(&impliedFeatures, "android.hardware.location", 1380487acdfb4eca3859fd688a1ff0a32fe6314b68f6Eino-Ville Talvala String8::format("requested %s permission", name.string()) 1381487acdfb4eca3859fd688a1ff0a32fe6314b68f6Eino-Ville Talvala .string()); 1382487acdfb4eca3859fd688a1ff0a32fe6314b68f6Eino-Ville Talvala } else if (name == "android.permission.BLUETOOTH" || 1383487acdfb4eca3859fd688a1ff0a32fe6314b68f6Eino-Ville Talvala name == "android.permission.BLUETOOTH_ADMIN") { 138469fe527bea12f262bfb1a5838f40e3433ad3cb78Eino-Ville Talvala if (targetSdk > 4) { 138569fe527bea12f262bfb1a5838f40e3433ad3cb78Eino-Ville Talvala addImpliedFeature(&impliedFeatures, "android.hardware.bluetooth", 138669fe527bea12f262bfb1a5838f40e3433ad3cb78Eino-Ville Talvala String8::format("requested %s permission", name.string()) 1387487acdfb4eca3859fd688a1ff0a32fe6314b68f6Eino-Ville Talvala .string()); 1388487acdfb4eca3859fd688a1ff0a32fe6314b68f6Eino-Ville Talvala addImpliedFeature(&impliedFeatures, "android.hardware.bluetooth", 1389487acdfb4eca3859fd688a1ff0a32fe6314b68f6Eino-Ville Talvala "targetSdkVersion > 4"); 1390487acdfb4eca3859fd688a1ff0a32fe6314b68f6Eino-Ville Talvala } 139169fe527bea12f262bfb1a5838f40e3433ad3cb78Eino-Ville Talvala } else if (name == "android.permission.RECORD_AUDIO") { 1392487acdfb4eca3859fd688a1ff0a32fe6314b68f6Eino-Ville Talvala addImpliedFeature(&impliedFeatures, "android.hardware.microphone", 139369fe527bea12f262bfb1a5838f40e3433ad3cb78Eino-Ville Talvala String8::format("requested %s permission", name.string()) 139469fe527bea12f262bfb1a5838f40e3433ad3cb78Eino-Ville Talvala .string()); 13954f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala } else if (name == "android.permission.ACCESS_WIFI_STATE" || 13964f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala name == "android.permission.CHANGE_WIFI_STATE" || 13974f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala name == "android.permission.CHANGE_WIFI_MULTICAST_STATE") { 13984f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala addImpliedFeature(&impliedFeatures, "android.hardware.wifi", 13994f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala String8::format("requested %s permission", name.string()) 14004f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala .string()); 14014f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala } else if (name == "android.permission.CALL_PHONE" || 14024f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala name == "android.permission.CALL_PRIVILEGED" || 14034f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala name == "android.permission.MODIFY_PHONE_STATE" || 14044f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala name == "android.permission.PROCESS_OUTGOING_CALLS" || 14054f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala name == "android.permission.READ_SMS" || 14064f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala name == "android.permission.RECEIVE_SMS" || 14074f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala name == "android.permission.RECEIVE_MMS" || 14084f8e5ce21df881796d05a1b2117dd8868570a57bEino-Ville Talvala name == "android.permission.RECEIVE_WAP_PUSH" || 140969fe527bea12f262bfb1a5838f40e3433ad3cb78Eino-Ville Talvala name == "android.permission.SEND_SMS" || 141069fe527bea12f262bfb1a5838f40e3433ad3cb78Eino-Ville Talvala name == "android.permission.WRITE_APN_SETTINGS" || 1411bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor name == "android.permission.WRITE_SMS") { 1412bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor addImpliedFeature(&impliedFeatures, "android.hardware.telephony", 1413bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor String8("requested a telephony permission").string()); 1414bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } else if (name == "android.permission.WRITE_EXTERNAL_STORAGE") { 1415e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks hasWriteExternalStoragePermission = true; 14163f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li } else if (name == "android.permission.READ_EXTERNAL_STORAGE") { 1417e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks hasReadExternalStoragePermission = true; 1418e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks } else if (name == "android.permission.READ_PHONE_STATE") { 1419bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor hasReadPhoneStatePermission = true; 142036f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li } else if (name == "android.permission.READ_CONTACTS") { 142136f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li hasReadContactsPermission = true; 14223f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li } else if (name == "android.permission.WRITE_CONTACTS") { 142336f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li hasWriteContactsPermission = true; 142436f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li } else if (name == "android.permission.READ_CALL_LOG") { 1425e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks hasReadCallLogPermission = true; 1426e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks } else if (name == "android.permission.WRITE_CALL_LOG") { 14273f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li hasWriteCallLogPermission = true; 1428e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks } 1429e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks 1430e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks printUsesPermission(name, 14313f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li getIntegerAttribute(tree, REQUIRED_ATTR, NULL, 1) == 0, 143236f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR, NULL, -1)); 14338cbb8f5e1f939b03515cb4d5942c3fcb226efb9eWu-cheng Li } else { 14343f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 14358cbb8f5e1f939b03515cb4d5942c3fcb226efb9eWu-cheng Li error.string()); 1436e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks goto bail; 14373f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li } 1438e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks } else if (tag == "uses-package") { 14393f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li String8 name = getAttribute(tree, NAME_ATTR, &error); 1440e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks if (name != "" && error == "") { 14419b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li printf("uses-package:'%s'\n", 14424c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li ResTable::normalizeForOutput(name.string()).string()); 14434c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li } else { 14444c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 14454c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li error.string()); 14464c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li goto bail; 14474c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li } 14484c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li } else if (tag == "original-package") { 14494c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li String8 name = getAttribute(tree, NAME_ATTR, &error); 14504c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li if (name != "" && error == "") { 145153b30912d3e8598c05e47308981971e958e98db2Wu-cheng Li printf("original-package:'%s'\n", 1452464cb21e2aaa448072449b82156f18bd64c0e613Joe Fernandez ResTable::normalizeForOutput(name.string()).string()); 14534c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li } else { 1454f0d6a48c6ad852b84687127f14b1ffde02416dc4Wu-cheng Li fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 14554c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li error.string()); 14564c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li goto bail; 14574c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li } 1458c0c683b3344c67700882f8059e7d18266366daa9Wu-cheng Li } else if (tag == "supports-gl-texture") { 14594c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li String8 name = getAttribute(tree, NAME_ATTR, &error); 14604c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li if (name != "" && error == "") { 14614c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li printf("supports-gl-texture:'%s'\n", 1462c0c683b3344c67700882f8059e7d18266366daa9Wu-cheng Li ResTable::normalizeForOutput(name.string()).string()); 14634c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li } else { 14644c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 14654c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li error.string()); 14664c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li goto bail; 14674c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li } 14684c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li } else if (tag == "compatible-screens") { 14694c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li printCompatibleScreens(tree, &error); 1470c0c683b3344c67700882f8059e7d18266366daa9Wu-cheng Li if (error != "") { 14714c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li fprintf(stderr, "ERROR getting compatible screens: %s\n", 14724c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li error.string()); 14734c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li goto bail; 14744c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li } 1475c0c683b3344c67700882f8059e7d18266366daa9Wu-cheng Li depth--; 14764c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li } else if (tag == "package-verifier") { 14774c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li String8 name = getAttribute(tree, NAME_ATTR, &error); 14788c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li if (name != "" && error == "") { 14794c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li String8 publicKey = getAttribute(tree, PUBLIC_KEY_ATTR, &error); 14808c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li if (publicKey != "" && error == "") { 14818c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li printf("package-verifier: name='%s' publicKey='%s'\n", 14828c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li ResTable::normalizeForOutput(name.string()).string(), 14838c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li ResTable::normalizeForOutput(publicKey.string()).string()); 14848c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li } 14858c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li } 14868c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li } 14878c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li } else if (depth == 3) { 14888c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li withinActivity = false; 14898c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li withinReceiver = false; 14908c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li withinService = false; 14918c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li withinProvider = false; 14928c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li hasIntentFilter = false; 14934c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li hasMetaHostPaymentCategory = false; 1494c0c683b3344c67700882f8059e7d18266366daa9Wu-cheng Li hasMetaOffHostPaymentCategory = false; 14954c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li hasBindDeviceAdminPermission = false; 14964c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li hasBindInputMethodPermission = false; 14974c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li hasBindAccessibilityServicePermission = false; 14984c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li hasBindPrintServicePermission = false; 1499c0c683b3344c67700882f8059e7d18266366daa9Wu-cheng Li hasBindNfcServicePermission = false; 15004c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li hasRequiredSafAttributes = false; 1501c0c683b3344c67700882f8059e7d18266366daa9Wu-cheng Li hasBindNotificationListenerServicePermission = false; 15024c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li hasBindDreamServicePermission = false; 15034c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li if (withinApplication) { 15044c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li if(tag == "activity") { 1505c0c683b3344c67700882f8059e7d18266366daa9Wu-cheng Li withinActivity = true; 15064c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li activityName = getAttribute(tree, NAME_ATTR, &error); 15074c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li if (error != "") { 15084c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 15094c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li error.string()); 1510c0c683b3344c67700882f8059e7d18266366daa9Wu-cheng Li goto bail; 15114c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li } 1512464cb21e2aaa448072449b82156f18bd64c0e613Joe Fernandez 15134c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li activityLabel = getResolvedAttribute(&res, tree, LABEL_ATTR, &error); 15144c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li if (error != "") { 15154c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li fprintf(stderr, "ERROR getting 'android:label' attribute: %s\n", 15164c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li error.string()); 15174c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li goto bail; 15184c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li } 15194c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li 15204c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li activityIcon = getResolvedAttribute(&res, tree, ICON_ATTR, &error); 15214c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li if (error != "") { 15224c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n", 1523464cb21e2aaa448072449b82156f18bd64c0e613Joe Fernandez error.string()); 152453b30912d3e8598c05e47308981971e958e98db2Wu-cheng Li goto bail; 1525464cb21e2aaa448072449b82156f18bd64c0e613Joe Fernandez } 1526464cb21e2aaa448072449b82156f18bd64c0e613Joe Fernandez 15274c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li activityBanner = getResolvedAttribute(&res, tree, BANNER_ATTR, &error); 1528464cb21e2aaa448072449b82156f18bd64c0e613Joe Fernandez if (error != "") { 15294c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li fprintf(stderr, "ERROR getting 'android:banner' attribute: %s\n", 1530f0d6a48c6ad852b84687127f14b1ffde02416dc4Wu-cheng Li error.string()); 1531c0c683b3344c67700882f8059e7d18266366daa9Wu-cheng Li goto bail; 1532c0c683b3344c67700882f8059e7d18266366daa9Wu-cheng Li } 1533c0c683b3344c67700882f8059e7d18266366daa9Wu-cheng Li 1534bb1e275c0e684dd213f124da77110cdd9d6f090cWu-cheng Li int32_t orien = getResolvedIntegerAttribute(&res, tree, 1535bb1e275c0e684dd213f124da77110cdd9d6f090cWu-cheng Li SCREEN_ORIENTATION_ATTR, &error); 1536bb1e275c0e684dd213f124da77110cdd9d6f090cWu-cheng Li if (error == "") { 15374c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li if (orien == 0 || orien == 6 || orien == 8) { 15384c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li // Requests landscape, sensorLandscape, or reverseLandscape. 15394c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li addImpliedFeature(&impliedFeatures, "android.hardware.screen.landscape", 1540c0c683b3344c67700882f8059e7d18266366daa9Wu-cheng Li "one or more activities have specified a landscape orientation"); 1541c0c683b3344c67700882f8059e7d18266366daa9Wu-cheng Li } else if (orien == 1 || orien == 7 || orien == 9) { 15428c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li // Requests portrait, sensorPortrait, or reversePortrait. 15438c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li addImpliedFeature(&impliedFeatures, "android.hardware.screen.portrait", 15448c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li "one or more activities have specified a portrait orientation"); 15458c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li } 1546f0d6a48c6ad852b84687127f14b1ffde02416dc4Wu-cheng Li } 1547f0d6a48c6ad852b84687127f14b1ffde02416dc4Wu-cheng Li } else if (tag == "uses-library") { 1548f0d6a48c6ad852b84687127f14b1ffde02416dc4Wu-cheng Li String8 libraryName = getAttribute(tree, NAME_ATTR, &error); 15498c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li if (error != "") { 15508c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li fprintf(stderr, 15518c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li "ERROR getting 'android:name' attribute for uses-library" 15528c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li " %s\n", error.string()); 15538c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li goto bail; 15548c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li } 15558c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li int req = getIntegerAttribute(tree, 15568c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li REQUIRED_ATTR, NULL, 1); 15578c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li printf("uses-library%s:'%s'\n", 15588c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li req ? "" : "-not-required", ResTable::normalizeForOutput( 15598c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li libraryName.string()).string()); 15608c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li } else if (tag == "receiver") { 15618c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li withinReceiver = true; 15628c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li receiverName = getAttribute(tree, NAME_ATTR, &error); 15638c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li 15648c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li if (error != "") { 15658c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li fprintf(stderr, 15668c13670c13a7a965884d92193b039e26c96b95c6Wu-cheng Li "ERROR getting 'android:name' attribute for receiver:" 15674c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li " %s\n", error.string()); 1568464cb21e2aaa448072449b82156f18bd64c0e613Joe Fernandez goto bail; 15694c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li } 1570bb1e275c0e684dd213f124da77110cdd9d6f090cWu-cheng Li 15714c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li String8 permission = getAttribute(tree, PERMISSION_ATTR, &error); 15724c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li if (error == "") { 15738df3b2b3989df44953153603681e03140fd853d6Eino-Ville Talvala if (permission == "android.permission.BIND_DEVICE_ADMIN") { 15748df3b2b3989df44953153603681e03140fd853d6Eino-Ville Talvala hasBindDeviceAdminPermission = true; 15758df3b2b3989df44953153603681e03140fd853d6Eino-Ville Talvala } 15768df3b2b3989df44953153603681e03140fd853d6Eino-Ville Talvala } else { 15778df3b2b3989df44953153603681e03140fd853d6Eino-Ville Talvala fprintf(stderr, "ERROR getting 'android:permission' attribute for" 15788df3b2b3989df44953153603681e03140fd853d6Eino-Ville Talvala " receiver '%s': %s\n", receiverName.string(), error.string()); 15798df3b2b3989df44953153603681e03140fd853d6Eino-Ville Talvala } 15808df3b2b3989df44953153603681e03140fd853d6Eino-Ville Talvala } else if (tag == "service") { 15814c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li withinService = true; 1582464cb21e2aaa448072449b82156f18bd64c0e613Joe Fernandez serviceName = getAttribute(tree, NAME_ATTR, &error); 15834c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li 1584bb1e275c0e684dd213f124da77110cdd9d6f090cWu-cheng Li if (error != "") { 1585d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua fprintf(stderr, "ERROR getting 'android:name' attribute for " 1586d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua "service:%s\n", error.string()); 1587d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua goto bail; 1588d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua } 1589d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua 1590d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua String8 permission = getAttribute(tree, PERMISSION_ATTR, &error); 1591d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua if (error == "") { 1592d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua if (permission == "android.permission.BIND_INPUT_METHOD") { 1593d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua hasBindInputMethodPermission = true; 1594d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua } else if (permission == "android.permission.BIND_ACCESSIBILITY_SERVICE") { 1595d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua hasBindAccessibilityServicePermission = true; 1596d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua } else if (permission == "android.permission.BIND_PRINT_SERVICE") { 1597d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua hasBindPrintServicePermission = true; 1598d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua } else if (permission == "android.permission.BIND_NFC_SERVICE") { 1599d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua hasBindNfcServicePermission = true; 1600d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua } else if (permission == "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE") { 1601d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua hasBindNotificationListenerServicePermission = true; 1602d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua } else if (permission == "android.permission.BIND_DREAM_SERVICE") { 1603d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua hasBindDreamServicePermission = true; 1604d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua } 1605d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua } else { 1606d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua fprintf(stderr, "ERROR getting 'android:permission' attribute for" 1607d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua " service '%s': %s\n", serviceName.string(), error.string()); 1608d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua } 1609d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua } else if (tag == "provider") { 1610d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua withinProvider = true; 1611d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua 1612d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua bool exported = getResolvedIntegerAttribute(&res, tree, EXPORTED_ATTR, &error); 1613d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua if (error != "") { 1614d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua fprintf(stderr, "ERROR getting 'android:exported' attribute for provider:" 1615d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua " %s\n", error.string()); 1616d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua goto bail; 1617d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua } 1618d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua 1619d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua bool grantUriPermissions = getResolvedIntegerAttribute(&res, tree, 1620d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua GRANT_URI_PERMISSIONS_ATTR, &error); 1621d52b308916d5f207791788e00bc48baecb90d8b8Wei Hua if (error != "") { 16224c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li fprintf(stderr, "ERROR getting 'android:grantUriPermissions' attribute for provider:" 16234c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li " %s\n", error.string()); 1624bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor goto bail; 1625bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } 1626bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor 1627bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor String8 permission = getResolvedAttribute(&res, tree, PERMISSION_ATTR, &error); 1628bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (error != "") { 1629bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor fprintf(stderr, "ERROR getting 'android:permission' attribute for provider:" 16309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " %s\n", error.string()); 1631bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor goto bail; 1632bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } 1633bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor 1634bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor hasRequiredSafAttributes |= exported && grantUriPermissions && 1635bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor permission == "android.permission.MANAGE_DOCUMENTS"; 1636bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor 16379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (bundle->getIncludeMetaData() && tag == "meta-data") { 16389b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li String8 metaDataName = getResolvedAttribute(&res, tree, NAME_ATTR, &error); 16399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (error != "") { 1640bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor fprintf(stderr, "ERROR getting 'android:name' attribute for " 1641bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor "meta-data:%s\n", error.string()); 1642bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor goto bail; 16439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("meta-data: name='%s' ", 16459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResTable::normalizeForOutput(metaDataName.string()).string()); 16469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printResolvedResourceAttribute(&res, tree, VALUE_ATTR, String8("value"), 16479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project &error); 16489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (error != "") { 16499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Try looking for a RESOURCE_ATTR 16509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project error = ""; 16519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printResolvedResourceAttribute(&res, tree, RESOURCE_ATTR, 16529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8("resource"), &error); 16539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (error != "") { 16549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR getting 'android:value' or " 16559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "'android:resource' attribute for " 16569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "meta-data:%s\n", error.string()); 16579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 16589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1660bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor printf("\n"); 16619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (withinSupportsInput && tag == "input-type") { 16629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 name = getAttribute(tree, NAME_ATTR, &error); 16639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (name != "" && error == "") { 16649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project supportedInput.add(name); 16659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 16669b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 16679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project error.string()); 16689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 16699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1671bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor } else if (withinFeatureGroup && tag == "uses-feature") { 16729b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li FeatureGroup& top = featureGroups.editTop(); 16739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 167499a3f3e4e06b4370101ca97cc11dbe81d772fefaWu-cheng Li String8 name = getResolvedAttribute(&res, tree, NAME_ATTR, &error); 1675bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (name != "" && error == "") { 16769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int required = getIntegerAttribute(tree, REQUIRED_ATTR, NULL, 1); 16779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project top.features.add(name, required); 16787005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala if (required) { 16797005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala addParentFeatures(&top, name); 16807005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala } 16817005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala 16827005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala } else { 16837005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala int vers = getIntegerAttribute(tree, GL_ES_VERSION_ATTR, &error); 16847005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala if (error == "") { 16857005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala if (vers > top.openGLESVersion) { 16867005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala top.openGLESVersion = vers; 16877005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala } 16887005b67c127d229017840925d2bc1bd84c43aaf5Eino-Ville Talvala } 16899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (depth == 4) { 16929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tag == "intent-filter") { 1693bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor hasIntentFilter = true; 1694bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor withinIntentFilter = true; 1695bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor actMainActivity = false; 1696bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor actWidgetReceivers = false; 1697bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor actImeService = false; 16989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project actWallpaperService = false; 16999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project actAccessibilityService = false; 17009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project actPrintService = false; 17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project actDeviceAdminEnabled = false; 17029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project actHostApduService = false; 17039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project actOffHostApduService = false; 17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project actDocumentsProvider = false; 17059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project actNotificationListenerService = false; 17069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project actDreamService = false; 17071c04a33c040dfb610952d62da9c93a53c291b2d7Wu-cheng Li actCamera = false; 17081c04a33c040dfb610952d62da9c93a53c291b2d7Wu-cheng Li actCameraSecure = false; 1709f76a50ce8fdc6aea22cabc77b2977a1a15a79630Ken Wakasa catLauncher = false; 17101c04a33c040dfb610952d62da9c93a53c291b2d7Wu-cheng Li } else if (withinService && tag == "meta-data") { 17111c04a33c040dfb610952d62da9c93a53c291b2d7Wu-cheng Li String8 name = getAttribute(tree, NAME_ATTR, &error); 17121c04a33c040dfb610952d62da9c93a53c291b2d7Wu-cheng Li if (error != "") { 17131c04a33c040dfb610952d62da9c93a53c291b2d7Wu-cheng Li fprintf(stderr, "ERROR getting 'android:name' attribute for" 17141c04a33c040dfb610952d62da9c93a53c291b2d7Wu-cheng Li " meta-data tag in service '%s': %s\n", serviceName.string(), error.string()); 17151c04a33c040dfb610952d62da9c93a53c291b2d7Wu-cheng Li goto bail; 17161c04a33c040dfb610952d62da9c93a53c291b2d7Wu-cheng Li } 17171c04a33c040dfb610952d62da9c93a53c291b2d7Wu-cheng Li 17181c04a33c040dfb610952d62da9c93a53c291b2d7Wu-cheng Li if (name == "android.nfc.cardemulation.host_apdu_service" || 1719bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor name == "android.nfc.cardemulation.off_host_apdu_service") { 17209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool offHost = true; 17219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (name == "android.nfc.cardemulation.host_apdu_service") { 17229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offHost = false; 17239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17249b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 17259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 xmlPath = getResolvedAttribute(&res, tree, RESOURCE_ATTR, &error); 17269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (error != "") { 17279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR getting 'android:resource' attribute for" 17289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " meta-data tag in service '%s': %s\n", serviceName.string(), error.string()); 17299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 17309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17324c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li Vector<String8> categories = getNfcAidCategories(assets, xmlPath, 17334c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li offHost, &error); 17344c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li if (error != "") { 17354c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li fprintf(stderr, "ERROR getting AID category for service '%s'\n", 17364c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li serviceName.string()); 17374c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li goto bail; 17384c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li } 17394c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li 17404c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li const size_t catLen = categories.size(); 17414c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li for (size_t i = 0; i < catLen; i++) { 17424c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li bool paymentCategory = (categories[i] == "payment"); 17434c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li if (offHost) { 17444c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li hasMetaOffHostPaymentCategory |= paymentCategory; 17454c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li } else { 17464c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li hasMetaHostPaymentCategory |= paymentCategory; 17474c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li } 17484c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li } 17494c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li } 17504c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li } 17519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ((depth == 5) && withinIntentFilter) { 17529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 action; 17539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tag == "action") { 17549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project action = getAttribute(tree, NAME_ATTR, &error); 17559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (error != "") { 17569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 17579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project error.string()); 175832a972c693400db50717435139fa292a63bc937aEino-Ville Talvala goto bail; 175932a972c693400db50717435139fa292a63bc937aEino-Ville Talvala } 176032a972c693400db50717435139fa292a63bc937aEino-Ville Talvala 176132a972c693400db50717435139fa292a63bc937aEino-Ville Talvala if (withinActivity) { 176232a972c693400db50717435139fa292a63bc937aEino-Ville Talvala if (action == "android.intent.action.MAIN") { 176332a972c693400db50717435139fa292a63bc937aEino-Ville Talvala isMainActivity = true; 176432a972c693400db50717435139fa292a63bc937aEino-Ville Talvala actMainActivity = true; 176532a972c693400db50717435139fa292a63bc937aEino-Ville Talvala } else if (action == "android.media.action.STILL_IMAGE_CAMERA" || 176632a972c693400db50717435139fa292a63bc937aEino-Ville Talvala action == "android.media.action.VIDEO_CAMERA") { 176732a972c693400db50717435139fa292a63bc937aEino-Ville Talvala actCamera = true; 176832a972c693400db50717435139fa292a63bc937aEino-Ville Talvala } else if (action == "android.media.action.STILL_IMAGE_CAMERA_SECURE") { 176932a972c693400db50717435139fa292a63bc937aEino-Ville Talvala actCameraSecure = true; 177032a972c693400db50717435139fa292a63bc937aEino-Ville Talvala } 177132a972c693400db50717435139fa292a63bc937aEino-Ville Talvala } else if (withinReceiver) { 177232a972c693400db50717435139fa292a63bc937aEino-Ville Talvala if (action == "android.appwidget.action.APPWIDGET_UPDATE") { 177332a972c693400db50717435139fa292a63bc937aEino-Ville Talvala actWidgetReceivers = true; 177432a972c693400db50717435139fa292a63bc937aEino-Ville Talvala } else if (action == "android.app.action.DEVICE_ADMIN_ENABLED") { 177532a972c693400db50717435139fa292a63bc937aEino-Ville Talvala actDeviceAdminEnabled = true; 177632a972c693400db50717435139fa292a63bc937aEino-Ville Talvala } 177732a972c693400db50717435139fa292a63bc937aEino-Ville Talvala } else if (withinService) { 177832a972c693400db50717435139fa292a63bc937aEino-Ville Talvala if (action == "android.view.InputMethod") { 177932a972c693400db50717435139fa292a63bc937aEino-Ville Talvala actImeService = true; 1780bde61a5731cdfef76a0691f8bd53b880606f5f6eWu-cheng Li } else if (action == "android.service.wallpaper.WallpaperService") { 1781bde61a5731cdfef76a0691f8bd53b880606f5f6eWu-cheng Li actWallpaperService = true; 1782bde61a5731cdfef76a0691f8bd53b880606f5f6eWu-cheng Li } else if (action == "android.accessibilityservice.AccessibilityService") { 1783bde61a5731cdfef76a0691f8bd53b880606f5f6eWu-cheng Li actAccessibilityService = true; 1784bde61a5731cdfef76a0691f8bd53b880606f5f6eWu-cheng Li } else if (action == "android.printservice.PrintService") { 1785bde61a5731cdfef76a0691f8bd53b880606f5f6eWu-cheng Li actPrintService = true; 1786bde61a5731cdfef76a0691f8bd53b880606f5f6eWu-cheng Li } else if (action == "android.nfc.cardemulation.action.HOST_APDU_SERVICE") { 178730771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li actHostApduService = true; 178830771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li } else if (action == "android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE") { 178930771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li actOffHostApduService = true; 179030771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li } else if (action == "android.service.notification.NotificationListenerService") { 179130771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li actNotificationListenerService = true; 179232a972c693400db50717435139fa292a63bc937aEino-Ville Talvala } else if (action == "android.service.dreams.DreamService") { 179332a972c693400db50717435139fa292a63bc937aEino-Ville Talvala actDreamService = true; 179430771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li } 179530771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li } else if (withinProvider) { 179630771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li if (action == "android.content.action.DOCUMENTS_PROVIDER") { 179730771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li actDocumentsProvider = true; 179830771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li } 179930771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li } 180030771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li if (action == "android.intent.action.SEARCH") { 180130771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li isSearchable = true; 180230771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li } 180330771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li } 180430771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li 180530771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li if (tag == "category") { 180630771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li String8 category = getAttribute(tree, NAME_ATTR, &error); 180730771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li if (error != "") { 180830771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li fprintf(stderr, "ERROR getting 'name' attribute: %s\n", 180930771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li error.string()); 181030771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li goto bail; 181130771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li } 181230771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li if (withinActivity) { 181330771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li if (category == "android.intent.category.LAUNCHER") { 181430771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li isLauncherActivity = true; 181530771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li } else if (category == "android.intent.category.LEANBACK_LAUNCHER") { 181630771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li isLeanbackLauncherActivity = true; 181730771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li } else if (category == "android.intent.category.HOME") { 181830771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li catLauncher = true; 181930771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li } 1820bde61a5731cdfef76a0691f8bd53b880606f5f6eWu-cheng Li } 182132a972c693400db50717435139fa292a63bc937aEino-Ville Talvala } 182232a972c693400db50717435139fa292a63bc937aEino-Ville Talvala } 182332a972c693400db50717435139fa292a63bc937aEino-Ville Talvala } 182432a972c693400db50717435139fa292a63bc937aEino-Ville Talvala 182532a972c693400db50717435139fa292a63bc937aEino-Ville Talvala // Pre-1.6 implicitly granted permission compatibility logic 1826bde61a5731cdfef76a0691f8bd53b880606f5f6eWu-cheng Li if (targetSdk < 4) { 1827bde61a5731cdfef76a0691f8bd53b880606f5f6eWu-cheng Li if (!hasWriteExternalStoragePermission) { 1828bde61a5731cdfef76a0691f8bd53b880606f5f6eWu-cheng Li printUsesPermission(String8("android.permission.WRITE_EXTERNAL_STORAGE")); 1829bde61a5731cdfef76a0691f8bd53b880606f5f6eWu-cheng Li printUsesImpliedPermission(String8("android.permission.WRITE_EXTERNAL_STORAGE"), 183030771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li String8("targetSdkVersion < 4")); 183130771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li hasWriteExternalStoragePermission = true; 1832bde61a5731cdfef76a0691f8bd53b880606f5f6eWu-cheng Li } 183332a972c693400db50717435139fa292a63bc937aEino-Ville Talvala if (!hasReadPhoneStatePermission) { 183432a972c693400db50717435139fa292a63bc937aEino-Ville Talvala printUsesPermission(String8("android.permission.READ_PHONE_STATE")); 183532a972c693400db50717435139fa292a63bc937aEino-Ville Talvala printUsesImpliedPermission(String8("android.permission.READ_PHONE_STATE"), 183632a972c693400db50717435139fa292a63bc937aEino-Ville Talvala String8("targetSdkVersion < 4")); 183732a972c693400db50717435139fa292a63bc937aEino-Ville Talvala } 1838bde61a5731cdfef76a0691f8bd53b880606f5f6eWu-cheng Li } 1839bde61a5731cdfef76a0691f8bd53b880606f5f6eWu-cheng Li 1840bde61a5731cdfef76a0691f8bd53b880606f5f6eWu-cheng Li // If the application has requested WRITE_EXTERNAL_STORAGE, we will 1841bde61a5731cdfef76a0691f8bd53b880606f5f6eWu-cheng Li // force them to always take READ_EXTERNAL_STORAGE as well. We always 184230771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li // do this (regardless of target API version) because we can't have 1843bde61a5731cdfef76a0691f8bd53b880606f5f6eWu-cheng Li // an app with write permission but not read permission. 184430771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li if (!hasReadExternalStoragePermission && hasWriteExternalStoragePermission) { 184530771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li printUsesPermission(String8("android.permission.READ_EXTERNAL_STORAGE")); 1846bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor printUsesImpliedPermission(String8("android.permission.READ_EXTERNAL_STORAGE"), 18479b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li String8("requested WRITE_EXTERNAL_STORAGE")); 18489b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 1849bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor 1850bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor // Pre-JellyBean call log permission compatibility. 1851bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (targetSdk < 16) { 1852bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (!hasReadCallLogPermission && hasReadContactsPermission) { 18539b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li printUsesPermission(String8("android.permission.READ_CALL_LOG")); 18549b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li printUsesImpliedPermission(String8("android.permission.READ_CALL_LOG"), 18559b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li String8("targetSdkVersion < 16 and requested READ_CONTACTS")); 18569b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 1857bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor if (!hasWriteCallLogPermission && hasWriteContactsPermission) { 1858bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor printUsesPermission(String8("android.permission.WRITE_CALL_LOG")); 1859bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor printUsesImpliedPermission(String8("android.permission.WRITE_CALL_LOG"), 1860bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor String8("targetSdkVersion < 16 and requested WRITE_CONTACTS")); 18619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18639b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 18649b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li addImpliedFeature(&impliedFeatures, "android.hardware.touchscreen", 18659b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li "default feature for all apps"); 18669b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 1867454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li const size_t numFeatureGroups = featureGroups.size(); 18689b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (numFeatureGroups == 0) { 18699b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li // If no <feature-group> tags were defined, apply auto-implied features. 18704c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li printFeatureGroup(commonFeatures, &impliedFeatures); 18719b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 18729b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } else { 18739b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li // <feature-group> tags are defined, so we ignore implied features and 18749b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li for (size_t i = 0; i < numFeatureGroups; i++) { 18759b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li FeatureGroup& grp = featureGroups.editItemAt(i); 18769b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 18779b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (commonFeatures.openGLESVersion > grp.openGLESVersion) { 18789b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li grp.openGLESVersion = commonFeatures.openGLESVersion; 18799b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 1880055c986ab841f8f758398841730f1e90313b132aRay Chen 18819b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li // Merge the features defined in the top level (not inside a <feature-group>) 18829b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li // with this feature group. 18839b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li const size_t numCommonFeatures = commonFeatures.features.size(); 18849b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li for (size_t j = 0; j < numCommonFeatures; j++) { 18859b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (grp.features.indexOfKey(commonFeatures.features.keyAt(j)) < 0) { 188636322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li grp.features.add(commonFeatures.features.keyAt(j), 188730771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li commonFeatures.features[j]); 188830771b773393596812b6cfd2a4ddf490c43437aaWu-cheng Li } 18896c8d2760736a0753dad96b4bb8f98c7d075e6d54Wu-cheng Li } 18906c8d2760736a0753dad96b4bb8f98c7d075e6d54Wu-cheng Li 18916c8d2760736a0753dad96b4bb8f98c7d075e6d54Wu-cheng Li if (!grp.features.isEmpty()) { 1892ff723b6c43d5a8fd0ae0e0732f5d47012d74e01dWu-cheng Li printFeatureGroup(grp); 189324b326a8978bf78e3e560723dde221792784325bWu-cheng Li } 189424b326a8978bf78e3e560723dde221792784325bWu-cheng Li } 189524b326a8978bf78e3e560723dde221792784325bWu-cheng Li } 18963773eef4e36fa4171a84b495dca849be112df0a8Eino-Ville Talvala 18973773eef4e36fa4171a84b495dca849be112df0a8Eino-Ville Talvala 1898d9c2601afa46811bcb1345963d38010690981a01Eino-Ville Talvala if (hasWidgetReceivers) { 1899d9c2601afa46811bcb1345963d38010690981a01Eino-Ville Talvala printComponentPresence("app-widget"); 1900e98e4c806320ccb3078805ac019cca3ed9796123Wu-cheng Li } 1901e98e4c806320ccb3078805ac019cca3ed9796123Wu-cheng Li if (hasDeviceAdminReceiver) { 19028cbb8f5e1f939b03515cb4d5942c3fcb226efb9eWu-cheng Li printComponentPresence("device-admin"); 19038cbb8f5e1f939b03515cb4d5942c3fcb226efb9eWu-cheng Li } 19048cbb8f5e1f939b03515cb4d5942c3fcb226efb9eWu-cheng Li if (hasImeService) { 19058cbb8f5e1f939b03515cb4d5942c3fcb226efb9eWu-cheng Li printComponentPresence("ime"); 19068cbb8f5e1f939b03515cb4d5942c3fcb226efb9eWu-cheng Li } 1907e339c5edbebedf446581f18ad70214007309bf4bWu-cheng Li if (hasWallpaperService) { 1908dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong printComponentPresence("wallpaper"); 1909dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong } 1910dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong if (hasAccessibilityService) { 19114c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li printComponentPresence("accessibility"); 19124c2292efbbfe7338138a9a0e8eefeaabdef1a0b4Wu-cheng Li } 191325d8fb51dae37f1becf4fb3d32e8600c418eb6e8Wu-cheng Li if (hasPrintService) { 191498bb251c8b527600e7a4cca6cc33499710bbfbf1Wu-cheng Li printComponentPresence("print-service"); 1915037abb8bb064c2878858c9b69978f6754f242627Eino-Ville Talvala } 1916037abb8bb064c2878858c9b69978f6754f242627Eino-Ville Talvala if (hasPaymentService) { 1917e339c5edbebedf446581f18ad70214007309bf4bWu-cheng Li printComponentPresence("payment"); 19189b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 19199b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (isSearchable) { 19209b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li printComponentPresence("search"); 19218cbb8f5e1f939b03515cb4d5942c3fcb226efb9eWu-cheng Li } 19223773eef4e36fa4171a84b495dca849be112df0a8Eino-Ville Talvala if (hasDocumentsProvider) { 19238cbb8f5e1f939b03515cb4d5942c3fcb226efb9eWu-cheng Li printComponentPresence("document-provider"); 19249b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 19259b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (hasLauncher) { 19269b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li printComponentPresence("launcher"); 19279b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 19289b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (hasNotificationListenerService) { 19299b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li printComponentPresence("notification-listener"); 19309b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 19319b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (hasDreamService) { 19329b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li printComponentPresence("dream"); 19339b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 19349b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (hasCameraActivity) { 19359b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li printComponentPresence("camera"); 19369b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 19379b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (hasCameraSecureActivity) { 19389b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li printComponentPresence("camera-secure"); 19399b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 19409b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 19419b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (hasMainActivity) { 19429b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li printf("main\n"); 19439b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 19449b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (hasOtherActivities) { 19459b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li printf("other-activities\n"); 19469b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 19479b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (hasOtherReceivers) { 19489b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li printf("other-receivers\n"); 19499b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 19509b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (hasOtherServices) { 19519b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li printf("other-services\n"); 19529b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 19539b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 19549b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li // For modern apps, if screen size buckets haven't been specified 19559b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li // but the new width ranges have, then infer the buckets from them. 195636f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li if (smallScreen > 0 && normalScreen > 0 && largeScreen > 0 && xlargeScreen > 0 19579b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li && requiresSmallestWidthDp > 0) { 1958068ef42c3ffe1eccec10f97f08541304f679fe67Wu-cheng Li int compatWidth = compatibleWidthLimitDp; 1959068ef42c3ffe1eccec10f97f08541304f679fe67Wu-cheng Li if (compatWidth <= 0) { 19609b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li compatWidth = requiresSmallestWidthDp; 19619b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 196236f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li if (requiresSmallestWidthDp <= 240 && compatWidth >= 240) { 19639b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li smallScreen = -1; 1964068ef42c3ffe1eccec10f97f08541304f679fe67Wu-cheng Li } else { 1965068ef42c3ffe1eccec10f97f08541304f679fe67Wu-cheng Li smallScreen = 0; 19669b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 19679b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (requiresSmallestWidthDp <= 320 && compatWidth >= 320) { 196836f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li normalScreen = -1; 19699b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } else { 19709b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li normalScreen = 0; 19719b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 19729b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (requiresSmallestWidthDp <= 480 && compatWidth >= 480) { 197336f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li largeScreen = -1; 197436322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li } else { 1975068ef42c3ffe1eccec10f97f08541304f679fe67Wu-cheng Li largeScreen = 0; 1976068ef42c3ffe1eccec10f97f08541304f679fe67Wu-cheng Li } 197736322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li if (requiresSmallestWidthDp <= 720 && compatWidth >= 720) { 1978068ef42c3ffe1eccec10f97f08541304f679fe67Wu-cheng Li xlargeScreen = -1; 19799b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } else { 198000e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li xlargeScreen = 0; 198100e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li } 198200e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li } 19839b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 198400e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li // Determine default values for any unspecified screen sizes, 198500e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li // based on the target SDK of the package. As of 4 (donut) 198600e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li // the screen size support was introduced, so all default to 198700e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li // enabled. 198800e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li if (smallScreen > 0) { 19899b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li smallScreen = targetSdk >= 4 ? -1 : 0; 199000e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li } 199100e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li if (normalScreen > 0) { 199200e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li normalScreen = -1; 199300e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li } 19949b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (largeScreen > 0) { 199500e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li largeScreen = targetSdk >= 4 ? -1 : 0; 199600e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li } 199700e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li if (xlargeScreen > 0) { 199800e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li // Introduced in Gingerbread. 19999b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li xlargeScreen = targetSdk >= 9 ? -1 : 0; 200000e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li } 200100e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li if (anyDensity > 0) { 200200e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li anyDensity = (targetSdk >= 4 || requiresSmallestWidthDp > 0 200300e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li || compatibleWidthLimitDp > 0) ? -1 : 0; 20049b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 200500e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li printf("supports-screens:"); 200600e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li if (smallScreen != 0) { 200700e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li printf(" 'small'"); 200800e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li } 20099b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (normalScreen != 0) { 201000e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li printf(" 'normal'"); 201100e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li } 201200e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li if (largeScreen != 0) { 201300e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li printf(" 'large'"); 20149b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 201500e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li if (xlargeScreen != 0) { 201600e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li printf(" 'xlarge'"); 201700e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li } 201800e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li printf("\n"); 20199b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li printf("supports-any-density: '%s'\n", anyDensity ? "true" : "false"); 202000e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li if (requiresSmallestWidthDp > 0) { 202100e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li printf("requires-smallest-width:'%d'\n", requiresSmallestWidthDp); 202200e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li } 202300e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li if (compatibleWidthLimitDp > 0) { 20249b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li printf("compatible-width-limit:'%d'\n", compatibleWidthLimitDp); 202500e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li } 202600e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li if (largestWidthLimitDp > 0) { 202700e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li printf("largest-width-limit:'%d'\n", largestWidthLimitDp); 202800e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li } 20299b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 203000e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li printf("locales:"); 203100e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li const size_t NL = locales.size(); 203200e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li for (size_t i=0; i<NL; i++) { 203300e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li const char* localeStr = locales[i].string(); 20349b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (localeStr == NULL || strlen(localeStr) == 0) { 203500e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li localeStr = "--_--"; 203600e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li } 203700e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li printf(" '%s'", localeStr); 203800e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li } 20399b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li printf("\n"); 204000e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li 204100e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li printf("densities:"); 204200e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li const size_t ND = densities.size(); 204300e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li for (size_t i=0; i<ND; i++) { 204400e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li printf(" '%d'", densities[i]); 20459b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 204600e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li printf("\n"); 204700e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li 204800e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li AssetDir* dir = assets.openNonAssetDir(assetsCookie, "lib"); 204900e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li if (dir != NULL) { 20509b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (dir->getFileCount() > 0) { 205100e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li printf("native-code:"); 205200e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li for (size_t i=0; i<dir->getFileCount(); i++) { 205300e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li printf(" '%s'", ResTable::normalizeForOutput( 205400e21f8eb57a7ae2c19516aa0290ab4fb5f251c2Wu-cheng Li dir->getFileName(i).string()).string()); 20559b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 20569b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li printf("\n"); 2057c58b42327df5fbc826e2fcc2674ab6db0edfcd92Wu-cheng Li } 2058c58b42327df5fbc826e2fcc2674ab6db0edfcd92Wu-cheng Li delete dir; 2059c58b42327df5fbc826e2fcc2674ab6db0edfcd92Wu-cheng Li } 2060c58b42327df5fbc826e2fcc2674ab6db0edfcd92Wu-cheng Li } else if (strcmp("badger", option) == 0) { 2061c58b42327df5fbc826e2fcc2674ab6db0edfcd92Wu-cheng Li printf("%s", CONSOLE_DATA); 2062c58b42327df5fbc826e2fcc2674ab6db0edfcd92Wu-cheng Li } else if (strcmp("configurations", option) == 0) { 206336322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li Vector<ResTable_config> configs; 2064da2f0ea10822628875a956e4bf096066c0debe9fEino-Ville Talvala res.getConfigurations(&configs); 2065da2f0ea10822628875a956e4bf096066c0debe9fEino-Ville Talvala const size_t N = configs.size(); 2066da2f0ea10822628875a956e4bf096066c0debe9fEino-Ville Talvala for (size_t i=0; i<N; i++) { 2067da2f0ea10822628875a956e4bf096066c0debe9fEino-Ville Talvala printf("%s\n", configs[i].toString().string()); 2068da2f0ea10822628875a956e4bf096066c0debe9fEino-Ville Talvala } 2069da2f0ea10822628875a956e4bf096066c0debe9fEino-Ville Talvala } else { 2070da2f0ea10822628875a956e4bf096066c0debe9fEino-Ville Talvala fprintf(stderr, "ERROR: unknown dump option '%s'\n", option); 2071da2f0ea10822628875a956e4bf096066c0debe9fEino-Ville Talvala goto bail; 2072f008f3ea82a0518375ee4ea41b32451badffbd95Wu-cheng Li } 2073f008f3ea82a0518375ee4ea41b32451badffbd95Wu-cheng Li } 207436322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li 207536322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li result = NO_ERROR; 207636f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li 207736322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Libail: 207836322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li if (asset) { 207936322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li delete asset; 208036322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li } 208136322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li return (result != NO_ERROR); 2082f008f3ea82a0518375ee4ea41b32451badffbd95Wu-cheng Li} 2083f008f3ea82a0518375ee4ea41b32451badffbd95Wu-cheng Li 2084f008f3ea82a0518375ee4ea41b32451badffbd95Wu-cheng Li 2085f008f3ea82a0518375ee4ea41b32451badffbd95Wu-cheng Li/* 2086f008f3ea82a0518375ee4ea41b32451badffbd95Wu-cheng Li * Handle the "add" command, which wants to add files to a new or 2087f008f3ea82a0518375ee4ea41b32451badffbd95Wu-cheng Li * pre-existing archive. 208836322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li */ 208936f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Liint doAdd(Bundle* bundle) 209036322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li{ 209136322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li ZipFile* zip = NULL; 209236322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li status_t result = UNKNOWN_ERROR; 209336322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li const char* zipFileName; 209436322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li 209536322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li if (bundle->getUpdate()) { 209636322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li /* avoid confusion */ 209736322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li fprintf(stderr, "ERROR: can't use '-u' with add\n"); 2098c58b42327df5fbc826e2fcc2674ab6db0edfcd92Wu-cheng Li goto bail; 2099c58b42327df5fbc826e2fcc2674ab6db0edfcd92Wu-cheng Li } 2100c58b42327df5fbc826e2fcc2674ab6db0edfcd92Wu-cheng Li 2101c58b42327df5fbc826e2fcc2674ab6db0edfcd92Wu-cheng Li if (bundle->getFileSpecCount() < 1) { 2102c58b42327df5fbc826e2fcc2674ab6db0edfcd92Wu-cheng Li fprintf(stderr, "ERROR: must specify zip file name\n"); 2103c58b42327df5fbc826e2fcc2674ab6db0edfcd92Wu-cheng Li goto bail; 2104c58b42327df5fbc826e2fcc2674ab6db0edfcd92Wu-cheng Li } 2105699fe9397974685e6b2c73f9a3a0eb9e5a5a2ccfWu-cheng Li zipFileName = bundle->getFileSpecEntry(0); 2106d45cb72ac0d7d57829ffc9223decb89a5fc42ce2Wu-cheng Li 2107b9ac75d3dfc53ab4a0a104da147f1dfd7bc8c12fWu-cheng Li if (bundle->getFileSpecCount() < 2) { 2108b9ac75d3dfc53ab4a0a104da147f1dfd7bc8c12fWu-cheng Li fprintf(stderr, "NOTE: nothing to do\n"); 2109b9ac75d3dfc53ab4a0a104da147f1dfd7bc8c12fWu-cheng Li goto bail; 2110b9ac75d3dfc53ab4a0a104da147f1dfd7bc8c12fWu-cheng Li } 2111b9ac75d3dfc53ab4a0a104da147f1dfd7bc8c12fWu-cheng Li 211253b30912d3e8598c05e47308981971e958e98db2Wu-cheng Li zip = openReadWrite(zipFileName, true); 211353b30912d3e8598c05e47308981971e958e98db2Wu-cheng Li if (zip == NULL) { 211453b30912d3e8598c05e47308981971e958e98db2Wu-cheng Li fprintf(stderr, "ERROR: failed opening/creating '%s' as Zip file\n", zipFileName); 211553b30912d3e8598c05e47308981971e958e98db2Wu-cheng Li goto bail; 211653b30912d3e8598c05e47308981971e958e98db2Wu-cheng Li } 211753b30912d3e8598c05e47308981971e958e98db2Wu-cheng Li 211853b30912d3e8598c05e47308981971e958e98db2Wu-cheng Li for (int i = 1; i < bundle->getFileSpecCount(); i++) { 211953b30912d3e8598c05e47308981971e958e98db2Wu-cheng Li const char* fileName = bundle->getFileSpecEntry(i); 212053b30912d3e8598c05e47308981971e958e98db2Wu-cheng Li 212153b30912d3e8598c05e47308981971e958e98db2Wu-cheng Li if (strcasecmp(String8(fileName).getPathExtension().string(), ".gz") == 0) { 212253b30912d3e8598c05e47308981971e958e98db2Wu-cheng Li printf(" '%s'... (from gzip)\n", fileName); 212353b30912d3e8598c05e47308981971e958e98db2Wu-cheng Li result = zip->addGzip(fileName, String8(fileName).getBasePath().string(), NULL); 2124d45cb72ac0d7d57829ffc9223decb89a5fc42ce2Wu-cheng Li } else { 2125d45cb72ac0d7d57829ffc9223decb89a5fc42ce2Wu-cheng Li if (bundle->getJunkPath()) { 2126699fe9397974685e6b2c73f9a3a0eb9e5a5a2ccfWu-cheng Li String8 storageName = String8(fileName).getPathLeaf(); 2127b9ac75d3dfc53ab4a0a104da147f1dfd7bc8c12fWu-cheng Li printf(" '%s' as '%s'...\n", fileName, 2128b9ac75d3dfc53ab4a0a104da147f1dfd7bc8c12fWu-cheng Li ResTable::normalizeForOutput(storageName.string()).string()); 2129b9ac75d3dfc53ab4a0a104da147f1dfd7bc8c12fWu-cheng Li result = zip->add(fileName, storageName.string(), 2130b9ac75d3dfc53ab4a0a104da147f1dfd7bc8c12fWu-cheng Li bundle->getCompressionMethod(), NULL); 213153b30912d3e8598c05e47308981971e958e98db2Wu-cheng Li } else { 213253b30912d3e8598c05e47308981971e958e98db2Wu-cheng Li printf(" '%s'...\n", fileName); 21330f4f97b70f6ad59b32e78720ba7357733bdef3e9Wu-cheng Li result = zip->add(fileName, bundle->getCompressionMethod(), NULL); 21340f4f97b70f6ad59b32e78720ba7357733bdef3e9Wu-cheng Li } 21350f4f97b70f6ad59b32e78720ba7357733bdef3e9Wu-cheng Li } 21360f4f97b70f6ad59b32e78720ba7357733bdef3e9Wu-cheng Li if (result != NO_ERROR) { 21370f4f97b70f6ad59b32e78720ba7357733bdef3e9Wu-cheng Li fprintf(stderr, "Unable to add '%s' to '%s'", bundle->getFileSpecEntry(i), zipFileName); 21380f4f97b70f6ad59b32e78720ba7357733bdef3e9Wu-cheng Li if (result == NAME_NOT_FOUND) { 21390f4f97b70f6ad59b32e78720ba7357733bdef3e9Wu-cheng Li fprintf(stderr, ": file not found\n"); 21400f4f97b70f6ad59b32e78720ba7357733bdef3e9Wu-cheng Li } else if (result == ALREADY_EXISTS) { 21410f4f97b70f6ad59b32e78720ba7357733bdef3e9Wu-cheng Li fprintf(stderr, ": already exists in archive\n"); 21420f4f97b70f6ad59b32e78720ba7357733bdef3e9Wu-cheng Li } else { 21430f4f97b70f6ad59b32e78720ba7357733bdef3e9Wu-cheng Li fprintf(stderr, "\n"); 21440f4f97b70f6ad59b32e78720ba7357733bdef3e9Wu-cheng Li } 2145b9ac75d3dfc53ab4a0a104da147f1dfd7bc8c12fWu-cheng Li goto bail; 2146b9ac75d3dfc53ab4a0a104da147f1dfd7bc8c12fWu-cheng Li } 2147b9ac75d3dfc53ab4a0a104da147f1dfd7bc8c12fWu-cheng Li } 2148b9ac75d3dfc53ab4a0a104da147f1dfd7bc8c12fWu-cheng Li 2149b9ac75d3dfc53ab4a0a104da147f1dfd7bc8c12fWu-cheng Li result = NO_ERROR; 2150e339c5edbebedf446581f18ad70214007309bf4bWu-cheng Li 2151e339c5edbebedf446581f18ad70214007309bf4bWu-cheng Libail: 2152e339c5edbebedf446581f18ad70214007309bf4bWu-cheng Li delete zip; 2153e339c5edbebedf446581f18ad70214007309bf4bWu-cheng Li return (result != NO_ERROR); 2154e339c5edbebedf446581f18ad70214007309bf4bWu-cheng Li} 2155e339c5edbebedf446581f18ad70214007309bf4bWu-cheng Li 2156e339c5edbebedf446581f18ad70214007309bf4bWu-cheng Li 2157e339c5edbebedf446581f18ad70214007309bf4bWu-cheng Li/* 2158e339c5edbebedf446581f18ad70214007309bf4bWu-cheng Li * Delete files from an existing archive. 2159e339c5edbebedf446581f18ad70214007309bf4bWu-cheng Li */ 2160e339c5edbebedf446581f18ad70214007309bf4bWu-cheng Liint doRemove(Bundle* bundle) 2161e339c5edbebedf446581f18ad70214007309bf4bWu-cheng Li{ 2162e339c5edbebedf446581f18ad70214007309bf4bWu-cheng Li ZipFile* zip = NULL; 2163e339c5edbebedf446581f18ad70214007309bf4bWu-cheng Li status_t result = UNKNOWN_ERROR; 2164e339c5edbebedf446581f18ad70214007309bf4bWu-cheng Li const char* zipFileName; 2165e339c5edbebedf446581f18ad70214007309bf4bWu-cheng Li 2166e339c5edbebedf446581f18ad70214007309bf4bWu-cheng Li if (bundle->getFileSpecCount() < 1) { 2167e339c5edbebedf446581f18ad70214007309bf4bWu-cheng Li fprintf(stderr, "ERROR: must specify zip file name\n"); 2168e339c5edbebedf446581f18ad70214007309bf4bWu-cheng Li goto bail; 2169ca099614841bc619f217dfa088da630a7eb1ab65Wu-cheng Li } 2170454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li zipFileName = bundle->getFileSpecEntry(0); 2171454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 2172454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li if (bundle->getFileSpecCount() < 2) { 2173454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li fprintf(stderr, "NOTE: nothing to do\n"); 2174454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li goto bail; 2175454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li } 2176454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 2177454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li zip = openReadWrite(zipFileName, false); 2178454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li if (zip == NULL) { 2179454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li fprintf(stderr, "ERROR: failed opening Zip archive '%s'\n", 2180454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li zipFileName); 2181454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li goto bail; 2182454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li } 21839b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 21849b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li for (int i = 1; i < bundle->getFileSpecCount(); i++) { 21859b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li const char* fileName = bundle->getFileSpecEntry(i); 2186eb68c46a40c773eb56ef7bcf8e7ece5c6a5a8d23Chih-Chung Chang ZipEntry* entry; 218710a1b30dfbd0bbeae6776e353600986647c6e0a8Wu-cheng Li 21889b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li entry = zip->getEntryByName(fileName); 21899b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (entry == NULL) { 219070fb9085044c5e6f52c33c970d238b764cf2373bWu-cheng Li printf(" '%s' NOT FOUND\n", fileName); 21919b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li continue; 21927d9a8ffd08fa950eb14f8224f6090fe46ab4aa9fIgor Murashkin } 21937d9a8ffd08fa950eb14f8224f6090fe46ab4aa9fIgor Murashkin 21947d9a8ffd08fa950eb14f8224f6090fe46ab4aa9fIgor Murashkin result = zip->remove(entry); 21957d9a8ffd08fa950eb14f8224f6090fe46ab4aa9fIgor Murashkin 21967d9a8ffd08fa950eb14f8224f6090fe46ab4aa9fIgor Murashkin if (result != NO_ERROR) { 21977d9a8ffd08fa950eb14f8224f6090fe46ab4aa9fIgor Murashkin fprintf(stderr, "Unable to delete '%s' from '%s'\n", 21987d9a8ffd08fa950eb14f8224f6090fe46ab4aa9fIgor Murashkin bundle->getFileSpecEntry(i), zipFileName); 21997d9a8ffd08fa950eb14f8224f6090fe46ab4aa9fIgor Murashkin goto bail; 22007d9a8ffd08fa950eb14f8224f6090fe46ab4aa9fIgor Murashkin } 22017d9a8ffd08fa950eb14f8224f6090fe46ab4aa9fIgor Murashkin } 22027d9a8ffd08fa950eb14f8224f6090fe46ab4aa9fIgor Murashkin 22039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* update the archive */ 22049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zip->flush(); 22057d9a8ffd08fa950eb14f8224f6090fe46ab4aa9fIgor Murashkin 22069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbail: 22079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete zip; 22089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (result != NO_ERROR); 22099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 22109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic status_t addResourcesToBuilder(const sp<AaptDir>& dir, const sp<ApkBuilder>& builder, bool ignoreConfig=false) { 22129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t numDirs = dir->getDirs().size(); 22139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i = 0; i < numDirs; i++) { 22149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool ignore = ignoreConfig; 22159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const sp<AaptDir>& subDir = dir->getDirs().valueAt(i); 22169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* dirStr = subDir->getLeaf().string(); 22179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!ignore && strstr(dirStr, "mipmap") == dirStr) { 22189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ignore = true; 22199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = addResourcesToBuilder(subDir, builder, ignore); 22219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 22229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return err; 22239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22249b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 22259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t numFiles = dir->getFiles().size(); 22279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i = 0; i < numFiles; i++) { 22289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<AaptGroup> gp = dir->getFiles().valueAt(i); 22290a12018e4cd6eaaeaec795f6b2af4499fe3a8bcdAli Utku Selen const size_t numConfigs = gp->getFiles().size(); 22309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t j = 0; j < numConfigs; j++) { 22319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = NO_ERROR; 22329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ignoreConfig) { 22339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = builder->getBaseSplit()->addEntry(gp->getPath(), gp->getFiles().valueAt(j)); 22349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 22359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = builder->addEntry(gp->getPath(), gp->getFiles().valueAt(j)); 22369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 22389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "Failed to add %s (%s) to builder.\n", 22399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gp->getPath().string(), gp->getFiles()[j]->getPrintableSource().string()); 22409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return err; 22419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22429b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 22439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 22459b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li} 22469b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 22479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic String8 buildApkName(const String8& original, const sp<ApkSplit>& split) { 22489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (split->isBase()) { 22499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return original; 22509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22519b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 22520a12018e4cd6eaaeaec795f6b2af4499fe3a8bcdAli Utku Selen String8 ext(original.getPathExtension()); 22530a12018e4cd6eaaeaec795f6b2af4499fe3a8bcdAli Utku Selen if (ext == String8(".apk")) { 22540a12018e4cd6eaaeaec795f6b2af4499fe3a8bcdAli Utku Selen return String8::format("%s_%s%s", 22559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project original.getBasePath().string(), 22569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project split->getDirectorySafeName().string(), 22579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ext.string()); 22589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return String8::format("%s_%s", original.string(), 22619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project split->getDirectorySafeName().string()); 22629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 22639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22649b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li/* 22659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Package up an asset directory and associated application files. 22669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 22679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint doPackage(Bundle* bundle) 22689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 22699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* outputAPKFile; 22709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int retVal = 1; 22719b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li status_t err; 22729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<AaptAssets> assets; 22739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int N; 22749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FILE* fp; 22759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 dependencyFile; 2276cb56923ba6350cf7441260886f6e8a1c6785886dEino-Ville Talvala sp<ApkBuilder> builder; 2277cb56923ba6350cf7441260886f6e8a1c6785886dEino-Ville Talvala 22789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // -c en_XA or/and ar_XB means do pseudolocalization 22799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<WeakResourceFilter> configFilter = new WeakResourceFilter(); 2280cb56923ba6350cf7441260886f6e8a1c6785886dEino-Ville Talvala err = configFilter->parse(bundle->getConfigurations()); 2281cb56923ba6350cf7441260886f6e8a1c6785886dEino-Ville Talvala if (err != NO_ERROR) { 22829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 22839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (configFilter->containsPseudo()) { 22857d9a8ffd08fa950eb14f8224f6090fe46ab4aa9fIgor Murashkin bundle->setPseudolocalize(bundle->getPseudolocalize() | PSEUDO_ACCENTED); 22869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (configFilter->containsPseudoBidi()) { 22889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bundle->setPseudolocalize(bundle->getPseudolocalize() | PSEUDO_BIDI); 22899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22909b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 22919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project N = bundle->getFileSpecCount(); 22929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (N < 1 && bundle->getResourceSourceDirs().size() == 0 && bundle->getJarFiles().size() == 0 22939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && bundle->getAndroidManifestFile() == NULL && bundle->getAssetSourceDirs().size() == 0) { 22949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: no input files\n"); 22957d9a8ffd08fa950eb14f8224f6090fe46ab4aa9fIgor Murashkin goto bail; 22967d9a8ffd08fa950eb14f8224f6090fe46ab4aa9fIgor Murashkin } 22977d9a8ffd08fa950eb14f8224f6090fe46ab4aa9fIgor Murashkin 22987d9a8ffd08fa950eb14f8224f6090fe46ab4aa9fIgor Murashkin outputAPKFile = bundle->getOutputAPKFile(); 22997d9a8ffd08fa950eb14f8224f6090fe46ab4aa9fIgor Murashkin 23007d9a8ffd08fa950eb14f8224f6090fe46ab4aa9fIgor Murashkin // Make sure the filenames provided exist and are of the appropriate type. 23017d9a8ffd08fa950eb14f8224f6090fe46ab4aa9fIgor Murashkin if (outputAPKFile) { 23027d9a8ffd08fa950eb14f8224f6090fe46ab4aa9fIgor Murashkin FileType type; 23037d9a8ffd08fa950eb14f8224f6090fe46ab4aa9fIgor Murashkin type = getFileType(outputAPKFile); 23047d9a8ffd08fa950eb14f8224f6090fe46ab4aa9fIgor Murashkin if (type != kFileTypeNonexistent && type != kFileTypeRegular) { 23057d9a8ffd08fa950eb14f8224f6090fe46ab4aa9fIgor Murashkin fprintf(stderr, 23067d9a8ffd08fa950eb14f8224f6090fe46ab4aa9fIgor Murashkin "ERROR: output file '%s' exists but is not regular file\n", 23079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outputAPKFile); 23089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 2309e98e4c806320ccb3078805ac019cca3ed9796123Wu-cheng Li } 2310f715bf95ded30821e81ba93bb48c08725e1c34aaWu-cheng Li } 2311f715bf95ded30821e81ba93bb48c08725e1c34aaWu-cheng Li 2312f715bf95ded30821e81ba93bb48c08725e1c34aaWu-cheng Li // Load the assets. 2313f715bf95ded30821e81ba93bb48c08725e1c34aaWu-cheng Li assets = new AaptAssets(); 2314f715bf95ded30821e81ba93bb48c08725e1c34aaWu-cheng Li 2315f715bf95ded30821e81ba93bb48c08725e1c34aaWu-cheng Li // Set up the resource gathering in assets if we're going to generate 2316f715bf95ded30821e81ba93bb48c08725e1c34aaWu-cheng Li // dependency files. Every time we encounter a resource while slurping 2317f715bf95ded30821e81ba93bb48c08725e1c34aaWu-cheng Li // the tree, we'll add it to these stores so we have full resource paths 2318f715bf95ded30821e81ba93bb48c08725e1c34aaWu-cheng Li // to write to a dependency file. 2319f715bf95ded30821e81ba93bb48c08725e1c34aaWu-cheng Li if (bundle->getGenDependencies()) { 2320f715bf95ded30821e81ba93bb48c08725e1c34aaWu-cheng Li sp<FilePathStore> resPathStore = new FilePathStore; 2321f715bf95ded30821e81ba93bb48c08725e1c34aaWu-cheng Li assets->setFullResPaths(resPathStore); 2322f715bf95ded30821e81ba93bb48c08725e1c34aaWu-cheng Li sp<FilePathStore> assetPathStore = new FilePathStore; 2323f715bf95ded30821e81ba93bb48c08725e1c34aaWu-cheng Li assets->setFullAssetPaths(assetPathStore); 2324f715bf95ded30821e81ba93bb48c08725e1c34aaWu-cheng Li } 2325f715bf95ded30821e81ba93bb48c08725e1c34aaWu-cheng Li 2326f715bf95ded30821e81ba93bb48c08725e1c34aaWu-cheng Li err = assets->slurpFromArgs(bundle); 2327f715bf95ded30821e81ba93bb48c08725e1c34aaWu-cheng Li if (err < 0) { 2328f715bf95ded30821e81ba93bb48c08725e1c34aaWu-cheng Li goto bail; 2329f715bf95ded30821e81ba93bb48c08725e1c34aaWu-cheng Li } 2330f715bf95ded30821e81ba93bb48c08725e1c34aaWu-cheng Li 2331e98e4c806320ccb3078805ac019cca3ed9796123Wu-cheng Li if (bundle->getVerbose()) { 2332e98e4c806320ccb3078805ac019cca3ed9796123Wu-cheng Li assets->print(String8()); 2333e98e4c806320ccb3078805ac019cca3ed9796123Wu-cheng Li } 23349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Create the ApkBuilder, which will collect the compiled files 23369b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li // to write to the final APK (or sets of APKs if we are building 23379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // a Split APK. 23389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder = new ApkBuilder(configFilter); 23399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If we are generating a Split APK, find out which configurations to split on. 23419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getSplitConfigurations().size() > 0) { 23429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Vector<String8>& splitStrs = bundle->getSplitConfigurations(); 23439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t numSplits = splitStrs.size(); 23449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i = 0; i < numSplits; i++) { 23459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project std::set<ConfigDescription> configs; 23469b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (!AaptConfig::parseCommaSeparatedList(splitStrs[i], &configs)) { 23479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: failed to parse split configuration '%s'\n", splitStrs[i].string()); 23489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 23499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = builder->createSplitForConfigs(configs); 23529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 23539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 23549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 235526274fae33b7b056cf5fe9fd6e823cae9e4ddae2Wu-cheng Li } 235626274fae33b7b056cf5fe9fd6e823cae9e4ddae2Wu-cheng Li } 235726274fae33b7b056cf5fe9fd6e823cae9e4ddae2Wu-cheng Li 23589b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li // If they asked for any fileAs that need to be compiled, do so. 2359c157e0cd161e5b3b28b72bafebb3360ed856a608Wu-cheng Li if (bundle->getResourceSourceDirs().size() || bundle->getAndroidManifestFile()) { 2360c157e0cd161e5b3b28b72bafebb3360ed856a608Wu-cheng Li err = buildResources(bundle, assets, builder); 2361c157e0cd161e5b3b28b72bafebb3360ed856a608Wu-cheng Li if (err != 0) { 2362c157e0cd161e5b3b28b72bafebb3360ed856a608Wu-cheng Li goto bail; 2363c157e0cd161e5b3b28b72bafebb3360ed856a608Wu-cheng Li } 2364c157e0cd161e5b3b28b72bafebb3360ed856a608Wu-cheng Li } 2365c157e0cd161e5b3b28b72bafebb3360ed856a608Wu-cheng Li 2366c157e0cd161e5b3b28b72bafebb3360ed856a608Wu-cheng Li // At this point we've read everything and processed everything. From here 2367c157e0cd161e5b3b28b72bafebb3360ed856a608Wu-cheng Li // on out it's just writing output files. 2368c157e0cd161e5b3b28b72bafebb3360ed856a608Wu-cheng Li if (SourcePos::hasErrors()) { 2369c157e0cd161e5b3b28b72bafebb3360ed856a608Wu-cheng Li goto bail; 23709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2372c157e0cd161e5b3b28b72bafebb3360ed856a608Wu-cheng Li // Update symbols with information about which ones are needed as Java symbols. 2373c157e0cd161e5b3b28b72bafebb3360ed856a608Wu-cheng Li assets->applyJavaSymbols(); 2374c157e0cd161e5b3b28b72bafebb3360ed856a608Wu-cheng Li if (SourcePos::hasErrors()) { 2375c157e0cd161e5b3b28b72bafebb3360ed856a608Wu-cheng Li goto bail; 23769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If we've been asked to generate a dependency file, do that here 23799b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (bundle->getGenDependencies()) { 23809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If this is the packaging step, generate the dependency file next to 23819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the output apk (e.g. bin/resources.ap_.d) 23829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outputAPKFile) { 23839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dependencyFile = String8(outputAPKFile); 23849b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li // Add the .d extension to the dependency file. 2385dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong dependencyFile.append(".d"); 23869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 23879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Else if this is the R.java dependency generation step, 23889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // generate the dependency file in the R.java package subdirectory 23899b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li // e.g. gen/com/foo/app/R.java.d 23909b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li dependencyFile = String8(bundle->getRClassDir()); 23919b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li dependencyFile.appendPath("R.java.d"); 23929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23939b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li // Make sure we have a clean dependency file to start with 23949b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li fp = fopen(dependencyFile, "w"); 23959b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li fclose(fp); 23963f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li } 23979c79938d47a3caa06e5fb956955374f30c55992bWu-cheng Li 23989b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li // Write out R.java constants 23999b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (!assets->havePrivateSymbols()) { 24009b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (bundle->getCustomPackage() == NULL) { 24019b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li // Write the R.java file into the appropriate class directory 24029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // e.g. gen/com/foo/app/R.java 24039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = writeResourceSymbols(bundle, assets, assets->getPackage(), true); 24049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 240532a972c693400db50717435139fa292a63bc937aEino-Ville Talvala const String8 customPkg(bundle->getCustomPackage()); 240632a972c693400db50717435139fa292a63bc937aEino-Ville Talvala err = writeResourceSymbols(bundle, assets, customPkg, true); 2407dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong } 240832a972c693400db50717435139fa292a63bc937aEino-Ville Talvala if (err < 0) { 2409dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong goto bail; 2410dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong } 2411dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong // If we have library files, we're going to write our R.java file into 2412dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong // the appropriate class directory for those libraries as well. 241332a972c693400db50717435139fa292a63bc937aEino-Ville Talvala // e.g. gen/com/foo/app/lib/R.java 2414dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong if (bundle->getExtraPackages() != NULL) { 2415dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong // Split on colon 2416dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong String8 libs(bundle->getExtraPackages()); 2417dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong char* packageString = strtok(libs.lockBuffer(libs.length()), ":"); 2418dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong while (packageString != NULL) { 2419dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong // Write the R.java file out with the correct package name 2420dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong err = writeResourceSymbols(bundle, assets, String8(packageString), true); 2421dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong if (err < 0) { 2422dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong goto bail; 2423dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong } 2424dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong packageString = strtok(NULL, ":"); 2425dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong } 2426dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong libs.unlockBuffer(); 2427dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong } 2428dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong } else { 2429dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong err = writeResourceSymbols(bundle, assets, assets->getPackage(), false); 2430dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong if (err < 0) { 2431dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong goto bail; 2432dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong } 2433dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong err = writeResourceSymbols(bundle, assets, assets->getSymbolsPrivatePackage(), true); 2434dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong if (err < 0) { 2435dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong goto bail; 2436dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong } 2437dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong } 2438dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong 2439dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong // Write out the ProGuard file 2440dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong err = writeProguardFile(bundle, assets); 2441dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong if (err < 0) { 2442dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong goto bail; 2443dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong } 2444dd0b16c26834d9a58b9865a467c7a26ea14482f3James Dong 244532a972c693400db50717435139fa292a63bc937aEino-Ville Talvala // Write the apk 24464c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li if (outputAPKFile) { 244732a972c693400db50717435139fa292a63bc937aEino-Ville Talvala // Gather all resources and add them to the APK Builder. The builder will then 24489b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li // figure out which Split they belong in. 244932a972c693400db50717435139fa292a63bc937aEino-Ville Talvala err = addResourcesToBuilder(assets, builder); 245032a972c693400db50717435139fa292a63bc937aEino-Ville Talvala if (err != NO_ERROR) { 2451c157e0cd161e5b3b28b72bafebb3360ed856a608Wu-cheng Li goto bail; 24529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2454c157e0cd161e5b3b28b72bafebb3360ed856a608Wu-cheng Li const Vector<sp<ApkSplit> >& splits = builder->getSplits(); 24559b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li const size_t numSplits = splits.size(); 24569b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li for (size_t i = 0; i < numSplits; i++) { 24579b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li const sp<ApkSplit>& split = splits[i]; 24589b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li String8 outputPath = buildApkName(String8(outputAPKFile), split); 24599b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li err = writeAPK(bundle, outputPath, split); 24609b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (err != NO_ERROR) { 24619b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li fprintf(stderr, "ERROR: packaging of '%s' failed\n", outputPath.string()); 24629b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li goto bail; 24639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24649b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 24659b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 24669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24679b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li // If we've been asked to generate a dependency file, we need to finish up here. 24689b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li // the writeResourceSymbols and writeAPK functions have already written the target 24699b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li // half of the dependency file, now we need to write the prerequisites. (files that 24709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the R.java file or .ap_ file depend on) 24719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getGenDependencies()) { 24729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Now that writeResourceSymbols or writeAPK has taken care of writing 24734c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li // the targets to our dependency file, we'll write the prereqs 24744c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li fp = fopen(dependencyFile, "a+"); 24753f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li fprintf(fp, " : "); 24764c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li bool includeRaw = (outputAPKFile != NULL); 24774c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li err = writeDependencyPreReqs(bundle, assets, fp, includeRaw); 24784c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li // Also manually add the AndroidManifeset since it's not under res/ or assets/ 24794c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li // and therefore was not added to our pathstores during slurping 24804c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li fprintf(fp, "%s \\\n", bundle->getAndroidManifestFile()); 24814c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li fclose(fp); 24824c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li } 24834c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li 24844c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li retVal = 0; 24859b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Libail: 24869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SourcePos::hasErrors()) { 24879b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li SourcePos::printErrors(stderr); 24889b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 24899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return retVal; 24909b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li} 24919b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 24929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 24939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Do PNG Crunching 24949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * PRECONDITIONS 24959b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li * -S flag points to a source directory containing drawable* folders 24969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * -C flag points to destination directory. The folder structure in the 24979b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li * source directory will be mirrored to the destination (cache) directory 24989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 24999b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li * POSTCONDITIONS 25009b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li * Destination directory will be updated to match the PNG files in 25019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the source directory. 25029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 25039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint doCrunch(Bundle* bundle) 25049b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li{ 25059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stdout, "Crunching PNG Files in "); 25069b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li fprintf(stdout, "source dir: %s\n", bundle->getResourceSourceDirs()[0]); 25079b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li fprintf(stdout, "To destination dir: %s\n", bundle->getCrunchedOutputDir()); 25089b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 25099b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li updatePreProcessedCache(bundle); 25109b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 25119b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li return NO_ERROR; 25129b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li} 25139b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 25149b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li/* 25159b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li * Do PNG Crunching on a single flag 25169b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li * -i points to a single png file 25179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * -o points to a single png output file 25189b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li */ 25199b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Liint doSingleCrunch(Bundle* bundle) 25209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 25219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stdout, "Crunching single PNG file: %s\n", bundle->getSingleCrunchInputFile()); 25229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stdout, "\tOutput file: %s\n", bundle->getSingleCrunchOutputFile()); 2523a18e90176a8e2442837d0503fbfd4adb9df0818fWu-cheng Li 2524a18e90176a8e2442837d0503fbfd4adb9df0818fWu-cheng Li String8 input(bundle->getSingleCrunchInputFile()); 25259b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li String8 output(bundle->getSingleCrunchOutputFile()); 25269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25275f1e69c76ef5886ed65e303490c5f660da4756efWu-cheng Li if (preProcessImageToCache(bundle, input, output) != NO_ERROR) { 25289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we can't return the status_t as it gets truncate to the lower 8 bits. 25295f1e69c76ef5886ed65e303490c5f660da4756efWu-cheng Li return 42; 25309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25319b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 25329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 25339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 25349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2535a18e90176a8e2442837d0503fbfd4adb9df0818fWu-cheng Lichar CONSOLE_DATA[2925] = { 2536a18e90176a8e2442837d0503fbfd4adb9df0818fWu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2537a18e90176a8e2442837d0503fbfd4adb9df0818fWu-cheng Li 32, 32, 32, 32, 32, 32, 32, 95, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 25389b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 25399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 25405f1e69c76ef5886ed65e303490c5f660da4756efWu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 63, 25419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 86, 35, 40, 46, 46, 95, 95, 95, 95, 97, 97, 44, 32, 46, 124, 42, 33, 83, 25425f1e69c76ef5886ed65e303490c5f660da4756efWu-cheng Li 62, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 25439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 25449b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 46, 58, 59, 61, 59, 61, 81, 25459b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 81, 81, 81, 66, 96, 61, 61, 58, 46, 46, 46, 58, 32, 32, 32, 32, 32, 32, 25469b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 25479b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 25489b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 32, 32, 32, 46, 61, 59, 59, 59, 58, 106, 81, 81, 81, 81, 102, 59, 61, 59, 25499b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 59, 61, 61, 61, 58, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 25503f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 25513f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 25525f1e69c76ef5886ed65e303490c5f660da4756efWu-cheng Li 59, 58, 109, 81, 81, 81, 81, 61, 59, 59, 59, 59, 59, 58, 59, 59, 46, 32, 25539b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 25545f1e69c76ef5886ed65e303490c5f660da4756efWu-cheng Li 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 25559b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 60, 81, 81, 81, 81, 87, 25569b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 58, 59, 59, 59, 59, 59, 59, 61, 119, 44, 32, 32, 32, 32, 32, 32, 32, 32, 25579b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 25589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 25599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 47, 61, 59, 59, 58, 100, 81, 81, 81, 81, 35, 58, 59, 59, 59, 59, 59, 58, 25609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 121, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 25614a68e3c26dd2512c319071dc20074baa6e7d171fHai Guo 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 25621620d118a49dc6df7b0e83d7343f8a8bb6e23b12Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 109, 58, 59, 59, 61, 81, 81, 2563454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 81, 81, 81, 109, 58, 59, 59, 59, 59, 61, 109, 81, 81, 76, 46, 32, 32, 32, 2564454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 2565454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2566454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 32, 32, 32, 41, 87, 59, 61, 59, 41, 81, 81, 81, 81, 81, 81, 59, 61, 59, 2567454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 59, 58, 109, 81, 81, 87, 39, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2568454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2569454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 60, 81, 91, 59, 2570454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 59, 61, 81, 81, 81, 81, 81, 87, 43, 59, 58, 59, 60, 81, 81, 81, 76, 32, 2571454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2572454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2573454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 52, 91, 58, 45, 59, 87, 81, 81, 81, 81, 2574454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 70, 58, 58, 58, 59, 106, 81, 81, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32, 2575454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 2576454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2577454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 32, 93, 40, 32, 46, 59, 100, 81, 81, 81, 81, 40, 58, 46, 46, 58, 100, 81, 2578454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 81, 68, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2579454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2580454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 32, 46, 46, 46, 32, 46, 46, 46, 32, 46, 32, 46, 45, 91, 59, 61, 58, 109, 2581454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 81, 81, 81, 87, 46, 58, 61, 59, 60, 81, 81, 80, 32, 32, 32, 32, 32, 32, 2582454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 2583454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 46, 46, 61, 59, 61, 61, 61, 59, 61, 61, 59, 2584454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 59, 59, 58, 58, 46, 46, 41, 58, 59, 58, 81, 81, 81, 81, 69, 58, 59, 59, 2585454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 60, 81, 81, 68, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2586454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 58, 59, 2587454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 61, 46, 25885f1e69c76ef5886ed65e303490c5f660da4756efWu-cheng Li 61, 59, 93, 81, 81, 81, 81, 107, 58, 59, 58, 109, 87, 68, 96, 32, 32, 32, 2589454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2590454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 32, 32, 10, 32, 32, 32, 46, 60, 61, 61, 59, 59, 59, 59, 59, 59, 59, 59, 2591454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 59, 59, 59, 59, 59, 59, 59, 59, 59, 58, 58, 58, 115, 109, 68, 41, 36, 81, 2592454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 109, 46, 61, 61, 81, 69, 96, 46, 58, 58, 46, 58, 46, 46, 32, 32, 32, 32, 2593454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 46, 32, 95, 81, 2594454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 67, 61, 61, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 2595454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 59, 59, 59, 59, 58, 68, 39, 61, 105, 61, 63, 81, 119, 58, 106, 80, 32, 58, 2596454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 61, 59, 59, 61, 59, 61, 59, 61, 46, 95, 32, 32, 32, 32, 32, 32, 32, 32, 2597454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 32, 32, 32, 32, 32, 32, 10, 32, 32, 36, 81, 109, 105, 59, 61, 59, 59, 59, 2598454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 46, 58, 37, 2599454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 73, 108, 108, 62, 52, 81, 109, 34, 32, 61, 59, 59, 59, 59, 59, 59, 59, 59, 2600454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 59, 61, 59, 61, 61, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 2601454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 32, 46, 45, 57, 101, 43, 43, 61, 61, 59, 59, 59, 59, 59, 59, 61, 59, 59, 2602454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 59, 59, 59, 59, 59, 59, 59, 58, 97, 46, 61, 108, 62, 126, 58, 106, 80, 96, 2603454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 46, 61, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 61, 2604454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 97, 103, 97, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 45, 46, 32, 2605454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 46, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45, 58, 59, 59, 59, 59, 61, 2606454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 119, 81, 97, 124, 105, 124, 124, 39, 126, 95, 119, 58, 61, 58, 59, 59, 59, 2607454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 119, 81, 81, 99, 32, 32, 2608454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2609454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 58, 106, 81, 81, 81, 109, 119, 2610454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 119, 119, 109, 109, 81, 81, 122, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 2611454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 59, 59, 59, 59, 59, 58, 115, 81, 87, 81, 102, 32, 32, 32, 32, 32, 32, 10, 2612454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2613454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 32, 32, 61, 58, 59, 61, 81, 81, 81, 81, 81, 81, 87, 87, 81, 81, 81, 81, 2614454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 81, 58, 59, 59, 59, 59, 59, 59, 59, 59, 58, 45, 45, 45, 59, 59, 59, 41, 2615454630f23784afcf3dd6fc58becbb9fb6aa878a9Wu-cheng Li 87, 66, 33, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 26167478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 93, 81, 2617da0a56df963353a1f1bd1914fa31f870d982dd5aScott Main 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 2618a696f5d667227365da732481770767dcb330dd23Mathias Agopian 45, 32, 46, 32, 32, 32, 32, 32, 46, 32, 126, 96, 32, 32, 32, 32, 32, 32, 2619df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 26207478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li 32, 32, 32, 32, 32, 32, 58, 61, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81, 2621951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 2622951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 2623951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 2624951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 59, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58, 2625951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 59, 59, 59, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2626951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2627951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 60, 81, 81, 81, 81, 2628951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 81, 81, 81, 81, 81, 81, 81, 81, 81, 59, 61, 59, 59, 61, 32, 32, 32, 32, 2629951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2630951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2631951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 32, 32, 32, 58, 59, 59, 93, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 2632951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 81, 81, 40, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2633951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 2634951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 106, 2635951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 76, 58, 59, 59, 59, 2636951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2637951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2638951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 32, 32, 32, 32, 32, 32, 32, 61, 58, 58, 81, 81, 81, 81, 81, 81, 81, 81, 2639951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 81, 81, 81, 81, 81, 87, 58, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 2640951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 2641951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2642951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 58, 59, 61, 41, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 87, 59, 2643951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 61, 58, 59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2644951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2645951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 61, 81, 81, 81, 2646951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 81, 81, 81, 81, 81, 81, 81, 81, 81, 107, 58, 59, 59, 59, 59, 58, 32, 32, 2647951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2648951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2649951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 32, 32, 32, 32, 58, 59, 59, 58, 51, 81, 81, 81, 81, 81, 81, 81, 81, 81, 2650951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 81, 102, 94, 59, 59, 59, 59, 59, 61, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2651951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 2652951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 2653951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 59, 59, 43, 63, 36, 81, 81, 81, 87, 64, 86, 102, 58, 59, 59, 59, 59, 59, 2654951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2655951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2656951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 59, 59, 43, 33, 2657a696f5d667227365da732481770767dcb330dd23Mathias Agopian 58, 126, 126, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32, 32, 2658951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 26599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 26609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 61, 59, 59, 59, 58, 45, 58, 61, 59, 58, 58, 58, 61, 59, 59, 59, 59, 59, 26619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 59, 59, 59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 26629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 26639b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 58, 95, 26649b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 32, 45, 61, 59, 61, 59, 59, 59, 59, 59, 59, 59, 45, 58, 59, 59, 59, 59, 26659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 61, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 26669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 26679b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 32, 32, 58, 61, 59, 59, 59, 59, 59, 61, 59, 61, 46, 46, 32, 45, 45, 45, 26689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 59, 58, 45, 45, 46, 58, 59, 59, 59, 59, 59, 59, 61, 46, 32, 32, 32, 32, 26699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 26709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 58, 59, 59, 59, 59, 26713f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li 59, 59, 59, 59, 59, 61, 59, 46, 32, 32, 46, 32, 46, 32, 58, 61, 59, 59, 26729b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 59, 59, 59, 59, 59, 59, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 26737478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 26743f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 45, 59, 59, 59, 59, 59, 59, 59, 59, 58, 32, 26753f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 58, 32, 2676951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 26779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 26789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 46, 61, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 61, 26799b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 46, 61, 59, 59, 59, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 26809b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 26819b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 26829b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 46, 61, 58, 59, 59, 59, 59, 2683f9293e7d5057f54ec90423f55b78138d5729e30fWu-cheng Li 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2684f9293e7d5057f54ec90423f55b78138d5729e30fWu-cheng Li 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2685f9293e7d5057f54ec90423f55b78138d5729e30fWu-cheng Li 32, 32, 32, 32, 58, 59, 59, 59, 59, 59, 59, 59, 59, 46, 46, 32, 32, 32, 26869b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 45, 32, 32, 32, 32, 32, 26873f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 26883f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 32, 45, 61, 26893f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li 59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 2690951516358e2841d2425f610bcd0175d9960135d2Eino-Ville Talvala 59, 59, 59, 58, 45, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 26919b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 26929b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45, 45, 32, 46, 32, 26939b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 61, 59, 58, 45, 45, 32, 32, 32, 2694eb68c46a40c773eb56ef7bcf8e7ece5c6a5a8d23Chih-Chung Chang 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2695eb68c46a40c773eb56ef7bcf8e7ece5c6a5a8d23Chih-Chung Chang 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2696eb68c46a40c773eb56ef7bcf8e7ece5c6a5a8d23Chih-Chung Chang 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2697a696f5d667227365da732481770767dcb330dd23Mathias Agopian 32, 32, 46, 32, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2698eb68c46a40c773eb56ef7bcf8e7ece5c6a5a8d23Chih-Chung Chang 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10 2699eb68c46a40c773eb56ef7bcf8e7ece5c6a5a8d23Chih-Chung Chang }; 2700eb68c46a40c773eb56ef7bcf8e7ece5c6a5a8d23Chih-Chung Chang