Command.cpp revision d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2d
1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Copyright 2006 The Android Open Source Project 3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Android Asset Packaging Tool main entry point. 5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 6ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski#include "AaptXml.h" 7fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski#include "ApkBuilder.h" 8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "Bundle.h" 92c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski#include "Images.h" 102c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski#include "Main.h" 11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "ResourceFilter.h" 12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "ResourceTable.h" 13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "XMLNode.h" 14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 152c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski#include <utils/Errors.h> 162c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski#include <utils/KeyedVector.h> 172c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski#include <utils/List.h> 18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <utils/Log.h> 192c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski#include <utils/SortedVector.h> 20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <utils/threads.h> 212c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski#include <utils/Vector.h> 22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <errno.h> 242c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski#include <fcntl.h> 25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 266f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez#include <iostream> 276f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez#include <string> 286f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez#include <sstream> 296f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez 30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiusing namespace android; 31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32ad751224401564dcc8338df3d5c4c5de7722be8fAdam Lesinski#ifndef AAPT_VERSION 33ad751224401564dcc8338df3d5c4c5de7722be8fAdam Lesinski #define AAPT_VERSION "" 34ad751224401564dcc8338df3d5c4c5de7722be8fAdam Lesinski#endif 35ad751224401564dcc8338df3d5c4c5de7722be8fAdam Lesinski 36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Show version info. All the cool kids do it. 38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doVersion(Bundle* bundle) 40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() != 0) { 42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("(ignoring extra arguments)\n"); 43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 44ad751224401564dcc8338df3d5c4c5de7722be8fAdam Lesinski printf("Android Asset Packaging Tool, v0.2-" AAPT_VERSION "\n"); 45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Open the file read only. The call fails if the file doesn't exist. 52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Returns NULL on failure. 54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 55282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiZipFile* openReadOnly(const char* fileName) 56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipFile* zip; 58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result; 59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip = new ZipFile; 61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = zip->open(fileName, ZipFile::kOpenReadOnly); 62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result != NO_ERROR) { 63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result == NAME_NOT_FOUND) { 64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: '%s' not found\n", fileName); 65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (result == PERMISSION_DENIED) { 66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: '%s' access denied\n", fileName); 67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: failed opening '%s' as Zip file\n", 69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fileName); 70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete zip; 72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return zip; 76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Open the file read-write. The file will be created if it doesn't 80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * already exist and "okayToCreate" is set. 81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Returns NULL on failure. 83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 84282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiZipFile* openReadWrite(const char* fileName, bool okayToCreate) 85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipFile* zip = NULL; 87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result; 88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int flags; 89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flags = ZipFile::kOpenReadWrite; 91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (okayToCreate) { 92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flags |= ZipFile::kOpenCreate; 93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip = new ZipFile; 96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = zip->open(fileName, flags); 97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result != NO_ERROR) { 98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete zip; 99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip = NULL; 100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return zip; 105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Return a short string describing the compression method. 110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiconst char* compressionName(int method) 112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (method == ZipEntry::kCompressStored) { 114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return "Stored"; 115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (method == ZipEntry::kCompressDeflated) { 116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return "Deflated"; 117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return "Unknown"; 119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Return the percent reduction in size (0% == no compression). 124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint calcPercent(long uncompressedLen, long compressedLen) 126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!uncompressedLen) { 128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (int) (100.0 - (compressedLen * 100.0) / uncompressedLen + 0.5); 131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Handle the "list" command, which can be a simple file dump or 136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * a verbose listing. 137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * The verbose listing closely matches the output of the Info-ZIP "unzip" 139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * command. 140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doList(Bundle* bundle) 142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int result = 1; 144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipFile* zip = NULL; 145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ZipEntry* entry; 146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski long totalUncLen, totalCompLen; 147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* zipFileName; 148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() != 1) { 150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: specify zip file name (only)\n"); 151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zipFileName = bundle->getFileSpecEntry(0); 154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip = openReadOnly(zipFileName); 156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (zip == NULL) { 157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int count, i; 161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Archive: %s\n", zipFileName); 164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf( 165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " Length Method Size Ratio Offset Date Time CRC-32 Name\n"); 166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf( 167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "-------- ------ ------- ----- ------- ---- ---- ------ ----\n"); 168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalUncLen = totalCompLen = 0; 171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count = zip->getNumEntries(); 173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i = 0; i < count; i++) { 174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entry = zip->getEntryByIndex(i); 175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char dateBuf[32]; 177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski time_t when; 178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski when = entry->getModWhen(); 180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strftime(dateBuf, sizeof(dateBuf), "%m-%d-%y %H:%M", 181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski localtime(&when)); 182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%8ld %-7.7s %7ld %3d%% %8zd %s %08lx %s\n", 184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (long) entry->getUncompressedLen(), 185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski compressionName(entry->getCompressionMethod()), 186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (long) entry->getCompressedLen(), 187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski calcPercent(entry->getUncompressedLen(), 188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entry->getCompressedLen()), 189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (size_t) entry->getLFHOffset(), 190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dateBuf, 191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entry->getCRC32(), 192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entry->getFileName()); 193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%s\n", entry->getFileName()); 195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalUncLen += entry->getUncompressedLen(); 198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalCompLen += entry->getCompressedLen(); 199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf( 203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "-------- ------- --- -------\n"); 204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%8ld %7ld %2d%% %d files\n", 205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalUncLen, 206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalCompLen, 207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski calcPercent(totalUncLen, totalCompLen), 208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip->getNumEntries()); 209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getAndroidList()) { 212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AssetManager assets; 213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!assets.addAssetPath(String8(zipFileName), NULL)) { 214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: list -a failed because assets could not be loaded\n"); 215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable& res = assets.getResources(false); 219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (&res == NULL) { 220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\nNo resource table found.\n"); 221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#ifndef HAVE_ANDROID_OS 223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\nResource table:\n"); 224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res.print(false); 225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Asset* manifestAsset = assets.openNonAsset("AndroidManifest.xml", 229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Asset::ACCESS_BUFFER); 230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (manifestAsset == NULL) { 231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\nNo AndroidManifest.xml found.\n"); 232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\nAndroid manifest:\n"); 234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree tree; 235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tree.setTo(manifestAsset->getBuffer(true), 236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski manifestAsset->getLength()); 237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printXMLBlock(&tree); 238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete manifestAsset; 240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = 0; 243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete zip; 246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return result; 247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 249ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinskistatic void printResolvedResourceAttribute(const ResTable& resTable, const ResXMLTree& tree, 25076327314d2238e105f8b94909f9c0cf85caca318Maurice Chu uint32_t attrRes, String8 attrLabel, String8* outError) 25176327314d2238e105f8b94909f9c0cf85caca318Maurice Chu{ 25276327314d2238e105f8b94909f9c0cf85caca318Maurice Chu Res_value value; 253ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski AaptXml::getResolvedResourceAttribute(resTable, tree, attrRes, &value, outError); 25476327314d2238e105f8b94909f9c0cf85caca318Maurice Chu if (*outError != "") { 25576327314d2238e105f8b94909f9c0cf85caca318Maurice Chu *outError = "error print resolved resource attribute"; 25676327314d2238e105f8b94909f9c0cf85caca318Maurice Chu return; 25776327314d2238e105f8b94909f9c0cf85caca318Maurice Chu } 25876327314d2238e105f8b94909f9c0cf85caca318Maurice Chu if (value.dataType == Res_value::TYPE_STRING) { 259ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 result = AaptXml::getResolvedAttribute(resTable, tree, attrRes, outError); 2602675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("%s='%s'", attrLabel.string(), 2612675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(result.string()).string()); 26276327314d2238e105f8b94909f9c0cf85caca318Maurice Chu } else if (Res_value::TYPE_FIRST_INT <= value.dataType && 26376327314d2238e105f8b94909f9c0cf85caca318Maurice Chu value.dataType <= Res_value::TYPE_LAST_INT) { 26476327314d2238e105f8b94909f9c0cf85caca318Maurice Chu printf("%s='%d'", attrLabel.string(), value.data); 26576327314d2238e105f8b94909f9c0cf85caca318Maurice Chu } else { 26676327314d2238e105f8b94909f9c0cf85caca318Maurice Chu printf("%s='0x%x'", attrLabel.string(), (int)value.data); 26776327314d2238e105f8b94909f9c0cf85caca318Maurice Chu } 26876327314d2238e105f8b94909f9c0cf85caca318Maurice Chu} 26976327314d2238e105f8b94909f9c0cf85caca318Maurice Chu 270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// These are attribute resource constants for the platform, as found 271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// in android.R.attr 272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskienum { 273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LABEL_ATTR = 0x01010001, 274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ICON_ATTR = 0x01010002, 275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NAME_ATTR = 0x01010003, 276a5018c900f126ee8424c82497f32983873db741bAdam Lesinski PERMISSION_ATTR = 0x01010006, 2779d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski EXPORTED_ATTR = 0x01010010, 2789d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski GRANT_URI_PERMISSIONS_ATTR = 0x0101001b, 27994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski RESOURCE_ATTR = 0x01010025, 280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DEBUGGABLE_ATTR = 0x0101000f, 281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski VALUE_ATTR = 0x01010024, 282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski VERSION_CODE_ATTR = 0x0101021b, 283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski VERSION_NAME_ATTR = 0x0101021c, 284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SCREEN_ORIENTATION_ATTR = 0x0101001e, 285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MIN_SDK_VERSION_ATTR = 0x0101020c, 286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MAX_SDK_VERSION_ATTR = 0x01010271, 287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_TOUCH_SCREEN_ATTR = 0x01010227, 288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_KEYBOARD_TYPE_ATTR = 0x01010228, 289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_HARD_KEYBOARD_ATTR = 0x01010229, 290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_NAVIGATION_ATTR = 0x0101022a, 291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_FIVE_WAY_NAV_ATTR = 0x01010232, 292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski TARGET_SDK_VERSION_ATTR = 0x01010270, 293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski TEST_ONLY_ATTR = 0x01010272, 294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ANY_DENSITY_ATTR = 0x0101026c, 295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski GL_ES_VERSION_ATTR = 0x01010281, 296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SMALL_SCREEN_ATTR = 0x01010284, 297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NORMAL_SCREEN_ATTR = 0x01010285, 298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LARGE_SCREEN_ATTR = 0x01010286, 299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski XLARGE_SCREEN_ATTR = 0x010102bf, 300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQUIRED_ATTR = 0x0101028e, 301caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski INSTALL_LOCATION_ATTR = 0x010102b7, 302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SCREEN_SIZE_ATTR = 0x010102ca, 303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SCREEN_DENSITY_ATTR = 0x010102cb, 304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQUIRES_SMALLEST_WIDTH_DP_ATTR = 0x01010364, 305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski COMPATIBLE_WIDTH_LIMIT_DP_ATTR = 0x01010365, 306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LARGEST_WIDTH_LIMIT_DP_ATTR = 0x01010366, 307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PUBLIC_KEY_ATTR = 0x010103a6, 30894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski CATEGORY_ATTR = 0x010103e8, 3090a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn BANNER_ATTR = 0x10103f2, 310d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn ISGAME_ATTR = 0x10103f4, 311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3132675f769673f69b0661ddee346292f25cb30a296Maurice ChuString8 getComponentName(String8 &pkgName, String8 &componentName) { 314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t idx = componentName.find("."); 315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 retStr(pkgName); 316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx == 0) { 317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski retStr += componentName; 318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (idx < 0) { 319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski retStr += "."; 320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski retStr += componentName; 321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3222675f769673f69b0661ddee346292f25cb30a296Maurice Chu return componentName; 323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3242675f769673f69b0661ddee346292f25cb30a296Maurice Chu return retStr; 325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3279cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinskistatic void printCompatibleScreens(ResXMLTree& tree, String8* outError) { 328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int depth = 0; 331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool first = true; 332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("compatible-screens:"); 333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth--; 336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (depth < 0) { 337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != ResXMLTree::START_TAG) { 342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth++; 3459cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski const char16_t* ctag16 = tree.getElementName(&len); 3469cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski if (ctag16 == NULL) { 3479cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski *outError = "failed to get XML element name (bad string pool)"; 3489cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski return; 3499cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski } 3509cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski String8 tag(ctag16); 351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag == "screen") { 352ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int32_t screenSize = AaptXml::getIntegerAttribute(tree, 353ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski SCREEN_SIZE_ATTR); 354ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int32_t screenDensity = AaptXml::getIntegerAttribute(tree, 355ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski SCREEN_DENSITY_ATTR); 356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (screenSize > 0 && screenDensity > 0) { 357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!first) { 358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(","); 359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski first = false; 361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("'%d/%d'", screenSize, screenDensity); 362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 36858f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinskistatic void printUsesPermission(const String8& name, bool optional=false, int maxSdkVersion=-1) { 36958f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printf("uses-permission: name='%s'", ResTable::normalizeForOutput(name.string()).string()); 37058f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski if (maxSdkVersion != -1) { 37158f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printf(" maxSdkVersion='%d'", maxSdkVersion); 37258f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski } 37358f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printf("\n"); 37458f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski 37558f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski if (optional) { 37658f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printf("optional-permission: name='%s'", 37758f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski ResTable::normalizeForOutput(name.string()).string()); 37858f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski if (maxSdkVersion != -1) { 37958f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printf(" maxSdkVersion='%d'", maxSdkVersion); 38058f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski } 38158f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printf("\n"); 38258f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski } 38358f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski} 38458f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski 38558f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinskistatic void printUsesImpliedPermission(const String8& name, const String8& reason) { 38658f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printf("uses-implied-permission: name='%s' reason='%s'\n", 38758f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski ResTable::normalizeForOutput(name.string()).string(), 38858f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski ResTable::normalizeForOutput(reason.string()).string()); 38958f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski} 39058f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski 39194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam LesinskiVector<String8> getNfcAidCategories(AssetManager& assets, String8 xmlPath, bool offHost, 39294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski String8 *outError = NULL) 39394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski{ 39494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski Asset* aidAsset = assets.openNonAsset(xmlPath, Asset::ACCESS_BUFFER); 39594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (aidAsset == NULL) { 39694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (outError != NULL) *outError = "xml resource does not exist"; 39794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski return Vector<String8>(); 39894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 39994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 40094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski const String8 serviceTagName(offHost ? "offhost-apdu-service" : "host-apdu-service"); 40194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 40294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool withinApduService = false; 40394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski Vector<String8> categories; 40494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 40594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski String8 error; 40694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski ResXMLTree tree; 40794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski tree.setTo(aidAsset->getBuffer(true), aidAsset->getLength()); 40894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 40994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski size_t len; 41094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski int depth = 0; 41194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski ResXMLTree::event_code_t code; 41294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 41394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (code == ResXMLTree::END_TAG) { 41494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski depth--; 4159cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski const char16_t* ctag16 = tree.getElementName(&len); 4169cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski if (ctag16 == NULL) { 4179cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski *outError = "failed to get XML element name (bad string pool)"; 4189cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski return Vector<String8>(); 4199cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski } 4209cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski String8 tag(ctag16); 42194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 42294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (depth == 0 && tag == serviceTagName) { 42394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski withinApduService = false; 42494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 42594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 42694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else if (code == ResXMLTree::START_TAG) { 42794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski depth++; 4289cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski const char16_t* ctag16 = tree.getElementName(&len); 4299cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski if (ctag16 == NULL) { 4309cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski *outError = "failed to get XML element name (bad string pool)"; 4319cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski return Vector<String8>(); 4329cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski } 4339cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski String8 tag(ctag16); 43494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 43594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (depth == 1) { 43694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (tag == serviceTagName) { 43794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski withinApduService = true; 43894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 43994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else if (depth == 2 && withinApduService) { 44094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (tag == "aid-group") { 441ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 category = AaptXml::getAttribute(tree, CATEGORY_ATTR, &error); 44294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (error != "") { 44394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (outError != NULL) *outError = error; 44494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski return Vector<String8>(); 44594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 44694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 44794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski categories.add(category); 44894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 44994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 45094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 45194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 45294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski aidAsset->close(); 45394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski return categories; 45494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski} 45594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 4569d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinskistatic void printComponentPresence(const char* componentName) { 4579d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printf("provides-component:'%s'\n", componentName); 4589d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski} 4599d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski 4602c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski/** 4612c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski * Represents a feature that has been automatically added due to 4622c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski * a pre-requisite or some other reason. 4632c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski */ 4642c72b6822debb08fe997926eedc110f62d287d34Adam Lesinskistruct ImpliedFeature { 4652c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski /** 4662c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski * Name of the implied feature. 4672c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski */ 4682c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8 name; 4692c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 4702c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski /** 4712c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski * List of human-readable reasons for why this feature was implied. 4722c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski */ 4732c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski SortedVector<String8> reasons; 4742c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski}; 4752c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 4762c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski/** 4772c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski * Represents a <feature-group> tag in the AndroidManifest.xml 4782c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski */ 4792c72b6822debb08fe997926eedc110f62d287d34Adam Lesinskistruct FeatureGroup { 480d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski FeatureGroup() : openGLESVersion(-1) {} 481d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski 4822c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski /** 4832c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski * Human readable label 4842c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski */ 4852c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8 label; 4862c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 4872c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski /** 4882c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski * Explicit features defined in the group 4892c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski */ 4902c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski KeyedVector<String8, bool> features; 491d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski 492d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski /** 493d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski * OpenGL ES version required 494d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski */ 495d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski int openGLESVersion; 4962c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski}; 4972c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 4982c72b6822debb08fe997926eedc110f62d287d34Adam Lesinskistatic void addImpliedFeature(KeyedVector<String8, ImpliedFeature>* impliedFeatures, 4992c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski const char* name, const char* reason) { 5002c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8 name8(name); 5012c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski ssize_t idx = impliedFeatures->indexOfKey(name8); 5022c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (idx < 0) { 5032c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski idx = impliedFeatures->add(name8, ImpliedFeature()); 5042c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski impliedFeatures->editValueAt(idx).name = name8; 5052c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 5062c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski impliedFeatures->editValueAt(idx).reasons.add(String8(reason)); 5072c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski} 5082c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 5092c72b6822debb08fe997926eedc110f62d287d34Adam Lesinskistatic void printFeatureGroup(const FeatureGroup& grp, 5102c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski const KeyedVector<String8, ImpliedFeature>* impliedFeatures = NULL) { 5112c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski printf("feature-group: label='%s'\n", grp.label.string()); 5122c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 513d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski if (grp.openGLESVersion > 0) { 514d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski printf(" uses-gl-es: '0x%x'\n", grp.openGLESVersion); 515d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski } 516d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski 5172c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski const size_t numFeatures = grp.features.size(); 5182c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski for (size_t i = 0; i < numFeatures; i++) { 5192c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (!grp.features[i]) { 5202c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski continue; 5212c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 5222c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 5232c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski const String8& featureName = grp.features.keyAt(i); 5242c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski printf(" uses-feature: name='%s'\n", 5252c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski ResTable::normalizeForOutput(featureName.string()).string()); 5262c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 5272c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 5282c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski const size_t numImpliedFeatures = 5292c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski (impliedFeatures != NULL) ? impliedFeatures->size() : 0; 5302c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski for (size_t i = 0; i < numImpliedFeatures; i++) { 5312c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski const ImpliedFeature& impliedFeature = impliedFeatures->valueAt(i); 5322c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (grp.features.indexOfKey(impliedFeature.name) >= 0) { 5332c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski // The feature is explicitly set, no need to use implied 5342c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski // definition. 5352c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski continue; 5362c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 5372c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 5382c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8 printableFeatureName(ResTable::normalizeForOutput( 5392c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski impliedFeature.name.string())); 5402c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski printf(" uses-feature: name='%s'\n", printableFeatureName.string()); 5412c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski printf(" uses-implied-feature: name='%s' reason='", 5422c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski printableFeatureName.string()); 5432c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski const size_t numReasons = impliedFeature.reasons.size(); 5442c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski for (size_t j = 0; j < numReasons; j++) { 5452c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski printf("%s", impliedFeature.reasons[j].string()); 5462c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (j + 2 < numReasons) { 5472c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski printf(", "); 5482c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } else if (j + 1 < numReasons) { 5492c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski printf(", and "); 5502c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 5512c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 5522c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski printf("'\n"); 5532c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 5542c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski} 5552c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 5562c72b6822debb08fe997926eedc110f62d287d34Adam Lesinskistatic void addParentFeatures(FeatureGroup* grp, const String8& name) { 5572c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (name == "android.hardware.camera.autofocus" || 5582c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski name == "android.hardware.camera.flash") { 5592c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski grp->features.add(String8("android.hardware.camera"), true); 5602c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } else if (name == "android.hardware.location.gps" || 5612c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski name == "android.hardware.location.network") { 5622c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski grp->features.add(String8("android.hardware.location"), true); 5632c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } else if (name == "android.hardware.touchscreen.multitouch") { 5642c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski grp->features.add(String8("android.hardware.touchscreen"), true); 5652c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } else if (name == "android.hardware.touchscreen.multitouch.distinct") { 5662c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski grp->features.add(String8("android.hardware.touchscreen.multitouch"), true); 5672c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski grp->features.add(String8("android.hardware.touchscreen"), true); 568d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski } else if (name == "android.hardware.opengles.aep") { 569d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski const int openGLESVersion31 = 0x00030001; 570d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski if (openGLESVersion31 > grp->openGLESVersion) { 571d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski grp->openGLESVersion = openGLESVersion31; 572d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski } 5732c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 5742c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski} 5752c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Handle the "dump" command, to extract select data from an archive. 578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiextern char CONSOLE_DATA[2925]; // see EOF 580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doDump(Bundle* bundle) 581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result = UNKNOWN_ERROR; 583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 1) { 585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: no dump option specified\n"); 586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 1; 587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 2) { 590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: no dump file specified\n"); 591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 1; 592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* option = bundle->getFileSpecEntry(0); 595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* filename = bundle->getFileSpecEntry(1); 596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AssetManager assets; 598f85e41f29a0e9313c2d4725f9d9648591ea49f3bNarayan Kamath int32_t assetsCookie; 599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!assets.addAssetPath(String8(filename), &assetsCookie)) { 600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: dump failed because assets could not be loaded\n"); 601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 1; 602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Make a dummy config for retrieving resources... we need to supply 605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // non-default values for some configs so that we can retrieve resources 606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // in the app that don't have a default. The most important of these is 607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the API version because key resources like icons will have an implicit 608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // version if they are using newer config types like density. 609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_config config; 61091447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath memset(&config, 0, sizeof(ResTable_config)); 611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.language[0] = 'e'; 612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.language[1] = 'n'; 613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.country[0] = 'U'; 614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.country[1] = 'S'; 615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.orientation = ResTable_config::ORIENTATION_PORT; 616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.density = ResTable_config::DENSITY_MEDIUM; 617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.sdkVersion = 10000; // Very high. 618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.screenWidthDp = 320; 619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.screenHeightDp = 480; 620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.smallestScreenWidthDp = 320; 621c2dea8daea2ae0001d56689d96ce1066012b7b40Adam Lesinski config.screenLayout |= ResTable_config::SCREENSIZE_NORMAL; 622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets.setConfiguration(config); 623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable& res = assets.getResources(false); 625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (&res == NULL) { 626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: dump failed because no resource table was found\n"); 62763e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski return 1; 62825e9d55e964c180ec6e57ba1d977d6c2e1115f5aAdam Lesinski } else if (res.getError() != NO_ERROR) { 62925e9d55e964c180ec6e57ba1d977d6c2e1115f5aAdam Lesinski fprintf(stderr, "ERROR: dump failed because the resource table is invalid/corrupt.\n"); 63063e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski return 1; 63163e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski } 63263e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski 6332cb761e3ddb9d68ab430013e9cd15ecaab9fbc62Adam Lesinski // The dynamicRefTable can be null if there are no resources for this asset cookie. 6342cb761e3ddb9d68ab430013e9cd15ecaab9fbc62Adam Lesinski // This fine. 63563e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski const DynamicRefTable* dynamicRefTable = res.getDynamicRefTableForCookie(assetsCookie); 636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 63763e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski Asset* asset = NULL; 63863e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski 639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp("resources", option) == 0) { 640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#ifndef HAVE_ANDROID_OS 641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res.print(bundle->getValues()); 642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("strings", option) == 0) { 645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResStringPool* pool = res.getTableStringBlock(0); 646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printStringPool(pool); 647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("xmltree", option) == 0) { 649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 3) { 650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: no dump xmltree resource file specified\n"); 651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i=2; i<bundle->getFileSpecCount(); i++) { 655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* resname = bundle->getFileSpecEntry(i); 65663e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski ResXMLTree tree(dynamicRefTable); 65763e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski asset = assets.openNonAsset(assetsCookie, resname, Asset::ACCESS_BUFFER); 658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (asset == NULL) { 659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: dump failed because resource %s found\n", resname); 660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.setTo(asset->getBuffer(true), 664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset->getLength()) != NO_ERROR) { 665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: Resource %s is corrupt\n", resname); 666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tree.restart(); 669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printXMLBlock(&tree); 670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tree.uninit(); 671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete asset; 672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset = NULL; 673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("xmlstrings", option) == 0) { 676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 3) { 677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: no dump xmltree resource file specified\n"); 678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i=2; i<bundle->getFileSpecCount(); i++) { 682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* resname = bundle->getFileSpecEntry(i); 68363e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski asset = assets.openNonAsset(assetsCookie, resname, Asset::ACCESS_BUFFER); 684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (asset == NULL) { 685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: dump failed because resource %s found\n", resname); 686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 68963e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski ResXMLTree tree(dynamicRefTable); 690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.setTo(asset->getBuffer(true), 691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset->getLength()) != NO_ERROR) { 692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: Resource %s is corrupt\n", resname); 693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printStringPool(&tree.getStrings()); 696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete asset; 697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset = NULL; 698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 70163e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski asset = assets.openNonAsset(assetsCookie, "AndroidManifest.xml", Asset::ACCESS_BUFFER); 702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (asset == NULL) { 703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: dump failed because no AndroidManifest.xml found\n"); 704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 70763e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski ResXMLTree tree(dynamicRefTable); 708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.setTo(asset->getBuffer(true), 709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset->getLength()) != NO_ERROR) { 710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: AndroidManifest.xml is corrupt\n"); 711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tree.restart(); 714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp("permissions", option) == 0) { 716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int depth = 0; 719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth--; 722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != ResXMLTree::START_TAG) { 725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth++; 7289cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski const char16_t* ctag16 = tree.getElementName(&len); 7299cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski if (ctag16 == NULL) { 7309cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski fprintf(stderr, "ERROR: failed to get XML element name (bad string pool)\n"); 7319cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski goto bail; 7329cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski } 7339cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski String8 tag(ctag16); 734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Depth %d tag %s\n", depth, tag.string()); 735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (depth == 1) { 736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag != "manifest") { 737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: manifest does not start with <manifest> tag\n"); 738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 740ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 pkg = AaptXml::getAttribute(tree, NULL, "package", NULL); 7412675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("package: %s\n", ResTable::normalizeForOutput(pkg.string()).string()); 742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (depth == 2 && tag == "permission") { 743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 error; 744ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); 745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: %s\n", error.string()); 747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 7492675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("permission: %s\n", 7502675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(name.string()).string()); 751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (depth == 2 && tag == "uses-permission") { 752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 error; 753ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); 754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: %s\n", error.string()); 756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 75858f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesPermission(name, 759ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski AaptXml::getIntegerAttribute(tree, REQUIRED_ATTR, 1) == 0, 760ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski AaptXml::getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR)); 761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("badging", option) == 0) { 764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<String8> locales; 765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res.getLocales(&locales); 766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<ResTable_config> configs; 768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res.getConfigurations(&configs); 769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SortedVector<int> densities; 770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NC = configs.size(); 771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<NC; i++) { 772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int dens = configs[i].density; 773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (dens == 0) { 774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dens = 160; 775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski densities.add(dens); 777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int depth = 0; 782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 error; 783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool withinActivity = false; 784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isMainActivity = false; 785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isLauncherActivity = false; 7860a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn bool isLeanbackLauncherActivity = false; 787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isSearchable = false; 788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool withinApplication = false; 789ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright bool withinSupportsInput = false; 7902c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski bool withinFeatureGroup = false; 791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool withinReceiver = false; 792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool withinService = false; 7939d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool withinProvider = false; 794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool withinIntentFilter = false; 795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasMainActivity = false; 796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasOtherActivities = false; 797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasOtherReceivers = false; 798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasOtherServices = false; 7999d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool hasIntentFilter = false; 8009d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski 801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasWallpaperService = false; 802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasImeService = false; 803a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool hasAccessibilityService = false; 804a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool hasPrintService = false; 805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasWidgetReceivers = false; 806a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool hasDeviceAdminReceiver = false; 80794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool hasPaymentService = false; 8089d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool hasDocumentsProvider = false; 8099d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool hasCameraActivity = false; 8109d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool hasCameraSecureActivity = false; 8119d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool hasLauncher = false; 8129d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool hasNotificationListenerService = false; 813eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock bool hasDreamService = false; 8149d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski 815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool actMainActivity = false; 816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool actWidgetReceivers = false; 817a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool actDeviceAdminEnabled = false; 818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool actImeService = false; 819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool actWallpaperService = false; 820a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool actAccessibilityService = false; 821a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool actPrintService = false; 82294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool actHostApduService = false; 82394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool actOffHostApduService = false; 8249d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool actDocumentsProvider = false; 8259d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool actNotificationListenerService = false; 826eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock bool actDreamService = false; 8279d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool actCamera = false; 8289d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool actCameraSecure = false; 8299d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool catLauncher = false; 83094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool hasMetaHostPaymentCategory = false; 83194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool hasMetaOffHostPaymentCategory = false; 832a5018c900f126ee8424c82497f32983873db741bAdam Lesinski 833a5018c900f126ee8424c82497f32983873db741bAdam Lesinski // These permissions are required by services implementing services 834a5018c900f126ee8424c82497f32983873db741bAdam Lesinski // the system binds to (IME, Accessibility, PrintServices, etc.) 835a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool hasBindDeviceAdminPermission = false; 836a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool hasBindInputMethodPermission = false; 837a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool hasBindAccessibilityServicePermission = false; 838a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool hasBindPrintServicePermission = false; 83994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool hasBindNfcServicePermission = false; 8409d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool hasRequiredSafAttributes = false; 8419d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool hasBindNotificationListenerServicePermission = false; 842eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock bool hasBindDreamServicePermission = false; 843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // These two implement the implicit permissions that are granted 845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // to pre-1.6 applications. 846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasWriteExternalStoragePermission = false; 847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasReadPhoneStatePermission = false; 848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If an app requests write storage, they will also get read storage. 850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasReadExternalStoragePermission = false; 851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Implement transition to read and write call log. 853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasReadContactsPermission = false; 854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasWriteContactsPermission = false; 855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasReadCallLogPermission = false; 856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasWriteCallLogPermission = false; 857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 858e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // If an app declares itself as multiArch, we report the 859e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // native libraries differently. 860e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski bool hasMultiArch = false; 861e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski 862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // This next group of variables is used to implement a group of 863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // backward-compatibility heuristics necessitated by the addition of 864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // some new uses-feature constants in 2.1 and 2.2. In most cases, the 865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // heuristic is "if an app requests a permission but doesn't explicitly 866282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // request the corresponding <uses-feature>, presume it's there anyway". 8672c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // 2.2 also added some other features that apps can request, but that 869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // have no corresponding permission, so we cannot implement any 870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // back-compatibility heuristic for them. The below are thus unnecessary 871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // (but are retained here for documentary purposes.) 872282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //bool specCompassFeature = false; 873282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //bool specAccelerometerFeature = false; 874282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //bool specProximityFeature = false; 875282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //bool specAmbientLightFeature = false; 876282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //bool specLiveWallpaperFeature = false; 877282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 878282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int targetSdk = 0; 879282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int smallScreen = 1; 880282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int normalScreen = 1; 881282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int largeScreen = 1; 882282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int xlargeScreen = 1; 883282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int anyDensity = 1; 884282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int requiresSmallestWidthDp = 0; 885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int compatibleWidthLimitDp = 0; 886282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int largestWidthLimitDp = 0; 887282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 pkg; 888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 activityName; 889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 activityLabel; 890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 activityIcon; 8910a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn String8 activityBanner; 892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 receiverName; 893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 serviceName; 894ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright Vector<String8> supportedInput; 8952c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 8962c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski FeatureGroup commonFeatures; 8972c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski Vector<FeatureGroup> featureGroups; 8982c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski KeyedVector<String8, ImpliedFeature> impliedFeatures; 8992c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth--; 903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (depth < 2) { 904ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (withinSupportsInput && !supportedInput.isEmpty()) { 905ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright printf("supports-input: '"); 906ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright const size_t N = supportedInput.size(); 907ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright for (size_t i=0; i<N; i++) { 9082675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("%s", ResTable::normalizeForOutput( 9092675f769673f69b0661ddee346292f25cb30a296Maurice Chu supportedInput[i].string()).string()); 910ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (i != N - 1) { 911ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright printf("' '"); 912ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else { 913ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright printf("'\n"); 914ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 915ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 916ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright supportedInput.clear(); 917ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinApplication = false; 919ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright withinSupportsInput = false; 9202c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski withinFeatureGroup = false; 921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (depth < 3) { 9220a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn if (withinActivity && isMainActivity) { 9232675f769673f69b0661ddee346292f25cb30a296Maurice Chu String8 aName(getComponentName(pkg, activityName)); 9240a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn if (isLauncherActivity) { 9250a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn printf("launchable-activity:"); 9269eaaaf0fe3917f4fec85d3e45da37914654847ecTim Kilbourn if (aName.length() > 0) { 9279eaaaf0fe3917f4fec85d3e45da37914654847ecTim Kilbourn printf(" name='%s' ", 9289eaaaf0fe3917f4fec85d3e45da37914654847ecTim Kilbourn ResTable::normalizeForOutput(aName.string()).string()); 9290a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn } 9300a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn printf(" label='%s' icon='%s'\n", 9319eaaaf0fe3917f4fec85d3e45da37914654847ecTim Kilbourn ResTable::normalizeForOutput(activityLabel.string()).string(), 9329eaaaf0fe3917f4fec85d3e45da37914654847ecTim Kilbourn ResTable::normalizeForOutput(activityIcon.string()).string()); 9330a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn } 9340a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn if (isLeanbackLauncherActivity) { 9350a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn printf("leanback-launchable-activity:"); 9369eaaaf0fe3917f4fec85d3e45da37914654847ecTim Kilbourn if (aName.length() > 0) { 9379eaaaf0fe3917f4fec85d3e45da37914654847ecTim Kilbourn printf(" name='%s' ", 9389eaaaf0fe3917f4fec85d3e45da37914654847ecTim Kilbourn ResTable::normalizeForOutput(aName.string()).string()); 9390a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn } 9400a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn printf(" label='%s' icon='%s' banner='%s'\n", 9419eaaaf0fe3917f4fec85d3e45da37914654847ecTim Kilbourn ResTable::normalizeForOutput(activityLabel.string()).string(), 9429eaaaf0fe3917f4fec85d3e45da37914654847ecTim Kilbourn ResTable::normalizeForOutput(activityIcon.string()).string(), 9439eaaaf0fe3917f4fec85d3e45da37914654847ecTim Kilbourn ResTable::normalizeForOutput(activityBanner.string()).string()); 944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasIntentFilter) { 947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasOtherActivities |= withinActivity; 948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasOtherReceivers |= withinReceiver; 949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasOtherServices |= withinService; 95094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else { 95194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (withinService) { 95294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasPaymentService |= (actHostApduService && hasMetaHostPaymentCategory && 95394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindNfcServicePermission); 95494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasPaymentService |= (actOffHostApduService && hasMetaOffHostPaymentCategory && 95594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindNfcServicePermission); 95694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinActivity = false; 959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinService = false; 960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinReceiver = false; 9619d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski withinProvider = false; 962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasIntentFilter = false; 9630a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn isMainActivity = isLauncherActivity = isLeanbackLauncherActivity = false; 964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (depth < 4) { 965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (withinIntentFilter) { 966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (withinActivity) { 967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasMainActivity |= actMainActivity; 9689d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasLauncher |= catLauncher; 9699d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasCameraActivity |= actCamera; 9709d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasCameraSecureActivity |= actCameraSecure; 9719d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasOtherActivities |= !actMainActivity && !actCamera && !actCameraSecure; 972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (withinReceiver) { 973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWidgetReceivers |= actWidgetReceivers; 974a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasDeviceAdminReceiver |= (actDeviceAdminEnabled && 975a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasBindDeviceAdminPermission); 976a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasOtherReceivers |= (!actWidgetReceivers && !actDeviceAdminEnabled); 977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (withinService) { 978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasImeService |= actImeService; 979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWallpaperService |= actWallpaperService; 980a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasAccessibilityService |= (actAccessibilityService && 981a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasBindAccessibilityServicePermission); 982a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasPrintService |= (actPrintService && hasBindPrintServicePermission); 9839d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasNotificationListenerService |= actNotificationListenerService && 9849d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasBindNotificationListenerServicePermission; 985eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock hasDreamService |= actDreamService && hasBindDreamServicePermission; 986a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasOtherServices |= (!actImeService && !actWallpaperService && 98794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski !actAccessibilityService && !actPrintService && 9889d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski !actHostApduService && !actOffHostApduService && 9899d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski !actNotificationListenerService); 9909d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } else if (withinProvider) { 9919d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasDocumentsProvider |= actDocumentsProvider && hasRequiredSafAttributes; 992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinIntentFilter = false; 995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != ResXMLTree::START_TAG) { 999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth++; 10029cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski 10039cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski const char16_t* ctag16 = tree.getElementName(&len); 10049cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski if (ctag16 == NULL) { 10059cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski fprintf(stderr, "ERROR: failed to get XML element name (bad string pool)\n"); 10069cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski goto bail; 10079cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski } 10089cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski String8 tag(ctag16); 1009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Depth %d, %s\n", depth, tag.string()); 1010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (depth == 1) { 1011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag != "manifest") { 1012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: manifest does not start with <manifest> tag\n"); 1013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1015ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski pkg = AaptXml::getAttribute(tree, NULL, "package", NULL); 10162675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("package: name='%s' ", 10172675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(pkg.string()).string()); 1018ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int32_t versionCode = AaptXml::getIntegerAttribute(tree, VERSION_CODE_ATTR, 1019ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski &error); 1020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1021ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski fprintf(stderr, "ERROR getting 'android:versionCode' attribute: %s\n", 1022ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski error.string()); 1023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (versionCode > 0) { 1026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("versionCode='%d' ", versionCode); 1027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("versionCode='' "); 1029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1030ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 versionName = AaptXml::getResolvedAttribute(res, tree, 1031ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski VERSION_NAME_ATTR, &error); 1032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1033ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski fprintf(stderr, "ERROR getting 'android:versionName' attribute: %s\n", 1034ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski error.string()); 1035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 103725d35a9d68fed6304352d0bfc2e0d581ed47f8b5Adam Lesinski printf("versionName='%s'", 10382675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(versionName.string()).string()); 103925d35a9d68fed6304352d0bfc2e0d581ed47f8b5Adam Lesinski 1040ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 splitName = AaptXml::getAttribute(tree, NULL, "split"); 104125d35a9d68fed6304352d0bfc2e0d581ed47f8b5Adam Lesinski if (!splitName.isEmpty()) { 104225d35a9d68fed6304352d0bfc2e0d581ed47f8b5Adam Lesinski printf(" split='%s'", ResTable::normalizeForOutput( 104325d35a9d68fed6304352d0bfc2e0d581ed47f8b5Adam Lesinski splitName.string()).string()); 104425d35a9d68fed6304352d0bfc2e0d581ed47f8b5Adam Lesinski } 1045ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski 10465283faba4a75a4d1fd9990637d22768e423895e3Adam Lesinski String8 platformVersionName = AaptXml::getAttribute(tree, NULL, 10475283faba4a75a4d1fd9990637d22768e423895e3Adam Lesinski "platformBuildVersionName"); 10485283faba4a75a4d1fd9990637d22768e423895e3Adam Lesinski printf(" platformBuildVersionName='%s'", platformVersionName.string()); 104925d35a9d68fed6304352d0bfc2e0d581ed47f8b5Adam Lesinski printf("\n"); 1050caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski 1051ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int32_t installLocation = AaptXml::getResolvedIntegerAttribute(res, tree, 1052ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski INSTALL_LOCATION_ATTR, &error); 1053caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski if (error != "") { 1054caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski fprintf(stderr, "ERROR getting 'android:installLocation' attribute: %s\n", 1055caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski error.string()); 1056caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski goto bail; 1057caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski } 1058caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski 1059caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski if (installLocation >= 0) { 1060caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski printf("install-location:'"); 1061caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski switch (installLocation) { 1062caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski case 0: 1063caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski printf("auto"); 1064caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski break; 1065caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski case 1: 1066caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski printf("internalOnly"); 1067caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski break; 1068caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski case 2: 1069caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski printf("preferExternal"); 1070caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski break; 1071caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski default: 1072caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski fprintf(stderr, "Invalid installLocation %d\n", installLocation); 1073caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski goto bail; 1074caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski } 1075caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski printf("'\n"); 1076caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski } 1077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (depth == 2) { 1078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinApplication = false; 1079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag == "application") { 1080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinApplication = true; 1081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 label; 1083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NL = locales.size(); 1084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<NL; i++) { 1085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* localeStr = locales[i].string(); 1086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets.setLocale(localeStr != NULL ? localeStr : ""); 1087ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 llabel = AaptXml::getResolvedAttribute(res, tree, LABEL_ATTR, 1088ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski &error); 1089282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (llabel != "") { 1090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (localeStr == NULL || strlen(localeStr) == 0) { 1091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski label = llabel; 10922675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("application-label:'%s'\n", 10932675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(llabel.string()).string()); 1094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (label == "") { 1096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski label = llabel; 1097282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1098282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("application-label-%s:'%s'\n", localeStr, 10992675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(llabel.string()).string()); 1100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_config tmpConfig = config; 1105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t ND = densities.size(); 1106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<ND; i++) { 1107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tmpConfig.density = densities[i]; 1108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets.setConfiguration(tmpConfig); 1109ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 icon = AaptXml::getResolvedAttribute(res, tree, ICON_ATTR, 1110ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski &error); 1111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (icon != "") { 11122675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("application-icon-%d:'%s'\n", densities[i], 11132675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(icon.string()).string()); 1114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets.setConfiguration(config); 1117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1118ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 icon = AaptXml::getResolvedAttribute(res, tree, ICON_ATTR, &error); 1119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1120ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n", 1121ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski error.string()); 1122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1124ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int32_t testOnly = AaptXml::getIntegerAttribute(tree, TEST_ONLY_ATTR, 0, 1125ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski &error); 1126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1127ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski fprintf(stderr, "ERROR getting 'android:testOnly' attribute: %s\n", 1128ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski error.string()); 1129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1131d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn 1132d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn String8 banner = AaptXml::getResolvedAttribute(res, tree, BANNER_ATTR, &error); 1133d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn if (error != "") { 1134d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn fprintf(stderr, "ERROR getting 'android:banner' attribute: %s\n", 1135d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn error.string()); 1136d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn goto bail; 1137d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn } 11382675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("application: label='%s' ", 11392675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(label.string()).string()); 1140d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn printf("icon='%s'", ResTable::normalizeForOutput(icon.string()).string()); 1141d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn if (banner != "") { 1142d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn printf(" banner='%s'", ResTable::normalizeForOutput(banner.string()).string()); 1143d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn } 1144d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn printf("\n"); 1145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (testOnly != 0) { 1146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("testOnly='%d'\n", testOnly); 1147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1149d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn int32_t isGame = AaptXml::getResolvedIntegerAttribute(res, tree, 1150d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn ISGAME_ATTR, 0, &error); 1151d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn if (error != "") { 1152d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn fprintf(stderr, "ERROR getting 'android:isGame' attribute: %s\n", 1153d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn error.string()); 1154d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn goto bail; 1155d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn } 1156d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn if (isGame != 0) { 1157d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn printf("application-isGame\n"); 1158d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn } 1159d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn 1160ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int32_t debuggable = AaptXml::getResolvedIntegerAttribute(res, tree, 1161ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski DEBUGGABLE_ATTR, 0, &error); 1162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1163ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski fprintf(stderr, "ERROR getting 'android:debuggable' attribute: %s\n", 1164ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski error.string()); 1165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (debuggable != 0) { 1168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("application-debuggable\n"); 1169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1170e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski 1171e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // We must search by name because the multiArch flag hasn't been API 1172e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // frozen yet. 1173e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski int32_t multiArchIndex = tree.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, 1174e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski "multiArch"); 1175e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski if (multiArchIndex >= 0) { 1176e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski Res_value value; 1177e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski if (tree.getAttributeValue(multiArchIndex, &value) != NO_ERROR) { 1178e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski if (value.dataType >= Res_value::TYPE_FIRST_INT && 1179e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski value.dataType <= Res_value::TYPE_LAST_INT) { 1180e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski hasMultiArch = value.data; 1181e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski } 1182e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski } 1183e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski } 1184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "uses-sdk") { 1185ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int32_t code = AaptXml::getIntegerAttribute(tree, MIN_SDK_VERSION_ATTR, &error); 1186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error = ""; 1188ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 name = AaptXml::getResolvedAttribute(res, tree, 1189ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski MIN_SDK_VERSION_ATTR, &error); 1190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:minSdkVersion' attribute: %s\n", 1192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 1193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name == "Donut") targetSdk = 4; 11962675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("sdkVersion:'%s'\n", 11972675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(name.string()).string()); 1198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (code != -1) { 1199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski targetSdk = code; 1200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("sdkVersion:'%d'\n", code); 1201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1202ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski code = AaptXml::getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR); 1203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != -1) { 1204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("maxSdkVersion:'%d'\n", code); 1205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1206ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski code = AaptXml::getIntegerAttribute(tree, TARGET_SDK_VERSION_ATTR, &error); 1207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error = ""; 1209ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 name = AaptXml::getResolvedAttribute(res, tree, 1210ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski TARGET_SDK_VERSION_ATTR, &error); 1211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:targetSdkVersion' attribute: %s\n", 1213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 1214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name == "Donut" && targetSdk < 4) targetSdk = 4; 12172675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("targetSdkVersion:'%s'\n", 12182675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(name.string()).string()); 1219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (code != -1) { 1220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (targetSdk < code) { 1221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski targetSdk = code; 1222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("targetSdkVersion:'%d'\n", code); 1224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "uses-configuration") { 1226ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int32_t reqTouchScreen = AaptXml::getIntegerAttribute(tree, 1227ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski REQ_TOUCH_SCREEN_ATTR, 0); 1228ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int32_t reqKeyboardType = AaptXml::getIntegerAttribute(tree, 1229ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski REQ_KEYBOARD_TYPE_ATTR, 0); 1230ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int32_t reqHardKeyboard = AaptXml::getIntegerAttribute(tree, 1231ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski REQ_HARD_KEYBOARD_ATTR, 0); 1232ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int32_t reqNavigation = AaptXml::getIntegerAttribute(tree, 1233ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski REQ_NAVIGATION_ATTR, 0); 1234ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int32_t reqFiveWayNav = AaptXml::getIntegerAttribute(tree, 1235ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski REQ_FIVE_WAY_NAV_ATTR, 0); 1236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-configuration:"); 1237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqTouchScreen != 0) { 1238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" reqTouchScreen='%d'", reqTouchScreen); 1239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqKeyboardType != 0) { 1241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" reqKeyboardType='%d'", reqKeyboardType); 1242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqHardKeyboard != 0) { 1244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" reqHardKeyboard='%d'", reqHardKeyboard); 1245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqNavigation != 0) { 1247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" reqNavigation='%d'", reqNavigation); 1248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqFiveWayNav != 0) { 1250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" reqFiveWayNav='%d'", reqFiveWayNav); 1251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 1253ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (tag == "supports-input") { 1254ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright withinSupportsInput = true; 1255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "supports-screens") { 1256ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski smallScreen = AaptXml::getIntegerAttribute(tree, 1257ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski SMALL_SCREEN_ATTR, 1); 1258ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski normalScreen = AaptXml::getIntegerAttribute(tree, 1259ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski NORMAL_SCREEN_ATTR, 1); 1260ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski largeScreen = AaptXml::getIntegerAttribute(tree, 1261ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski LARGE_SCREEN_ATTR, 1); 1262ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski xlargeScreen = AaptXml::getIntegerAttribute(tree, 1263ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski XLARGE_SCREEN_ATTR, 1); 1264ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski anyDensity = AaptXml::getIntegerAttribute(tree, 1265ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski ANY_DENSITY_ATTR, 1); 1266ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski requiresSmallestWidthDp = AaptXml::getIntegerAttribute(tree, 1267ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski REQUIRES_SMALLEST_WIDTH_DP_ATTR, 0); 1268ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski compatibleWidthLimitDp = AaptXml::getIntegerAttribute(tree, 1269ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski COMPATIBLE_WIDTH_LIMIT_DP_ATTR, 0); 1270ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski largestWidthLimitDp = AaptXml::getIntegerAttribute(tree, 1271ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski LARGEST_WIDTH_LIMIT_DP_ATTR, 0); 12722c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } else if (tag == "feature-group") { 12732c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski withinFeatureGroup = true; 12742c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski FeatureGroup group; 1275ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski group.label = AaptXml::getResolvedAttribute(res, tree, LABEL_ATTR, &error); 12762c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (error != "") { 12772c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski fprintf(stderr, "ERROR getting 'android:label' attribute:" 12782c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski " %s\n", error.string()); 12792c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski goto bail; 12802c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 12812c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski featureGroups.add(group); 12822c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 1283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "uses-feature") { 1284ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); 1285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 1286ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int req = AaptXml::getIntegerAttribute(tree, 1287ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski REQUIRED_ATTR, 1); 1288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 12892c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski commonFeatures.features.add(name, req); 12902c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (req) { 12912c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addParentFeatures(&commonFeatures, name); 1292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1294ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int vers = AaptXml::getIntegerAttribute(tree, 1295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski GL_ES_VERSION_ATTR, &error); 1296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error == "") { 1297d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski if (vers > commonFeatures.openGLESVersion) { 1298d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski commonFeatures.openGLESVersion = vers; 1299d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski } 1300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "uses-permission") { 1303ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); 1304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 1305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name == "android.permission.CAMERA") { 1306d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.camera", 13072c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8::format("requested %s permission", name.string()) 13082c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski .string()); 1309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.ACCESS_FINE_LOCATION") { 13102c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.location.gps", 13112c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8::format("requested %s permission", name.string()) 13122c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski .string()); 13132c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.location", 13142c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8::format("requested %s permission", name.string()) 13152c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski .string()); 1316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.ACCESS_MOCK_LOCATION") { 13172c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.location", 13182c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8::format("requested %s permission", name.string()) 13192c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski .string()); 1320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.ACCESS_COARSE_LOCATION") { 13212c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.location.network", 13222c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8::format("requested %s permission", name.string()) 13232c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski .string()); 13242c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.location", 13252c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8::format("requested %s permission", name.string()) 13262c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski .string()); 1327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" || 1328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.INSTALL_LOCATION_PROVIDER") { 13292c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.location", 13302c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8::format("requested %s permission", name.string()) 13312c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski .string()); 1332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.BLUETOOTH" || 1333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.BLUETOOTH_ADMIN") { 13342c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (targetSdk > 4) { 13352c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.bluetooth", 13362c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8::format("requested %s permission", name.string()) 13372c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski .string()); 13382c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.bluetooth", 13392c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski "targetSdkVersion > 4"); 13402c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 1341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.RECORD_AUDIO") { 13422c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.microphone", 13432c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8::format("requested %s permission", name.string()) 13442c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski .string()); 1345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.ACCESS_WIFI_STATE" || 1346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.CHANGE_WIFI_STATE" || 1347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.CHANGE_WIFI_MULTICAST_STATE") { 13482c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.wifi", 13492c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8::format("requested %s permission", name.string()) 13502c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski .string()); 1351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.CALL_PHONE" || 1352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.CALL_PRIVILEGED" || 1353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.MODIFY_PHONE_STATE" || 1354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.PROCESS_OUTGOING_CALLS" || 1355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.READ_SMS" || 1356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.RECEIVE_SMS" || 1357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.RECEIVE_MMS" || 1358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.RECEIVE_WAP_PUSH" || 1359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.SEND_SMS" || 1360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.WRITE_APN_SETTINGS" || 1361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.WRITE_SMS") { 13622c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.telephony", 13632c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8("requested a telephony permission").string()); 1364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.WRITE_EXTERNAL_STORAGE") { 1365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWriteExternalStoragePermission = true; 1366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.READ_EXTERNAL_STORAGE") { 1367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasReadExternalStoragePermission = true; 1368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.READ_PHONE_STATE") { 1369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasReadPhoneStatePermission = true; 1370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.READ_CONTACTS") { 1371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasReadContactsPermission = true; 1372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.WRITE_CONTACTS") { 1373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWriteContactsPermission = true; 1374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.READ_CALL_LOG") { 1375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasReadCallLogPermission = true; 1376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.WRITE_CALL_LOG") { 1377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWriteCallLogPermission = true; 1378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 137958f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski 138058f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesPermission(name, 1381ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski AaptXml::getIntegerAttribute(tree, REQUIRED_ATTR, 1) == 0, 1382ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski AaptXml::getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR)); 138358f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski } else { 1384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 1386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "uses-package") { 1389ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); 1390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 13912675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("uses-package:'%s'\n", 13922675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(name.string()).string()); 1393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 1396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "original-package") { 1399ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); 1400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 14012675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("original-package:'%s'\n", 14022675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(name.string()).string()); 1403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 1406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "supports-gl-texture") { 1409ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); 1410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 14112675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("supports-gl-texture:'%s'\n", 14122675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(name.string()).string()); 1413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 1416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "compatible-screens") { 14199cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski printCompatibleScreens(tree, &error); 14209cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski if (error != "") { 14219cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski fprintf(stderr, "ERROR getting compatible screens: %s\n", 14229cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski error.string()); 14239cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski goto bail; 14249cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski } 1425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth--; 1426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "package-verifier") { 1427ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); 1428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 1429ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 publicKey = AaptXml::getAttribute(tree, PUBLIC_KEY_ATTR, &error); 1430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (publicKey != "" && error == "") { 1431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("package-verifier: name='%s' publicKey='%s'\n", 14322675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(name.string()).string(), 14332675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(publicKey.string()).string()); 1434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1437ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (depth == 3) { 1438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinActivity = false; 1439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinReceiver = false; 1440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinService = false; 14419d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski withinProvider = false; 1442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasIntentFilter = false; 144394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasMetaHostPaymentCategory = false; 144494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasMetaOffHostPaymentCategory = false; 144594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindDeviceAdminPermission = false; 144694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindInputMethodPermission = false; 144794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindAccessibilityServicePermission = false; 144894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindPrintServicePermission = false; 144994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindNfcServicePermission = false; 14509d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasRequiredSafAttributes = false; 14519d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasBindNotificationListenerServicePermission = false; 1452eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock hasBindDreamServicePermission = false; 1453ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (withinApplication) { 1454ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if(tag == "activity") { 1455ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright withinActivity = true; 1456ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski activityName = AaptXml::getAttribute(tree, NAME_ATTR, &error); 1457ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1458ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1459ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright error.string()); 1460ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1461ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1463ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski activityLabel = AaptXml::getResolvedAttribute(res, tree, LABEL_ATTR, 1464ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski &error); 1465ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1466ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:label' attribute: %s\n", 1467ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright error.string()); 1468ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1469ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1471ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski activityIcon = AaptXml::getResolvedAttribute(res, tree, ICON_ATTR, 1472ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski &error); 1473ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1474ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n", 1475ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright error.string()); 1476ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1477ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1479ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski activityBanner = AaptXml::getResolvedAttribute(res, tree, BANNER_ATTR, 1480ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski &error); 14810a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn if (error != "") { 14820a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn fprintf(stderr, "ERROR getting 'android:banner' attribute: %s\n", 14830a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn error.string()); 14840a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn goto bail; 14850a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn } 14860a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn 1487ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int32_t orien = AaptXml::getResolvedIntegerAttribute(res, tree, 1488ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright SCREEN_ORIENTATION_ATTR, &error); 1489ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error == "") { 1490ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (orien == 0 || orien == 6 || orien == 8) { 1491ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright // Requests landscape, sensorLandscape, or reverseLandscape. 14922c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.screen.landscape", 14932c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski "one or more activities have specified a landscape orientation"); 1494ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (orien == 1 || orien == 7 || orien == 9) { 1495ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright // Requests portrait, sensorPortrait, or reversePortrait. 14962c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.screen.portrait", 14972c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski "one or more activities have specified a portrait orientation"); 1498ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1500ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (tag == "uses-library") { 1501ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 libraryName = AaptXml::getAttribute(tree, NAME_ATTR, &error); 1502ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1503ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, 1504ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright "ERROR getting 'android:name' attribute for uses-library" 1505ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright " %s\n", error.string()); 1506ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1507ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1508ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int req = AaptXml::getIntegerAttribute(tree, 1509ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski REQUIRED_ATTR, 1); 1510ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright printf("uses-library%s:'%s'\n", 15112675f769673f69b0661ddee346292f25cb30a296Maurice Chu req ? "" : "-not-required", ResTable::normalizeForOutput( 15122675f769673f69b0661ddee346292f25cb30a296Maurice Chu libraryName.string()).string()); 1513ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (tag == "receiver") { 1514ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright withinReceiver = true; 1515ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski receiverName = AaptXml::getAttribute(tree, NAME_ATTR, &error); 1516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1517ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1518ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, 1519ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright "ERROR getting 'android:name' attribute for receiver:" 1520ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright " %s\n", error.string()); 1521ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1522ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1523a5018c900f126ee8424c82497f32983873db741bAdam Lesinski 1524ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 permission = AaptXml::getAttribute(tree, PERMISSION_ATTR, 1525ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski &error); 1526a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (error == "") { 1527a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (permission == "android.permission.BIND_DEVICE_ADMIN") { 1528a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasBindDeviceAdminPermission = true; 1529a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1530a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else { 1531a5018c900f126ee8424c82497f32983873db741bAdam Lesinski fprintf(stderr, "ERROR getting 'android:permission' attribute for" 1532a5018c900f126ee8424c82497f32983873db741bAdam Lesinski " receiver '%s': %s\n", receiverName.string(), error.string()); 1533a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1534ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (tag == "service") { 1535ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright withinService = true; 1536ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski serviceName = AaptXml::getAttribute(tree, NAME_ATTR, &error); 1537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1538ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1539ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:name' attribute for " 1540ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright "service:%s\n", error.string()); 1541ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1542ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1543a5018c900f126ee8424c82497f32983873db741bAdam Lesinski 1544ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 permission = AaptXml::getAttribute(tree, PERMISSION_ATTR, 1545ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski &error); 1546a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (error == "") { 1547a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (permission == "android.permission.BIND_INPUT_METHOD") { 1548a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasBindInputMethodPermission = true; 1549a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if (permission == "android.permission.BIND_ACCESSIBILITY_SERVICE") { 1550a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasBindAccessibilityServicePermission = true; 1551a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if (permission == "android.permission.BIND_PRINT_SERVICE") { 1552a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasBindPrintServicePermission = true; 155394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else if (permission == "android.permission.BIND_NFC_SERVICE") { 155494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindNfcServicePermission = true; 15559d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } else if (permission == "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE") { 15569d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasBindNotificationListenerServicePermission = true; 1557eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock } else if (permission == "android.permission.BIND_DREAM_SERVICE") { 1558eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock hasBindDreamServicePermission = true; 1559a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1560a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else { 1561a5018c900f126ee8424c82497f32983873db741bAdam Lesinski fprintf(stderr, "ERROR getting 'android:permission' attribute for" 1562a5018c900f126ee8424c82497f32983873db741bAdam Lesinski " service '%s': %s\n", serviceName.string(), error.string()); 1563a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 15649d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } else if (tag == "provider") { 15659d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski withinProvider = true; 15669d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski 1567ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski bool exported = AaptXml::getResolvedIntegerAttribute(res, tree, 1568ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski EXPORTED_ATTR, &error); 15699d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (error != "") { 15709d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski fprintf(stderr, "ERROR getting 'android:exported' attribute for provider:" 15719d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski " %s\n", error.string()); 15729d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski goto bail; 15739d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 15749d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski 1575ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski bool grantUriPermissions = AaptXml::getResolvedIntegerAttribute( 1576ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski res, tree, GRANT_URI_PERMISSIONS_ATTR, &error); 15779d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (error != "") { 15789d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski fprintf(stderr, "ERROR getting 'android:grantUriPermissions' attribute for provider:" 15799d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski " %s\n", error.string()); 15809d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski goto bail; 15819d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 15829d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski 1583ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 permission = AaptXml::getResolvedAttribute(res, tree, 1584ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski PERMISSION_ATTR, &error); 15859d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (error != "") { 15869d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski fprintf(stderr, "ERROR getting 'android:permission' attribute for provider:" 15879d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski " %s\n", error.string()); 15889d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski goto bail; 15899d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 15909d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski 15919d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasRequiredSafAttributes |= exported && grantUriPermissions && 15929d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski permission == "android.permission.MANAGE_DOCUMENTS"; 15939d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski 1594ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (bundle->getIncludeMetaData() && tag == "meta-data") { 1595ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 metaDataName = AaptXml::getResolvedAttribute(res, tree, 1596ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski NAME_ATTR, &error); 1597ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1598ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:name' attribute for " 1599ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright "meta-data:%s\n", error.string()); 1600ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1601ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 16022675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("meta-data: name='%s' ", 16032675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(metaDataName.string()).string()); 1604ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski printResolvedResourceAttribute(res, tree, VALUE_ATTR, String8("value"), 160576327314d2238e105f8b94909f9c0cf85caca318Maurice Chu &error); 1606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 160776327314d2238e105f8b94909f9c0cf85caca318Maurice Chu // Try looking for a RESOURCE_ATTR 160876327314d2238e105f8b94909f9c0cf85caca318Maurice Chu error = ""; 1609ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski printResolvedResourceAttribute(res, tree, RESOURCE_ATTR, 161076327314d2238e105f8b94909f9c0cf85caca318Maurice Chu String8("resource"), &error); 1611ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 161276327314d2238e105f8b94909f9c0cf85caca318Maurice Chu fprintf(stderr, "ERROR getting 'android:value' or " 161376327314d2238e105f8b94909f9c0cf85caca318Maurice Chu "'android:resource' attribute for " 161476327314d2238e105f8b94909f9c0cf85caca318Maurice Chu "meta-data:%s\n", error.string()); 1615ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1616ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1617ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 161876327314d2238e105f8b94909f9c0cf85caca318Maurice Chu printf("\n"); 1619ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (withinSupportsInput && tag == "input-type") { 1620ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); 1621ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (name != "" && error == "") { 1622ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright supportedInput.add(name); 1623ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else { 1624ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1625ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright error.string()); 1626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 16292c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } else if (withinFeatureGroup && tag == "uses-feature") { 1630d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski FeatureGroup& top = featureGroups.editTop(); 1631d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski 1632ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 name = AaptXml::getResolvedAttribute(res, tree, NAME_ATTR, &error); 1633d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski if (name != "" && error == "") { 1634d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski top.features.add(name, true); 1635d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski addParentFeatures(&top, name); 1636d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski } else { 1637ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int vers = AaptXml::getIntegerAttribute(tree, GL_ES_VERSION_ATTR, 1638ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski &error); 1639d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski if (error == "") { 1640d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski if (vers > top.openGLESVersion) { 1641d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski top.openGLESVersion = vers; 1642d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski } 1643d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski } 16442c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 1645a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 164694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else if (depth == 4) { 164794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (tag == "intent-filter") { 164894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasIntentFilter = true; 164994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski withinIntentFilter = true; 165094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actMainActivity = false; 165194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actWidgetReceivers = false; 165294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actImeService = false; 165394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actWallpaperService = false; 165494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actAccessibilityService = false; 165594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actPrintService = false; 165694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actDeviceAdminEnabled = false; 165794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actHostApduService = false; 165894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actOffHostApduService = false; 16599d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski actDocumentsProvider = false; 16609d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski actNotificationListenerService = false; 1661eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock actDreamService = false; 16629d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski actCamera = false; 16639d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski actCameraSecure = false; 16649d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski catLauncher = false; 166594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else if (withinService && tag == "meta-data") { 1666ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); 166794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (error != "") { 166894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute for" 166994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski " meta-data tag in service '%s': %s\n", serviceName.string(), error.string()); 167094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski goto bail; 167194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 167294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 167394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (name == "android.nfc.cardemulation.host_apdu_service" || 167494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski name == "android.nfc.cardemulation.off_host_apdu_service") { 167594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool offHost = true; 167694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (name == "android.nfc.cardemulation.host_apdu_service") { 167794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski offHost = false; 167894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 167994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 1680ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 xmlPath = AaptXml::getResolvedAttribute(res, tree, 1681ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski RESOURCE_ATTR, &error); 168294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (error != "") { 168394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski fprintf(stderr, "ERROR getting 'android:resource' attribute for" 168494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski " meta-data tag in service '%s': %s\n", serviceName.string(), error.string()); 168594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski goto bail; 168694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 168794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 168894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski Vector<String8> categories = getNfcAidCategories(assets, xmlPath, 168994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski offHost, &error); 169094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (error != "") { 169194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski fprintf(stderr, "ERROR getting AID category for service '%s'\n", 169294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski serviceName.string()); 169394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski goto bail; 169494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 169594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 169694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski const size_t catLen = categories.size(); 169794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski for (size_t i = 0; i < catLen; i++) { 169894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool paymentCategory = (categories[i] == "payment"); 169994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (offHost) { 170094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasMetaOffHostPaymentCategory |= paymentCategory; 170194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else { 170294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasMetaHostPaymentCategory |= paymentCategory; 170394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 170494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 170594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 170694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 1707a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if ((depth == 5) && withinIntentFilter) { 1708a5018c900f126ee8424c82497f32983873db741bAdam Lesinski String8 action; 1709a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (tag == "action") { 1710ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski action = AaptXml::getAttribute(tree, NAME_ATTR, &error); 1711a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (error != "") { 1712a5018c900f126ee8424c82497f32983873db741bAdam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1713a5018c900f126ee8424c82497f32983873db741bAdam Lesinski error.string()); 1714a5018c900f126ee8424c82497f32983873db741bAdam Lesinski goto bail; 1715a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1716a5018c900f126ee8424c82497f32983873db741bAdam Lesinski 1717a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (withinActivity) { 1718a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (action == "android.intent.action.MAIN") { 1719a5018c900f126ee8424c82497f32983873db741bAdam Lesinski isMainActivity = true; 1720a5018c900f126ee8424c82497f32983873db741bAdam Lesinski actMainActivity = true; 17219d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } else if (action == "android.media.action.STILL_IMAGE_CAMERA" || 17229d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski action == "android.media.action.VIDEO_CAMERA") { 17239d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski actCamera = true; 17249d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } else if (action == "android.media.action.STILL_IMAGE_CAMERA_SECURE") { 17259d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski actCameraSecure = true; 1726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1727a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if (withinReceiver) { 1728a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (action == "android.appwidget.action.APPWIDGET_UPDATE") { 1729a5018c900f126ee8424c82497f32983873db741bAdam Lesinski actWidgetReceivers = true; 1730a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if (action == "android.app.action.DEVICE_ADMIN_ENABLED") { 1731a5018c900f126ee8424c82497f32983873db741bAdam Lesinski actDeviceAdminEnabled = true; 1732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1733a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if (withinService) { 1734a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (action == "android.view.InputMethod") { 1735a5018c900f126ee8424c82497f32983873db741bAdam Lesinski actImeService = true; 1736a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if (action == "android.service.wallpaper.WallpaperService") { 1737a5018c900f126ee8424c82497f32983873db741bAdam Lesinski actWallpaperService = true; 1738a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if (action == "android.accessibilityservice.AccessibilityService") { 1739a5018c900f126ee8424c82497f32983873db741bAdam Lesinski actAccessibilityService = true; 1740a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if (action == "android.printservice.PrintService") { 1741a5018c900f126ee8424c82497f32983873db741bAdam Lesinski actPrintService = true; 174294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else if (action == "android.nfc.cardemulation.action.HOST_APDU_SERVICE") { 174394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actHostApduService = true; 174494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else if (action == "android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE") { 174594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actOffHostApduService = true; 17469d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } else if (action == "android.service.notification.NotificationListenerService") { 17479d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski actNotificationListenerService = true; 1748eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock } else if (action == "android.service.dreams.DreamService") { 1749eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock actDreamService = true; 17509d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 17519d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } else if (withinProvider) { 17529d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (action == "android.content.action.DOCUMENTS_PROVIDER") { 17539d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski actDocumentsProvider = true; 1754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1756a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (action == "android.intent.action.SEARCH") { 1757a5018c900f126ee8424c82497f32983873db741bAdam Lesinski isSearchable = true; 1758a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1759a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1761a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (tag == "category") { 1762ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 category = AaptXml::getAttribute(tree, NAME_ATTR, &error); 1763a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (error != "") { 1764a5018c900f126ee8424c82497f32983873db741bAdam Lesinski fprintf(stderr, "ERROR getting 'name' attribute: %s\n", 1765a5018c900f126ee8424c82497f32983873db741bAdam Lesinski error.string()); 1766a5018c900f126ee8424c82497f32983873db741bAdam Lesinski goto bail; 1767a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1768a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (withinActivity) { 1769a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (category == "android.intent.category.LAUNCHER") { 1770a5018c900f126ee8424c82497f32983873db741bAdam Lesinski isLauncherActivity = true; 17710a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn } else if (category == "android.intent.category.LEANBACK_LAUNCHER") { 17720a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn isLeanbackLauncherActivity = true; 17739d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } else if (category == "android.intent.category.HOME") { 17749d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski catLauncher = true; 1775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Pre-1.6 implicitly granted permission compatibility logic 1782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (targetSdk < 4) { 1783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasWriteExternalStoragePermission) { 178458f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesPermission(String8("android.permission.WRITE_EXTERNAL_STORAGE")); 178558f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesImpliedPermission(String8("android.permission.WRITE_EXTERNAL_STORAGE"), 178658f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski String8("targetSdkVersion < 4")); 1787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWriteExternalStoragePermission = true; 1788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasReadPhoneStatePermission) { 179058f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesPermission(String8("android.permission.READ_PHONE_STATE")); 179158f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesImpliedPermission(String8("android.permission.READ_PHONE_STATE"), 179258f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski String8("targetSdkVersion < 4")); 1793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If the application has requested WRITE_EXTERNAL_STORAGE, we will 1797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // force them to always take READ_EXTERNAL_STORAGE as well. We always 1798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // do this (regardless of target API version) because we can't have 1799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // an app with write permission but not read permission. 1800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasReadExternalStoragePermission && hasWriteExternalStoragePermission) { 180158f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesPermission(String8("android.permission.READ_EXTERNAL_STORAGE")); 180258f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesImpliedPermission(String8("android.permission.READ_EXTERNAL_STORAGE"), 180358f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski String8("requested WRITE_EXTERNAL_STORAGE")); 1804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Pre-JellyBean call log permission compatibility. 1807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (targetSdk < 16) { 1808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasReadCallLogPermission && hasReadContactsPermission) { 180958f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesPermission(String8("android.permission.READ_CALL_LOG")); 181058f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesImpliedPermission(String8("android.permission.READ_CALL_LOG"), 181158f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski String8("targetSdkVersion < 16 and requested READ_CONTACTS")); 1812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasWriteCallLogPermission && hasWriteContactsPermission) { 181458f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesPermission(String8("android.permission.WRITE_CALL_LOG")); 181558f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesImpliedPermission(String8("android.permission.WRITE_CALL_LOG"), 181658f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski String8("targetSdkVersion < 16 and requested WRITE_CONTACTS")); 1817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 18202c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.touchscreen", 18212c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski "default feature for all apps"); 18222c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 18232c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski const size_t numFeatureGroups = featureGroups.size(); 18242c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (numFeatureGroups == 0) { 18252c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski // If no <feature-group> tags were defined, apply auto-implied features. 18262c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski printFeatureGroup(commonFeatures, &impliedFeatures); 18272c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 18282c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } else { 18292c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski // <feature-group> tags are defined, so we ignore implied features and 18302c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski for (size_t i = 0; i < numFeatureGroups; i++) { 18312c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski FeatureGroup& grp = featureGroups.editItemAt(i); 18322c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 1833d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski if (commonFeatures.openGLESVersion > grp.openGLESVersion) { 1834d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski grp.openGLESVersion = commonFeatures.openGLESVersion; 1835d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski } 1836d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski 18372c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski // Merge the features defined in the top level (not inside a <feature-group>) 18382c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski // with this feature group. 18392c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski const size_t numCommonFeatures = commonFeatures.features.size(); 18402c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski for (size_t j = 0; j < numCommonFeatures; j++) { 18412c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (grp.features.indexOfKey(commonFeatures.features.keyAt(j)) < 0) { 1842d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski grp.features.add(commonFeatures.features.keyAt(j), 1843d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski commonFeatures.features[j]); 18442c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 1845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 18472c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (!grp.features.isEmpty()) { 18482c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski printFeatureGroup(grp); 18492c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 1850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 18532c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 1854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasWidgetReceivers) { 18559d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("app-widget"); 1856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1857a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (hasDeviceAdminReceiver) { 18589d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("device-admin"); 1859a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasImeService) { 18619d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("ime"); 1862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasWallpaperService) { 18649d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("wallpaper"); 1865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1866a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (hasAccessibilityService) { 18679d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("accessibility"); 1868a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1869a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (hasPrintService) { 18709d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("print-service"); 1871a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 187294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (hasPaymentService) { 18739d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("payment"); 18749d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 18759d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (isSearchable) { 18769d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("search"); 18779d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 18789d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (hasDocumentsProvider) { 18799d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("document-provider"); 18809d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 18819d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (hasLauncher) { 18829d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("launcher"); 18839d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 18849d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (hasNotificationListenerService) { 18859d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("notification-listener"); 18869d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 1887eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock if (hasDreamService) { 1888eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock printComponentPresence("dream"); 1889eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock } 18909d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (hasCameraActivity) { 18919d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("camera"); 18929d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 18939d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (hasCameraSecureActivity) { 18949d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("camera-secure"); 18959d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 18969d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski 18979d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (hasMainActivity) { 18989d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printf("main\n"); 189994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 1900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasOtherActivities) { 1901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("other-activities\n"); 1902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 19039d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (hasOtherReceivers) { 1904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("other-receivers\n"); 1905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasOtherServices) { 1907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("other-services\n"); 1908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // For modern apps, if screen size buckets haven't been specified 1911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // but the new width ranges have, then infer the buckets from them. 1912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (smallScreen > 0 && normalScreen > 0 && largeScreen > 0 && xlargeScreen > 0 1913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && requiresSmallestWidthDp > 0) { 1914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int compatWidth = compatibleWidthLimitDp; 1915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (compatWidth <= 0) { 1916282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski compatWidth = requiresSmallestWidthDp; 1917282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (requiresSmallestWidthDp <= 240 && compatWidth >= 240) { 1919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski smallScreen = -1; 1920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski smallScreen = 0; 1922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (requiresSmallestWidthDp <= 320 && compatWidth >= 320) { 1924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski normalScreen = -1; 1925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski normalScreen = 0; 1927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1928282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (requiresSmallestWidthDp <= 480 && compatWidth >= 480) { 1929282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski largeScreen = -1; 1930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski largeScreen = 0; 1932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (requiresSmallestWidthDp <= 720 && compatWidth >= 720) { 1934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski xlargeScreen = -1; 1935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski xlargeScreen = 0; 1937282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1938282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1940282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Determine default values for any unspecified screen sizes, 1941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // based on the target SDK of the package. As of 4 (donut) 1942282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the screen size support was introduced, so all default to 1943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // enabled. 1944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (smallScreen > 0) { 1945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski smallScreen = targetSdk >= 4 ? -1 : 0; 1946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (normalScreen > 0) { 1948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski normalScreen = -1; 1949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1950282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (largeScreen > 0) { 1951282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski largeScreen = targetSdk >= 4 ? -1 : 0; 1952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (xlargeScreen > 0) { 1954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Introduced in Gingerbread. 1955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski xlargeScreen = targetSdk >= 9 ? -1 : 0; 1956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (anyDensity > 0) { 1958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski anyDensity = (targetSdk >= 4 || requiresSmallestWidthDp > 0 1959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || compatibleWidthLimitDp > 0) ? -1 : 0; 1960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("supports-screens:"); 1962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (smallScreen != 0) { 1963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" 'small'"); 1964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (normalScreen != 0) { 1966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" 'normal'"); 1967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (largeScreen != 0) { 1969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" 'large'"); 1970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (xlargeScreen != 0) { 1972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" 'xlarge'"); 1973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 1975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("supports-any-density: '%s'\n", anyDensity ? "true" : "false"); 1976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (requiresSmallestWidthDp > 0) { 1977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("requires-smallest-width:'%d'\n", requiresSmallestWidthDp); 1978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (compatibleWidthLimitDp > 0) { 1980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("compatible-width-limit:'%d'\n", compatibleWidthLimitDp); 1981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (largestWidthLimitDp > 0) { 1983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("largest-width-limit:'%d'\n", largestWidthLimitDp); 1984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("locales:"); 1987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NL = locales.size(); 1988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<NL; i++) { 1989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* localeStr = locales[i].string(); 1990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (localeStr == NULL || strlen(localeStr) == 0) { 1991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski localeStr = "--_--"; 1992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" '%s'", localeStr); 1994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 1996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("densities:"); 1998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t ND = densities.size(); 1999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<ND; i++) { 2000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" '%d'", densities[i]); 2001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 2003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AssetDir* dir = assets.openNonAssetDir(assetsCookie, "lib"); 2005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (dir != NULL) { 2006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (dir->getFileCount() > 0) { 2007e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski SortedVector<String8> architectures; 2008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<dir->getFileCount(); i++) { 2009e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski architectures.add(ResTable::normalizeForOutput( 2010e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski dir->getFileName(i).string())); 2011e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski } 2012e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski 2013e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski bool outputAltNativeCode = false; 2014e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // A multiArch package is one that contains 64-bit and 2015e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // 32-bit versions of native code and expects 3rd-party 2016e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // apps to load these native code libraries. Since most 2017e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // 64-bit systems also support 32-bit apps, the apps 2018e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // loading this multiArch package's code may be either 2019e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // 32-bit or 64-bit. 2020e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski if (hasMultiArch) { 2021e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // If this is a multiArch package, report the 64-bit 2022e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // version only. Then as a separate entry, report the 2023e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // rest. 2024e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // 2025e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // If we report the 32-bit architecture, this APK will 2026e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // be installed on a 32-bit device, causing a large waste 2027e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // of bandwidth and disk space. This assumes that 2028e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // the developer of the multiArch package has also 2029e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // made a version that is 32-bit only. 2030e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski String8 intel64("x86_64"); 2031e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski String8 arm64("arm64-v8a"); 2032e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski ssize_t index = architectures.indexOf(intel64); 2033e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski if (index < 0) { 2034e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski index = architectures.indexOf(arm64); 2035e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski } 2036e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski 2037e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski if (index >= 0) { 2038e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski printf("native-code: '%s'\n", architectures[index].string()); 2039e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski architectures.removeAt(index); 2040e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski outputAltNativeCode = true; 2041e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski } 2042e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski } 2043e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski 2044e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski const size_t archCount = architectures.size(); 2045e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski if (archCount > 0) { 2046e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski if (outputAltNativeCode) { 2047e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski printf("alt-"); 2048e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski } 2049e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski printf("native-code:"); 2050e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski for (size_t i = 0; i < archCount; i++) { 2051e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski printf(" '%s'", architectures[i].string()); 2052e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski } 2053e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski printf("\n"); 2054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete dir; 2057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("badger", option) == 0) { 2059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%s", CONSOLE_DATA); 2060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("configurations", option) == 0) { 2061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<ResTable_config> configs; 2062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res.getConfigurations(&configs); 2063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = configs.size(); 2064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 2065282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%s\n", configs[i].toString().string()); 2066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2067282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: unknown dump option '%s'\n", option); 2069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2070282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2071282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2072282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2073282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = NO_ERROR; 2074282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 2076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (asset) { 2077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete asset; 2078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (result != NO_ERROR); 2080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 2084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Handle the "add" command, which wants to add files to a new or 2085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * pre-existing archive. 2086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 2087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doAdd(Bundle* bundle) 2088282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2089282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipFile* zip = NULL; 2090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result = UNKNOWN_ERROR; 2091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* zipFileName; 2092282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2093282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getUpdate()) { 2094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* avoid confusion */ 2095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: can't use '-u' with add\n"); 2096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2097282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2098282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2099282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 1) { 2100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: must specify zip file name\n"); 2101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zipFileName = bundle->getFileSpecEntry(0); 2104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 2) { 2106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "NOTE: nothing to do\n"); 2107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip = openReadWrite(zipFileName, true); 2111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (zip == NULL) { 2112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: failed opening/creating '%s' as Zip file\n", zipFileName); 2113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i = 1; i < bundle->getFileSpecCount(); i++) { 2117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* fileName = bundle->getFileSpecEntry(i); 2118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcasecmp(String8(fileName).getPathExtension().string(), ".gz") == 0) { 2120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" '%s'... (from gzip)\n", fileName); 2121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = zip->addGzip(fileName, String8(fileName).getBasePath().string(), NULL); 2122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getJunkPath()) { 2124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 storageName = String8(fileName).getPathLeaf(); 21252675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf(" '%s' as '%s'...\n", fileName, 21262675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(storageName.string()).string()); 2127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = zip->add(fileName, storageName.string(), 2128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bundle->getCompressionMethod(), NULL); 2129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" '%s'...\n", fileName); 2131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = zip->add(fileName, bundle->getCompressionMethod(), NULL); 2132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result != NO_ERROR) { 2135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "Unable to add '%s' to '%s'", bundle->getFileSpecEntry(i), zipFileName); 2136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result == NAME_NOT_FOUND) { 2137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, ": file not found\n"); 2138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (result == ALREADY_EXISTS) { 2139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, ": already exists in archive\n"); 2140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "\n"); 2142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = NO_ERROR; 2148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 2150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete zip; 2151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (result != NO_ERROR); 2152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 2156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Delete files from an existing archive. 2157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 2158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doRemove(Bundle* bundle) 2159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipFile* zip = NULL; 2161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result = UNKNOWN_ERROR; 2162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* zipFileName; 2163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 1) { 2165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: must specify zip file name\n"); 2166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zipFileName = bundle->getFileSpecEntry(0); 2169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 2) { 2171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "NOTE: nothing to do\n"); 2172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip = openReadWrite(zipFileName, false); 2176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (zip == NULL) { 2177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: failed opening Zip archive '%s'\n", 2178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zipFileName); 2179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i = 1; i < bundle->getFileSpecCount(); i++) { 2183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* fileName = bundle->getFileSpecEntry(i); 2184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry* entry; 2185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entry = zip->getEntryByName(fileName); 2187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (entry == NULL) { 2188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" '%s' NOT FOUND\n", fileName); 2189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = zip->remove(entry); 2193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result != NO_ERROR) { 2195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "Unable to delete '%s' from '%s'\n", 2196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bundle->getFileSpecEntry(i), zipFileName); 2197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* update the archive */ 2202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip->flush(); 2203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 2205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete zip; 2206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (result != NO_ERROR); 2207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 22093921e87e6e67a063caa1987937d7944b24aef489Adam Lesinskistatic status_t addResourcesToBuilder(const sp<AaptDir>& dir, const sp<ApkBuilder>& builder, bool ignoreConfig=false) { 2210fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const size_t numDirs = dir->getDirs().size(); 2211fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski for (size_t i = 0; i < numDirs; i++) { 22123921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski bool ignore = ignoreConfig; 22133921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski const sp<AaptDir>& subDir = dir->getDirs().valueAt(i); 22143921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski const char* dirStr = subDir->getLeaf().string(); 22153921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski if (!ignore && strstr(dirStr, "mipmap") == dirStr) { 22163921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski ignore = true; 22173921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski } 22183921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski status_t err = addResourcesToBuilder(subDir, builder, ignore); 2219fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (err != NO_ERROR) { 2220fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return err; 2221fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2222fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2223fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 2224fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const size_t numFiles = dir->getFiles().size(); 2225fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski for (size_t i = 0; i < numFiles; i++) { 2226fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski sp<AaptGroup> gp = dir->getFiles().valueAt(i); 2227fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const size_t numConfigs = gp->getFiles().size(); 2228fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski for (size_t j = 0; j < numConfigs; j++) { 22293921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski status_t err = NO_ERROR; 22303921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski if (ignoreConfig) { 22313921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski err = builder->getBaseSplit()->addEntry(gp->getPath(), gp->getFiles().valueAt(j)); 22323921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski } else { 22333921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski err = builder->addEntry(gp->getPath(), gp->getFiles().valueAt(j)); 22343921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski } 2235fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (err != NO_ERROR) { 2236fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski fprintf(stderr, "Failed to add %s (%s) to builder.\n", 2237fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski gp->getPath().string(), gp->getFiles()[j]->getPrintableSource().string()); 2238fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return err; 2239fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2240fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2241fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2242fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return NO_ERROR; 2243fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski} 2244fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 2245fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskistatic String8 buildApkName(const String8& original, const sp<ApkSplit>& split) { 2246fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (split->isBase()) { 2247fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return original; 2248fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2249fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 2250fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski String8 ext(original.getPathExtension()); 2251fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (ext == String8(".apk")) { 2252fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return String8::format("%s_%s%s", 2253fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski original.getBasePath().string(), 2254fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski split->getDirectorySafeName().string(), 2255fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski ext.string()); 2256fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2257fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 2258fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return String8::format("%s_%s", original.string(), 2259fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski split->getDirectorySafeName().string()); 2260fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski} 2261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 2263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Package up an asset directory and associated application files. 2264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 2265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doPackage(Bundle* bundle) 2266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* outputAPKFile; 2268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int retVal = 1; 2269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err; 2270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptAssets> assets; 2271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int N; 2272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FILE* fp; 2273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 dependencyFile; 2274fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski sp<ApkBuilder> builder; 2275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2276a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin // -c en_XA or/and ar_XB means do pseudolocalization 2277fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski sp<WeakResourceFilter> configFilter = new WeakResourceFilter(); 2278fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski err = configFilter->parse(bundle->getConfigurations()); 2279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 2280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2282fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (configFilter->containsPseudo()) { 2283a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin bundle->setPseudolocalize(bundle->getPseudolocalize() | PSEUDO_ACCENTED); 2284a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin } 2285fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (configFilter->containsPseudoBidi()) { 2286a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin bundle->setPseudolocalize(bundle->getPseudolocalize() | PSEUDO_BIDI); 2287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski N = bundle->getFileSpecCount(); 2290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (N < 1 && bundle->getResourceSourceDirs().size() == 0 && bundle->getJarFiles().size() == 0 229109384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski && bundle->getAndroidManifestFile() == NULL && bundle->getAssetSourceDirs().size() == 0) { 2292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: no input files\n"); 2293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outputAPKFile = bundle->getOutputAPKFile(); 2297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Make sure the filenames provided exist and are of the appropriate type. 2299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outputAPKFile) { 2300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FileType type; 2301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type = getFileType(outputAPKFile); 2302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (type != kFileTypeNonexistent && type != kFileTypeRegular) { 2303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, 2304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "ERROR: output file '%s' exists but is not regular file\n", 2305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outputAPKFile); 2306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Load the assets. 2311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets = new AaptAssets(); 2312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Set up the resource gathering in assets if we're going to generate 2314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // dependency files. Every time we encounter a resource while slurping 2315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the tree, we'll add it to these stores so we have full resource paths 2316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // to write to a dependency file. 2317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getGenDependencies()) { 2318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<FilePathStore> resPathStore = new FilePathStore; 2319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->setFullResPaths(resPathStore); 2320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<FilePathStore> assetPathStore = new FilePathStore; 2321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->setFullAssetPaths(assetPathStore); 2322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = assets->slurpFromArgs(bundle); 2325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 2326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 2330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->print(String8()); 2331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2333fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // Create the ApkBuilder, which will collect the compiled files 2334fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // to write to the final APK (or sets of APKs if we are building 2335fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // a Split APK. 2336fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski builder = new ApkBuilder(configFilter); 2337fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 2338fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // If we are generating a Split APK, find out which configurations to split on. 2339fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (bundle->getSplitConfigurations().size() > 0) { 2340fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const Vector<String8>& splitStrs = bundle->getSplitConfigurations(); 2341fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const size_t numSplits = splitStrs.size(); 2342fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski for (size_t i = 0; i < numSplits; i++) { 2343fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski std::set<ConfigDescription> configs; 2344fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (!AaptConfig::parseCommaSeparatedList(splitStrs[i], &configs)) { 2345fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski fprintf(stderr, "ERROR: failed to parse split configuration '%s'\n", splitStrs[i].string()); 2346fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski goto bail; 2347fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2348fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 2349fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski err = builder->createSplitForConfigs(configs); 2350fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (err != NO_ERROR) { 2351fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski goto bail; 2352fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2353fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2354fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2355fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 2356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If they asked for any fileAs that need to be compiled, do so. 2357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getResourceSourceDirs().size() || bundle->getAndroidManifestFile()) { 2358fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski err = buildResources(bundle, assets, builder); 2359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != 0) { 2360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // At this point we've read everything and processed everything. From here 2365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // on out it's just writing output files. 2366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (SourcePos::hasErrors()) { 2367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Update symbols with information about which ones are needed as Java symbols. 2371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->applyJavaSymbols(); 2372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (SourcePos::hasErrors()) { 2373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If we've been asked to generate a dependency file, do that here 2377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getGenDependencies()) { 2378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If this is the packaging step, generate the dependency file next to 2379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the output apk (e.g. bin/resources.ap_.d) 2380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outputAPKFile) { 2381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dependencyFile = String8(outputAPKFile); 2382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Add the .d extension to the dependency file. 2383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dependencyFile.append(".d"); 2384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Else if this is the R.java dependency generation step, 2386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // generate the dependency file in the R.java package subdirectory 2387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // e.g. gen/com/foo/app/R.java.d 2388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dependencyFile = String8(bundle->getRClassDir()); 2389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dependencyFile.appendPath("R.java.d"); 2390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Make sure we have a clean dependency file to start with 2392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fp = fopen(dependencyFile, "w"); 2393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fclose(fp); 2394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write out R.java constants 2397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!assets->havePrivateSymbols()) { 2398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getCustomPackage() == NULL) { 2399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write the R.java file into the appropriate class directory 2400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // e.g. gen/com/foo/app/R.java 24011e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski err = writeResourceSymbols(bundle, assets, assets->getPackage(), true, 24021e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski bundle->getBuildSharedLibrary()); 2403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8 customPkg(bundle->getCustomPackage()); 24051e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski err = writeResourceSymbols(bundle, assets, customPkg, true, 24061e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski bundle->getBuildSharedLibrary()); 2407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 2409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If we have library files, we're going to write our R.java file into 2412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the appropriate class directory for those libraries as well. 2413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // e.g. gen/com/foo/app/lib/R.java 2414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getExtraPackages() != NULL) { 2415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Split on colon 2416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 libs(bundle->getExtraPackages()); 2417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char* packageString = strtok(libs.lockBuffer(libs.length()), ":"); 2418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (packageString != NULL) { 2419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write the R.java file out with the correct package name 24200f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba err = writeResourceSymbols(bundle, assets, String8(packageString), true, 24210f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba bundle->getBuildSharedLibrary()); 2422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 2423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski packageString = strtok(NULL, ":"); 2426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski libs.unlockBuffer(); 2428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 24301e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski err = writeResourceSymbols(bundle, assets, assets->getPackage(), false, false); 2431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 2432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 24341e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski err = writeResourceSymbols(bundle, assets, assets->getSymbolsPrivatePackage(), true, false); 2435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 2436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write out the ProGuard file 2441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeProguardFile(bundle, assets); 2442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 2443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write the apk 2447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outputAPKFile) { 2448fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // Gather all resources and add them to the APK Builder. The builder will then 2449fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // figure out which Split they belong in. 2450fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski err = addResourcesToBuilder(assets, builder); 2451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 2452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2454fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 2455fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const Vector<sp<ApkSplit> >& splits = builder->getSplits(); 2456fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const size_t numSplits = splits.size(); 2457fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski for (size_t i = 0; i < numSplits; i++) { 2458fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const sp<ApkSplit>& split = splits[i]; 2459fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski String8 outputPath = buildApkName(String8(outputAPKFile), split); 2460fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski err = writeAPK(bundle, outputPath, split); 2461fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (err != NO_ERROR) { 2462fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski fprintf(stderr, "ERROR: packaging of '%s' failed\n", outputPath.string()); 2463fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski goto bail; 2464fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2465fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If we've been asked to generate a dependency file, we need to finish up here. 2469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the writeResourceSymbols and writeAPK functions have already written the target 2470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // half of the dependency file, now we need to write the prerequisites. (files that 2471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the R.java file or .ap_ file depend on) 2472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getGenDependencies()) { 2473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Now that writeResourceSymbols or writeAPK has taken care of writing 2474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the targets to our dependency file, we'll write the prereqs 2475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fp = fopen(dependencyFile, "a+"); 2476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, " : "); 2477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool includeRaw = (outputAPKFile != NULL); 2478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeDependencyPreReqs(bundle, assets, fp, includeRaw); 2479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Also manually add the AndroidManifeset since it's not under res/ or assets/ 2480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // and therefore was not added to our pathstores during slurping 2481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s \\\n", bundle->getAndroidManifestFile()); 2482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fclose(fp); 2483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski retVal = 0; 2486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 2487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (SourcePos::hasErrors()) { 2488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos::printErrors(stderr); 2489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return retVal; 2491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 2494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Do PNG Crunching 2495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * PRECONDITIONS 2496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * -S flag points to a source directory containing drawable* folders 2497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * -C flag points to destination directory. The folder structure in the 2498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * source directory will be mirrored to the destination (cache) directory 2499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 2500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * POSTCONDITIONS 2501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Destination directory will be updated to match the PNG files in 25022675f769673f69b0661ddee346292f25cb30a296Maurice Chu * the source directory. 2503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 2504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doCrunch(Bundle* bundle) 2505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "Crunching PNG Files in "); 2507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "source dir: %s\n", bundle->getResourceSourceDirs()[0]); 2508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "To destination dir: %s\n", bundle->getCrunchedOutputDir()); 2509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski updatePreProcessedCache(bundle); 2511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 2513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 2516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Do PNG Crunching on a single flag 2517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * -i points to a single png file 2518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * -o points to a single png output file 2519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 2520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doSingleCrunch(Bundle* bundle) 2521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "Crunching single PNG file: %s\n", bundle->getSingleCrunchInputFile()); 2523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "\tOutput file: %s\n", bundle->getSingleCrunchOutputFile()); 2524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 input(bundle->getSingleCrunchInputFile()); 2526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 output(bundle->getSingleCrunchOutputFile()); 2527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (preProcessImageToCache(bundle, input, output) != NO_ERROR) { 2529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // we can't return the status_t as it gets truncate to the lower 8 bits. 2530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 42; 2531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 2534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 25366f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochezint runInDaemonMode(Bundle* bundle) { 25376f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez std::cout << "Ready" << std::endl; 25386f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez for (std::string line; std::getline(std::cin, line);) { 25396f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez if (line == "quit") { 25406f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez return NO_ERROR; 25416f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez } 25426f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez std::stringstream ss; 25436f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez ss << line; 25446f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez std::string s; 25456f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez 25466f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez std::string command, parameterOne, parameterTwo; 25476f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez std::getline(ss, command, ' '); 25486f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez std::getline(ss, parameterOne, ' '); 25496f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez std::getline(ss, parameterTwo, ' '); 25506f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez if (command[0] == 's') { 25516f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez bundle->setSingleCrunchInputFile(parameterOne.c_str()); 25526f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez bundle->setSingleCrunchOutputFile(parameterTwo.c_str()); 25536f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez std::cout << "Crunching " << parameterOne << std::endl; 25546f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez if (doSingleCrunch(bundle) != NO_ERROR) { 25556f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez std::cout << "Error" << std::endl; 25566f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez } 25576f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez std::cout << "Done" << std::endl; 25586f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez } else { 25596f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez // in case of invalid command, just bail out. 25606f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez std::cerr << "Unknown command" << std::endl; 25616f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez return -1; 25626f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez } 25636f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez } 25646f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez return -1; 25656f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez} 25666f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez 2567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskichar CONSOLE_DATA[2925] = { 2568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 95, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 2572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 63, 2573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 86, 35, 40, 46, 46, 95, 95, 95, 95, 97, 97, 44, 32, 46, 124, 42, 33, 83, 2574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 62, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 46, 58, 59, 61, 59, 61, 81, 2577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 66, 96, 61, 61, 58, 46, 46, 46, 58, 32, 32, 32, 32, 32, 32, 2578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 2579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 46, 61, 59, 59, 59, 58, 106, 81, 81, 81, 81, 102, 59, 61, 59, 2581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 61, 61, 61, 58, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 2584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 58, 109, 81, 81, 81, 81, 61, 59, 59, 59, 59, 59, 58, 59, 59, 46, 32, 2585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 60, 81, 81, 81, 81, 87, 2588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 58, 59, 59, 59, 59, 59, 59, 61, 119, 44, 32, 32, 32, 32, 32, 32, 32, 32, 2589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 2590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 2591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 47, 61, 59, 59, 58, 100, 81, 81, 81, 81, 35, 58, 59, 59, 59, 59, 59, 58, 2592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 121, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 109, 58, 59, 59, 61, 81, 81, 2595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 109, 58, 59, 59, 59, 59, 61, 109, 81, 81, 76, 46, 32, 32, 32, 2596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 2597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 41, 87, 59, 61, 59, 41, 81, 81, 81, 81, 81, 81, 59, 61, 59, 2599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 58, 109, 81, 81, 87, 39, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 60, 81, 91, 59, 2602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 61, 81, 81, 81, 81, 81, 87, 43, 59, 58, 59, 60, 81, 81, 81, 76, 32, 2603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 52, 91, 58, 45, 59, 87, 81, 81, 81, 81, 2606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 70, 58, 58, 58, 59, 106, 81, 81, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32, 2607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 2608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 93, 40, 32, 46, 59, 100, 81, 81, 81, 81, 40, 58, 46, 46, 58, 100, 81, 2610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 68, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 46, 46, 46, 32, 46, 46, 46, 32, 46, 32, 46, 45, 91, 59, 61, 58, 109, 2613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 87, 46, 58, 61, 59, 60, 81, 81, 80, 32, 32, 32, 32, 32, 32, 2614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 2615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 46, 46, 61, 59, 61, 61, 61, 59, 61, 61, 59, 2616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 58, 58, 46, 46, 41, 58, 59, 58, 81, 81, 81, 81, 69, 58, 59, 59, 2617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 60, 81, 81, 68, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 58, 59, 2619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 61, 46, 2620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 59, 93, 81, 81, 81, 81, 107, 58, 59, 58, 109, 87, 68, 96, 32, 32, 32, 2621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 10, 32, 32, 32, 46, 60, 61, 61, 59, 59, 59, 59, 59, 59, 59, 59, 2623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 59, 59, 59, 58, 58, 58, 115, 109, 68, 41, 36, 81, 2624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 109, 46, 61, 61, 81, 69, 96, 46, 58, 58, 46, 58, 46, 46, 32, 32, 32, 32, 2625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 46, 32, 95, 81, 2626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 67, 61, 61, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 2627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 58, 68, 39, 61, 105, 61, 63, 81, 119, 58, 106, 80, 32, 58, 2628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 59, 59, 61, 59, 61, 59, 61, 46, 95, 32, 32, 32, 32, 32, 32, 32, 32, 2629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 10, 32, 32, 36, 81, 109, 105, 59, 61, 59, 59, 59, 2630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 46, 58, 37, 2631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 73, 108, 108, 62, 52, 81, 109, 34, 32, 61, 59, 59, 59, 59, 59, 59, 59, 59, 2632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 61, 59, 61, 61, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 2633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 46, 45, 57, 101, 43, 43, 61, 61, 59, 59, 59, 59, 59, 59, 61, 59, 59, 2634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 59, 58, 97, 46, 61, 108, 62, 126, 58, 106, 80, 96, 2635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46, 61, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 61, 2636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 97, 103, 97, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 45, 46, 32, 2637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45, 58, 59, 59, 59, 59, 61, 2638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 119, 81, 97, 124, 105, 124, 124, 39, 126, 95, 119, 58, 61, 58, 59, 59, 59, 2639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 119, 81, 81, 99, 32, 32, 2640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 58, 106, 81, 81, 81, 109, 119, 2642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 119, 119, 109, 109, 81, 81, 122, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 2643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 58, 115, 81, 87, 81, 102, 32, 32, 32, 32, 32, 32, 10, 2644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 61, 58, 59, 61, 81, 81, 81, 81, 81, 81, 87, 87, 81, 81, 81, 81, 2646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 58, 59, 59, 59, 59, 59, 59, 59, 59, 58, 45, 45, 45, 59, 59, 59, 41, 2647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 87, 66, 33, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 2648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 93, 81, 2649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 2650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 45, 32, 46, 32, 32, 32, 32, 32, 46, 32, 126, 96, 32, 32, 32, 32, 32, 32, 2651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 58, 61, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81, 2653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 2654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 2655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 2656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58, 2657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 60, 81, 81, 81, 81, 2660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 81, 81, 81, 81, 59, 61, 59, 59, 61, 32, 32, 32, 32, 2661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 58, 59, 59, 93, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 2664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 40, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 2666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 106, 2667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 76, 58, 59, 59, 59, 2668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 61, 58, 58, 81, 81, 81, 81, 81, 81, 81, 81, 2671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 87, 58, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 2672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 2673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 58, 59, 61, 41, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 87, 59, 2675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 58, 59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 61, 81, 81, 81, 2678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 81, 81, 81, 81, 107, 58, 59, 59, 59, 59, 58, 32, 32, 2679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 58, 59, 59, 58, 51, 81, 81, 81, 81, 81, 81, 81, 81, 81, 2682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 102, 94, 59, 59, 59, 59, 59, 61, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 2684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 2685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 43, 63, 36, 81, 81, 81, 87, 64, 86, 102, 58, 59, 59, 59, 59, 59, 2686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 59, 59, 43, 33, 2689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 58, 126, 126, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32, 32, 2690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 2691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 2692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 59, 59, 59, 58, 45, 58, 61, 59, 58, 58, 58, 61, 59, 59, 59, 59, 59, 2693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 2694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 2695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 58, 95, 2696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 45, 61, 59, 61, 59, 59, 59, 59, 59, 59, 59, 45, 58, 59, 59, 59, 59, 2697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 58, 61, 59, 59, 59, 59, 59, 61, 59, 61, 46, 46, 32, 45, 45, 45, 2700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 58, 45, 45, 46, 58, 59, 59, 59, 59, 59, 59, 61, 46, 32, 32, 32, 32, 2701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 2702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 58, 59, 59, 59, 59, 2703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 61, 59, 46, 32, 32, 46, 32, 46, 32, 58, 61, 59, 59, 2704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 45, 59, 59, 59, 59, 59, 59, 59, 59, 58, 32, 2707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 58, 32, 2708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 2709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46, 61, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 61, 2711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46, 61, 59, 59, 59, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 2713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 2714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 46, 61, 58, 59, 59, 59, 59, 2715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 58, 59, 59, 59, 59, 59, 59, 59, 59, 46, 46, 32, 32, 32, 2718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 45, 32, 32, 32, 32, 32, 2719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 2720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 32, 45, 61, 2721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 2722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 58, 45, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45, 45, 32, 46, 32, 2725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 61, 59, 58, 45, 45, 32, 32, 32, 2726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 46, 32, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10 2731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski }; 2732