Command.cpp revision e47fd129057b19862e94b89f9ba413b5ceaca498
1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Copyright 2006 The Android Open Source Project 3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Android Asset Packaging Tool main entry point. 5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 6fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski#include "ApkBuilder.h" 7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "Bundle.h" 82c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski#include "Images.h" 92c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski#include "Main.h" 10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "ResourceFilter.h" 11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "ResourceTable.h" 12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "XMLNode.h" 13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 142c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski#include <utils/Errors.h> 152c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski#include <utils/KeyedVector.h> 162c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski#include <utils/List.h> 17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <utils/Log.h> 182c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski#include <utils/SortedVector.h> 19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <utils/threads.h> 202c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski#include <utils/Vector.h> 21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <errno.h> 232c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski#include <fcntl.h> 24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiusing namespace android; 26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Show version info. All the cool kids do it. 29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doVersion(Bundle* bundle) 31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() != 0) { 33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("(ignoring extra arguments)\n"); 34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Android Asset Packaging Tool, v0.2\n"); 36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Open the file read only. The call fails if the file doesn't exist. 43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Returns NULL on failure. 45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 46282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiZipFile* openReadOnly(const char* fileName) 47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipFile* zip; 49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result; 50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip = new ZipFile; 52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = zip->open(fileName, ZipFile::kOpenReadOnly); 53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result != NO_ERROR) { 54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result == NAME_NOT_FOUND) { 55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: '%s' not found\n", fileName); 56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (result == PERMISSION_DENIED) { 57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: '%s' access denied\n", fileName); 58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: failed opening '%s' as Zip file\n", 60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fileName); 61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete zip; 63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return zip; 67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Open the file read-write. The file will be created if it doesn't 71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * already exist and "okayToCreate" is set. 72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Returns NULL on failure. 74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 75282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiZipFile* openReadWrite(const char* fileName, bool okayToCreate) 76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipFile* zip = NULL; 78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result; 79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int flags; 80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flags = ZipFile::kOpenReadWrite; 82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (okayToCreate) { 83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flags |= ZipFile::kOpenCreate; 84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip = new ZipFile; 87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = zip->open(fileName, flags); 88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result != NO_ERROR) { 89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete zip; 90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip = NULL; 91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return zip; 96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Return a short string describing the compression method. 101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiconst char* compressionName(int method) 103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (method == ZipEntry::kCompressStored) { 105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return "Stored"; 106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (method == ZipEntry::kCompressDeflated) { 107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return "Deflated"; 108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return "Unknown"; 110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Return the percent reduction in size (0% == no compression). 115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint calcPercent(long uncompressedLen, long compressedLen) 117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!uncompressedLen) { 119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (int) (100.0 - (compressedLen * 100.0) / uncompressedLen + 0.5); 122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Handle the "list" command, which can be a simple file dump or 127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * a verbose listing. 128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * The verbose listing closely matches the output of the Info-ZIP "unzip" 130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * command. 131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doList(Bundle* bundle) 133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int result = 1; 135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipFile* zip = NULL; 136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ZipEntry* entry; 137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski long totalUncLen, totalCompLen; 138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* zipFileName; 139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() != 1) { 141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: specify zip file name (only)\n"); 142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zipFileName = bundle->getFileSpecEntry(0); 145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip = openReadOnly(zipFileName); 147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (zip == NULL) { 148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int count, i; 152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Archive: %s\n", zipFileName); 155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf( 156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " Length Method Size Ratio Offset Date Time CRC-32 Name\n"); 157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf( 158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "-------- ------ ------- ----- ------- ---- ---- ------ ----\n"); 159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalUncLen = totalCompLen = 0; 162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count = zip->getNumEntries(); 164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i = 0; i < count; i++) { 165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entry = zip->getEntryByIndex(i); 166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char dateBuf[32]; 168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski time_t when; 169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski when = entry->getModWhen(); 171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strftime(dateBuf, sizeof(dateBuf), "%m-%d-%y %H:%M", 172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski localtime(&when)); 173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%8ld %-7.7s %7ld %3d%% %8zd %s %08lx %s\n", 175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (long) entry->getUncompressedLen(), 176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski compressionName(entry->getCompressionMethod()), 177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (long) entry->getCompressedLen(), 178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski calcPercent(entry->getUncompressedLen(), 179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entry->getCompressedLen()), 180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (size_t) entry->getLFHOffset(), 181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dateBuf, 182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entry->getCRC32(), 183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entry->getFileName()); 184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%s\n", entry->getFileName()); 186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalUncLen += entry->getUncompressedLen(); 189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalCompLen += entry->getCompressedLen(); 190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf( 194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "-------- ------- --- -------\n"); 195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%8ld %7ld %2d%% %d files\n", 196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalUncLen, 197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalCompLen, 198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski calcPercent(totalUncLen, totalCompLen), 199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip->getNumEntries()); 200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getAndroidList()) { 203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AssetManager assets; 204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!assets.addAssetPath(String8(zipFileName), NULL)) { 205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: list -a failed because assets could not be loaded\n"); 206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable& res = assets.getResources(false); 210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (&res == NULL) { 211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\nNo resource table found.\n"); 212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#ifndef HAVE_ANDROID_OS 214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\nResource table:\n"); 215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res.print(false); 216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Asset* manifestAsset = assets.openNonAsset("AndroidManifest.xml", 220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Asset::ACCESS_BUFFER); 221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (manifestAsset == NULL) { 222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\nNo AndroidManifest.xml found.\n"); 223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\nAndroid manifest:\n"); 225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree tree; 226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tree.setTo(manifestAsset->getBuffer(true), 227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski manifestAsset->getLength()); 228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printXMLBlock(&tree); 229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete manifestAsset; 231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = 0; 234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete zip; 237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return result; 238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic ssize_t indexOfAttribute(const ResXMLTree& tree, uint32_t attrRes) 241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t N = tree.getAttributeCount(); 243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.getAttributeNameResID(i) == attrRes) { 245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (ssize_t)i; 246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return -1; 249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 251282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiString8 getAttribute(const ResXMLTree& tree, const char* ns, 252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* attr, String8* outError) 253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t idx = tree.indexOfAttribute(ns, attr); 255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx < 0) { 256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String8(); 257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value.dataType != Res_value::TYPE_STRING) { 261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError != NULL) { 262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outError = "attribute is not a string value"; 263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String8(); 265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint16_t* str = tree.getAttributeStringValue(idx, &len); 269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return str ? String8(str, len) : String8(); 270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic String8 getAttribute(const ResXMLTree& tree, uint32_t attrRes, String8* outError) 273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t idx = indexOfAttribute(tree, attrRes); 275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx < 0) { 276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String8(); 277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value.dataType != Res_value::TYPE_STRING) { 281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError != NULL) { 282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outError = "attribute is not a string value"; 283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String8(); 285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint16_t* str = tree.getAttributeStringValue(idx, &len); 289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return str ? String8(str, len) : String8(); 290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic int32_t getIntegerAttribute(const ResXMLTree& tree, uint32_t attrRes, 293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8* outError, int32_t defValue = -1) 294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t idx = indexOfAttribute(tree, attrRes); 296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx < 0) { 297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return defValue; 298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value.dataType < Res_value::TYPE_FIRST_INT 302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || value.dataType > Res_value::TYPE_LAST_INT) { 303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError != NULL) { 304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outError = "attribute is not an integer value"; 305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return defValue; 307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return value.data; 310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic int32_t getResolvedIntegerAttribute(const ResTable* resTable, const ResXMLTree& tree, 313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t attrRes, String8* outError, int32_t defValue = -1) 314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t idx = indexOfAttribute(tree, attrRes); 316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx < 0) { 317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return defValue; 318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value.dataType == Res_value::TYPE_REFERENCE) { 322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resTable->resolveReference(&value, 0); 323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value.dataType < Res_value::TYPE_FIRST_INT 325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || value.dataType > Res_value::TYPE_LAST_INT) { 326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError != NULL) { 327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outError = "attribute is not an integer value"; 328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return defValue; 330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return value.data; 333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic String8 getResolvedAttribute(const ResTable* resTable, const ResXMLTree& tree, 336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t attrRes, String8* outError) 337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t idx = indexOfAttribute(tree, attrRes); 339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx < 0) { 340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String8(); 341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value.dataType == Res_value::TYPE_STRING) { 345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint16_t* str = tree.getAttributeStringValue(idx, &len); 347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return str ? String8(str, len) : String8(); 348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resTable->resolveReference(&value, 0); 350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value.dataType != Res_value::TYPE_STRING) { 351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError != NULL) { 352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outError = "attribute is not a string value"; 353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String8(); 355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Res_value* value2 = &value; 359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* str = const_cast<ResTable*>(resTable)->valueToString(value2, 0, NULL, &len); 360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return str ? String8(str, len) : String8(); 361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void getResolvedResourceAttribute(Res_value* value, const ResTable* resTable, 364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResXMLTree& tree, uint32_t attrRes, String8* outError) 365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t idx = indexOfAttribute(tree, attrRes); 367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx < 0) { 368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError != NULL) { 369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outError = "attribute could not be found"; 370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.getAttributeValue(idx, value) != NO_ERROR) { 374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value->dataType == Res_value::TYPE_REFERENCE) { 375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resTable->resolveReference(value, 0); 376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // The attribute was found and was resolved if need be. 378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError != NULL) { 381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outError = "error getting resolved resource attribute"; 382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 38576327314d2238e105f8b94909f9c0cf85caca318Maurice Chustatic void printResolvedResourceAttribute(const ResTable* resTable, const ResXMLTree& tree, 38676327314d2238e105f8b94909f9c0cf85caca318Maurice Chu uint32_t attrRes, String8 attrLabel, String8* outError) 38776327314d2238e105f8b94909f9c0cf85caca318Maurice Chu{ 38876327314d2238e105f8b94909f9c0cf85caca318Maurice Chu Res_value value; 38976327314d2238e105f8b94909f9c0cf85caca318Maurice Chu getResolvedResourceAttribute(&value, resTable, tree, attrRes, outError); 39076327314d2238e105f8b94909f9c0cf85caca318Maurice Chu if (*outError != "") { 39176327314d2238e105f8b94909f9c0cf85caca318Maurice Chu *outError = "error print resolved resource attribute"; 39276327314d2238e105f8b94909f9c0cf85caca318Maurice Chu return; 39376327314d2238e105f8b94909f9c0cf85caca318Maurice Chu } 39476327314d2238e105f8b94909f9c0cf85caca318Maurice Chu if (value.dataType == Res_value::TYPE_STRING) { 39576327314d2238e105f8b94909f9c0cf85caca318Maurice Chu String8 result = getResolvedAttribute(resTable, tree, attrRes, outError); 3962675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("%s='%s'", attrLabel.string(), 3972675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(result.string()).string()); 39876327314d2238e105f8b94909f9c0cf85caca318Maurice Chu } else if (Res_value::TYPE_FIRST_INT <= value.dataType && 39976327314d2238e105f8b94909f9c0cf85caca318Maurice Chu value.dataType <= Res_value::TYPE_LAST_INT) { 40076327314d2238e105f8b94909f9c0cf85caca318Maurice Chu printf("%s='%d'", attrLabel.string(), value.data); 40176327314d2238e105f8b94909f9c0cf85caca318Maurice Chu } else { 40276327314d2238e105f8b94909f9c0cf85caca318Maurice Chu printf("%s='0x%x'", attrLabel.string(), (int)value.data); 40376327314d2238e105f8b94909f9c0cf85caca318Maurice Chu } 40476327314d2238e105f8b94909f9c0cf85caca318Maurice Chu} 40576327314d2238e105f8b94909f9c0cf85caca318Maurice Chu 406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// These are attribute resource constants for the platform, as found 407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// in android.R.attr 408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskienum { 409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LABEL_ATTR = 0x01010001, 410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ICON_ATTR = 0x01010002, 411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NAME_ATTR = 0x01010003, 412a5018c900f126ee8424c82497f32983873db741bAdam Lesinski PERMISSION_ATTR = 0x01010006, 4139d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski EXPORTED_ATTR = 0x01010010, 4149d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski GRANT_URI_PERMISSIONS_ATTR = 0x0101001b, 41594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski RESOURCE_ATTR = 0x01010025, 416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DEBUGGABLE_ATTR = 0x0101000f, 417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski VALUE_ATTR = 0x01010024, 418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski VERSION_CODE_ATTR = 0x0101021b, 419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski VERSION_NAME_ATTR = 0x0101021c, 420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SCREEN_ORIENTATION_ATTR = 0x0101001e, 421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MIN_SDK_VERSION_ATTR = 0x0101020c, 422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MAX_SDK_VERSION_ATTR = 0x01010271, 423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_TOUCH_SCREEN_ATTR = 0x01010227, 424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_KEYBOARD_TYPE_ATTR = 0x01010228, 425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_HARD_KEYBOARD_ATTR = 0x01010229, 426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_NAVIGATION_ATTR = 0x0101022a, 427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_FIVE_WAY_NAV_ATTR = 0x01010232, 428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski TARGET_SDK_VERSION_ATTR = 0x01010270, 429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski TEST_ONLY_ATTR = 0x01010272, 430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ANY_DENSITY_ATTR = 0x0101026c, 431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski GL_ES_VERSION_ATTR = 0x01010281, 432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SMALL_SCREEN_ATTR = 0x01010284, 433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NORMAL_SCREEN_ATTR = 0x01010285, 434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LARGE_SCREEN_ATTR = 0x01010286, 435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski XLARGE_SCREEN_ATTR = 0x010102bf, 436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQUIRED_ATTR = 0x0101028e, 437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SCREEN_SIZE_ATTR = 0x010102ca, 438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SCREEN_DENSITY_ATTR = 0x010102cb, 439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQUIRES_SMALLEST_WIDTH_DP_ATTR = 0x01010364, 440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski COMPATIBLE_WIDTH_LIMIT_DP_ATTR = 0x01010365, 441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LARGEST_WIDTH_LIMIT_DP_ATTR = 0x01010366, 442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PUBLIC_KEY_ATTR = 0x010103a6, 44394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski CATEGORY_ATTR = 0x010103e8, 4440a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn BANNER_ATTR = 0x10103f2, 445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4472675f769673f69b0661ddee346292f25cb30a296Maurice ChuString8 getComponentName(String8 &pkgName, String8 &componentName) { 448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t idx = componentName.find("."); 449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 retStr(pkgName); 450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx == 0) { 451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski retStr += componentName; 452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (idx < 0) { 453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski retStr += "."; 454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski retStr += componentName; 455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 4562675f769673f69b0661ddee346292f25cb30a296Maurice Chu return componentName; 457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4582675f769673f69b0661ddee346292f25cb30a296Maurice Chu return retStr; 459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4619cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinskistatic void printCompatibleScreens(ResXMLTree& tree, String8* outError) { 462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int depth = 0; 465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool first = true; 466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("compatible-screens:"); 467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth--; 470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (depth < 0) { 471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != ResXMLTree::START_TAG) { 476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth++; 4799cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski const char16_t* ctag16 = tree.getElementName(&len); 4809cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski if (ctag16 == NULL) { 4819cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski *outError = "failed to get XML element name (bad string pool)"; 4829cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski return; 4839cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski } 4849cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski String8 tag(ctag16); 485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag == "screen") { 486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t screenSize = getIntegerAttribute(tree, 487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SCREEN_SIZE_ATTR, NULL, -1); 488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t screenDensity = getIntegerAttribute(tree, 489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SCREEN_DENSITY_ATTR, NULL, -1); 490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (screenSize > 0 && screenDensity > 0) { 491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!first) { 492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(","); 493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski first = false; 495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("'%d/%d'", screenSize, screenDensity); 496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 50258f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinskistatic void printUsesPermission(const String8& name, bool optional=false, int maxSdkVersion=-1) { 50358f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printf("uses-permission: name='%s'", ResTable::normalizeForOutput(name.string()).string()); 50458f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski if (maxSdkVersion != -1) { 50558f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printf(" maxSdkVersion='%d'", maxSdkVersion); 50658f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski } 50758f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printf("\n"); 50858f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski 50958f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski if (optional) { 51058f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printf("optional-permission: name='%s'", 51158f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski ResTable::normalizeForOutput(name.string()).string()); 51258f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski if (maxSdkVersion != -1) { 51358f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printf(" maxSdkVersion='%d'", maxSdkVersion); 51458f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski } 51558f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printf("\n"); 51658f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski } 51758f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski} 51858f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski 51958f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinskistatic void printUsesImpliedPermission(const String8& name, const String8& reason) { 52058f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printf("uses-implied-permission: name='%s' reason='%s'\n", 52158f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski ResTable::normalizeForOutput(name.string()).string(), 52258f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski ResTable::normalizeForOutput(reason.string()).string()); 52358f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski} 52458f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski 52594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam LesinskiVector<String8> getNfcAidCategories(AssetManager& assets, String8 xmlPath, bool offHost, 52694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski String8 *outError = NULL) 52794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski{ 52894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski Asset* aidAsset = assets.openNonAsset(xmlPath, Asset::ACCESS_BUFFER); 52994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (aidAsset == NULL) { 53094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (outError != NULL) *outError = "xml resource does not exist"; 53194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski return Vector<String8>(); 53294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 53394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 53494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski const String8 serviceTagName(offHost ? "offhost-apdu-service" : "host-apdu-service"); 53594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 53694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool withinApduService = false; 53794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski Vector<String8> categories; 53894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 53994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski String8 error; 54094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski ResXMLTree tree; 54194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski tree.setTo(aidAsset->getBuffer(true), aidAsset->getLength()); 54294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 54394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski size_t len; 54494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski int depth = 0; 54594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski ResXMLTree::event_code_t code; 54694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 54794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (code == ResXMLTree::END_TAG) { 54894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski depth--; 5499cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski const char16_t* ctag16 = tree.getElementName(&len); 5509cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski if (ctag16 == NULL) { 5519cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski *outError = "failed to get XML element name (bad string pool)"; 5529cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski return Vector<String8>(); 5539cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski } 5549cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski String8 tag(ctag16); 55594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 55694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (depth == 0 && tag == serviceTagName) { 55794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski withinApduService = false; 55894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 55994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 56094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else if (code == ResXMLTree::START_TAG) { 56194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski depth++; 5629cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski const char16_t* ctag16 = tree.getElementName(&len); 5639cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski if (ctag16 == NULL) { 5649cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski *outError = "failed to get XML element name (bad string pool)"; 5659cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski return Vector<String8>(); 5669cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski } 5679cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski String8 tag(ctag16); 56894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 56994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (depth == 1) { 57094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (tag == serviceTagName) { 57194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski withinApduService = true; 57294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 57394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else if (depth == 2 && withinApduService) { 57494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (tag == "aid-group") { 57594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski String8 category = getAttribute(tree, CATEGORY_ATTR, &error); 57694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (error != "") { 57794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (outError != NULL) *outError = error; 57894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski return Vector<String8>(); 57994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 58094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 58194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski categories.add(category); 58294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 58394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 58494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 58594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 58694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski aidAsset->close(); 58794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski return categories; 58894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski} 58994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 5909d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinskistatic void printComponentPresence(const char* componentName) { 5919d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printf("provides-component:'%s'\n", componentName); 5929d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski} 5939d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski 5942c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski/** 5952c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski * Represents a feature that has been automatically added due to 5962c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski * a pre-requisite or some other reason. 5972c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski */ 5982c72b6822debb08fe997926eedc110f62d287d34Adam Lesinskistruct ImpliedFeature { 5992c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski /** 6002c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski * Name of the implied feature. 6012c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski */ 6022c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8 name; 6032c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 6042c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski /** 6052c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski * List of human-readable reasons for why this feature was implied. 6062c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski */ 6072c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski SortedVector<String8> reasons; 6082c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski}; 6092c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 6102c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski/** 6112c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski * Represents a <feature-group> tag in the AndroidManifest.xml 6122c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski */ 6132c72b6822debb08fe997926eedc110f62d287d34Adam Lesinskistruct FeatureGroup { 614d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski FeatureGroup() : openGLESVersion(-1) {} 615d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski 6162c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski /** 6172c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski * Human readable label 6182c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski */ 6192c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8 label; 6202c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 6212c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski /** 6222c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski * Explicit features defined in the group 6232c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski */ 6242c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski KeyedVector<String8, bool> features; 625d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski 626d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski /** 627d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski * OpenGL ES version required 628d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski */ 629d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski int openGLESVersion; 6302c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski}; 6312c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 6322c72b6822debb08fe997926eedc110f62d287d34Adam Lesinskistatic void addImpliedFeature(KeyedVector<String8, ImpliedFeature>* impliedFeatures, 6332c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski const char* name, const char* reason) { 6342c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8 name8(name); 6352c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski ssize_t idx = impliedFeatures->indexOfKey(name8); 6362c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (idx < 0) { 6372c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski idx = impliedFeatures->add(name8, ImpliedFeature()); 6382c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski impliedFeatures->editValueAt(idx).name = name8; 6392c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 6402c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski impliedFeatures->editValueAt(idx).reasons.add(String8(reason)); 6412c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski} 6422c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 6432c72b6822debb08fe997926eedc110f62d287d34Adam Lesinskistatic void printFeatureGroup(const FeatureGroup& grp, 6442c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski const KeyedVector<String8, ImpliedFeature>* impliedFeatures = NULL) { 6452c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski printf("feature-group: label='%s'\n", grp.label.string()); 6462c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 647d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski if (grp.openGLESVersion > 0) { 648d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski printf(" uses-gl-es: '0x%x'\n", grp.openGLESVersion); 649d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski } 650d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski 6512c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski const size_t numFeatures = grp.features.size(); 6522c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski for (size_t i = 0; i < numFeatures; i++) { 6532c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (!grp.features[i]) { 6542c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski continue; 6552c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 6562c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 6572c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski const String8& featureName = grp.features.keyAt(i); 6582c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski printf(" uses-feature: name='%s'\n", 6592c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski ResTable::normalizeForOutput(featureName.string()).string()); 6602c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 6612c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 6622c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski const size_t numImpliedFeatures = 6632c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski (impliedFeatures != NULL) ? impliedFeatures->size() : 0; 6642c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski for (size_t i = 0; i < numImpliedFeatures; i++) { 6652c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski const ImpliedFeature& impliedFeature = impliedFeatures->valueAt(i); 6662c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (grp.features.indexOfKey(impliedFeature.name) >= 0) { 6672c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski // The feature is explicitly set, no need to use implied 6682c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski // definition. 6692c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski continue; 6702c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 6712c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 6722c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8 printableFeatureName(ResTable::normalizeForOutput( 6732c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski impliedFeature.name.string())); 6742c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski printf(" uses-feature: name='%s'\n", printableFeatureName.string()); 6752c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski printf(" uses-implied-feature: name='%s' reason='", 6762c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski printableFeatureName.string()); 6772c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski const size_t numReasons = impliedFeature.reasons.size(); 6782c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski for (size_t j = 0; j < numReasons; j++) { 6792c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski printf("%s", impliedFeature.reasons[j].string()); 6802c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (j + 2 < numReasons) { 6812c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski printf(", "); 6822c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } else if (j + 1 < numReasons) { 6832c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski printf(", and "); 6842c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 6852c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 6862c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski printf("'\n"); 6872c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 6882c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski} 6892c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 6902c72b6822debb08fe997926eedc110f62d287d34Adam Lesinskistatic void addParentFeatures(FeatureGroup* grp, const String8& name) { 6912c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (name == "android.hardware.camera.autofocus" || 6922c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski name == "android.hardware.camera.flash") { 6932c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski grp->features.add(String8("android.hardware.camera"), true); 6942c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } else if (name == "android.hardware.location.gps" || 6952c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski name == "android.hardware.location.network") { 6962c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski grp->features.add(String8("android.hardware.location"), true); 6972c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } else if (name == "android.hardware.touchscreen.multitouch") { 6982c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski grp->features.add(String8("android.hardware.touchscreen"), true); 6992c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } else if (name == "android.hardware.touchscreen.multitouch.distinct") { 7002c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski grp->features.add(String8("android.hardware.touchscreen.multitouch"), true); 7012c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski grp->features.add(String8("android.hardware.touchscreen"), true); 702d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski } else if (name == "android.hardware.opengles.aep") { 703d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski const int openGLESVersion31 = 0x00030001; 704d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski if (openGLESVersion31 > grp->openGLESVersion) { 705d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski grp->openGLESVersion = openGLESVersion31; 706d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski } 7072c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 7082c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski} 7092c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Handle the "dump" command, to extract select data from an archive. 712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiextern char CONSOLE_DATA[2925]; // see EOF 714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doDump(Bundle* bundle) 715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result = UNKNOWN_ERROR; 717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 1) { 719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: no dump option specified\n"); 720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 1; 721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 2) { 724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: no dump file specified\n"); 725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 1; 726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* option = bundle->getFileSpecEntry(0); 729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* filename = bundle->getFileSpecEntry(1); 730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AssetManager assets; 732f85e41f29a0e9313c2d4725f9d9648591ea49f3bNarayan Kamath int32_t assetsCookie; 733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!assets.addAssetPath(String8(filename), &assetsCookie)) { 734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: dump failed because assets could not be loaded\n"); 735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 1; 736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Make a dummy config for retrieving resources... we need to supply 739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // non-default values for some configs so that we can retrieve resources 740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // in the app that don't have a default. The most important of these is 741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the API version because key resources like icons will have an implicit 742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // version if they are using newer config types like density. 743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_config config; 74491447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath memset(&config, 0, sizeof(ResTable_config)); 745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.language[0] = 'e'; 746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.language[1] = 'n'; 747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.country[0] = 'U'; 748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.country[1] = 'S'; 749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.orientation = ResTable_config::ORIENTATION_PORT; 750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.density = ResTable_config::DENSITY_MEDIUM; 751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.sdkVersion = 10000; // Very high. 752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.screenWidthDp = 320; 753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.screenHeightDp = 480; 754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.smallestScreenWidthDp = 320; 755c2dea8daea2ae0001d56689d96ce1066012b7b40Adam Lesinski config.screenLayout |= ResTable_config::SCREENSIZE_NORMAL; 756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets.setConfiguration(config); 757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable& res = assets.getResources(false); 759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (&res == NULL) { 760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: dump failed because no resource table was found\n"); 76163e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski return 1; 76225e9d55e964c180ec6e57ba1d977d6c2e1115f5aAdam Lesinski } else if (res.getError() != NO_ERROR) { 76325e9d55e964c180ec6e57ba1d977d6c2e1115f5aAdam Lesinski fprintf(stderr, "ERROR: dump failed because the resource table is invalid/corrupt.\n"); 76463e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski return 1; 76563e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski } 76663e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski 7672cb761e3ddb9d68ab430013e9cd15ecaab9fbc62Adam Lesinski // The dynamicRefTable can be null if there are no resources for this asset cookie. 7682cb761e3ddb9d68ab430013e9cd15ecaab9fbc62Adam Lesinski // This fine. 76963e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski const DynamicRefTable* dynamicRefTable = res.getDynamicRefTableForCookie(assetsCookie); 770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 77163e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski Asset* asset = NULL; 77263e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski 773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp("resources", option) == 0) { 774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#ifndef HAVE_ANDROID_OS 775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res.print(bundle->getValues()); 776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("strings", option) == 0) { 779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResStringPool* pool = res.getTableStringBlock(0); 780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printStringPool(pool); 781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("xmltree", option) == 0) { 783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 3) { 784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: no dump xmltree resource file specified\n"); 785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i=2; i<bundle->getFileSpecCount(); i++) { 789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* resname = bundle->getFileSpecEntry(i); 79063e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski ResXMLTree tree(dynamicRefTable); 79163e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski asset = assets.openNonAsset(assetsCookie, resname, Asset::ACCESS_BUFFER); 792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (asset == NULL) { 793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: dump failed because resource %s found\n", resname); 794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.setTo(asset->getBuffer(true), 798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset->getLength()) != NO_ERROR) { 799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: Resource %s is corrupt\n", resname); 800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tree.restart(); 803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printXMLBlock(&tree); 804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tree.uninit(); 805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete asset; 806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset = NULL; 807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("xmlstrings", option) == 0) { 810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 3) { 811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: no dump xmltree resource file specified\n"); 812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i=2; i<bundle->getFileSpecCount(); i++) { 816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* resname = bundle->getFileSpecEntry(i); 81763e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski asset = assets.openNonAsset(assetsCookie, resname, Asset::ACCESS_BUFFER); 818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (asset == NULL) { 819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: dump failed because resource %s found\n", resname); 820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 82363e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski ResXMLTree tree(dynamicRefTable); 824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.setTo(asset->getBuffer(true), 825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset->getLength()) != NO_ERROR) { 826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: Resource %s is corrupt\n", resname); 827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printStringPool(&tree.getStrings()); 830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete asset; 831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset = NULL; 832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 83563e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski asset = assets.openNonAsset(assetsCookie, "AndroidManifest.xml", Asset::ACCESS_BUFFER); 836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (asset == NULL) { 837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: dump failed because no AndroidManifest.xml found\n"); 838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 84163e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski ResXMLTree tree(dynamicRefTable); 842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.setTo(asset->getBuffer(true), 843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset->getLength()) != NO_ERROR) { 844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: AndroidManifest.xml is corrupt\n"); 845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tree.restart(); 848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp("permissions", option) == 0) { 850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int depth = 0; 853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth--; 856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != ResXMLTree::START_TAG) { 859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth++; 8629cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski const char16_t* ctag16 = tree.getElementName(&len); 8639cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski if (ctag16 == NULL) { 8649cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski fprintf(stderr, "ERROR: failed to get XML element name (bad string pool)\n"); 8659cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski goto bail; 8669cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski } 8679cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski String8 tag(ctag16); 868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Depth %d tag %s\n", depth, tag.string()); 869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (depth == 1) { 870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag != "manifest") { 871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: manifest does not start with <manifest> tag\n"); 872282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 873282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 874282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 pkg = getAttribute(tree, NULL, "package", NULL); 8752675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("package: %s\n", ResTable::normalizeForOutput(pkg.string()).string()); 876282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (depth == 2 && tag == "permission") { 877282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 error; 878282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getAttribute(tree, NAME_ATTR, &error); 879282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 880282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: %s\n", error.string()); 881282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 882282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 8832675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("permission: %s\n", 8842675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(name.string()).string()); 885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (depth == 2 && tag == "uses-permission") { 886282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 error; 887282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getAttribute(tree, NAME_ATTR, &error); 888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: %s\n", error.string()); 890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 89258f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesPermission(name, 89358f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski getIntegerAttribute(tree, REQUIRED_ATTR, NULL, 1) == 0, 89458f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR, NULL, -1)); 895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("badging", option) == 0) { 898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<String8> locales; 899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res.getLocales(&locales); 900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<ResTable_config> configs; 902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res.getConfigurations(&configs); 903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SortedVector<int> densities; 904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NC = configs.size(); 905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<NC; i++) { 906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int dens = configs[i].density; 907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (dens == 0) { 908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dens = 160; 909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski densities.add(dens); 911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int depth = 0; 916282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 error; 917282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool withinActivity = false; 918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isMainActivity = false; 919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isLauncherActivity = false; 9200a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn bool isLeanbackLauncherActivity = false; 921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isSearchable = false; 922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool withinApplication = false; 923ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright bool withinSupportsInput = false; 9242c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski bool withinFeatureGroup = false; 925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool withinReceiver = false; 926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool withinService = false; 9279d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool withinProvider = false; 928282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool withinIntentFilter = false; 929282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasMainActivity = false; 930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasOtherActivities = false; 931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasOtherReceivers = false; 932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasOtherServices = false; 9339d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool hasIntentFilter = false; 9349d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski 935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasWallpaperService = false; 936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasImeService = false; 937a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool hasAccessibilityService = false; 938a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool hasPrintService = false; 939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasWidgetReceivers = false; 940a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool hasDeviceAdminReceiver = false; 94194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool hasPaymentService = false; 9429d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool hasDocumentsProvider = false; 9439d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool hasCameraActivity = false; 9449d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool hasCameraSecureActivity = false; 9459d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool hasLauncher = false; 9469d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool hasNotificationListenerService = false; 947eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock bool hasDreamService = false; 9489d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski 949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool actMainActivity = false; 950282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool actWidgetReceivers = false; 951a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool actDeviceAdminEnabled = false; 952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool actImeService = false; 953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool actWallpaperService = false; 954a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool actAccessibilityService = false; 955a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool actPrintService = false; 95694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool actHostApduService = false; 95794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool actOffHostApduService = false; 9589d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool actDocumentsProvider = false; 9599d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool actNotificationListenerService = false; 960eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock bool actDreamService = false; 9619d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool actCamera = false; 9629d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool actCameraSecure = false; 9639d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool catLauncher = false; 96494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool hasMetaHostPaymentCategory = false; 96594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool hasMetaOffHostPaymentCategory = false; 966a5018c900f126ee8424c82497f32983873db741bAdam Lesinski 967a5018c900f126ee8424c82497f32983873db741bAdam Lesinski // These permissions are required by services implementing services 968a5018c900f126ee8424c82497f32983873db741bAdam Lesinski // the system binds to (IME, Accessibility, PrintServices, etc.) 969a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool hasBindDeviceAdminPermission = false; 970a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool hasBindInputMethodPermission = false; 971a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool hasBindAccessibilityServicePermission = false; 972a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool hasBindPrintServicePermission = false; 97394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool hasBindNfcServicePermission = false; 9749d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool hasRequiredSafAttributes = false; 9759d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool hasBindNotificationListenerServicePermission = false; 976eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock bool hasBindDreamServicePermission = false; 977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // These two implement the implicit permissions that are granted 979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // to pre-1.6 applications. 980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasWriteExternalStoragePermission = false; 981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasReadPhoneStatePermission = false; 982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If an app requests write storage, they will also get read storage. 984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasReadExternalStoragePermission = false; 985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Implement transition to read and write call log. 987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasReadContactsPermission = false; 988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasWriteContactsPermission = false; 989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasReadCallLogPermission = false; 990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasWriteCallLogPermission = false; 991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 992e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // If an app declares itself as multiArch, we report the 993e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // native libraries differently. 994e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski bool hasMultiArch = false; 995e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski 996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // This next group of variables is used to implement a group of 997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // backward-compatibility heuristics necessitated by the addition of 998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // some new uses-feature constants in 2.1 and 2.2. In most cases, the 999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // heuristic is "if an app requests a permission but doesn't explicitly 1000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // request the corresponding <uses-feature>, presume it's there anyway". 10012c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 1002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // 2.2 also added some other features that apps can request, but that 1003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // have no corresponding permission, so we cannot implement any 1004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // back-compatibility heuristic for them. The below are thus unnecessary 1005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // (but are retained here for documentary purposes.) 1006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //bool specCompassFeature = false; 1007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //bool specAccelerometerFeature = false; 1008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //bool specProximityFeature = false; 1009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //bool specAmbientLightFeature = false; 1010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //bool specLiveWallpaperFeature = false; 1011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int targetSdk = 0; 1013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int smallScreen = 1; 1014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int normalScreen = 1; 1015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int largeScreen = 1; 1016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int xlargeScreen = 1; 1017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int anyDensity = 1; 1018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int requiresSmallestWidthDp = 0; 1019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int compatibleWidthLimitDp = 0; 1020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int largestWidthLimitDp = 0; 1021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 pkg; 1022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 activityName; 1023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 activityLabel; 1024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 activityIcon; 10250a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn String8 activityBanner; 1026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 receiverName; 1027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 serviceName; 1028ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright Vector<String8> supportedInput; 10292c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 10302c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski FeatureGroup commonFeatures; 10312c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski Vector<FeatureGroup> featureGroups; 10322c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski KeyedVector<String8, ImpliedFeature> impliedFeatures; 10332c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 1034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 1035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 1036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth--; 1037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (depth < 2) { 1038ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (withinSupportsInput && !supportedInput.isEmpty()) { 1039ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright printf("supports-input: '"); 1040ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright const size_t N = supportedInput.size(); 1041ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright for (size_t i=0; i<N; i++) { 10422675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("%s", ResTable::normalizeForOutput( 10432675f769673f69b0661ddee346292f25cb30a296Maurice Chu supportedInput[i].string()).string()); 1044ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (i != N - 1) { 1045ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright printf("' '"); 1046ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else { 1047ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright printf("'\n"); 1048ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1049ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1050ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright supportedInput.clear(); 1051ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinApplication = false; 1053ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright withinSupportsInput = false; 10542c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski withinFeatureGroup = false; 1055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (depth < 3) { 10560a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn if (withinActivity && isMainActivity) { 10572675f769673f69b0661ddee346292f25cb30a296Maurice Chu String8 aName(getComponentName(pkg, activityName)); 10580a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn if (isLauncherActivity) { 10590a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn printf("launchable-activity:"); 10609eaaaf0fe3917f4fec85d3e45da37914654847ecTim Kilbourn if (aName.length() > 0) { 10619eaaaf0fe3917f4fec85d3e45da37914654847ecTim Kilbourn printf(" name='%s' ", 10629eaaaf0fe3917f4fec85d3e45da37914654847ecTim Kilbourn ResTable::normalizeForOutput(aName.string()).string()); 10630a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn } 10640a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn printf(" label='%s' icon='%s'\n", 10659eaaaf0fe3917f4fec85d3e45da37914654847ecTim Kilbourn ResTable::normalizeForOutput(activityLabel.string()).string(), 10669eaaaf0fe3917f4fec85d3e45da37914654847ecTim Kilbourn ResTable::normalizeForOutput(activityIcon.string()).string()); 10670a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn } 10680a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn if (isLeanbackLauncherActivity) { 10690a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn printf("leanback-launchable-activity:"); 10709eaaaf0fe3917f4fec85d3e45da37914654847ecTim Kilbourn if (aName.length() > 0) { 10719eaaaf0fe3917f4fec85d3e45da37914654847ecTim Kilbourn printf(" name='%s' ", 10729eaaaf0fe3917f4fec85d3e45da37914654847ecTim Kilbourn ResTable::normalizeForOutput(aName.string()).string()); 10730a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn } 10740a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn printf(" label='%s' icon='%s' banner='%s'\n", 10759eaaaf0fe3917f4fec85d3e45da37914654847ecTim Kilbourn ResTable::normalizeForOutput(activityLabel.string()).string(), 10769eaaaf0fe3917f4fec85d3e45da37914654847ecTim Kilbourn ResTable::normalizeForOutput(activityIcon.string()).string(), 10779eaaaf0fe3917f4fec85d3e45da37914654847ecTim Kilbourn ResTable::normalizeForOutput(activityBanner.string()).string()); 1078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasIntentFilter) { 1081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasOtherActivities |= withinActivity; 1082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasOtherReceivers |= withinReceiver; 1083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasOtherServices |= withinService; 108494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else { 108594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (withinService) { 108694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasPaymentService |= (actHostApduService && hasMetaHostPaymentCategory && 108794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindNfcServicePermission); 108894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasPaymentService |= (actOffHostApduService && hasMetaOffHostPaymentCategory && 108994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindNfcServicePermission); 109094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 1091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1092282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinActivity = false; 1093282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinService = false; 1094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinReceiver = false; 10959d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski withinProvider = false; 1096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasIntentFilter = false; 10970a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn isMainActivity = isLauncherActivity = isLeanbackLauncherActivity = false; 1098282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (depth < 4) { 1099282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (withinIntentFilter) { 1100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (withinActivity) { 1101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasMainActivity |= actMainActivity; 11029d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasLauncher |= catLauncher; 11039d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasCameraActivity |= actCamera; 11049d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasCameraSecureActivity |= actCameraSecure; 11059d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasOtherActivities |= !actMainActivity && !actCamera && !actCameraSecure; 1106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (withinReceiver) { 1107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWidgetReceivers |= actWidgetReceivers; 1108a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasDeviceAdminReceiver |= (actDeviceAdminEnabled && 1109a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasBindDeviceAdminPermission); 1110a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasOtherReceivers |= (!actWidgetReceivers && !actDeviceAdminEnabled); 1111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (withinService) { 1112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasImeService |= actImeService; 1113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWallpaperService |= actWallpaperService; 1114a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasAccessibilityService |= (actAccessibilityService && 1115a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasBindAccessibilityServicePermission); 1116a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasPrintService |= (actPrintService && hasBindPrintServicePermission); 11179d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasNotificationListenerService |= actNotificationListenerService && 11189d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasBindNotificationListenerServicePermission; 1119eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock hasDreamService |= actDreamService && hasBindDreamServicePermission; 1120a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasOtherServices |= (!actImeService && !actWallpaperService && 112194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski !actAccessibilityService && !actPrintService && 11229d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski !actHostApduService && !actOffHostApduService && 11239d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski !actNotificationListenerService); 11249d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } else if (withinProvider) { 11259d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasDocumentsProvider |= actDocumentsProvider && hasRequiredSafAttributes; 1126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinIntentFilter = false; 1129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != ResXMLTree::START_TAG) { 1133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth++; 11369cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski 11379cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski const char16_t* ctag16 = tree.getElementName(&len); 11389cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski if (ctag16 == NULL) { 11399cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski fprintf(stderr, "ERROR: failed to get XML element name (bad string pool)\n"); 11409cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski goto bail; 11419cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski } 11429cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski String8 tag(ctag16); 1143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Depth %d, %s\n", depth, tag.string()); 1144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (depth == 1) { 1145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag != "manifest") { 1146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: manifest does not start with <manifest> tag\n"); 1147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pkg = getAttribute(tree, NULL, "package", NULL); 11502675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("package: name='%s' ", 11512675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(pkg.string()).string()); 1152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t versionCode = getIntegerAttribute(tree, VERSION_CODE_ATTR, &error); 1153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:versionCode' attribute: %s\n", error.string()); 1155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (versionCode > 0) { 1158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("versionCode='%d' ", versionCode); 1159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("versionCode='' "); 1161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 versionName = getResolvedAttribute(&res, tree, VERSION_NAME_ATTR, &error); 1163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:versionName' attribute: %s\n", error.string()); 1165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 116725d35a9d68fed6304352d0bfc2e0d581ed47f8b5Adam Lesinski printf("versionName='%s'", 11682675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(versionName.string()).string()); 116925d35a9d68fed6304352d0bfc2e0d581ed47f8b5Adam Lesinski 117025d35a9d68fed6304352d0bfc2e0d581ed47f8b5Adam Lesinski String8 splitName = getAttribute(tree, NULL, "split", NULL); 117125d35a9d68fed6304352d0bfc2e0d581ed47f8b5Adam Lesinski if (!splitName.isEmpty()) { 117225d35a9d68fed6304352d0bfc2e0d581ed47f8b5Adam Lesinski printf(" split='%s'", ResTable::normalizeForOutput( 117325d35a9d68fed6304352d0bfc2e0d581ed47f8b5Adam Lesinski splitName.string()).string()); 117425d35a9d68fed6304352d0bfc2e0d581ed47f8b5Adam Lesinski } 117525d35a9d68fed6304352d0bfc2e0d581ed47f8b5Adam Lesinski printf("\n"); 1176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (depth == 2) { 1177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinApplication = false; 1178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag == "application") { 1179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinApplication = true; 1180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 label; 1182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NL = locales.size(); 1183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<NL; i++) { 1184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* localeStr = locales[i].string(); 1185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets.setLocale(localeStr != NULL ? localeStr : ""); 1186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 llabel = getResolvedAttribute(&res, tree, LABEL_ATTR, &error); 1187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (llabel != "") { 1188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (localeStr == NULL || strlen(localeStr) == 0) { 1189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski label = llabel; 11902675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("application-label:'%s'\n", 11912675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(llabel.string()).string()); 1192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (label == "") { 1194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski label = llabel; 1195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("application-label-%s:'%s'\n", localeStr, 11972675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(llabel.string()).string()); 1198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_config tmpConfig = config; 1203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t ND = densities.size(); 1204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<ND; i++) { 1205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tmpConfig.density = densities[i]; 1206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets.setConfiguration(tmpConfig); 1207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 icon = getResolvedAttribute(&res, tree, ICON_ATTR, &error); 1208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (icon != "") { 12092675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("application-icon-%d:'%s'\n", densities[i], 12102675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(icon.string()).string()); 1211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets.setConfiguration(config); 1214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 icon = getResolvedAttribute(&res, tree, ICON_ATTR, &error); 1216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n", error.string()); 1218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t testOnly = getIntegerAttribute(tree, TEST_ONLY_ATTR, &error, 0); 1221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:testOnly' attribute: %s\n", error.string()); 1223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 12252675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("application: label='%s' ", 12262675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(label.string()).string()); 12272675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("icon='%s'\n", ResTable::normalizeForOutput(icon.string()).string()); 1228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (testOnly != 0) { 1229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("testOnly='%d'\n", testOnly); 1230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t debuggable = getResolvedIntegerAttribute(&res, tree, DEBUGGABLE_ATTR, &error, 0); 1233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:debuggable' attribute: %s\n", error.string()); 1235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (debuggable != 0) { 1238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("application-debuggable\n"); 1239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1240e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski 1241e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // We must search by name because the multiArch flag hasn't been API 1242e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // frozen yet. 1243e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski int32_t multiArchIndex = tree.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, 1244e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski "multiArch"); 1245e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski if (multiArchIndex >= 0) { 1246e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski Res_value value; 1247e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski if (tree.getAttributeValue(multiArchIndex, &value) != NO_ERROR) { 1248e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski if (value.dataType >= Res_value::TYPE_FIRST_INT && 1249e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski value.dataType <= Res_value::TYPE_LAST_INT) { 1250e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski hasMultiArch = value.data; 1251e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski } 1252e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski } 1253e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski } 1254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "uses-sdk") { 1255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t code = getIntegerAttribute(tree, MIN_SDK_VERSION_ATTR, &error); 1256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error = ""; 1258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getResolvedAttribute(&res, tree, MIN_SDK_VERSION_ATTR, &error); 1259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:minSdkVersion' attribute: %s\n", 1261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 1262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name == "Donut") targetSdk = 4; 12652675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("sdkVersion:'%s'\n", 12662675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(name.string()).string()); 1267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (code != -1) { 1268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski targetSdk = code; 1269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("sdkVersion:'%d'\n", code); 1270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski code = getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR, NULL, -1); 1272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != -1) { 1273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("maxSdkVersion:'%d'\n", code); 1274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski code = getIntegerAttribute(tree, TARGET_SDK_VERSION_ATTR, &error); 1276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error = ""; 1278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getResolvedAttribute(&res, tree, TARGET_SDK_VERSION_ATTR, &error); 1279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:targetSdkVersion' attribute: %s\n", 1281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 1282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name == "Donut" && targetSdk < 4) targetSdk = 4; 12852675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("targetSdkVersion:'%s'\n", 12862675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(name.string()).string()); 1287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (code != -1) { 1288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (targetSdk < code) { 1289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski targetSdk = code; 1290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("targetSdkVersion:'%d'\n", code); 1292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "uses-configuration") { 1294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t reqTouchScreen = getIntegerAttribute(tree, 1295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_TOUCH_SCREEN_ATTR, NULL, 0); 1296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t reqKeyboardType = getIntegerAttribute(tree, 1297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_KEYBOARD_TYPE_ATTR, NULL, 0); 1298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t reqHardKeyboard = getIntegerAttribute(tree, 1299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_HARD_KEYBOARD_ATTR, NULL, 0); 1300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t reqNavigation = getIntegerAttribute(tree, 1301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_NAVIGATION_ATTR, NULL, 0); 1302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t reqFiveWayNav = getIntegerAttribute(tree, 1303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_FIVE_WAY_NAV_ATTR, NULL, 0); 1304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-configuration:"); 1305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqTouchScreen != 0) { 1306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" reqTouchScreen='%d'", reqTouchScreen); 1307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqKeyboardType != 0) { 1309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" reqKeyboardType='%d'", reqKeyboardType); 1310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqHardKeyboard != 0) { 1312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" reqHardKeyboard='%d'", reqHardKeyboard); 1313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqNavigation != 0) { 1315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" reqNavigation='%d'", reqNavigation); 1316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqFiveWayNav != 0) { 1318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" reqFiveWayNav='%d'", reqFiveWayNav); 1319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 1321ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (tag == "supports-input") { 1322ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright withinSupportsInput = true; 1323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "supports-screens") { 1324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski smallScreen = getIntegerAttribute(tree, 1325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SMALL_SCREEN_ATTR, NULL, 1); 1326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski normalScreen = getIntegerAttribute(tree, 1327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NORMAL_SCREEN_ATTR, NULL, 1); 1328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski largeScreen = getIntegerAttribute(tree, 1329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LARGE_SCREEN_ATTR, NULL, 1); 1330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski xlargeScreen = getIntegerAttribute(tree, 1331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski XLARGE_SCREEN_ATTR, NULL, 1); 1332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski anyDensity = getIntegerAttribute(tree, 1333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ANY_DENSITY_ATTR, NULL, 1); 1334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski requiresSmallestWidthDp = getIntegerAttribute(tree, 1335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQUIRES_SMALLEST_WIDTH_DP_ATTR, NULL, 0); 1336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski compatibleWidthLimitDp = getIntegerAttribute(tree, 1337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski COMPATIBLE_WIDTH_LIMIT_DP_ATTR, NULL, 0); 1338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski largestWidthLimitDp = getIntegerAttribute(tree, 1339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LARGEST_WIDTH_LIMIT_DP_ATTR, NULL, 0); 13402c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } else if (tag == "feature-group") { 13412c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski withinFeatureGroup = true; 13422c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski FeatureGroup group; 13432c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski group.label = getResolvedAttribute(&res, tree, LABEL_ATTR, &error); 13442c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (error != "") { 13452c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski fprintf(stderr, "ERROR getting 'android:label' attribute:" 13462c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski " %s\n", error.string()); 13472c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski goto bail; 13482c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 13492c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski featureGroups.add(group); 13502c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 1351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "uses-feature") { 1352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getAttribute(tree, NAME_ATTR, &error); 1353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 1354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int req = getIntegerAttribute(tree, 1355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQUIRED_ATTR, NULL, 1); 1356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 13572c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski commonFeatures.features.add(name, req); 13582c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (req) { 13592c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addParentFeatures(&commonFeatures, name); 1360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int vers = getIntegerAttribute(tree, 1363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski GL_ES_VERSION_ATTR, &error); 1364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error == "") { 1365d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski if (vers > commonFeatures.openGLESVersion) { 1366d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski commonFeatures.openGLESVersion = vers; 1367d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski } 1368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "uses-permission") { 1371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getAttribute(tree, NAME_ATTR, &error); 1372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 1373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name == "android.permission.CAMERA") { 1374d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.camera", 13752c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8::format("requested %s permission", name.string()) 13762c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski .string()); 1377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.ACCESS_FINE_LOCATION") { 13782c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.location.gps", 13792c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8::format("requested %s permission", name.string()) 13802c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski .string()); 13812c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.location", 13822c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8::format("requested %s permission", name.string()) 13832c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski .string()); 1384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.ACCESS_MOCK_LOCATION") { 13852c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.location", 13862c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8::format("requested %s permission", name.string()) 13872c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski .string()); 1388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.ACCESS_COARSE_LOCATION") { 13892c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.location.network", 13902c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8::format("requested %s permission", name.string()) 13912c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski .string()); 13922c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.location", 13932c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8::format("requested %s permission", name.string()) 13942c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski .string()); 1395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" || 1396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.INSTALL_LOCATION_PROVIDER") { 13972c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.location", 13982c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8::format("requested %s permission", name.string()) 13992c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski .string()); 1400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.BLUETOOTH" || 1401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.BLUETOOTH_ADMIN") { 14022c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (targetSdk > 4) { 14032c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.bluetooth", 14042c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8::format("requested %s permission", name.string()) 14052c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski .string()); 14062c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.bluetooth", 14072c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski "targetSdkVersion > 4"); 14082c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 1409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.RECORD_AUDIO") { 14102c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.microphone", 14112c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8::format("requested %s permission", name.string()) 14122c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski .string()); 1413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.ACCESS_WIFI_STATE" || 1414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.CHANGE_WIFI_STATE" || 1415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.CHANGE_WIFI_MULTICAST_STATE") { 14162c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.wifi", 14172c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8::format("requested %s permission", name.string()) 14182c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski .string()); 1419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.CALL_PHONE" || 1420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.CALL_PRIVILEGED" || 1421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.MODIFY_PHONE_STATE" || 1422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.PROCESS_OUTGOING_CALLS" || 1423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.READ_SMS" || 1424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.RECEIVE_SMS" || 1425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.RECEIVE_MMS" || 1426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.RECEIVE_WAP_PUSH" || 1427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.SEND_SMS" || 1428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.WRITE_APN_SETTINGS" || 1429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.WRITE_SMS") { 14302c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.telephony", 14312c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8("requested a telephony permission").string()); 1432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.WRITE_EXTERNAL_STORAGE") { 1433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWriteExternalStoragePermission = true; 1434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.READ_EXTERNAL_STORAGE") { 1435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasReadExternalStoragePermission = true; 1436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.READ_PHONE_STATE") { 1437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasReadPhoneStatePermission = true; 1438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.READ_CONTACTS") { 1439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasReadContactsPermission = true; 1440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.WRITE_CONTACTS") { 1441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWriteContactsPermission = true; 1442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.READ_CALL_LOG") { 1443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasReadCallLogPermission = true; 1444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.WRITE_CALL_LOG") { 1445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWriteCallLogPermission = true; 1446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 144758f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski 144858f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesPermission(name, 144958f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski getIntegerAttribute(tree, REQUIRED_ATTR, NULL, 1) == 0, 145058f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR, NULL, -1)); 145158f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski } else { 1452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 1454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "uses-package") { 1457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getAttribute(tree, NAME_ATTR, &error); 1458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 14592675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("uses-package:'%s'\n", 14602675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(name.string()).string()); 1461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 1464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "original-package") { 1467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getAttribute(tree, NAME_ATTR, &error); 1468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 14692675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("original-package:'%s'\n", 14702675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(name.string()).string()); 1471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 1474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "supports-gl-texture") { 1477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getAttribute(tree, NAME_ATTR, &error); 1478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 14792675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("supports-gl-texture:'%s'\n", 14802675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(name.string()).string()); 1481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 1484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "compatible-screens") { 14879cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski printCompatibleScreens(tree, &error); 14889cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski if (error != "") { 14899cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski fprintf(stderr, "ERROR getting compatible screens: %s\n", 14909cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski error.string()); 14919cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski goto bail; 14929cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski } 1493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth--; 1494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "package-verifier") { 1495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getAttribute(tree, NAME_ATTR, &error); 1496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 1497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 publicKey = getAttribute(tree, PUBLIC_KEY_ATTR, &error); 1498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (publicKey != "" && error == "") { 1499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("package-verifier: name='%s' publicKey='%s'\n", 15002675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(name.string()).string(), 15012675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(publicKey.string()).string()); 1502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1505ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (depth == 3) { 1506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinActivity = false; 1507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinReceiver = false; 1508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinService = false; 15099d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski withinProvider = false; 1510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasIntentFilter = false; 151194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasMetaHostPaymentCategory = false; 151294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasMetaOffHostPaymentCategory = false; 151394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindDeviceAdminPermission = false; 151494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindInputMethodPermission = false; 151594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindAccessibilityServicePermission = false; 151694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindPrintServicePermission = false; 151794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindNfcServicePermission = false; 15189d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasRequiredSafAttributes = false; 15199d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasBindNotificationListenerServicePermission = false; 1520eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock hasBindDreamServicePermission = false; 1521ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (withinApplication) { 1522ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if(tag == "activity") { 1523ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright withinActivity = true; 1524ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright activityName = getAttribute(tree, NAME_ATTR, &error); 1525ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1526ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1527ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright error.string()); 1528ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1529ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1531ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright activityLabel = getResolvedAttribute(&res, tree, LABEL_ATTR, &error); 1532ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1533ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:label' attribute: %s\n", 1534ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright error.string()); 1535ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1536ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1538ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright activityIcon = getResolvedAttribute(&res, tree, ICON_ATTR, &error); 1539ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1540ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n", 1541ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright error.string()); 1542ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1543ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 15450a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn activityBanner = getResolvedAttribute(&res, tree, BANNER_ATTR, &error); 15460a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn if (error != "") { 15470a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn fprintf(stderr, "ERROR getting 'android:banner' attribute: %s\n", 15480a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn error.string()); 15490a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn goto bail; 15500a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn } 15510a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn 1552ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright int32_t orien = getResolvedIntegerAttribute(&res, tree, 1553ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright SCREEN_ORIENTATION_ATTR, &error); 1554ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error == "") { 1555ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (orien == 0 || orien == 6 || orien == 8) { 1556ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright // Requests landscape, sensorLandscape, or reverseLandscape. 15572c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.screen.landscape", 15582c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski "one or more activities have specified a landscape orientation"); 1559ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (orien == 1 || orien == 7 || orien == 9) { 1560ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright // Requests portrait, sensorPortrait, or reversePortrait. 15612c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.screen.portrait", 15622c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski "one or more activities have specified a portrait orientation"); 1563ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1565ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (tag == "uses-library") { 1566ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright String8 libraryName = getAttribute(tree, NAME_ATTR, &error); 1567ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1568ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, 1569ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright "ERROR getting 'android:name' attribute for uses-library" 1570ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright " %s\n", error.string()); 1571ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1572ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1573ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright int req = getIntegerAttribute(tree, 1574ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright REQUIRED_ATTR, NULL, 1); 1575ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright printf("uses-library%s:'%s'\n", 15762675f769673f69b0661ddee346292f25cb30a296Maurice Chu req ? "" : "-not-required", ResTable::normalizeForOutput( 15772675f769673f69b0661ddee346292f25cb30a296Maurice Chu libraryName.string()).string()); 1578ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (tag == "receiver") { 1579ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright withinReceiver = true; 1580ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright receiverName = getAttribute(tree, NAME_ATTR, &error); 1581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1582ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1583ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, 1584ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright "ERROR getting 'android:name' attribute for receiver:" 1585ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright " %s\n", error.string()); 1586ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1587ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1588a5018c900f126ee8424c82497f32983873db741bAdam Lesinski 1589a5018c900f126ee8424c82497f32983873db741bAdam Lesinski String8 permission = getAttribute(tree, PERMISSION_ATTR, &error); 1590a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (error == "") { 1591a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (permission == "android.permission.BIND_DEVICE_ADMIN") { 1592a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasBindDeviceAdminPermission = true; 1593a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1594a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else { 1595a5018c900f126ee8424c82497f32983873db741bAdam Lesinski fprintf(stderr, "ERROR getting 'android:permission' attribute for" 1596a5018c900f126ee8424c82497f32983873db741bAdam Lesinski " receiver '%s': %s\n", receiverName.string(), error.string()); 1597a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1598ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (tag == "service") { 1599ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright withinService = true; 1600ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright serviceName = getAttribute(tree, NAME_ATTR, &error); 1601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1602ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1603ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:name' attribute for " 1604ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright "service:%s\n", error.string()); 1605ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1606ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1607a5018c900f126ee8424c82497f32983873db741bAdam Lesinski 1608a5018c900f126ee8424c82497f32983873db741bAdam Lesinski String8 permission = getAttribute(tree, PERMISSION_ATTR, &error); 1609a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (error == "") { 1610a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (permission == "android.permission.BIND_INPUT_METHOD") { 1611a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasBindInputMethodPermission = true; 1612a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if (permission == "android.permission.BIND_ACCESSIBILITY_SERVICE") { 1613a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasBindAccessibilityServicePermission = true; 1614a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if (permission == "android.permission.BIND_PRINT_SERVICE") { 1615a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasBindPrintServicePermission = true; 161694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else if (permission == "android.permission.BIND_NFC_SERVICE") { 161794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindNfcServicePermission = true; 16189d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } else if (permission == "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE") { 16199d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasBindNotificationListenerServicePermission = true; 1620eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock } else if (permission == "android.permission.BIND_DREAM_SERVICE") { 1621eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock hasBindDreamServicePermission = true; 1622a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1623a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else { 1624a5018c900f126ee8424c82497f32983873db741bAdam Lesinski fprintf(stderr, "ERROR getting 'android:permission' attribute for" 1625a5018c900f126ee8424c82497f32983873db741bAdam Lesinski " service '%s': %s\n", serviceName.string(), error.string()); 1626a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 16279d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } else if (tag == "provider") { 16289d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski withinProvider = true; 16299d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski 16309d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool exported = getResolvedIntegerAttribute(&res, tree, EXPORTED_ATTR, &error); 16319d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (error != "") { 16329d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski fprintf(stderr, "ERROR getting 'android:exported' attribute for provider:" 16339d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski " %s\n", error.string()); 16349d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski goto bail; 16359d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 16369d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski 16379d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool grantUriPermissions = getResolvedIntegerAttribute(&res, tree, 16389d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski GRANT_URI_PERMISSIONS_ATTR, &error); 16399d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (error != "") { 16409d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski fprintf(stderr, "ERROR getting 'android:grantUriPermissions' attribute for provider:" 16419d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski " %s\n", error.string()); 16429d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski goto bail; 16439d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 16449d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski 16459d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski String8 permission = getResolvedAttribute(&res, tree, PERMISSION_ATTR, &error); 16469d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (error != "") { 16479d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski fprintf(stderr, "ERROR getting 'android:permission' attribute for provider:" 16489d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski " %s\n", error.string()); 16499d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski goto bail; 16509d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 16519d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski 16529d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasRequiredSafAttributes |= exported && grantUriPermissions && 16539d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski permission == "android.permission.MANAGE_DOCUMENTS"; 16549d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski 1655ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (bundle->getIncludeMetaData() && tag == "meta-data") { 1656b71adb6571aa740f4fa794602133f708e1b96545Adam Lesinski String8 metaDataName = getResolvedAttribute(&res, tree, NAME_ATTR, &error); 1657ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1658ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:name' attribute for " 1659ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright "meta-data:%s\n", error.string()); 1660ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1661ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 16622675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("meta-data: name='%s' ", 16632675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(metaDataName.string()).string()); 166476327314d2238e105f8b94909f9c0cf85caca318Maurice Chu printResolvedResourceAttribute(&res, tree, VALUE_ATTR, String8("value"), 166576327314d2238e105f8b94909f9c0cf85caca318Maurice Chu &error); 1666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 166776327314d2238e105f8b94909f9c0cf85caca318Maurice Chu // Try looking for a RESOURCE_ATTR 166876327314d2238e105f8b94909f9c0cf85caca318Maurice Chu error = ""; 166976327314d2238e105f8b94909f9c0cf85caca318Maurice Chu printResolvedResourceAttribute(&res, tree, RESOURCE_ATTR, 167076327314d2238e105f8b94909f9c0cf85caca318Maurice Chu String8("resource"), &error); 1671ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 167276327314d2238e105f8b94909f9c0cf85caca318Maurice Chu fprintf(stderr, "ERROR getting 'android:value' or " 167376327314d2238e105f8b94909f9c0cf85caca318Maurice Chu "'android:resource' attribute for " 167476327314d2238e105f8b94909f9c0cf85caca318Maurice Chu "meta-data:%s\n", error.string()); 1675ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1676ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1677ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 167876327314d2238e105f8b94909f9c0cf85caca318Maurice Chu printf("\n"); 1679ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (withinSupportsInput && tag == "input-type") { 1680ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright String8 name = getAttribute(tree, NAME_ATTR, &error); 1681ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (name != "" && error == "") { 1682ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright supportedInput.add(name); 1683ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else { 1684ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1685ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright error.string()); 1686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 16892c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } else if (withinFeatureGroup && tag == "uses-feature") { 1690d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski FeatureGroup& top = featureGroups.editTop(); 1691d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski 16922c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8 name = getResolvedAttribute(&res, tree, NAME_ATTR, &error); 1693d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski if (name != "" && error == "") { 1694d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski top.features.add(name, true); 1695d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski addParentFeatures(&top, name); 1696d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski } else { 1697d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski int vers = getIntegerAttribute(tree, GL_ES_VERSION_ATTR, &error); 1698d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski if (error == "") { 1699d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski if (vers > top.openGLESVersion) { 1700d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski top.openGLESVersion = vers; 1701d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski } 1702d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski } 17032c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 1704a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 170594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else if (depth == 4) { 170694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (tag == "intent-filter") { 170794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasIntentFilter = true; 170894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski withinIntentFilter = true; 170994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actMainActivity = false; 171094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actWidgetReceivers = false; 171194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actImeService = false; 171294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actWallpaperService = false; 171394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actAccessibilityService = false; 171494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actPrintService = false; 171594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actDeviceAdminEnabled = false; 171694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actHostApduService = false; 171794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actOffHostApduService = false; 17189d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski actDocumentsProvider = false; 17199d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski actNotificationListenerService = false; 1720eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock actDreamService = false; 17219d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski actCamera = false; 17229d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski actCameraSecure = false; 17239d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski catLauncher = false; 172494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else if (withinService && tag == "meta-data") { 172594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski String8 name = getAttribute(tree, NAME_ATTR, &error); 172694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (error != "") { 172794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute for" 172894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski " meta-data tag in service '%s': %s\n", serviceName.string(), error.string()); 172994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski goto bail; 173094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 173194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 173294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (name == "android.nfc.cardemulation.host_apdu_service" || 173394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski name == "android.nfc.cardemulation.off_host_apdu_service") { 173494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool offHost = true; 173594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (name == "android.nfc.cardemulation.host_apdu_service") { 173694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski offHost = false; 173794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 173894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 173994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski String8 xmlPath = getResolvedAttribute(&res, tree, RESOURCE_ATTR, &error); 174094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (error != "") { 174194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski fprintf(stderr, "ERROR getting 'android:resource' attribute for" 174294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski " meta-data tag in service '%s': %s\n", serviceName.string(), error.string()); 174394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski goto bail; 174494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 174594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 174694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski Vector<String8> categories = getNfcAidCategories(assets, xmlPath, 174794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski offHost, &error); 174894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (error != "") { 174994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski fprintf(stderr, "ERROR getting AID category for service '%s'\n", 175094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski serviceName.string()); 175194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski goto bail; 175294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 175394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 175494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski const size_t catLen = categories.size(); 175594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski for (size_t i = 0; i < catLen; i++) { 175694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool paymentCategory = (categories[i] == "payment"); 175794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (offHost) { 175894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasMetaOffHostPaymentCategory |= paymentCategory; 175994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else { 176094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasMetaHostPaymentCategory |= paymentCategory; 176194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 176294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 176394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 176494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 1765a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if ((depth == 5) && withinIntentFilter) { 1766a5018c900f126ee8424c82497f32983873db741bAdam Lesinski String8 action; 1767a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (tag == "action") { 1768a5018c900f126ee8424c82497f32983873db741bAdam Lesinski action = getAttribute(tree, NAME_ATTR, &error); 1769a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (error != "") { 1770a5018c900f126ee8424c82497f32983873db741bAdam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1771a5018c900f126ee8424c82497f32983873db741bAdam Lesinski error.string()); 1772a5018c900f126ee8424c82497f32983873db741bAdam Lesinski goto bail; 1773a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1774a5018c900f126ee8424c82497f32983873db741bAdam Lesinski 1775a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (withinActivity) { 1776a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (action == "android.intent.action.MAIN") { 1777a5018c900f126ee8424c82497f32983873db741bAdam Lesinski isMainActivity = true; 1778a5018c900f126ee8424c82497f32983873db741bAdam Lesinski actMainActivity = true; 17799d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } else if (action == "android.media.action.STILL_IMAGE_CAMERA" || 17809d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski action == "android.media.action.VIDEO_CAMERA") { 17819d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski actCamera = true; 17829d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } else if (action == "android.media.action.STILL_IMAGE_CAMERA_SECURE") { 17839d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski actCameraSecure = true; 1784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1785a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if (withinReceiver) { 1786a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (action == "android.appwidget.action.APPWIDGET_UPDATE") { 1787a5018c900f126ee8424c82497f32983873db741bAdam Lesinski actWidgetReceivers = true; 1788a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if (action == "android.app.action.DEVICE_ADMIN_ENABLED") { 1789a5018c900f126ee8424c82497f32983873db741bAdam Lesinski actDeviceAdminEnabled = true; 1790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1791a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if (withinService) { 1792a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (action == "android.view.InputMethod") { 1793a5018c900f126ee8424c82497f32983873db741bAdam Lesinski actImeService = true; 1794a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if (action == "android.service.wallpaper.WallpaperService") { 1795a5018c900f126ee8424c82497f32983873db741bAdam Lesinski actWallpaperService = true; 1796a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if (action == "android.accessibilityservice.AccessibilityService") { 1797a5018c900f126ee8424c82497f32983873db741bAdam Lesinski actAccessibilityService = true; 1798a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if (action == "android.printservice.PrintService") { 1799a5018c900f126ee8424c82497f32983873db741bAdam Lesinski actPrintService = true; 180094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else if (action == "android.nfc.cardemulation.action.HOST_APDU_SERVICE") { 180194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actHostApduService = true; 180294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else if (action == "android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE") { 180394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actOffHostApduService = true; 18049d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } else if (action == "android.service.notification.NotificationListenerService") { 18059d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski actNotificationListenerService = true; 1806eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock } else if (action == "android.service.dreams.DreamService") { 1807eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock actDreamService = true; 18089d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 18099d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } else if (withinProvider) { 18109d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (action == "android.content.action.DOCUMENTS_PROVIDER") { 18119d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski actDocumentsProvider = true; 1812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1814a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (action == "android.intent.action.SEARCH") { 1815a5018c900f126ee8424c82497f32983873db741bAdam Lesinski isSearchable = true; 1816a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1817a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1819a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (tag == "category") { 1820a5018c900f126ee8424c82497f32983873db741bAdam Lesinski String8 category = getAttribute(tree, NAME_ATTR, &error); 1821a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (error != "") { 1822a5018c900f126ee8424c82497f32983873db741bAdam Lesinski fprintf(stderr, "ERROR getting 'name' attribute: %s\n", 1823a5018c900f126ee8424c82497f32983873db741bAdam Lesinski error.string()); 1824a5018c900f126ee8424c82497f32983873db741bAdam Lesinski goto bail; 1825a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1826a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (withinActivity) { 1827a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (category == "android.intent.category.LAUNCHER") { 1828a5018c900f126ee8424c82497f32983873db741bAdam Lesinski isLauncherActivity = true; 18290a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn } else if (category == "android.intent.category.LEANBACK_LAUNCHER") { 18300a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn isLeanbackLauncherActivity = true; 18319d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } else if (category == "android.intent.category.HOME") { 18329d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski catLauncher = true; 1833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Pre-1.6 implicitly granted permission compatibility logic 1840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (targetSdk < 4) { 1841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasWriteExternalStoragePermission) { 184258f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesPermission(String8("android.permission.WRITE_EXTERNAL_STORAGE")); 184358f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesImpliedPermission(String8("android.permission.WRITE_EXTERNAL_STORAGE"), 184458f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski String8("targetSdkVersion < 4")); 1845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWriteExternalStoragePermission = true; 1846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasReadPhoneStatePermission) { 184858f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesPermission(String8("android.permission.READ_PHONE_STATE")); 184958f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesImpliedPermission(String8("android.permission.READ_PHONE_STATE"), 185058f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski String8("targetSdkVersion < 4")); 1851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If the application has requested WRITE_EXTERNAL_STORAGE, we will 1855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // force them to always take READ_EXTERNAL_STORAGE as well. We always 1856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // do this (regardless of target API version) because we can't have 1857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // an app with write permission but not read permission. 1858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasReadExternalStoragePermission && hasWriteExternalStoragePermission) { 185958f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesPermission(String8("android.permission.READ_EXTERNAL_STORAGE")); 186058f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesImpliedPermission(String8("android.permission.READ_EXTERNAL_STORAGE"), 186158f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski String8("requested WRITE_EXTERNAL_STORAGE")); 1862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Pre-JellyBean call log permission compatibility. 1865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (targetSdk < 16) { 1866282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasReadCallLogPermission && hasReadContactsPermission) { 186758f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesPermission(String8("android.permission.READ_CALL_LOG")); 186858f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesImpliedPermission(String8("android.permission.READ_CALL_LOG"), 186958f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski String8("targetSdkVersion < 16 and requested READ_CONTACTS")); 1870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasWriteCallLogPermission && hasWriteContactsPermission) { 187258f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesPermission(String8("android.permission.WRITE_CALL_LOG")); 187358f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesImpliedPermission(String8("android.permission.WRITE_CALL_LOG"), 187458f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski String8("targetSdkVersion < 16 and requested WRITE_CONTACTS")); 1875282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1876282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1877282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 18782c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.touchscreen", 18792c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski "default feature for all apps"); 18802c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 18812c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski const size_t numFeatureGroups = featureGroups.size(); 18822c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (numFeatureGroups == 0) { 18832c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski // If no <feature-group> tags were defined, apply auto-implied features. 18842c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski printFeatureGroup(commonFeatures, &impliedFeatures); 18852c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 18862c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } else { 18872c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski // <feature-group> tags are defined, so we ignore implied features and 18882c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski for (size_t i = 0; i < numFeatureGroups; i++) { 18892c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski FeatureGroup& grp = featureGroups.editItemAt(i); 18902c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 1891d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski if (commonFeatures.openGLESVersion > grp.openGLESVersion) { 1892d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski grp.openGLESVersion = commonFeatures.openGLESVersion; 1893d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski } 1894d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski 18952c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski // Merge the features defined in the top level (not inside a <feature-group>) 18962c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski // with this feature group. 18972c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski const size_t numCommonFeatures = commonFeatures.features.size(); 18982c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski for (size_t j = 0; j < numCommonFeatures; j++) { 18992c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (grp.features.indexOfKey(commonFeatures.features.keyAt(j)) < 0) { 1900d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski grp.features.add(commonFeatures.features.keyAt(j), 1901d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski commonFeatures.features[j]); 19022c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 1903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 19052c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (!grp.features.isEmpty()) { 19062c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski printFeatureGroup(grp); 19072c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 1908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 19112c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 1912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasWidgetReceivers) { 19139d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("app-widget"); 1914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1915a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (hasDeviceAdminReceiver) { 19169d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("device-admin"); 1917a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasImeService) { 19199d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("ime"); 1920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasWallpaperService) { 19229d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("wallpaper"); 1923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1924a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (hasAccessibilityService) { 19259d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("accessibility"); 1926a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1927a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (hasPrintService) { 19289d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("print-service"); 1929a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 193094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (hasPaymentService) { 19319d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("payment"); 19329d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 19339d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (isSearchable) { 19349d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("search"); 19359d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 19369d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (hasDocumentsProvider) { 19379d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("document-provider"); 19389d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 19399d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (hasLauncher) { 19409d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("launcher"); 19419d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 19429d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (hasNotificationListenerService) { 19439d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("notification-listener"); 19449d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 1945eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock if (hasDreamService) { 1946eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock printComponentPresence("dream"); 1947eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock } 19489d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (hasCameraActivity) { 19499d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("camera"); 19509d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 19519d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (hasCameraSecureActivity) { 19529d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("camera-secure"); 19539d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 19549d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski 19559d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (hasMainActivity) { 19569d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printf("main\n"); 195794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 1958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasOtherActivities) { 1959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("other-activities\n"); 1960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 19619d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (hasOtherReceivers) { 1962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("other-receivers\n"); 1963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasOtherServices) { 1965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("other-services\n"); 1966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // For modern apps, if screen size buckets haven't been specified 1969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // but the new width ranges have, then infer the buckets from them. 1970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (smallScreen > 0 && normalScreen > 0 && largeScreen > 0 && xlargeScreen > 0 1971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && requiresSmallestWidthDp > 0) { 1972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int compatWidth = compatibleWidthLimitDp; 1973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (compatWidth <= 0) { 1974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski compatWidth = requiresSmallestWidthDp; 1975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (requiresSmallestWidthDp <= 240 && compatWidth >= 240) { 1977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski smallScreen = -1; 1978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski smallScreen = 0; 1980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (requiresSmallestWidthDp <= 320 && compatWidth >= 320) { 1982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski normalScreen = -1; 1983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski normalScreen = 0; 1985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (requiresSmallestWidthDp <= 480 && compatWidth >= 480) { 1987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski largeScreen = -1; 1988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski largeScreen = 0; 1990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (requiresSmallestWidthDp <= 720 && compatWidth >= 720) { 1992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski xlargeScreen = -1; 1993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski xlargeScreen = 0; 1995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Determine default values for any unspecified screen sizes, 1999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // based on the target SDK of the package. As of 4 (donut) 2000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the screen size support was introduced, so all default to 2001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // enabled. 2002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (smallScreen > 0) { 2003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski smallScreen = targetSdk >= 4 ? -1 : 0; 2004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (normalScreen > 0) { 2006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski normalScreen = -1; 2007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (largeScreen > 0) { 2009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski largeScreen = targetSdk >= 4 ? -1 : 0; 2010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (xlargeScreen > 0) { 2012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Introduced in Gingerbread. 2013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski xlargeScreen = targetSdk >= 9 ? -1 : 0; 2014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (anyDensity > 0) { 2016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski anyDensity = (targetSdk >= 4 || requiresSmallestWidthDp > 0 2017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || compatibleWidthLimitDp > 0) ? -1 : 0; 2018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("supports-screens:"); 2020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (smallScreen != 0) { 2021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" 'small'"); 2022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (normalScreen != 0) { 2024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" 'normal'"); 2025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (largeScreen != 0) { 2027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" 'large'"); 2028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (xlargeScreen != 0) { 2030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" 'xlarge'"); 2031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 2033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("supports-any-density: '%s'\n", anyDensity ? "true" : "false"); 2034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (requiresSmallestWidthDp > 0) { 2035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("requires-smallest-width:'%d'\n", requiresSmallestWidthDp); 2036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (compatibleWidthLimitDp > 0) { 2038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("compatible-width-limit:'%d'\n", compatibleWidthLimitDp); 2039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (largestWidthLimitDp > 0) { 2041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("largest-width-limit:'%d'\n", largestWidthLimitDp); 2042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("locales:"); 2045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NL = locales.size(); 2046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<NL; i++) { 2047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* localeStr = locales[i].string(); 2048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (localeStr == NULL || strlen(localeStr) == 0) { 2049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski localeStr = "--_--"; 2050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" '%s'", localeStr); 2052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 2054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("densities:"); 2056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t ND = densities.size(); 2057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<ND; i++) { 2058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" '%d'", densities[i]); 2059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 2061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AssetDir* dir = assets.openNonAssetDir(assetsCookie, "lib"); 2063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (dir != NULL) { 2064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (dir->getFileCount() > 0) { 2065e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski SortedVector<String8> architectures; 2066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<dir->getFileCount(); i++) { 2067e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski architectures.add(ResTable::normalizeForOutput( 2068e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski dir->getFileName(i).string())); 2069e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski } 2070e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski 2071e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski bool outputAltNativeCode = false; 2072e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // A multiArch package is one that contains 64-bit and 2073e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // 32-bit versions of native code and expects 3rd-party 2074e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // apps to load these native code libraries. Since most 2075e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // 64-bit systems also support 32-bit apps, the apps 2076e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // loading this multiArch package's code may be either 2077e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // 32-bit or 64-bit. 2078e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski if (hasMultiArch) { 2079e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // If this is a multiArch package, report the 64-bit 2080e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // version only. Then as a separate entry, report the 2081e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // rest. 2082e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // 2083e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // If we report the 32-bit architecture, this APK will 2084e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // be installed on a 32-bit device, causing a large waste 2085e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // of bandwidth and disk space. This assumes that 2086e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // the developer of the multiArch package has also 2087e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // made a version that is 32-bit only. 2088e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski String8 intel64("x86_64"); 2089e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski String8 arm64("arm64-v8a"); 2090e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski ssize_t index = architectures.indexOf(intel64); 2091e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski if (index < 0) { 2092e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski index = architectures.indexOf(arm64); 2093e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski } 2094e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski 2095e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski if (index >= 0) { 2096e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski printf("native-code: '%s'\n", architectures[index].string()); 2097e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski architectures.removeAt(index); 2098e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski outputAltNativeCode = true; 2099e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski } 2100e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski } 2101e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski 2102e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski const size_t archCount = architectures.size(); 2103e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski if (archCount > 0) { 2104e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski if (outputAltNativeCode) { 2105e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski printf("alt-"); 2106e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski } 2107e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski printf("native-code:"); 2108e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski for (size_t i = 0; i < archCount; i++) { 2109e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski printf(" '%s'", architectures[i].string()); 2110e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski } 2111e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski printf("\n"); 2112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete dir; 2115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("badger", option) == 0) { 2117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%s", CONSOLE_DATA); 2118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("configurations", option) == 0) { 2119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<ResTable_config> configs; 2120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res.getConfigurations(&configs); 2121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = configs.size(); 2122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 2123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%s\n", configs[i].toString().string()); 2124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: unknown dump option '%s'\n", option); 2127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = NO_ERROR; 2132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 2134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (asset) { 2135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete asset; 2136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (result != NO_ERROR); 2138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 2142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Handle the "add" command, which wants to add files to a new or 2143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * pre-existing archive. 2144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 2145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doAdd(Bundle* bundle) 2146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipFile* zip = NULL; 2148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result = UNKNOWN_ERROR; 2149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* zipFileName; 2150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getUpdate()) { 2152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* avoid confusion */ 2153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: can't use '-u' with add\n"); 2154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 1) { 2158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: must specify zip file name\n"); 2159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zipFileName = bundle->getFileSpecEntry(0); 2162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 2) { 2164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "NOTE: nothing to do\n"); 2165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip = openReadWrite(zipFileName, true); 2169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (zip == NULL) { 2170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: failed opening/creating '%s' as Zip file\n", zipFileName); 2171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i = 1; i < bundle->getFileSpecCount(); i++) { 2175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* fileName = bundle->getFileSpecEntry(i); 2176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcasecmp(String8(fileName).getPathExtension().string(), ".gz") == 0) { 2178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" '%s'... (from gzip)\n", fileName); 2179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = zip->addGzip(fileName, String8(fileName).getBasePath().string(), NULL); 2180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getJunkPath()) { 2182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 storageName = String8(fileName).getPathLeaf(); 21832675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf(" '%s' as '%s'...\n", fileName, 21842675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(storageName.string()).string()); 2185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = zip->add(fileName, storageName.string(), 2186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bundle->getCompressionMethod(), NULL); 2187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" '%s'...\n", fileName); 2189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = zip->add(fileName, bundle->getCompressionMethod(), NULL); 2190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result != NO_ERROR) { 2193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "Unable to add '%s' to '%s'", bundle->getFileSpecEntry(i), zipFileName); 2194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result == NAME_NOT_FOUND) { 2195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, ": file not found\n"); 2196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (result == ALREADY_EXISTS) { 2197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, ": already exists in archive\n"); 2198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "\n"); 2200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = NO_ERROR; 2206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 2208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete zip; 2209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (result != NO_ERROR); 2210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 2214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Delete files from an existing archive. 2215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 2216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doRemove(Bundle* bundle) 2217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipFile* zip = NULL; 2219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result = UNKNOWN_ERROR; 2220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* zipFileName; 2221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 1) { 2223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: must specify zip file name\n"); 2224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zipFileName = bundle->getFileSpecEntry(0); 2227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 2) { 2229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "NOTE: nothing to do\n"); 2230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip = openReadWrite(zipFileName, false); 2234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (zip == NULL) { 2235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: failed opening Zip archive '%s'\n", 2236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zipFileName); 2237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i = 1; i < bundle->getFileSpecCount(); i++) { 2241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* fileName = bundle->getFileSpecEntry(i); 2242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry* entry; 2243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entry = zip->getEntryByName(fileName); 2245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (entry == NULL) { 2246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" '%s' NOT FOUND\n", fileName); 2247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = zip->remove(entry); 2251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result != NO_ERROR) { 2253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "Unable to delete '%s' from '%s'\n", 2254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bundle->getFileSpecEntry(i), zipFileName); 2255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* update the archive */ 2260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip->flush(); 2261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 2263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete zip; 2264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (result != NO_ERROR); 2265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 22673921e87e6e67a063caa1987937d7944b24aef489Adam Lesinskistatic status_t addResourcesToBuilder(const sp<AaptDir>& dir, const sp<ApkBuilder>& builder, bool ignoreConfig=false) { 2268fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const size_t numDirs = dir->getDirs().size(); 2269fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski for (size_t i = 0; i < numDirs; i++) { 22703921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski bool ignore = ignoreConfig; 22713921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski const sp<AaptDir>& subDir = dir->getDirs().valueAt(i); 22723921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski const char* dirStr = subDir->getLeaf().string(); 22733921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski if (!ignore && strstr(dirStr, "mipmap") == dirStr) { 22743921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski ignore = true; 22753921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski } 22763921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski status_t err = addResourcesToBuilder(subDir, builder, ignore); 2277fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (err != NO_ERROR) { 2278fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return err; 2279fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2280fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2281fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 2282fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const size_t numFiles = dir->getFiles().size(); 2283fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski for (size_t i = 0; i < numFiles; i++) { 2284fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski sp<AaptGroup> gp = dir->getFiles().valueAt(i); 2285fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const size_t numConfigs = gp->getFiles().size(); 2286fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski for (size_t j = 0; j < numConfigs; j++) { 22873921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski status_t err = NO_ERROR; 22883921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski if (ignoreConfig) { 22893921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski err = builder->getBaseSplit()->addEntry(gp->getPath(), gp->getFiles().valueAt(j)); 22903921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski } else { 22913921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski err = builder->addEntry(gp->getPath(), gp->getFiles().valueAt(j)); 22923921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski } 2293fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (err != NO_ERROR) { 2294fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski fprintf(stderr, "Failed to add %s (%s) to builder.\n", 2295fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski gp->getPath().string(), gp->getFiles()[j]->getPrintableSource().string()); 2296fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return err; 2297fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2298fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2299fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2300fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return NO_ERROR; 2301fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski} 2302fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 2303fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskistatic String8 buildApkName(const String8& original, const sp<ApkSplit>& split) { 2304fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (split->isBase()) { 2305fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return original; 2306fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2307fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 2308fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski String8 ext(original.getPathExtension()); 2309fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (ext == String8(".apk")) { 2310fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return String8::format("%s_%s%s", 2311fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski original.getBasePath().string(), 2312fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski split->getDirectorySafeName().string(), 2313fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski ext.string()); 2314fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2315fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 2316fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return String8::format("%s_%s", original.string(), 2317fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski split->getDirectorySafeName().string()); 2318fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski} 2319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 2321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Package up an asset directory and associated application files. 2322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 2323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doPackage(Bundle* bundle) 2324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* outputAPKFile; 2326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int retVal = 1; 2327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err; 2328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptAssets> assets; 2329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int N; 2330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FILE* fp; 2331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 dependencyFile; 2332fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski sp<ApkBuilder> builder; 2333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2334a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin // -c en_XA or/and ar_XB means do pseudolocalization 2335fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski sp<WeakResourceFilter> configFilter = new WeakResourceFilter(); 2336fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski err = configFilter->parse(bundle->getConfigurations()); 2337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 2338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2340fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (configFilter->containsPseudo()) { 2341a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin bundle->setPseudolocalize(bundle->getPseudolocalize() | PSEUDO_ACCENTED); 2342a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin } 2343fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (configFilter->containsPseudoBidi()) { 2344a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin bundle->setPseudolocalize(bundle->getPseudolocalize() | PSEUDO_BIDI); 2345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski N = bundle->getFileSpecCount(); 2348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (N < 1 && bundle->getResourceSourceDirs().size() == 0 && bundle->getJarFiles().size() == 0 234909384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski && bundle->getAndroidManifestFile() == NULL && bundle->getAssetSourceDirs().size() == 0) { 2350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: no input files\n"); 2351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outputAPKFile = bundle->getOutputAPKFile(); 2355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Make sure the filenames provided exist and are of the appropriate type. 2357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outputAPKFile) { 2358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FileType type; 2359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type = getFileType(outputAPKFile); 2360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (type != kFileTypeNonexistent && type != kFileTypeRegular) { 2361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, 2362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "ERROR: output file '%s' exists but is not regular file\n", 2363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outputAPKFile); 2364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Load the assets. 2369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets = new AaptAssets(); 2370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Set up the resource gathering in assets if we're going to generate 2372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // dependency files. Every time we encounter a resource while slurping 2373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the tree, we'll add it to these stores so we have full resource paths 2374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // to write to a dependency file. 2375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getGenDependencies()) { 2376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<FilePathStore> resPathStore = new FilePathStore; 2377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->setFullResPaths(resPathStore); 2378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<FilePathStore> assetPathStore = new FilePathStore; 2379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->setFullAssetPaths(assetPathStore); 2380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = assets->slurpFromArgs(bundle); 2383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 2384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 2388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->print(String8()); 2389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2391fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // Create the ApkBuilder, which will collect the compiled files 2392fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // to write to the final APK (or sets of APKs if we are building 2393fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // a Split APK. 2394fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski builder = new ApkBuilder(configFilter); 2395fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 2396fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // If we are generating a Split APK, find out which configurations to split on. 2397fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (bundle->getSplitConfigurations().size() > 0) { 2398fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const Vector<String8>& splitStrs = bundle->getSplitConfigurations(); 2399fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const size_t numSplits = splitStrs.size(); 2400fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski for (size_t i = 0; i < numSplits; i++) { 2401fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski std::set<ConfigDescription> configs; 2402fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (!AaptConfig::parseCommaSeparatedList(splitStrs[i], &configs)) { 2403fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski fprintf(stderr, "ERROR: failed to parse split configuration '%s'\n", splitStrs[i].string()); 2404fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski goto bail; 2405fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2406fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 2407fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski err = builder->createSplitForConfigs(configs); 2408fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (err != NO_ERROR) { 2409fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski goto bail; 2410fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2411fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2412fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2413fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 2414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If they asked for any fileAs that need to be compiled, do so. 2415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getResourceSourceDirs().size() || bundle->getAndroidManifestFile()) { 2416fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski err = buildResources(bundle, assets, builder); 2417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != 0) { 2418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // At this point we've read everything and processed everything. From here 2423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // on out it's just writing output files. 2424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (SourcePos::hasErrors()) { 2425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Update symbols with information about which ones are needed as Java symbols. 2429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->applyJavaSymbols(); 2430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (SourcePos::hasErrors()) { 2431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If we've been asked to generate a dependency file, do that here 2435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getGenDependencies()) { 2436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If this is the packaging step, generate the dependency file next to 2437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the output apk (e.g. bin/resources.ap_.d) 2438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outputAPKFile) { 2439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dependencyFile = String8(outputAPKFile); 2440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Add the .d extension to the dependency file. 2441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dependencyFile.append(".d"); 2442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Else if this is the R.java dependency generation step, 2444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // generate the dependency file in the R.java package subdirectory 2445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // e.g. gen/com/foo/app/R.java.d 2446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dependencyFile = String8(bundle->getRClassDir()); 2447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dependencyFile.appendPath("R.java.d"); 2448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Make sure we have a clean dependency file to start with 2450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fp = fopen(dependencyFile, "w"); 2451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fclose(fp); 2452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write out R.java constants 2455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!assets->havePrivateSymbols()) { 2456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getCustomPackage() == NULL) { 2457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write the R.java file into the appropriate class directory 2458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // e.g. gen/com/foo/app/R.java 2459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeResourceSymbols(bundle, assets, assets->getPackage(), true); 2460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8 customPkg(bundle->getCustomPackage()); 2462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeResourceSymbols(bundle, assets, customPkg, true); 2463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 2465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If we have library files, we're going to write our R.java file into 2468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the appropriate class directory for those libraries as well. 2469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // e.g. gen/com/foo/app/lib/R.java 2470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getExtraPackages() != NULL) { 2471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Split on colon 2472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 libs(bundle->getExtraPackages()); 2473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char* packageString = strtok(libs.lockBuffer(libs.length()), ":"); 2474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (packageString != NULL) { 2475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write the R.java file out with the correct package name 2476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeResourceSymbols(bundle, assets, String8(packageString), true); 2477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 2478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski packageString = strtok(NULL, ":"); 2481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski libs.unlockBuffer(); 2483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeResourceSymbols(bundle, assets, assets->getPackage(), false); 2486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 2487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeResourceSymbols(bundle, assets, assets->getSymbolsPrivatePackage(), true); 2490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 2491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write out the ProGuard file 2496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeProguardFile(bundle, assets); 2497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 2498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write the apk 2502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outputAPKFile) { 2503fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // Gather all resources and add them to the APK Builder. The builder will then 2504fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // figure out which Split they belong in. 2505fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski err = addResourcesToBuilder(assets, builder); 2506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 2507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2509fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 2510fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const Vector<sp<ApkSplit> >& splits = builder->getSplits(); 2511fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const size_t numSplits = splits.size(); 2512fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski for (size_t i = 0; i < numSplits; i++) { 2513fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const sp<ApkSplit>& split = splits[i]; 2514fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski String8 outputPath = buildApkName(String8(outputAPKFile), split); 2515fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski err = writeAPK(bundle, outputPath, split); 2516fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (err != NO_ERROR) { 2517fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski fprintf(stderr, "ERROR: packaging of '%s' failed\n", outputPath.string()); 2518fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski goto bail; 2519fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2520fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If we've been asked to generate a dependency file, we need to finish up here. 2524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the writeResourceSymbols and writeAPK functions have already written the target 2525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // half of the dependency file, now we need to write the prerequisites. (files that 2526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the R.java file or .ap_ file depend on) 2527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getGenDependencies()) { 2528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Now that writeResourceSymbols or writeAPK has taken care of writing 2529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the targets to our dependency file, we'll write the prereqs 2530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fp = fopen(dependencyFile, "a+"); 2531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, " : "); 2532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool includeRaw = (outputAPKFile != NULL); 2533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeDependencyPreReqs(bundle, assets, fp, includeRaw); 2534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Also manually add the AndroidManifeset since it's not under res/ or assets/ 2535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // and therefore was not added to our pathstores during slurping 2536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s \\\n", bundle->getAndroidManifestFile()); 2537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fclose(fp); 2538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski retVal = 0; 2541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 2542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (SourcePos::hasErrors()) { 2543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos::printErrors(stderr); 2544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return retVal; 2546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 2549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Do PNG Crunching 2550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * PRECONDITIONS 2551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * -S flag points to a source directory containing drawable* folders 2552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * -C flag points to destination directory. The folder structure in the 2553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * source directory will be mirrored to the destination (cache) directory 2554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 2555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * POSTCONDITIONS 2556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Destination directory will be updated to match the PNG files in 25572675f769673f69b0661ddee346292f25cb30a296Maurice Chu * the source directory. 2558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 2559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doCrunch(Bundle* bundle) 2560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "Crunching PNG Files in "); 2562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "source dir: %s\n", bundle->getResourceSourceDirs()[0]); 2563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "To destination dir: %s\n", bundle->getCrunchedOutputDir()); 2564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski updatePreProcessedCache(bundle); 2566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 2568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 2571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Do PNG Crunching on a single flag 2572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * -i points to a single png file 2573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * -o points to a single png output file 2574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 2575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doSingleCrunch(Bundle* bundle) 2576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "Crunching single PNG file: %s\n", bundle->getSingleCrunchInputFile()); 2578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "\tOutput file: %s\n", bundle->getSingleCrunchOutputFile()); 2579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 input(bundle->getSingleCrunchInputFile()); 2581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 output(bundle->getSingleCrunchOutputFile()); 2582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (preProcessImageToCache(bundle, input, output) != NO_ERROR) { 2584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // we can't return the status_t as it gets truncate to the lower 8 bits. 2585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 42; 2586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 2589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskichar CONSOLE_DATA[2925] = { 2592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 95, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 2596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 63, 2597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 86, 35, 40, 46, 46, 95, 95, 95, 95, 97, 97, 44, 32, 46, 124, 42, 33, 83, 2598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 62, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 46, 58, 59, 61, 59, 61, 81, 2601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 66, 96, 61, 61, 58, 46, 46, 46, 58, 32, 32, 32, 32, 32, 32, 2602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 2603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 46, 61, 59, 59, 59, 58, 106, 81, 81, 81, 81, 102, 59, 61, 59, 2605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 61, 61, 61, 58, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 2608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 58, 109, 81, 81, 81, 81, 61, 59, 59, 59, 59, 59, 58, 59, 59, 46, 32, 2609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 60, 81, 81, 81, 81, 87, 2612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 58, 59, 59, 59, 59, 59, 59, 61, 119, 44, 32, 32, 32, 32, 32, 32, 32, 32, 2613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 2614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 2615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 47, 61, 59, 59, 58, 100, 81, 81, 81, 81, 35, 58, 59, 59, 59, 59, 59, 58, 2616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 121, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 109, 58, 59, 59, 61, 81, 81, 2619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 109, 58, 59, 59, 59, 59, 61, 109, 81, 81, 76, 46, 32, 32, 32, 2620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 2621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 41, 87, 59, 61, 59, 41, 81, 81, 81, 81, 81, 81, 59, 61, 59, 2623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 58, 109, 81, 81, 87, 39, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 60, 81, 91, 59, 2626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 61, 81, 81, 81, 81, 81, 87, 43, 59, 58, 59, 60, 81, 81, 81, 76, 32, 2627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 52, 91, 58, 45, 59, 87, 81, 81, 81, 81, 2630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 70, 58, 58, 58, 59, 106, 81, 81, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32, 2631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 2632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 93, 40, 32, 46, 59, 100, 81, 81, 81, 81, 40, 58, 46, 46, 58, 100, 81, 2634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 68, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 46, 46, 46, 32, 46, 46, 46, 32, 46, 32, 46, 45, 91, 59, 61, 58, 109, 2637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 87, 46, 58, 61, 59, 60, 81, 81, 80, 32, 32, 32, 32, 32, 32, 2638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 2639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 46, 46, 61, 59, 61, 61, 61, 59, 61, 61, 59, 2640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 58, 58, 46, 46, 41, 58, 59, 58, 81, 81, 81, 81, 69, 58, 59, 59, 2641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 60, 81, 81, 68, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 58, 59, 2643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 61, 46, 2644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 59, 93, 81, 81, 81, 81, 107, 58, 59, 58, 109, 87, 68, 96, 32, 32, 32, 2645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 10, 32, 32, 32, 46, 60, 61, 61, 59, 59, 59, 59, 59, 59, 59, 59, 2647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 59, 59, 59, 58, 58, 58, 115, 109, 68, 41, 36, 81, 2648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 109, 46, 61, 61, 81, 69, 96, 46, 58, 58, 46, 58, 46, 46, 32, 32, 32, 32, 2649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 46, 32, 95, 81, 2650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 67, 61, 61, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 2651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 58, 68, 39, 61, 105, 61, 63, 81, 119, 58, 106, 80, 32, 58, 2652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 59, 59, 61, 59, 61, 59, 61, 46, 95, 32, 32, 32, 32, 32, 32, 32, 32, 2653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 10, 32, 32, 36, 81, 109, 105, 59, 61, 59, 59, 59, 2654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 46, 58, 37, 2655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 73, 108, 108, 62, 52, 81, 109, 34, 32, 61, 59, 59, 59, 59, 59, 59, 59, 59, 2656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 61, 59, 61, 61, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 2657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 46, 45, 57, 101, 43, 43, 61, 61, 59, 59, 59, 59, 59, 59, 61, 59, 59, 2658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 59, 58, 97, 46, 61, 108, 62, 126, 58, 106, 80, 96, 2659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46, 61, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 61, 2660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 97, 103, 97, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 45, 46, 32, 2661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45, 58, 59, 59, 59, 59, 61, 2662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 119, 81, 97, 124, 105, 124, 124, 39, 126, 95, 119, 58, 61, 58, 59, 59, 59, 2663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 119, 81, 81, 99, 32, 32, 2664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 58, 106, 81, 81, 81, 109, 119, 2666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 119, 119, 109, 109, 81, 81, 122, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 2667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 58, 115, 81, 87, 81, 102, 32, 32, 32, 32, 32, 32, 10, 2668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 61, 58, 59, 61, 81, 81, 81, 81, 81, 81, 87, 87, 81, 81, 81, 81, 2670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 58, 59, 59, 59, 59, 59, 59, 59, 59, 58, 45, 45, 45, 59, 59, 59, 41, 2671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 87, 66, 33, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 2672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 93, 81, 2673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 2674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 45, 32, 46, 32, 32, 32, 32, 32, 46, 32, 126, 96, 32, 32, 32, 32, 32, 32, 2675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 58, 61, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81, 2677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 2678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 2679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 2680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58, 2681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 60, 81, 81, 81, 81, 2684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 81, 81, 81, 81, 59, 61, 59, 59, 61, 32, 32, 32, 32, 2685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 58, 59, 59, 93, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 2688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 40, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 2690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 106, 2691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 76, 58, 59, 59, 59, 2692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 61, 58, 58, 81, 81, 81, 81, 81, 81, 81, 81, 2695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 87, 58, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 2696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 2697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 58, 59, 61, 41, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 87, 59, 2699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 58, 59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 61, 81, 81, 81, 2702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 81, 81, 81, 81, 107, 58, 59, 59, 59, 59, 58, 32, 32, 2703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 58, 59, 59, 58, 51, 81, 81, 81, 81, 81, 81, 81, 81, 81, 2706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 102, 94, 59, 59, 59, 59, 59, 61, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 2708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 2709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 43, 63, 36, 81, 81, 81, 87, 64, 86, 102, 58, 59, 59, 59, 59, 59, 2710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 59, 59, 43, 33, 2713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 58, 126, 126, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32, 32, 2714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 2715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 2716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 59, 59, 59, 58, 45, 58, 61, 59, 58, 58, 58, 61, 59, 59, 59, 59, 59, 2717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 2718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 2719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 58, 95, 2720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 45, 61, 59, 61, 59, 59, 59, 59, 59, 59, 59, 45, 58, 59, 59, 59, 59, 2721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 58, 61, 59, 59, 59, 59, 59, 61, 59, 61, 46, 46, 32, 45, 45, 45, 2724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 58, 45, 45, 46, 58, 59, 59, 59, 59, 59, 59, 61, 46, 32, 32, 32, 32, 2725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 2726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 58, 59, 59, 59, 59, 2727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 61, 59, 46, 32, 32, 46, 32, 46, 32, 58, 61, 59, 59, 2728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 45, 59, 59, 59, 59, 59, 59, 59, 59, 58, 32, 2731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 58, 32, 2732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 2733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46, 61, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 61, 2735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46, 61, 59, 59, 59, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 2737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 2738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 46, 61, 58, 59, 59, 59, 59, 2739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 58, 59, 59, 59, 59, 59, 59, 59, 59, 46, 46, 32, 32, 32, 2742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 45, 32, 32, 32, 32, 32, 2743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 2744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 32, 45, 61, 2745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 2746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 58, 45, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45, 45, 32, 46, 32, 2749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 61, 59, 58, 45, 45, 32, 32, 32, 2750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 46, 32, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10 2755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski }; 2756