Command.cpp revision 1bcc3d691fd1cb68abced62caf3024e2bb228561
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" 10b1f6ad82dd8d1702617a757a88430604b3131facXavier Ducrohet#include "Images.h" 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "XMLNode.h" 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 133b4062eeb01be33951ba214e027da523cf09f8b1Mathias Agopian#include <utils/Log.h> 143b4062eeb01be33951ba214e027da523cf09f8b1Mathias Agopian#include <utils/threads.h> 153b4062eeb01be33951ba214e027da523cf09f8b1Mathias Agopian#include <utils/List.h> 163b4062eeb01be33951ba214e027da523cf09f8b1Mathias Agopian#include <utils/Errors.h> 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <fcntl.h> 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <errno.h> 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectusing namespace android; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Show version info. All the cool kids do it. 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint doVersion(Bundle* bundle) 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getFileSpecCount() != 0) 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("(ignoring extra arguments)\n"); 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("Android Asset Packaging Tool, v0.2\n"); 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open the file read only. The call fails if the file doesn't exist. 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns NULL on failure. 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectZipFile* openReadOnly(const char* fileName) 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipFile* zip; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t result; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zip = new ZipFile; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = zip->open(fileName, ZipFile::kOpenReadOnly); 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result != NO_ERROR) { 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result == NAME_NOT_FOUND) 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: '%s' not found\n", fileName); 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (result == PERMISSION_DENIED) 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: '%s' access denied\n", fileName); 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: failed opening '%s' as Zip file\n", 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fileName); 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete zip; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return zip; 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open the file read-write. The file will be created if it doesn't 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * already exist and "okayToCreate" is set. 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns NULL on failure. 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectZipFile* openReadWrite(const char* fileName, bool okayToCreate) 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipFile* zip = NULL; 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t result; 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int flags; 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags = ZipFile::kOpenReadWrite; 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (okayToCreate) 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags |= ZipFile::kOpenCreate; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zip = new ZipFile; 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = zip->open(fileName, flags); 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result != NO_ERROR) { 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete zip; 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zip = NULL; 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbail: 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return zip; 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return a short string describing the compression method. 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst char* compressionName(int method) 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (method == ZipEntry::kCompressStored) 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "Stored"; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (method == ZipEntry::kCompressDeflated) 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "Deflated"; 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "Unknown"; 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the percent reduction in size (0% == no compression). 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint calcPercent(long uncompressedLen, long compressedLen) 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!uncompressedLen) 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (int) (100.0 - (compressedLen * 100.0) / uncompressedLen + 0.5); 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Handle the "list" command, which can be a simple file dump or 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a verbose listing. 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The verbose listing closely matches the output of the Info-ZIP "unzip" 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * command. 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint doList(Bundle* bundle) 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int result = 1; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipFile* zip = NULL; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ZipEntry* entry; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long totalUncLen, totalCompLen; 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* zipFileName; 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getFileSpecCount() != 1) { 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: specify zip file name (only)\n"); 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zipFileName = bundle->getFileSpecEntry(0); 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zip = openReadOnly(zipFileName); 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (zip == NULL) 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int count, i; 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getVerbose()) { 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("Archive: %s\n", zipFileName); 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf( 146fb2a9467ad77336edbf2a1a272dbe6ec30ef8a1bKenny Root " Length Method Size Ratio Offset Date Time CRC-32 Name\n"); 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf( 148fb2a9467ad77336edbf2a1a272dbe6ec30ef8a1bKenny Root "-------- ------ ------- ----- ------- ---- ---- ------ ----\n"); 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project totalUncLen = totalCompLen = 0; 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project count = zip->getNumEntries(); 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i = 0; i < count; i++) { 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project entry = zip->getEntryByIndex(i); 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getVerbose()) { 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char dateBuf[32]; 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project time_t when; 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project when = entry->getModWhen(); 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project strftime(dateBuf, sizeof(dateBuf), "%m-%d-%y %H:%M", 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project localtime(&when)); 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 164fb2a9467ad77336edbf2a1a272dbe6ec30ef8a1bKenny Root printf("%8ld %-7.7s %7ld %3d%% %8zd %s %08lx %s\n", 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (long) entry->getUncompressedLen(), 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project compressionName(entry->getCompressionMethod()), 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (long) entry->getCompressedLen(), 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calcPercent(entry->getUncompressedLen(), 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project entry->getCompressedLen()), 170fb2a9467ad77336edbf2a1a272dbe6ec30ef8a1bKenny Root (size_t) entry->getLFHOffset(), 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dateBuf, 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project entry->getCRC32(), 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project entry->getFileName()); 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("%s\n", entry->getFileName()); 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project totalUncLen += entry->getUncompressedLen(); 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project totalCompLen += entry->getCompressedLen(); 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getVerbose()) { 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf( 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "-------- ------- --- -------\n"); 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("%8ld %7ld %2d%% %d files\n", 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project totalUncLen, 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project totalCompLen, 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calcPercent(totalUncLen, totalCompLen), 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zip->getNumEntries()); 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getAndroidList()) { 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetManager assets; 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!assets.addAssetPath(String8(zipFileName), NULL)) { 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: list -a failed because assets could not be loaded\n"); 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1987ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable& res = assets.getResources(false); 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (&res == NULL) { 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("\nNo resource table found.\n"); 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 203f1ff21ac62a51f5ba8ca0821ea8a90f70957e25dSteve Block#ifndef HAVE_ANDROID_OS 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("\nResource table:\n"); 205e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn res.print(false); 206f1ff21ac62a51f5ba8ca0821ea8a90f70957e25dSteve Block#endif 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2087ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Asset* manifestAsset = assets.openNonAsset("AndroidManifest.xml", 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Asset::ACCESS_BUFFER); 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (manifestAsset == NULL) { 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("\nNo AndroidManifest.xml found.\n"); 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("\nAndroid manifest:\n"); 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResXMLTree tree; 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tree.setTo(manifestAsset->getBuffer(true), 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project manifestAsset->getLength()); 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printXMLBlock(&tree); 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete manifestAsset; 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2227ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = 0; 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbail: 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete zip; 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic ssize_t indexOfAttribute(const ResXMLTree& tree, uint32_t attrRes) 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t N = tree.getAttributeCount(); 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<N; i++) { 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tree.getAttributeNameResID(i) == attrRes) { 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (ssize_t)i; 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2411553c82e084ac5763fb393857224145506771b99Joe OnoratoString8 getAttribute(const ResXMLTree& tree, const char* ns, 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* attr, String8* outError) 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t idx = tree.indexOfAttribute(ns, attr); 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx < 0) { 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return String8(); 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Res_value value; 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value.dataType != Res_value::TYPE_STRING) { 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outError != NULL) *outError = "attribute is not a string value"; 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return String8(); 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t len; 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t* str = tree.getAttributeStringValue(idx, &len); 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return str ? String8(str, len) : String8(); 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic String8 getAttribute(const ResXMLTree& tree, uint32_t attrRes, String8* outError) 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t idx = indexOfAttribute(tree, attrRes); 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx < 0) { 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return String8(); 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Res_value value; 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value.dataType != Res_value::TYPE_STRING) { 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outError != NULL) *outError = "attribute is not a string value"; 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return String8(); 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t len; 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t* str = tree.getAttributeStringValue(idx, &len); 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return str ? String8(str, len) : String8(); 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 278bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackbornstatic int32_t getIntegerAttribute(const ResXMLTree& tree, uint32_t attrRes, 279bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn String8* outError, int32_t defValue = -1) 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t idx = indexOfAttribute(tree, attrRes); 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx < 0) { 283bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn return defValue; 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Res_value value; 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 287bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (value.dataType < Res_value::TYPE_FIRST_INT 288bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn || value.dataType > Res_value::TYPE_LAST_INT) { 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outError != NULL) *outError = "attribute is not an integer value"; 290bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn return defValue; 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return value.data; 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 296f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackbornstatic int32_t getResolvedIntegerAttribute(const ResTable* resTable, const ResXMLTree& tree, 297f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn uint32_t attrRes, String8* outError, int32_t defValue = -1) 298f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn{ 299f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn ssize_t idx = indexOfAttribute(tree, attrRes); 300f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn if (idx < 0) { 301f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn return defValue; 302f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn } 303f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn Res_value value; 304f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 305f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn if (value.dataType == Res_value::TYPE_REFERENCE) { 306f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn resTable->resolveReference(&value, 0); 307f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn } 308f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn if (value.dataType < Res_value::TYPE_FIRST_INT 309f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn || value.dataType > Res_value::TYPE_LAST_INT) { 310f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn if (outError != NULL) *outError = "attribute is not an integer value"; 311f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn return defValue; 312f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn } 313f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn } 314f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn return value.data; 315f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn} 316f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic String8 getResolvedAttribute(const ResTable* resTable, const ResXMLTree& tree, 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t attrRes, String8* outError) 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t idx = indexOfAttribute(tree, attrRes); 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx < 0) { 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return String8(); 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Res_value value; 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value.dataType == Res_value::TYPE_STRING) { 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t len; 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t* str = tree.getAttributeStringValue(idx, &len); 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return str ? String8(str, len) : String8(); 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resTable->resolveReference(&value, 0); 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value.dataType != Res_value::TYPE_STRING) { 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outError != NULL) *outError = "attribute is not a string value"; 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return String8(); 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t len; 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Res_value* value2 = &value; 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* str = const_cast<ResTable*>(resTable)->valueToString(value2, 0, NULL, &len); 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return str ? String8(str, len) : String8(); 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// These are attribute resource constants for the platform, as found 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// in android.R.attr 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectenum { 346f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn LABEL_ATTR = 0x01010001, 347f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn ICON_ATTR = 0x01010002, 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NAME_ATTR = 0x01010003, 349b6ec11ef372a498c4d5fd2317a015b808495a2edDan Morrill DEBUGGABLE_ATTR = 0x0101000f, 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project VERSION_CODE_ATTR = 0x0101021b, 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project VERSION_NAME_ATTR = 0x0101021c, 352f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn SCREEN_ORIENTATION_ATTR = 0x0101001e, 353bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn MIN_SDK_VERSION_ATTR = 0x0101020c, 35475c498426a17b47d445711bb9e36794b05876a56Suchi Amalapurapu MAX_SDK_VERSION_ATTR = 0x01010271, 355bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn REQ_TOUCH_SCREEN_ATTR = 0x01010227, 356bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn REQ_KEYBOARD_TYPE_ATTR = 0x01010228, 357bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn REQ_HARD_KEYBOARD_ATTR = 0x01010229, 358bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn REQ_NAVIGATION_ATTR = 0x0101022a, 359bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn REQ_FIVE_WAY_NAV_ATTR = 0x01010232, 360bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn TARGET_SDK_VERSION_ATTR = 0x01010270, 361bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn TEST_ONLY_ATTR = 0x01010272, 362a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn ANY_DENSITY_ATTR = 0x0101026c, 363e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn GL_ES_VERSION_ATTR = 0x01010281, 364723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn SMALL_SCREEN_ATTR = 0x01010284, 365723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn NORMAL_SCREEN_ATTR = 0x01010285, 366723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn LARGE_SCREEN_ATTR = 0x01010286, 367f43489d7d5e1c0c5c9a7e54c22845fcb99765f81Dianne Hackborn XLARGE_SCREEN_ATTR = 0x010102bf, 368e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn REQUIRED_ATTR = 0x0101028e, 369a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn SCREEN_SIZE_ATTR = 0x010102ca, 370a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn SCREEN_DENSITY_ATTR = 0x010102cb, 371e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn REQUIRES_SMALLEST_WIDTH_DP_ATTR = 0x01010364, 372e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn COMPATIBLE_WIDTH_LIMIT_DP_ATTR = 0x01010365, 373e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn LARGEST_WIDTH_LIMIT_DP_ATTR = 0x01010366, 37456088a55ca6c9277f09040a7883117cb127e1e56Kenny Root PUBLIC_KEY_ATTR = 0x010103a6, 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3777ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapuconst char *getComponentName(String8 &pkgName, String8 &componentName) { 3787ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu ssize_t idx = componentName.find("."); 3797ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu String8 retStr(pkgName); 3807ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu if (idx == 0) { 3817ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu retStr += componentName; 3827ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } else if (idx < 0) { 3837ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu retStr += "."; 3847ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu retStr += componentName; 3857ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } else { 3867ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu return componentName.string(); 3877ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } 3887ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu return retStr.string(); 3897ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu} 3907ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 391a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackbornstatic void printCompatibleScreens(ResXMLTree& tree) { 392a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn size_t len; 393a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn ResXMLTree::event_code_t code; 394a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn int depth = 0; 395a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn bool first = true; 396a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn printf("compatible-screens:"); 397a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 398a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn if (code == ResXMLTree::END_TAG) { 399a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn depth--; 400a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn if (depth < 0) { 401a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn break; 402a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn } 403a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn continue; 404a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn } 405a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn if (code != ResXMLTree::START_TAG) { 406a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn continue; 407a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn } 408a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn depth++; 409a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn String8 tag(tree.getElementName(&len)); 410a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn if (tag == "screen") { 411a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn int32_t screenSize = getIntegerAttribute(tree, 412a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn SCREEN_SIZE_ATTR, NULL, -1); 413a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn int32_t screenDensity = getIntegerAttribute(tree, 414a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn SCREEN_DENSITY_ATTR, NULL, -1); 415a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn if (screenSize > 0 && screenDensity > 0) { 416a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn if (!first) { 417a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn printf(","); 418a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn } 419a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn first = false; 420a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn printf("'%d/%d'", screenSize, screenDensity); 421a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn } 422a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn } 423a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn } 424a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn printf("\n"); 425a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn} 426a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Handle the "dump" command, to extract select data from an archive. 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 430e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrillextern char CONSOLE_DATA[2925]; // see EOF 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint doDump(Bundle* bundle) 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t result = UNKNOWN_ERROR; 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Asset* asset = NULL; 4357ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getFileSpecCount() < 1) { 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: no dump option specified\n"); 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 1; 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4407ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getFileSpecCount() < 2) { 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: no dump file specified\n"); 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 1; 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4457ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* option = bundle->getFileSpecEntry(0); 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* filename = bundle->getFileSpecEntry(1); 4487ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetManager assets; 450bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn void* assetsCookie; 451bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (!assets.addAssetPath(String8(filename), &assetsCookie)) { 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: dump failed because assets could not be loaded\n"); 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 1; 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4557ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 456e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn // Make a dummy config for retrieving resources... we need to supply 457e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn // non-default values for some configs so that we can retrieve resources 458e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn // in the app that don't have a default. The most important of these is 459e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn // the API version because key resources like icons will have an implicit 460e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn // version if they are using newer config types like density. 461e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn ResTable_config config; 462e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn config.language[0] = 'e'; 463e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn config.language[1] = 'n'; 464e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn config.country[0] = 'U'; 465e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn config.country[1] = 'S'; 466e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn config.orientation = ResTable_config::ORIENTATION_PORT; 467e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn config.density = ResTable_config::DENSITY_MEDIUM; 468e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn config.sdkVersion = 10000; // Very high. 469e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn config.screenWidthDp = 320; 470e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn config.screenHeightDp = 480; 471e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn config.smallestScreenWidthDp = 320; 472e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn assets.setConfiguration(config); 473e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable& res = assets.getResources(false); 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (&res == NULL) { 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: dump failed because no resource table was found\n"); 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4797ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (strcmp("resources", option) == 0) { 481f1ff21ac62a51f5ba8ca0821ea8a90f70957e25dSteve Block#ifndef HAVE_ANDROID_OS 482e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn res.print(bundle->getValues()); 483f1ff21ac62a51f5ba8ca0821ea8a90f70957e25dSteve Block#endif 4846c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 4856c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } else if (strcmp("strings", option) == 0) { 4866c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const ResStringPool* pool = res.getTableStringBlock(0); 4876c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn printStringPool(pool); 4886c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (strcmp("xmltree", option) == 0) { 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getFileSpecCount() < 3) { 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: no dump xmltree resource file specified\n"); 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4947ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=2; i<bundle->getFileSpecCount(); i++) { 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* resname = bundle->getFileSpecEntry(i); 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResXMLTree tree; 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project asset = assets.openNonAsset(resname, Asset::ACCESS_BUFFER); 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (asset == NULL) { 50044b283dc27ed8ba5a946d809489f29b4ae88cb15Kenny Root fprintf(stderr, "ERROR: dump failed because resource %s found\n", resname); 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5037ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tree.setTo(asset->getBuffer(true), 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project asset->getLength()) != NO_ERROR) { 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: Resource %s is corrupt\n", resname); 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tree.restart(); 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printXMLBlock(&tree); 51119138468caf7050d482dc15f35a344eab11bb756Kenny Root tree.uninit(); 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete asset; 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project asset = NULL; 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5157ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (strcmp("xmlstrings", option) == 0) { 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getFileSpecCount() < 3) { 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: no dump xmltree resource file specified\n"); 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5217ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=2; i<bundle->getFileSpecCount(); i++) { 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* resname = bundle->getFileSpecEntry(i); 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResXMLTree tree; 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project asset = assets.openNonAsset(resname, Asset::ACCESS_BUFFER); 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (asset == NULL) { 52744b283dc27ed8ba5a946d809489f29b4ae88cb15Kenny Root fprintf(stderr, "ERROR: dump failed because resource %s found\n", resname); 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5307ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tree.setTo(asset->getBuffer(true), 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project asset->getLength()) != NO_ERROR) { 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: Resource %s is corrupt\n", resname); 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printStringPool(&tree.getStrings()); 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete asset; 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project asset = NULL; 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5407ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResXMLTree tree; 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project asset = assets.openNonAsset("AndroidManifest.xml", 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Asset::ACCESS_BUFFER); 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (asset == NULL) { 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: dump failed because no AndroidManifest.xml found\n"); 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5497ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tree.setTo(asset->getBuffer(true), 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project asset->getLength()) != NO_ERROR) { 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: AndroidManifest.xml is corrupt\n"); 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tree.restart(); 5567ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (strcmp("permissions", option) == 0) { 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t len; 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResXMLTree::event_code_t code; 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int depth = 0; 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (code == ResXMLTree::END_TAG) { 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project depth--; 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (code != ResXMLTree::START_TAG) { 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project depth++; 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 tag(tree.getElementName(&len)); 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Depth %d tag %s\n", depth, tag.string()); 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (depth == 1) { 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tag != "manifest") { 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: manifest does not start with <manifest> tag\n"); 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 pkg = getAttribute(tree, NULL, "package", NULL); 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("package: %s\n", pkg.string()); 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (depth == 2 && tag == "permission") { 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 error; 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 name = getAttribute(tree, NAME_ATTR, &error); 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (error != "") { 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: %s\n", error.string()); 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("permission: %s\n", name.string()); 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (depth == 2 && tag == "uses-permission") { 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 error; 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 name = getAttribute(tree, NAME_ATTR, &error); 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (error != "") { 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: %s\n", error.string()); 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("uses-permission: %s\n", name.string()); 5951bcc3d691fd1cb68abced62caf3024e2bb228561Nick Kralevich int req = getIntegerAttribute(tree, REQUIRED_ATTR, NULL, 1); 5961bcc3d691fd1cb68abced62caf3024e2bb228561Nick Kralevich if (!req) { 5971bcc3d691fd1cb68abced62caf3024e2bb228561Nick Kralevich printf("optional-permission: %s\n", name.string()); 5981bcc3d691fd1cb68abced62caf3024e2bb228561Nick Kralevich } 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (strcmp("badging", option) == 0) { 602e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn Vector<String8> locales; 603e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn res.getLocales(&locales); 604e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn 605e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn Vector<ResTable_config> configs; 606e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn res.getConfigurations(&configs); 607e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn SortedVector<int> densities; 608e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn const size_t NC = configs.size(); 609e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn for (size_t i=0; i<NC; i++) { 610e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn int dens = configs[i].density; 611e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn if (dens == 0) dens = 160; 612e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn densities.add(dens); 613e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 614e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t len; 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResXMLTree::event_code_t code; 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int depth = 0; 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 error; 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool withinActivity = false; 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool isMainActivity = false; 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool isLauncherActivity = false; 6221b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool isSearchable = false; 6237ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu bool withinApplication = false; 6247ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu bool withinReceiver = false; 6251b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool withinService = false; 6261b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool withinIntentFilter = false; 6271b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool hasMainActivity = false; 6281b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool hasOtherActivities = false; 6291b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool hasOtherReceivers = false; 6301b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool hasOtherServices = false; 6311b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool hasWallpaperService = false; 6321b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool hasImeService = false; 6331b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool hasWidgetReceivers = false; 6341b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool hasIntentFilter = false; 6351b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool actMainActivity = false; 6361b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool actWidgetReceivers = false; 6371b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool actImeService = false; 6381b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu bool actWallpaperService = false; 63989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill 640063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root // These two implement the implicit permissions that are granted 641063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root // to pre-1.6 applications. 642063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root bool hasWriteExternalStoragePermission = false; 643063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root bool hasReadPhoneStatePermission = false; 644063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root 6457924512aa12c6af37d90e8ccfcdf04eb78a294a3Dianne Hackborn // If an app requests write storage, they will also get read storage. 6467924512aa12c6af37d90e8ccfcdf04eb78a294a3Dianne Hackborn bool hasReadExternalStoragePermission = false; 6477924512aa12c6af37d90e8ccfcdf04eb78a294a3Dianne Hackborn 64831b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn // Implement transition to read and write call log. 64931b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn bool hasReadContactsPermission = false; 65031b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn bool hasWriteContactsPermission = false; 65131b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn bool hasReadCallLogPermission = false; 65231b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn bool hasWriteCallLogPermission = false; 65331b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn 65489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // This next group of variables is used to implement a group of 65589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // backward-compatibility heuristics necessitated by the addition of 65689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // some new uses-feature constants in 2.1 and 2.2. In most cases, the 65789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // heuristic is "if an app requests a permission but doesn't explicitly 65889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // request the corresponding <uses-feature>, presume it's there anyway". 65989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool specCameraFeature = false; // camera-related 66089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool specCameraAutofocusFeature = false; 66189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool reqCameraAutofocusFeature = false; 66289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool reqCameraFlashFeature = false; 663e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn bool hasCameraPermission = false; 66489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool specLocationFeature = false; // location-related 66589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool specNetworkLocFeature = false; 66689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool reqNetworkLocFeature = false; 667ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn bool specGpsFeature = false; 66889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool reqGpsFeature = false; 66989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool hasMockLocPermission = false; 67089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool hasCoarseLocPermission = false; 671ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn bool hasGpsPermission = false; 67289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool hasGeneralLocPermission = false; 67389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool specBluetoothFeature = false; // Bluetooth API-related 67489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool hasBluetoothPermission = false; 67589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool specMicrophoneFeature = false; // microphone-related 67689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool hasRecordAudioPermission = false; 67789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool specWiFiFeature = false; 67889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool hasWiFiPermission = false; 67989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool specTelephonyFeature = false; // telephony-related 68089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool reqTelephonySubFeature = false; 68189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool hasTelephonyPermission = false; 68289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool specTouchscreenFeature = false; // touchscreen-related 68389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool specMultitouchFeature = false; 68489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill bool reqDistinctMultitouchFeature = false; 685e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn bool specScreenPortraitFeature = false; 686e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn bool specScreenLandscapeFeature = false; 687f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn bool reqScreenPortraitFeature = false; 688f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn bool reqScreenLandscapeFeature = false; 68989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // 2.2 also added some other features that apps can request, but that 69089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // have no corresponding permission, so we cannot implement any 69189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // back-compatibility heuristic for them. The below are thus unnecessary 69289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // (but are retained here for documentary purposes.) 69389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill //bool specCompassFeature = false; 69489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill //bool specAccelerometerFeature = false; 69589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill //bool specProximityFeature = false; 69689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill //bool specAmbientLightFeature = false; 69789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill //bool specLiveWallpaperFeature = false; 69889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill 699723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn int targetSdk = 0; 700723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn int smallScreen = 1; 701723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn int normalScreen = 1; 702723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn int largeScreen = 1; 703f43489d7d5e1c0c5c9a7e54c22845fcb99765f81Dianne Hackborn int xlargeScreen = 1; 704a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn int anyDensity = 1; 705e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn int requiresSmallestWidthDp = 0; 706e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn int compatibleWidthLimitDp = 0; 707e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn int largestWidthLimitDp = 0; 7087ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu String8 pkg; 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 activityName; 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 activityLabel; 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 activityIcon; 7127ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu String8 receiverName; 7131b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu String8 serviceName; 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (code == ResXMLTree::END_TAG) { 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project depth--; 7171b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (depth < 2) { 7181b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu withinApplication = false; 7191b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } else if (depth < 3) { 7201b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (withinActivity && isMainActivity && isLauncherActivity) { 7211b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu const char *aName = getComponentName(pkg, activityName); 722e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn printf("launchable-activity:"); 7231b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (aName != NULL) { 724e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn printf(" name='%s' ", aName); 7251b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 726e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn printf(" label='%s' icon='%s'\n", 7271b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu activityLabel.string(), 7281b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu activityIcon.string()); 7291b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 7301b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (!hasIntentFilter) { 7311b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu hasOtherActivities |= withinActivity; 7321b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu hasOtherReceivers |= withinReceiver; 7331b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu hasOtherServices |= withinService; 7341b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 7351b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu withinActivity = false; 7361b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu withinService = false; 7371b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu withinReceiver = false; 7381b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu hasIntentFilter = false; 7391b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu isMainActivity = isLauncherActivity = false; 7401b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } else if (depth < 4) { 7411b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (withinIntentFilter) { 7421b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (withinActivity) { 7431b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu hasMainActivity |= actMainActivity; 7441b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu hasOtherActivities |= !actMainActivity; 7451b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } else if (withinReceiver) { 7461b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu hasWidgetReceivers |= actWidgetReceivers; 7471b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu hasOtherReceivers |= !actWidgetReceivers; 7481b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } else if (withinService) { 7491b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu hasImeService |= actImeService; 7501b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu hasWallpaperService |= actWallpaperService; 7511b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu hasOtherServices |= (!actImeService && !actWallpaperService); 7521b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 7531b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 7541b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu withinIntentFilter = false; 7551b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (code != ResXMLTree::START_TAG) { 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project depth++; 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 tag(tree.getElementName(&len)); 7631b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu //printf("Depth %d, %s\n", depth, tag.string()); 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (depth == 1) { 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tag != "manifest") { 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: manifest does not start with <manifest> tag\n"); 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7697ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu pkg = getAttribute(tree, NULL, "package", NULL); 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("package: name='%s' ", pkg.string()); 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t versionCode = getIntegerAttribute(tree, VERSION_CODE_ATTR, &error); 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (error != "") { 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR getting 'android:versionCode' attribute: %s\n", error.string()); 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (versionCode > 0) { 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("versionCode='%d' ", versionCode); 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("versionCode='' "); 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 781cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn String8 versionName = getResolvedAttribute(&res, tree, VERSION_NAME_ATTR, &error); 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (error != "") { 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR getting 'android:versionName' attribute: %s\n", error.string()); 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("versionName='%s'\n", versionName.string()); 7877ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } else if (depth == 2) { 7887ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu withinApplication = false; 7897ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu if (tag == "application") { 7907ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu withinApplication = true; 791e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn 792e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn String8 label; 793e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn const size_t NL = locales.size(); 794e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn for (size_t i=0; i<NL; i++) { 795e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn const char* localeStr = locales[i].string(); 796e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn assets.setLocale(localeStr != NULL ? localeStr : ""); 797e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn String8 llabel = getResolvedAttribute(&res, tree, LABEL_ATTR, &error); 798e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn if (llabel != "") { 799e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn if (localeStr == NULL || strlen(localeStr) == 0) { 800e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn label = llabel; 801e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn printf("application-label:'%s'\n", llabel.string()); 802e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } else { 803e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn if (label == "") { 804e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn label = llabel; 805e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 806e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn printf("application-label-%s:'%s'\n", localeStr, 807e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn llabel.string()); 808e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 809e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 8107ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } 811e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn 812e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn ResTable_config tmpConfig = config; 813e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn const size_t ND = densities.size(); 814e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn for (size_t i=0; i<ND; i++) { 815e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn tmpConfig.density = densities[i]; 816e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn assets.setConfiguration(tmpConfig); 817e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn String8 icon = getResolvedAttribute(&res, tree, ICON_ATTR, &error); 818e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn if (icon != "") { 819e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn printf("application-icon-%d:'%s'\n", densities[i], icon.string()); 820e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 821e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 822e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn assets.setConfiguration(config); 823e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn 8247ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu String8 icon = getResolvedAttribute(&res, tree, ICON_ATTR, &error); 8257ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu if (error != "") { 8267ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n", error.string()); 8277ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu goto bail; 8287ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } 829bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn int32_t testOnly = getIntegerAttribute(tree, TEST_ONLY_ATTR, &error, 0); 8307ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu if (error != "") { 831bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn fprintf(stderr, "ERROR getting 'android:testOnly' attribute: %s\n", error.string()); 8327ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu goto bail; 8337ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } 834e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn printf("application: label='%s' ", label.string()); 835e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn printf("icon='%s'\n", icon.string()); 836bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (testOnly != 0) { 837bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn printf("testOnly='%d'\n", testOnly); 838bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } 839b6ec11ef372a498c4d5fd2317a015b808495a2edDan Morrill 840b6ec11ef372a498c4d5fd2317a015b808495a2edDan Morrill int32_t debuggable = getResolvedIntegerAttribute(&res, tree, DEBUGGABLE_ATTR, &error, 0); 841b6ec11ef372a498c4d5fd2317a015b808495a2edDan Morrill if (error != "") { 842b6ec11ef372a498c4d5fd2317a015b808495a2edDan Morrill fprintf(stderr, "ERROR getting 'android:debuggable' attribute: %s\n", error.string()); 843b6ec11ef372a498c4d5fd2317a015b808495a2edDan Morrill goto bail; 844b6ec11ef372a498c4d5fd2317a015b808495a2edDan Morrill } 845b6ec11ef372a498c4d5fd2317a015b808495a2edDan Morrill if (debuggable != 0) { 846b6ec11ef372a498c4d5fd2317a015b808495a2edDan Morrill printf("application-debuggable\n"); 847b6ec11ef372a498c4d5fd2317a015b808495a2edDan Morrill } 848bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } else if (tag == "uses-sdk") { 849bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn int32_t code = getIntegerAttribute(tree, MIN_SDK_VERSION_ATTR, &error); 850bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (error != "") { 851bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn error = ""; 852bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn String8 name = getResolvedAttribute(&res, tree, MIN_SDK_VERSION_ATTR, &error); 853bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (error != "") { 854bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn fprintf(stderr, "ERROR getting 'android:minSdkVersion' attribute: %s\n", 855bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn error.string()); 856bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn goto bail; 857bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } 858723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn if (name == "Donut") targetSdk = 4; 859bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn printf("sdkVersion:'%s'\n", name.string()); 860bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } else if (code != -1) { 861723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn targetSdk = code; 862bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn printf("sdkVersion:'%d'\n", code); 863bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } 86475c498426a17b47d445711bb9e36794b05876a56Suchi Amalapurapu code = getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR, NULL, -1); 86575c498426a17b47d445711bb9e36794b05876a56Suchi Amalapurapu if (code != -1) { 86675c498426a17b47d445711bb9e36794b05876a56Suchi Amalapurapu printf("maxSdkVersion:'%d'\n", code); 86775c498426a17b47d445711bb9e36794b05876a56Suchi Amalapurapu } 868bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn code = getIntegerAttribute(tree, TARGET_SDK_VERSION_ATTR, &error); 869bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (error != "") { 870bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn error = ""; 871bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn String8 name = getResolvedAttribute(&res, tree, TARGET_SDK_VERSION_ATTR, &error); 872bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (error != "") { 873bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn fprintf(stderr, "ERROR getting 'android:targetSdkVersion' attribute: %s\n", 874bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn error.string()); 875bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn goto bail; 876bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } 877723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn if (name == "Donut" && targetSdk < 4) targetSdk = 4; 878bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn printf("targetSdkVersion:'%s'\n", name.string()); 879bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } else if (code != -1) { 880723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn if (targetSdk < code) { 881723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn targetSdk = code; 882723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn } 883bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn printf("targetSdkVersion:'%d'\n", code); 884bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } 885bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } else if (tag == "uses-configuration") { 886bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn int32_t reqTouchScreen = getIntegerAttribute(tree, 887bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn REQ_TOUCH_SCREEN_ATTR, NULL, 0); 888bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn int32_t reqKeyboardType = getIntegerAttribute(tree, 889bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn REQ_KEYBOARD_TYPE_ATTR, NULL, 0); 890bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn int32_t reqHardKeyboard = getIntegerAttribute(tree, 891bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn REQ_HARD_KEYBOARD_ATTR, NULL, 0); 892bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn int32_t reqNavigation = getIntegerAttribute(tree, 893bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn REQ_NAVIGATION_ATTR, NULL, 0); 894bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn int32_t reqFiveWayNav = getIntegerAttribute(tree, 895bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn REQ_FIVE_WAY_NAV_ATTR, NULL, 0); 896cb2d50d0d6e2e37ae02b014999da23ecd32038b8Dianne Hackborn printf("uses-configuration:"); 897bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (reqTouchScreen != 0) { 898bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn printf(" reqTouchScreen='%d'", reqTouchScreen); 899bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } 900bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (reqKeyboardType != 0) { 901bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn printf(" reqKeyboardType='%d'", reqKeyboardType); 902bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } 903bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (reqHardKeyboard != 0) { 904bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn printf(" reqHardKeyboard='%d'", reqHardKeyboard); 905bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } 906bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (reqNavigation != 0) { 907bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn printf(" reqNavigation='%d'", reqNavigation); 9087ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } 909bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (reqFiveWayNav != 0) { 910bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn printf(" reqFiveWayNav='%d'", reqFiveWayNav); 911bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } 912bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn printf("\n"); 913723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn } else if (tag == "supports-screens") { 914723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn smallScreen = getIntegerAttribute(tree, 915723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn SMALL_SCREEN_ATTR, NULL, 1); 916723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn normalScreen = getIntegerAttribute(tree, 917723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn NORMAL_SCREEN_ATTR, NULL, 1); 918723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn largeScreen = getIntegerAttribute(tree, 919723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn LARGE_SCREEN_ATTR, NULL, 1); 920f43489d7d5e1c0c5c9a7e54c22845fcb99765f81Dianne Hackborn xlargeScreen = getIntegerAttribute(tree, 921f43489d7d5e1c0c5c9a7e54c22845fcb99765f81Dianne Hackborn XLARGE_SCREEN_ATTR, NULL, 1); 922a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn anyDensity = getIntegerAttribute(tree, 923a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn ANY_DENSITY_ATTR, NULL, 1); 924e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn requiresSmallestWidthDp = getIntegerAttribute(tree, 925e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn REQUIRES_SMALLEST_WIDTH_DP_ATTR, NULL, 0); 926e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn compatibleWidthLimitDp = getIntegerAttribute(tree, 927e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn COMPATIBLE_WIDTH_LIMIT_DP_ATTR, NULL, 0); 928e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn largestWidthLimitDp = getIntegerAttribute(tree, 929e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn LARGEST_WIDTH_LIMIT_DP_ATTR, NULL, 0); 930e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn } else if (tag == "uses-feature") { 931e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn String8 name = getAttribute(tree, NAME_ATTR, &error); 93240b94725dc1c62ea66db0b9502dd81b97dd3e35fSuchi Amalapurapu 93340b94725dc1c62ea66db0b9502dd81b97dd3e35fSuchi Amalapurapu if (name != "" && error == "") { 934e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn int req = getIntegerAttribute(tree, 935e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn REQUIRED_ATTR, NULL, 1); 93689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill 937e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn if (name == "android.hardware.camera") { 938e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn specCameraFeature = true; 93989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.hardware.camera.autofocus") { 94089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // these have no corresponding permission to check for, 94189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // but should imply the foundational camera permission 94289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill reqCameraAutofocusFeature = reqCameraAutofocusFeature || req; 94389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill specCameraAutofocusFeature = true; 94489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (req && (name == "android.hardware.camera.flash")) { 94589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // these have no corresponding permission to check for, 94689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // but should imply the foundational camera permission 94789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill reqCameraFlashFeature = true; 94889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.hardware.location") { 94989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill specLocationFeature = true; 95089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.hardware.location.network") { 95189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill specNetworkLocFeature = true; 95289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill reqNetworkLocFeature = reqNetworkLocFeature || req; 953ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn } else if (name == "android.hardware.location.gps") { 954ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn specGpsFeature = true; 95589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill reqGpsFeature = reqGpsFeature || req; 95689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.hardware.bluetooth") { 95789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill specBluetoothFeature = true; 95889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.hardware.touchscreen") { 95989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill specTouchscreenFeature = true; 96089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.hardware.touchscreen.multitouch") { 96189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill specMultitouchFeature = true; 96289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.hardware.touchscreen.multitouch.distinct") { 96389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill reqDistinctMultitouchFeature = reqDistinctMultitouchFeature || req; 96489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.hardware.microphone") { 96589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill specMicrophoneFeature = true; 96689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.hardware.wifi") { 96789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill specWiFiFeature = true; 96889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.hardware.telephony") { 96989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill specTelephonyFeature = true; 97089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (req && (name == "android.hardware.telephony.gsm" || 97189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.hardware.telephony.cdma")) { 97289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // these have no corresponding permission to check for, 97389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // but should imply the foundational telephony permission 97489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill reqTelephonySubFeature = true; 975e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } else if (name == "android.hardware.screen.portrait") { 976e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn specScreenPortraitFeature = true; 977e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } else if (name == "android.hardware.screen.landscape") { 978e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn specScreenLandscapeFeature = true; 979e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn } 980e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn printf("uses-feature%s:'%s'\n", 981e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn req ? "" : "-not-required", name.string()); 982e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn } else { 983e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn int vers = getIntegerAttribute(tree, 984e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn GL_ES_VERSION_ATTR, &error); 985e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn if (error == "") { 986e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn printf("uses-gl-es:'0x%x'\n", vers); 987e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn } 988e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn } 989e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn } else if (tag == "uses-permission") { 990e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn String8 name = getAttribute(tree, NAME_ATTR, &error); 99140b94725dc1c62ea66db0b9502dd81b97dd3e35fSuchi Amalapurapu if (name != "" && error == "") { 992e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn if (name == "android.permission.CAMERA") { 993e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn hasCameraPermission = true; 994ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn } else if (name == "android.permission.ACCESS_FINE_LOCATION") { 995ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn hasGpsPermission = true; 99689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.permission.ACCESS_MOCK_LOCATION") { 99789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill hasMockLocPermission = true; 99889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.permission.ACCESS_COARSE_LOCATION") { 99989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill hasCoarseLocPermission = true; 100089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" || 100189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.permission.INSTALL_LOCATION_PROVIDER") { 100289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill hasGeneralLocPermission = true; 100389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.permission.BLUETOOTH" || 100489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.permission.BLUETOOTH_ADMIN") { 100589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill hasBluetoothPermission = true; 100689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.permission.RECORD_AUDIO") { 100789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill hasRecordAudioPermission = true; 100889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.permission.ACCESS_WIFI_STATE" || 100989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.permission.CHANGE_WIFI_STATE" || 101089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.permission.CHANGE_WIFI_MULTICAST_STATE") { 101189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill hasWiFiPermission = true; 101289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (name == "android.permission.CALL_PHONE" || 101389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.permission.CALL_PRIVILEGED" || 101489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.permission.MODIFY_PHONE_STATE" || 101589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.permission.PROCESS_OUTGOING_CALLS" || 101689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.permission.READ_SMS" || 101789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.permission.RECEIVE_SMS" || 101889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.permission.RECEIVE_MMS" || 101989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.permission.RECEIVE_WAP_PUSH" || 102089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.permission.SEND_SMS" || 102189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.permission.WRITE_APN_SETTINGS" || 102289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill name == "android.permission.WRITE_SMS") { 102389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill hasTelephonyPermission = true; 1024063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root } else if (name == "android.permission.WRITE_EXTERNAL_STORAGE") { 1025063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root hasWriteExternalStoragePermission = true; 10267924512aa12c6af37d90e8ccfcdf04eb78a294a3Dianne Hackborn } else if (name == "android.permission.READ_EXTERNAL_STORAGE") { 10277924512aa12c6af37d90e8ccfcdf04eb78a294a3Dianne Hackborn hasReadExternalStoragePermission = true; 1028063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root } else if (name == "android.permission.READ_PHONE_STATE") { 1029063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root hasReadPhoneStatePermission = true; 103031b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn } else if (name == "android.permission.READ_CONTACTS") { 103131b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn hasReadContactsPermission = true; 103231b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn } else if (name == "android.permission.WRITE_CONTACTS") { 103331b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn hasWriteContactsPermission = true; 103431b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn } else if (name == "android.permission.READ_CALL_LOG") { 103531b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn hasReadCallLogPermission = true; 103631b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn } else if (name == "android.permission.WRITE_CALL_LOG") { 103731b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn hasWriteCallLogPermission = true; 1038e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn } 1039e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn printf("uses-permission:'%s'\n", name.string()); 10401bcc3d691fd1cb68abced62caf3024e2bb228561Nick Kralevich int req = getIntegerAttribute(tree, REQUIRED_ATTR, NULL, 1); 10411bcc3d691fd1cb68abced62caf3024e2bb228561Nick Kralevich if (!req) { 10421bcc3d691fd1cb68abced62caf3024e2bb228561Nick Kralevich printf("optional-permission:'%s'\n", name.string()); 10431bcc3d691fd1cb68abced62caf3024e2bb228561Nick Kralevich } 1044e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn } else { 1045e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1046e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn error.string()); 1047e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn goto bail; 1048e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn } 104943b6803095e41e6a1cf844a77813c6cdbdc84ec3Dianne Hackborn } else if (tag == "uses-package") { 105043b6803095e41e6a1cf844a77813c6cdbdc84ec3Dianne Hackborn String8 name = getAttribute(tree, NAME_ATTR, &error); 105143b6803095e41e6a1cf844a77813c6cdbdc84ec3Dianne Hackborn if (name != "" && error == "") { 105243b6803095e41e6a1cf844a77813c6cdbdc84ec3Dianne Hackborn printf("uses-package:'%s'\n", name.string()); 105343b6803095e41e6a1cf844a77813c6cdbdc84ec3Dianne Hackborn } else { 105443b6803095e41e6a1cf844a77813c6cdbdc84ec3Dianne Hackborn fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 105543b6803095e41e6a1cf844a77813c6cdbdc84ec3Dianne Hackborn error.string()); 105643b6803095e41e6a1cf844a77813c6cdbdc84ec3Dianne Hackborn goto bail; 105743b6803095e41e6a1cf844a77813c6cdbdc84ec3Dianne Hackborn } 1058e2c17f9174144a6eca3fdbed8d5d1370f318f549Jeff Hamilton } else if (tag == "original-package") { 1059e2c17f9174144a6eca3fdbed8d5d1370f318f549Jeff Hamilton String8 name = getAttribute(tree, NAME_ATTR, &error); 1060e2c17f9174144a6eca3fdbed8d5d1370f318f549Jeff Hamilton if (name != "" && error == "") { 1061e2c17f9174144a6eca3fdbed8d5d1370f318f549Jeff Hamilton printf("original-package:'%s'\n", name.string()); 1062e2c17f9174144a6eca3fdbed8d5d1370f318f549Jeff Hamilton } else { 1063e2c17f9174144a6eca3fdbed8d5d1370f318f549Jeff Hamilton fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1064e2c17f9174144a6eca3fdbed8d5d1370f318f549Jeff Hamilton error.string()); 1065e2c17f9174144a6eca3fdbed8d5d1370f318f549Jeff Hamilton goto bail; 1066e2c17f9174144a6eca3fdbed8d5d1370f318f549Jeff Hamilton } 1067096b67f65510a5076f1f845f9e19dda2b30ea6bbDan Morrill } else if (tag == "supports-gl-texture") { 10686f51fc14d0c3df8f9153ae5df992cc2731f099c8Dan Morrill String8 name = getAttribute(tree, NAME_ATTR, &error); 10696f51fc14d0c3df8f9153ae5df992cc2731f099c8Dan Morrill if (name != "" && error == "") { 1070096b67f65510a5076f1f845f9e19dda2b30ea6bbDan Morrill printf("supports-gl-texture:'%s'\n", name.string()); 10716f51fc14d0c3df8f9153ae5df992cc2731f099c8Dan Morrill } else { 10726f51fc14d0c3df8f9153ae5df992cc2731f099c8Dan Morrill fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 10736f51fc14d0c3df8f9153ae5df992cc2731f099c8Dan Morrill error.string()); 10746f51fc14d0c3df8f9153ae5df992cc2731f099c8Dan Morrill goto bail; 10756f51fc14d0c3df8f9153ae5df992cc2731f099c8Dan Morrill } 1076a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn } else if (tag == "compatible-screens") { 1077a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn printCompatibleScreens(tree); 1078a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn depth--; 107956088a55ca6c9277f09040a7883117cb127e1e56Kenny Root } else if (tag == "package-verifier") { 108056088a55ca6c9277f09040a7883117cb127e1e56Kenny Root String8 name = getAttribute(tree, NAME_ATTR, &error); 108156088a55ca6c9277f09040a7883117cb127e1e56Kenny Root if (name != "" && error == "") { 108256088a55ca6c9277f09040a7883117cb127e1e56Kenny Root String8 publicKey = getAttribute(tree, PUBLIC_KEY_ATTR, &error); 108356088a55ca6c9277f09040a7883117cb127e1e56Kenny Root if (publicKey != "" && error == "") { 108456088a55ca6c9277f09040a7883117cb127e1e56Kenny Root printf("package-verifier: name='%s' publicKey='%s'\n", 108556088a55ca6c9277f09040a7883117cb127e1e56Kenny Root name.string(), publicKey.string()); 108656088a55ca6c9277f09040a7883117cb127e1e56Kenny Root } 108756088a55ca6c9277f09040a7883117cb127e1e56Kenny Root } 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10897ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } else if (depth == 3 && withinApplication) { 10907ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu withinActivity = false; 10917ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu withinReceiver = false; 10921b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu withinService = false; 10931b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu hasIntentFilter = false; 10947ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu if(tag == "activity") { 10957ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu withinActivity = true; 10967ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu activityName = getAttribute(tree, NAME_ATTR, &error); 10977ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu if (error != "") { 10987ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", error.string()); 10997ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu goto bail; 11007ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11027ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu activityLabel = getResolvedAttribute(&res, tree, LABEL_ATTR, &error); 11037ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu if (error != "") { 11047ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu fprintf(stderr, "ERROR getting 'android:label' attribute: %s\n", error.string()); 11057ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu goto bail; 11067ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11087ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu activityIcon = getResolvedAttribute(&res, tree, ICON_ATTR, &error); 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (error != "") { 11107ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n", error.string()); 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1113f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn 1114f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn int32_t orien = getResolvedIntegerAttribute(&res, tree, 1115f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn SCREEN_ORIENTATION_ATTR, &error); 1116f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn if (error == "") { 1117f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn if (orien == 0 || orien == 6 || orien == 8) { 1118f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn // Requests landscape, sensorLandscape, or reverseLandscape. 1119f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn reqScreenLandscapeFeature = true; 1120f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn } else if (orien == 1 || orien == 7 || orien == 9) { 1121f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn // Requests portrait, sensorPortrait, or reversePortrait. 1122f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn reqScreenPortraitFeature = true; 1123f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn } 1124f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn } 11257ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } else if (tag == "uses-library") { 11267ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu String8 libraryName = getAttribute(tree, NAME_ATTR, &error); 11277ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu if (error != "") { 11287ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu fprintf(stderr, "ERROR getting 'android:name' attribute for uses-library: %s\n", error.string()); 11297ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu goto bail; 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 113149237345d83e62fdb9eb8d50b13ad086636a04faDianne Hackborn int req = getIntegerAttribute(tree, 113249237345d83e62fdb9eb8d50b13ad086636a04faDianne Hackborn REQUIRED_ATTR, NULL, 1); 113349237345d83e62fdb9eb8d50b13ad086636a04faDianne Hackborn printf("uses-library%s:'%s'\n", 113449237345d83e62fdb9eb8d50b13ad086636a04faDianne Hackborn req ? "" : "-not-required", libraryName.string()); 11357ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } else if (tag == "receiver") { 11367ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu withinReceiver = true; 11377ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu receiverName = getAttribute(tree, NAME_ATTR, &error); 11387ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (error != "") { 11407ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu fprintf(stderr, "ERROR getting 'android:name' attribute for receiver: %s\n", error.string()); 11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11431b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } else if (tag == "service") { 11441b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu withinService = true; 11451b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu serviceName = getAttribute(tree, NAME_ATTR, &error); 11461b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu 11471b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (error != "") { 11481b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu fprintf(stderr, "ERROR getting 'android:name' attribute for service: %s\n", error.string()); 11491b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu goto bail; 11501b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 11517ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } 11521b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } else if ((depth == 4) && (tag == "intent-filter")) { 11531b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu hasIntentFilter = true; 11541b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu withinIntentFilter = true; 11551b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu actMainActivity = actWidgetReceivers = actImeService = actWallpaperService = false; 11561b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } else if ((depth == 5) && withinIntentFilter){ 11571b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu String8 action; 11581b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (tag == "action") { 11591b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu action = getAttribute(tree, NAME_ATTR, &error); 11601b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (error != "") { 11611b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", error.string()); 11621b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu goto bail; 11631b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 11641b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (withinActivity) { 1165bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (action == "android.intent.action.MAIN") { 1166bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn isMainActivity = true; 11671b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu actMainActivity = true; 1168bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } 11691b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } else if (withinReceiver) { 11701b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (action == "android.appwidget.action.APPWIDGET_UPDATE") { 11711b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu actWidgetReceivers = true; 11727ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } 11731b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } else if (withinService) { 11741b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (action == "android.view.InputMethod") { 11751b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu actImeService = true; 11761b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } else if (action == "android.service.wallpaper.WallpaperService") { 11771b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu actWallpaperService = true; 11787ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } 11797ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } 11801b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (action == "android.intent.action.SEARCH") { 11811b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu isSearchable = true; 11827ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } 11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11851b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (tag == "category") { 11861b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu String8 category = getAttribute(tree, NAME_ATTR, &error); 11871b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (error != "") { 11881b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu fprintf(stderr, "ERROR getting 'name' attribute: %s\n", error.string()); 11891b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu goto bail; 11901b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 11911b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (withinActivity) { 11921b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (category == "android.intent.category.LAUNCHER") { 11931b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu isLauncherActivity = true; 11941b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 11951b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 11967ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu } 11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1199063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root 1200063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root // Pre-1.6 implicitly granted permission compatibility logic 1201063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root if (targetSdk < 4) { 1202063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root if (!hasWriteExternalStoragePermission) { 1203063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root printf("uses-permission:'android.permission.WRITE_EXTERNAL_STORAGE'\n"); 12044aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn printf("uses-implied-permission:'android.permission.WRITE_EXTERNAL_STORAGE'," \ 12054aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn "'targetSdkVersion < 4'\n"); 12067924512aa12c6af37d90e8ccfcdf04eb78a294a3Dianne Hackborn hasWriteExternalStoragePermission = true; 1207063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root } 1208063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root if (!hasReadPhoneStatePermission) { 1209063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root printf("uses-permission:'android.permission.READ_PHONE_STATE'\n"); 12104aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn printf("uses-implied-permission:'android.permission.READ_PHONE_STATE'," \ 12114aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn "'targetSdkVersion < 4'\n"); 1212063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root } 1213063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root } 12141b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu 12157924512aa12c6af37d90e8ccfcdf04eb78a294a3Dianne Hackborn // If the application has requested WRITE_EXTERNAL_STORAGE, we will 12162bd8d0403be62df679f0f94ab4d84c9ae9a2e918Dianne Hackborn // force them to always take READ_EXTERNAL_STORAGE as well. We always 12172bd8d0403be62df679f0f94ab4d84c9ae9a2e918Dianne Hackborn // do this (regardless of target API version) because we can't have 12182bd8d0403be62df679f0f94ab4d84c9ae9a2e918Dianne Hackborn // an app with write permission but not read permission. 12197924512aa12c6af37d90e8ccfcdf04eb78a294a3Dianne Hackborn if (!hasReadExternalStoragePermission && hasWriteExternalStoragePermission) { 12207924512aa12c6af37d90e8ccfcdf04eb78a294a3Dianne Hackborn printf("uses-permission:'android.permission.READ_EXTERNAL_STORAGE'\n"); 12214aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn printf("uses-implied-permission:'android.permission.READ_EXTERNAL_STORAGE'," \ 12224aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn "'requested WRITE_EXTERNAL_STORAGE'\n"); 12237924512aa12c6af37d90e8ccfcdf04eb78a294a3Dianne Hackborn } 12247924512aa12c6af37d90e8ccfcdf04eb78a294a3Dianne Hackborn 122531b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn // Pre-JellyBean call log permission compatibility. 122631b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn if (targetSdk < 16) { 122731b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn if (!hasReadCallLogPermission && hasReadContactsPermission) { 122831b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn printf("uses-permission:'android.permission.READ_CALL_LOG'\n"); 12294aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn printf("uses-implied-permission:'android.permission.READ_CALL_LOG'," \ 12304aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn "'targetSdkVersion < 16 and requested READ_CONTACTS'\n"); 123131b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn } 123231b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn if (!hasWriteCallLogPermission && hasWriteContactsPermission) { 123331b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn printf("uses-permission:'android.permission.WRITE_CALL_LOG'\n"); 12344aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn printf("uses-implied-permission:'android.permission.WRITE_CALL_LOG'," \ 12354aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn "'targetSdkVersion < 16 and requested WRITE_CONTACTS'\n"); 123631b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn } 123731b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn } 123831b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn 123989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill /* The following blocks handle printing "inferred" uses-features, based 124089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill * on whether related features or permissions are used by the app. 124189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill * Note that the various spec*Feature variables denote whether the 124289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill * relevant tag was *present* in the AndroidManfest, not that it was 124389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill * present and set to true. 124489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill */ 124589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // Camera-related back-compatibility logic 124689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill if (!specCameraFeature) { 12474aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn if (reqCameraFlashFeature) { 124889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // if app requested a sub-feature (autofocus or flash) and didn't 124989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // request the base camera feature, we infer that it meant to 125089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill printf("uses-feature:'android.hardware.camera'\n"); 12514aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn printf("uses-implied-feature:'android.hardware.camera'," \ 12524aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn "'requested android.hardware.camera.flash feature'\n"); 12534aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn } else if (reqCameraAutofocusFeature) { 12544aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn // if app requested a sub-feature (autofocus or flash) and didn't 12554aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn // request the base camera feature, we infer that it meant to 12564aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn printf("uses-feature:'android.hardware.camera'\n"); 12574aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn printf("uses-implied-feature:'android.hardware.camera'," \ 12584aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn "'requested android.hardware.camera.autofocus feature'\n"); 125989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } else if (hasCameraPermission) { 126089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // if app wants to use camera but didn't request the feature, we infer 126189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // that it meant to, and further that it wants autofocus 126289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // (which was the 1.0 - 1.5 behavior) 126389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill printf("uses-feature:'android.hardware.camera'\n"); 126489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill if (!specCameraAutofocusFeature) { 126589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill printf("uses-feature:'android.hardware.camera.autofocus'\n"); 12664aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn printf("uses-implied-feature:'android.hardware.camera.autofocus'," \ 12674aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn "'requested android.permission.CAMERA permission'\n"); 126889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } 126989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } 1270e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn } 1271dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker 127289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // Location-related back-compatibility logic 127389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill if (!specLocationFeature && 127489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill (hasMockLocPermission || hasCoarseLocPermission || hasGpsPermission || 127589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill hasGeneralLocPermission || reqNetworkLocFeature || reqGpsFeature)) { 127689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // if app either takes a location-related permission or requests one of the 127789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // sub-features, we infer that it also meant to request the base location feature 127889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill printf("uses-feature:'android.hardware.location'\n"); 12794aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn printf("uses-implied-feature:'android.hardware.location'," \ 12804aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn "'requested a location access permission'\n"); 128189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } 1282ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn if (!specGpsFeature && hasGpsPermission) { 128389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // if app takes GPS (FINE location) perm but does not request the GPS 128489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // feature, we infer that it meant to 1285ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn printf("uses-feature:'android.hardware.location.gps'\n"); 12864aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn printf("uses-implied-feature:'android.hardware.location.gps'," \ 12874aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn "'requested android.permission.ACCESS_FINE_LOCATION permission'\n"); 1288ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn } 128989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill if (!specNetworkLocFeature && hasCoarseLocPermission) { 129089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // if app takes Network location (COARSE location) perm but does not request the 129189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // network location feature, we infer that it meant to 129289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill printf("uses-feature:'android.hardware.location.network'\n"); 12934aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn printf("uses-implied-feature:'android.hardware.location.network'," \ 1294ec559ff78caa16cffcc7b9d688fe911e8945e17dDianne Hackborn "'requested android.permission.ACCESS_COARSE_LOCATION permission'\n"); 129589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } 129689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill 129789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // Bluetooth-related compatibility logic 12986b22d81aa35d9a9b32670995c002e92588b2fe09Dan Morrill if (!specBluetoothFeature && hasBluetoothPermission && (targetSdk > 4)) { 129989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // if app takes a Bluetooth permission but does not request the Bluetooth 130089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // feature, we infer that it meant to 130189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill printf("uses-feature:'android.hardware.bluetooth'\n"); 13024aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn printf("uses-implied-feature:'android.hardware.bluetooth'," \ 13034aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn "'requested android.permission.BLUETOOTH or android.permission.BLUETOOTH_ADMIN " \ 13044aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn "permission and targetSdkVersion > 4'\n"); 130589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } 130689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill 130789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // Microphone-related compatibility logic 130889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill if (!specMicrophoneFeature && hasRecordAudioPermission) { 130989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // if app takes the record-audio permission but does not request the microphone 131089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // feature, we infer that it meant to 131189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill printf("uses-feature:'android.hardware.microphone'\n"); 13124aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn printf("uses-implied-feature:'android.hardware.microphone'," \ 13134aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn "'requested android.permission.RECORD_AUDIO permission'\n"); 131489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } 131589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill 131689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // WiFi-related compatibility logic 131789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill if (!specWiFiFeature && hasWiFiPermission) { 131889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // if app takes one of the WiFi permissions but does not request the WiFi 131989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // feature, we infer that it meant to 132089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill printf("uses-feature:'android.hardware.wifi'\n"); 13214aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn printf("uses-implied-feature:'android.hardware.wifi'," \ 13224aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn "'requested android.permission.ACCESS_WIFI_STATE, " \ 13234aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn "android.permission.CHANGE_WIFI_STATE, or " \ 13244aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn "android.permission.CHANGE_WIFI_MULTICAST_STATE permission'\n"); 132589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } 132689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill 132789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // Telephony-related compatibility logic 132889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill if (!specTelephonyFeature && (hasTelephonyPermission || reqTelephonySubFeature)) { 132989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // if app takes one of the telephony permissions or requests a sub-feature but 133089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // does not request the base telephony feature, we infer that it meant to 133189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill printf("uses-feature:'android.hardware.telephony'\n"); 13324aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn printf("uses-implied-feature:'android.hardware.telephony'," \ 13334aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn "'requested a telephony-related permission or feature'\n"); 133489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } 133589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill 133689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // Touchscreen-related back-compatibility logic 133789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill if (!specTouchscreenFeature) { // not a typo! 133889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // all apps are presumed to require a touchscreen, unless they explicitly say 133989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // <uses-feature android:name="android.hardware.touchscreen" android:required="false"/> 134089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // Note that specTouchscreenFeature is true if the tag is present, regardless 134189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // of whether its value is true or false, so this is safe 134289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill printf("uses-feature:'android.hardware.touchscreen'\n"); 13434aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn printf("uses-implied-feature:'android.hardware.touchscreen'," \ 13444aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn "'assumed you require a touch screen unless explicitly made optional'\n"); 134589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } 134689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill if (!specMultitouchFeature && reqDistinctMultitouchFeature) { 134789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // if app takes one of the telephony permissions or requests a sub-feature but 134889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill // does not request the base telephony feature, we infer that it meant to 134989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill printf("uses-feature:'android.hardware.touchscreen.multitouch'\n"); 13504aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn printf("uses-implied-feature:'android.hardware.touchscreen.multitouch'," \ 13514aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn "'requested android.hardware.touchscreen.multitouch.distinct feature'\n"); 135289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill } 1353ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn 1354e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn // Landscape/portrait-related compatibility logic 1355f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn if (!specScreenLandscapeFeature && !specScreenPortraitFeature) { 1356f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn // If the app has specified any activities in its manifest 1357f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn // that request a specific orientation, then assume that 1358f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn // orientation is required. 1359f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn if (reqScreenLandscapeFeature) { 1360f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn printf("uses-feature:'android.hardware.screen.landscape'\n"); 13614aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn printf("uses-implied-feature:'android.hardware.screen.landscape'," \ 13624aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn "'one or more activities have specified a landscape orientation'\n"); 1363f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn } 1364f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn if (reqScreenPortraitFeature) { 1365f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn printf("uses-feature:'android.hardware.screen.portrait'\n"); 13664aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn printf("uses-implied-feature:'android.hardware.screen.portrait'," \ 13674aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn "'one or more activities have specified a portrait orientation'\n"); 1368f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn } 1369e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 1370e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn 13711b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (hasMainActivity) { 13721b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu printf("main\n"); 13731b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 13741b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (hasWidgetReceivers) { 13751b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu printf("app-widget\n"); 13761b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 13771b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (hasImeService) { 13781b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu printf("ime\n"); 13791b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 13801b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (hasWallpaperService) { 13811b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu printf("wallpaper\n"); 13821b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 13831b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (hasOtherActivities) { 13841b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu printf("other-activities\n"); 13851b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 13861b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (isSearchable) { 13871b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu printf("search\n"); 13881b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 13891b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (hasOtherReceivers) { 13901b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu printf("other-receivers\n"); 13911b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 13921b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu if (hasOtherServices) { 13931b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu printf("other-services\n"); 13941b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu } 13951b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu 1396e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn // For modern apps, if screen size buckets haven't been specified 1397e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn // but the new width ranges have, then infer the buckets from them. 1398e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn if (smallScreen > 0 && normalScreen > 0 && largeScreen > 0 && xlargeScreen > 0 1399e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn && requiresSmallestWidthDp > 0) { 1400e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn int compatWidth = compatibleWidthLimitDp; 1401e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn if (compatWidth <= 0) compatWidth = requiresSmallestWidthDp; 1402e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn if (requiresSmallestWidthDp <= 240 && compatWidth >= 240) { 1403e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn smallScreen = -1; 1404e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } else { 1405e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn smallScreen = 0; 1406e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 1407e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn if (requiresSmallestWidthDp <= 320 && compatWidth >= 320) { 1408e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn normalScreen = -1; 1409e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } else { 1410e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn normalScreen = 0; 1411e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 1412e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn if (requiresSmallestWidthDp <= 480 && compatWidth >= 480) { 1413e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn largeScreen = -1; 1414e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } else { 1415e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn largeScreen = 0; 1416e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 1417e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn if (requiresSmallestWidthDp <= 720 && compatWidth >= 720) { 1418e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn xlargeScreen = -1; 1419e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } else { 1420e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn xlargeScreen = 0; 1421e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 1422e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 1423e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn 1424723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn // Determine default values for any unspecified screen sizes, 1425723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn // based on the target SDK of the package. As of 4 (donut) 1426723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn // the screen size support was introduced, so all default to 1427723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn // enabled. 1428723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn if (smallScreen > 0) { 1429723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn smallScreen = targetSdk >= 4 ? -1 : 0; 1430723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn } 1431723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn if (normalScreen > 0) { 1432723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn normalScreen = -1; 1433723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn } 1434723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn if (largeScreen > 0) { 1435723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn largeScreen = targetSdk >= 4 ? -1 : 0; 1436723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn } 1437f43489d7d5e1c0c5c9a7e54c22845fcb99765f81Dianne Hackborn if (xlargeScreen > 0) { 1438d58fb97ddf052b3ceac921ac7e936af990392b2cScott Main // Introduced in Gingerbread. 1439d58fb97ddf052b3ceac921ac7e936af990392b2cScott Main xlargeScreen = targetSdk >= 9 ? -1 : 0; 1440f43489d7d5e1c0c5c9a7e54c22845fcb99765f81Dianne Hackborn } 1441a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn if (anyDensity > 0) { 1442e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn anyDensity = (targetSdk >= 4 || requiresSmallestWidthDp > 0 1443e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn || compatibleWidthLimitDp > 0) ? -1 : 0; 1444a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn } 1445723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn printf("supports-screens:"); 1446723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn if (smallScreen != 0) printf(" 'small'"); 1447723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn if (normalScreen != 0) printf(" 'normal'"); 1448723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn if (largeScreen != 0) printf(" 'large'"); 1449f43489d7d5e1c0c5c9a7e54c22845fcb99765f81Dianne Hackborn if (xlargeScreen != 0) printf(" 'xlarge'"); 1450723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn printf("\n"); 1451a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn printf("supports-any-density: '%s'\n", anyDensity ? "true" : "false"); 1452e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn if (requiresSmallestWidthDp > 0) { 1453e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn printf("requires-smallest-width:'%d'\n", requiresSmallestWidthDp); 1454e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 1455e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn if (compatibleWidthLimitDp > 0) { 1456e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn printf("compatible-width-limit:'%d'\n", compatibleWidthLimitDp); 1457e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 1458e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn if (largestWidthLimitDp > 0) { 1459e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn printf("largest-width-limit:'%d'\n", largestWidthLimitDp); 1460e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn } 1461a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn 14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("locales:"); 1463e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn const size_t NL = locales.size(); 1464e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn for (size_t i=0; i<NL; i++) { 14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* localeStr = locales[i].string(); 14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (localeStr == NULL || strlen(localeStr) == 0) { 14679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project localeStr = "--_--"; 14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf(" '%s'", localeStr); 14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("\n"); 14721b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu 1473e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn printf("densities:"); 1474e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn const size_t ND = densities.size(); 1475e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn for (size_t i=0; i<ND; i++) { 1476e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn printf(" '%d'", densities[i]); 1477e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn } 1478e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn printf("\n"); 14791b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu 1480bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn AssetDir* dir = assets.openNonAssetDir(assetsCookie, "lib"); 1481bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (dir != NULL) { 1482bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn if (dir->getFileCount() > 0) { 1483bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn printf("native-code:"); 1484bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn for (size_t i=0; i<dir->getFileCount(); i++) { 1485bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn printf(" '%s'", dir->getFileName(i).string()); 1486bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } 1487bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn printf("\n"); 1488bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } 1489bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn delete dir; 1490bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn } 1491e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill } else if (strcmp("badger", option) == 0) { 14926c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn printf("%s", CONSOLE_DATA); 14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (strcmp("configurations", option) == 0) { 14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Vector<ResTable_config> configs; 14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res.getConfigurations(&configs); 14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t N = configs.size(); 14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<N; i++) { 14989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("%s\n", configs[i].toString().string()); 14999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: unknown dump option '%s'\n", option); 15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = NO_ERROR; 15077ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu 15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbail: 15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (asset) { 15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete asset; 15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (result != NO_ERROR); 15139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 15149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Handle the "add" command, which wants to add files to a new or 15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * pre-existing archive. 15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint doAdd(Bundle* bundle) 15219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipFile* zip = NULL; 15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t result = UNKNOWN_ERROR; 15249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* zipFileName; 15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getUpdate()) { 15279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* avoid confusion */ 15289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: can't use '-u' with add\n"); 15299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 15309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getFileSpecCount() < 1) { 15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: must specify zip file name\n"); 15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zipFileName = bundle->getFileSpecEntry(0); 15379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getFileSpecCount() < 2) { 15399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "NOTE: nothing to do\n"); 15409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 15419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zip = openReadWrite(zipFileName, true); 15449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (zip == NULL) { 15459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: failed opening/creating '%s' as Zip file\n", zipFileName); 15469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 15479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 1; i < bundle->getFileSpecCount(); i++) { 15509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* fileName = bundle->getFileSpecEntry(i); 15519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (strcasecmp(String8(fileName).getPathExtension().string(), ".gz") == 0) { 15539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf(" '%s'... (from gzip)\n", fileName); 15549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = zip->addGzip(fileName, String8(fileName).getBasePath().string(), NULL); 15559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1556dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker if (bundle->getJunkPath()) { 1557dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker String8 storageName = String8(fileName).getPathLeaf(); 1558dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker printf(" '%s' as '%s'...\n", fileName, storageName.string()); 1559dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker result = zip->add(fileName, storageName.string(), 1560dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker bundle->getCompressionMethod(), NULL); 1561dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker } else { 1562dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker printf(" '%s'...\n", fileName); 1563dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker result = zip->add(fileName, bundle->getCompressionMethod(), NULL); 1564dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker } 15659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result != NO_ERROR) { 15679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "Unable to add '%s' to '%s'", bundle->getFileSpecEntry(i), zipFileName); 15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result == NAME_NOT_FOUND) 15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, ": file not found\n"); 15709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (result == ALREADY_EXISTS) 15719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, ": already exists in archive\n"); 15729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else 15739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "\n"); 15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 15759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = NO_ERROR; 15799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbail: 15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete zip; 15829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (result != NO_ERROR); 15839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 15849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 15879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Delete files from an existing archive. 15889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint doRemove(Bundle* bundle) 15909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 15919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipFile* zip = NULL; 15929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t result = UNKNOWN_ERROR; 15939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* zipFileName; 15949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getFileSpecCount() < 1) { 15969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: must specify zip file name\n"); 15979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 15989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zipFileName = bundle->getFileSpecEntry(0); 16009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getFileSpecCount() < 2) { 16029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "NOTE: nothing to do\n"); 16039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 16049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zip = openReadWrite(zipFileName, false); 16079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (zip == NULL) { 16089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: failed opening Zip archive '%s'\n", 16099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zipFileName); 16109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 16119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 1; i < bundle->getFileSpecCount(); i++) { 16149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* fileName = bundle->getFileSpecEntry(i); 16159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry* entry; 16169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project entry = zip->getEntryByName(fileName); 16189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (entry == NULL) { 16199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf(" '%s' NOT FOUND\n", fileName); 16209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 16219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = zip->remove(entry); 16249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result != NO_ERROR) { 16269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "Unable to delete '%s' from '%s'\n", 16279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bundle->getFileSpecEntry(i), zipFileName); 16289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 16299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* update the archive */ 16339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zip->flush(); 16349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbail: 16369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete zip; 16379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (result != NO_ERROR); 16389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 16399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 16429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Package up an asset directory and associated application files. 16439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 16449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint doPackage(Bundle* bundle) 16459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 16469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* outputAPKFile; 16479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int retVal = 1; 16489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err; 16499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<AaptAssets> assets; 16509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int N; 16519bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin FILE* fp; 16529bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin String8 dependencyFile; 16539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // -c zz_ZZ means do pseudolocalization 16559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResourceFilter filter; 16569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = filter.parse(bundle->getConfigurations()); 16579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 16589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 16599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (filter.containsPseudo()) { 16619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bundle->setPseudolocalize(true); 16629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project N = bundle->getFileSpecCount(); 16659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (N < 1 && bundle->getResourceSourceDirs().size() == 0 && bundle->getJarFiles().size() == 0 16669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && bundle->getAndroidManifestFile() == NULL && bundle->getAssetSourceDir() == NULL) { 16679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: no input files\n"); 16689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 16699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outputAPKFile = bundle->getOutputAPKFile(); 16729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Make sure the filenames provided exist and are of the appropriate type. 16749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outputAPKFile) { 16759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FileType type; 16769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project type = getFileType(outputAPKFile); 16779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type != kFileTypeNonexistent && type != kFileTypeRegular) { 16789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, 16799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "ERROR: output file '%s' exists but is not regular file\n", 16809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outputAPKFile); 16819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 16829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Load the assets. 16869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assets = new AaptAssets(); 16879bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin 168803589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin // Set up the resource gathering in assets if we're going to generate 1689b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // dependency files. Every time we encounter a resource while slurping 1690b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // the tree, we'll add it to these stores so we have full resource paths 1691b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // to write to a dependency file. 16929bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin if (bundle->getGenDependencies()) { 169303589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin sp<FilePathStore> resPathStore = new FilePathStore; 169403589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin assets->setFullResPaths(resPathStore); 169503589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin sp<FilePathStore> assetPathStore = new FilePathStore; 169603589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin assets->setFullAssetPaths(assetPathStore); 16979bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin } 16989bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin 16999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = assets->slurpFromArgs(bundle); 17009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err < 0) { 17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 17029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getVerbose()) { 1705e6b680364dd992907a8d2037685a2e500d188dfbDianne Hackborn assets->print(String8()); 17069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17089bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin // If they asked for any fileAs that need to be compiled, do so. 17099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bundle->getResourceSourceDirs().size() || bundle->getAndroidManifestFile()) { 17109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = buildResources(bundle, assets); 17119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != 0) { 17129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 17139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // At this point we've read everything and processed everything. From here 17179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // on out it's just writing output files. 17189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SourcePos::hasErrors()) { 17199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 17209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17221644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn // Update symbols with information about which ones are needed as Java symbols. 17231644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn assets->applyJavaSymbols(); 17241644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn if (SourcePos::hasErrors()) { 17251644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn goto bail; 17261644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn } 17271644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn 1728b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // If we've been asked to generate a dependency file, do that here 17299bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin if (bundle->getGenDependencies()) { 1730b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // If this is the packaging step, generate the dependency file next to 1731b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // the output apk (e.g. bin/resources.ap_.d) 173203589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin if (outputAPKFile) { 173303589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin dependencyFile = String8(outputAPKFile); 1734b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // Add the .d extension to the dependency file. 173503589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin dependencyFile.append(".d"); 173603589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin } else { 1737b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // Else if this is the R.java dependency generation step, 1738b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // generate the dependency file in the R.java package subdirectory 1739b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // e.g. gen/com/foo/app/R.java.d 174003589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin dependencyFile = String8(bundle->getRClassDir()); 1741b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin dependencyFile.appendPath("R.java.d"); 174203589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin } 17439bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin // Make sure we have a clean dependency file to start with 17449bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin fp = fopen(dependencyFile, "w"); 17459bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin fclose(fp); 17469bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin } 17479bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin 17489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Write out R.java constants 17491644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn if (!assets->havePrivateSymbols()) { 175063459ad555c10de1f316d6de01fc3cd0c0aaa457Xavier Ducrohet if (bundle->getCustomPackage() == NULL) { 1751b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // Write the R.java file into the appropriate class directory 1752b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // e.g. gen/com/foo/app/R.java 175363459ad555c10de1f316d6de01fc3cd0c0aaa457Xavier Ducrohet err = writeResourceSymbols(bundle, assets, assets->getPackage(), true); 175463459ad555c10de1f316d6de01fc3cd0c0aaa457Xavier Ducrohet } else { 175563459ad555c10de1f316d6de01fc3cd0c0aaa457Xavier Ducrohet const String8 customPkg(bundle->getCustomPackage()); 175663459ad555c10de1f316d6de01fc3cd0c0aaa457Xavier Ducrohet err = writeResourceSymbols(bundle, assets, customPkg, true); 175763459ad555c10de1f316d6de01fc3cd0c0aaa457Xavier Ducrohet } 17589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err < 0) { 17599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 17609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1761002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang // If we have library files, we're going to write our R.java file into 1762002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang // the appropriate class directory for those libraries as well. 1763002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang // e.g. gen/com/foo/app/lib/R.java 1764002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang if (bundle->getExtraPackages() != NULL) { 1765002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang // Split on colon 1766002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang String8 libs(bundle->getExtraPackages()); 1767002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang char* packageString = strtok(libs.lockBuffer(libs.length()), ":"); 1768002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang while (packageString != NULL) { 1769002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang // Write the R.java file out with the correct package name 1770002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang err = writeResourceSymbols(bundle, assets, String8(packageString), true); 1771002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang if (err < 0) { 1772002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang goto bail; 1773002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang } 1774002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang packageString = strtok(NULL, ":"); 1775002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang } 1776002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang libs.unlockBuffer(); 1777002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang } 17789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 17799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = writeResourceSymbols(bundle, assets, assets->getPackage(), false); 17809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err < 0) { 17819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 17829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = writeResourceSymbols(bundle, assets, assets->getSymbolsPrivatePackage(), true); 17849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err < 0) { 17859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 17869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17891553c82e084ac5763fb393857224145506771b99Joe Onorato // Write out the ProGuard file 17901553c82e084ac5763fb393857224145506771b99Joe Onorato err = writeProguardFile(bundle, assets); 17911553c82e084ac5763fb393857224145506771b99Joe Onorato if (err < 0) { 17921553c82e084ac5763fb393857224145506771b99Joe Onorato goto bail; 17931553c82e084ac5763fb393857224145506771b99Joe Onorato } 17941553c82e084ac5763fb393857224145506771b99Joe Onorato 17959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Write the apk 17969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outputAPKFile) { 17979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = writeAPK(bundle, assets, String8(outputAPKFile)); 17989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 17999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "ERROR: packaging of '%s' failed\n", outputAPKFile); 18009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 18019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1804b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // If we've been asked to generate a dependency file, we need to finish up here. 1805b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // the writeResourceSymbols and writeAPK functions have already written the target 1806b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // half of the dependency file, now we need to write the prerequisites. (files that 1807b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // the R.java file or .ap_ file depend on) 180803589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin if (bundle->getGenDependencies()) { 180903589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin // Now that writeResourceSymbols or writeAPK has taken care of writing 181003589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin // the targets to our dependency file, we'll write the prereqs 181103589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin fp = fopen(dependencyFile, "a+"); 181203589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin fprintf(fp, " : "); 181303589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin bool includeRaw = (outputAPKFile != NULL); 181403589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin err = writeDependencyPreReqs(bundle, assets, fp, includeRaw); 1815b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // Also manually add the AndroidManifeset since it's not under res/ or assets/ 1816b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin // and therefore was not added to our pathstores during slurping 181703589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin fprintf(fp, "%s \\\n", bundle->getAndroidManifestFile()); 181803589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin fclose(fp); 181903589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin } 182003589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin 18219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project retVal = 0; 18229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbail: 18239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SourcePos::hasErrors()) { 18249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SourcePos::printErrors(stderr); 18259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return retVal; 18279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 18288a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 18298a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin/* 18308a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin * Do PNG Crunching 18318a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin * PRECONDITIONS 18328a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin * -S flag points to a source directory containing drawable* folders 18338a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin * -C flag points to destination directory. The folder structure in the 18348a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin * source directory will be mirrored to the destination (cache) directory 18358a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin * 18368a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin * POSTCONDITIONS 18378a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin * Destination directory will be updated to match the PNG files in 18388a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin * the source directory. 18398a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin */ 18408a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskinint doCrunch(Bundle* bundle) 18418a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin{ 18428a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin fprintf(stdout, "Crunching PNG Files in "); 18438a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin fprintf(stdout, "source dir: %s\n", bundle->getResourceSourceDirs()[0]); 18448a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin fprintf(stdout, "To destination dir: %s\n", bundle->getCrunchedOutputDir()); 18458a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 18468a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin updatePreProcessedCache(bundle); 18478a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 18488a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin return NO_ERROR; 18498a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin} 1850e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 1851b1f6ad82dd8d1702617a757a88430604b3131facXavier Ducrohet/* 1852b1f6ad82dd8d1702617a757a88430604b3131facXavier Ducrohet * Do PNG Crunching on a single flag 1853b1f6ad82dd8d1702617a757a88430604b3131facXavier Ducrohet * -i points to a single png file 1854b1f6ad82dd8d1702617a757a88430604b3131facXavier Ducrohet * -o points to a single png output file 1855b1f6ad82dd8d1702617a757a88430604b3131facXavier Ducrohet */ 1856b1f6ad82dd8d1702617a757a88430604b3131facXavier Ducrohetint doSingleCrunch(Bundle* bundle) 1857b1f6ad82dd8d1702617a757a88430604b3131facXavier Ducrohet{ 1858b1f6ad82dd8d1702617a757a88430604b3131facXavier Ducrohet fprintf(stdout, "Crunching single PNG file: %s\n", bundle->getSingleCrunchInputFile()); 1859b1f6ad82dd8d1702617a757a88430604b3131facXavier Ducrohet fprintf(stdout, "\tOutput file: %s\n", bundle->getSingleCrunchOutputFile()); 1860b1f6ad82dd8d1702617a757a88430604b3131facXavier Ducrohet 1861b1f6ad82dd8d1702617a757a88430604b3131facXavier Ducrohet String8 input(bundle->getSingleCrunchInputFile()); 1862b1f6ad82dd8d1702617a757a88430604b3131facXavier Ducrohet String8 output(bundle->getSingleCrunchOutputFile()); 1863b7de2194d54eb81b1db4b50c171ddd0339831155Xavier Ducrohet 1864c75d3f5c10bf6d7718ef69c6bbc1cdf64cd8ff04Xavier Ducrohet if (preProcessImageToCache(bundle, input, output) != NO_ERROR) { 1865c75d3f5c10bf6d7718ef69c6bbc1cdf64cd8ff04Xavier Ducrohet // we can't return the status_t as it gets truncate to the lower 8 bits. 1866c75d3f5c10bf6d7718ef69c6bbc1cdf64cd8ff04Xavier Ducrohet return 42; 1867c75d3f5c10bf6d7718ef69c6bbc1cdf64cd8ff04Xavier Ducrohet } 1868b7de2194d54eb81b1db4b50c171ddd0339831155Xavier Ducrohet 1869c75d3f5c10bf6d7718ef69c6bbc1cdf64cd8ff04Xavier Ducrohet return NO_ERROR; 1870b1f6ad82dd8d1702617a757a88430604b3131facXavier Ducrohet} 1871b1f6ad82dd8d1702617a757a88430604b3131facXavier Ducrohet 1872e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrillchar CONSOLE_DATA[2925] = { 1873e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1874e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 95, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1875e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1876e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 1877e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 63, 1878e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 86, 35, 40, 46, 46, 95, 95, 95, 95, 97, 97, 44, 32, 46, 124, 42, 33, 83, 1879e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 62, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1880e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1881e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 46, 58, 59, 61, 59, 61, 81, 1882e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 81, 81, 81, 66, 96, 61, 61, 58, 46, 46, 46, 58, 32, 32, 32, 32, 32, 32, 1883e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 1884e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1885e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 46, 61, 59, 59, 59, 58, 106, 81, 81, 81, 81, 102, 59, 61, 59, 1886e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 61, 61, 61, 58, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1887e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1888e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 1889e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 58, 109, 81, 81, 81, 81, 61, 59, 59, 59, 59, 59, 58, 59, 59, 46, 32, 1890e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1891e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1892e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 60, 81, 81, 81, 81, 87, 1893e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 58, 59, 59, 59, 59, 59, 59, 61, 119, 44, 32, 32, 32, 32, 32, 32, 32, 32, 1894e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 1895e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 1896e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 47, 61, 59, 59, 58, 100, 81, 81, 81, 81, 35, 58, 59, 59, 59, 59, 59, 58, 1897e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 121, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1898e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1899e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 109, 58, 59, 59, 61, 81, 81, 1900e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 81, 81, 81, 109, 58, 59, 59, 59, 59, 61, 109, 81, 81, 76, 46, 32, 32, 32, 1901e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 1902e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1903e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 41, 87, 59, 61, 59, 41, 81, 81, 81, 81, 81, 81, 59, 61, 59, 1904e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 58, 109, 81, 81, 87, 39, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1905e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1906e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 60, 81, 91, 59, 1907e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 61, 81, 81, 81, 81, 81, 87, 43, 59, 58, 59, 60, 81, 81, 81, 76, 32, 1908e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1909e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1910e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 52, 91, 58, 45, 59, 87, 81, 81, 81, 81, 1911e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 70, 58, 58, 58, 59, 106, 81, 81, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32, 1912e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 1913e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1914e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 93, 40, 32, 46, 59, 100, 81, 81, 81, 81, 40, 58, 46, 46, 58, 100, 81, 1915e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 81, 68, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1916e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1917e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 46, 46, 46, 32, 46, 46, 46, 32, 46, 32, 46, 45, 91, 59, 61, 58, 109, 1918e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 81, 81, 81, 87, 46, 58, 61, 59, 60, 81, 81, 80, 32, 32, 32, 32, 32, 32, 1919e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 1920e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 46, 46, 61, 59, 61, 61, 61, 59, 61, 61, 59, 1921e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 58, 58, 46, 46, 41, 58, 59, 58, 81, 81, 81, 81, 69, 58, 59, 59, 1922e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 60, 81, 81, 68, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1923e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 58, 59, 1924e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 61, 46, 1925e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 61, 59, 93, 81, 81, 81, 81, 107, 58, 59, 58, 109, 87, 68, 96, 32, 32, 32, 1926e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1927e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 10, 32, 32, 32, 46, 60, 61, 61, 59, 59, 59, 59, 59, 59, 59, 59, 1928e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 59, 59, 59, 59, 59, 59, 59, 58, 58, 58, 115, 109, 68, 41, 36, 81, 1929e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 109, 46, 61, 61, 81, 69, 96, 46, 58, 58, 46, 58, 46, 46, 32, 32, 32, 32, 1930e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 46, 32, 95, 81, 1931e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 67, 61, 61, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 1932e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 59, 59, 58, 68, 39, 61, 105, 61, 63, 81, 119, 58, 106, 80, 32, 58, 1933e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 61, 59, 59, 61, 59, 61, 59, 61, 46, 95, 32, 32, 32, 32, 32, 32, 32, 32, 1934e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 10, 32, 32, 36, 81, 109, 105, 59, 61, 59, 59, 59, 1935e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 46, 58, 37, 1936e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 73, 108, 108, 62, 52, 81, 109, 34, 32, 61, 59, 59, 59, 59, 59, 59, 59, 59, 1937e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 61, 59, 61, 61, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 1938e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 46, 45, 57, 101, 43, 43, 61, 61, 59, 59, 59, 59, 59, 59, 61, 59, 59, 1939e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 59, 59, 59, 59, 59, 58, 97, 46, 61, 108, 62, 126, 58, 106, 80, 96, 1940e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 46, 61, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 61, 1941e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 97, 103, 97, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 45, 46, 32, 1942e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 46, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45, 58, 59, 59, 59, 59, 61, 1943e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 119, 81, 97, 124, 105, 124, 124, 39, 126, 95, 119, 58, 61, 58, 59, 59, 59, 1944e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 119, 81, 81, 99, 32, 32, 1945e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1946e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 58, 106, 81, 81, 81, 109, 119, 1947e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 119, 119, 109, 109, 81, 81, 122, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 1948e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 59, 59, 59, 58, 115, 81, 87, 81, 102, 32, 32, 32, 32, 32, 32, 10, 1949e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1950e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 61, 58, 59, 61, 81, 81, 81, 81, 81, 81, 87, 87, 81, 81, 81, 81, 1951e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 81, 58, 59, 59, 59, 59, 59, 59, 59, 59, 58, 45, 45, 45, 59, 59, 59, 41, 1952e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 87, 66, 33, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 1953e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 93, 81, 1954e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 1955e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 45, 32, 46, 32, 32, 32, 32, 32, 46, 32, 126, 96, 32, 32, 32, 32, 32, 32, 1956e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1957e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 58, 61, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81, 1958e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 1959e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 1960e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 1961e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58, 1962e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 59, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1963e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1964e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 60, 81, 81, 81, 81, 1965e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 81, 81, 81, 81, 81, 81, 81, 81, 81, 59, 61, 59, 59, 61, 32, 32, 32, 32, 1966e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1967e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1968e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 58, 59, 59, 93, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 1969e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 81, 81, 40, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1970e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 1971e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 106, 1972e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 76, 58, 59, 59, 59, 1973e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1974e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1975e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 61, 58, 58, 81, 81, 81, 81, 81, 81, 81, 81, 1976e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 81, 81, 81, 81, 81, 87, 58, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 1977e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 1978e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1979e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 58, 59, 61, 41, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 87, 59, 1980e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 61, 58, 59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1981e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1982e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 61, 81, 81, 81, 1983e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 81, 81, 81, 81, 81, 81, 81, 81, 81, 107, 58, 59, 59, 59, 59, 58, 32, 32, 1984e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1985e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1986e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 58, 59, 59, 58, 51, 81, 81, 81, 81, 81, 81, 81, 81, 81, 1987e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 81, 102, 94, 59, 59, 59, 59, 59, 61, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1988e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 1989e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 1990e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 43, 63, 36, 81, 81, 81, 87, 64, 86, 102, 58, 59, 59, 59, 59, 59, 1991e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1992e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1993e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 59, 59, 43, 33, 1994e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 58, 126, 126, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32, 32, 1995e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 1996e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 1997e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 61, 59, 59, 59, 58, 45, 58, 61, 59, 58, 58, 58, 61, 59, 59, 59, 59, 59, 1998e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 1999e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 2000e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 58, 95, 2001e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 45, 61, 59, 61, 59, 59, 59, 59, 59, 59, 59, 45, 58, 59, 59, 59, 59, 2002e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 61, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2003e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2004e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 58, 61, 59, 59, 59, 59, 59, 61, 59, 61, 46, 46, 32, 45, 45, 45, 2005e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 58, 45, 45, 46, 58, 59, 59, 59, 59, 59, 59, 61, 46, 32, 32, 32, 32, 2006e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 2007e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 58, 59, 59, 59, 59, 2008e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 59, 59, 59, 61, 59, 46, 32, 32, 46, 32, 46, 32, 58, 61, 59, 59, 2009e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 59, 59, 59, 59, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2010e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2011e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 45, 59, 59, 59, 59, 59, 59, 59, 59, 58, 32, 2012e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 58, 32, 2013e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 2014e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2015e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 46, 61, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 61, 2016e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 46, 61, 59, 59, 59, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2017e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 2018e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 2019e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 46, 61, 58, 59, 59, 59, 59, 2020e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2021e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2022e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 58, 59, 59, 59, 59, 59, 59, 59, 59, 46, 46, 32, 32, 32, 2023e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 45, 32, 32, 32, 32, 32, 2024e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 2025e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 32, 45, 61, 2026e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 2027e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 59, 59, 59, 58, 45, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2028e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2029e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45, 45, 32, 46, 32, 2030e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 61, 59, 58, 45, 45, 32, 32, 32, 2031e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2032e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2033e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2034e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 46, 32, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2035e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10 2036e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill }; 2037