Command.cpp revision 43158773b469c2d5b23e52998d0afba9a4b34323
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 218ba3fe56edc1da4dad0d831a1892e7b1c3c20c437Elliott Hughes#ifdef __ANDROID__ 219b8dc7bc582ee4acd9d6c1379701a002c5ddbe323Andreas Gampe static const bool kHaveAndroidOs = true; 220b8dc7bc582ee4acd9d6c1379701a002c5ddbe323Andreas Gampe#else 221b8dc7bc582ee4acd9d6c1379701a002c5ddbe323Andreas Gampe static const bool kHaveAndroidOs = false; 222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 223b8dc7bc582ee4acd9d6c1379701a002c5ddbe323Andreas Gampe const ResTable& res = assets.getResources(false); 224b8dc7bc582ee4acd9d6c1379701a002c5ddbe323Andreas Gampe if (!kHaveAndroidOs) { 225b8dc7bc582ee4acd9d6c1379701a002c5ddbe323Andreas Gampe printf("\nResource table:\n"); 226b8dc7bc582ee4acd9d6c1379701a002c5ddbe323Andreas Gampe res.print(false); 227b8dc7bc582ee4acd9d6c1379701a002c5ddbe323Andreas Gampe } 228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Asset* manifestAsset = assets.openNonAsset("AndroidManifest.xml", 230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Asset::ACCESS_BUFFER); 231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (manifestAsset == NULL) { 232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\nNo AndroidManifest.xml found.\n"); 233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\nAndroid manifest:\n"); 235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree tree; 236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tree.setTo(manifestAsset->getBuffer(true), 237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski manifestAsset->getLength()); 238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printXMLBlock(&tree); 239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete manifestAsset; 241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = 0; 244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete zip; 247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return result; 248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 250ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinskistatic void printResolvedResourceAttribute(const ResTable& resTable, const ResXMLTree& tree, 25176327314d2238e105f8b94909f9c0cf85caca318Maurice Chu uint32_t attrRes, String8 attrLabel, String8* outError) 25276327314d2238e105f8b94909f9c0cf85caca318Maurice Chu{ 25376327314d2238e105f8b94909f9c0cf85caca318Maurice Chu Res_value value; 254ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski AaptXml::getResolvedResourceAttribute(resTable, tree, attrRes, &value, outError); 25576327314d2238e105f8b94909f9c0cf85caca318Maurice Chu if (*outError != "") { 25676327314d2238e105f8b94909f9c0cf85caca318Maurice Chu *outError = "error print resolved resource attribute"; 25776327314d2238e105f8b94909f9c0cf85caca318Maurice Chu return; 25876327314d2238e105f8b94909f9c0cf85caca318Maurice Chu } 25976327314d2238e105f8b94909f9c0cf85caca318Maurice Chu if (value.dataType == Res_value::TYPE_STRING) { 260ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 result = AaptXml::getResolvedAttribute(resTable, tree, attrRes, outError); 2612675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("%s='%s'", attrLabel.string(), 2622675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(result.string()).string()); 26376327314d2238e105f8b94909f9c0cf85caca318Maurice Chu } else if (Res_value::TYPE_FIRST_INT <= value.dataType && 26476327314d2238e105f8b94909f9c0cf85caca318Maurice Chu value.dataType <= Res_value::TYPE_LAST_INT) { 26576327314d2238e105f8b94909f9c0cf85caca318Maurice Chu printf("%s='%d'", attrLabel.string(), value.data); 26676327314d2238e105f8b94909f9c0cf85caca318Maurice Chu } else { 26776327314d2238e105f8b94909f9c0cf85caca318Maurice Chu printf("%s='0x%x'", attrLabel.string(), (int)value.data); 26876327314d2238e105f8b94909f9c0cf85caca318Maurice Chu } 26976327314d2238e105f8b94909f9c0cf85caca318Maurice Chu} 27076327314d2238e105f8b94909f9c0cf85caca318Maurice Chu 271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// These are attribute resource constants for the platform, as found 272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// in android.R.attr 273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskienum { 274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LABEL_ATTR = 0x01010001, 275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ICON_ATTR = 0x01010002, 276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NAME_ATTR = 0x01010003, 277a5018c900f126ee8424c82497f32983873db741bAdam Lesinski PERMISSION_ATTR = 0x01010006, 2789d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski EXPORTED_ATTR = 0x01010010, 2799d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski GRANT_URI_PERMISSIONS_ATTR = 0x0101001b, 28094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski RESOURCE_ATTR = 0x01010025, 281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DEBUGGABLE_ATTR = 0x0101000f, 282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski VALUE_ATTR = 0x01010024, 283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski VERSION_CODE_ATTR = 0x0101021b, 284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski VERSION_NAME_ATTR = 0x0101021c, 285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SCREEN_ORIENTATION_ATTR = 0x0101001e, 286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MIN_SDK_VERSION_ATTR = 0x0101020c, 287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MAX_SDK_VERSION_ATTR = 0x01010271, 288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_TOUCH_SCREEN_ATTR = 0x01010227, 289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_KEYBOARD_TYPE_ATTR = 0x01010228, 290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_HARD_KEYBOARD_ATTR = 0x01010229, 291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_NAVIGATION_ATTR = 0x0101022a, 292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_FIVE_WAY_NAV_ATTR = 0x01010232, 293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski TARGET_SDK_VERSION_ATTR = 0x01010270, 294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski TEST_ONLY_ATTR = 0x01010272, 295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ANY_DENSITY_ATTR = 0x0101026c, 296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski GL_ES_VERSION_ATTR = 0x01010281, 297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SMALL_SCREEN_ATTR = 0x01010284, 298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NORMAL_SCREEN_ATTR = 0x01010285, 299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LARGE_SCREEN_ATTR = 0x01010286, 300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski XLARGE_SCREEN_ATTR = 0x010102bf, 301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQUIRED_ATTR = 0x0101028e, 302caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski INSTALL_LOCATION_ATTR = 0x010102b7, 303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SCREEN_SIZE_ATTR = 0x010102ca, 304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SCREEN_DENSITY_ATTR = 0x010102cb, 305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQUIRES_SMALLEST_WIDTH_DP_ATTR = 0x01010364, 306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski COMPATIBLE_WIDTH_LIMIT_DP_ATTR = 0x01010365, 307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LARGEST_WIDTH_LIMIT_DP_ATTR = 0x01010366, 308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PUBLIC_KEY_ATTR = 0x010103a6, 30994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski CATEGORY_ATTR = 0x010103e8, 3100a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn BANNER_ATTR = 0x10103f2, 311d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn ISGAME_ATTR = 0x10103f4, 312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3142675f769673f69b0661ddee346292f25cb30a296Maurice ChuString8 getComponentName(String8 &pkgName, String8 &componentName) { 315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t idx = componentName.find("."); 316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 retStr(pkgName); 317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx == 0) { 318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski retStr += componentName; 319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (idx < 0) { 320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski retStr += "."; 321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski retStr += componentName; 322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3232675f769673f69b0661ddee346292f25cb30a296Maurice Chu return componentName; 324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3252675f769673f69b0661ddee346292f25cb30a296Maurice Chu return retStr; 326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3289cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinskistatic void printCompatibleScreens(ResXMLTree& tree, String8* outError) { 329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int depth = 0; 332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool first = true; 333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("compatible-screens:"); 334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth--; 337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (depth < 0) { 338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != ResXMLTree::START_TAG) { 343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth++; 3469cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski const char16_t* ctag16 = tree.getElementName(&len); 3479cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski if (ctag16 == NULL) { 3489cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski *outError = "failed to get XML element name (bad string pool)"; 3499cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski return; 3509cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski } 3519cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski String8 tag(ctag16); 352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag == "screen") { 353ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int32_t screenSize = AaptXml::getIntegerAttribute(tree, 354ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski SCREEN_SIZE_ATTR); 355ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int32_t screenDensity = AaptXml::getIntegerAttribute(tree, 356ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski SCREEN_DENSITY_ATTR); 357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (screenSize > 0 && screenDensity > 0) { 358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!first) { 359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(","); 360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski first = false; 362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("'%d/%d'", screenSize, screenDensity); 363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 36958f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinskistatic void printUsesPermission(const String8& name, bool optional=false, int maxSdkVersion=-1) { 37058f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printf("uses-permission: name='%s'", ResTable::normalizeForOutput(name.string()).string()); 37158f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski if (maxSdkVersion != -1) { 37258f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printf(" maxSdkVersion='%d'", maxSdkVersion); 37358f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski } 37458f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printf("\n"); 37558f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski 37658f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski if (optional) { 37758f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printf("optional-permission: name='%s'", 37858f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski ResTable::normalizeForOutput(name.string()).string()); 37958f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski if (maxSdkVersion != -1) { 38058f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printf(" maxSdkVersion='%d'", maxSdkVersion); 38158f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski } 38258f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printf("\n"); 38358f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski } 38458f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski} 38558f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski 3865f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinskistatic void printUsesPermissionSdk23(const String8& name, int maxSdkVersion=-1) { 3875f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski printf("uses-permission-sdk-23: "); 3885f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski 3895f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski printf("name='%s'", ResTable::normalizeForOutput(name.string()).string()); 3905f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski if (maxSdkVersion != -1) { 3915f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski printf(" maxSdkVersion='%d'", maxSdkVersion); 3925f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } 3935f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski printf("\n"); 3945f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski} 3955f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski 39658f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinskistatic void printUsesImpliedPermission(const String8& name, const String8& reason) { 39758f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printf("uses-implied-permission: name='%s' reason='%s'\n", 39858f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski ResTable::normalizeForOutput(name.string()).string(), 39958f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski ResTable::normalizeForOutput(reason.string()).string()); 40058f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski} 40158f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski 40294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam LesinskiVector<String8> getNfcAidCategories(AssetManager& assets, String8 xmlPath, bool offHost, 40394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski String8 *outError = NULL) 40494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski{ 40594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski Asset* aidAsset = assets.openNonAsset(xmlPath, Asset::ACCESS_BUFFER); 40694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (aidAsset == NULL) { 40794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (outError != NULL) *outError = "xml resource does not exist"; 40894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski return Vector<String8>(); 40994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 41094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 41194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski const String8 serviceTagName(offHost ? "offhost-apdu-service" : "host-apdu-service"); 41294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 41394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool withinApduService = false; 41494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski Vector<String8> categories; 41594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 41694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski String8 error; 41794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski ResXMLTree tree; 41894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski tree.setTo(aidAsset->getBuffer(true), aidAsset->getLength()); 41994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 42094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski size_t len; 42194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski int depth = 0; 42294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski ResXMLTree::event_code_t code; 42394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 42494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (code == ResXMLTree::END_TAG) { 42594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski depth--; 4269cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski const char16_t* ctag16 = tree.getElementName(&len); 4279cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski if (ctag16 == NULL) { 4289cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski *outError = "failed to get XML element name (bad string pool)"; 4299cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski return Vector<String8>(); 4309cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski } 4319cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski String8 tag(ctag16); 43294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 43394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (depth == 0 && tag == serviceTagName) { 43494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski withinApduService = false; 43594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 43694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 43794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else if (code == ResXMLTree::START_TAG) { 43894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski depth++; 4399cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski const char16_t* ctag16 = tree.getElementName(&len); 4409cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski if (ctag16 == NULL) { 4419cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski *outError = "failed to get XML element name (bad string pool)"; 4429cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski return Vector<String8>(); 4439cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski } 4449cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski String8 tag(ctag16); 44594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 44694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (depth == 1) { 44794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (tag == serviceTagName) { 44894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski withinApduService = true; 44994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 45094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else if (depth == 2 && withinApduService) { 45194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (tag == "aid-group") { 452ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 category = AaptXml::getAttribute(tree, CATEGORY_ATTR, &error); 45394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (error != "") { 45494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (outError != NULL) *outError = error; 45594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski return Vector<String8>(); 45694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 45794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 45894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski categories.add(category); 45994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 46094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 46194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 46294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 46394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski aidAsset->close(); 46494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski return categories; 46594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski} 46694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 4679d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinskistatic void printComponentPresence(const char* componentName) { 4689d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printf("provides-component:'%s'\n", componentName); 4699d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski} 4709d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski 4712c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski/** 4722c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski * Represents a feature that has been automatically added due to 4732c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski * a pre-requisite or some other reason. 4742c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski */ 4752c72b6822debb08fe997926eedc110f62d287d34Adam Lesinskistruct ImpliedFeature { 4765f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski ImpliedFeature() : impliedBySdk23(false) {} 4775f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski ImpliedFeature(const String8& n, bool sdk23) : name(n), impliedBySdk23(sdk23) {} 4785f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski 4792c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski /** 4802c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski * Name of the implied feature. 4812c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski */ 4822c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8 name; 4832c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 4842c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski /** 4855f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski * Was this implied by a permission from SDK 23 (<uses-permission-sdk-23 />)? 4865f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski */ 4875f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski bool impliedBySdk23; 4885f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski 4895f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski /** 4902c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski * List of human-readable reasons for why this feature was implied. 4912c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski */ 4922c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski SortedVector<String8> reasons; 4932c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski}; 4942c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 495694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinskistruct Feature { 496694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski Feature() : required(false), version(-1) {} 497694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski Feature(bool required, int32_t version = -1) : required(required), version(version) {} 498694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski 499694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski /** 500694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski * Whether the feature is required. 501694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski */ 502694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski bool required; 503694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski 504694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski /** 505694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski * What version of the feature is requested. 506694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski */ 507694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski int32_t version; 508694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski}; 509694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski 5102c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski/** 5112c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski * Represents a <feature-group> tag in the AndroidManifest.xml 5122c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski */ 5132c72b6822debb08fe997926eedc110f62d287d34Adam Lesinskistruct FeatureGroup { 514d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski FeatureGroup() : openGLESVersion(-1) {} 515d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski 5162c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski /** 5172c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski * Human readable label 5182c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski */ 5192c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8 label; 5202c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 5212c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski /** 5222c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski * Explicit features defined in the group 5232c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski */ 524694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski KeyedVector<String8, Feature> features; 525d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski 526d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski /** 527d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski * OpenGL ES version required 528d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski */ 529d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski int openGLESVersion; 5302c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski}; 5312c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 532ca955a4c3ab3d4b83c6e9d5278bcd8d2258d44adAdam Lesinskistatic bool hasFeature(const char* name, const FeatureGroup& grp, 533ca955a4c3ab3d4b83c6e9d5278bcd8d2258d44adAdam Lesinski const KeyedVector<String8, ImpliedFeature>& implied) { 534ca955a4c3ab3d4b83c6e9d5278bcd8d2258d44adAdam Lesinski String8 name8(name); 535ca955a4c3ab3d4b83c6e9d5278bcd8d2258d44adAdam Lesinski ssize_t idx = grp.features.indexOfKey(name8); 536ca955a4c3ab3d4b83c6e9d5278bcd8d2258d44adAdam Lesinski if (idx < 0) { 537ca955a4c3ab3d4b83c6e9d5278bcd8d2258d44adAdam Lesinski idx = implied.indexOfKey(name8); 538ca955a4c3ab3d4b83c6e9d5278bcd8d2258d44adAdam Lesinski } 539ca955a4c3ab3d4b83c6e9d5278bcd8d2258d44adAdam Lesinski return idx >= 0; 540ca955a4c3ab3d4b83c6e9d5278bcd8d2258d44adAdam Lesinski} 541ca955a4c3ab3d4b83c6e9d5278bcd8d2258d44adAdam Lesinski 5422c72b6822debb08fe997926eedc110f62d287d34Adam Lesinskistatic void addImpliedFeature(KeyedVector<String8, ImpliedFeature>* impliedFeatures, 54343158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski const char* name, const String8& reason, bool sdk23) { 5442c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8 name8(name); 5452c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski ssize_t idx = impliedFeatures->indexOfKey(name8); 5462c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (idx < 0) { 5475f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski idx = impliedFeatures->add(name8, ImpliedFeature(name8, sdk23)); 5482c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 5495f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski 5505f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski ImpliedFeature* feature = &impliedFeatures->editValueAt(idx); 5515f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski 5525f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski // A non-sdk 23 implied feature takes precedence. 5535f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski if (feature->impliedBySdk23 && !sdk23) { 5545f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski feature->impliedBySdk23 = false; 5555f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } 55643158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski feature->reasons.add(reason); 5572c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski} 5582c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 5595f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinskistatic void printFeatureGroupImpl(const FeatureGroup& grp, 5605f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski const KeyedVector<String8, ImpliedFeature>* impliedFeatures) { 5612c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski printf("feature-group: label='%s'\n", grp.label.string()); 5622c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 563d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski if (grp.openGLESVersion > 0) { 564d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski printf(" uses-gl-es: '0x%x'\n", grp.openGLESVersion); 565d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski } 566d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski 5672c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski const size_t numFeatures = grp.features.size(); 5682c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski for (size_t i = 0; i < numFeatures; i++) { 569694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski const Feature& feature = grp.features[i]; 570694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski const bool required = feature.required; 571694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski const int32_t version = feature.version; 5722c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 5732c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski const String8& featureName = grp.features.keyAt(i); 574694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski printf(" uses-feature%s: name='%s'", (required ? "" : "-not-required"), 5752c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski ResTable::normalizeForOutput(featureName.string()).string()); 576694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski 577694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski if (version > 0) { 578694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski printf(" version='%d'", version); 579694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski } 580694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski printf("\n"); 5812c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 5822c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 5832c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski const size_t numImpliedFeatures = 5842c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski (impliedFeatures != NULL) ? impliedFeatures->size() : 0; 5852c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski for (size_t i = 0; i < numImpliedFeatures; i++) { 5862c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski const ImpliedFeature& impliedFeature = impliedFeatures->valueAt(i); 5872c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (grp.features.indexOfKey(impliedFeature.name) >= 0) { 5882c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski // The feature is explicitly set, no need to use implied 5892c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski // definition. 5902c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski continue; 5912c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 5922c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 5932c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski String8 printableFeatureName(ResTable::normalizeForOutput( 5942c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski impliedFeature.name.string())); 5955f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski const char* sdk23Suffix = impliedFeature.impliedBySdk23 ? "-sdk-23" : ""; 5965f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski 5975f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski printf(" uses-feature%s: name='%s'\n", sdk23Suffix, printableFeatureName.string()); 5985f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski printf(" uses-implied-feature%s: name='%s' reason='", sdk23Suffix, 5995f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski printableFeatureName.string()); 6002c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski const size_t numReasons = impliedFeature.reasons.size(); 6012c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski for (size_t j = 0; j < numReasons; j++) { 6022c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski printf("%s", impliedFeature.reasons[j].string()); 6032c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (j + 2 < numReasons) { 6042c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski printf(", "); 6052c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } else if (j + 1 < numReasons) { 6062c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski printf(", and "); 6072c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 6082c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 6092c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski printf("'\n"); 6102c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 6112c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski} 6122c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 6135f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinskistatic void printFeatureGroup(const FeatureGroup& grp) { 6145f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski printFeatureGroupImpl(grp, NULL); 6155f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski} 6165f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski 6175f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinskistatic void printDefaultFeatureGroup(const FeatureGroup& grp, 6185f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski const KeyedVector<String8, ImpliedFeature>& impliedFeatures) { 6195f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski printFeatureGroupImpl(grp, &impliedFeatures); 6205f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski} 6215f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski 6222c72b6822debb08fe997926eedc110f62d287d34Adam Lesinskistatic void addParentFeatures(FeatureGroup* grp, const String8& name) { 6232c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (name == "android.hardware.camera.autofocus" || 6242c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski name == "android.hardware.camera.flash") { 625694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski grp->features.add(String8("android.hardware.camera"), Feature(true)); 6262c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } else if (name == "android.hardware.location.gps" || 6272c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski name == "android.hardware.location.network") { 628694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski grp->features.add(String8("android.hardware.location"), Feature(true)); 629ca955a4c3ab3d4b83c6e9d5278bcd8d2258d44adAdam Lesinski } else if (name == "android.hardware.faketouch.multitouch") { 630ca955a4c3ab3d4b83c6e9d5278bcd8d2258d44adAdam Lesinski grp->features.add(String8("android.hardware.faketouch"), Feature(true)); 631ca955a4c3ab3d4b83c6e9d5278bcd8d2258d44adAdam Lesinski } else if (name == "android.hardware.faketouch.multitouch.distinct" || 632ca955a4c3ab3d4b83c6e9d5278bcd8d2258d44adAdam Lesinski name == "android.hardware.faketouch.multitouch.jazzhands") { 633ca955a4c3ab3d4b83c6e9d5278bcd8d2258d44adAdam Lesinski grp->features.add(String8("android.hardware.faketouch.multitouch"), Feature(true)); 634ca955a4c3ab3d4b83c6e9d5278bcd8d2258d44adAdam Lesinski grp->features.add(String8("android.hardware.faketouch"), Feature(true)); 6352c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } else if (name == "android.hardware.touchscreen.multitouch") { 636694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski grp->features.add(String8("android.hardware.touchscreen"), Feature(true)); 637ca955a4c3ab3d4b83c6e9d5278bcd8d2258d44adAdam Lesinski } else if (name == "android.hardware.touchscreen.multitouch.distinct" || 638ca955a4c3ab3d4b83c6e9d5278bcd8d2258d44adAdam Lesinski name == "android.hardware.touchscreen.multitouch.jazzhands") { 639694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski grp->features.add(String8("android.hardware.touchscreen.multitouch"), Feature(true)); 640694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski grp->features.add(String8("android.hardware.touchscreen"), Feature(true)); 641d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski } else if (name == "android.hardware.opengles.aep") { 642d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski const int openGLESVersion31 = 0x00030001; 643d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski if (openGLESVersion31 > grp->openGLESVersion) { 644d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski grp->openGLESVersion = openGLESVersion31; 645d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski } 6462c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 6472c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski} 6482c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 6495f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinskistatic void addImpliedFeaturesForPermission(const int targetSdk, const String8& name, 6505f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski KeyedVector<String8, ImpliedFeature>* impliedFeatures, 6515f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski bool impliedBySdk23Permission) { 6525f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski if (name == "android.permission.CAMERA") { 6535f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski addImpliedFeature(impliedFeatures, "android.hardware.camera", 65443158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski String8::format("requested %s permission", name.string()), 65543158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski impliedBySdk23Permission); 6565f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } else if (name == "android.permission.ACCESS_FINE_LOCATION") { 65743158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski if (targetSdk < SDK_LOLLIPOP) { 65843158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski addImpliedFeature(impliedFeatures, "android.hardware.location.gps", 65943158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski String8::format("requested %s permission", name.string()), 66043158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski impliedBySdk23Permission); 66143158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski addImpliedFeature(impliedFeatures, "android.hardware.location.gps", 66243158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski String8::format("targetSdkVersion < %d", SDK_LOLLIPOP), 66343158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski impliedBySdk23Permission); 66443158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski } 6655f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski addImpliedFeature(impliedFeatures, "android.hardware.location", 66643158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski String8::format("requested %s permission", name.string()), 66743158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski impliedBySdk23Permission); 6685f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } else if (name == "android.permission.ACCESS_COARSE_LOCATION") { 66943158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski if (targetSdk < SDK_LOLLIPOP) { 67043158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski addImpliedFeature(impliedFeatures, "android.hardware.location.network", 67143158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski String8::format("requested %s permission", name.string()), 67243158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski impliedBySdk23Permission); 67343158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski addImpliedFeature(impliedFeatures, "android.hardware.location.network", 67443158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski String8::format("targetSdkVersion < %d", SDK_LOLLIPOP), 67543158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski impliedBySdk23Permission); 67643158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski } 6775f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski addImpliedFeature(impliedFeatures, "android.hardware.location", 67843158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski String8::format("requested %s permission", name.string()), 67943158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski impliedBySdk23Permission); 68043158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski } else if (name == "android.permission.ACCESS_MOCK_LOCATION" || 68143158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski name == "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" || 6825f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski name == "android.permission.INSTALL_LOCATION_PROVIDER") { 6835f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski addImpliedFeature(impliedFeatures, "android.hardware.location", 68443158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski String8::format("requested %s permission", name.string()), 68543158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski impliedBySdk23Permission); 6865f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } else if (name == "android.permission.BLUETOOTH" || 6875f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski name == "android.permission.BLUETOOTH_ADMIN") { 68843158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski if (targetSdk > SDK_DONUT) { 6895f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski addImpliedFeature(impliedFeatures, "android.hardware.bluetooth", 69043158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski String8::format("requested %s permission", name.string()), 69143158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski impliedBySdk23Permission); 6925f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski addImpliedFeature(impliedFeatures, "android.hardware.bluetooth", 69343158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski String8::format("targetSdkVersion > %d", SDK_DONUT), 69443158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski impliedBySdk23Permission); 6955f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } 6965f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } else if (name == "android.permission.RECORD_AUDIO") { 6975f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski addImpliedFeature(impliedFeatures, "android.hardware.microphone", 69843158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski String8::format("requested %s permission", name.string()), 69943158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski impliedBySdk23Permission); 7005f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } else if (name == "android.permission.ACCESS_WIFI_STATE" || 7015f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski name == "android.permission.CHANGE_WIFI_STATE" || 7025f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski name == "android.permission.CHANGE_WIFI_MULTICAST_STATE") { 7035f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski addImpliedFeature(impliedFeatures, "android.hardware.wifi", 70443158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski String8::format("requested %s permission", name.string()), 70543158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski impliedBySdk23Permission); 7065f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } else if (name == "android.permission.CALL_PHONE" || 7075f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski name == "android.permission.CALL_PRIVILEGED" || 7085f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski name == "android.permission.MODIFY_PHONE_STATE" || 7095f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski name == "android.permission.PROCESS_OUTGOING_CALLS" || 7105f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski name == "android.permission.READ_SMS" || 7115f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski name == "android.permission.RECEIVE_SMS" || 7125f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski name == "android.permission.RECEIVE_MMS" || 7135f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski name == "android.permission.RECEIVE_WAP_PUSH" || 7145f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski name == "android.permission.SEND_SMS" || 7155f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski name == "android.permission.WRITE_APN_SETTINGS" || 7165f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski name == "android.permission.WRITE_SMS") { 7175f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski addImpliedFeature(impliedFeatures, "android.hardware.telephony", 71843158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski String8("requested a telephony permission"), 71943158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski impliedBySdk23Permission); 7205f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } 7215f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski} 7225f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski 723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Handle the "dump" command, to extract select data from an archive. 725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiextern char CONSOLE_DATA[2925]; // see EOF 727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doDump(Bundle* bundle) 728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result = UNKNOWN_ERROR; 730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 1) { 732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: no dump option specified\n"); 733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 1; 734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 2) { 737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: no dump file specified\n"); 738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 1; 739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* option = bundle->getFileSpecEntry(0); 742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* filename = bundle->getFileSpecEntry(1); 743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AssetManager assets; 745f85e41f29a0e9313c2d4725f9d9648591ea49f3bNarayan Kamath int32_t assetsCookie; 746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!assets.addAssetPath(String8(filename), &assetsCookie)) { 747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: dump failed because assets could not be loaded\n"); 748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 1; 749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Make a dummy config for retrieving resources... we need to supply 752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // non-default values for some configs so that we can retrieve resources 753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // in the app that don't have a default. The most important of these is 754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the API version because key resources like icons will have an implicit 755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // version if they are using newer config types like density. 756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_config config; 75791447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath memset(&config, 0, sizeof(ResTable_config)); 758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.language[0] = 'e'; 759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.language[1] = 'n'; 760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.country[0] = 'U'; 761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.country[1] = 'S'; 762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.orientation = ResTable_config::ORIENTATION_PORT; 763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.density = ResTable_config::DENSITY_MEDIUM; 764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.sdkVersion = 10000; // Very high. 765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.screenWidthDp = 320; 766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.screenHeightDp = 480; 767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.smallestScreenWidthDp = 320; 768c2dea8daea2ae0001d56689d96ce1066012b7b40Adam Lesinski config.screenLayout |= ResTable_config::SCREENSIZE_NORMAL; 769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets.setConfiguration(config); 770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable& res = assets.getResources(false); 7726800165351b693fa7e4bcf0f205655f0cd16b361Dan Albert if (res.getError() != NO_ERROR) { 77325e9d55e964c180ec6e57ba1d977d6c2e1115f5aAdam Lesinski fprintf(stderr, "ERROR: dump failed because the resource table is invalid/corrupt.\n"); 77463e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski return 1; 77563e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski } 77663e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski 777694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski // Source for AndroidManifest.xml 778694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski const String8 manifestFile = String8::format("%s@AndroidManifest.xml", filename); 779694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski 7802cb761e3ddb9d68ab430013e9cd15ecaab9fbc62Adam Lesinski // The dynamicRefTable can be null if there are no resources for this asset cookie. 7812cb761e3ddb9d68ab430013e9cd15ecaab9fbc62Adam Lesinski // This fine. 78263e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski const DynamicRefTable* dynamicRefTable = res.getDynamicRefTableForCookie(assetsCookie); 783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 78463e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski Asset* asset = NULL; 78563e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski 786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp("resources", option) == 0) { 787ba3fe56edc1da4dad0d831a1892e7b1c3c20c437Elliott Hughes#ifndef __ANDROID__ 788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res.print(bundle->getValues()); 789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("strings", option) == 0) { 792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResStringPool* pool = res.getTableStringBlock(0); 793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printStringPool(pool); 794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("xmltree", option) == 0) { 796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 3) { 797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: no dump xmltree resource file specified\n"); 798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i=2; i<bundle->getFileSpecCount(); i++) { 802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* resname = bundle->getFileSpecEntry(i); 80363e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski ResXMLTree tree(dynamicRefTable); 80463e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski asset = assets.openNonAsset(assetsCookie, resname, Asset::ACCESS_BUFFER); 805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (asset == NULL) { 806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: dump failed because resource %s found\n", resname); 807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.setTo(asset->getBuffer(true), 811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset->getLength()) != NO_ERROR) { 812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: Resource %s is corrupt\n", resname); 813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tree.restart(); 816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printXMLBlock(&tree); 817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tree.uninit(); 818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete asset; 819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset = NULL; 820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("xmlstrings", option) == 0) { 823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 3) { 824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: no dump xmltree resource file specified\n"); 825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i=2; i<bundle->getFileSpecCount(); i++) { 829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* resname = bundle->getFileSpecEntry(i); 83063e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski asset = assets.openNonAsset(assetsCookie, resname, Asset::ACCESS_BUFFER); 831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (asset == NULL) { 832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: dump failed because resource %s found\n", resname); 833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 83663e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski ResXMLTree tree(dynamicRefTable); 837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.setTo(asset->getBuffer(true), 838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset->getLength()) != NO_ERROR) { 839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: Resource %s is corrupt\n", resname); 840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printStringPool(&tree.getStrings()); 843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete asset; 844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset = NULL; 845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 84863e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski asset = assets.openNonAsset(assetsCookie, "AndroidManifest.xml", Asset::ACCESS_BUFFER); 849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (asset == NULL) { 850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: dump failed because no AndroidManifest.xml found\n"); 851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 85463e646eed5a8d7f5d04544ac8628f65b0173cf3aAdam Lesinski ResXMLTree tree(dynamicRefTable); 855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.setTo(asset->getBuffer(true), 856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset->getLength()) != NO_ERROR) { 857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: AndroidManifest.xml is corrupt\n"); 858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tree.restart(); 861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp("permissions", option) == 0) { 863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int depth = 0; 8665f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && 8675f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski code != ResXMLTree::BAD_DOCUMENT) { 868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth--; 870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 872282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != ResXMLTree::START_TAG) { 873282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 874282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 875282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth++; 8769cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski const char16_t* ctag16 = tree.getElementName(&len); 8779cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski if (ctag16 == NULL) { 8789cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski fprintf(stderr, "ERROR: failed to get XML element name (bad string pool)\n"); 8799cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski goto bail; 8809cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski } 8819cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski String8 tag(ctag16); 882282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Depth %d tag %s\n", depth, tag.string()); 883282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (depth == 1) { 884282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag != "manifest") { 885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: manifest does not start with <manifest> tag\n"); 886282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 887282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 888ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 pkg = AaptXml::getAttribute(tree, NULL, "package", NULL); 8892675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("package: %s\n", ResTable::normalizeForOutput(pkg.string()).string()); 8905f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } else if (depth == 2) { 8915f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski if (tag == "permission") { 8925f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski String8 error; 8935f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); 8945f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski if (error != "") { 8955f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski fprintf(stderr, "ERROR: %s\n", error.string()); 8965f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski goto bail; 8975f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } 8985f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski 8995f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski if (name == "") { 9005f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski fprintf(stderr, "ERROR: missing 'android:name' for permission\n"); 9015f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski goto bail; 9025f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } 9035f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski printf("permission: %s\n", 9045f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski ResTable::normalizeForOutput(name.string()).string()); 9055f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } else if (tag == "uses-permission") { 9065f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski String8 error; 9075f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); 9085f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski if (error != "") { 9095f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski fprintf(stderr, "ERROR: %s\n", error.string()); 9105f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski goto bail; 9115f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } 9125f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski 9135f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski if (name == "") { 9145f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski fprintf(stderr, "ERROR: missing 'android:name' for uses-permission\n"); 9155f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski goto bail; 9165f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } 9175f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski printUsesPermission(name, 9185f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski AaptXml::getIntegerAttribute(tree, REQUIRED_ATTR, 1) == 0, 9195f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski AaptXml::getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR)); 9205f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } else if (tag == "uses-permission-sdk-23" || tag == "uses-permission-sdk-m") { 9215f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski String8 error; 9225f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); 9235f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski if (error != "") { 9245f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski fprintf(stderr, "ERROR: %s\n", error.string()); 9255f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski goto bail; 9265f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } 9275f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski 9285f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski if (name == "") { 9295f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski fprintf(stderr, "ERROR: missing 'android:name' for " 9305f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski "uses-permission-sdk-23\n"); 9315f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski goto bail; 9325f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } 9335f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski printUsesPermissionSdk23( 9345f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski name, 9355f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski AaptXml::getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR)); 936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 937282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 938282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("badging", option) == 0) { 940282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<String8> locales; 941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res.getLocales(&locales); 942282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<ResTable_config> configs; 944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res.getConfigurations(&configs); 945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SortedVector<int> densities; 946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NC = configs.size(); 947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<NC; i++) { 948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int dens = configs[i].density; 949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (dens == 0) { 950282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dens = 160; 951282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski densities.add(dens); 953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int depth = 0; 958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 error; 959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool withinActivity = false; 960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isMainActivity = false; 961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isLauncherActivity = false; 9620a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn bool isLeanbackLauncherActivity = false; 963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isSearchable = false; 964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool withinApplication = false; 965ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright bool withinSupportsInput = false; 9662c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski bool withinFeatureGroup = false; 967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool withinReceiver = false; 968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool withinService = false; 9699d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool withinProvider = false; 970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool withinIntentFilter = false; 971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasMainActivity = false; 972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasOtherActivities = false; 973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasOtherReceivers = false; 974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasOtherServices = false; 9759d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool hasIntentFilter = false; 9769d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski 977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasWallpaperService = false; 978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasImeService = false; 979a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool hasAccessibilityService = false; 980a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool hasPrintService = false; 981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasWidgetReceivers = false; 982a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool hasDeviceAdminReceiver = false; 98394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool hasPaymentService = false; 9849d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool hasDocumentsProvider = false; 9859d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool hasCameraActivity = false; 9869d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool hasCameraSecureActivity = false; 9879d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool hasLauncher = false; 9889d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool hasNotificationListenerService = false; 989eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock bool hasDreamService = false; 9909d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski 991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool actMainActivity = false; 992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool actWidgetReceivers = false; 993a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool actDeviceAdminEnabled = false; 994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool actImeService = false; 995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool actWallpaperService = false; 996a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool actAccessibilityService = false; 997a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool actPrintService = false; 99894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool actHostApduService = false; 99994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool actOffHostApduService = false; 10009d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool actDocumentsProvider = false; 10019d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool actNotificationListenerService = false; 1002eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock bool actDreamService = false; 10039d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool actCamera = false; 10049d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool actCameraSecure = false; 10059d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool catLauncher = false; 100694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool hasMetaHostPaymentCategory = false; 100794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool hasMetaOffHostPaymentCategory = false; 1008a5018c900f126ee8424c82497f32983873db741bAdam Lesinski 1009a5018c900f126ee8424c82497f32983873db741bAdam Lesinski // These permissions are required by services implementing services 1010a5018c900f126ee8424c82497f32983873db741bAdam Lesinski // the system binds to (IME, Accessibility, PrintServices, etc.) 1011a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool hasBindDeviceAdminPermission = false; 1012a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool hasBindInputMethodPermission = false; 1013a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool hasBindAccessibilityServicePermission = false; 1014a5018c900f126ee8424c82497f32983873db741bAdam Lesinski bool hasBindPrintServicePermission = false; 101594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool hasBindNfcServicePermission = false; 10169d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool hasRequiredSafAttributes = false; 10179d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski bool hasBindNotificationListenerServicePermission = false; 1018eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock bool hasBindDreamServicePermission = false; 1019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // These two implement the implicit permissions that are granted 1021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // to pre-1.6 applications. 1022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasWriteExternalStoragePermission = false; 1023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasReadPhoneStatePermission = false; 1024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If an app requests write storage, they will also get read storage. 1026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasReadExternalStoragePermission = false; 1027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Implement transition to read and write call log. 1029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasReadContactsPermission = false; 1030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasWriteContactsPermission = false; 1031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasReadCallLogPermission = false; 1032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasWriteCallLogPermission = false; 1033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1034e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // If an app declares itself as multiArch, we report the 1035e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // native libraries differently. 1036e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski bool hasMultiArch = false; 1037e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski 1038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // This next group of variables is used to implement a group of 1039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // backward-compatibility heuristics necessitated by the addition of 1040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // some new uses-feature constants in 2.1 and 2.2. In most cases, the 1041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // heuristic is "if an app requests a permission but doesn't explicitly 1042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // request the corresponding <uses-feature>, presume it's there anyway". 10432c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 1044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // 2.2 also added some other features that apps can request, but that 1045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // have no corresponding permission, so we cannot implement any 1046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // back-compatibility heuristic for them. The below are thus unnecessary 1047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // (but are retained here for documentary purposes.) 1048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //bool specCompassFeature = false; 1049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //bool specAccelerometerFeature = false; 1050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //bool specProximityFeature = false; 1051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //bool specAmbientLightFeature = false; 1052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //bool specLiveWallpaperFeature = false; 1053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int targetSdk = 0; 1055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int smallScreen = 1; 1056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int normalScreen = 1; 1057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int largeScreen = 1; 1058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int xlargeScreen = 1; 1059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int anyDensity = 1; 1060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int requiresSmallestWidthDp = 0; 1061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int compatibleWidthLimitDp = 0; 1062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int largestWidthLimitDp = 0; 1063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 pkg; 1064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 activityName; 1065282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 activityLabel; 1066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 activityIcon; 10670a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn String8 activityBanner; 1068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 receiverName; 1069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 serviceName; 1070ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright Vector<String8> supportedInput; 10712c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 10722c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski FeatureGroup commonFeatures; 10732c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski Vector<FeatureGroup> featureGroups; 10742c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski KeyedVector<String8, ImpliedFeature> impliedFeatures; 10752c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 10765f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && 10775f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski code != ResXMLTree::BAD_DOCUMENT) { 1078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 1079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth--; 1080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (depth < 2) { 1081ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (withinSupportsInput && !supportedInput.isEmpty()) { 1082ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright printf("supports-input: '"); 1083ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright const size_t N = supportedInput.size(); 1084ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright for (size_t i=0; i<N; i++) { 10852675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("%s", ResTable::normalizeForOutput( 10862675f769673f69b0661ddee346292f25cb30a296Maurice Chu supportedInput[i].string()).string()); 1087ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (i != N - 1) { 1088ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright printf("' '"); 1089ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else { 1090ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright printf("'\n"); 1091ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1092ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1093ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright supportedInput.clear(); 1094ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinApplication = false; 1096ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright withinSupportsInput = false; 10972c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski withinFeatureGroup = false; 1098282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (depth < 3) { 10990a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn if (withinActivity && isMainActivity) { 11002675f769673f69b0661ddee346292f25cb30a296Maurice Chu String8 aName(getComponentName(pkg, activityName)); 11010a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn if (isLauncherActivity) { 11020a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn printf("launchable-activity:"); 11039eaaaf0fe3917f4fec85d3e45da37914654847ecTim Kilbourn if (aName.length() > 0) { 11049eaaaf0fe3917f4fec85d3e45da37914654847ecTim Kilbourn printf(" name='%s' ", 11059eaaaf0fe3917f4fec85d3e45da37914654847ecTim Kilbourn ResTable::normalizeForOutput(aName.string()).string()); 11060a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn } 11070a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn printf(" label='%s' icon='%s'\n", 11085f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski ResTable::normalizeForOutput(activityLabel.string()) 11095f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski .string(), 11105f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski ResTable::normalizeForOutput(activityIcon.string()) 11115f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski .string()); 11120a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn } 11130a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn if (isLeanbackLauncherActivity) { 11140a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn printf("leanback-launchable-activity:"); 11159eaaaf0fe3917f4fec85d3e45da37914654847ecTim Kilbourn if (aName.length() > 0) { 11169eaaaf0fe3917f4fec85d3e45da37914654847ecTim Kilbourn printf(" name='%s' ", 11179eaaaf0fe3917f4fec85d3e45da37914654847ecTim Kilbourn ResTable::normalizeForOutput(aName.string()).string()); 11180a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn } 11190a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn printf(" label='%s' icon='%s' banner='%s'\n", 11205f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski ResTable::normalizeForOutput(activityLabel.string()) 11215f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski .string(), 11225f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski ResTable::normalizeForOutput(activityIcon.string()) 11235f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski .string(), 11245f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski ResTable::normalizeForOutput(activityBanner.string()) 11255f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski .string()); 1126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasIntentFilter) { 1129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasOtherActivities |= withinActivity; 1130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasOtherReceivers |= withinReceiver; 1131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasOtherServices |= withinService; 113294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else { 113394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (withinService) { 113494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasPaymentService |= (actHostApduService && hasMetaHostPaymentCategory && 113594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindNfcServicePermission); 113694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasPaymentService |= (actOffHostApduService && hasMetaOffHostPaymentCategory && 113794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindNfcServicePermission); 113894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 1139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinActivity = false; 1141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinService = false; 1142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinReceiver = false; 11439d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski withinProvider = false; 1144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasIntentFilter = false; 11450a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn isMainActivity = isLauncherActivity = isLeanbackLauncherActivity = false; 1146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (depth < 4) { 1147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (withinIntentFilter) { 1148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (withinActivity) { 1149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasMainActivity |= actMainActivity; 11509d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasLauncher |= catLauncher; 11519d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasCameraActivity |= actCamera; 11529d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasCameraSecureActivity |= actCameraSecure; 11535f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski hasOtherActivities |= 11545f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski !actMainActivity && !actCamera && !actCameraSecure; 1155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (withinReceiver) { 1156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWidgetReceivers |= actWidgetReceivers; 1157a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasDeviceAdminReceiver |= (actDeviceAdminEnabled && 1158a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasBindDeviceAdminPermission); 11595f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski hasOtherReceivers |= 11605f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski (!actWidgetReceivers && !actDeviceAdminEnabled); 1161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (withinService) { 1162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasImeService |= actImeService; 1163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWallpaperService |= actWallpaperService; 1164a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasAccessibilityService |= (actAccessibilityService && 1165a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasBindAccessibilityServicePermission); 11665f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski hasPrintService |= 11675f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski (actPrintService && hasBindPrintServicePermission); 11689d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasNotificationListenerService |= actNotificationListenerService && 11699d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasBindNotificationListenerServicePermission; 1170eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock hasDreamService |= actDreamService && hasBindDreamServicePermission; 1171a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasOtherServices |= (!actImeService && !actWallpaperService && 117294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski !actAccessibilityService && !actPrintService && 11739d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski !actHostApduService && !actOffHostApduService && 11749d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski !actNotificationListenerService); 11759d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } else if (withinProvider) { 11765f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski hasDocumentsProvider |= 11775f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski actDocumentsProvider && hasRequiredSafAttributes; 1178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinIntentFilter = false; 1181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != ResXMLTree::START_TAG) { 1185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth++; 11889cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski 11899cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski const char16_t* ctag16 = tree.getElementName(&len); 11909cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski if (ctag16 == NULL) { 11919cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski fprintf(stderr, "ERROR: failed to get XML element name (bad string pool)\n"); 11929cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski goto bail; 11939cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski } 11949cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski String8 tag(ctag16); 1195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Depth %d, %s\n", depth, tag.string()); 1196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (depth == 1) { 1197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag != "manifest") { 1198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: manifest does not start with <manifest> tag\n"); 1199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1201ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski pkg = AaptXml::getAttribute(tree, NULL, "package", NULL); 12022675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("package: name='%s' ", 12032675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(pkg.string()).string()); 1204ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int32_t versionCode = AaptXml::getIntegerAttribute(tree, VERSION_CODE_ATTR, 1205ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski &error); 1206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1207ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski fprintf(stderr, "ERROR getting 'android:versionCode' attribute: %s\n", 1208ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski error.string()); 1209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (versionCode > 0) { 1212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("versionCode='%d' ", versionCode); 1213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("versionCode='' "); 1215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1216ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 versionName = AaptXml::getResolvedAttribute(res, tree, 1217ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski VERSION_NAME_ATTR, &error); 1218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1219ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski fprintf(stderr, "ERROR getting 'android:versionName' attribute: %s\n", 1220ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski error.string()); 1221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 122325d35a9d68fed6304352d0bfc2e0d581ed47f8b5Adam Lesinski printf("versionName='%s'", 12242675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(versionName.string()).string()); 122525d35a9d68fed6304352d0bfc2e0d581ed47f8b5Adam Lesinski 1226ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 splitName = AaptXml::getAttribute(tree, NULL, "split"); 122725d35a9d68fed6304352d0bfc2e0d581ed47f8b5Adam Lesinski if (!splitName.isEmpty()) { 122825d35a9d68fed6304352d0bfc2e0d581ed47f8b5Adam Lesinski printf(" split='%s'", ResTable::normalizeForOutput( 122925d35a9d68fed6304352d0bfc2e0d581ed47f8b5Adam Lesinski splitName.string()).string()); 123025d35a9d68fed6304352d0bfc2e0d581ed47f8b5Adam Lesinski } 1231ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski 12325283faba4a75a4d1fd9990637d22768e423895e3Adam Lesinski String8 platformVersionName = AaptXml::getAttribute(tree, NULL, 12335283faba4a75a4d1fd9990637d22768e423895e3Adam Lesinski "platformBuildVersionName"); 12345283faba4a75a4d1fd9990637d22768e423895e3Adam Lesinski printf(" platformBuildVersionName='%s'", platformVersionName.string()); 123525d35a9d68fed6304352d0bfc2e0d581ed47f8b5Adam Lesinski printf("\n"); 1236caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski 1237ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int32_t installLocation = AaptXml::getResolvedIntegerAttribute(res, tree, 1238ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski INSTALL_LOCATION_ATTR, &error); 1239caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski if (error != "") { 1240caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski fprintf(stderr, "ERROR getting 'android:installLocation' attribute: %s\n", 1241caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski error.string()); 1242caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski goto bail; 1243caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski } 1244caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski 1245caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski if (installLocation >= 0) { 1246caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski printf("install-location:'"); 1247caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski switch (installLocation) { 1248caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski case 0: 1249caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski printf("auto"); 1250caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski break; 1251caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski case 1: 1252caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski printf("internalOnly"); 1253caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski break; 1254caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski case 2: 1255caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski printf("preferExternal"); 1256caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski break; 1257caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski default: 1258caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski fprintf(stderr, "Invalid installLocation %d\n", installLocation); 1259caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski goto bail; 1260caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski } 1261caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski printf("'\n"); 1262caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski } 1263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (depth == 2) { 1264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinApplication = false; 1265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag == "application") { 1266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinApplication = true; 1267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 label; 1269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NL = locales.size(); 1270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<NL; i++) { 1271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* localeStr = locales[i].string(); 1272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets.setLocale(localeStr != NULL ? localeStr : ""); 1273ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 llabel = AaptXml::getResolvedAttribute(res, tree, LABEL_ATTR, 1274ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski &error); 1275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (llabel != "") { 1276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (localeStr == NULL || strlen(localeStr) == 0) { 1277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski label = llabel; 12782675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("application-label:'%s'\n", 12792675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(llabel.string()).string()); 1280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (label == "") { 1282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski label = llabel; 1283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("application-label-%s:'%s'\n", localeStr, 12852675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(llabel.string()).string()); 1286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_config tmpConfig = config; 1291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t ND = densities.size(); 1292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<ND; i++) { 1293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tmpConfig.density = densities[i]; 1294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets.setConfiguration(tmpConfig); 1295ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 icon = AaptXml::getResolvedAttribute(res, tree, ICON_ATTR, 1296ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski &error); 1297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (icon != "") { 12982675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("application-icon-%d:'%s'\n", densities[i], 12992675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(icon.string()).string()); 1300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets.setConfiguration(config); 1303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1304ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 icon = AaptXml::getResolvedAttribute(res, tree, ICON_ATTR, &error); 1305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1306ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n", 1307ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski error.string()); 1308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1310ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int32_t testOnly = AaptXml::getIntegerAttribute(tree, TEST_ONLY_ATTR, 0, 1311ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski &error); 1312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1313ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski fprintf(stderr, "ERROR getting 'android:testOnly' attribute: %s\n", 1314ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski error.string()); 1315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1317d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn 13185f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski String8 banner = AaptXml::getResolvedAttribute(res, tree, BANNER_ATTR, 13195f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski &error); 1320d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn if (error != "") { 1321d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn fprintf(stderr, "ERROR getting 'android:banner' attribute: %s\n", 1322d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn error.string()); 1323d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn goto bail; 1324d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn } 13252675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("application: label='%s' ", 13262675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(label.string()).string()); 1327d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn printf("icon='%s'", ResTable::normalizeForOutput(icon.string()).string()); 1328d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn if (banner != "") { 13295f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski printf(" banner='%s'", 13305f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski ResTable::normalizeForOutput(banner.string()).string()); 1331d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn } 1332d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn printf("\n"); 1333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (testOnly != 0) { 1334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("testOnly='%d'\n", testOnly); 1335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1337d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn int32_t isGame = AaptXml::getResolvedIntegerAttribute(res, tree, 1338d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn ISGAME_ATTR, 0, &error); 1339d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn if (error != "") { 1340d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn fprintf(stderr, "ERROR getting 'android:isGame' attribute: %s\n", 1341d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn error.string()); 1342d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn goto bail; 1343d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn } 1344d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn if (isGame != 0) { 1345d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn printf("application-isGame\n"); 1346d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn } 1347d9b1cad71e8aaf94e7738d2e47d3a06daa3cdf2dTim Kilbourn 1348ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int32_t debuggable = AaptXml::getResolvedIntegerAttribute(res, tree, 1349ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski DEBUGGABLE_ATTR, 0, &error); 1350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1351ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski fprintf(stderr, "ERROR getting 'android:debuggable' attribute: %s\n", 1352ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski error.string()); 1353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (debuggable != 0) { 1356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("application-debuggable\n"); 1357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1358e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski 1359e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // We must search by name because the multiArch flag hasn't been API 1360e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // frozen yet. 1361e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski int32_t multiArchIndex = tree.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, 1362e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski "multiArch"); 1363e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski if (multiArchIndex >= 0) { 1364e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski Res_value value; 1365e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski if (tree.getAttributeValue(multiArchIndex, &value) != NO_ERROR) { 1366e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski if (value.dataType >= Res_value::TYPE_FIRST_INT && 1367e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski value.dataType <= Res_value::TYPE_LAST_INT) { 1368e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski hasMultiArch = value.data; 1369e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski } 1370e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski } 1371e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski } 1372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "uses-sdk") { 13735f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski int32_t code = AaptXml::getIntegerAttribute(tree, MIN_SDK_VERSION_ATTR, 13745f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski &error); 1375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error = ""; 1377ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 name = AaptXml::getResolvedAttribute(res, tree, 1378ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski MIN_SDK_VERSION_ATTR, &error); 1379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 13805f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski fprintf(stderr, 13815f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski "ERROR getting 'android:minSdkVersion' attribute: %s\n", 1382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 1383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name == "Donut") targetSdk = 4; 13862675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("sdkVersion:'%s'\n", 13872675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(name.string()).string()); 1388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (code != -1) { 1389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski targetSdk = code; 1390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("sdkVersion:'%d'\n", code); 1391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1392ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski code = AaptXml::getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR); 1393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != -1) { 1394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("maxSdkVersion:'%d'\n", code); 1395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1396ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski code = AaptXml::getIntegerAttribute(tree, TARGET_SDK_VERSION_ATTR, &error); 1397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error = ""; 1399ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 name = AaptXml::getResolvedAttribute(res, tree, 1400ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski TARGET_SDK_VERSION_ATTR, &error); 1401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 14025f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski fprintf(stderr, 14035f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski "ERROR getting 'android:targetSdkVersion' attribute: %s\n", 1404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 1405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name == "Donut" && targetSdk < 4) targetSdk = 4; 14082675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("targetSdkVersion:'%s'\n", 14092675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(name.string()).string()); 1410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (code != -1) { 1411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (targetSdk < code) { 1412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski targetSdk = code; 1413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("targetSdkVersion:'%d'\n", code); 1415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "uses-configuration") { 1417ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int32_t reqTouchScreen = AaptXml::getIntegerAttribute(tree, 1418ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski REQ_TOUCH_SCREEN_ATTR, 0); 1419ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int32_t reqKeyboardType = AaptXml::getIntegerAttribute(tree, 1420ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski REQ_KEYBOARD_TYPE_ATTR, 0); 1421ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int32_t reqHardKeyboard = AaptXml::getIntegerAttribute(tree, 1422ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski REQ_HARD_KEYBOARD_ATTR, 0); 1423ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int32_t reqNavigation = AaptXml::getIntegerAttribute(tree, 1424ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski REQ_NAVIGATION_ATTR, 0); 1425ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int32_t reqFiveWayNav = AaptXml::getIntegerAttribute(tree, 1426ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski REQ_FIVE_WAY_NAV_ATTR, 0); 1427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-configuration:"); 1428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqTouchScreen != 0) { 1429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" reqTouchScreen='%d'", reqTouchScreen); 1430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqKeyboardType != 0) { 1432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" reqKeyboardType='%d'", reqKeyboardType); 1433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqHardKeyboard != 0) { 1435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" reqHardKeyboard='%d'", reqHardKeyboard); 1436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqNavigation != 0) { 1438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" reqNavigation='%d'", reqNavigation); 1439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqFiveWayNav != 0) { 1441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" reqFiveWayNav='%d'", reqFiveWayNav); 1442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 1444ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (tag == "supports-input") { 1445ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright withinSupportsInput = true; 1446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "supports-screens") { 1447ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski smallScreen = AaptXml::getIntegerAttribute(tree, 1448ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski SMALL_SCREEN_ATTR, 1); 1449ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski normalScreen = AaptXml::getIntegerAttribute(tree, 1450ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski NORMAL_SCREEN_ATTR, 1); 1451ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski largeScreen = AaptXml::getIntegerAttribute(tree, 1452ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski LARGE_SCREEN_ATTR, 1); 1453ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski xlargeScreen = AaptXml::getIntegerAttribute(tree, 1454ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski XLARGE_SCREEN_ATTR, 1); 1455ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski anyDensity = AaptXml::getIntegerAttribute(tree, 1456ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski ANY_DENSITY_ATTR, 1); 1457ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski requiresSmallestWidthDp = AaptXml::getIntegerAttribute(tree, 1458ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski REQUIRES_SMALLEST_WIDTH_DP_ATTR, 0); 1459ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski compatibleWidthLimitDp = AaptXml::getIntegerAttribute(tree, 1460ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski COMPATIBLE_WIDTH_LIMIT_DP_ATTR, 0); 1461ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski largestWidthLimitDp = AaptXml::getIntegerAttribute(tree, 1462ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski LARGEST_WIDTH_LIMIT_DP_ATTR, 0); 14632c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } else if (tag == "feature-group") { 14642c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski withinFeatureGroup = true; 14652c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski FeatureGroup group; 1466ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski group.label = AaptXml::getResolvedAttribute(res, tree, LABEL_ATTR, &error); 14672c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (error != "") { 14682c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski fprintf(stderr, "ERROR getting 'android:label' attribute:" 14692c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski " %s\n", error.string()); 14702c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski goto bail; 14712c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 14722c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski featureGroups.add(group); 14732c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 1474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "uses-feature") { 1475ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); 1476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 1477694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski const char* androidSchema = 1478694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski "http://schemas.android.com/apk/res/android"; 1479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1480694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski int32_t req = AaptXml::getIntegerAttribute(tree, REQUIRED_ATTR, 1, 1481694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski &error); 1482694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski if (error != "") { 1483694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski SourcePos(manifestFile, tree.getLineNumber()).error( 1484694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski "failed to read attribute 'android:required': %s", 1485694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski error.string()); 1486694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski goto bail; 1487694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski } 1488694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski 1489694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski int32_t version = AaptXml::getIntegerAttribute(tree, androidSchema, 1490694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski "version", 0, &error); 1491694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski if (error != "") { 1492694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski SourcePos(manifestFile, tree.getLineNumber()).error( 1493694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski "failed to read attribute 'android:version': %s", 1494694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski error.string()); 1495694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski goto bail; 1496694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski } 1497694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski 1498694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski commonFeatures.features.add(name, Feature(req != 0, version)); 14992c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (req) { 15002c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski addParentFeatures(&commonFeatures, name); 1501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1503ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int vers = AaptXml::getIntegerAttribute(tree, 1504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski GL_ES_VERSION_ATTR, &error); 1505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error == "") { 1506d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski if (vers > commonFeatures.openGLESVersion) { 1507d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski commonFeatures.openGLESVersion = vers; 1508d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski } 1509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "uses-permission") { 1512ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); 15135f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski if (error != "") { 15145f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 15155f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski error.string()); 15165f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski goto bail; 15175f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } 151858f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski 15195f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski if (name == "") { 15205f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski fprintf(stderr, "ERROR: missing 'android:name' for uses-permission\n"); 15215f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski goto bail; 15225f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } 15235f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski 15245f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski addImpliedFeaturesForPermission(targetSdk, name, &impliedFeatures, false); 15255f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski 15265f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski if (name == "android.permission.WRITE_EXTERNAL_STORAGE") { 15275f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski hasWriteExternalStoragePermission = true; 15285f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } else if (name == "android.permission.READ_EXTERNAL_STORAGE") { 15295f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski hasReadExternalStoragePermission = true; 15305f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } else if (name == "android.permission.READ_PHONE_STATE") { 15315f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski hasReadPhoneStatePermission = true; 15325f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } else if (name == "android.permission.READ_CONTACTS") { 15335f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski hasReadContactsPermission = true; 15345f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } else if (name == "android.permission.WRITE_CONTACTS") { 15355f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski hasWriteContactsPermission = true; 15365f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } else if (name == "android.permission.READ_CALL_LOG") { 15375f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski hasReadCallLogPermission = true; 15385f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } else if (name == "android.permission.WRITE_CALL_LOG") { 15395f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski hasWriteCallLogPermission = true; 15405f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } 15415f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski 15425f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski printUsesPermission(name, 15435f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski AaptXml::getIntegerAttribute(tree, REQUIRED_ATTR, 1) == 0, 15445f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski AaptXml::getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR)); 15455f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski 15465f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } else if (tag == "uses-permission-sdk-23" || tag == "uses-permission-sdk-m") { 15475f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); 15485f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski if (error != "") { 1549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 1551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 15535f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski 15545f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski if (name == "") { 15555f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski fprintf(stderr, "ERROR: missing 'android:name' for " 15565f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski "uses-permission-sdk-23\n"); 15575f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski goto bail; 15585f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } 15595f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski 15605f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski addImpliedFeaturesForPermission(targetSdk, name, &impliedFeatures, true); 15615f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski 15625f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski printUsesPermissionSdk23( 15635f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski name, AaptXml::getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR)); 15645f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski 1565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "uses-package") { 1566ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); 1567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 15682675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("uses-package:'%s'\n", 15692675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(name.string()).string()); 1570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 1573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "original-package") { 1576ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); 1577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 15782675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("original-package:'%s'\n", 15792675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(name.string()).string()); 1580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 1583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "supports-gl-texture") { 1586ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); 1587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 15882675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("supports-gl-texture:'%s'\n", 15892675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(name.string()).string()); 1590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 1593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "compatible-screens") { 15969cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski printCompatibleScreens(tree, &error); 15979cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski if (error != "") { 15989cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski fprintf(stderr, "ERROR getting compatible screens: %s\n", 15999cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski error.string()); 16009cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski goto bail; 16019cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski } 1602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth--; 1603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "package-verifier") { 1604ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); 1605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 16065f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski String8 publicKey = AaptXml::getAttribute(tree, PUBLIC_KEY_ATTR, 16075f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski &error); 1608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (publicKey != "" && error == "") { 1609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("package-verifier: name='%s' publicKey='%s'\n", 16102675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(name.string()).string(), 16112675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(publicKey.string()).string()); 1612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1615ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (depth == 3) { 1616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinActivity = false; 1617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinReceiver = false; 1618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinService = false; 16199d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski withinProvider = false; 1620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasIntentFilter = false; 162194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasMetaHostPaymentCategory = false; 162294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasMetaOffHostPaymentCategory = false; 162394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindDeviceAdminPermission = false; 162494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindInputMethodPermission = false; 162594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindAccessibilityServicePermission = false; 162694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindPrintServicePermission = false; 162794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindNfcServicePermission = false; 16289d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasRequiredSafAttributes = false; 16299d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasBindNotificationListenerServicePermission = false; 1630eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock hasBindDreamServicePermission = false; 1631ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (withinApplication) { 1632ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if(tag == "activity") { 1633ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright withinActivity = true; 1634ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski activityName = AaptXml::getAttribute(tree, NAME_ATTR, &error); 1635ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1636ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1637ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright error.string()); 1638ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1639ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1641ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski activityLabel = AaptXml::getResolvedAttribute(res, tree, LABEL_ATTR, 1642ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski &error); 1643ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1644ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:label' attribute: %s\n", 1645ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright error.string()); 1646ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1647ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1649ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski activityIcon = AaptXml::getResolvedAttribute(res, tree, ICON_ATTR, 1650ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski &error); 1651ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1652ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n", 1653ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright error.string()); 1654ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1655ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1657ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski activityBanner = AaptXml::getResolvedAttribute(res, tree, BANNER_ATTR, 1658ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski &error); 16590a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn if (error != "") { 16600a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn fprintf(stderr, "ERROR getting 'android:banner' attribute: %s\n", 16610a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn error.string()); 16620a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn goto bail; 16630a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn } 16640a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn 1665ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int32_t orien = AaptXml::getResolvedIntegerAttribute(res, tree, 1666ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright SCREEN_ORIENTATION_ATTR, &error); 1667ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error == "") { 1668ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (orien == 0 || orien == 6 || orien == 8) { 1669ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright // Requests landscape, sensorLandscape, or reverseLandscape. 167043158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski addImpliedFeature( 167143158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski &impliedFeatures, "android.hardware.screen.landscape", 167243158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski String8("one or more activities have specified a " 167343158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski "landscape orientation"), 167443158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski false); 1675ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (orien == 1 || orien == 7 || orien == 9) { 1676ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright // Requests portrait, sensorPortrait, or reversePortrait. 167743158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski addImpliedFeature( 167843158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski &impliedFeatures, "android.hardware.screen.portrait", 167943158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski String8("one or more activities have specified a " 168043158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski "portrait orientation"), 168143158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski false); 1682ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1684ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (tag == "uses-library") { 1685ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 libraryName = AaptXml::getAttribute(tree, NAME_ATTR, &error); 1686ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1687ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, 1688ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright "ERROR getting 'android:name' attribute for uses-library" 1689ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright " %s\n", error.string()); 1690ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1691ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1692ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int req = AaptXml::getIntegerAttribute(tree, 1693ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski REQUIRED_ATTR, 1); 1694ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright printf("uses-library%s:'%s'\n", 16952675f769673f69b0661ddee346292f25cb30a296Maurice Chu req ? "" : "-not-required", ResTable::normalizeForOutput( 16962675f769673f69b0661ddee346292f25cb30a296Maurice Chu libraryName.string()).string()); 1697ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (tag == "receiver") { 1698ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright withinReceiver = true; 1699ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski receiverName = AaptXml::getAttribute(tree, NAME_ATTR, &error); 1700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1701ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1702ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, 1703ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright "ERROR getting 'android:name' attribute for receiver:" 1704ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright " %s\n", error.string()); 1705ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1706ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1707a5018c900f126ee8424c82497f32983873db741bAdam Lesinski 1708ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 permission = AaptXml::getAttribute(tree, PERMISSION_ATTR, 1709ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski &error); 1710a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (error == "") { 1711a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (permission == "android.permission.BIND_DEVICE_ADMIN") { 1712a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasBindDeviceAdminPermission = true; 1713a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1714a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else { 17155f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski fprintf(stderr, 17165f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski "ERROR getting 'android:permission' attribute for" 17175f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski " receiver '%s': %s\n", 17185f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski receiverName.string(), error.string()); 1719a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1720ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (tag == "service") { 1721ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright withinService = true; 1722ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski serviceName = AaptXml::getAttribute(tree, NAME_ATTR, &error); 1723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1724ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1725ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:name' attribute for " 1726ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright "service:%s\n", error.string()); 1727ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1728ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1729a5018c900f126ee8424c82497f32983873db741bAdam Lesinski 1730ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 permission = AaptXml::getAttribute(tree, PERMISSION_ATTR, 1731ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski &error); 1732a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (error == "") { 1733a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (permission == "android.permission.BIND_INPUT_METHOD") { 1734a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasBindInputMethodPermission = true; 17355f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } else if (permission == 17365f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski "android.permission.BIND_ACCESSIBILITY_SERVICE") { 1737a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasBindAccessibilityServicePermission = true; 17385f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } else if (permission == 17395f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski "android.permission.BIND_PRINT_SERVICE") { 1740a5018c900f126ee8424c82497f32983873db741bAdam Lesinski hasBindPrintServicePermission = true; 17415f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } else if (permission == 17425f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski "android.permission.BIND_NFC_SERVICE") { 174394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasBindNfcServicePermission = true; 17445f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } else if (permission == 17455f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE") { 17469d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasBindNotificationListenerServicePermission = true; 1747eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock } else if (permission == "android.permission.BIND_DREAM_SERVICE") { 1748eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock hasBindDreamServicePermission = true; 1749a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1750a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else { 17515f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski fprintf(stderr, "ERROR getting 'android:permission' attribute for " 17525f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski "service '%s': %s\n", serviceName.string(), error.string()); 1753a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 17549d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } else if (tag == "provider") { 17559d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski withinProvider = true; 17569d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski 1757ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski bool exported = AaptXml::getResolvedIntegerAttribute(res, tree, 1758ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski EXPORTED_ATTR, &error); 17599d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (error != "") { 17605f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski fprintf(stderr, 17615f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski "ERROR getting 'android:exported' attribute for provider:" 17629d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski " %s\n", error.string()); 17639d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski goto bail; 17649d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 17659d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski 1766ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski bool grantUriPermissions = AaptXml::getResolvedIntegerAttribute( 1767ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski res, tree, GRANT_URI_PERMISSIONS_ATTR, &error); 17689d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (error != "") { 17695f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski fprintf(stderr, 17705f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski "ERROR getting 'android:grantUriPermissions' attribute for " 17715f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski "provider: %s\n", error.string()); 17729d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski goto bail; 17739d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 17749d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski 1775ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 permission = AaptXml::getResolvedAttribute(res, tree, 1776ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski PERMISSION_ATTR, &error); 17779d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (error != "") { 17785f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski fprintf(stderr, "ERROR getting 'android:permission' attribute for " 17795f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski "provider: %s\n", error.string()); 17809d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski goto bail; 17819d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 17829d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski 17839d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski hasRequiredSafAttributes |= exported && grantUriPermissions && 17849d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski permission == "android.permission.MANAGE_DOCUMENTS"; 17859d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski 1786ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (bundle->getIncludeMetaData() && tag == "meta-data") { 1787ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 metaDataName = AaptXml::getResolvedAttribute(res, tree, 1788ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski NAME_ATTR, &error); 1789ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1790ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:name' attribute for " 1791ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright "meta-data:%s\n", error.string()); 1792ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1793ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 17942675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf("meta-data: name='%s' ", 17952675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(metaDataName.string()).string()); 1796ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski printResolvedResourceAttribute(res, tree, VALUE_ATTR, String8("value"), 179776327314d2238e105f8b94909f9c0cf85caca318Maurice Chu &error); 1798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 179976327314d2238e105f8b94909f9c0cf85caca318Maurice Chu // Try looking for a RESOURCE_ATTR 180076327314d2238e105f8b94909f9c0cf85caca318Maurice Chu error = ""; 1801ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski printResolvedResourceAttribute(res, tree, RESOURCE_ATTR, 180276327314d2238e105f8b94909f9c0cf85caca318Maurice Chu String8("resource"), &error); 1803ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 180476327314d2238e105f8b94909f9c0cf85caca318Maurice Chu fprintf(stderr, "ERROR getting 'android:value' or " 180576327314d2238e105f8b94909f9c0cf85caca318Maurice Chu "'android:resource' attribute for " 180676327314d2238e105f8b94909f9c0cf85caca318Maurice Chu "meta-data:%s\n", error.string()); 1807ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1808ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1809ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 181076327314d2238e105f8b94909f9c0cf85caca318Maurice Chu printf("\n"); 1811ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (withinSupportsInput && tag == "input-type") { 1812ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); 1813ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (name != "" && error == "") { 1814ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright supportedInput.add(name); 1815ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else { 1816ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1817ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright error.string()); 1818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 18212c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } else if (withinFeatureGroup && tag == "uses-feature") { 1822694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski const String8 androidSchema("http://schemas.android.com/apk/res/android"); 1823d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski FeatureGroup& top = featureGroups.editTop(); 1824d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski 1825ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 name = AaptXml::getResolvedAttribute(res, tree, NAME_ATTR, &error); 1826d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski if (name != "" && error == "") { 1827694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski Feature feature(true); 1828694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski 1829694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski int32_t featureVers = AaptXml::getIntegerAttribute( 1830694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski tree, androidSchema.string(), "version", 0, &error); 1831694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski if (error == "") { 1832694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski feature.version = featureVers; 1833694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski } else { 1834694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski SourcePos(manifestFile, tree.getLineNumber()).error( 1835694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski "failed to read attribute 'android:version': %s", 1836694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski error.string()); 1837694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski goto bail; 1838694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski } 1839694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski 1840694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski top.features.add(name, feature); 1841d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski addParentFeatures(&top, name); 1842694d0a7dfd281060c9f8d92a79bda1b7071affe3Adam Lesinski 1843d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski } else { 1844ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int vers = AaptXml::getIntegerAttribute(tree, GL_ES_VERSION_ATTR, 1845ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski &error); 1846d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski if (error == "") { 1847d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski if (vers > top.openGLESVersion) { 1848d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski top.openGLESVersion = vers; 1849d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski } 1850d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski } 18512c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 1852a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 185394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else if (depth == 4) { 185494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (tag == "intent-filter") { 185594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasIntentFilter = true; 185694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski withinIntentFilter = true; 185794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actMainActivity = false; 185894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actWidgetReceivers = false; 185994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actImeService = false; 186094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actWallpaperService = false; 186194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actAccessibilityService = false; 186294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actPrintService = false; 186394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actDeviceAdminEnabled = false; 186494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actHostApduService = false; 186594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actOffHostApduService = false; 18669d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski actDocumentsProvider = false; 18679d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski actNotificationListenerService = false; 1868eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock actDreamService = false; 18699d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski actCamera = false; 18709d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski actCameraSecure = false; 18719d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski catLauncher = false; 187294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else if (withinService && tag == "meta-data") { 1873ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); 187494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (error != "") { 18755f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute for " 18765f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski "meta-data tag in service '%s': %s\n", serviceName.string(), 18775f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski error.string()); 187894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski goto bail; 187994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 188094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 188194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (name == "android.nfc.cardemulation.host_apdu_service" || 188294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski name == "android.nfc.cardemulation.off_host_apdu_service") { 188394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool offHost = true; 188494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (name == "android.nfc.cardemulation.host_apdu_service") { 188594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski offHost = false; 188694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 188794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 1888ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 xmlPath = AaptXml::getResolvedAttribute(res, tree, 1889ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski RESOURCE_ATTR, &error); 189094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (error != "") { 18915f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski fprintf(stderr, "ERROR getting 'android:resource' attribute for " 18925f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski "meta-data tag in service '%s': %s\n", 18935f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski serviceName.string(), error.string()); 189494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski goto bail; 189594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 189694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 189794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski Vector<String8> categories = getNfcAidCategories(assets, xmlPath, 189894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski offHost, &error); 189994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (error != "") { 190094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski fprintf(stderr, "ERROR getting AID category for service '%s'\n", 190194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski serviceName.string()); 190294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski goto bail; 190394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 190494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski 190594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski const size_t catLen = categories.size(); 190694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski for (size_t i = 0; i < catLen; i++) { 190794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski bool paymentCategory = (categories[i] == "payment"); 190894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (offHost) { 190994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasMetaOffHostPaymentCategory |= paymentCategory; 191094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } else { 191194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski hasMetaHostPaymentCategory |= paymentCategory; 191294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 191394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 191494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 191594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 1916a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if ((depth == 5) && withinIntentFilter) { 1917a5018c900f126ee8424c82497f32983873db741bAdam Lesinski String8 action; 1918a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (tag == "action") { 1919ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski action = AaptXml::getAttribute(tree, NAME_ATTR, &error); 1920a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (error != "") { 1921a5018c900f126ee8424c82497f32983873db741bAdam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1922a5018c900f126ee8424c82497f32983873db741bAdam Lesinski error.string()); 1923a5018c900f126ee8424c82497f32983873db741bAdam Lesinski goto bail; 1924a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1925a5018c900f126ee8424c82497f32983873db741bAdam Lesinski 1926a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (withinActivity) { 1927a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (action == "android.intent.action.MAIN") { 1928a5018c900f126ee8424c82497f32983873db741bAdam Lesinski isMainActivity = true; 1929a5018c900f126ee8424c82497f32983873db741bAdam Lesinski actMainActivity = true; 19309d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } else if (action == "android.media.action.STILL_IMAGE_CAMERA" || 19319d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski action == "android.media.action.VIDEO_CAMERA") { 19329d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski actCamera = true; 19339d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } else if (action == "android.media.action.STILL_IMAGE_CAMERA_SECURE") { 19349d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski actCameraSecure = true; 1935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1936a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if (withinReceiver) { 1937a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (action == "android.appwidget.action.APPWIDGET_UPDATE") { 1938a5018c900f126ee8424c82497f32983873db741bAdam Lesinski actWidgetReceivers = true; 1939a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if (action == "android.app.action.DEVICE_ADMIN_ENABLED") { 1940a5018c900f126ee8424c82497f32983873db741bAdam Lesinski actDeviceAdminEnabled = true; 1941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1942a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if (withinService) { 1943a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (action == "android.view.InputMethod") { 1944a5018c900f126ee8424c82497f32983873db741bAdam Lesinski actImeService = true; 1945a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } else if (action == "android.service.wallpaper.WallpaperService") { 1946a5018c900f126ee8424c82497f32983873db741bAdam Lesinski actWallpaperService = true; 19475f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } else if (action == 19485f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski "android.accessibilityservice.AccessibilityService") { 1949a5018c900f126ee8424c82497f32983873db741bAdam Lesinski actAccessibilityService = true; 19505f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } else if (action =="android.printservice.PrintService") { 1951a5018c900f126ee8424c82497f32983873db741bAdam Lesinski actPrintService = true; 19525f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } else if (action == 19535f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski "android.nfc.cardemulation.action.HOST_APDU_SERVICE") { 195494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actHostApduService = true; 19555f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } else if (action == 19565f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski "android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE") { 195794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski actOffHostApduService = true; 19585f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski } else if (action == 19595f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski "android.service.notification.NotificationListenerService") { 19609d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski actNotificationListenerService = true; 1961eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock } else if (action == "android.service.dreams.DreamService") { 1962eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock actDreamService = true; 19639d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 19649d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } else if (withinProvider) { 19659d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (action == "android.content.action.DOCUMENTS_PROVIDER") { 19669d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski actDocumentsProvider = true; 1967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1969a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (action == "android.intent.action.SEARCH") { 1970a5018c900f126ee8424c82497f32983873db741bAdam Lesinski isSearchable = true; 1971a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1972a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1974a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (tag == "category") { 1975ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 category = AaptXml::getAttribute(tree, NAME_ATTR, &error); 1976a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (error != "") { 1977a5018c900f126ee8424c82497f32983873db741bAdam Lesinski fprintf(stderr, "ERROR getting 'name' attribute: %s\n", 1978a5018c900f126ee8424c82497f32983873db741bAdam Lesinski error.string()); 1979a5018c900f126ee8424c82497f32983873db741bAdam Lesinski goto bail; 1980a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 1981a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (withinActivity) { 1982a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (category == "android.intent.category.LAUNCHER") { 1983a5018c900f126ee8424c82497f32983873db741bAdam Lesinski isLauncherActivity = true; 19840a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn } else if (category == "android.intent.category.LEANBACK_LAUNCHER") { 19850a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn isLeanbackLauncherActivity = true; 19869d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } else if (category == "android.intent.category.HOME") { 19879d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski catLauncher = true; 1988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Pre-1.6 implicitly granted permission compatibility logic 1995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (targetSdk < 4) { 1996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasWriteExternalStoragePermission) { 199758f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesPermission(String8("android.permission.WRITE_EXTERNAL_STORAGE")); 199858f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesImpliedPermission(String8("android.permission.WRITE_EXTERNAL_STORAGE"), 199958f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski String8("targetSdkVersion < 4")); 2000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWriteExternalStoragePermission = true; 2001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasReadPhoneStatePermission) { 200358f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesPermission(String8("android.permission.READ_PHONE_STATE")); 200458f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesImpliedPermission(String8("android.permission.READ_PHONE_STATE"), 200558f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski String8("targetSdkVersion < 4")); 2006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If the application has requested WRITE_EXTERNAL_STORAGE, we will 2010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // force them to always take READ_EXTERNAL_STORAGE as well. We always 2011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // do this (regardless of target API version) because we can't have 2012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // an app with write permission but not read permission. 2013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasReadExternalStoragePermission && hasWriteExternalStoragePermission) { 201458f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesPermission(String8("android.permission.READ_EXTERNAL_STORAGE")); 201558f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesImpliedPermission(String8("android.permission.READ_EXTERNAL_STORAGE"), 201658f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski String8("requested WRITE_EXTERNAL_STORAGE")); 2017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Pre-JellyBean call log permission compatibility. 2020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (targetSdk < 16) { 2021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasReadCallLogPermission && hasReadContactsPermission) { 202258f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesPermission(String8("android.permission.READ_CALL_LOG")); 202358f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesImpliedPermission(String8("android.permission.READ_CALL_LOG"), 202458f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski String8("targetSdkVersion < 16 and requested READ_CONTACTS")); 2025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasWriteCallLogPermission && hasWriteContactsPermission) { 202758f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesPermission(String8("android.permission.WRITE_CALL_LOG")); 202858f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski printUsesImpliedPermission(String8("android.permission.WRITE_CALL_LOG"), 202958f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski String8("targetSdkVersion < 16 and requested WRITE_CONTACTS")); 2030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2033ca955a4c3ab3d4b83c6e9d5278bcd8d2258d44adAdam Lesinski // If the app hasn't declared the touchscreen as a feature requirement (either 2034ca955a4c3ab3d4b83c6e9d5278bcd8d2258d44adAdam Lesinski // directly or implied, required or not), then the faketouch feature is implied. 2035ca955a4c3ab3d4b83c6e9d5278bcd8d2258d44adAdam Lesinski if (!hasFeature("android.hardware.touchscreen", commonFeatures, impliedFeatures)) { 2036ca955a4c3ab3d4b83c6e9d5278bcd8d2258d44adAdam Lesinski addImpliedFeature(&impliedFeatures, "android.hardware.faketouch", 203743158773b469c2d5b23e52998d0afba9a4b34323Adam Lesinski String8("default feature for all apps"), false); 2038ca955a4c3ab3d4b83c6e9d5278bcd8d2258d44adAdam Lesinski } 20392c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 20402c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski const size_t numFeatureGroups = featureGroups.size(); 20412c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (numFeatureGroups == 0) { 20422c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski // If no <feature-group> tags were defined, apply auto-implied features. 20435f3b2ecb3e9d27e77bd59c7b9006a6239b773944Adam Lesinski printDefaultFeatureGroup(commonFeatures, impliedFeatures); 20442c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 20452c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } else { 20462c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski // <feature-group> tags are defined, so we ignore implied features and 20472c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski for (size_t i = 0; i < numFeatureGroups; i++) { 20482c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski FeatureGroup& grp = featureGroups.editItemAt(i); 20492c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 2050d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski if (commonFeatures.openGLESVersion > grp.openGLESVersion) { 2051d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski grp.openGLESVersion = commonFeatures.openGLESVersion; 2052d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski } 2053d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski 20542c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski // Merge the features defined in the top level (not inside a <feature-group>) 20552c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski // with this feature group. 20562c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski const size_t numCommonFeatures = commonFeatures.features.size(); 20572c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski for (size_t j = 0; j < numCommonFeatures; j++) { 20582c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski if (grp.features.indexOfKey(commonFeatures.features.keyAt(j)) < 0) { 2059d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski grp.features.add(commonFeatures.features.keyAt(j), 2060d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski commonFeatures.features[j]); 20612c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 2062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 206473a05114b051c6dcf5e5126ac94eaf8cac0ab289Adam Lesinski if (!grp.features.isEmpty()) { 20652c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski printFeatureGroup(grp); 20662c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski } 2067282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 20702c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski 2071282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasWidgetReceivers) { 20729d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("app-widget"); 2073282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2074a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (hasDeviceAdminReceiver) { 20759d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("device-admin"); 2076a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 2077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasImeService) { 20789d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("ime"); 2079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasWallpaperService) { 20819d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("wallpaper"); 2082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2083a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (hasAccessibilityService) { 20849d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("accessibility"); 2085a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 2086a5018c900f126ee8424c82497f32983873db741bAdam Lesinski if (hasPrintService) { 20879d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("print-service"); 2088a5018c900f126ee8424c82497f32983873db741bAdam Lesinski } 208994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski if (hasPaymentService) { 20909d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("payment"); 20919d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 20929d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (isSearchable) { 20939d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("search"); 20949d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 20959d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (hasDocumentsProvider) { 20969d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("document-provider"); 20979d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 20989d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (hasLauncher) { 20999d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("launcher"); 21009d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 21019d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (hasNotificationListenerService) { 21029d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("notification-listener"); 21039d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 2104eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock if (hasDreamService) { 2105eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock printComponentPresence("dream"); 2106eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock } 21079d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (hasCameraActivity) { 21089d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("camera"); 21099d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 21109d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (hasCameraSecureActivity) { 21119d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printComponentPresence("camera-secure"); 21129d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski } 21139d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski 21149d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (hasMainActivity) { 21159d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski printf("main\n"); 211694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski } 2117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasOtherActivities) { 2118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("other-activities\n"); 2119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 21209d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski if (hasOtherReceivers) { 2121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("other-receivers\n"); 2122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasOtherServices) { 2124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("other-services\n"); 2125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // For modern apps, if screen size buckets haven't been specified 2128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // but the new width ranges have, then infer the buckets from them. 2129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (smallScreen > 0 && normalScreen > 0 && largeScreen > 0 && xlargeScreen > 0 2130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && requiresSmallestWidthDp > 0) { 2131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int compatWidth = compatibleWidthLimitDp; 2132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (compatWidth <= 0) { 2133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski compatWidth = requiresSmallestWidthDp; 2134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (requiresSmallestWidthDp <= 240 && compatWidth >= 240) { 2136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski smallScreen = -1; 2137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski smallScreen = 0; 2139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (requiresSmallestWidthDp <= 320 && compatWidth >= 320) { 2141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski normalScreen = -1; 2142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski normalScreen = 0; 2144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (requiresSmallestWidthDp <= 480 && compatWidth >= 480) { 2146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski largeScreen = -1; 2147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski largeScreen = 0; 2149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (requiresSmallestWidthDp <= 720 && compatWidth >= 720) { 2151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski xlargeScreen = -1; 2152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski xlargeScreen = 0; 2154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Determine default values for any unspecified screen sizes, 2158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // based on the target SDK of the package. As of 4 (donut) 2159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the screen size support was introduced, so all default to 2160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // enabled. 2161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (smallScreen > 0) { 2162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski smallScreen = targetSdk >= 4 ? -1 : 0; 2163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (normalScreen > 0) { 2165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski normalScreen = -1; 2166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (largeScreen > 0) { 2168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski largeScreen = targetSdk >= 4 ? -1 : 0; 2169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (xlargeScreen > 0) { 2171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Introduced in Gingerbread. 2172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski xlargeScreen = targetSdk >= 9 ? -1 : 0; 2173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (anyDensity > 0) { 2175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski anyDensity = (targetSdk >= 4 || requiresSmallestWidthDp > 0 2176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || compatibleWidthLimitDp > 0) ? -1 : 0; 2177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("supports-screens:"); 2179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (smallScreen != 0) { 2180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" 'small'"); 2181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (normalScreen != 0) { 2183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" 'normal'"); 2184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (largeScreen != 0) { 2186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" 'large'"); 2187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (xlargeScreen != 0) { 2189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" 'xlarge'"); 2190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 2192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("supports-any-density: '%s'\n", anyDensity ? "true" : "false"); 2193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (requiresSmallestWidthDp > 0) { 2194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("requires-smallest-width:'%d'\n", requiresSmallestWidthDp); 2195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (compatibleWidthLimitDp > 0) { 2197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("compatible-width-limit:'%d'\n", compatibleWidthLimitDp); 2198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (largestWidthLimitDp > 0) { 2200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("largest-width-limit:'%d'\n", largestWidthLimitDp); 2201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("locales:"); 2204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NL = locales.size(); 2205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<NL; i++) { 2206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* localeStr = locales[i].string(); 2207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (localeStr == NULL || strlen(localeStr) == 0) { 2208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski localeStr = "--_--"; 2209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" '%s'", localeStr); 2211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 2213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("densities:"); 2215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t ND = densities.size(); 2216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<ND; i++) { 2217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" '%d'", densities[i]); 2218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 2220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AssetDir* dir = assets.openNonAssetDir(assetsCookie, "lib"); 2222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (dir != NULL) { 2223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (dir->getFileCount() > 0) { 2224e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski SortedVector<String8> architectures; 2225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<dir->getFileCount(); i++) { 2226e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski architectures.add(ResTable::normalizeForOutput( 2227e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski dir->getFileName(i).string())); 2228e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski } 2229e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski 2230e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski bool outputAltNativeCode = false; 2231e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // A multiArch package is one that contains 64-bit and 2232e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // 32-bit versions of native code and expects 3rd-party 2233e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // apps to load these native code libraries. Since most 2234e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // 64-bit systems also support 32-bit apps, the apps 2235e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // loading this multiArch package's code may be either 2236e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // 32-bit or 64-bit. 2237e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski if (hasMultiArch) { 2238e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // If this is a multiArch package, report the 64-bit 2239e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // version only. Then as a separate entry, report the 2240e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // rest. 2241e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // 2242e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // If we report the 32-bit architecture, this APK will 2243e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // be installed on a 32-bit device, causing a large waste 2244e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // of bandwidth and disk space. This assumes that 2245e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // the developer of the multiArch package has also 2246e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski // made a version that is 32-bit only. 2247e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski String8 intel64("x86_64"); 2248e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski String8 arm64("arm64-v8a"); 2249e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski ssize_t index = architectures.indexOf(intel64); 2250e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski if (index < 0) { 2251e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski index = architectures.indexOf(arm64); 2252e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski } 2253e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski 2254e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski if (index >= 0) { 2255e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski printf("native-code: '%s'\n", architectures[index].string()); 2256e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski architectures.removeAt(index); 2257e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski outputAltNativeCode = true; 2258e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski } 2259e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski } 2260e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski 2261e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski const size_t archCount = architectures.size(); 2262e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski if (archCount > 0) { 2263e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski if (outputAltNativeCode) { 2264e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski printf("alt-"); 2265e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski } 2266e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski printf("native-code:"); 2267e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski for (size_t i = 0; i < archCount; i++) { 2268e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski printf(" '%s'", architectures[i].string()); 2269e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski } 2270e47fd129057b19862e94b89f9ba413b5ceaca498Adam Lesinski printf("\n"); 2271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete dir; 2274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("badger", option) == 0) { 2276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%s", CONSOLE_DATA); 2277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("configurations", option) == 0) { 2278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<ResTable_config> configs; 2279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res.getConfigurations(&configs); 2280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = configs.size(); 2281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 2282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%s\n", configs[i].toString().string()); 2283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: unknown dump option '%s'\n", option); 2286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = NO_ERROR; 2291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 2293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (asset) { 2294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete asset; 2295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (result != NO_ERROR); 2297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 2301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Handle the "add" command, which wants to add files to a new or 2302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * pre-existing archive. 2303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 2304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doAdd(Bundle* bundle) 2305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipFile* zip = NULL; 2307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result = UNKNOWN_ERROR; 2308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* zipFileName; 2309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getUpdate()) { 2311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* avoid confusion */ 2312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: can't use '-u' with add\n"); 2313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 1) { 2317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: must specify zip file name\n"); 2318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zipFileName = bundle->getFileSpecEntry(0); 2321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 2) { 2323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "NOTE: nothing to do\n"); 2324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip = openReadWrite(zipFileName, true); 2328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (zip == NULL) { 2329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: failed opening/creating '%s' as Zip file\n", zipFileName); 2330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i = 1; i < bundle->getFileSpecCount(); i++) { 2334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* fileName = bundle->getFileSpecEntry(i); 2335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcasecmp(String8(fileName).getPathExtension().string(), ".gz") == 0) { 2337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" '%s'... (from gzip)\n", fileName); 2338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = zip->addGzip(fileName, String8(fileName).getBasePath().string(), NULL); 2339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getJunkPath()) { 2341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 storageName = String8(fileName).getPathLeaf(); 23422675f769673f69b0661ddee346292f25cb30a296Maurice Chu printf(" '%s' as '%s'...\n", fileName, 23432675f769673f69b0661ddee346292f25cb30a296Maurice Chu ResTable::normalizeForOutput(storageName.string()).string()); 2344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = zip->add(fileName, storageName.string(), 2345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bundle->getCompressionMethod(), NULL); 2346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" '%s'...\n", fileName); 2348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = zip->add(fileName, bundle->getCompressionMethod(), NULL); 2349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result != NO_ERROR) { 2352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "Unable to add '%s' to '%s'", bundle->getFileSpecEntry(i), zipFileName); 2353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result == NAME_NOT_FOUND) { 2354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, ": file not found\n"); 2355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (result == ALREADY_EXISTS) { 2356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, ": already exists in archive\n"); 2357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "\n"); 2359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = NO_ERROR; 2365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 2367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete zip; 2368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (result != NO_ERROR); 2369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 2373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Delete files from an existing archive. 2374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 2375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doRemove(Bundle* bundle) 2376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipFile* zip = NULL; 2378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result = UNKNOWN_ERROR; 2379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* zipFileName; 2380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 1) { 2382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: must specify zip file name\n"); 2383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zipFileName = bundle->getFileSpecEntry(0); 2386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 2) { 2388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "NOTE: nothing to do\n"); 2389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip = openReadWrite(zipFileName, false); 2393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (zip == NULL) { 2394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: failed opening Zip archive '%s'\n", 2395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zipFileName); 2396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i = 1; i < bundle->getFileSpecCount(); i++) { 2400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* fileName = bundle->getFileSpecEntry(i); 2401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry* entry; 2402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entry = zip->getEntryByName(fileName); 2404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (entry == NULL) { 2405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" '%s' NOT FOUND\n", fileName); 2406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = zip->remove(entry); 2410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result != NO_ERROR) { 2412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "Unable to delete '%s' from '%s'\n", 2413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bundle->getFileSpecEntry(i), zipFileName); 2414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* update the archive */ 2419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip->flush(); 2420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 2422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete zip; 2423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (result != NO_ERROR); 2424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 24263921e87e6e67a063caa1987937d7944b24aef489Adam Lesinskistatic status_t addResourcesToBuilder(const sp<AaptDir>& dir, const sp<ApkBuilder>& builder, bool ignoreConfig=false) { 2427fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const size_t numDirs = dir->getDirs().size(); 2428fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski for (size_t i = 0; i < numDirs; i++) { 24293921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski bool ignore = ignoreConfig; 24303921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski const sp<AaptDir>& subDir = dir->getDirs().valueAt(i); 24313921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski const char* dirStr = subDir->getLeaf().string(); 24323921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski if (!ignore && strstr(dirStr, "mipmap") == dirStr) { 24333921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski ignore = true; 24343921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski } 24353921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski status_t err = addResourcesToBuilder(subDir, builder, ignore); 2436fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (err != NO_ERROR) { 2437fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return err; 2438fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2439fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2440fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 2441fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const size_t numFiles = dir->getFiles().size(); 2442fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski for (size_t i = 0; i < numFiles; i++) { 2443fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski sp<AaptGroup> gp = dir->getFiles().valueAt(i); 2444fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const size_t numConfigs = gp->getFiles().size(); 2445fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski for (size_t j = 0; j < numConfigs; j++) { 24463921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski status_t err = NO_ERROR; 24473921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski if (ignoreConfig) { 24483921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski err = builder->getBaseSplit()->addEntry(gp->getPath(), gp->getFiles().valueAt(j)); 24493921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski } else { 24503921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski err = builder->addEntry(gp->getPath(), gp->getFiles().valueAt(j)); 24513921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski } 2452fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (err != NO_ERROR) { 2453fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski fprintf(stderr, "Failed to add %s (%s) to builder.\n", 2454fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski gp->getPath().string(), gp->getFiles()[j]->getPrintableSource().string()); 2455fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return err; 2456fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2457fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2458fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2459fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return NO_ERROR; 2460fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski} 2461fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 2462fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskistatic String8 buildApkName(const String8& original, const sp<ApkSplit>& split) { 2463fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (split->isBase()) { 2464fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return original; 2465fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2466fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 2467fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski String8 ext(original.getPathExtension()); 2468fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (ext == String8(".apk")) { 2469fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return String8::format("%s_%s%s", 2470fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski original.getBasePath().string(), 2471fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski split->getDirectorySafeName().string(), 2472fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski ext.string()); 2473fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2474fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 2475fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return String8::format("%s_%s", original.string(), 2476fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski split->getDirectorySafeName().string()); 2477fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski} 2478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 2480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Package up an asset directory and associated application files. 2481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 2482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doPackage(Bundle* bundle) 2483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* outputAPKFile; 2485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int retVal = 1; 2486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err; 2487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptAssets> assets; 2488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int N; 2489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FILE* fp; 2490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 dependencyFile; 2491fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski sp<ApkBuilder> builder; 2492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2493a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin // -c en_XA or/and ar_XB means do pseudolocalization 2494fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski sp<WeakResourceFilter> configFilter = new WeakResourceFilter(); 2495fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski err = configFilter->parse(bundle->getConfigurations()); 2496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 2497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2499fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (configFilter->containsPseudo()) { 2500a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin bundle->setPseudolocalize(bundle->getPseudolocalize() | PSEUDO_ACCENTED); 2501a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin } 2502fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (configFilter->containsPseudoBidi()) { 2503a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin bundle->setPseudolocalize(bundle->getPseudolocalize() | PSEUDO_BIDI); 2504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski N = bundle->getFileSpecCount(); 2507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (N < 1 && bundle->getResourceSourceDirs().size() == 0 && bundle->getJarFiles().size() == 0 250809384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski && bundle->getAndroidManifestFile() == NULL && bundle->getAssetSourceDirs().size() == 0) { 2509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: no input files\n"); 2510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outputAPKFile = bundle->getOutputAPKFile(); 2514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Make sure the filenames provided exist and are of the appropriate type. 2516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outputAPKFile) { 2517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FileType type; 2518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type = getFileType(outputAPKFile); 2519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (type != kFileTypeNonexistent && type != kFileTypeRegular) { 2520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, 2521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "ERROR: output file '%s' exists but is not regular file\n", 2522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outputAPKFile); 2523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Load the assets. 2528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets = new AaptAssets(); 2529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Set up the resource gathering in assets if we're going to generate 2531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // dependency files. Every time we encounter a resource while slurping 2532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the tree, we'll add it to these stores so we have full resource paths 2533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // to write to a dependency file. 2534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getGenDependencies()) { 2535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<FilePathStore> resPathStore = new FilePathStore; 2536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->setFullResPaths(resPathStore); 2537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<FilePathStore> assetPathStore = new FilePathStore; 2538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->setFullAssetPaths(assetPathStore); 2539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = assets->slurpFromArgs(bundle); 2542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 2543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 2547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->print(String8()); 2548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2550fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // Create the ApkBuilder, which will collect the compiled files 2551fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // to write to the final APK (or sets of APKs if we are building 2552fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // a Split APK. 2553fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski builder = new ApkBuilder(configFilter); 2554fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 2555fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // If we are generating a Split APK, find out which configurations to split on. 2556fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (bundle->getSplitConfigurations().size() > 0) { 2557fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const Vector<String8>& splitStrs = bundle->getSplitConfigurations(); 2558fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const size_t numSplits = splitStrs.size(); 2559fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski for (size_t i = 0; i < numSplits; i++) { 2560fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski std::set<ConfigDescription> configs; 2561fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (!AaptConfig::parseCommaSeparatedList(splitStrs[i], &configs)) { 2562fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski fprintf(stderr, "ERROR: failed to parse split configuration '%s'\n", splitStrs[i].string()); 2563fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski goto bail; 2564fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2565fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 2566fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski err = builder->createSplitForConfigs(configs); 2567fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (err != NO_ERROR) { 2568fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski goto bail; 2569fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2570fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2571fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2572fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 2573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If they asked for any fileAs that need to be compiled, do so. 2574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getResourceSourceDirs().size() || bundle->getAndroidManifestFile()) { 2575fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski err = buildResources(bundle, assets, builder); 2576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != 0) { 2577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // At this point we've read everything and processed everything. From here 2582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // on out it's just writing output files. 2583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (SourcePos::hasErrors()) { 2584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Update symbols with information about which ones are needed as Java symbols. 2588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->applyJavaSymbols(); 2589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (SourcePos::hasErrors()) { 2590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If we've been asked to generate a dependency file, do that here 2594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getGenDependencies()) { 2595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If this is the packaging step, generate the dependency file next to 2596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the output apk (e.g. bin/resources.ap_.d) 2597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outputAPKFile) { 2598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dependencyFile = String8(outputAPKFile); 2599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Add the .d extension to the dependency file. 2600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dependencyFile.append(".d"); 2601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Else if this is the R.java dependency generation step, 2603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // generate the dependency file in the R.java package subdirectory 2604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // e.g. gen/com/foo/app/R.java.d 2605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dependencyFile = String8(bundle->getRClassDir()); 2606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dependencyFile.appendPath("R.java.d"); 2607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Make sure we have a clean dependency file to start with 2609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fp = fopen(dependencyFile, "w"); 2610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fclose(fp); 2611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write out R.java constants 2614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!assets->havePrivateSymbols()) { 2615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getCustomPackage() == NULL) { 2616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write the R.java file into the appropriate class directory 2617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // e.g. gen/com/foo/app/R.java 26181e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski err = writeResourceSymbols(bundle, assets, assets->getPackage(), true, 2619a6d7e3fb9c9233b9ae46b702d17433854c43d6a0Tao Bai bundle->getBuildSharedLibrary() || bundle->getBuildAppAsSharedLibrary()); 2620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8 customPkg(bundle->getCustomPackage()); 26221e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski err = writeResourceSymbols(bundle, assets, customPkg, true, 2623a6d7e3fb9c9233b9ae46b702d17433854c43d6a0Tao Bai bundle->getBuildSharedLibrary() || bundle->getBuildAppAsSharedLibrary()); 2624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 2626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If we have library files, we're going to write our R.java file into 2629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the appropriate class directory for those libraries as well. 2630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // e.g. gen/com/foo/app/lib/R.java 2631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getExtraPackages() != NULL) { 2632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Split on colon 2633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 libs(bundle->getExtraPackages()); 2634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char* packageString = strtok(libs.lockBuffer(libs.length()), ":"); 2635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (packageString != NULL) { 2636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write the R.java file out with the correct package name 26370f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba err = writeResourceSymbols(bundle, assets, String8(packageString), true, 2638a6d7e3fb9c9233b9ae46b702d17433854c43d6a0Tao Bai bundle->getBuildSharedLibrary() || bundle->getBuildAppAsSharedLibrary()); 2639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 2640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski packageString = strtok(NULL, ":"); 2643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski libs.unlockBuffer(); 2645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 26471e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski err = writeResourceSymbols(bundle, assets, assets->getPackage(), false, false); 2648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 2649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 26511e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski err = writeResourceSymbols(bundle, assets, assets->getSymbolsPrivatePackage(), true, false); 2652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 2653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write out the ProGuard file 2658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeProguardFile(bundle, assets); 2659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 2660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2663682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal // Write out the Main Dex ProGuard file 2664682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal err = writeMainDexProguardFile(bundle, assets); 2665682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal if (err < 0) { 2666682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal goto bail; 2667682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal } 2668682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal 2669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write the apk 2670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outputAPKFile) { 2671fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // Gather all resources and add them to the APK Builder. The builder will then 2672fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // figure out which Split they belong in. 2673fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski err = addResourcesToBuilder(assets, builder); 2674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 2675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 2676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2677fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 2678fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const Vector<sp<ApkSplit> >& splits = builder->getSplits(); 2679fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const size_t numSplits = splits.size(); 2680fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski for (size_t i = 0; i < numSplits; i++) { 2681fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const sp<ApkSplit>& split = splits[i]; 2682fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski String8 outputPath = buildApkName(String8(outputAPKFile), split); 2683fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski err = writeAPK(bundle, outputPath, split); 2684fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (err != NO_ERROR) { 2685fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski fprintf(stderr, "ERROR: packaging of '%s' failed\n", outputPath.string()); 2686fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski goto bail; 2687fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2688fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 2689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If we've been asked to generate a dependency file, we need to finish up here. 2692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the writeResourceSymbols and writeAPK functions have already written the target 2693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // half of the dependency file, now we need to write the prerequisites. (files that 2694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the R.java file or .ap_ file depend on) 2695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getGenDependencies()) { 2696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Now that writeResourceSymbols or writeAPK has taken care of writing 2697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the targets to our dependency file, we'll write the prereqs 2698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fp = fopen(dependencyFile, "a+"); 2699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, " : "); 2700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool includeRaw = (outputAPKFile != NULL); 2701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeDependencyPreReqs(bundle, assets, fp, includeRaw); 2702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Also manually add the AndroidManifeset since it's not under res/ or assets/ 2703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // and therefore was not added to our pathstores during slurping 2704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s \\\n", bundle->getAndroidManifestFile()); 2705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fclose(fp); 2706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski retVal = 0; 2709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 2710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (SourcePos::hasErrors()) { 2711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos::printErrors(stderr); 2712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return retVal; 2714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 2717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Do PNG Crunching 2718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * PRECONDITIONS 2719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * -S flag points to a source directory containing drawable* folders 2720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * -C flag points to destination directory. The folder structure in the 2721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * source directory will be mirrored to the destination (cache) directory 2722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 2723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * POSTCONDITIONS 2724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Destination directory will be updated to match the PNG files in 27252675f769673f69b0661ddee346292f25cb30a296Maurice Chu * the source directory. 2726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 2727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doCrunch(Bundle* bundle) 2728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "Crunching PNG Files in "); 2730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "source dir: %s\n", bundle->getResourceSourceDirs()[0]); 2731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "To destination dir: %s\n", bundle->getCrunchedOutputDir()); 2732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski updatePreProcessedCache(bundle); 2734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 2736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 2739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Do PNG Crunching on a single flag 2740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * -i points to a single png file 2741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * -o points to a single png output file 2742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 2743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doSingleCrunch(Bundle* bundle) 2744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "Crunching single PNG file: %s\n", bundle->getSingleCrunchInputFile()); 2746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "\tOutput file: %s\n", bundle->getSingleCrunchOutputFile()); 2747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 input(bundle->getSingleCrunchInputFile()); 2749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 output(bundle->getSingleCrunchOutputFile()); 2750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (preProcessImageToCache(bundle, input, output) != NO_ERROR) { 2752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // we can't return the status_t as it gets truncate to the lower 8 bits. 2753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 42; 2754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 2757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 27596f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochezint runInDaemonMode(Bundle* bundle) { 27606f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez std::cout << "Ready" << std::endl; 2761de3ab0a9e8609f6a631b2c047f352069bb9cfa86Chris Warrington for (std::string cmd; std::getline(std::cin, cmd);) { 2762de3ab0a9e8609f6a631b2c047f352069bb9cfa86Chris Warrington if (cmd == "quit") { 27636f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez return NO_ERROR; 2764de3ab0a9e8609f6a631b2c047f352069bb9cfa86Chris Warrington } else if (cmd == "s") { 2765de3ab0a9e8609f6a631b2c047f352069bb9cfa86Chris Warrington // Two argument crunch 2766de3ab0a9e8609f6a631b2c047f352069bb9cfa86Chris Warrington std::string inputFile, outputFile; 2767de3ab0a9e8609f6a631b2c047f352069bb9cfa86Chris Warrington std::getline(std::cin, inputFile); 2768de3ab0a9e8609f6a631b2c047f352069bb9cfa86Chris Warrington std::getline(std::cin, outputFile); 2769de3ab0a9e8609f6a631b2c047f352069bb9cfa86Chris Warrington bundle->setSingleCrunchInputFile(inputFile.c_str()); 2770de3ab0a9e8609f6a631b2c047f352069bb9cfa86Chris Warrington bundle->setSingleCrunchOutputFile(outputFile.c_str()); 2771de3ab0a9e8609f6a631b2c047f352069bb9cfa86Chris Warrington std::cout << "Crunching " << inputFile << std::endl; 27726f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez if (doSingleCrunch(bundle) != NO_ERROR) { 27736f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez std::cout << "Error" << std::endl; 27746f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez } 27756f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez std::cout << "Done" << std::endl; 27766f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez } else { 27776f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez // in case of invalid command, just bail out. 27786f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez std::cerr << "Unknown command" << std::endl; 27796f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez return -1; 27806f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez } 27816f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez } 27826f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez return -1; 27836f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez} 27846f1280cf170b358a57ff70341a9f2ad224e5a662Jerome Dochez 2785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskichar CONSOLE_DATA[2925] = { 2786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 95, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 2790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 63, 2791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 86, 35, 40, 46, 46, 95, 95, 95, 95, 97, 97, 44, 32, 46, 124, 42, 33, 83, 2792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 62, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 46, 58, 59, 61, 59, 61, 81, 2795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 66, 96, 61, 61, 58, 46, 46, 46, 58, 32, 32, 32, 32, 32, 32, 2796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 2797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 46, 61, 59, 59, 59, 58, 106, 81, 81, 81, 81, 102, 59, 61, 59, 2799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 61, 61, 61, 58, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 2802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 58, 109, 81, 81, 81, 81, 61, 59, 59, 59, 59, 59, 58, 59, 59, 46, 32, 2803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 60, 81, 81, 81, 81, 87, 2806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 58, 59, 59, 59, 59, 59, 59, 61, 119, 44, 32, 32, 32, 32, 32, 32, 32, 32, 2807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 2808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 2809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 47, 61, 59, 59, 58, 100, 81, 81, 81, 81, 35, 58, 59, 59, 59, 59, 59, 58, 2810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 121, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 109, 58, 59, 59, 61, 81, 81, 2813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 109, 58, 59, 59, 59, 59, 61, 109, 81, 81, 76, 46, 32, 32, 32, 2814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 2815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 41, 87, 59, 61, 59, 41, 81, 81, 81, 81, 81, 81, 59, 61, 59, 2817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 58, 109, 81, 81, 87, 39, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 60, 81, 91, 59, 2820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 61, 81, 81, 81, 81, 81, 87, 43, 59, 58, 59, 60, 81, 81, 81, 76, 32, 2821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 52, 91, 58, 45, 59, 87, 81, 81, 81, 81, 2824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 70, 58, 58, 58, 59, 106, 81, 81, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32, 2825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 2826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 93, 40, 32, 46, 59, 100, 81, 81, 81, 81, 40, 58, 46, 46, 58, 100, 81, 2828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 68, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 46, 46, 46, 32, 46, 46, 46, 32, 46, 32, 46, 45, 91, 59, 61, 58, 109, 2831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 87, 46, 58, 61, 59, 60, 81, 81, 80, 32, 32, 32, 32, 32, 32, 2832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 2833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 46, 46, 61, 59, 61, 61, 61, 59, 61, 61, 59, 2834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 58, 58, 46, 46, 41, 58, 59, 58, 81, 81, 81, 81, 69, 58, 59, 59, 2835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 60, 81, 81, 68, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 58, 59, 2837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 61, 46, 2838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 59, 93, 81, 81, 81, 81, 107, 58, 59, 58, 109, 87, 68, 96, 32, 32, 32, 2839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 10, 32, 32, 32, 46, 60, 61, 61, 59, 59, 59, 59, 59, 59, 59, 59, 2841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 59, 59, 59, 58, 58, 58, 115, 109, 68, 41, 36, 81, 2842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 109, 46, 61, 61, 81, 69, 96, 46, 58, 58, 46, 58, 46, 46, 32, 32, 32, 32, 2843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 46, 32, 95, 81, 2844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 67, 61, 61, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 2845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 58, 68, 39, 61, 105, 61, 63, 81, 119, 58, 106, 80, 32, 58, 2846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 59, 59, 61, 59, 61, 59, 61, 46, 95, 32, 32, 32, 32, 32, 32, 32, 32, 2847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 10, 32, 32, 36, 81, 109, 105, 59, 61, 59, 59, 59, 2848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 46, 58, 37, 2849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 73, 108, 108, 62, 52, 81, 109, 34, 32, 61, 59, 59, 59, 59, 59, 59, 59, 59, 2850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 61, 59, 61, 61, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 2851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 46, 45, 57, 101, 43, 43, 61, 61, 59, 59, 59, 59, 59, 59, 61, 59, 59, 2852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 59, 58, 97, 46, 61, 108, 62, 126, 58, 106, 80, 96, 2853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46, 61, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 61, 2854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 97, 103, 97, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 45, 46, 32, 2855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45, 58, 59, 59, 59, 59, 61, 2856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 119, 81, 97, 124, 105, 124, 124, 39, 126, 95, 119, 58, 61, 58, 59, 59, 59, 2857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 119, 81, 81, 99, 32, 32, 2858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 58, 106, 81, 81, 81, 109, 119, 2860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 119, 119, 109, 109, 81, 81, 122, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 2861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 58, 115, 81, 87, 81, 102, 32, 32, 32, 32, 32, 32, 10, 2862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 61, 58, 59, 61, 81, 81, 81, 81, 81, 81, 87, 87, 81, 81, 81, 81, 2864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 58, 59, 59, 59, 59, 59, 59, 59, 59, 58, 45, 45, 45, 59, 59, 59, 41, 2865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 87, 66, 33, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 2866282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 93, 81, 2867282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 2868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 45, 32, 46, 32, 32, 32, 32, 32, 46, 32, 126, 96, 32, 32, 32, 32, 32, 32, 2869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 58, 61, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81, 2871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 2872282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 2873282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 2874282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58, 2875282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2876282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2877282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 60, 81, 81, 81, 81, 2878282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 81, 81, 81, 81, 59, 61, 59, 59, 61, 32, 32, 32, 32, 2879282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2880282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2881282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 58, 59, 59, 93, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 2882282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 40, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2883282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 2884282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 106, 2885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 76, 58, 59, 59, 59, 2886282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2887282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 61, 58, 58, 81, 81, 81, 81, 81, 81, 81, 81, 2889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 87, 58, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 2890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 2891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 58, 59, 61, 41, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 87, 59, 2893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 58, 59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 61, 81, 81, 81, 2896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 81, 81, 81, 81, 107, 58, 59, 59, 59, 59, 58, 32, 32, 2897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 58, 59, 59, 58, 51, 81, 81, 81, 81, 81, 81, 81, 81, 81, 2900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 102, 94, 59, 59, 59, 59, 59, 61, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 2902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 2903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 43, 63, 36, 81, 81, 81, 87, 64, 86, 102, 58, 59, 59, 59, 59, 59, 2904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 59, 59, 43, 33, 2907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 58, 126, 126, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32, 32, 2908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 2909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 2910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 59, 59, 59, 58, 45, 58, 61, 59, 58, 58, 58, 61, 59, 59, 59, 59, 59, 2911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 2912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 2913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 58, 95, 2914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 45, 61, 59, 61, 59, 59, 59, 59, 59, 59, 59, 45, 58, 59, 59, 59, 59, 2915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2916282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2917282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 58, 61, 59, 59, 59, 59, 59, 61, 59, 61, 46, 46, 32, 45, 45, 45, 2918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 58, 45, 45, 46, 58, 59, 59, 59, 59, 59, 59, 61, 46, 32, 32, 32, 32, 2919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 2920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 58, 59, 59, 59, 59, 2921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 61, 59, 46, 32, 32, 46, 32, 46, 32, 58, 61, 59, 59, 2922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 45, 59, 59, 59, 59, 59, 59, 59, 59, 58, 32, 2925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 58, 32, 2926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 2927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2928282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46, 61, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 61, 2929282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46, 61, 59, 59, 59, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 2931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 2932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 46, 61, 58, 59, 59, 59, 59, 2933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 58, 59, 59, 59, 59, 59, 59, 59, 59, 46, 46, 32, 32, 32, 2936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 45, 32, 32, 32, 32, 32, 2937282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 2938282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 32, 45, 61, 2939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 2940282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 58, 45, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2942282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45, 45, 32, 46, 32, 2943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 61, 59, 58, 45, 45, 32, 32, 32, 2944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 46, 32, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10 2949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski }; 2950