Command.cpp revision 91447d88f2bdf9c2bf8d1a53570efef6172fba74
1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Copyright 2006 The Android Open Source Project 3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Android Asset Packaging Tool main entry point. 5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 6282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "Main.h" 7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "Bundle.h" 8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "ResourceFilter.h" 9282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "ResourceTable.h" 10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "Images.h" 11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "XMLNode.h" 12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <utils/Log.h> 14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <utils/threads.h> 15282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <utils/List.h> 16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <utils/Errors.h> 17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <fcntl.h> 19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <errno.h> 20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiusing namespace android; 22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Show version info. All the cool kids do it. 25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doVersion(Bundle* bundle) 27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() != 0) { 29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("(ignoring extra arguments)\n"); 30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Android Asset Packaging Tool, v0.2\n"); 32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Open the file read only. The call fails if the file doesn't exist. 39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Returns NULL on failure. 41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 42282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiZipFile* openReadOnly(const char* fileName) 43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipFile* zip; 45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result; 46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip = new ZipFile; 48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = zip->open(fileName, ZipFile::kOpenReadOnly); 49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result != NO_ERROR) { 50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result == NAME_NOT_FOUND) { 51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: '%s' not found\n", fileName); 52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (result == PERMISSION_DENIED) { 53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: '%s' access denied\n", fileName); 54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: failed opening '%s' as Zip file\n", 56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fileName); 57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete zip; 59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return zip; 63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Open the file read-write. The file will be created if it doesn't 67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * already exist and "okayToCreate" is set. 68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Returns NULL on failure. 70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 71282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiZipFile* openReadWrite(const char* fileName, bool okayToCreate) 72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipFile* zip = NULL; 74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result; 75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int flags; 76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flags = ZipFile::kOpenReadWrite; 78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (okayToCreate) { 79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flags |= ZipFile::kOpenCreate; 80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip = new ZipFile; 83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = zip->open(fileName, flags); 84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result != NO_ERROR) { 85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete zip; 86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip = NULL; 87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return zip; 92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Return a short string describing the compression method. 97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiconst char* compressionName(int method) 99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (method == ZipEntry::kCompressStored) { 101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return "Stored"; 102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (method == ZipEntry::kCompressDeflated) { 103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return "Deflated"; 104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return "Unknown"; 106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Return the percent reduction in size (0% == no compression). 111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint calcPercent(long uncompressedLen, long compressedLen) 113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!uncompressedLen) { 115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (int) (100.0 - (compressedLen * 100.0) / uncompressedLen + 0.5); 118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Handle the "list" command, which can be a simple file dump or 123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * a verbose listing. 124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * The verbose listing closely matches the output of the Info-ZIP "unzip" 126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * command. 127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doList(Bundle* bundle) 129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int result = 1; 131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipFile* zip = NULL; 132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ZipEntry* entry; 133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski long totalUncLen, totalCompLen; 134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* zipFileName; 135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() != 1) { 137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: specify zip file name (only)\n"); 138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zipFileName = bundle->getFileSpecEntry(0); 141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip = openReadOnly(zipFileName); 143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (zip == NULL) { 144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int count, i; 148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Archive: %s\n", zipFileName); 151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf( 152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " Length Method Size Ratio Offset Date Time CRC-32 Name\n"); 153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf( 154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "-------- ------ ------- ----- ------- ---- ---- ------ ----\n"); 155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalUncLen = totalCompLen = 0; 158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count = zip->getNumEntries(); 160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i = 0; i < count; i++) { 161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entry = zip->getEntryByIndex(i); 162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char dateBuf[32]; 164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski time_t when; 165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski when = entry->getModWhen(); 167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strftime(dateBuf, sizeof(dateBuf), "%m-%d-%y %H:%M", 168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski localtime(&when)); 169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%8ld %-7.7s %7ld %3d%% %8zd %s %08lx %s\n", 171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (long) entry->getUncompressedLen(), 172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski compressionName(entry->getCompressionMethod()), 173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (long) entry->getCompressedLen(), 174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski calcPercent(entry->getUncompressedLen(), 175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entry->getCompressedLen()), 176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (size_t) entry->getLFHOffset(), 177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dateBuf, 178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entry->getCRC32(), 179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entry->getFileName()); 180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%s\n", entry->getFileName()); 182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalUncLen += entry->getUncompressedLen(); 185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalCompLen += entry->getCompressedLen(); 186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf( 190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "-------- ------- --- -------\n"); 191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%8ld %7ld %2d%% %d files\n", 192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalUncLen, 193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalCompLen, 194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski calcPercent(totalUncLen, totalCompLen), 195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip->getNumEntries()); 196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getAndroidList()) { 199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AssetManager assets; 200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!assets.addAssetPath(String8(zipFileName), NULL)) { 201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: list -a failed because assets could not be loaded\n"); 202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable& res = assets.getResources(false); 206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (&res == NULL) { 207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\nNo resource table found.\n"); 208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#ifndef HAVE_ANDROID_OS 210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\nResource table:\n"); 211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res.print(false); 212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Asset* manifestAsset = assets.openNonAsset("AndroidManifest.xml", 216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Asset::ACCESS_BUFFER); 217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (manifestAsset == NULL) { 218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\nNo AndroidManifest.xml found.\n"); 219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\nAndroid manifest:\n"); 221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree tree; 222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tree.setTo(manifestAsset->getBuffer(true), 223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski manifestAsset->getLength()); 224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printXMLBlock(&tree); 225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete manifestAsset; 227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = 0; 230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete zip; 233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return result; 234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic ssize_t indexOfAttribute(const ResXMLTree& tree, uint32_t attrRes) 237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t N = tree.getAttributeCount(); 239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.getAttributeNameResID(i) == attrRes) { 241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (ssize_t)i; 242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return -1; 245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 247282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiString8 getAttribute(const ResXMLTree& tree, const char* ns, 248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* attr, String8* outError) 249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t idx = tree.indexOfAttribute(ns, attr); 251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx < 0) { 252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String8(); 253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value.dataType != Res_value::TYPE_STRING) { 257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError != NULL) { 258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outError = "attribute is not a string value"; 259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String8(); 261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint16_t* str = tree.getAttributeStringValue(idx, &len); 265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return str ? String8(str, len) : String8(); 266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic String8 getAttribute(const ResXMLTree& tree, uint32_t attrRes, String8* outError) 269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t idx = indexOfAttribute(tree, attrRes); 271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx < 0) { 272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String8(); 273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value.dataType != Res_value::TYPE_STRING) { 277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError != NULL) { 278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outError = "attribute is not a string value"; 279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String8(); 281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint16_t* str = tree.getAttributeStringValue(idx, &len); 285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return str ? String8(str, len) : String8(); 286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic int32_t getIntegerAttribute(const ResXMLTree& tree, uint32_t attrRes, 289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8* outError, int32_t defValue = -1) 290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t idx = indexOfAttribute(tree, attrRes); 292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx < 0) { 293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return defValue; 294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value.dataType < Res_value::TYPE_FIRST_INT 298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || value.dataType > Res_value::TYPE_LAST_INT) { 299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError != NULL) { 300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outError = "attribute is not an integer value"; 301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return defValue; 303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return value.data; 306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic int32_t getResolvedIntegerAttribute(const ResTable* resTable, const ResXMLTree& tree, 309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t attrRes, String8* outError, int32_t defValue = -1) 310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t idx = indexOfAttribute(tree, attrRes); 312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx < 0) { 313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return defValue; 314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value.dataType == Res_value::TYPE_REFERENCE) { 318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resTable->resolveReference(&value, 0); 319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value.dataType < Res_value::TYPE_FIRST_INT 321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || value.dataType > Res_value::TYPE_LAST_INT) { 322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError != NULL) { 323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outError = "attribute is not an integer value"; 324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return defValue; 326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return value.data; 329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic String8 getResolvedAttribute(const ResTable* resTable, const ResXMLTree& tree, 332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t attrRes, String8* outError) 333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t idx = indexOfAttribute(tree, attrRes); 335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx < 0) { 336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String8(); 337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value.dataType == Res_value::TYPE_STRING) { 341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint16_t* str = tree.getAttributeStringValue(idx, &len); 343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return str ? String8(str, len) : String8(); 344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resTable->resolveReference(&value, 0); 346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value.dataType != Res_value::TYPE_STRING) { 347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError != NULL) { 348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outError = "attribute is not a string value"; 349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String8(); 351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Res_value* value2 = &value; 355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* str = const_cast<ResTable*>(resTable)->valueToString(value2, 0, NULL, &len); 356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return str ? String8(str, len) : String8(); 357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void getResolvedResourceAttribute(Res_value* value, const ResTable* resTable, 360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResXMLTree& tree, uint32_t attrRes, String8* outError) 361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t idx = indexOfAttribute(tree, attrRes); 363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx < 0) { 364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError != NULL) { 365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outError = "attribute could not be found"; 366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.getAttributeValue(idx, value) != NO_ERROR) { 370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value->dataType == Res_value::TYPE_REFERENCE) { 371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resTable->resolveReference(value, 0); 372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // The attribute was found and was resolved if need be. 374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError != NULL) { 377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outError = "error getting resolved resource attribute"; 378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 38176327314d2238e105f8b94909f9c0cf85caca318Maurice Chustatic void printResolvedResourceAttribute(const ResTable* resTable, const ResXMLTree& tree, 38276327314d2238e105f8b94909f9c0cf85caca318Maurice Chu uint32_t attrRes, String8 attrLabel, String8* outError) 38376327314d2238e105f8b94909f9c0cf85caca318Maurice Chu{ 38476327314d2238e105f8b94909f9c0cf85caca318Maurice Chu Res_value value; 38576327314d2238e105f8b94909f9c0cf85caca318Maurice Chu getResolvedResourceAttribute(&value, resTable, tree, attrRes, outError); 38676327314d2238e105f8b94909f9c0cf85caca318Maurice Chu if (*outError != "") { 38776327314d2238e105f8b94909f9c0cf85caca318Maurice Chu *outError = "error print resolved resource attribute"; 38876327314d2238e105f8b94909f9c0cf85caca318Maurice Chu return; 38976327314d2238e105f8b94909f9c0cf85caca318Maurice Chu } 39076327314d2238e105f8b94909f9c0cf85caca318Maurice Chu if (value.dataType == Res_value::TYPE_STRING) { 39176327314d2238e105f8b94909f9c0cf85caca318Maurice Chu String8 result = getResolvedAttribute(resTable, tree, attrRes, outError); 3922675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("%s='%s'", attrLabel.string(), 3932675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(result.string()).string()); 39476327314d2238e105f8b94909f9c0cf85caca318Maurice Chu } else if (Res_value::TYPE_FIRST_INT <= value.dataType && 39576327314d2238e105f8b94909f9c0cf85caca318Maurice Chu value.dataType <= Res_value::TYPE_LAST_INT) { 39676327314d2238e105f8b94909f9c0cf85caca318Maurice Chu printf("%s='%d'", attrLabel.string(), value.data); 39776327314d2238e105f8b94909f9c0cf85caca318Maurice Chu } else { 39876327314d2238e105f8b94909f9c0cf85caca318Maurice Chu printf("%s='0x%x'", attrLabel.string(), (int)value.data); 39976327314d2238e105f8b94909f9c0cf85caca318Maurice Chu } 40076327314d2238e105f8b94909f9c0cf85caca318Maurice Chu} 40176327314d2238e105f8b94909f9c0cf85caca318Maurice Chu 402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// These are attribute resource constants for the platform, as found 403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// in android.R.attr 404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskienum { 405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LABEL_ATTR = 0x01010001, 406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ICON_ATTR = 0x01010002, 407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NAME_ATTR = 0x01010003, 408a5018c900f126ee8424c82497f32983873db741bAdam Lesinski PERMISSION_ATTR = 0x01010006, 40994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski RESOURCE_ATTR = 0x01010025, 410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DEBUGGABLE_ATTR = 0x0101000f, 411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski VALUE_ATTR = 0x01010024, 412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski VERSION_CODE_ATTR = 0x0101021b, 413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski VERSION_NAME_ATTR = 0x0101021c, 414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SCREEN_ORIENTATION_ATTR = 0x0101001e, 415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MIN_SDK_VERSION_ATTR = 0x0101020c, 416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MAX_SDK_VERSION_ATTR = 0x01010271, 417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_TOUCH_SCREEN_ATTR = 0x01010227, 418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_KEYBOARD_TYPE_ATTR = 0x01010228, 419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_HARD_KEYBOARD_ATTR = 0x01010229, 420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_NAVIGATION_ATTR = 0x0101022a, 421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_FIVE_WAY_NAV_ATTR = 0x01010232, 422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski TARGET_SDK_VERSION_ATTR = 0x01010270, 423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski TEST_ONLY_ATTR = 0x01010272, 424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ANY_DENSITY_ATTR = 0x0101026c, 425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski GL_ES_VERSION_ATTR = 0x01010281, 426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SMALL_SCREEN_ATTR = 0x01010284, 427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NORMAL_SCREEN_ATTR = 0x01010285, 428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LARGE_SCREEN_ATTR = 0x01010286, 429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski XLARGE_SCREEN_ATTR = 0x010102bf, 430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQUIRED_ATTR = 0x0101028e, 431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SCREEN_SIZE_ATTR = 0x010102ca, 432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SCREEN_DENSITY_ATTR = 0x010102cb, 433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQUIRES_SMALLEST_WIDTH_DP_ATTR = 0x01010364, 434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski COMPATIBLE_WIDTH_LIMIT_DP_ATTR = 0x01010365, 435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LARGEST_WIDTH_LIMIT_DP_ATTR = 0x01010366, 436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PUBLIC_KEY_ATTR = 0x010103a6, 43794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski CATEGORY_ATTR = 0x010103e8, 438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4402675f769673f69b0661ddee346292f25cb30a296Maurice ChuString8 getComponentName(String8 &pkgName, String8 &componentName) { 441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t idx = componentName.find("."); 442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 retStr(pkgName); 443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx == 0) { 444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski retStr += componentName; 445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (idx < 0) { 446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski retStr += "."; 447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski retStr += componentName; 448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 4492675f769673f69b0661ddee346292f25cb30a296Maurice Chu return componentName; 450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4512675f769673f69b0661ddee346292f25cb30a296Maurice Chu return retStr; 452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void printCompatibleScreens(ResXMLTree& tree) { 455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int depth = 0; 458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool first = true; 459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("compatible-screens:"); 460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth--; 463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (depth < 0) { 464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != ResXMLTree::START_TAG) { 469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth++; 472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 tag(tree.getElementName(&len)); 473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag == "screen") { 474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t screenSize = getIntegerAttribute(tree, 475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SCREEN_SIZE_ATTR, NULL, -1); 476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t screenDensity = getIntegerAttribute(tree, 477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SCREEN_DENSITY_ATTR, NULL, -1); 478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (screenSize > 0 && screenDensity > 0) { 479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!first) { 480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(","); 481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski first = false; 483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("'%d/%d'", screenSize, screenDensity); 484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 49058f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinskistatic void printUsesPermission(const String8& name, bool optional=false, int maxSdkVersion=-1) { 49158f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printf("uses-permission: name='%s'", ResTable::normalizeForOutput(name.string()).string()); 49258f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski if (maxSdkVersion != -1) { 49358f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printf(" maxSdkVersion='%d'", maxSdkVersion); 49458f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski } 49558f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printf("\n"); 49658f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski 49758f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski if (optional) { 49858f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printf("optional-permission: name='%s'", 49958f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski ResTable::normalizeForOutput(name.string()).string()); 50058f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski if (maxSdkVersion != -1) { 50158f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printf(" maxSdkVersion='%d'", maxSdkVersion); 50258f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski } 50358f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printf("\n"); 50458f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski } 50558f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski} 50658f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski 50758f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinskistatic void printUsesImpliedPermission(const String8& name, const String8& reason) { 50858f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printf("uses-implied-permission: name='%s' reason='%s'\n", 50958f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski ResTable::normalizeForOutput(name.string()).string(), 51058f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski ResTable::normalizeForOutput(reason.string()).string()); 51158f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski} 51258f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski 51394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam LesinskiVector<String8> getNfcAidCategories(AssetManager& assets, String8 xmlPath, bool offHost, 51494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski String8 *outError = NULL) 51594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski{ 51694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski Asset* aidAsset = assets.openNonAsset(xmlPath, Asset::ACCESS_BUFFER); 51794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (aidAsset == NULL) { 51894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (outError != NULL) *outError = "xml resource does not exist"; 51994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski return Vector<String8>(); 52094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 52194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 52294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski const String8 serviceTagName(offHost ? "offhost-apdu-service" : "host-apdu-service"); 52394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 52494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool withinApduService = false; 52594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski Vector<String8> categories; 52694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 52794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski String8 error; 52894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski ResXMLTree tree; 52994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski tree.setTo(aidAsset->getBuffer(true), aidAsset->getLength()); 53094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 53194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski size_t len; 53294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski int depth = 0; 53394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski ResXMLTree::event_code_t code; 53494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 53594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (code == ResXMLTree::END_TAG) { 53694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski depth--; 53794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski String8 tag(tree.getElementName(&len)); 53894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 53994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (depth == 0 && tag == serviceTagName) { 54094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski withinApduService = false; 54194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 54294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 54394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else if (code == ResXMLTree::START_TAG) { 54494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski depth++; 54594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski String8 tag(tree.getElementName(&len)); 54694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 54794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (depth == 1) { 54894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (tag == serviceTagName) { 54994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski withinApduService = true; 55094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 55194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else if (depth == 2 && withinApduService) { 55294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (tag == "aid-group") { 55394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski String8 category = getAttribute(tree, CATEGORY_ATTR, &error); 55494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (error != "") { 55594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (outError != NULL) *outError = error; 55694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski return Vector<String8>(); 55794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 55894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 55994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski categories.add(category); 56094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 56194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 56294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 56394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 56494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski aidAsset->close(); 56594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski return categories; 56694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski} 56794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Handle the "dump" command, to extract select data from an archive. 570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiextern char CONSOLE_DATA[2925]; // see EOF 572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doDump(Bundle* bundle) 573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result = UNKNOWN_ERROR; 575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Asset* asset = NULL; 576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 1) { 578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: no dump option specified\n"); 579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 1; 580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 2) { 583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: no dump file specified\n"); 584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 1; 585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* option = bundle->getFileSpecEntry(0); 588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* filename = bundle->getFileSpecEntry(1); 589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AssetManager assets; 591f85e41f29a0e9313c2d4725f9d9648591ea49f3bNarayan Kamath int32_t assetsCookie; 592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!assets.addAssetPath(String8(filename), &assetsCookie)) { 593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: dump failed because assets could not be loaded\n"); 594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 1; 595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Make a dummy config for retrieving resources... we need to supply 598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // non-default values for some configs so that we can retrieve resources 599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // in the app that don't have a default. The most important of these is 600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the API version because key resources like icons will have an implicit 601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // version if they are using newer config types like density. 602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_config config; 60391447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath memset(&config, 0, sizeof(ResTable_config)); 604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.language[0] = 'e'; 605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.language[1] = 'n'; 606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.country[0] = 'U'; 607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.country[1] = 'S'; 608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.orientation = ResTable_config::ORIENTATION_PORT; 609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.density = ResTable_config::DENSITY_MEDIUM; 610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.sdkVersion = 10000; // Very high. 611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.screenWidthDp = 320; 612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.screenHeightDp = 480; 613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.smallestScreenWidthDp = 320; 614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets.setConfiguration(config); 615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable& res = assets.getResources(false); 617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (&res == NULL) { 618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: dump failed because no resource table was found\n"); 619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp("resources", option) == 0) { 623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#ifndef HAVE_ANDROID_OS 624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res.print(bundle->getValues()); 625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("strings", option) == 0) { 628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResStringPool* pool = res.getTableStringBlock(0); 629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printStringPool(pool); 630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("xmltree", option) == 0) { 632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 3) { 633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: no dump xmltree resource file specified\n"); 634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i=2; i<bundle->getFileSpecCount(); i++) { 638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* resname = bundle->getFileSpecEntry(i); 639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree tree; 640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset = assets.openNonAsset(resname, Asset::ACCESS_BUFFER); 641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (asset == NULL) { 642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: dump failed because resource %s found\n", resname); 643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.setTo(asset->getBuffer(true), 647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset->getLength()) != NO_ERROR) { 648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: Resource %s is corrupt\n", resname); 649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tree.restart(); 652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printXMLBlock(&tree); 653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tree.uninit(); 654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete asset; 655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset = NULL; 656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("xmlstrings", option) == 0) { 659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 3) { 660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: no dump xmltree resource file specified\n"); 661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i=2; i<bundle->getFileSpecCount(); i++) { 665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* resname = bundle->getFileSpecEntry(i); 666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree tree; 667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset = assets.openNonAsset(resname, Asset::ACCESS_BUFFER); 668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (asset == NULL) { 669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: dump failed because resource %s found\n", resname); 670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.setTo(asset->getBuffer(true), 674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset->getLength()) != NO_ERROR) { 675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: Resource %s is corrupt\n", resname); 676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printStringPool(&tree.getStrings()); 679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete asset; 680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset = NULL; 681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree tree; 685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset = assets.openNonAsset("AndroidManifest.xml", 686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Asset::ACCESS_BUFFER); 687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (asset == NULL) { 688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: dump failed because no AndroidManifest.xml found\n"); 689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.setTo(asset->getBuffer(true), 693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset->getLength()) != NO_ERROR) { 694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: AndroidManifest.xml is corrupt\n"); 695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tree.restart(); 698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp("permissions", option) == 0) { 700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int depth = 0; 703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth--; 706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != ResXMLTree::START_TAG) { 709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth++; 712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 tag(tree.getElementName(&len)); 713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Depth %d tag %s\n", depth, tag.string()); 714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (depth == 1) { 715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag != "manifest") { 716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: manifest does not start with <manifest> tag\n"); 717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 pkg = getAttribute(tree, NULL, "package", NULL); 7202675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("package: %s\n", ResTable::normalizeForOutput(pkg.string()).string()); 721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (depth == 2 && tag == "permission") { 722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 error; 723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getAttribute(tree, NAME_ATTR, &error); 724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: %s\n", error.string()); 726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 7282675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("permission: %s\n", 7292675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(name.string()).string()); 730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (depth == 2 && tag == "uses-permission") { 731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 error; 732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getAttribute(tree, NAME_ATTR, &error); 733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: %s\n", error.string()); 735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 73758f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesPermission(name, 73858f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski getIntegerAttribute(tree, REQUIRED_ATTR, NULL, 1) == 0, 73958f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR, NULL, -1)); 740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("badging", option) == 0) { 743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<String8> locales; 744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res.getLocales(&locales); 745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<ResTable_config> configs; 747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res.getConfigurations(&configs); 748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SortedVector<int> densities; 749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NC = configs.size(); 750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<NC; i++) { 751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int dens = configs[i].density; 752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (dens == 0) { 753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dens = 160; 754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski densities.add(dens); 756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int depth = 0; 761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 error; 762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool withinActivity = false; 763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isMainActivity = false; 764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isLauncherActivity = false; 765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isSearchable = false; 766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool withinApplication = false; 767ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright bool withinSupportsInput = false; 768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool withinReceiver = false; 769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool withinService = false; 770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool withinIntentFilter = false; 771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasMainActivity = false; 772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasOtherActivities = false; 773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasOtherReceivers = false; 774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasOtherServices = false; 775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasWallpaperService = false; 776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasImeService = false; 777a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool hasAccessibilityService = false; 778a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool hasPrintService = false; 779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasWidgetReceivers = false; 780a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool hasDeviceAdminReceiver = false; 781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasIntentFilter = false; 78294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool hasPaymentService = false; 783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool actMainActivity = false; 784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool actWidgetReceivers = false; 785a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool actDeviceAdminEnabled = false; 786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool actImeService = false; 787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool actWallpaperService = false; 788a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool actAccessibilityService = false; 789a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool actPrintService = false; 79094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool actHostApduService = false; 79194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool actOffHostApduService = false; 79294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool hasMetaHostPaymentCategory = false; 79394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool hasMetaOffHostPaymentCategory = false; 794a5018c900f126ee8424c82497f32983873db741bAdam Lesinski 795a5018c900f126ee8424c82497f32983873db741bAdam Lesinski // These permissions are required by services implementing services 796a5018c900f126ee8424c82497f32983873db741bAdam Lesinski // the system binds to (IME, Accessibility, PrintServices, etc.) 797a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool hasBindDeviceAdminPermission = false; 798a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool hasBindInputMethodPermission = false; 799a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool hasBindAccessibilityServicePermission = false; 800a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool hasBindPrintServicePermission = false; 80194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool hasBindNfcServicePermission = false; 802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // These two implement the implicit permissions that are granted 804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // to pre-1.6 applications. 805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasWriteExternalStoragePermission = false; 806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasReadPhoneStatePermission = false; 807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If an app requests write storage, they will also get read storage. 809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasReadExternalStoragePermission = false; 810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Implement transition to read and write call log. 812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasReadContactsPermission = false; 813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasWriteContactsPermission = false; 814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasReadCallLogPermission = false; 815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasWriteCallLogPermission = false; 816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // This next group of variables is used to implement a group of 818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // backward-compatibility heuristics necessitated by the addition of 819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // some new uses-feature constants in 2.1 and 2.2. In most cases, the 820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // heuristic is "if an app requests a permission but doesn't explicitly 821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // request the corresponding <uses-feature>, presume it's there anyway". 822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool specCameraFeature = false; // camera-related 823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool specCameraAutofocusFeature = false; 824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool reqCameraAutofocusFeature = false; 825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool reqCameraFlashFeature = false; 826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasCameraPermission = false; 827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool specLocationFeature = false; // location-related 828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool specNetworkLocFeature = false; 829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool reqNetworkLocFeature = false; 830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool specGpsFeature = false; 831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool reqGpsFeature = false; 832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasMockLocPermission = false; 833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasCoarseLocPermission = false; 834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasGpsPermission = false; 835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasGeneralLocPermission = false; 836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool specBluetoothFeature = false; // Bluetooth API-related 837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasBluetoothPermission = false; 838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool specMicrophoneFeature = false; // microphone-related 839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasRecordAudioPermission = false; 840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool specWiFiFeature = false; 841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasWiFiPermission = false; 842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool specTelephonyFeature = false; // telephony-related 843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool reqTelephonySubFeature = false; 844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasTelephonyPermission = false; 845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool specTouchscreenFeature = false; // touchscreen-related 846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool specMultitouchFeature = false; 847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool reqDistinctMultitouchFeature = false; 848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool specScreenPortraitFeature = false; 849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool specScreenLandscapeFeature = false; 850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool reqScreenPortraitFeature = false; 851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool reqScreenLandscapeFeature = false; 852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // 2.2 also added some other features that apps can request, but that 853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // have no corresponding permission, so we cannot implement any 854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // back-compatibility heuristic for them. The below are thus unnecessary 855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // (but are retained here for documentary purposes.) 856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //bool specCompassFeature = false; 857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //bool specAccelerometerFeature = false; 858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //bool specProximityFeature = false; 859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //bool specAmbientLightFeature = false; 860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //bool specLiveWallpaperFeature = false; 861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int targetSdk = 0; 863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int smallScreen = 1; 864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int normalScreen = 1; 865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int largeScreen = 1; 866282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int xlargeScreen = 1; 867282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int anyDensity = 1; 868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int requiresSmallestWidthDp = 0; 869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int compatibleWidthLimitDp = 0; 870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int largestWidthLimitDp = 0; 871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 pkg; 872282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 activityName; 873282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 activityLabel; 874282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 activityIcon; 875282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 receiverName; 876282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 serviceName; 877ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright Vector<String8> supportedInput; 878282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 879282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 880282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth--; 881282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (depth < 2) { 882ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (withinSupportsInput && !supportedInput.isEmpty()) { 883ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright printf("supports-input: '"); 884ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright const size_t N = supportedInput.size(); 885ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright for (size_t i=0; i<N; i++) { 8862675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("%s", ResTable::normalizeForOutput( 8872675f769673f69b0661ddee346292f25cb30a296Maurice Chu supportedInput[i].string()).string()); 888ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (i != N - 1) { 889ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright printf("' '"); 890ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else { 891ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright printf("'\n"); 892ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 893ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 894ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright supportedInput.clear(); 895ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinApplication = false; 897ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright withinSupportsInput = false; 898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (depth < 3) { 899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (withinActivity && isMainActivity && isLauncherActivity) { 9002675f769673f69b0661ddee346292f25cb30a296Maurice Chu String8 aName(getComponentName(pkg, activityName)); 901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("launchable-activity:"); 9022675f769673f69b0661ddee346292f25cb30a296Maurice Chu if (aName.length() > 0) { 9032675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf(" name='%s' ", 9042675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(aName.string()).string()); 905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" label='%s' icon='%s'\n", 9072675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(activityLabel.string()).string(), 9082675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(activityIcon.string()).string()); 909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasIntentFilter) { 911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasOtherActivities |= withinActivity; 912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasOtherReceivers |= withinReceiver; 913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasOtherServices |= withinService; 91494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else { 91594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (withinService) { 91694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasPaymentService |= (actHostApduService && hasMetaHostPaymentCategory && 91794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindNfcServicePermission); 91894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasPaymentService |= (actOffHostApduService && hasMetaOffHostPaymentCategory && 91994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindNfcServicePermission); 92094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinActivity = false; 923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinService = false; 924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinReceiver = false; 925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasIntentFilter = false; 926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski isMainActivity = isLauncherActivity = false; 927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (depth < 4) { 928282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (withinIntentFilter) { 929282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (withinActivity) { 930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasMainActivity |= actMainActivity; 931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasOtherActivities |= !actMainActivity; 932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (withinReceiver) { 933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWidgetReceivers |= actWidgetReceivers; 934a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasDeviceAdminReceiver |= (actDeviceAdminEnabled && 935a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasBindDeviceAdminPermission); 936a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasOtherReceivers |= (!actWidgetReceivers && !actDeviceAdminEnabled); 937282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (withinService) { 938282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasImeService |= actImeService; 939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWallpaperService |= actWallpaperService; 940a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasAccessibilityService |= (actAccessibilityService && 941a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasBindAccessibilityServicePermission); 942a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasPrintService |= (actPrintService && hasBindPrintServicePermission); 943a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasOtherServices |= (!actImeService && !actWallpaperService && 94494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski !actAccessibilityService && !actPrintService && 94594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski !actHostApduService && !actOffHostApduService); 946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinIntentFilter = false; 949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 950282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 951282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != ResXMLTree::START_TAG) { 953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth++; 956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 tag(tree.getElementName(&len)); 957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Depth %d, %s\n", depth, tag.string()); 958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (depth == 1) { 959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag != "manifest") { 960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: manifest does not start with <manifest> tag\n"); 961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pkg = getAttribute(tree, NULL, "package", NULL); 9642675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("package: name='%s' ", 9652675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(pkg.string()).string()); 966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t versionCode = getIntegerAttribute(tree, VERSION_CODE_ATTR, &error); 967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:versionCode' attribute: %s\n", error.string()); 969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (versionCode > 0) { 972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("versionCode='%d' ", versionCode); 973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("versionCode='' "); 975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 versionName = getResolvedAttribute(&res, tree, VERSION_NAME_ATTR, &error); 977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:versionName' attribute: %s\n", error.string()); 979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 9812675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("versionName='%s'\n", 9822675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(versionName.string()).string()); 983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (depth == 2) { 984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinApplication = false; 985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag == "application") { 986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinApplication = true; 987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 label; 989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NL = locales.size(); 990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<NL; i++) { 991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* localeStr = locales[i].string(); 992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets.setLocale(localeStr != NULL ? localeStr : ""); 993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 llabel = getResolvedAttribute(&res, tree, LABEL_ATTR, &error); 994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (llabel != "") { 995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (localeStr == NULL || strlen(localeStr) == 0) { 996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski label = llabel; 9972675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("application-label:'%s'\n", 9982675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(llabel.string()).string()); 999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (label == "") { 1001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski label = llabel; 1002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("application-label-%s:'%s'\n", localeStr, 10042675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(llabel.string()).string()); 1005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_config tmpConfig = config; 1010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t ND = densities.size(); 1011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<ND; i++) { 1012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tmpConfig.density = densities[i]; 1013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets.setConfiguration(tmpConfig); 1014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 icon = getResolvedAttribute(&res, tree, ICON_ATTR, &error); 1015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (icon != "") { 10162675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("application-icon-%d:'%s'\n", densities[i], 10172675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(icon.string()).string()); 1018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets.setConfiguration(config); 1021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 icon = getResolvedAttribute(&res, tree, ICON_ATTR, &error); 1023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n", error.string()); 1025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t testOnly = getIntegerAttribute(tree, TEST_ONLY_ATTR, &error, 0); 1028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:testOnly' attribute: %s\n", error.string()); 1030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 10322675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("application: label='%s' ", 10332675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(label.string()).string()); 10342675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("icon='%s'\n", ResTable::normalizeForOutput(icon.string()).string()); 1035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (testOnly != 0) { 1036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("testOnly='%d'\n", testOnly); 1037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t debuggable = getResolvedIntegerAttribute(&res, tree, DEBUGGABLE_ATTR, &error, 0); 1040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:debuggable' attribute: %s\n", error.string()); 1042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (debuggable != 0) { 1045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("application-debuggable\n"); 1046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "uses-sdk") { 1048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t code = getIntegerAttribute(tree, MIN_SDK_VERSION_ATTR, &error); 1049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error = ""; 1051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getResolvedAttribute(&res, tree, MIN_SDK_VERSION_ATTR, &error); 1052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:minSdkVersion' attribute: %s\n", 1054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 1055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name == "Donut") targetSdk = 4; 10582675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("sdkVersion:'%s'\n", 10592675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(name.string()).string()); 1060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (code != -1) { 1061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski targetSdk = code; 1062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("sdkVersion:'%d'\n", code); 1063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski code = getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR, NULL, -1); 1065282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != -1) { 1066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("maxSdkVersion:'%d'\n", code); 1067282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski code = getIntegerAttribute(tree, TARGET_SDK_VERSION_ATTR, &error); 1069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1070282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error = ""; 1071282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getResolvedAttribute(&res, tree, TARGET_SDK_VERSION_ATTR, &error); 1072282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1073282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:targetSdkVersion' attribute: %s\n", 1074282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 1075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name == "Donut" && targetSdk < 4) targetSdk = 4; 10782675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("targetSdkVersion:'%s'\n", 10792675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(name.string()).string()); 1080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (code != -1) { 1081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (targetSdk < code) { 1082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski targetSdk = code; 1083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("targetSdkVersion:'%d'\n", code); 1085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "uses-configuration") { 1087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t reqTouchScreen = getIntegerAttribute(tree, 1088282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_TOUCH_SCREEN_ATTR, NULL, 0); 1089282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t reqKeyboardType = getIntegerAttribute(tree, 1090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_KEYBOARD_TYPE_ATTR, NULL, 0); 1091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t reqHardKeyboard = getIntegerAttribute(tree, 1092282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_HARD_KEYBOARD_ATTR, NULL, 0); 1093282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t reqNavigation = getIntegerAttribute(tree, 1094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_NAVIGATION_ATTR, NULL, 0); 1095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t reqFiveWayNav = getIntegerAttribute(tree, 1096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_FIVE_WAY_NAV_ATTR, NULL, 0); 1097282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-configuration:"); 1098282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqTouchScreen != 0) { 1099282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" reqTouchScreen='%d'", reqTouchScreen); 1100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqKeyboardType != 0) { 1102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" reqKeyboardType='%d'", reqKeyboardType); 1103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqHardKeyboard != 0) { 1105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" reqHardKeyboard='%d'", reqHardKeyboard); 1106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqNavigation != 0) { 1108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" reqNavigation='%d'", reqNavigation); 1109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqFiveWayNav != 0) { 1111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" reqFiveWayNav='%d'", reqFiveWayNav); 1112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 1114ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (tag == "supports-input") { 1115ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright withinSupportsInput = true; 1116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "supports-screens") { 1117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski smallScreen = getIntegerAttribute(tree, 1118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SMALL_SCREEN_ATTR, NULL, 1); 1119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski normalScreen = getIntegerAttribute(tree, 1120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NORMAL_SCREEN_ATTR, NULL, 1); 1121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski largeScreen = getIntegerAttribute(tree, 1122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LARGE_SCREEN_ATTR, NULL, 1); 1123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski xlargeScreen = getIntegerAttribute(tree, 1124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski XLARGE_SCREEN_ATTR, NULL, 1); 1125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski anyDensity = getIntegerAttribute(tree, 1126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ANY_DENSITY_ATTR, NULL, 1); 1127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski requiresSmallestWidthDp = getIntegerAttribute(tree, 1128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQUIRES_SMALLEST_WIDTH_DP_ATTR, NULL, 0); 1129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski compatibleWidthLimitDp = getIntegerAttribute(tree, 1130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski COMPATIBLE_WIDTH_LIMIT_DP_ATTR, NULL, 0); 1131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski largestWidthLimitDp = getIntegerAttribute(tree, 1132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LARGEST_WIDTH_LIMIT_DP_ATTR, NULL, 0); 1133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "uses-feature") { 1134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getAttribute(tree, NAME_ATTR, &error); 1135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 1137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int req = getIntegerAttribute(tree, 1138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQUIRED_ATTR, NULL, 1); 1139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name == "android.hardware.camera") { 1141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specCameraFeature = true; 1142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.hardware.camera.autofocus") { 1143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // these have no corresponding permission to check for, 1144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // but should imply the foundational camera permission 1145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski reqCameraAutofocusFeature = reqCameraAutofocusFeature || req; 1146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specCameraAutofocusFeature = true; 1147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (req && (name == "android.hardware.camera.flash")) { 1148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // these have no corresponding permission to check for, 1149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // but should imply the foundational camera permission 1150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski reqCameraFlashFeature = true; 1151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.hardware.location") { 1152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specLocationFeature = true; 1153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.hardware.location.network") { 1154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specNetworkLocFeature = true; 1155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski reqNetworkLocFeature = reqNetworkLocFeature || req; 1156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.hardware.location.gps") { 1157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specGpsFeature = true; 1158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski reqGpsFeature = reqGpsFeature || req; 1159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.hardware.bluetooth") { 1160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specBluetoothFeature = true; 1161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.hardware.touchscreen") { 1162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specTouchscreenFeature = true; 1163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.hardware.touchscreen.multitouch") { 1164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specMultitouchFeature = true; 1165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.hardware.touchscreen.multitouch.distinct") { 1166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski reqDistinctMultitouchFeature = reqDistinctMultitouchFeature || req; 1167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.hardware.microphone") { 1168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specMicrophoneFeature = true; 1169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.hardware.wifi") { 1170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specWiFiFeature = true; 1171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.hardware.telephony") { 1172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specTelephonyFeature = true; 1173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (req && (name == "android.hardware.telephony.gsm" || 1174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.hardware.telephony.cdma")) { 1175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // these have no corresponding permission to check for, 1176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // but should imply the foundational telephony permission 1177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski reqTelephonySubFeature = true; 1178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.hardware.screen.portrait") { 1179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specScreenPortraitFeature = true; 1180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.hardware.screen.landscape") { 1181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specScreenLandscapeFeature = true; 1182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature%s:'%s'\n", 11842675f769673f69b0661ddee346292f25cb30a296Maurice Chu req ? "" : "-not-required", 11852675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(name.string()).string()); 1186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int vers = getIntegerAttribute(tree, 1188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski GL_ES_VERSION_ATTR, &error); 1189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error == "") { 1190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-gl-es:'0x%x'\n", vers); 1191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "uses-permission") { 1194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getAttribute(tree, NAME_ATTR, &error); 1195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 1196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name == "android.permission.CAMERA") { 1197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasCameraPermission = true; 1198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.ACCESS_FINE_LOCATION") { 1199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasGpsPermission = true; 1200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.ACCESS_MOCK_LOCATION") { 1201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasMockLocPermission = true; 1202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.ACCESS_COARSE_LOCATION") { 1203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasCoarseLocPermission = true; 1204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" || 1205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.INSTALL_LOCATION_PROVIDER") { 1206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasGeneralLocPermission = true; 1207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.BLUETOOTH" || 1208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.BLUETOOTH_ADMIN") { 1209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasBluetoothPermission = true; 1210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.RECORD_AUDIO") { 1211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasRecordAudioPermission = true; 1212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.ACCESS_WIFI_STATE" || 1213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.CHANGE_WIFI_STATE" || 1214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.CHANGE_WIFI_MULTICAST_STATE") { 1215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWiFiPermission = true; 1216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.CALL_PHONE" || 1217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.CALL_PRIVILEGED" || 1218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.MODIFY_PHONE_STATE" || 1219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.PROCESS_OUTGOING_CALLS" || 1220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.READ_SMS" || 1221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.RECEIVE_SMS" || 1222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.RECEIVE_MMS" || 1223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.RECEIVE_WAP_PUSH" || 1224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.SEND_SMS" || 1225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.WRITE_APN_SETTINGS" || 1226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.WRITE_SMS") { 1227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasTelephonyPermission = true; 1228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.WRITE_EXTERNAL_STORAGE") { 1229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWriteExternalStoragePermission = true; 1230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.READ_EXTERNAL_STORAGE") { 1231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasReadExternalStoragePermission = true; 1232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.READ_PHONE_STATE") { 1233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasReadPhoneStatePermission = true; 1234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.READ_CONTACTS") { 1235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasReadContactsPermission = true; 1236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.WRITE_CONTACTS") { 1237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWriteContactsPermission = true; 1238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.READ_CALL_LOG") { 1239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasReadCallLogPermission = true; 1240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.WRITE_CALL_LOG") { 1241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWriteCallLogPermission = true; 1242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 124358f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski 124458f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesPermission(name, 124558f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski getIntegerAttribute(tree, REQUIRED_ATTR, NULL, 1) == 0, 124658f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR, NULL, -1)); 124758f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski } else { 1248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 1250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "uses-package") { 1253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getAttribute(tree, NAME_ATTR, &error); 1254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 12552675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("uses-package:'%s'\n", 12562675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(name.string()).string()); 1257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 1260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "original-package") { 1263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getAttribute(tree, NAME_ATTR, &error); 1264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 12652675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("original-package:'%s'\n", 12662675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(name.string()).string()); 1267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 1270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "supports-gl-texture") { 1273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getAttribute(tree, NAME_ATTR, &error); 1274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 12752675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("supports-gl-texture:'%s'\n", 12762675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(name.string()).string()); 1277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 1280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "compatible-screens") { 1283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printCompatibleScreens(tree); 1284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth--; 1285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "package-verifier") { 1286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getAttribute(tree, NAME_ATTR, &error); 1287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 1288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 publicKey = getAttribute(tree, PUBLIC_KEY_ATTR, &error); 1289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (publicKey != "" && error == "") { 1290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("package-verifier: name='%s' publicKey='%s'\n", 12912675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(name.string()).string(), 12922675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(publicKey.string()).string()); 1293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1296ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (depth == 3) { 1297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinActivity = false; 1298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinReceiver = false; 1299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinService = false; 1300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasIntentFilter = false; 130194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasMetaHostPaymentCategory = false; 130294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasMetaOffHostPaymentCategory = false; 130394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindDeviceAdminPermission = false; 130494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindInputMethodPermission = false; 130594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindAccessibilityServicePermission = false; 130694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindPrintServicePermission = false; 130794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindNfcServicePermission = false; 1308ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (withinApplication) { 1309ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if(tag == "activity") { 1310ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright withinActivity = true; 1311ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright activityName = getAttribute(tree, NAME_ATTR, &error); 1312ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1313ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1314ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright error.string()); 1315ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1316ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1318ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright activityLabel = getResolvedAttribute(&res, tree, LABEL_ATTR, &error); 1319ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1320ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:label' attribute: %s\n", 1321ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright error.string()); 1322ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1323ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1325ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright activityIcon = getResolvedAttribute(&res, tree, ICON_ATTR, &error); 1326ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1327ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n", 1328ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright error.string()); 1329ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1330ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1332ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright int32_t orien = getResolvedIntegerAttribute(&res, tree, 1333ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright SCREEN_ORIENTATION_ATTR, &error); 1334ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error == "") { 1335ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (orien == 0 || orien == 6 || orien == 8) { 1336ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright // Requests landscape, sensorLandscape, or reverseLandscape. 1337ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright reqScreenLandscapeFeature = true; 1338ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (orien == 1 || orien == 7 || orien == 9) { 1339ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright // Requests portrait, sensorPortrait, or reversePortrait. 1340ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright reqScreenPortraitFeature = true; 1341ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1343ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (tag == "uses-library") { 1344ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright String8 libraryName = getAttribute(tree, NAME_ATTR, &error); 1345ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1346ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, 1347ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright "ERROR getting 'android:name' attribute for uses-library" 1348ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright " %s\n", error.string()); 1349ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1350ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1351ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright int req = getIntegerAttribute(tree, 1352ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright REQUIRED_ATTR, NULL, 1); 1353ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright printf("uses-library%s:'%s'\n", 13542675f769673f69b0661ddee346292f25cb30a296Maurice Chu req ? "" : "-not-required", ResTable::normalizeForOutput( 13552675f769673f69b0661ddee346292f25cb30a296Maurice Chu libraryName.string()).string()); 1356ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (tag == "receiver") { 1357ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright withinReceiver = true; 1358ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright receiverName = getAttribute(tree, NAME_ATTR, &error); 1359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1360ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1361ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, 1362ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright "ERROR getting 'android:name' attribute for receiver:" 1363ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright " %s\n", error.string()); 1364ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1365ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1366a5018c900f126ee8424c82497f32983873db741bAdam Lesinski 1367a5018c900f126ee8424c82497f32983873db741bAdam Lesinski String8 permission = getAttribute(tree, PERMISSION_ATTR, &error); 1368a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (error == "") { 1369a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (permission == "android.permission.BIND_DEVICE_ADMIN") { 1370a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasBindDeviceAdminPermission = true; 1371a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1372a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else { 1373a5018c900f126ee8424c82497f32983873db741bAdam Lesinski fprintf(stderr, "ERROR getting 'android:permission' attribute for" 1374a5018c900f126ee8424c82497f32983873db741bAdam Lesinski " receiver '%s': %s\n", receiverName.string(), error.string()); 1375a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1376ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (tag == "service") { 1377ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright withinService = true; 1378ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright serviceName = getAttribute(tree, NAME_ATTR, &error); 1379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1380ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1381ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:name' attribute for " 1382ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright "service:%s\n", error.string()); 1383ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1384ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1385a5018c900f126ee8424c82497f32983873db741bAdam Lesinski 1386a5018c900f126ee8424c82497f32983873db741bAdam Lesinski String8 permission = getAttribute(tree, PERMISSION_ATTR, &error); 1387a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (error == "") { 1388a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (permission == "android.permission.BIND_INPUT_METHOD") { 1389a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasBindInputMethodPermission = true; 1390a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if (permission == "android.permission.BIND_ACCESSIBILITY_SERVICE") { 1391a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasBindAccessibilityServicePermission = true; 1392a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if (permission == "android.permission.BIND_PRINT_SERVICE") { 1393a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasBindPrintServicePermission = true; 139494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else if (permission == "android.permission.BIND_NFC_SERVICE") { 139594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindNfcServicePermission = true; 1396a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1397a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else { 1398a5018c900f126ee8424c82497f32983873db741bAdam Lesinski fprintf(stderr, "ERROR getting 'android:permission' attribute for" 1399a5018c900f126ee8424c82497f32983873db741bAdam Lesinski " service '%s': %s\n", serviceName.string(), error.string()); 1400a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1401ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (bundle->getIncludeMetaData() && tag == "meta-data") { 1402ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright String8 metaDataName = getAttribute(tree, NAME_ATTR, &error); 1403ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1404ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:name' attribute for " 1405ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright "meta-data:%s\n", error.string()); 1406ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1407ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 14082675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("meta-data: name='%s' ", 14092675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(metaDataName.string()).string()); 141076327314d2238e105f8b94909f9c0cf85caca318Maurice Chu printResolvedResourceAttribute(&res, tree, VALUE_ATTR, String8("value"), 141176327314d2238e105f8b94909f9c0cf85caca318Maurice Chu &error); 1412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 141376327314d2238e105f8b94909f9c0cf85caca318Maurice Chu // Try looking for a RESOURCE_ATTR 141476327314d2238e105f8b94909f9c0cf85caca318Maurice Chu error = ""; 141576327314d2238e105f8b94909f9c0cf85caca318Maurice Chu printResolvedResourceAttribute(&res, tree, RESOURCE_ATTR, 141676327314d2238e105f8b94909f9c0cf85caca318Maurice Chu String8("resource"), &error); 1417ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 141876327314d2238e105f8b94909f9c0cf85caca318Maurice Chu fprintf(stderr, "ERROR getting 'android:value' or " 141976327314d2238e105f8b94909f9c0cf85caca318Maurice Chu "'android:resource' attribute for " 142076327314d2238e105f8b94909f9c0cf85caca318Maurice Chu "meta-data:%s\n", error.string()); 1421ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1422ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1423ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 142476327314d2238e105f8b94909f9c0cf85caca318Maurice Chu printf("\n"); 1425ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (withinSupportsInput && tag == "input-type") { 1426ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright String8 name = getAttribute(tree, NAME_ATTR, &error); 1427ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (name != "" && error == "") { 1428ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright supportedInput.add(name); 1429ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else { 1430ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1431ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright error.string()); 1432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1435a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 143694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else if (depth == 4) { 143794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (tag == "intent-filter") { 143894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasIntentFilter = true; 143994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski withinIntentFilter = true; 144094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actMainActivity = false; 144194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actWidgetReceivers = false; 144294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actImeService = false; 144394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actWallpaperService = false; 144494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actAccessibilityService = false; 144594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actPrintService = false; 144694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actDeviceAdminEnabled = false; 144794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actHostApduService = false; 144894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actOffHostApduService = false; 144994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else if (withinService && tag == "meta-data") { 145094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski String8 name = getAttribute(tree, NAME_ATTR, &error); 145194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (error != "") { 145294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute for" 145394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski " meta-data tag in service '%s': %s\n", serviceName.string(), error.string()); 145494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski goto bail; 145594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 145694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 145794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (name == "android.nfc.cardemulation.host_apdu_service" || 145894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski name == "android.nfc.cardemulation.off_host_apdu_service") { 145994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool offHost = true; 146094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (name == "android.nfc.cardemulation.host_apdu_service") { 146194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski offHost = false; 146294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 146394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 146494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski String8 xmlPath = getResolvedAttribute(&res, tree, RESOURCE_ATTR, &error); 146594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (error != "") { 146694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski fprintf(stderr, "ERROR getting 'android:resource' attribute for" 146794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski " meta-data tag in service '%s': %s\n", serviceName.string(), error.string()); 146894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski goto bail; 146994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 147094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 147194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski Vector<String8> categories = getNfcAidCategories(assets, xmlPath, 147294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski offHost, &error); 147394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (error != "") { 147494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski fprintf(stderr, "ERROR getting AID category for service '%s'\n", 147594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski serviceName.string()); 147694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski goto bail; 147794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 147894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 147994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski const size_t catLen = categories.size(); 148094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski for (size_t i = 0; i < catLen; i++) { 148194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool paymentCategory = (categories[i] == "payment"); 148294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (offHost) { 148394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasMetaOffHostPaymentCategory |= paymentCategory; 148494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else { 148594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasMetaHostPaymentCategory |= paymentCategory; 148694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 148794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 148894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 148994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 1490a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if ((depth == 5) && withinIntentFilter) { 1491a5018c900f126ee8424c82497f32983873db741bAdam Lesinski String8 action; 1492a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (tag == "action") { 1493a5018c900f126ee8424c82497f32983873db741bAdam Lesinski action = getAttribute(tree, NAME_ATTR, &error); 1494a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (error != "") { 1495a5018c900f126ee8424c82497f32983873db741bAdam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1496a5018c900f126ee8424c82497f32983873db741bAdam Lesinski error.string()); 1497a5018c900f126ee8424c82497f32983873db741bAdam Lesinski goto bail; 1498a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1499a5018c900f126ee8424c82497f32983873db741bAdam Lesinski 1500a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (withinActivity) { 1501a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (action == "android.intent.action.MAIN") { 1502a5018c900f126ee8424c82497f32983873db741bAdam Lesinski isMainActivity = true; 1503a5018c900f126ee8424c82497f32983873db741bAdam Lesinski actMainActivity = true; 1504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1505a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if (withinReceiver) { 1506a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (action == "android.appwidget.action.APPWIDGET_UPDATE") { 1507a5018c900f126ee8424c82497f32983873db741bAdam Lesinski actWidgetReceivers = true; 1508a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if (action == "android.app.action.DEVICE_ADMIN_ENABLED") { 1509a5018c900f126ee8424c82497f32983873db741bAdam Lesinski actDeviceAdminEnabled = true; 1510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1511a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if (withinService) { 1512a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (action == "android.view.InputMethod") { 1513a5018c900f126ee8424c82497f32983873db741bAdam Lesinski actImeService = true; 1514a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if (action == "android.service.wallpaper.WallpaperService") { 1515a5018c900f126ee8424c82497f32983873db741bAdam Lesinski actWallpaperService = true; 1516a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if (action == "android.accessibilityservice.AccessibilityService") { 1517a5018c900f126ee8424c82497f32983873db741bAdam Lesinski actAccessibilityService = true; 1518a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if (action == "android.printservice.PrintService") { 1519a5018c900f126ee8424c82497f32983873db741bAdam Lesinski actPrintService = true; 152094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else if (action == "android.nfc.cardemulation.action.HOST_APDU_SERVICE") { 152194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actHostApduService = true; 152294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else if (action == "android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE") { 152394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actOffHostApduService = true; 1524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1526a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (action == "android.intent.action.SEARCH") { 1527a5018c900f126ee8424c82497f32983873db741bAdam Lesinski isSearchable = true; 1528a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1529a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1531a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (tag == "category") { 1532a5018c900f126ee8424c82497f32983873db741bAdam Lesinski String8 category = getAttribute(tree, NAME_ATTR, &error); 1533a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (error != "") { 1534a5018c900f126ee8424c82497f32983873db741bAdam Lesinski fprintf(stderr, "ERROR getting 'name' attribute: %s\n", 1535a5018c900f126ee8424c82497f32983873db741bAdam Lesinski error.string()); 1536a5018c900f126ee8424c82497f32983873db741bAdam Lesinski goto bail; 1537a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1538a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (withinActivity) { 1539a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (category == "android.intent.category.LAUNCHER") { 1540a5018c900f126ee8424c82497f32983873db741bAdam Lesinski isLauncherActivity = true; 1541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Pre-1.6 implicitly granted permission compatibility logic 1548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (targetSdk < 4) { 1549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasWriteExternalStoragePermission) { 155058f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesPermission(String8("android.permission.WRITE_EXTERNAL_STORAGE")); 155158f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesImpliedPermission(String8("android.permission.WRITE_EXTERNAL_STORAGE"), 155258f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski String8("targetSdkVersion < 4")); 1553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWriteExternalStoragePermission = true; 1554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasReadPhoneStatePermission) { 155658f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesPermission(String8("android.permission.READ_PHONE_STATE")); 155758f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesImpliedPermission(String8("android.permission.READ_PHONE_STATE"), 155858f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski String8("targetSdkVersion < 4")); 1559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If the application has requested WRITE_EXTERNAL_STORAGE, we will 1563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // force them to always take READ_EXTERNAL_STORAGE as well. We always 1564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // do this (regardless of target API version) because we can't have 1565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // an app with write permission but not read permission. 1566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasReadExternalStoragePermission && hasWriteExternalStoragePermission) { 156758f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesPermission(String8("android.permission.READ_EXTERNAL_STORAGE")); 156858f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesImpliedPermission(String8("android.permission.READ_EXTERNAL_STORAGE"), 156958f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski String8("requested WRITE_EXTERNAL_STORAGE")); 1570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Pre-JellyBean call log permission compatibility. 1573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (targetSdk < 16) { 1574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasReadCallLogPermission && hasReadContactsPermission) { 157558f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesPermission(String8("android.permission.READ_CALL_LOG")); 157658f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesImpliedPermission(String8("android.permission.READ_CALL_LOG"), 157758f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski String8("targetSdkVersion < 16 and requested READ_CONTACTS")); 1578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasWriteCallLogPermission && hasWriteContactsPermission) { 158058f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesPermission(String8("android.permission.WRITE_CALL_LOG")); 158158f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesImpliedPermission(String8("android.permission.WRITE_CALL_LOG"), 158258f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski String8("targetSdkVersion < 16 and requested WRITE_CONTACTS")); 1583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* The following blocks handle printing "inferred" uses-features, based 1587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * on whether related features or permissions are used by the app. 1588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Note that the various spec*Feature variables denote whether the 1589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * relevant tag was *present* in the AndroidManfest, not that it was 1590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * present and set to true. 1591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 1592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Camera-related back-compatibility logic 1593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!specCameraFeature) { 1594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqCameraFlashFeature) { 1595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if app requested a sub-feature (autofocus or flash) and didn't 1596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // request the base camera feature, we infer that it meant to 1597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.camera'\n"); 1598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-feature:'android.hardware.camera'," \ 1599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'requested android.hardware.camera.flash feature'\n"); 1600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (reqCameraAutofocusFeature) { 1601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if app requested a sub-feature (autofocus or flash) and didn't 1602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // request the base camera feature, we infer that it meant to 1603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.camera'\n"); 1604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-feature:'android.hardware.camera'," \ 1605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'requested android.hardware.camera.autofocus feature'\n"); 1606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (hasCameraPermission) { 16072675f769673f69b0661ddee346292f25cb30a296Maurice Chu // if app wants to use camera but didn't request the feature, we infer 1608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // that it meant to, and further that it wants autofocus 1609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // (which was the 1.0 - 1.5 behavior) 1610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.camera'\n"); 1611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!specCameraAutofocusFeature) { 1612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.camera.autofocus'\n"); 1613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-feature:'android.hardware.camera.autofocus'," \ 1614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'requested android.permission.CAMERA permission'\n"); 1615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Location-related back-compatibility logic 1620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!specLocationFeature && 1621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (hasMockLocPermission || hasCoarseLocPermission || hasGpsPermission || 1622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasGeneralLocPermission || reqNetworkLocFeature || reqGpsFeature)) { 1623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if app either takes a location-related permission or requests one of the 1624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // sub-features, we infer that it also meant to request the base location feature 1625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.location'\n"); 1626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-feature:'android.hardware.location'," \ 1627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'requested a location access permission'\n"); 1628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!specGpsFeature && hasGpsPermission) { 1630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if app takes GPS (FINE location) perm but does not request the GPS 1631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // feature, we infer that it meant to 1632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.location.gps'\n"); 1633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-feature:'android.hardware.location.gps'," \ 1634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'requested android.permission.ACCESS_FINE_LOCATION permission'\n"); 1635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!specNetworkLocFeature && hasCoarseLocPermission) { 1637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if app takes Network location (COARSE location) perm but does not request the 1638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // network location feature, we infer that it meant to 1639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.location.network'\n"); 1640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-feature:'android.hardware.location.network'," \ 1641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'requested android.permission.ACCESS_COARSE_LOCATION permission'\n"); 1642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Bluetooth-related compatibility logic 1645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!specBluetoothFeature && hasBluetoothPermission && (targetSdk > 4)) { 1646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if app takes a Bluetooth permission but does not request the Bluetooth 1647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // feature, we infer that it meant to 1648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.bluetooth'\n"); 1649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-feature:'android.hardware.bluetooth'," \ 1650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'requested android.permission.BLUETOOTH or android.permission.BLUETOOTH_ADMIN " \ 1651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "permission and targetSdkVersion > 4'\n"); 1652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Microphone-related compatibility logic 1655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!specMicrophoneFeature && hasRecordAudioPermission) { 1656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if app takes the record-audio permission but does not request the microphone 1657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // feature, we infer that it meant to 1658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.microphone'\n"); 1659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-feature:'android.hardware.microphone'," \ 1660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'requested android.permission.RECORD_AUDIO permission'\n"); 1661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // WiFi-related compatibility logic 1664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!specWiFiFeature && hasWiFiPermission) { 1665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if app takes one of the WiFi permissions but does not request the WiFi 1666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // feature, we infer that it meant to 1667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.wifi'\n"); 1668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-feature:'android.hardware.wifi'," \ 1669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'requested android.permission.ACCESS_WIFI_STATE, " \ 1670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "android.permission.CHANGE_WIFI_STATE, or " \ 1671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "android.permission.CHANGE_WIFI_MULTICAST_STATE permission'\n"); 1672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Telephony-related compatibility logic 1675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!specTelephonyFeature && (hasTelephonyPermission || reqTelephonySubFeature)) { 1676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if app takes one of the telephony permissions or requests a sub-feature but 1677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // does not request the base telephony feature, we infer that it meant to 1678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.telephony'\n"); 1679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-feature:'android.hardware.telephony'," \ 1680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'requested a telephony-related permission or feature'\n"); 1681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Touchscreen-related back-compatibility logic 1684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!specTouchscreenFeature) { // not a typo! 1685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // all apps are presumed to require a touchscreen, unless they explicitly say 1686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // <uses-feature android:name="android.hardware.touchscreen" android:required="false"/> 1687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Note that specTouchscreenFeature is true if the tag is present, regardless 1688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // of whether its value is true or false, so this is safe 1689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.touchscreen'\n"); 1690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-feature:'android.hardware.touchscreen'," \ 1691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'assumed you require a touch screen unless explicitly made optional'\n"); 1692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!specMultitouchFeature && reqDistinctMultitouchFeature) { 1694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if app takes one of the telephony permissions or requests a sub-feature but 1695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // does not request the base telephony feature, we infer that it meant to 1696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.touchscreen.multitouch'\n"); 1697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-feature:'android.hardware.touchscreen.multitouch'," \ 1698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'requested android.hardware.touchscreen.multitouch.distinct feature'\n"); 1699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Landscape/portrait-related compatibility logic 1702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!specScreenLandscapeFeature && !specScreenPortraitFeature) { 1703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If the app has specified any activities in its manifest 1704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // that request a specific orientation, then assume that 1705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // orientation is required. 1706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqScreenLandscapeFeature) { 1707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.screen.landscape'\n"); 1708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-feature:'android.hardware.screen.landscape'," \ 1709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'one or more activities have specified a landscape orientation'\n"); 1710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqScreenPortraitFeature) { 1712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.screen.portrait'\n"); 1713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-feature:'android.hardware.screen.portrait'," \ 1714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'one or more activities have specified a portrait orientation'\n"); 1715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasMainActivity) { 1719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("main\n"); 1720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasWidgetReceivers) { 1722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("app-widget\n"); 1723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1724a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (hasDeviceAdminReceiver) { 1725a5018c900f126ee8424c82497f32983873db741bAdam Lesinski printf("device-admin\n"); 1726a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasImeService) { 1728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("ime\n"); 1729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasWallpaperService) { 1731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("wallpaper\n"); 1732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1733a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (hasAccessibilityService) { 1734a5018c900f126ee8424c82497f32983873db741bAdam Lesinski printf("accessibility\n"); 1735a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1736a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (hasPrintService) { 1737a5018c900f126ee8424c82497f32983873db741bAdam Lesinski printf("print\n"); 1738a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 173994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (hasPaymentService) { 174094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski printf("payment\n"); 174194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 1742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasOtherActivities) { 1743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("other-activities\n"); 1744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (isSearchable) { 1746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("search\n"); 1747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasOtherReceivers) { 1749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("other-receivers\n"); 1750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasOtherServices) { 1752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("other-services\n"); 1753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // For modern apps, if screen size buckets haven't been specified 1756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // but the new width ranges have, then infer the buckets from them. 1757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (smallScreen > 0 && normalScreen > 0 && largeScreen > 0 && xlargeScreen > 0 1758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && requiresSmallestWidthDp > 0) { 1759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int compatWidth = compatibleWidthLimitDp; 1760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (compatWidth <= 0) { 1761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski compatWidth = requiresSmallestWidthDp; 1762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (requiresSmallestWidthDp <= 240 && compatWidth >= 240) { 1764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski smallScreen = -1; 1765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski smallScreen = 0; 1767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (requiresSmallestWidthDp <= 320 && compatWidth >= 320) { 1769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski normalScreen = -1; 1770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski normalScreen = 0; 1772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (requiresSmallestWidthDp <= 480 && compatWidth >= 480) { 1774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski largeScreen = -1; 1775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski largeScreen = 0; 1777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (requiresSmallestWidthDp <= 720 && compatWidth >= 720) { 1779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski xlargeScreen = -1; 1780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski xlargeScreen = 0; 1782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Determine default values for any unspecified screen sizes, 1786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // based on the target SDK of the package. As of 4 (donut) 1787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the screen size support was introduced, so all default to 1788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // enabled. 1789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (smallScreen > 0) { 1790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski smallScreen = targetSdk >= 4 ? -1 : 0; 1791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (normalScreen > 0) { 1793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski normalScreen = -1; 1794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (largeScreen > 0) { 1796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski largeScreen = targetSdk >= 4 ? -1 : 0; 1797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (xlargeScreen > 0) { 1799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Introduced in Gingerbread. 1800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski xlargeScreen = targetSdk >= 9 ? -1 : 0; 1801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (anyDensity > 0) { 1803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski anyDensity = (targetSdk >= 4 || requiresSmallestWidthDp > 0 1804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || compatibleWidthLimitDp > 0) ? -1 : 0; 1805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("supports-screens:"); 1807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (smallScreen != 0) { 1808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" 'small'"); 1809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (normalScreen != 0) { 1811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" 'normal'"); 1812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (largeScreen != 0) { 1814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" 'large'"); 1815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (xlargeScreen != 0) { 1817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" 'xlarge'"); 1818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 1820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("supports-any-density: '%s'\n", anyDensity ? "true" : "false"); 1821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (requiresSmallestWidthDp > 0) { 1822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("requires-smallest-width:'%d'\n", requiresSmallestWidthDp); 1823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (compatibleWidthLimitDp > 0) { 1825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("compatible-width-limit:'%d'\n", compatibleWidthLimitDp); 1826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (largestWidthLimitDp > 0) { 1828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("largest-width-limit:'%d'\n", largestWidthLimitDp); 1829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("locales:"); 1832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NL = locales.size(); 1833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<NL; i++) { 1834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* localeStr = locales[i].string(); 1835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (localeStr == NULL || strlen(localeStr) == 0) { 1836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski localeStr = "--_--"; 1837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" '%s'", localeStr); 1839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 1841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("densities:"); 1843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t ND = densities.size(); 1844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<ND; i++) { 1845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" '%d'", densities[i]); 1846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 1848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AssetDir* dir = assets.openNonAssetDir(assetsCookie, "lib"); 1850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (dir != NULL) { 1851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (dir->getFileCount() > 0) { 1852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("native-code:"); 1853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<dir->getFileCount(); i++) { 18542675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf(" '%s'", ResTable::normalizeForOutput( 18552675f769673f69b0661ddee346292f25cb30a296Maurice Chu dir->getFileName(i).string()).string()); 1856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 1858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete dir; 1860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("badger", option) == 0) { 1862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%s", CONSOLE_DATA); 1863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("configurations", option) == 0) { 1864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<ResTable_config> configs; 1865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res.getConfigurations(&configs); 1866282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = configs.size(); 1867282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 1868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%s\n", configs[i].toString().string()); 1869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: unknown dump option '%s'\n", option); 1872282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1873282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1874282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1875282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1876282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = NO_ERROR; 1877282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1878282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 1879282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (asset) { 1880282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete asset; 1881282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1882282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (result != NO_ERROR); 1883282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1884282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1886282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 1887282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Handle the "add" command, which wants to add files to a new or 1888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * pre-existing archive. 1889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 1890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doAdd(Bundle* bundle) 1891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipFile* zip = NULL; 1893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result = UNKNOWN_ERROR; 1894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* zipFileName; 1895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getUpdate()) { 1897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* avoid confusion */ 1898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: can't use '-u' with add\n"); 1899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 1) { 1903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: must specify zip file name\n"); 1904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zipFileName = bundle->getFileSpecEntry(0); 1907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 2) { 1909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "NOTE: nothing to do\n"); 1910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip = openReadWrite(zipFileName, true); 1914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (zip == NULL) { 1915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: failed opening/creating '%s' as Zip file\n", zipFileName); 1916282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1917282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i = 1; i < bundle->getFileSpecCount(); i++) { 1920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* fileName = bundle->getFileSpecEntry(i); 1921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcasecmp(String8(fileName).getPathExtension().string(), ".gz") == 0) { 1923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" '%s'... (from gzip)\n", fileName); 1924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = zip->addGzip(fileName, String8(fileName).getBasePath().string(), NULL); 1925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getJunkPath()) { 1927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 storageName = String8(fileName).getPathLeaf(); 19282675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf(" '%s' as '%s'...\n", fileName, 19292675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(storageName.string()).string()); 1930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = zip->add(fileName, storageName.string(), 1931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bundle->getCompressionMethod(), NULL); 1932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" '%s'...\n", fileName); 1934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = zip->add(fileName, bundle->getCompressionMethod(), NULL); 1935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1937282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result != NO_ERROR) { 1938282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "Unable to add '%s' to '%s'", bundle->getFileSpecEntry(i), zipFileName); 1939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result == NAME_NOT_FOUND) { 1940282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, ": file not found\n"); 1941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (result == ALREADY_EXISTS) { 1942282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, ": already exists in archive\n"); 1943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "\n"); 1945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1950282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = NO_ERROR; 1951282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 1953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete zip; 1954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (result != NO_ERROR); 1955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 1959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Delete files from an existing archive. 1960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 1961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doRemove(Bundle* bundle) 1962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipFile* zip = NULL; 1964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result = UNKNOWN_ERROR; 1965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* zipFileName; 1966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 1) { 1968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: must specify zip file name\n"); 1969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zipFileName = bundle->getFileSpecEntry(0); 1972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 2) { 1974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "NOTE: nothing to do\n"); 1975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip = openReadWrite(zipFileName, false); 1979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (zip == NULL) { 1980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: failed opening Zip archive '%s'\n", 1981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zipFileName); 1982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i = 1; i < bundle->getFileSpecCount(); i++) { 1986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* fileName = bundle->getFileSpecEntry(i); 1987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry* entry; 1988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entry = zip->getEntryByName(fileName); 1990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (entry == NULL) { 1991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" '%s' NOT FOUND\n", fileName); 1992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = zip->remove(entry); 1996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result != NO_ERROR) { 1998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "Unable to delete '%s' from '%s'\n", 1999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bundle->getFileSpecEntry(i), zipFileName); 2000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* update the archive */ 2005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip->flush(); 2006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 2008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete zip; 2009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (result != NO_ERROR); 2010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 2014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Package up an asset directory and associated application files. 2015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 2016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doPackage(Bundle* bundle) 2017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* outputAPKFile; 2019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int retVal = 1; 2020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err; 2021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptAssets> assets; 2022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int N; 2023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FILE* fp; 2024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 dependencyFile; 2025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // -c zz_ZZ means do pseudolocalization 2027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceFilter filter; 2028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = filter.parse(bundle->getConfigurations()); 2029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 2030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (filter.containsPseudo()) { 2033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bundle->setPseudolocalize(true); 2034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski N = bundle->getFileSpecCount(); 2037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (N < 1 && bundle->getResourceSourceDirs().size() == 0 && bundle->getJarFiles().size() == 0 203809384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski && bundle->getAndroidManifestFile() == NULL && bundle->getAssetSourceDirs().size() == 0) { 2039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: no input files\n"); 2040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outputAPKFile = bundle->getOutputAPKFile(); 2044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Make sure the filenames provided exist and are of the appropriate type. 2046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outputAPKFile) { 2047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FileType type; 2048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type = getFileType(outputAPKFile); 2049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (type != kFileTypeNonexistent && type != kFileTypeRegular) { 2050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, 2051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "ERROR: output file '%s' exists but is not regular file\n", 2052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outputAPKFile); 2053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Load the assets. 2058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets = new AaptAssets(); 2059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Set up the resource gathering in assets if we're going to generate 2061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // dependency files. Every time we encounter a resource while slurping 2062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the tree, we'll add it to these stores so we have full resource paths 2063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // to write to a dependency file. 2064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getGenDependencies()) { 2065282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<FilePathStore> resPathStore = new FilePathStore; 2066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->setFullResPaths(resPathStore); 2067282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<FilePathStore> assetPathStore = new FilePathStore; 2068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->setFullAssetPaths(assetPathStore); 2069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2070282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2071282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = assets->slurpFromArgs(bundle); 2072282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 2073282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2074282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 2077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->print(String8()); 2078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If they asked for any fileAs that need to be compiled, do so. 2081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getResourceSourceDirs().size() || bundle->getAndroidManifestFile()) { 2082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = buildResources(bundle, assets); 2083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != 0) { 2084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2088282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // At this point we've read everything and processed everything. From here 2089282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // on out it's just writing output files. 2090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (SourcePos::hasErrors()) { 2091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2092282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2093282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Update symbols with information about which ones are needed as Java symbols. 2095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->applyJavaSymbols(); 2096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (SourcePos::hasErrors()) { 2097282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2098282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2099282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If we've been asked to generate a dependency file, do that here 2101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getGenDependencies()) { 2102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If this is the packaging step, generate the dependency file next to 2103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the output apk (e.g. bin/resources.ap_.d) 2104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outputAPKFile) { 2105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dependencyFile = String8(outputAPKFile); 2106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Add the .d extension to the dependency file. 2107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dependencyFile.append(".d"); 2108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Else if this is the R.java dependency generation step, 2110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // generate the dependency file in the R.java package subdirectory 2111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // e.g. gen/com/foo/app/R.java.d 2112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dependencyFile = String8(bundle->getRClassDir()); 2113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dependencyFile.appendPath("R.java.d"); 2114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Make sure we have a clean dependency file to start with 2116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fp = fopen(dependencyFile, "w"); 2117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fclose(fp); 2118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write out R.java constants 2121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!assets->havePrivateSymbols()) { 2122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getCustomPackage() == NULL) { 2123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write the R.java file into the appropriate class directory 2124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // e.g. gen/com/foo/app/R.java 2125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeResourceSymbols(bundle, assets, assets->getPackage(), true); 2126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8 customPkg(bundle->getCustomPackage()); 2128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeResourceSymbols(bundle, assets, customPkg, true); 2129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 2131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If we have library files, we're going to write our R.java file into 2134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the appropriate class directory for those libraries as well. 2135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // e.g. gen/com/foo/app/lib/R.java 2136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getExtraPackages() != NULL) { 2137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Split on colon 2138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 libs(bundle->getExtraPackages()); 2139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char* packageString = strtok(libs.lockBuffer(libs.length()), ":"); 2140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (packageString != NULL) { 2141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write the R.java file out with the correct package name 2142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeResourceSymbols(bundle, assets, String8(packageString), true); 2143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 2144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski packageString = strtok(NULL, ":"); 2147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski libs.unlockBuffer(); 2149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeResourceSymbols(bundle, assets, assets->getPackage(), false); 2152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 2153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeResourceSymbols(bundle, assets, assets->getSymbolsPrivatePackage(), true); 2156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 2157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write out the ProGuard file 2162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeProguardFile(bundle, assets); 2163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 2164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write the apk 2168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outputAPKFile) { 2169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeAPK(bundle, assets, String8(outputAPKFile)); 2170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 2171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: packaging of '%s' failed\n", outputAPKFile); 2172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If we've been asked to generate a dependency file, we need to finish up here. 2177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the writeResourceSymbols and writeAPK functions have already written the target 2178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // half of the dependency file, now we need to write the prerequisites. (files that 2179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the R.java file or .ap_ file depend on) 2180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getGenDependencies()) { 2181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Now that writeResourceSymbols or writeAPK has taken care of writing 2182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the targets to our dependency file, we'll write the prereqs 2183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fp = fopen(dependencyFile, "a+"); 2184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, " : "); 2185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool includeRaw = (outputAPKFile != NULL); 2186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeDependencyPreReqs(bundle, assets, fp, includeRaw); 2187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Also manually add the AndroidManifeset since it's not under res/ or assets/ 2188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // and therefore was not added to our pathstores during slurping 2189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s \\\n", bundle->getAndroidManifestFile()); 2190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fclose(fp); 2191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski retVal = 0; 2194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 2195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (SourcePos::hasErrors()) { 2196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos::printErrors(stderr); 2197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return retVal; 2199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 2202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Do PNG Crunching 2203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * PRECONDITIONS 2204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * -S flag points to a source directory containing drawable* folders 2205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * -C flag points to destination directory. The folder structure in the 2206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * source directory will be mirrored to the destination (cache) directory 2207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 2208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * POSTCONDITIONS 2209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Destination directory will be updated to match the PNG files in 22102675f769673f69b0661ddee346292f25cb30a296Maurice Chu * the source directory. 2211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 2212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doCrunch(Bundle* bundle) 2213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "Crunching PNG Files in "); 2215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "source dir: %s\n", bundle->getResourceSourceDirs()[0]); 2216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "To destination dir: %s\n", bundle->getCrunchedOutputDir()); 2217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski updatePreProcessedCache(bundle); 2219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 2221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 2224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Do PNG Crunching on a single flag 2225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * -i points to a single png file 2226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * -o points to a single png output file 2227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 2228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doSingleCrunch(Bundle* bundle) 2229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "Crunching single PNG file: %s\n", bundle->getSingleCrunchInputFile()); 2231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "\tOutput file: %s\n", bundle->getSingleCrunchOutputFile()); 2232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 input(bundle->getSingleCrunchInputFile()); 2234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 output(bundle->getSingleCrunchOutputFile()); 2235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (preProcessImageToCache(bundle, input, output) != NO_ERROR) { 2237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // we can't return the status_t as it gets truncate to the lower 8 bits. 2238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 42; 2239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 2242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskichar CONSOLE_DATA[2925] = { 2245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 95, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 2249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 63, 2250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 86, 35, 40, 46, 46, 95, 95, 95, 95, 97, 97, 44, 32, 46, 124, 42, 33, 83, 2251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 62, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 46, 58, 59, 61, 59, 61, 81, 2254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 66, 96, 61, 61, 58, 46, 46, 46, 58, 32, 32, 32, 32, 32, 32, 2255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 2256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 46, 61, 59, 59, 59, 58, 106, 81, 81, 81, 81, 102, 59, 61, 59, 2258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 61, 61, 61, 58, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 2261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 58, 109, 81, 81, 81, 81, 61, 59, 59, 59, 59, 59, 58, 59, 59, 46, 32, 2262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 60, 81, 81, 81, 81, 87, 2265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 58, 59, 59, 59, 59, 59, 59, 61, 119, 44, 32, 32, 32, 32, 32, 32, 32, 32, 2266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 2267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 2268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 47, 61, 59, 59, 58, 100, 81, 81, 81, 81, 35, 58, 59, 59, 59, 59, 59, 58, 2269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 121, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 109, 58, 59, 59, 61, 81, 81, 2272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 109, 58, 59, 59, 59, 59, 61, 109, 81, 81, 76, 46, 32, 32, 32, 2273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 2274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 41, 87, 59, 61, 59, 41, 81, 81, 81, 81, 81, 81, 59, 61, 59, 2276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 58, 109, 81, 81, 87, 39, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 60, 81, 91, 59, 2279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 61, 81, 81, 81, 81, 81, 87, 43, 59, 58, 59, 60, 81, 81, 81, 76, 32, 2280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 52, 91, 58, 45, 59, 87, 81, 81, 81, 81, 2283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 70, 58, 58, 58, 59, 106, 81, 81, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32, 2284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 2285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 93, 40, 32, 46, 59, 100, 81, 81, 81, 81, 40, 58, 46, 46, 58, 100, 81, 2287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 68, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 46, 46, 46, 32, 46, 46, 46, 32, 46, 32, 46, 45, 91, 59, 61, 58, 109, 2290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 87, 46, 58, 61, 59, 60, 81, 81, 80, 32, 32, 32, 32, 32, 32, 2291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 2292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 46, 46, 61, 59, 61, 61, 61, 59, 61, 61, 59, 2293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 58, 58, 46, 46, 41, 58, 59, 58, 81, 81, 81, 81, 69, 58, 59, 59, 2294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 60, 81, 81, 68, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 58, 59, 2296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 61, 46, 2297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 59, 93, 81, 81, 81, 81, 107, 58, 59, 58, 109, 87, 68, 96, 32, 32, 32, 2298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 10, 32, 32, 32, 46, 60, 61, 61, 59, 59, 59, 59, 59, 59, 59, 59, 2300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 59, 59, 59, 58, 58, 58, 115, 109, 68, 41, 36, 81, 2301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 109, 46, 61, 61, 81, 69, 96, 46, 58, 58, 46, 58, 46, 46, 32, 32, 32, 32, 2302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 46, 32, 95, 81, 2303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 67, 61, 61, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 2304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 58, 68, 39, 61, 105, 61, 63, 81, 119, 58, 106, 80, 32, 58, 2305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 59, 59, 61, 59, 61, 59, 61, 46, 95, 32, 32, 32, 32, 32, 32, 32, 32, 2306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 10, 32, 32, 36, 81, 109, 105, 59, 61, 59, 59, 59, 2307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 46, 58, 37, 2308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 73, 108, 108, 62, 52, 81, 109, 34, 32, 61, 59, 59, 59, 59, 59, 59, 59, 59, 2309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 61, 59, 61, 61, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 2310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 46, 45, 57, 101, 43, 43, 61, 61, 59, 59, 59, 59, 59, 59, 61, 59, 59, 2311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 59, 58, 97, 46, 61, 108, 62, 126, 58, 106, 80, 96, 2312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46, 61, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 61, 2313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 97, 103, 97, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 45, 46, 32, 2314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45, 58, 59, 59, 59, 59, 61, 2315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 119, 81, 97, 124, 105, 124, 124, 39, 126, 95, 119, 58, 61, 58, 59, 59, 59, 2316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 119, 81, 81, 99, 32, 32, 2317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 58, 106, 81, 81, 81, 109, 119, 2319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 119, 119, 109, 109, 81, 81, 122, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 2320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 58, 115, 81, 87, 81, 102, 32, 32, 32, 32, 32, 32, 10, 2321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 61, 58, 59, 61, 81, 81, 81, 81, 81, 81, 87, 87, 81, 81, 81, 81, 2323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 58, 59, 59, 59, 59, 59, 59, 59, 59, 58, 45, 45, 45, 59, 59, 59, 41, 2324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 87, 66, 33, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 2325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 93, 81, 2326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 2327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 45, 32, 46, 32, 32, 32, 32, 32, 46, 32, 126, 96, 32, 32, 32, 32, 32, 32, 2328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 58, 61, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81, 2330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 2331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 2332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 2333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58, 2334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 60, 81, 81, 81, 81, 2337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 81, 81, 81, 81, 59, 61, 59, 59, 61, 32, 32, 32, 32, 2338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 58, 59, 59, 93, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 2341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 40, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 2343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 106, 2344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 76, 58, 59, 59, 59, 2345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 61, 58, 58, 81, 81, 81, 81, 81, 81, 81, 81, 2348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 87, 58, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 2349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 2350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 58, 59, 61, 41, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 87, 59, 2352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 58, 59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 61, 81, 81, 81, 2355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 81, 81, 81, 81, 107, 58, 59, 59, 59, 59, 58, 32, 32, 2356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 58, 59, 59, 58, 51, 81, 81, 81, 81, 81, 81, 81, 81, 81, 2359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 102, 94, 59, 59, 59, 59, 59, 61, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 2361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 2362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 43, 63, 36, 81, 81, 81, 87, 64, 86, 102, 58, 59, 59, 59, 59, 59, 2363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 59, 59, 43, 33, 2366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 58, 126, 126, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32, 32, 2367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 2368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 2369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 59, 59, 59, 58, 45, 58, 61, 59, 58, 58, 58, 61, 59, 59, 59, 59, 59, 2370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 2371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 2372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 58, 95, 2373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 45, 61, 59, 61, 59, 59, 59, 59, 59, 59, 59, 45, 58, 59, 59, 59, 59, 2374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 58, 61, 59, 59, 59, 59, 59, 61, 59, 61, 46, 46, 32, 45, 45, 45, 2377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 58, 45, 45, 46, 58, 59, 59, 59, 59, 59, 59, 61, 46, 32, 32, 32, 32, 2378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 2379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 58, 59, 59, 59, 59, 2380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 61, 59, 46, 32, 32, 46, 32, 46, 32, 58, 61, 59, 59, 2381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 45, 59, 59, 59, 59, 59, 59, 59, 59, 58, 32, 2384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 58, 32, 2385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 2386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46, 61, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 61, 2388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46, 61, 59, 59, 59, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 2390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 2391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 46, 61, 58, 59, 59, 59, 59, 2392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 58, 59, 59, 59, 59, 59, 59, 59, 59, 46, 46, 32, 32, 32, 2395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 45, 32, 32, 32, 32, 32, 2396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 2397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 32, 45, 61, 2398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 2399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 58, 45, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45, 45, 32, 46, 32, 2402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 61, 59, 58, 45, 45, 32, 32, 32, 2403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 46, 32, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10 2408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski }; 2409