Command.cpp revision 6c997a9e880e08c354ffd809bd62df9e25e9c4d4
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 "Main.h" 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "Bundle.h" 8e6b680364dd992907a8d2037685a2e500d188dfbDianne Hackborn#include "ResourceFilter.h" 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "ResourceTable.h" 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "XMLNode.h" 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 123b4062eeb01be33951ba214e027da523cf09f8b1Mathias Agopian#include <utils/Log.h> 133b4062eeb01be33951ba214e027da523cf09f8b1Mathias Agopian#include <utils/threads.h> 143b4062eeb01be33951ba214e027da523cf09f8b1Mathias Agopian#include <utils/List.h> 153b4062eeb01be33951ba214e027da523cf09f8b1Mathias Agopian#include <utils/Errors.h> 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <fcntl.h> 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <errno.h> 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectusing namespace android; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Show version info. All the cool kids do it. 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint doVersion(Bundle* bundle) 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getFileSpecCount() != 0) 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("(ignoring extra arguments)\n"); 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("Android Asset Packaging Tool, v0.2\n"); 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open the file read only. The call fails if the file doesn't exist. 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns NULL on failure. 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectZipFile* openReadOnly(const char* fileName) 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipFile* zip; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t result; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zip = new ZipFile; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = zip->open(fileName, ZipFile::kOpenReadOnly); 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result != NO_ERROR) { 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result == NAME_NOT_FOUND) 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: '%s' not found\n", fileName); 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (result == PERMISSION_DENIED) 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: '%s' access denied\n", fileName); 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: failed opening '%s' as Zip file\n", 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fileName); 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete zip; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return zip; 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open the file read-write. The file will be created if it doesn't 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * already exist and "okayToCreate" is set. 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns NULL on failure. 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectZipFile* openReadWrite(const char* fileName, bool okayToCreate) 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipFile* zip = NULL; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t result; 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int flags; 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags = ZipFile::kOpenReadWrite; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (okayToCreate) 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags |= ZipFile::kOpenCreate; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zip = new ZipFile; 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = zip->open(fileName, flags); 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result != NO_ERROR) { 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete zip; 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zip = NULL; 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbail: 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return zip; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return a short string describing the compression method. 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst char* compressionName(int method) 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (method == ZipEntry::kCompressStored) 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "Stored"; 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (method == ZipEntry::kCompressDeflated) 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "Deflated"; 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "Unknown"; 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the percent reduction in size (0% == no compression). 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint calcPercent(long uncompressedLen, long compressedLen) 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!uncompressedLen) 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (int) (100.0 - (compressedLen * 100.0) / uncompressedLen + 0.5); 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Handle the "list" command, which can be a simple file dump or 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a verbose listing. 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The verbose listing closely matches the output of the Info-ZIP "unzip" 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * command. 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint doList(Bundle* bundle) 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int result = 1; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipFile* zip = NULL; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ZipEntry* entry; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long totalUncLen, totalCompLen; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* zipFileName; 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getFileSpecCount() != 1) { 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: specify zip file name (only)\n"); 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zipFileName = bundle->getFileSpecEntry(0); 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zip = openReadOnly(zipFileName); 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (zip == NULL) 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int count, i; 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getVerbose()) { 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("Archive: %s\n", zipFileName); 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf( 145fb2a9467ad77336edbf2a1a272dbe6ec30ef8a1bKenny Root " Length Method Size Ratio Offset Date Time CRC-32 Name\n"); 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf( 147fb2a9467ad77336edbf2a1a272dbe6ec30ef8a1bKenny Root "-------- ------ ------- ----- ------- ---- ---- ------ ----\n"); 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project totalUncLen = totalCompLen = 0; 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project count = zip->getNumEntries(); 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i = 0; i < count; i++) { 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project entry = zip->getEntryByIndex(i); 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getVerbose()) { 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char dateBuf[32]; 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project time_t when; 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project when = entry->getModWhen(); 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project strftime(dateBuf, sizeof(dateBuf), "%m-%d-%y %H:%M", 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project localtime(&when)); 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 163fb2a9467ad77336edbf2a1a272dbe6ec30ef8a1bKenny Root printf("%8ld %-7.7s %7ld %3d%% %8zd %s %08lx %s\n", 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (long) entry->getUncompressedLen(), 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project compressionName(entry->getCompressionMethod()), 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (long) entry->getCompressedLen(), 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calcPercent(entry->getUncompressedLen(), 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project entry->getCompressedLen()), 169fb2a9467ad77336edbf2a1a272dbe6ec30ef8a1bKenny Root (size_t) entry->getLFHOffset(), 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dateBuf, 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project entry->getCRC32(), 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project entry->getFileName()); 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("%s\n", entry->getFileName()); 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project totalUncLen += entry->getUncompressedLen(); 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project totalCompLen += entry->getCompressedLen(); 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getVerbose()) { 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf( 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "-------- ------- --- -------\n"); 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("%8ld %7ld %2d%% %d files\n", 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project totalUncLen, 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project totalCompLen, 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calcPercent(totalUncLen, totalCompLen), 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zip->getNumEntries()); 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getAndroidList()) { 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetManager assets; 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!assets.addAssetPath(String8(zipFileName), NULL)) { 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: list -a failed because assets could not be loaded\n"); 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1977ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable& res = assets.getResources(false); 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (&res == NULL) { 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("\nNo resource table found.\n"); 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 202f1ff21ac62a51f5ba8ca0821ea8a90f70957e25dSteve Block#ifndef HAVE_ANDROID_OS 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("\nResource table:\n"); 204e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn res.print(false); 205f1ff21ac62a51f5ba8ca0821ea8a90f70957e25dSteve Block#endif 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2077ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Asset* manifestAsset = assets.openNonAsset("AndroidManifest.xml", 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Asset::ACCESS_BUFFER); 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (manifestAsset == NULL) { 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("\nNo AndroidManifest.xml found.\n"); 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("\nAndroid manifest:\n"); 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResXMLTree tree; 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tree.setTo(manifestAsset->getBuffer(true), 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project manifestAsset->getLength()); 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printXMLBlock(&tree); 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete manifestAsset; 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2217ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = 0; 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbail: 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete zip; 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic ssize_t indexOfAttribute(const ResXMLTree& tree, uint32_t attrRes) 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t N = tree.getAttributeCount(); 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<N; i++) { 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tree.getAttributeNameResID(i) == attrRes) { 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (ssize_t)i; 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2401553c82e084ac5763fb393857224145506771b99Joe OnoratoString8 getAttribute(const ResXMLTree& tree, const char* ns, 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* attr, String8* outError) 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t idx = tree.indexOfAttribute(ns, attr); 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx < 0) { 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return String8(); 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Res_value value; 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value.dataType != Res_value::TYPE_STRING) { 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outError != NULL) *outError = "attribute is not a string value"; 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return String8(); 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t len; 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t* str = tree.getAttributeStringValue(idx, &len); 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return str ? String8(str, len) : String8(); 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic String8 getAttribute(const ResXMLTree& tree, uint32_t attrRes, String8* outError) 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t idx = indexOfAttribute(tree, attrRes); 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx < 0) { 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return String8(); 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Res_value value; 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value.dataType != Res_value::TYPE_STRING) { 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outError != NULL) *outError = "attribute is not a string value"; 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return String8(); 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t len; 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t* str = tree.getAttributeStringValue(idx, &len); 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return str ? String8(str, len) : String8(); 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 277bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackbornstatic int32_t getIntegerAttribute(const ResXMLTree& tree, uint32_t attrRes, 278bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn String8* outError, int32_t defValue = -1) 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t idx = indexOfAttribute(tree, attrRes); 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx < 0) { 282bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn return defValue; 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Res_value value; 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 286bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (value.dataType < Res_value::TYPE_FIRST_INT 287bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn || value.dataType > Res_value::TYPE_LAST_INT) { 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outError != NULL) *outError = "attribute is not an integer value"; 289bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn return defValue; 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return value.data; 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 295f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackbornstatic int32_t getResolvedIntegerAttribute(const ResTable* resTable, const ResXMLTree& tree, 296f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn uint32_t attrRes, String8* outError, int32_t defValue = -1) 297f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn{ 298f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn ssize_t idx = indexOfAttribute(tree, attrRes); 299f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn if (idx < 0) { 300f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn return defValue; 301f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn } 302f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn Res_value value; 303f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 304f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn if (value.dataType == Res_value::TYPE_REFERENCE) { 305f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn resTable->resolveReference(&value, 0); 306f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn } 307f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn if (value.dataType < Res_value::TYPE_FIRST_INT 308f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn || value.dataType > Res_value::TYPE_LAST_INT) { 309f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn if (outError != NULL) *outError = "attribute is not an integer value"; 310f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn return defValue; 311f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn } 312f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn } 313f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn return value.data; 314f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn} 315f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic String8 getResolvedAttribute(const ResTable* resTable, const ResXMLTree& tree, 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t attrRes, String8* outError) 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t idx = indexOfAttribute(tree, attrRes); 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx < 0) { 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return String8(); 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Res_value value; 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value.dataType == Res_value::TYPE_STRING) { 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t len; 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t* str = tree.getAttributeStringValue(idx, &len); 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return str ? String8(str, len) : String8(); 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resTable->resolveReference(&value, 0); 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value.dataType != Res_value::TYPE_STRING) { 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outError != NULL) *outError = "attribute is not a string value"; 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return String8(); 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t len; 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Res_value* value2 = &value; 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* str = const_cast<ResTable*>(resTable)->valueToString(value2, 0, NULL, &len); 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return str ? String8(str, len) : String8(); 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// These are attribute resource constants for the platform, as found 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// in android.R.attr 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectenum { 345f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn LABEL_ATTR = 0x01010001, 346f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn ICON_ATTR = 0x01010002, 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NAME_ATTR = 0x01010003, 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project VERSION_CODE_ATTR = 0x0101021b, 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project VERSION_NAME_ATTR = 0x0101021c, 350f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn SCREEN_ORIENTATION_ATTR = 0x0101001e, 351bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn MIN_SDK_VERSION_ATTR = 0x0101020c, 35275c498426a17b47d445711bb9e36794b05876a56Suchi Amalapurapu MAX_SDK_VERSION_ATTR = 0x01010271, 353bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn REQ_TOUCH_SCREEN_ATTR = 0x01010227, 354bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn REQ_KEYBOARD_TYPE_ATTR = 0x01010228, 355bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn REQ_HARD_KEYBOARD_ATTR = 0x01010229, 356bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn REQ_NAVIGATION_ATTR = 0x0101022a, 357bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn REQ_FIVE_WAY_NAV_ATTR = 0x01010232, 358bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn TARGET_SDK_VERSION_ATTR = 0x01010270, 359bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn TEST_ONLY_ATTR = 0x01010272, 360a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn ANY_DENSITY_ATTR = 0x0101026c, 361e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn GL_ES_VERSION_ATTR = 0x01010281, 362723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn SMALL_SCREEN_ATTR = 0x01010284, 363723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn NORMAL_SCREEN_ATTR = 0x01010285, 364723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn LARGE_SCREEN_ATTR = 0x01010286, 365f43489d7d5e1c0c5c9a7e54c22845fcb99765f81Dianne Hackborn XLARGE_SCREEN_ATTR = 0x010102bf, 366e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn REQUIRED_ATTR = 0x0101028e, 367a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn SCREEN_SIZE_ATTR = 0x010102ca, 368a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn SCREEN_DENSITY_ATTR = 0x010102cb, 369e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn REQUIRES_SMALLEST_WIDTH_DP_ATTR = 0x01010364, 370e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn COMPATIBLE_WIDTH_LIMIT_DP_ATTR = 0x01010365, 371e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn LARGEST_WIDTH_LIMIT_DP_ATTR = 0x01010366, 37256088a55ca6c9277f09040a7883117cb127e1e56Kenny Root PUBLIC_KEY_ATTR = 0x010103a6, 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3757ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapuconst char *getComponentName(String8 &pkgName, String8 &componentName) { 3767ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu ssize_t idx = componentName.find("."); 3777ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu String8 retStr(pkgName); 3787ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu if (idx == 0) { 3797ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu retStr += componentName; 3807ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } else if (idx < 0) { 3817ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu retStr += "."; 3827ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu retStr += componentName; 3837ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } else { 3847ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu return componentName.string(); 3857ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } 3867ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu return retStr.string(); 3877ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu} 3887ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 389a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackbornstatic void printCompatibleScreens(ResXMLTree& tree) { 390a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn size_t len; 391a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn ResXMLTree::event_code_t code; 392a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn int depth = 0; 393a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn bool first = true; 394a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn printf("compatible-screens:"); 395a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 396a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn if (code == ResXMLTree::END_TAG) { 397a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn depth--; 398a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn if (depth < 0) { 399a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn break; 400a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn } 401a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn continue; 402a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn } 403a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn if (code != ResXMLTree::START_TAG) { 404a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn continue; 405a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn } 406a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn depth++; 407a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn String8 tag(tree.getElementName(&len)); 408a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn if (tag == "screen") { 409a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn int32_t screenSize = getIntegerAttribute(tree, 410a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn SCREEN_SIZE_ATTR, NULL, -1); 411a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn int32_t screenDensity = getIntegerAttribute(tree, 412a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn SCREEN_DENSITY_ATTR, NULL, -1); 413a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn if (screenSize > 0 && screenDensity > 0) { 414a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn if (!first) { 415a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn printf(","); 416a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn } 417a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn first = false; 418a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn printf("'%d/%d'", screenSize, screenDensity); 419a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn } 420a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn } 421a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn } 422a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn printf("\n"); 423a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn} 424a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Handle the "dump" command, to extract select data from an archive. 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 428e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrillextern char CONSOLE_DATA[2925]; // see EOF 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint doDump(Bundle* bundle) 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t result = UNKNOWN_ERROR; 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Asset* asset = NULL; 4337ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getFileSpecCount() < 1) { 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: no dump option specified\n"); 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 1; 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4387ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getFileSpecCount() < 2) { 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: no dump file specified\n"); 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 1; 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4437ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* option = bundle->getFileSpecEntry(0); 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* filename = bundle->getFileSpecEntry(1); 4467ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetManager assets; 448bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn void* assetsCookie; 449bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (!assets.addAssetPath(String8(filename), &assetsCookie)) { 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: dump failed because assets could not be loaded\n"); 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 1; 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4537ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 454e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn // Make a dummy config for retrieving resources... we need to supply 455e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn // non-default values for some configs so that we can retrieve resources 456e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn // in the app that don't have a default. The most important of these is 457e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn // the API version because key resources like icons will have an implicit 458e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn // version if they are using newer config types like density. 459e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn ResTable_config config; 460e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn config.language[0] = 'e'; 461e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn config.language[1] = 'n'; 462e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn config.country[0] = 'U'; 463e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn config.country[1] = 'S'; 464e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn config.orientation = ResTable_config::ORIENTATION_PORT; 465e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn config.density = ResTable_config::DENSITY_MEDIUM; 466e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn config.sdkVersion = 10000; // Very high. 467e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn config.screenWidthDp = 320; 468e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn config.screenHeightDp = 480; 469e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn config.smallestScreenWidthDp = 320; 470e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn assets.setConfiguration(config); 471e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable& res = assets.getResources(false); 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (&res == NULL) { 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: dump failed because no resource table was found\n"); 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4777ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (strcmp("resources", option) == 0) { 479f1ff21ac62a51f5ba8ca0821ea8a90f70957e25dSteve Block#ifndef HAVE_ANDROID_OS 480e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn res.print(bundle->getValues()); 481f1ff21ac62a51f5ba8ca0821ea8a90f70957e25dSteve Block#endif 4826c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 4836c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } else if (strcmp("strings", option) == 0) { 4846c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const ResStringPool* pool = res.getTableStringBlock(0); 4856c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn printStringPool(pool); 4866c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (strcmp("xmltree", option) == 0) { 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getFileSpecCount() < 3) { 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: no dump xmltree resource file specified\n"); 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4927ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=2; i<bundle->getFileSpecCount(); i++) { 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* resname = bundle->getFileSpecEntry(i); 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResXMLTree tree; 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project asset = assets.openNonAsset(resname, Asset::ACCESS_BUFFER); 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (asset == NULL) { 49844b283dc27ed8ba5a946d809489f29b4ae88cb15Kenny Root fprintf(stderr, "ERROR: dump failed because resource %s found\n", resname); 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5017ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tree.setTo(asset->getBuffer(true), 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project asset->getLength()) != NO_ERROR) { 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: Resource %s is corrupt\n", resname); 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tree.restart(); 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printXMLBlock(&tree); 50919138468caf7050d482dc15f35a344eab11bb756Kenny Root tree.uninit(); 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete asset; 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project asset = NULL; 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5137ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (strcmp("xmlstrings", option) == 0) { 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getFileSpecCount() < 3) { 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: no dump xmltree resource file specified\n"); 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5197ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=2; i<bundle->getFileSpecCount(); i++) { 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* resname = bundle->getFileSpecEntry(i); 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResXMLTree tree; 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project asset = assets.openNonAsset(resname, Asset::ACCESS_BUFFER); 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (asset == NULL) { 52544b283dc27ed8ba5a946d809489f29b4ae88cb15Kenny Root fprintf(stderr, "ERROR: dump failed because resource %s found\n", resname); 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5287ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tree.setTo(asset->getBuffer(true), 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project asset->getLength()) != NO_ERROR) { 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: Resource %s is corrupt\n", resname); 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printStringPool(&tree.getStrings()); 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete asset; 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project asset = NULL; 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5387ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResXMLTree tree; 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project asset = assets.openNonAsset("AndroidManifest.xml", 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Asset::ACCESS_BUFFER); 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (asset == NULL) { 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: dump failed because no AndroidManifest.xml found\n"); 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5477ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tree.setTo(asset->getBuffer(true), 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project asset->getLength()) != NO_ERROR) { 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: AndroidManifest.xml is corrupt\n"); 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tree.restart(); 5547ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (strcmp("permissions", option) == 0) { 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t len; 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResXMLTree::event_code_t code; 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int depth = 0; 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (code == ResXMLTree::END_TAG) { 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project depth--; 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (code != ResXMLTree::START_TAG) { 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project depth++; 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 tag(tree.getElementName(&len)); 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Depth %d tag %s\n", depth, tag.string()); 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (depth == 1) { 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tag != "manifest") { 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: manifest does not start with <manifest> tag\n"); 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 pkg = getAttribute(tree, NULL, "package", NULL); 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("package: %s\n", pkg.string()); 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (depth == 2 && tag == "permission") { 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 error; 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 name = getAttribute(tree, NAME_ATTR, &error); 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (error != "") { 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: %s\n", error.string()); 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("permission: %s\n", name.string()); 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (depth == 2 && tag == "uses-permission") { 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 error; 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 name = getAttribute(tree, NAME_ATTR, &error); 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (error != "") { 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: %s\n", error.string()); 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("uses-permission: %s\n", name.string()); 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (strcmp("badging", option) == 0) { 596e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn Vector<String8> locales; 597e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn res.getLocales(&locales); 598e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn 599e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn Vector<ResTable_config> configs; 600e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn res.getConfigurations(&configs); 601e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn SortedVector<int> densities; 602e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn const size_t NC = configs.size(); 603e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn for (size_t i=0; i<NC; i++) { 604e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn int dens = configs[i].density; 605e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn if (dens == 0) dens = 160; 606e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn densities.add(dens); 607e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 608e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t len; 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResXMLTree::event_code_t code; 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int depth = 0; 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 error; 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool withinActivity = false; 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool isMainActivity = false; 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool isLauncherActivity = false; 6161b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool isSearchable = false; 6177ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu bool withinApplication = false; 6187ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu bool withinReceiver = false; 6191b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool withinService = false; 6201b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool withinIntentFilter = false; 6211b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool hasMainActivity = false; 6221b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool hasOtherActivities = false; 6231b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool hasOtherReceivers = false; 6241b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool hasOtherServices = false; 6251b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool hasWallpaperService = false; 6261b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool hasImeService = false; 6271b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool hasWidgetReceivers = false; 6281b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool hasIntentFilter = false; 6291b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool actMainActivity = false; 6301b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool actWidgetReceivers = false; 6311b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool actImeService = false; 6321b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool actWallpaperService = false; 63389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill 634063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root // These two implement the implicit permissions that are granted 635063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root // to pre-1.6 applications. 636063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root bool hasWriteExternalStoragePermission = false; 637063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root bool hasReadPhoneStatePermission = false; 638063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root 63989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // This next group of variables is used to implement a group of 64089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // backward-compatibility heuristics necessitated by the addition of 64189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // some new uses-feature constants in 2.1 and 2.2. In most cases, the 64289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // heuristic is "if an app requests a permission but doesn't explicitly 64389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // request the corresponding <uses-feature>, presume it's there anyway". 64489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool specCameraFeature = false; // camera-related 64589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool specCameraAutofocusFeature = false; 64689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool reqCameraAutofocusFeature = false; 64789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool reqCameraFlashFeature = false; 648e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn bool hasCameraPermission = false; 64989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool specLocationFeature = false; // location-related 65089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool specNetworkLocFeature = false; 65189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool reqNetworkLocFeature = false; 652ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn bool specGpsFeature = false; 65389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool reqGpsFeature = false; 65489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool hasMockLocPermission = false; 65589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool hasCoarseLocPermission = false; 656ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn bool hasGpsPermission = false; 65789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool hasGeneralLocPermission = false; 65889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool specBluetoothFeature = false; // Bluetooth API-related 65989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool hasBluetoothPermission = false; 66089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool specMicrophoneFeature = false; // microphone-related 66189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool hasRecordAudioPermission = false; 66289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool specWiFiFeature = false; 66389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool hasWiFiPermission = false; 66489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool specTelephonyFeature = false; // telephony-related 66589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool reqTelephonySubFeature = false; 66689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool hasTelephonyPermission = false; 66789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool specTouchscreenFeature = false; // touchscreen-related 66889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool specMultitouchFeature = false; 66989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool reqDistinctMultitouchFeature = false; 670e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn bool specScreenPortraitFeature = false; 671e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn bool specScreenLandscapeFeature = false; 672f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn bool reqScreenPortraitFeature = false; 673f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn bool reqScreenLandscapeFeature = false; 67489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // 2.2 also added some other features that apps can request, but that 67589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // have no corresponding permission, so we cannot implement any 67689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // back-compatibility heuristic for them. The below are thus unnecessary 67789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // (but are retained here for documentary purposes.) 67889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill //bool specCompassFeature = false; 67989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill //bool specAccelerometerFeature = false; 68089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill //bool specProximityFeature = false; 68189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill //bool specAmbientLightFeature = false; 68289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill //bool specLiveWallpaperFeature = false; 68389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill 684723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn int targetSdk = 0; 685723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn int smallScreen = 1; 686723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn int normalScreen = 1; 687723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn int largeScreen = 1; 688f43489d7d5e1c0c5c9a7e54c22845fcb99765f81Dianne Hackborn int xlargeScreen = 1; 689a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn int anyDensity = 1; 690e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn int requiresSmallestWidthDp = 0; 691e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn int compatibleWidthLimitDp = 0; 692e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn int largestWidthLimitDp = 0; 6937ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu String8 pkg; 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 activityName; 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 activityLabel; 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 activityIcon; 6977ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu String8 receiverName; 6981b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu String8 serviceName; 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (code == ResXMLTree::END_TAG) { 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project depth--; 7021b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (depth < 2) { 7031b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu withinApplication = false; 7041b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } else if (depth < 3) { 7051b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (withinActivity && isMainActivity && isLauncherActivity) { 7061b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu const char *aName = getComponentName(pkg, activityName); 707e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn printf("launchable-activity:"); 7081b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (aName != NULL) { 709e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn printf(" name='%s' ", aName); 7101b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 711e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn printf(" label='%s' icon='%s'\n", 7121b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu activityLabel.string(), 7131b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu activityIcon.string()); 7141b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 7151b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (!hasIntentFilter) { 7161b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu hasOtherActivities |= withinActivity; 7171b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu hasOtherReceivers |= withinReceiver; 7181b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu hasOtherServices |= withinService; 7191b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 7201b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu withinActivity = false; 7211b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu withinService = false; 7221b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu withinReceiver = false; 7231b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu hasIntentFilter = false; 7241b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu isMainActivity = isLauncherActivity = false; 7251b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } else if (depth < 4) { 7261b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (withinIntentFilter) { 7271b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (withinActivity) { 7281b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu hasMainActivity |= actMainActivity; 7291b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu hasOtherActivities |= !actMainActivity; 7301b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } else if (withinReceiver) { 7311b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu hasWidgetReceivers |= actWidgetReceivers; 7321b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu hasOtherReceivers |= !actWidgetReceivers; 7331b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } else if (withinService) { 7341b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu hasImeService |= actImeService; 7351b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu hasWallpaperService |= actWallpaperService; 7361b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu hasOtherServices |= (!actImeService && !actWallpaperService); 7371b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 7381b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 7391b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu withinIntentFilter = false; 7401b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (code != ResXMLTree::START_TAG) { 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project depth++; 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 tag(tree.getElementName(&len)); 7481b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu //printf("Depth %d, %s\n", depth, tag.string()); 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (depth == 1) { 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tag != "manifest") { 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: manifest does not start with <manifest> tag\n"); 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7547ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu pkg = getAttribute(tree, NULL, "package", NULL); 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("package: name='%s' ", pkg.string()); 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t versionCode = getIntegerAttribute(tree, VERSION_CODE_ATTR, &error); 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (error != "") { 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR getting 'android:versionCode' attribute: %s\n", error.string()); 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (versionCode > 0) { 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("versionCode='%d' ", versionCode); 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("versionCode='' "); 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 766cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn String8 versionName = getResolvedAttribute(&res, tree, VERSION_NAME_ATTR, &error); 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (error != "") { 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR getting 'android:versionName' attribute: %s\n", error.string()); 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("versionName='%s'\n", versionName.string()); 7727ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } else if (depth == 2) { 7737ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu withinApplication = false; 7747ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu if (tag == "application") { 7757ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu withinApplication = true; 776e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn 777e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn String8 label; 778e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn const size_t NL = locales.size(); 779e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn for (size_t i=0; i<NL; i++) { 780e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn const char* localeStr = locales[i].string(); 781e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn assets.setLocale(localeStr != NULL ? localeStr : ""); 782e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn String8 llabel = getResolvedAttribute(&res, tree, LABEL_ATTR, &error); 783e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn if (llabel != "") { 784e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn if (localeStr == NULL || strlen(localeStr) == 0) { 785e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn label = llabel; 786e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn printf("application-label:'%s'\n", llabel.string()); 787e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } else { 788e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn if (label == "") { 789e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn label = llabel; 790e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 791e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn printf("application-label-%s:'%s'\n", localeStr, 792e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn llabel.string()); 793e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 794e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 7957ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } 796e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn 797e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn ResTable_config tmpConfig = config; 798e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn const size_t ND = densities.size(); 799e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn for (size_t i=0; i<ND; i++) { 800e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn tmpConfig.density = densities[i]; 801e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn assets.setConfiguration(tmpConfig); 802e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn String8 icon = getResolvedAttribute(&res, tree, ICON_ATTR, &error); 803e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn if (icon != "") { 804e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn printf("application-icon-%d:'%s'\n", densities[i], icon.string()); 805e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 806e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 807e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn assets.setConfiguration(config); 808e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn 8097ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu String8 icon = getResolvedAttribute(&res, tree, ICON_ATTR, &error); 8107ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu if (error != "") { 8117ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n", error.string()); 8127ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu goto bail; 8137ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } 814bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn int32_t testOnly = getIntegerAttribute(tree, TEST_ONLY_ATTR, &error, 0); 8157ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu if (error != "") { 816bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn fprintf(stderr, "ERROR getting 'android:testOnly' attribute: %s\n", error.string()); 8177ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu goto bail; 8187ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } 819e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn printf("application: label='%s' ", label.string()); 820e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn printf("icon='%s'\n", icon.string()); 821bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (testOnly != 0) { 822bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn printf("testOnly='%d'\n", testOnly); 823bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } 824bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } else if (tag == "uses-sdk") { 825bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn int32_t code = getIntegerAttribute(tree, MIN_SDK_VERSION_ATTR, &error); 826bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (error != "") { 827bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn error = ""; 828bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn String8 name = getResolvedAttribute(&res, tree, MIN_SDK_VERSION_ATTR, &error); 829bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (error != "") { 830bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn fprintf(stderr, "ERROR getting 'android:minSdkVersion' attribute: %s\n", 831bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn error.string()); 832bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn goto bail; 833bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } 834723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn if (name == "Donut") targetSdk = 4; 835bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn printf("sdkVersion:'%s'\n", name.string()); 836bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } else if (code != -1) { 837723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn targetSdk = code; 838bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn printf("sdkVersion:'%d'\n", code); 839bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } 84075c498426a17b47d445711bb9e36794b05876a56Suchi Amalapurapu code = getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR, NULL, -1); 84175c498426a17b47d445711bb9e36794b05876a56Suchi Amalapurapu if (code != -1) { 84275c498426a17b47d445711bb9e36794b05876a56Suchi Amalapurapu printf("maxSdkVersion:'%d'\n", code); 84375c498426a17b47d445711bb9e36794b05876a56Suchi Amalapurapu } 844bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn code = getIntegerAttribute(tree, TARGET_SDK_VERSION_ATTR, &error); 845bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (error != "") { 846bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn error = ""; 847bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn String8 name = getResolvedAttribute(&res, tree, TARGET_SDK_VERSION_ATTR, &error); 848bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (error != "") { 849bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn fprintf(stderr, "ERROR getting 'android:targetSdkVersion' attribute: %s\n", 850bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn error.string()); 851bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn goto bail; 852bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } 853723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn if (name == "Donut" && targetSdk < 4) targetSdk = 4; 854bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn printf("targetSdkVersion:'%s'\n", name.string()); 855bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } else if (code != -1) { 856723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn if (targetSdk < code) { 857723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn targetSdk = code; 858723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn } 859bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn printf("targetSdkVersion:'%d'\n", code); 860bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } 861bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } else if (tag == "uses-configuration") { 862bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn int32_t reqTouchScreen = getIntegerAttribute(tree, 863bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn REQ_TOUCH_SCREEN_ATTR, NULL, 0); 864bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn int32_t reqKeyboardType = getIntegerAttribute(tree, 865bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn REQ_KEYBOARD_TYPE_ATTR, NULL, 0); 866bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn int32_t reqHardKeyboard = getIntegerAttribute(tree, 867bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn REQ_HARD_KEYBOARD_ATTR, NULL, 0); 868bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn int32_t reqNavigation = getIntegerAttribute(tree, 869bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn REQ_NAVIGATION_ATTR, NULL, 0); 870bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn int32_t reqFiveWayNav = getIntegerAttribute(tree, 871bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn REQ_FIVE_WAY_NAV_ATTR, NULL, 0); 872cb2d50d0d6e2e37ae02b014999da23ecd32038b8Dianne Hackborn printf("uses-configuration:"); 873bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (reqTouchScreen != 0) { 874bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn printf(" reqTouchScreen='%d'", reqTouchScreen); 875bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } 876bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (reqKeyboardType != 0) { 877bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn printf(" reqKeyboardType='%d'", reqKeyboardType); 878bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } 879bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (reqHardKeyboard != 0) { 880bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn printf(" reqHardKeyboard='%d'", reqHardKeyboard); 881bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } 882bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (reqNavigation != 0) { 883bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn printf(" reqNavigation='%d'", reqNavigation); 8847ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } 885bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (reqFiveWayNav != 0) { 886bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn printf(" reqFiveWayNav='%d'", reqFiveWayNav); 887bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } 888bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn printf("\n"); 889723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn } else if (tag == "supports-screens") { 890723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn smallScreen = getIntegerAttribute(tree, 891723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn SMALL_SCREEN_ATTR, NULL, 1); 892723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn normalScreen = getIntegerAttribute(tree, 893723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn NORMAL_SCREEN_ATTR, NULL, 1); 894723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn largeScreen = getIntegerAttribute(tree, 895723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn LARGE_SCREEN_ATTR, NULL, 1); 896f43489d7d5e1c0c5c9a7e54c22845fcb99765f81Dianne Hackborn xlargeScreen = getIntegerAttribute(tree, 897f43489d7d5e1c0c5c9a7e54c22845fcb99765f81Dianne Hackborn XLARGE_SCREEN_ATTR, NULL, 1); 898a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn anyDensity = getIntegerAttribute(tree, 899a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn ANY_DENSITY_ATTR, NULL, 1); 900e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn requiresSmallestWidthDp = getIntegerAttribute(tree, 901e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn REQUIRES_SMALLEST_WIDTH_DP_ATTR, NULL, 0); 902e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn compatibleWidthLimitDp = getIntegerAttribute(tree, 903e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn COMPATIBLE_WIDTH_LIMIT_DP_ATTR, NULL, 0); 904e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn largestWidthLimitDp = getIntegerAttribute(tree, 905e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn LARGEST_WIDTH_LIMIT_DP_ATTR, NULL, 0); 906e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn } else if (tag == "uses-feature") { 907e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn String8 name = getAttribute(tree, NAME_ATTR, &error); 90840b94725dc1c62ea66db0b9502dd81b97dd3e35fSuchi Amalapurapu 90940b94725dc1c62ea66db0b9502dd81b97dd3e35fSuchi Amalapurapu if (name != "" && error == "") { 910e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn int req = getIntegerAttribute(tree, 911e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn REQUIRED_ATTR, NULL, 1); 91289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill 913e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn if (name == "android.hardware.camera") { 914e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn specCameraFeature = true; 91589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.hardware.camera.autofocus") { 91689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // these have no corresponding permission to check for, 91789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // but should imply the foundational camera permission 91889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill reqCameraAutofocusFeature = reqCameraAutofocusFeature || req; 91989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill specCameraAutofocusFeature = true; 92089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (req && (name == "android.hardware.camera.flash")) { 92189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // these have no corresponding permission to check for, 92289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // but should imply the foundational camera permission 92389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill reqCameraFlashFeature = true; 92489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.hardware.location") { 92589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill specLocationFeature = true; 92689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.hardware.location.network") { 92789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill specNetworkLocFeature = true; 92889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill reqNetworkLocFeature = reqNetworkLocFeature || req; 929ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn } else if (name == "android.hardware.location.gps") { 930ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn specGpsFeature = true; 93189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill reqGpsFeature = reqGpsFeature || req; 93289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.hardware.bluetooth") { 93389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill specBluetoothFeature = true; 93489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.hardware.touchscreen") { 93589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill specTouchscreenFeature = true; 93689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.hardware.touchscreen.multitouch") { 93789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill specMultitouchFeature = true; 93889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.hardware.touchscreen.multitouch.distinct") { 93989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill reqDistinctMultitouchFeature = reqDistinctMultitouchFeature || req; 94089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.hardware.microphone") { 94189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill specMicrophoneFeature = true; 94289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.hardware.wifi") { 94389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill specWiFiFeature = true; 94489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.hardware.telephony") { 94589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill specTelephonyFeature = true; 94689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (req && (name == "android.hardware.telephony.gsm" || 94789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.hardware.telephony.cdma")) { 94889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // these have no corresponding permission to check for, 94989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // but should imply the foundational telephony permission 95089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill reqTelephonySubFeature = true; 951e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } else if (name == "android.hardware.screen.portrait") { 952e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn specScreenPortraitFeature = true; 953e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } else if (name == "android.hardware.screen.landscape") { 954e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn specScreenLandscapeFeature = true; 955e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn } 956e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn printf("uses-feature%s:'%s'\n", 957e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn req ? "" : "-not-required", name.string()); 958e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn } else { 959e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn int vers = getIntegerAttribute(tree, 960e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn GL_ES_VERSION_ATTR, &error); 961e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn if (error == "") { 962e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn printf("uses-gl-es:'0x%x'\n", vers); 963e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn } 964e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn } 965e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn } else if (tag == "uses-permission") { 966e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn String8 name = getAttribute(tree, NAME_ATTR, &error); 96740b94725dc1c62ea66db0b9502dd81b97dd3e35fSuchi Amalapurapu if (name != "" && error == "") { 968e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn if (name == "android.permission.CAMERA") { 969e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn hasCameraPermission = true; 970ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn } else if (name == "android.permission.ACCESS_FINE_LOCATION") { 971ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn hasGpsPermission = true; 97289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.permission.ACCESS_MOCK_LOCATION") { 97389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill hasMockLocPermission = true; 97489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.permission.ACCESS_COARSE_LOCATION") { 97589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill hasCoarseLocPermission = true; 97689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" || 97789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.permission.INSTALL_LOCATION_PROVIDER") { 97889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill hasGeneralLocPermission = true; 97989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.permission.BLUETOOTH" || 98089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.permission.BLUETOOTH_ADMIN") { 98189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill hasBluetoothPermission = true; 98289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.permission.RECORD_AUDIO") { 98389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill hasRecordAudioPermission = true; 98489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.permission.ACCESS_WIFI_STATE" || 98589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.permission.CHANGE_WIFI_STATE" || 98689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.permission.CHANGE_WIFI_MULTICAST_STATE") { 98789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill hasWiFiPermission = true; 98889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.permission.CALL_PHONE" || 98989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.permission.CALL_PRIVILEGED" || 99089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.permission.MODIFY_PHONE_STATE" || 99189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.permission.PROCESS_OUTGOING_CALLS" || 99289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.permission.READ_SMS" || 99389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.permission.RECEIVE_SMS" || 99489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.permission.RECEIVE_MMS" || 99589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.permission.RECEIVE_WAP_PUSH" || 99689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.permission.SEND_SMS" || 99789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.permission.WRITE_APN_SETTINGS" || 99889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.permission.WRITE_SMS") { 99989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill hasTelephonyPermission = true; 1000063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root } else if (name == "android.permission.WRITE_EXTERNAL_STORAGE") { 1001063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root hasWriteExternalStoragePermission = true; 1002063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root } else if (name == "android.permission.READ_PHONE_STATE") { 1003063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root hasReadPhoneStatePermission = true; 1004e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn } 1005e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn printf("uses-permission:'%s'\n", name.string()); 1006e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn } else { 1007e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1008e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn error.string()); 1009e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn goto bail; 1010e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn } 101143b6803095e41e6a1cf844a77813c6cdbdc84ec3Dianne Hackborn } else if (tag == "uses-package") { 101243b6803095e41e6a1cf844a77813c6cdbdc84ec3Dianne Hackborn String8 name = getAttribute(tree, NAME_ATTR, &error); 101343b6803095e41e6a1cf844a77813c6cdbdc84ec3Dianne Hackborn if (name != "" && error == "") { 101443b6803095e41e6a1cf844a77813c6cdbdc84ec3Dianne Hackborn printf("uses-package:'%s'\n", name.string()); 101543b6803095e41e6a1cf844a77813c6cdbdc84ec3Dianne Hackborn } else { 101643b6803095e41e6a1cf844a77813c6cdbdc84ec3Dianne Hackborn fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 101743b6803095e41e6a1cf844a77813c6cdbdc84ec3Dianne Hackborn error.string()); 101843b6803095e41e6a1cf844a77813c6cdbdc84ec3Dianne Hackborn goto bail; 101943b6803095e41e6a1cf844a77813c6cdbdc84ec3Dianne Hackborn } 1020e2c17f9174144a6eca3fdbed8d5d1370f318f549Jeff Hamilton } else if (tag == "original-package") { 1021e2c17f9174144a6eca3fdbed8d5d1370f318f549Jeff Hamilton String8 name = getAttribute(tree, NAME_ATTR, &error); 1022e2c17f9174144a6eca3fdbed8d5d1370f318f549Jeff Hamilton if (name != "" && error == "") { 1023e2c17f9174144a6eca3fdbed8d5d1370f318f549Jeff Hamilton printf("original-package:'%s'\n", name.string()); 1024e2c17f9174144a6eca3fdbed8d5d1370f318f549Jeff Hamilton } else { 1025e2c17f9174144a6eca3fdbed8d5d1370f318f549Jeff Hamilton fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1026e2c17f9174144a6eca3fdbed8d5d1370f318f549Jeff Hamilton error.string()); 1027e2c17f9174144a6eca3fdbed8d5d1370f318f549Jeff Hamilton goto bail; 1028e2c17f9174144a6eca3fdbed8d5d1370f318f549Jeff Hamilton } 1029096b67f65510a5076f1f845f9e19dda2b30ea6bbDan Morrill } else if (tag == "supports-gl-texture") { 10306f51fc14d0c3df8f9153ae5df992cc2731f099c8Dan Morrill String8 name = getAttribute(tree, NAME_ATTR, &error); 10316f51fc14d0c3df8f9153ae5df992cc2731f099c8Dan Morrill if (name != "" && error == "") { 1032096b67f65510a5076f1f845f9e19dda2b30ea6bbDan Morrill printf("supports-gl-texture:'%s'\n", name.string()); 10336f51fc14d0c3df8f9153ae5df992cc2731f099c8Dan Morrill } else { 10346f51fc14d0c3df8f9153ae5df992cc2731f099c8Dan Morrill fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 10356f51fc14d0c3df8f9153ae5df992cc2731f099c8Dan Morrill error.string()); 10366f51fc14d0c3df8f9153ae5df992cc2731f099c8Dan Morrill goto bail; 10376f51fc14d0c3df8f9153ae5df992cc2731f099c8Dan Morrill } 1038a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn } else if (tag == "compatible-screens") { 1039a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn printCompatibleScreens(tree); 1040a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn depth--; 104156088a55ca6c9277f09040a7883117cb127e1e56Kenny Root } else if (tag == "package-verifier") { 104256088a55ca6c9277f09040a7883117cb127e1e56Kenny Root String8 name = getAttribute(tree, NAME_ATTR, &error); 104356088a55ca6c9277f09040a7883117cb127e1e56Kenny Root if (name != "" && error == "") { 104456088a55ca6c9277f09040a7883117cb127e1e56Kenny Root String8 publicKey = getAttribute(tree, PUBLIC_KEY_ATTR, &error); 104556088a55ca6c9277f09040a7883117cb127e1e56Kenny Root if (publicKey != "" && error == "") { 104656088a55ca6c9277f09040a7883117cb127e1e56Kenny Root printf("package-verifier: name='%s' publicKey='%s'\n", 104756088a55ca6c9277f09040a7883117cb127e1e56Kenny Root name.string(), publicKey.string()); 104856088a55ca6c9277f09040a7883117cb127e1e56Kenny Root } 104956088a55ca6c9277f09040a7883117cb127e1e56Kenny Root } 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10517ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } else if (depth == 3 && withinApplication) { 10527ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu withinActivity = false; 10537ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu withinReceiver = false; 10541b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu withinService = false; 10551b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu hasIntentFilter = false; 10567ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu if(tag == "activity") { 10577ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu withinActivity = true; 10587ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu activityName = getAttribute(tree, NAME_ATTR, &error); 10597ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu if (error != "") { 10607ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", error.string()); 10617ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu goto bail; 10627ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10647ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu activityLabel = getResolvedAttribute(&res, tree, LABEL_ATTR, &error); 10657ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu if (error != "") { 10667ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu fprintf(stderr, "ERROR getting 'android:label' attribute: %s\n", error.string()); 10677ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu goto bail; 10687ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10707ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu activityIcon = getResolvedAttribute(&res, tree, ICON_ATTR, &error); 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (error != "") { 10727ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n", error.string()); 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1075f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn 1076f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn int32_t orien = getResolvedIntegerAttribute(&res, tree, 1077f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn SCREEN_ORIENTATION_ATTR, &error); 1078f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn if (error == "") { 1079f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn if (orien == 0 || orien == 6 || orien == 8) { 1080f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn // Requests landscape, sensorLandscape, or reverseLandscape. 1081f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn reqScreenLandscapeFeature = true; 1082f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn } else if (orien == 1 || orien == 7 || orien == 9) { 1083f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn // Requests portrait, sensorPortrait, or reversePortrait. 1084f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn reqScreenPortraitFeature = true; 1085f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn } 1086f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn } 10877ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } else if (tag == "uses-library") { 10887ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu String8 libraryName = getAttribute(tree, NAME_ATTR, &error); 10897ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu if (error != "") { 10907ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu fprintf(stderr, "ERROR getting 'android:name' attribute for uses-library: %s\n", error.string()); 10917ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu goto bail; 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 109349237345d83e62fdb9eb8d50b13ad086636a04faDianne Hackborn int req = getIntegerAttribute(tree, 109449237345d83e62fdb9eb8d50b13ad086636a04faDianne Hackborn REQUIRED_ATTR, NULL, 1); 109549237345d83e62fdb9eb8d50b13ad086636a04faDianne Hackborn printf("uses-library%s:'%s'\n", 109649237345d83e62fdb9eb8d50b13ad086636a04faDianne Hackborn req ? "" : "-not-required", libraryName.string()); 10977ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } else if (tag == "receiver") { 10987ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu withinReceiver = true; 10997ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu receiverName = getAttribute(tree, NAME_ATTR, &error); 11007ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (error != "") { 11027ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu fprintf(stderr, "ERROR getting 'android:name' attribute for receiver: %s\n", error.string()); 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11051b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } else if (tag == "service") { 11061b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu withinService = true; 11071b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu serviceName = getAttribute(tree, NAME_ATTR, &error); 11081b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu 11091b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (error != "") { 11101b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu fprintf(stderr, "ERROR getting 'android:name' attribute for service: %s\n", error.string()); 11111b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu goto bail; 11121b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 11137ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } 11141b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } else if ((depth == 4) && (tag == "intent-filter")) { 11151b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu hasIntentFilter = true; 11161b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu withinIntentFilter = true; 11171b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu actMainActivity = actWidgetReceivers = actImeService = actWallpaperService = false; 11181b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } else if ((depth == 5) && withinIntentFilter){ 11191b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu String8 action; 11201b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (tag == "action") { 11211b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu action = getAttribute(tree, NAME_ATTR, &error); 11221b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (error != "") { 11231b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", error.string()); 11241b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu goto bail; 11251b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 11261b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (withinActivity) { 1127bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (action == "android.intent.action.MAIN") { 1128bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn isMainActivity = true; 11291b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu actMainActivity = true; 1130bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } 11311b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } else if (withinReceiver) { 11321b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (action == "android.appwidget.action.APPWIDGET_UPDATE") { 11331b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu actWidgetReceivers = true; 11347ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } 11351b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } else if (withinService) { 11361b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (action == "android.view.InputMethod") { 11371b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu actImeService = true; 11381b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } else if (action == "android.service.wallpaper.WallpaperService") { 11391b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu actWallpaperService = true; 11407ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } 11417ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } 11421b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (action == "android.intent.action.SEARCH") { 11431b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu isSearchable = true; 11447ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } 11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11471b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (tag == "category") { 11481b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu String8 category = getAttribute(tree, NAME_ATTR, &error); 11491b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (error != "") { 11501b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu fprintf(stderr, "ERROR getting 'name' attribute: %s\n", error.string()); 11511b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu goto bail; 11521b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 11531b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (withinActivity) { 11541b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (category == "android.intent.category.LAUNCHER") { 11551b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu isLauncherActivity = true; 11561b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 11571b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 11587ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } 11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1161063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root 1162063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root // Pre-1.6 implicitly granted permission compatibility logic 1163063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root if (targetSdk < 4) { 1164063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root if (!hasWriteExternalStoragePermission) { 1165063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root printf("uses-permission:'android.permission.WRITE_EXTERNAL_STORAGE'\n"); 1166063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root } 1167063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root if (!hasReadPhoneStatePermission) { 1168063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root printf("uses-permission:'android.permission.READ_PHONE_STATE'\n"); 1169063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root } 1170063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root } 11711b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu 117289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill /* The following blocks handle printing "inferred" uses-features, based 117389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill * on whether related features or permissions are used by the app. 117489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill * Note that the various spec*Feature variables denote whether the 117589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill * relevant tag was *present* in the AndroidManfest, not that it was 117689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill * present and set to true. 117789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill */ 117889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // Camera-related back-compatibility logic 117989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill if (!specCameraFeature) { 118089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill if (reqCameraFlashFeature || reqCameraAutofocusFeature) { 118189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // if app requested a sub-feature (autofocus or flash) and didn't 118289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // request the base camera feature, we infer that it meant to 118389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill printf("uses-feature:'android.hardware.camera'\n"); 118489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (hasCameraPermission) { 118589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // if app wants to use camera but didn't request the feature, we infer 118689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // that it meant to, and further that it wants autofocus 118789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // (which was the 1.0 - 1.5 behavior) 118889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill printf("uses-feature:'android.hardware.camera'\n"); 118989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill if (!specCameraAutofocusFeature) { 119089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill printf("uses-feature:'android.hardware.camera.autofocus'\n"); 119189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } 119289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } 1193e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn } 1194dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker 119589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // Location-related back-compatibility logic 119689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill if (!specLocationFeature && 119789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill (hasMockLocPermission || hasCoarseLocPermission || hasGpsPermission || 119889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill hasGeneralLocPermission || reqNetworkLocFeature || reqGpsFeature)) { 119989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // if app either takes a location-related permission or requests one of the 120089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // sub-features, we infer that it also meant to request the base location feature 120189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill printf("uses-feature:'android.hardware.location'\n"); 120289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } 1203ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn if (!specGpsFeature && hasGpsPermission) { 120489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // if app takes GPS (FINE location) perm but does not request the GPS 120589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // feature, we infer that it meant to 1206ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn printf("uses-feature:'android.hardware.location.gps'\n"); 1207ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn } 120889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill if (!specNetworkLocFeature && hasCoarseLocPermission) { 120989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // if app takes Network location (COARSE location) perm but does not request the 121089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // network location feature, we infer that it meant to 121189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill printf("uses-feature:'android.hardware.location.network'\n"); 121289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } 121389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill 121489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // Bluetooth-related compatibility logic 12156b22d81aa35d9a9b32670995c002e92588b2fe09Dan Morrill if (!specBluetoothFeature && hasBluetoothPermission && (targetSdk > 4)) { 121689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // if app takes a Bluetooth permission but does not request the Bluetooth 121789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // feature, we infer that it meant to 121889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill printf("uses-feature:'android.hardware.bluetooth'\n"); 121989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } 122089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill 122189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // Microphone-related compatibility logic 122289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill if (!specMicrophoneFeature && hasRecordAudioPermission) { 122389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // if app takes the record-audio permission but does not request the microphone 122489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // feature, we infer that it meant to 122589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill printf("uses-feature:'android.hardware.microphone'\n"); 122689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } 122789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill 122889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // WiFi-related compatibility logic 122989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill if (!specWiFiFeature && hasWiFiPermission) { 123089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // if app takes one of the WiFi permissions but does not request the WiFi 123189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // feature, we infer that it meant to 123289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill printf("uses-feature:'android.hardware.wifi'\n"); 123389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } 123489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill 123589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // Telephony-related compatibility logic 123689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill if (!specTelephonyFeature && (hasTelephonyPermission || reqTelephonySubFeature)) { 123789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // if app takes one of the telephony permissions or requests a sub-feature but 123889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // does not request the base telephony feature, we infer that it meant to 123989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill printf("uses-feature:'android.hardware.telephony'\n"); 124089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } 124189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill 124289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // Touchscreen-related back-compatibility logic 124389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill if (!specTouchscreenFeature) { // not a typo! 124489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // all apps are presumed to require a touchscreen, unless they explicitly say 124589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // <uses-feature android:name="android.hardware.touchscreen" android:required="false"/> 124689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // Note that specTouchscreenFeature is true if the tag is present, regardless 124789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // of whether its value is true or false, so this is safe 124889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill printf("uses-feature:'android.hardware.touchscreen'\n"); 124989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } 125089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill if (!specMultitouchFeature && reqDistinctMultitouchFeature) { 125189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // if app takes one of the telephony permissions or requests a sub-feature but 125289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // does not request the base telephony feature, we infer that it meant to 125389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill printf("uses-feature:'android.hardware.touchscreen.multitouch'\n"); 125489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } 1255ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn 1256e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn // Landscape/portrait-related compatibility logic 1257f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn if (!specScreenLandscapeFeature && !specScreenPortraitFeature) { 1258f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn // If the app has specified any activities in its manifest 1259f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn // that request a specific orientation, then assume that 1260f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn // orientation is required. 1261f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn if (reqScreenLandscapeFeature) { 1262f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn printf("uses-feature:'android.hardware.screen.landscape'\n"); 1263f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn } 1264f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn if (reqScreenPortraitFeature) { 1265f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn printf("uses-feature:'android.hardware.screen.portrait'\n"); 1266f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn } 1267e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 1268e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn 12691b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (hasMainActivity) { 12701b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu printf("main\n"); 12711b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 12721b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (hasWidgetReceivers) { 12731b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu printf("app-widget\n"); 12741b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 12751b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (hasImeService) { 12761b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu printf("ime\n"); 12771b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 12781b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (hasWallpaperService) { 12791b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu printf("wallpaper\n"); 12801b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 12811b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (hasOtherActivities) { 12821b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu printf("other-activities\n"); 12831b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 12841b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (isSearchable) { 12851b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu printf("search\n"); 12861b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 12871b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (hasOtherReceivers) { 12881b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu printf("other-receivers\n"); 12891b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 12901b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (hasOtherServices) { 12911b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu printf("other-services\n"); 12921b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 12931b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu 1294e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn // For modern apps, if screen size buckets haven't been specified 1295e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn // but the new width ranges have, then infer the buckets from them. 1296e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn if (smallScreen > 0 && normalScreen > 0 && largeScreen > 0 && xlargeScreen > 0 1297e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn && requiresSmallestWidthDp > 0) { 1298e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn int compatWidth = compatibleWidthLimitDp; 1299e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn if (compatWidth <= 0) compatWidth = requiresSmallestWidthDp; 1300e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn if (requiresSmallestWidthDp <= 240 && compatWidth >= 240) { 1301e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn smallScreen = -1; 1302e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } else { 1303e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn smallScreen = 0; 1304e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 1305e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn if (requiresSmallestWidthDp <= 320 && compatWidth >= 320) { 1306e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn normalScreen = -1; 1307e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } else { 1308e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn normalScreen = 0; 1309e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 1310e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn if (requiresSmallestWidthDp <= 480 && compatWidth >= 480) { 1311e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn largeScreen = -1; 1312e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } else { 1313e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn largeScreen = 0; 1314e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 1315e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn if (requiresSmallestWidthDp <= 720 && compatWidth >= 720) { 1316e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn xlargeScreen = -1; 1317e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } else { 1318e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn xlargeScreen = 0; 1319e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 1320e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 1321e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn 1322723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn // Determine default values for any unspecified screen sizes, 1323723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn // based on the target SDK of the package. As of 4 (donut) 1324723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn // the screen size support was introduced, so all default to 1325723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn // enabled. 1326723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn if (smallScreen > 0) { 1327723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn smallScreen = targetSdk >= 4 ? -1 : 0; 1328723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn } 1329723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn if (normalScreen > 0) { 1330723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn normalScreen = -1; 1331723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn } 1332723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn if (largeScreen > 0) { 1333723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn largeScreen = targetSdk >= 4 ? -1 : 0; 1334723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn } 1335f43489d7d5e1c0c5c9a7e54c22845fcb99765f81Dianne Hackborn if (xlargeScreen > 0) { 1336d58fb97ddf052b3ceac921ac7e936af990392b2cScott Main // Introduced in Gingerbread. 1337d58fb97ddf052b3ceac921ac7e936af990392b2cScott Main xlargeScreen = targetSdk >= 9 ? -1 : 0; 1338f43489d7d5e1c0c5c9a7e54c22845fcb99765f81Dianne Hackborn } 1339a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn if (anyDensity > 0) { 1340e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn anyDensity = (targetSdk >= 4 || requiresSmallestWidthDp > 0 1341e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn || compatibleWidthLimitDp > 0) ? -1 : 0; 1342a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn } 1343723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn printf("supports-screens:"); 1344723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn if (smallScreen != 0) printf(" 'small'"); 1345723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn if (normalScreen != 0) printf(" 'normal'"); 1346723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn if (largeScreen != 0) printf(" 'large'"); 1347f43489d7d5e1c0c5c9a7e54c22845fcb99765f81Dianne Hackborn if (xlargeScreen != 0) printf(" 'xlarge'"); 1348723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn printf("\n"); 1349a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn printf("supports-any-density: '%s'\n", anyDensity ? "true" : "false"); 1350e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn if (requiresSmallestWidthDp > 0) { 1351e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn printf("requires-smallest-width:'%d'\n", requiresSmallestWidthDp); 1352e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 1353e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn if (compatibleWidthLimitDp > 0) { 1354e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn printf("compatible-width-limit:'%d'\n", compatibleWidthLimitDp); 1355e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 1356e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn if (largestWidthLimitDp > 0) { 1357e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn printf("largest-width-limit:'%d'\n", largestWidthLimitDp); 1358e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 1359a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn 13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("locales:"); 1361e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn const size_t NL = locales.size(); 1362e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn for (size_t i=0; i<NL; i++) { 13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* localeStr = locales[i].string(); 13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (localeStr == NULL || strlen(localeStr) == 0) { 13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project localeStr = "--_--"; 13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf(" '%s'", localeStr); 13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("\n"); 13701b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu 1371e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn printf("densities:"); 1372e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn const size_t ND = densities.size(); 1373e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn for (size_t i=0; i<ND; i++) { 1374e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn printf(" '%d'", densities[i]); 1375e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn } 1376e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn printf("\n"); 13771b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu 1378bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn AssetDir* dir = assets.openNonAssetDir(assetsCookie, "lib"); 1379bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (dir != NULL) { 1380bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (dir->getFileCount() > 0) { 1381bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn printf("native-code:"); 1382bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn for (size_t i=0; i<dir->getFileCount(); i++) { 1383bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn printf(" '%s'", dir->getFileName(i).string()); 1384bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } 1385bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn printf("\n"); 1386bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } 1387bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn delete dir; 1388bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } 1389e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill } else if (strcmp("badger", option) == 0) { 13906c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn printf("%s", CONSOLE_DATA); 13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (strcmp("configurations", option) == 0) { 13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Vector<ResTable_config> configs; 13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res.getConfigurations(&configs); 13949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t N = configs.size(); 13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<N; i++) { 13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("%s\n", configs[i].toString().string()); 13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: unknown dump option '%s'\n", option); 14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = NO_ERROR; 14057ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbail: 14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (asset) { 14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete asset; 14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (result != NO_ERROR); 14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Handle the "add" command, which wants to add files to a new or 14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * pre-existing archive. 14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint doAdd(Bundle* bundle) 14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipFile* zip = NULL; 14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t result = UNKNOWN_ERROR; 14229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* zipFileName; 14239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getUpdate()) { 14259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* avoid confusion */ 14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: can't use '-u' with add\n"); 14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getFileSpecCount() < 1) { 14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: must specify zip file name\n"); 14329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zipFileName = bundle->getFileSpecEntry(0); 14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getFileSpecCount() < 2) { 14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "NOTE: nothing to do\n"); 14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 14399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zip = openReadWrite(zipFileName, true); 14429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (zip == NULL) { 14439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: failed opening/creating '%s' as Zip file\n", zipFileName); 14449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 14459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 1; i < bundle->getFileSpecCount(); i++) { 14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* fileName = bundle->getFileSpecEntry(i); 14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (strcasecmp(String8(fileName).getPathExtension().string(), ".gz") == 0) { 14519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf(" '%s'... (from gzip)\n", fileName); 14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = zip->addGzip(fileName, String8(fileName).getBasePath().string(), NULL); 14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1454dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker if (bundle->getJunkPath()) { 1455dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker String8 storageName = String8(fileName).getPathLeaf(); 1456dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker printf(" '%s' as '%s'...\n", fileName, storageName.string()); 1457dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker result = zip->add(fileName, storageName.string(), 1458dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker bundle->getCompressionMethod(), NULL); 1459dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker } else { 1460dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker printf(" '%s'...\n", fileName); 1461dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker result = zip->add(fileName, bundle->getCompressionMethod(), NULL); 1462dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker } 14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result != NO_ERROR) { 14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "Unable to add '%s' to '%s'", bundle->getFileSpecEntry(i), zipFileName); 14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result == NAME_NOT_FOUND) 14679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, ": file not found\n"); 14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (result == ALREADY_EXISTS) 14699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, ": already exists in archive\n"); 14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else 14719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "\n"); 14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 14739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = NO_ERROR; 14779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbail: 14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete zip; 14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (result != NO_ERROR); 14819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Delete files from an existing archive. 14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint doRemove(Bundle* bundle) 14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipFile* zip = NULL; 14909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t result = UNKNOWN_ERROR; 14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* zipFileName; 14929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getFileSpecCount() < 1) { 14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: must specify zip file name\n"); 14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zipFileName = bundle->getFileSpecEntry(0); 14989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getFileSpecCount() < 2) { 15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "NOTE: nothing to do\n"); 15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zip = openReadWrite(zipFileName, false); 15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (zip == NULL) { 15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: failed opening Zip archive '%s'\n", 15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zipFileName); 15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 1; i < bundle->getFileSpecCount(); i++) { 15129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* fileName = bundle->getFileSpecEntry(i); 15139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry* entry; 15149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project entry = zip->getEntryByName(fileName); 15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (entry == NULL) { 15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf(" '%s' NOT FOUND\n", fileName); 15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = zip->remove(entry); 15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result != NO_ERROR) { 15249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "Unable to delete '%s' from '%s'\n", 15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bundle->getFileSpecEntry(i), zipFileName); 15269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 15279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* update the archive */ 15319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zip->flush(); 15329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbail: 15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete zip; 15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (result != NO_ERROR); 15369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 15379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 15409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Package up an asset directory and associated application files. 15419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint doPackage(Bundle* bundle) 15439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 15449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* outputAPKFile; 15459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int retVal = 1; 15469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err; 15479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<AaptAssets> assets; 15489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int N; 15499bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin FILE* fp; 15509bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin String8 dependencyFile; 15519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // -c zz_ZZ means do pseudolocalization 15539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResourceFilter filter; 15549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = filter.parse(bundle->getConfigurations()); 15559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (filter.containsPseudo()) { 15599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bundle->setPseudolocalize(true); 15609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project N = bundle->getFileSpecCount(); 15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (N < 1 && bundle->getResourceSourceDirs().size() == 0 && bundle->getJarFiles().size() == 0 15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && bundle->getAndroidManifestFile() == NULL && bundle->getAssetSourceDir() == NULL) { 15659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: no input files\n"); 15669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 15679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outputAPKFile = bundle->getOutputAPKFile(); 15709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Make sure the filenames provided exist and are of the appropriate type. 15729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outputAPKFile) { 15739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FileType type; 15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project type = getFileType(outputAPKFile); 15759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type != kFileTypeNonexistent && type != kFileTypeRegular) { 15769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, 15779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "ERROR: output file '%s' exists but is not regular file\n", 15789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outputAPKFile); 15799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 15809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Load the assets. 15849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assets = new AaptAssets(); 15859bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin 158603589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin // Set up the resource gathering in assets if we're going to generate 1587b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // dependency files. Every time we encounter a resource while slurping 1588b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // the tree, we'll add it to these stores so we have full resource paths 1589b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // to write to a dependency file. 15909bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin if (bundle->getGenDependencies()) { 159103589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin sp<FilePathStore> resPathStore = new FilePathStore; 159203589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin assets->setFullResPaths(resPathStore); 159303589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin sp<FilePathStore> assetPathStore = new FilePathStore; 159403589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin assets->setFullAssetPaths(assetPathStore); 15959bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin } 15969bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin 15979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = assets->slurpFromArgs(bundle); 15989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err < 0) { 15999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 16009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getVerbose()) { 1603e6b680364dd992907a8d2037685a2e500d188dfbDianne Hackborn assets->print(String8()); 16049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16069bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin // If they asked for any fileAs that need to be compiled, do so. 16079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getResourceSourceDirs().size() || bundle->getAndroidManifestFile()) { 16089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = buildResources(bundle, assets); 16099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != 0) { 16109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 16119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // At this point we've read everything and processed everything. From here 16159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // on out it's just writing output files. 16169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SourcePos::hasErrors()) { 16179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 16189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1620b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // If we've been asked to generate a dependency file, do that here 16219bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin if (bundle->getGenDependencies()) { 1622b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // If this is the packaging step, generate the dependency file next to 1623b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // the output apk (e.g. bin/resources.ap_.d) 162403589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin if (outputAPKFile) { 162503589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin dependencyFile = String8(outputAPKFile); 1626b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // Add the .d extension to the dependency file. 162703589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin dependencyFile.append(".d"); 162803589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin } else { 1629b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // Else if this is the R.java dependency generation step, 1630b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // generate the dependency file in the R.java package subdirectory 1631b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // e.g. gen/com/foo/app/R.java.d 163203589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin dependencyFile = String8(bundle->getRClassDir()); 1633b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin dependencyFile.appendPath("R.java.d"); 163403589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin } 16359bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin // Make sure we have a clean dependency file to start with 16369bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin fp = fopen(dependencyFile, "w"); 16379bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin fclose(fp); 16389bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin } 16399bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin 16409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Write out R.java constants 16419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (assets->getPackage() == assets->getSymbolsPrivatePackage()) { 164263459ad555c10de1f316d6de01fc3cd0c0aaa457Xavier Ducrohet if (bundle->getCustomPackage() == NULL) { 1643b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // Write the R.java file into the appropriate class directory 1644b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // e.g. gen/com/foo/app/R.java 164563459ad555c10de1f316d6de01fc3cd0c0aaa457Xavier Ducrohet err = writeResourceSymbols(bundle, assets, assets->getPackage(), true); 1646b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // If we have library files, we're going to write our R.java file into 1647b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // the appropriate class directory for those libraries as well. 1648b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // e.g. gen/com/foo/app/lib/R.java 1649ce89f1531ed8b96b8b790b3f8b18dd4cf483f7f0Josiah Gaskin if (bundle->getExtraPackages() != NULL) { 16509bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin // Split on colon 1651ce89f1531ed8b96b8b790b3f8b18dd4cf483f7f0Josiah Gaskin String8 libs(bundle->getExtraPackages()); 16529bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin char* packageString = strtok(libs.lockBuffer(libs.length()), ":"); 1653ce89f1531ed8b96b8b790b3f8b18dd4cf483f7f0Josiah Gaskin while (packageString != NULL) { 1654b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // Write the R.java file out with the correct package name 1655ce89f1531ed8b96b8b790b3f8b18dd4cf483f7f0Josiah Gaskin err = writeResourceSymbols(bundle, assets, String8(packageString), true); 16569bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin packageString = strtok(NULL, ":"); 1657ce89f1531ed8b96b8b790b3f8b18dd4cf483f7f0Josiah Gaskin } 1658ce89f1531ed8b96b8b790b3f8b18dd4cf483f7f0Josiah Gaskin libs.unlockBuffer(); 1659ce89f1531ed8b96b8b790b3f8b18dd4cf483f7f0Josiah Gaskin } 166063459ad555c10de1f316d6de01fc3cd0c0aaa457Xavier Ducrohet } else { 166163459ad555c10de1f316d6de01fc3cd0c0aaa457Xavier Ducrohet const String8 customPkg(bundle->getCustomPackage()); 166263459ad555c10de1f316d6de01fc3cd0c0aaa457Xavier Ducrohet err = writeResourceSymbols(bundle, assets, customPkg, true); 166363459ad555c10de1f316d6de01fc3cd0c0aaa457Xavier Ducrohet } 16649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err < 0) { 16659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 16669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 16689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = writeResourceSymbols(bundle, assets, assets->getPackage(), false); 16699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err < 0) { 16709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 16719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = writeResourceSymbols(bundle, assets, assets->getSymbolsPrivatePackage(), true); 16739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err < 0) { 16749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 16759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16781553c82e084ac5763fb393857224145506771b99Joe Onorato // Write out the ProGuard file 16791553c82e084ac5763fb393857224145506771b99Joe Onorato err = writeProguardFile(bundle, assets); 16801553c82e084ac5763fb393857224145506771b99Joe Onorato if (err < 0) { 16811553c82e084ac5763fb393857224145506771b99Joe Onorato goto bail; 16821553c82e084ac5763fb393857224145506771b99Joe Onorato } 16831553c82e084ac5763fb393857224145506771b99Joe Onorato 16849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Write the apk 16859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outputAPKFile) { 16869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = writeAPK(bundle, assets, String8(outputAPKFile)); 16879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 16889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: packaging of '%s' failed\n", outputAPKFile); 16899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 16909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1693b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // If we've been asked to generate a dependency file, we need to finish up here. 1694b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // the writeResourceSymbols and writeAPK functions have already written the target 1695b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // half of the dependency file, now we need to write the prerequisites. (files that 1696b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // the R.java file or .ap_ file depend on) 169703589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin if (bundle->getGenDependencies()) { 169803589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin // Now that writeResourceSymbols or writeAPK has taken care of writing 169903589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin // the targets to our dependency file, we'll write the prereqs 170003589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin fp = fopen(dependencyFile, "a+"); 170103589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin fprintf(fp, " : "); 170203589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin bool includeRaw = (outputAPKFile != NULL); 170303589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin err = writeDependencyPreReqs(bundle, assets, fp, includeRaw); 1704b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // Also manually add the AndroidManifeset since it's not under res/ or assets/ 1705b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // and therefore was not added to our pathstores during slurping 170603589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin fprintf(fp, "%s \\\n", bundle->getAndroidManifestFile()); 170703589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin fclose(fp); 170803589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin } 170903589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin 17109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project retVal = 0; 17119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbail: 17129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SourcePos::hasErrors()) { 17139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SourcePos::printErrors(stderr); 17149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return retVal; 17169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 17178a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 17188a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin/* 17198a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin * Do PNG Crunching 17208a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin * PRECONDITIONS 17218a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin * -S flag points to a source directory containing drawable* folders 17228a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin * -C flag points to destination directory. The folder structure in the 17238a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin * source directory will be mirrored to the destination (cache) directory 17248a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin * 17258a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin * POSTCONDITIONS 17268a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin * Destination directory will be updated to match the PNG files in 17278a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin * the source directory. 17288a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin */ 17298a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskinint doCrunch(Bundle* bundle) 17308a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin{ 17318a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin fprintf(stdout, "Crunching PNG Files in "); 17328a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin fprintf(stdout, "source dir: %s\n", bundle->getResourceSourceDirs()[0]); 17338a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin fprintf(stdout, "To destination dir: %s\n", bundle->getCrunchedOutputDir()); 17348a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 17358a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin updatePreProcessedCache(bundle); 17368a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 17378a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin return NO_ERROR; 17388a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin} 1739e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 1740e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrillchar CONSOLE_DATA[2925] = { 1741e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1742e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 95, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1743e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1744e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 1745e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 63, 1746e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 86, 35, 40, 46, 46, 95, 95, 95, 95, 97, 97, 44, 32, 46, 124, 42, 33, 83, 1747e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 62, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1748e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1749e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 46, 58, 59, 61, 59, 61, 81, 1750e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 81, 81, 81, 66, 96, 61, 61, 58, 46, 46, 46, 58, 32, 32, 32, 32, 32, 32, 1751e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 1752e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1753e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 46, 61, 59, 59, 59, 58, 106, 81, 81, 81, 81, 102, 59, 61, 59, 1754e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 61, 61, 61, 58, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1755e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1756e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 1757e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 58, 109, 81, 81, 81, 81, 61, 59, 59, 59, 59, 59, 58, 59, 59, 46, 32, 1758e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1759e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1760e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 60, 81, 81, 81, 81, 87, 1761e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 58, 59, 59, 59, 59, 59, 59, 61, 119, 44, 32, 32, 32, 32, 32, 32, 32, 32, 1762e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 1763e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 1764e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 47, 61, 59, 59, 58, 100, 81, 81, 81, 81, 35, 58, 59, 59, 59, 59, 59, 58, 1765e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 121, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1766e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1767e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 109, 58, 59, 59, 61, 81, 81, 1768e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 81, 81, 81, 109, 58, 59, 59, 59, 59, 61, 109, 81, 81, 76, 46, 32, 32, 32, 1769e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 1770e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1771e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 41, 87, 59, 61, 59, 41, 81, 81, 81, 81, 81, 81, 59, 61, 59, 1772e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 58, 109, 81, 81, 87, 39, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1773e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1774e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 60, 81, 91, 59, 1775e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 61, 81, 81, 81, 81, 81, 87, 43, 59, 58, 59, 60, 81, 81, 81, 76, 32, 1776e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1777e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1778e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 52, 91, 58, 45, 59, 87, 81, 81, 81, 81, 1779e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 70, 58, 58, 58, 59, 106, 81, 81, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32, 1780e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 1781e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1782e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 93, 40, 32, 46, 59, 100, 81, 81, 81, 81, 40, 58, 46, 46, 58, 100, 81, 1783e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 81, 68, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1784e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1785e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 46, 46, 46, 32, 46, 46, 46, 32, 46, 32, 46, 45, 91, 59, 61, 58, 109, 1786e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 81, 81, 81, 87, 46, 58, 61, 59, 60, 81, 81, 80, 32, 32, 32, 32, 32, 32, 1787e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 1788e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 46, 46, 61, 59, 61, 61, 61, 59, 61, 61, 59, 1789e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 58, 58, 46, 46, 41, 58, 59, 58, 81, 81, 81, 81, 69, 58, 59, 59, 1790e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 60, 81, 81, 68, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1791e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 58, 59, 1792e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 61, 46, 1793e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 61, 59, 93, 81, 81, 81, 81, 107, 58, 59, 58, 109, 87, 68, 96, 32, 32, 32, 1794e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1795e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 10, 32, 32, 32, 46, 60, 61, 61, 59, 59, 59, 59, 59, 59, 59, 59, 1796e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 59, 59, 59, 59, 59, 59, 59, 58, 58, 58, 115, 109, 68, 41, 36, 81, 1797e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 109, 46, 61, 61, 81, 69, 96, 46, 58, 58, 46, 58, 46, 46, 32, 32, 32, 32, 1798e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 46, 32, 95, 81, 1799e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 67, 61, 61, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 1800e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 59, 59, 58, 68, 39, 61, 105, 61, 63, 81, 119, 58, 106, 80, 32, 58, 1801e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 61, 59, 59, 61, 59, 61, 59, 61, 46, 95, 32, 32, 32, 32, 32, 32, 32, 32, 1802e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 10, 32, 32, 36, 81, 109, 105, 59, 61, 59, 59, 59, 1803e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 46, 58, 37, 1804e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 73, 108, 108, 62, 52, 81, 109, 34, 32, 61, 59, 59, 59, 59, 59, 59, 59, 59, 1805e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 61, 59, 61, 61, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 1806e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 46, 45, 57, 101, 43, 43, 61, 61, 59, 59, 59, 59, 59, 59, 61, 59, 59, 1807e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 59, 59, 59, 59, 59, 58, 97, 46, 61, 108, 62, 126, 58, 106, 80, 96, 1808e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 46, 61, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 61, 1809e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 97, 103, 97, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 45, 46, 32, 1810e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 46, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45, 58, 59, 59, 59, 59, 61, 1811e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 119, 81, 97, 124, 105, 124, 124, 39, 126, 95, 119, 58, 61, 58, 59, 59, 59, 1812e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 119, 81, 81, 99, 32, 32, 1813e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1814e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 58, 106, 81, 81, 81, 109, 119, 1815e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 119, 119, 109, 109, 81, 81, 122, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 1816e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 59, 59, 59, 58, 115, 81, 87, 81, 102, 32, 32, 32, 32, 32, 32, 10, 1817e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1818e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 61, 58, 59, 61, 81, 81, 81, 81, 81, 81, 87, 87, 81, 81, 81, 81, 1819e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 81, 58, 59, 59, 59, 59, 59, 59, 59, 59, 58, 45, 45, 45, 59, 59, 59, 41, 1820e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 87, 66, 33, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 1821e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 93, 81, 1822e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 1823e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 45, 32, 46, 32, 32, 32, 32, 32, 46, 32, 126, 96, 32, 32, 32, 32, 32, 32, 1824e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1825e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 58, 61, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81, 1826e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 1827e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 1828e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 1829e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58, 1830e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 59, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1831e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1832e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 60, 81, 81, 81, 81, 1833e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 81, 81, 81, 81, 81, 81, 81, 81, 81, 59, 61, 59, 59, 61, 32, 32, 32, 32, 1834e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1835e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1836e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 58, 59, 59, 93, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 1837e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 81, 81, 40, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1838e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 1839e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 106, 1840e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 76, 58, 59, 59, 59, 1841e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1842e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1843e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 61, 58, 58, 81, 81, 81, 81, 81, 81, 81, 81, 1844e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 81, 81, 81, 81, 81, 87, 58, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 1845e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 1846e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1847e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 58, 59, 61, 41, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 87, 59, 1848e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 61, 58, 59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1849e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1850e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 61, 81, 81, 81, 1851e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 81, 81, 81, 81, 81, 81, 81, 81, 81, 107, 58, 59, 59, 59, 59, 58, 32, 32, 1852e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1853e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1854e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 58, 59, 59, 58, 51, 81, 81, 81, 81, 81, 81, 81, 81, 81, 1855e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 81, 102, 94, 59, 59, 59, 59, 59, 61, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1856e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 1857e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 1858e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 43, 63, 36, 81, 81, 81, 87, 64, 86, 102, 58, 59, 59, 59, 59, 59, 1859e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1860e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1861e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 59, 59, 43, 33, 1862e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 58, 126, 126, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32, 32, 1863e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 1864e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 1865e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 61, 59, 59, 59, 58, 45, 58, 61, 59, 58, 58, 58, 61, 59, 59, 59, 59, 59, 1866e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 1867e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 1868e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 58, 95, 1869e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 45, 61, 59, 61, 59, 59, 59, 59, 59, 59, 59, 45, 58, 59, 59, 59, 59, 1870e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 61, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1871e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1872e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 58, 61, 59, 59, 59, 59, 59, 61, 59, 61, 46, 46, 32, 45, 45, 45, 1873e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 58, 45, 45, 46, 58, 59, 59, 59, 59, 59, 59, 61, 46, 32, 32, 32, 32, 1874e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 1875e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 58, 59, 59, 59, 59, 1876e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 59, 59, 59, 61, 59, 46, 32, 32, 46, 32, 46, 32, 58, 61, 59, 59, 1877e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 59, 59, 59, 59, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1878e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1879e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 45, 59, 59, 59, 59, 59, 59, 59, 59, 58, 32, 1880e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 58, 32, 1881e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 1882e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1883e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 46, 61, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 61, 1884e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 46, 61, 59, 59, 59, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1885e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 1886e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 1887e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 46, 61, 58, 59, 59, 59, 59, 1888e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1889e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1890e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 58, 59, 59, 59, 59, 59, 59, 59, 59, 46, 46, 32, 32, 32, 1891e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 45, 32, 32, 32, 32, 32, 1892e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 1893e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 32, 45, 61, 1894e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 1895e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 59, 58, 45, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1896e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1897e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45, 45, 32, 46, 32, 1898e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 61, 59, 58, 45, 45, 32, 32, 32, 1899e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1900e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1901e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1902e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 46, 32, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1903e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10 1904e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill }; 1905