Command.cpp revision ec4fdec76f2916b91a69d979f400cd69a3812631
1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Copyright 2006 The Android Open Source Project 3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Android Asset Packaging Tool main entry point. 5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 6282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "Main.h" 7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "Bundle.h" 8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "ResourceFilter.h" 9282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "ResourceTable.h" 10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "Images.h" 11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "XMLNode.h" 12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <utils/Log.h> 14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <utils/threads.h> 15282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <utils/List.h> 16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <utils/Errors.h> 17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <fcntl.h> 19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <errno.h> 20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiusing namespace android; 22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Show version info. All the cool kids do it. 25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doVersion(Bundle* bundle) 27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() != 0) { 29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("(ignoring extra arguments)\n"); 30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Android Asset Packaging Tool, v0.2\n"); 32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Open the file read only. The call fails if the file doesn't exist. 39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Returns NULL on failure. 41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 42282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiZipFile* openReadOnly(const char* fileName) 43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipFile* zip; 45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result; 46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip = new ZipFile; 48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = zip->open(fileName, ZipFile::kOpenReadOnly); 49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result != NO_ERROR) { 50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result == NAME_NOT_FOUND) { 51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: '%s' not found\n", fileName); 52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (result == PERMISSION_DENIED) { 53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: '%s' access denied\n", fileName); 54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: failed opening '%s' as Zip file\n", 56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fileName); 57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete zip; 59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return zip; 63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Open the file read-write. The file will be created if it doesn't 67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * already exist and "okayToCreate" is set. 68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Returns NULL on failure. 70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 71282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiZipFile* openReadWrite(const char* fileName, bool okayToCreate) 72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipFile* zip = NULL; 74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result; 75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int flags; 76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flags = ZipFile::kOpenReadWrite; 78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (okayToCreate) { 79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flags |= ZipFile::kOpenCreate; 80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip = new ZipFile; 83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = zip->open(fileName, flags); 84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result != NO_ERROR) { 85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete zip; 86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip = NULL; 87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return zip; 92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Return a short string describing the compression method. 97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiconst char* compressionName(int method) 99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (method == ZipEntry::kCompressStored) { 101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return "Stored"; 102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (method == ZipEntry::kCompressDeflated) { 103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return "Deflated"; 104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return "Unknown"; 106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Return the percent reduction in size (0% == no compression). 111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint calcPercent(long uncompressedLen, long compressedLen) 113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!uncompressedLen) { 115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (int) (100.0 - (compressedLen * 100.0) / uncompressedLen + 0.5); 118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Handle the "list" command, which can be a simple file dump or 123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * a verbose listing. 124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * The verbose listing closely matches the output of the Info-ZIP "unzip" 126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * command. 127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doList(Bundle* bundle) 129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int result = 1; 131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipFile* zip = NULL; 132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ZipEntry* entry; 133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski long totalUncLen, totalCompLen; 134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* zipFileName; 135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() != 1) { 137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: specify zip file name (only)\n"); 138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zipFileName = bundle->getFileSpecEntry(0); 141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip = openReadOnly(zipFileName); 143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (zip == NULL) { 144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int count, i; 148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Archive: %s\n", zipFileName); 151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf( 152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " Length Method Size Ratio Offset Date Time CRC-32 Name\n"); 153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf( 154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "-------- ------ ------- ----- ------- ---- ---- ------ ----\n"); 155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalUncLen = totalCompLen = 0; 158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count = zip->getNumEntries(); 160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i = 0; i < count; i++) { 161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entry = zip->getEntryByIndex(i); 162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char dateBuf[32]; 164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski time_t when; 165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski when = entry->getModWhen(); 167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strftime(dateBuf, sizeof(dateBuf), "%m-%d-%y %H:%M", 168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski localtime(&when)); 169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%8ld %-7.7s %7ld %3d%% %8zd %s %08lx %s\n", 171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (long) entry->getUncompressedLen(), 172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski compressionName(entry->getCompressionMethod()), 173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (long) entry->getCompressedLen(), 174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski calcPercent(entry->getUncompressedLen(), 175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entry->getCompressedLen()), 176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (size_t) entry->getLFHOffset(), 177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dateBuf, 178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entry->getCRC32(), 179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entry->getFileName()); 180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%s\n", entry->getFileName()); 182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalUncLen += entry->getUncompressedLen(); 185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalCompLen += entry->getCompressedLen(); 186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf( 190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "-------- ------- --- -------\n"); 191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%8ld %7ld %2d%% %d files\n", 192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalUncLen, 193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalCompLen, 194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski calcPercent(totalUncLen, totalCompLen), 195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip->getNumEntries()); 196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getAndroidList()) { 199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AssetManager assets; 200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!assets.addAssetPath(String8(zipFileName), NULL)) { 201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: list -a failed because assets could not be loaded\n"); 202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable& res = assets.getResources(false); 206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (&res == NULL) { 207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\nNo resource table found.\n"); 208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#ifndef HAVE_ANDROID_OS 210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\nResource table:\n"); 211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res.print(false); 212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Asset* manifestAsset = assets.openNonAsset("AndroidManifest.xml", 216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Asset::ACCESS_BUFFER); 217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (manifestAsset == NULL) { 218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\nNo AndroidManifest.xml found.\n"); 219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\nAndroid manifest:\n"); 221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree tree; 222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tree.setTo(manifestAsset->getBuffer(true), 223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski manifestAsset->getLength()); 224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printXMLBlock(&tree); 225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete manifestAsset; 227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = 0; 230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete zip; 233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return result; 234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic ssize_t indexOfAttribute(const ResXMLTree& tree, uint32_t attrRes) 237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t N = tree.getAttributeCount(); 239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.getAttributeNameResID(i) == attrRes) { 241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (ssize_t)i; 242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return -1; 245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 247282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiString8 getAttribute(const ResXMLTree& tree, const char* ns, 248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* attr, String8* outError) 249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t idx = tree.indexOfAttribute(ns, attr); 251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx < 0) { 252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String8(); 253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value.dataType != Res_value::TYPE_STRING) { 257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError != NULL) { 258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outError = "attribute is not a string value"; 259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String8(); 261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint16_t* str = tree.getAttributeStringValue(idx, &len); 265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return str ? String8(str, len) : String8(); 266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic String8 getAttribute(const ResXMLTree& tree, uint32_t attrRes, String8* outError) 269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t idx = indexOfAttribute(tree, attrRes); 271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx < 0) { 272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String8(); 273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value.dataType != Res_value::TYPE_STRING) { 277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError != NULL) { 278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outError = "attribute is not a string value"; 279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String8(); 281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint16_t* str = tree.getAttributeStringValue(idx, &len); 285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return str ? String8(str, len) : String8(); 286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic int32_t getIntegerAttribute(const ResXMLTree& tree, uint32_t attrRes, 289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8* outError, int32_t defValue = -1) 290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t idx = indexOfAttribute(tree, attrRes); 292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx < 0) { 293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return defValue; 294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value.dataType < Res_value::TYPE_FIRST_INT 298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || value.dataType > Res_value::TYPE_LAST_INT) { 299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError != NULL) { 300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outError = "attribute is not an integer value"; 301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return defValue; 303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return value.data; 306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic int32_t getResolvedIntegerAttribute(const ResTable* resTable, const ResXMLTree& tree, 309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t attrRes, String8* outError, int32_t defValue = -1) 310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t idx = indexOfAttribute(tree, attrRes); 312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx < 0) { 313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return defValue; 314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value.dataType == Res_value::TYPE_REFERENCE) { 318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resTable->resolveReference(&value, 0); 319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value.dataType < Res_value::TYPE_FIRST_INT 321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || value.dataType > Res_value::TYPE_LAST_INT) { 322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError != NULL) { 323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outError = "attribute is not an integer value"; 324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return defValue; 326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return value.data; 329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic String8 getResolvedAttribute(const ResTable* resTable, const ResXMLTree& tree, 332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t attrRes, String8* outError) 333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t idx = indexOfAttribute(tree, attrRes); 335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx < 0) { 336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String8(); 337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.getAttributeValue(idx, &value) != NO_ERROR) { 340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value.dataType == Res_value::TYPE_STRING) { 341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint16_t* str = tree.getAttributeStringValue(idx, &len); 343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return str ? String8(str, len) : String8(); 344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resTable->resolveReference(&value, 0); 346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value.dataType != Res_value::TYPE_STRING) { 347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError != NULL) { 348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outError = "attribute is not a string value"; 349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String8(); 351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Res_value* value2 = &value; 355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* str = const_cast<ResTable*>(resTable)->valueToString(value2, 0, NULL, &len); 356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return str ? String8(str, len) : String8(); 357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void getResolvedResourceAttribute(Res_value* value, const ResTable* resTable, 360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResXMLTree& tree, uint32_t attrRes, String8* outError) 361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t idx = indexOfAttribute(tree, attrRes); 363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx < 0) { 364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError != NULL) { 365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outError = "attribute could not be found"; 366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.getAttributeValue(idx, value) != NO_ERROR) { 370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value->dataType == Res_value::TYPE_REFERENCE) { 371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resTable->resolveReference(value, 0); 372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // The attribute was found and was resolved if need be. 374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError != NULL) { 377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outError = "error getting resolved resource attribute"; 378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// These are attribute resource constants for the platform, as found 382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// in android.R.attr 383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskienum { 384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LABEL_ATTR = 0x01010001, 385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ICON_ATTR = 0x01010002, 386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NAME_ATTR = 0x01010003, 387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DEBUGGABLE_ATTR = 0x0101000f, 388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski VALUE_ATTR = 0x01010024, 389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski VERSION_CODE_ATTR = 0x0101021b, 390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski VERSION_NAME_ATTR = 0x0101021c, 391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SCREEN_ORIENTATION_ATTR = 0x0101001e, 392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MIN_SDK_VERSION_ATTR = 0x0101020c, 393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MAX_SDK_VERSION_ATTR = 0x01010271, 394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_TOUCH_SCREEN_ATTR = 0x01010227, 395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_KEYBOARD_TYPE_ATTR = 0x01010228, 396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_HARD_KEYBOARD_ATTR = 0x01010229, 397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_NAVIGATION_ATTR = 0x0101022a, 398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_FIVE_WAY_NAV_ATTR = 0x01010232, 399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski TARGET_SDK_VERSION_ATTR = 0x01010270, 400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski TEST_ONLY_ATTR = 0x01010272, 401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ANY_DENSITY_ATTR = 0x0101026c, 402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski GL_ES_VERSION_ATTR = 0x01010281, 403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SMALL_SCREEN_ATTR = 0x01010284, 404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NORMAL_SCREEN_ATTR = 0x01010285, 405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LARGE_SCREEN_ATTR = 0x01010286, 406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski XLARGE_SCREEN_ATTR = 0x010102bf, 407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQUIRED_ATTR = 0x0101028e, 408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SCREEN_SIZE_ATTR = 0x010102ca, 409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SCREEN_DENSITY_ATTR = 0x010102cb, 410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQUIRES_SMALLEST_WIDTH_DP_ATTR = 0x01010364, 411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski COMPATIBLE_WIDTH_LIMIT_DP_ATTR = 0x01010365, 412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LARGEST_WIDTH_LIMIT_DP_ATTR = 0x01010366, 413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PUBLIC_KEY_ATTR = 0x010103a6, 414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiconst char *getComponentName(String8 &pkgName, String8 &componentName) { 417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t idx = componentName.find("."); 418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 retStr(pkgName); 419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx == 0) { 420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski retStr += componentName; 421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (idx < 0) { 422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski retStr += "."; 423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski retStr += componentName; 424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return componentName.string(); 426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return retStr.string(); 428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void printCompatibleScreens(ResXMLTree& tree) { 431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int depth = 0; 434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool first = true; 435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("compatible-screens:"); 436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth--; 439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (depth < 0) { 440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != ResXMLTree::START_TAG) { 445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth++; 448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 tag(tree.getElementName(&len)); 449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag == "screen") { 450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t screenSize = getIntegerAttribute(tree, 451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SCREEN_SIZE_ATTR, NULL, -1); 452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t screenDensity = getIntegerAttribute(tree, 453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SCREEN_DENSITY_ATTR, NULL, -1); 454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (screenSize > 0 && screenDensity > 0) { 455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!first) { 456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(","); 457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski first = false; 459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("'%d/%d'", screenSize, screenDensity); 460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Handle the "dump" command, to extract select data from an archive. 468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiextern char CONSOLE_DATA[2925]; // see EOF 470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doDump(Bundle* bundle) 471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result = UNKNOWN_ERROR; 473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Asset* asset = NULL; 474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 1) { 476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: no dump option specified\n"); 477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 1; 478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 2) { 481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: no dump file specified\n"); 482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 1; 483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* option = bundle->getFileSpecEntry(0); 486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* filename = bundle->getFileSpecEntry(1); 487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AssetManager assets; 489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski void* assetsCookie; 490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!assets.addAssetPath(String8(filename), &assetsCookie)) { 491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: dump failed because assets could not be loaded\n"); 492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 1; 493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Make a dummy config for retrieving resources... we need to supply 496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // non-default values for some configs so that we can retrieve resources 497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // in the app that don't have a default. The most important of these is 498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the API version because key resources like icons will have an implicit 499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // version if they are using newer config types like density. 500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_config config; 501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.language[0] = 'e'; 502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.language[1] = 'n'; 503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.country[0] = 'U'; 504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.country[1] = 'S'; 505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.orientation = ResTable_config::ORIENTATION_PORT; 506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.density = ResTable_config::DENSITY_MEDIUM; 507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.sdkVersion = 10000; // Very high. 508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.screenWidthDp = 320; 509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.screenHeightDp = 480; 510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.smallestScreenWidthDp = 320; 511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets.setConfiguration(config); 512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable& res = assets.getResources(false); 514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (&res == NULL) { 515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: dump failed because no resource table was found\n"); 516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp("resources", option) == 0) { 520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#ifndef HAVE_ANDROID_OS 521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res.print(bundle->getValues()); 522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("strings", option) == 0) { 525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResStringPool* pool = res.getTableStringBlock(0); 526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printStringPool(pool); 527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("xmltree", option) == 0) { 529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 3) { 530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: no dump xmltree resource file specified\n"); 531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i=2; i<bundle->getFileSpecCount(); i++) { 535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* resname = bundle->getFileSpecEntry(i); 536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree tree; 537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset = assets.openNonAsset(resname, Asset::ACCESS_BUFFER); 538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (asset == NULL) { 539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: dump failed because resource %s found\n", resname); 540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.setTo(asset->getBuffer(true), 544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset->getLength()) != NO_ERROR) { 545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: Resource %s is corrupt\n", resname); 546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tree.restart(); 549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printXMLBlock(&tree); 550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tree.uninit(); 551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete asset; 552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset = NULL; 553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("xmlstrings", option) == 0) { 556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 3) { 557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: no dump xmltree resource file specified\n"); 558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i=2; i<bundle->getFileSpecCount(); i++) { 562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* resname = bundle->getFileSpecEntry(i); 563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree tree; 564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset = assets.openNonAsset(resname, Asset::ACCESS_BUFFER); 565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (asset == NULL) { 566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: dump failed because resource %s found\n", resname); 567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.setTo(asset->getBuffer(true), 571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset->getLength()) != NO_ERROR) { 572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: Resource %s is corrupt\n", resname); 573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printStringPool(&tree.getStrings()); 576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete asset; 577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset = NULL; 578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree tree; 582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset = assets.openNonAsset("AndroidManifest.xml", 583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Asset::ACCESS_BUFFER); 584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (asset == NULL) { 585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: dump failed because no AndroidManifest.xml found\n"); 586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tree.setTo(asset->getBuffer(true), 590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asset->getLength()) != NO_ERROR) { 591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: AndroidManifest.xml is corrupt\n"); 592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tree.restart(); 595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp("permissions", option) == 0) { 597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int depth = 0; 600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth--; 603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != ResXMLTree::START_TAG) { 606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth++; 609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 tag(tree.getElementName(&len)); 610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Depth %d tag %s\n", depth, tag.string()); 611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (depth == 1) { 612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag != "manifest") { 613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: manifest does not start with <manifest> tag\n"); 614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 pkg = getAttribute(tree, NULL, "package", NULL); 617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("package: %s\n", pkg.string()); 618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (depth == 2 && tag == "permission") { 619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 error; 620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getAttribute(tree, NAME_ATTR, &error); 621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: %s\n", error.string()); 623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("permission: %s\n", name.string()); 626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (depth == 2 && tag == "uses-permission") { 627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 error; 628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getAttribute(tree, NAME_ATTR, &error); 629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: %s\n", error.string()); 631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-permission: %s\n", name.string()); 634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int req = getIntegerAttribute(tree, REQUIRED_ATTR, NULL, 1); 635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!req) { 636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("optional-permission: %s\n", name.string()); 637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("badging", option) == 0) { 641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<String8> locales; 642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res.getLocales(&locales); 643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<ResTable_config> configs; 645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res.getConfigurations(&configs); 646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SortedVector<int> densities; 647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NC = configs.size(); 648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<NC; i++) { 649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int dens = configs[i].density; 650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (dens == 0) { 651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dens = 160; 652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski densities.add(dens); 654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int depth = 0; 659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 error; 660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool withinActivity = false; 661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isMainActivity = false; 662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isLauncherActivity = false; 663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isSearchable = false; 664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool withinApplication = false; 665ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright bool withinSupportsInput = false; 666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool withinReceiver = false; 667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool withinService = false; 668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool withinIntentFilter = false; 669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasMainActivity = false; 670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasOtherActivities = false; 671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasOtherReceivers = false; 672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasOtherServices = false; 673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasWallpaperService = false; 674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasImeService = false; 675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasWidgetReceivers = false; 676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasIntentFilter = false; 677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool actMainActivity = false; 678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool actWidgetReceivers = false; 679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool actImeService = false; 680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool actWallpaperService = false; 681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // These two implement the implicit permissions that are granted 683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // to pre-1.6 applications. 684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasWriteExternalStoragePermission = false; 685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasReadPhoneStatePermission = false; 686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If an app requests write storage, they will also get read storage. 688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasReadExternalStoragePermission = false; 689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Implement transition to read and write call log. 691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasReadContactsPermission = false; 692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasWriteContactsPermission = false; 693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasReadCallLogPermission = false; 694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasWriteCallLogPermission = false; 695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // This next group of variables is used to implement a group of 697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // backward-compatibility heuristics necessitated by the addition of 698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // some new uses-feature constants in 2.1 and 2.2. In most cases, the 699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // heuristic is "if an app requests a permission but doesn't explicitly 700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // request the corresponding <uses-feature>, presume it's there anyway". 701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool specCameraFeature = false; // camera-related 702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool specCameraAutofocusFeature = false; 703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool reqCameraAutofocusFeature = false; 704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool reqCameraFlashFeature = false; 705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasCameraPermission = false; 706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool specLocationFeature = false; // location-related 707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool specNetworkLocFeature = false; 708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool reqNetworkLocFeature = false; 709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool specGpsFeature = false; 710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool reqGpsFeature = false; 711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasMockLocPermission = false; 712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasCoarseLocPermission = false; 713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasGpsPermission = false; 714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasGeneralLocPermission = false; 715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool specBluetoothFeature = false; // Bluetooth API-related 716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasBluetoothPermission = false; 717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool specMicrophoneFeature = false; // microphone-related 718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasRecordAudioPermission = false; 719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool specWiFiFeature = false; 720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasWiFiPermission = false; 721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool specTelephonyFeature = false; // telephony-related 722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool reqTelephonySubFeature = false; 723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasTelephonyPermission = false; 724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool specTouchscreenFeature = false; // touchscreen-related 725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool specMultitouchFeature = false; 726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool reqDistinctMultitouchFeature = false; 727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool specScreenPortraitFeature = false; 728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool specScreenLandscapeFeature = false; 729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool reqScreenPortraitFeature = false; 730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool reqScreenLandscapeFeature = false; 731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // 2.2 also added some other features that apps can request, but that 732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // have no corresponding permission, so we cannot implement any 733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // back-compatibility heuristic for them. The below are thus unnecessary 734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // (but are retained here for documentary purposes.) 735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //bool specCompassFeature = false; 736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //bool specAccelerometerFeature = false; 737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //bool specProximityFeature = false; 738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //bool specAmbientLightFeature = false; 739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //bool specLiveWallpaperFeature = false; 740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int targetSdk = 0; 742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int smallScreen = 1; 743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int normalScreen = 1; 744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int largeScreen = 1; 745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int xlargeScreen = 1; 746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int anyDensity = 1; 747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int requiresSmallestWidthDp = 0; 748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int compatibleWidthLimitDp = 0; 749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int largestWidthLimitDp = 0; 750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 pkg; 751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 activityName; 752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 activityLabel; 753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 activityIcon; 754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 receiverName; 755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 serviceName; 756ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright Vector<String8> supportedInput; 757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth--; 760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (depth < 2) { 761ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (withinSupportsInput && !supportedInput.isEmpty()) { 762ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright printf("supports-input: '"); 763ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright const size_t N = supportedInput.size(); 764ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright for (size_t i=0; i<N; i++) { 765ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright printf("%s", supportedInput[i].string()); 766ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (i != N - 1) { 767ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright printf("' '"); 768ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else { 769ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright printf("'\n"); 770ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 771ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 772ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright supportedInput.clear(); 773ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinApplication = false; 775ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright withinSupportsInput = false; 776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (depth < 3) { 777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (withinActivity && isMainActivity && isLauncherActivity) { 778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char *aName = getComponentName(pkg, activityName); 779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("launchable-activity:"); 780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (aName != NULL) { 781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" name='%s' ", aName); 782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" label='%s' icon='%s'\n", 784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski activityLabel.string(), 785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski activityIcon.string()); 786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasIntentFilter) { 788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasOtherActivities |= withinActivity; 789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasOtherReceivers |= withinReceiver; 790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasOtherServices |= withinService; 791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinActivity = false; 793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinService = false; 794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinReceiver = false; 795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasIntentFilter = false; 796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski isMainActivity = isLauncherActivity = false; 797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (depth < 4) { 798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (withinIntentFilter) { 799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (withinActivity) { 800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasMainActivity |= actMainActivity; 801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasOtherActivities |= !actMainActivity; 802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (withinReceiver) { 803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWidgetReceivers |= actWidgetReceivers; 804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasOtherReceivers |= !actWidgetReceivers; 805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (withinService) { 806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasImeService |= actImeService; 807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWallpaperService |= actWallpaperService; 808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasOtherServices |= (!actImeService && !actWallpaperService); 809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinIntentFilter = false; 812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != ResXMLTree::START_TAG) { 816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth++; 819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 tag(tree.getElementName(&len)); 820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Depth %d, %s\n", depth, tag.string()); 821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (depth == 1) { 822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag != "manifest") { 823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: manifest does not start with <manifest> tag\n"); 824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pkg = getAttribute(tree, NULL, "package", NULL); 827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("package: name='%s' ", pkg.string()); 828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t versionCode = getIntegerAttribute(tree, VERSION_CODE_ATTR, &error); 829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:versionCode' attribute: %s\n", error.string()); 831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (versionCode > 0) { 834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("versionCode='%d' ", versionCode); 835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("versionCode='' "); 837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 versionName = getResolvedAttribute(&res, tree, VERSION_NAME_ATTR, &error); 839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:versionName' attribute: %s\n", error.string()); 841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("versionName='%s'\n", versionName.string()); 844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (depth == 2) { 845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinApplication = false; 846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag == "application") { 847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinApplication = true; 848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 label; 850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NL = locales.size(); 851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<NL; i++) { 852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* localeStr = locales[i].string(); 853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets.setLocale(localeStr != NULL ? localeStr : ""); 854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 llabel = getResolvedAttribute(&res, tree, LABEL_ATTR, &error); 855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (llabel != "") { 856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (localeStr == NULL || strlen(localeStr) == 0) { 857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski label = llabel; 858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("application-label:'%s'\n", llabel.string()); 859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (label == "") { 861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski label = llabel; 862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("application-label-%s:'%s'\n", localeStr, 864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski llabel.string()); 865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 866282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 867282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_config tmpConfig = config; 870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t ND = densities.size(); 871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<ND; i++) { 872282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tmpConfig.density = densities[i]; 873282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets.setConfiguration(tmpConfig); 874282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 icon = getResolvedAttribute(&res, tree, ICON_ATTR, &error); 875282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (icon != "") { 876282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("application-icon-%d:'%s'\n", densities[i], icon.string()); 877282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 878282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 879282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets.setConfiguration(config); 880282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 881282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 icon = getResolvedAttribute(&res, tree, ICON_ATTR, &error); 882282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 883282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n", error.string()); 884282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 886282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t testOnly = getIntegerAttribute(tree, TEST_ONLY_ATTR, &error, 0); 887282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:testOnly' attribute: %s\n", error.string()); 889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("application: label='%s' ", label.string()); 892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("icon='%s'\n", icon.string()); 893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (testOnly != 0) { 894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("testOnly='%d'\n", testOnly); 895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t debuggable = getResolvedIntegerAttribute(&res, tree, DEBUGGABLE_ATTR, &error, 0); 898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:debuggable' attribute: %s\n", error.string()); 900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (debuggable != 0) { 903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("application-debuggable\n"); 904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "uses-sdk") { 906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t code = getIntegerAttribute(tree, MIN_SDK_VERSION_ATTR, &error); 907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error = ""; 909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getResolvedAttribute(&res, tree, MIN_SDK_VERSION_ATTR, &error); 910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:minSdkVersion' attribute: %s\n", 912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name == "Donut") targetSdk = 4; 916282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("sdkVersion:'%s'\n", name.string()); 917282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (code != -1) { 918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski targetSdk = code; 919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("sdkVersion:'%d'\n", code); 920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski code = getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR, NULL, -1); 922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != -1) { 923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("maxSdkVersion:'%d'\n", code); 924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski code = getIntegerAttribute(tree, TARGET_SDK_VERSION_ATTR, &error); 926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error = ""; 928282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getResolvedAttribute(&res, tree, TARGET_SDK_VERSION_ATTR, &error); 929282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:targetSdkVersion' attribute: %s\n", 931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name == "Donut" && targetSdk < 4) targetSdk = 4; 935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("targetSdkVersion:'%s'\n", name.string()); 936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (code != -1) { 937282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (targetSdk < code) { 938282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski targetSdk = code; 939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 940282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("targetSdkVersion:'%d'\n", code); 941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 942282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "uses-configuration") { 943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t reqTouchScreen = getIntegerAttribute(tree, 944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_TOUCH_SCREEN_ATTR, NULL, 0); 945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t reqKeyboardType = getIntegerAttribute(tree, 946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_KEYBOARD_TYPE_ATTR, NULL, 0); 947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t reqHardKeyboard = getIntegerAttribute(tree, 948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_HARD_KEYBOARD_ATTR, NULL, 0); 949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t reqNavigation = getIntegerAttribute(tree, 950282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_NAVIGATION_ATTR, NULL, 0); 951282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t reqFiveWayNav = getIntegerAttribute(tree, 952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQ_FIVE_WAY_NAV_ATTR, NULL, 0); 953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-configuration:"); 954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqTouchScreen != 0) { 955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" reqTouchScreen='%d'", reqTouchScreen); 956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqKeyboardType != 0) { 958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" reqKeyboardType='%d'", reqKeyboardType); 959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqHardKeyboard != 0) { 961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" reqHardKeyboard='%d'", reqHardKeyboard); 962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqNavigation != 0) { 964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" reqNavigation='%d'", reqNavigation); 965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqFiveWayNav != 0) { 967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" reqFiveWayNav='%d'", reqFiveWayNav); 968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 970ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (tag == "supports-input") { 971ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright withinSupportsInput = true; 972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "supports-screens") { 973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski smallScreen = getIntegerAttribute(tree, 974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SMALL_SCREEN_ATTR, NULL, 1); 975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski normalScreen = getIntegerAttribute(tree, 976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NORMAL_SCREEN_ATTR, NULL, 1); 977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski largeScreen = getIntegerAttribute(tree, 978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LARGE_SCREEN_ATTR, NULL, 1); 979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski xlargeScreen = getIntegerAttribute(tree, 980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski XLARGE_SCREEN_ATTR, NULL, 1); 981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski anyDensity = getIntegerAttribute(tree, 982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ANY_DENSITY_ATTR, NULL, 1); 983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski requiresSmallestWidthDp = getIntegerAttribute(tree, 984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQUIRES_SMALLEST_WIDTH_DP_ATTR, NULL, 0); 985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski compatibleWidthLimitDp = getIntegerAttribute(tree, 986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski COMPATIBLE_WIDTH_LIMIT_DP_ATTR, NULL, 0); 987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski largestWidthLimitDp = getIntegerAttribute(tree, 988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LARGEST_WIDTH_LIMIT_DP_ATTR, NULL, 0); 989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "uses-feature") { 990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getAttribute(tree, NAME_ATTR, &error); 991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int req = getIntegerAttribute(tree, 994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski REQUIRED_ATTR, NULL, 1); 995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name == "android.hardware.camera") { 997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specCameraFeature = true; 998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.hardware.camera.autofocus") { 999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // these have no corresponding permission to check for, 1000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // but should imply the foundational camera permission 1001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski reqCameraAutofocusFeature = reqCameraAutofocusFeature || req; 1002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specCameraAutofocusFeature = true; 1003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (req && (name == "android.hardware.camera.flash")) { 1004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // these have no corresponding permission to check for, 1005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // but should imply the foundational camera permission 1006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski reqCameraFlashFeature = true; 1007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.hardware.location") { 1008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specLocationFeature = true; 1009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.hardware.location.network") { 1010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specNetworkLocFeature = true; 1011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski reqNetworkLocFeature = reqNetworkLocFeature || req; 1012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.hardware.location.gps") { 1013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specGpsFeature = true; 1014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski reqGpsFeature = reqGpsFeature || req; 1015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.hardware.bluetooth") { 1016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specBluetoothFeature = true; 1017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.hardware.touchscreen") { 1018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specTouchscreenFeature = true; 1019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.hardware.touchscreen.multitouch") { 1020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specMultitouchFeature = true; 1021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.hardware.touchscreen.multitouch.distinct") { 1022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski reqDistinctMultitouchFeature = reqDistinctMultitouchFeature || req; 1023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.hardware.microphone") { 1024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specMicrophoneFeature = true; 1025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.hardware.wifi") { 1026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specWiFiFeature = true; 1027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.hardware.telephony") { 1028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specTelephonyFeature = true; 1029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (req && (name == "android.hardware.telephony.gsm" || 1030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.hardware.telephony.cdma")) { 1031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // these have no corresponding permission to check for, 1032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // but should imply the foundational telephony permission 1033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski reqTelephonySubFeature = true; 1034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.hardware.screen.portrait") { 1035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specScreenPortraitFeature = true; 1036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.hardware.screen.landscape") { 1037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specScreenLandscapeFeature = true; 1038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature%s:'%s'\n", 1040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski req ? "" : "-not-required", name.string()); 1041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int vers = getIntegerAttribute(tree, 1043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski GL_ES_VERSION_ATTR, &error); 1044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error == "") { 1045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-gl-es:'0x%x'\n", vers); 1046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "uses-permission") { 1049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getAttribute(tree, NAME_ATTR, &error); 1050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 1051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name == "android.permission.CAMERA") { 1052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasCameraPermission = true; 1053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.ACCESS_FINE_LOCATION") { 1054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasGpsPermission = true; 1055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.ACCESS_MOCK_LOCATION") { 1056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasMockLocPermission = true; 1057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.ACCESS_COARSE_LOCATION") { 1058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasCoarseLocPermission = true; 1059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" || 1060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.INSTALL_LOCATION_PROVIDER") { 1061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasGeneralLocPermission = true; 1062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.BLUETOOTH" || 1063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.BLUETOOTH_ADMIN") { 1064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasBluetoothPermission = true; 1065282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.RECORD_AUDIO") { 1066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasRecordAudioPermission = true; 1067282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.ACCESS_WIFI_STATE" || 1068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.CHANGE_WIFI_STATE" || 1069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.CHANGE_WIFI_MULTICAST_STATE") { 1070282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWiFiPermission = true; 1071282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.CALL_PHONE" || 1072282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.CALL_PRIVILEGED" || 1073282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.MODIFY_PHONE_STATE" || 1074282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.PROCESS_OUTGOING_CALLS" || 1075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.READ_SMS" || 1076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.RECEIVE_SMS" || 1077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.RECEIVE_MMS" || 1078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.RECEIVE_WAP_PUSH" || 1079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.SEND_SMS" || 1080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.WRITE_APN_SETTINGS" || 1081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name == "android.permission.WRITE_SMS") { 1082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasTelephonyPermission = true; 1083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.WRITE_EXTERNAL_STORAGE") { 1084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWriteExternalStoragePermission = true; 1085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.READ_EXTERNAL_STORAGE") { 1086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasReadExternalStoragePermission = true; 1087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.READ_PHONE_STATE") { 1088282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasReadPhoneStatePermission = true; 1089282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.READ_CONTACTS") { 1090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasReadContactsPermission = true; 1091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.WRITE_CONTACTS") { 1092282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWriteContactsPermission = true; 1093282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.READ_CALL_LOG") { 1094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasReadCallLogPermission = true; 1095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (name == "android.permission.WRITE_CALL_LOG") { 1096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWriteCallLogPermission = true; 1097282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1098282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-permission:'%s'\n", name.string()); 1099282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int req = getIntegerAttribute(tree, REQUIRED_ATTR, NULL, 1); 1100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!req) { 1101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("optional-permission:'%s'\n", name.string()); 1102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 1106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "uses-package") { 1109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getAttribute(tree, NAME_ATTR, &error); 1110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 1111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-package:'%s'\n", name.string()); 1112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 1115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "original-package") { 1118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getAttribute(tree, NAME_ATTR, &error); 1119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 1120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("original-package:'%s'\n", name.string()); 1121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 1124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "supports-gl-texture") { 1127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getAttribute(tree, NAME_ATTR, &error); 1128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 1129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("supports-gl-texture:'%s'\n", name.string()); 1130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error.string()); 1133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "compatible-screens") { 1136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printCompatibleScreens(tree); 1137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth--; 1138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "package-verifier") { 1139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getAttribute(tree, NAME_ATTR, &error); 1140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name != "" && error == "") { 1141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 publicKey = getAttribute(tree, PUBLIC_KEY_ATTR, &error); 1142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (publicKey != "" && error == "") { 1143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("package-verifier: name='%s' publicKey='%s'\n", 1144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name.string(), publicKey.string()); 1145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1148ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (depth == 3) { 1149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinActivity = false; 1150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinReceiver = false; 1151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski withinService = false; 1152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasIntentFilter = false; 1153ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (withinApplication) { 1154ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if(tag == "activity") { 1155ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright withinActivity = true; 1156ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright activityName = getAttribute(tree, NAME_ATTR, &error); 1157ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1158ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1159ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright error.string()); 1160ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1161ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1163ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright activityLabel = getResolvedAttribute(&res, tree, LABEL_ATTR, &error); 1164ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1165ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:label' attribute: %s\n", 1166ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright error.string()); 1167ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1168ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1170ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright activityIcon = getResolvedAttribute(&res, tree, ICON_ATTR, &error); 1171ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1172ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n", 1173ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright error.string()); 1174ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1175ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1177ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright int32_t orien = getResolvedIntegerAttribute(&res, tree, 1178ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright SCREEN_ORIENTATION_ATTR, &error); 1179ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error == "") { 1180ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (orien == 0 || orien == 6 || orien == 8) { 1181ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright // Requests landscape, sensorLandscape, or reverseLandscape. 1182ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright reqScreenLandscapeFeature = true; 1183ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (orien == 1 || orien == 7 || orien == 9) { 1184ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright // Requests portrait, sensorPortrait, or reversePortrait. 1185ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright reqScreenPortraitFeature = true; 1186ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1188ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (tag == "uses-library") { 1189ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright String8 libraryName = getAttribute(tree, NAME_ATTR, &error); 1190ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1191ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, 1192ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright "ERROR getting 'android:name' attribute for uses-library" 1193ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright " %s\n", error.string()); 1194ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1195ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1196ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright int req = getIntegerAttribute(tree, 1197ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright REQUIRED_ATTR, NULL, 1); 1198ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright printf("uses-library%s:'%s'\n", 1199ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright req ? "" : "-not-required", libraryName.string()); 1200ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (tag == "receiver") { 1201ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright withinReceiver = true; 1202ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright receiverName = getAttribute(tree, NAME_ATTR, &error); 1203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1204ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1205ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, 1206ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright "ERROR getting 'android:name' attribute for receiver:" 1207ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright " %s\n", error.string()); 1208ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1209ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1210ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (tag == "service") { 1211ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright withinService = true; 1212ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright serviceName = getAttribute(tree, NAME_ATTR, &error); 1213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1214ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1215ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:name' attribute for " 1216ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright "service:%s\n", error.string()); 1217ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1218ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1219ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (bundle->getIncludeMetaData() && tag == "meta-data") { 1220ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright String8 metaDataName = getAttribute(tree, NAME_ATTR, &error); 1221ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1222ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:name' attribute for " 1223ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright "meta-data:%s\n", error.string()); 1224ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1225ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1226ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright printf("meta-data: name='%s' ", metaDataName.string()); 1227ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright Res_value value; 1228ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright getResolvedResourceAttribute(&value, &res, tree, VALUE_ATTR, &error); 1229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 1230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR getting 'android:value' attribute for " 1231ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright "meta-data:%s\n", error.string()); 1232ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1233ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1234ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (value.dataType == Res_value::TYPE_STRING) { 1235ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright String8 metaDataValue = getAttribute(tree, value.data, &error); 1236ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1237ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:value' attribute for " 1238ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright "meta-data: %s\n", error.string()); 1239ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1240ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1241ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright printf("value='%s'\n", metaDataValue.string()); 1242ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (Res_value::TYPE_FIRST_INT <= value.dataType && 1243ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright value.dataType <= Res_value::TYPE_LAST_INT) { 1244ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright printf("value='%d'\n", value.data); 1245ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else { 1246ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright printf("value=(type 0x%x)0x%x", 1247ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright (int)value.dataType, (int)value.data); 1248ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1249ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (withinSupportsInput && tag == "input-type") { 1250ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright String8 name = getAttribute(tree, NAME_ATTR, &error); 1251ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (name != "" && error == "") { 1252ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright supportedInput.add(name); 1253ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else { 1254ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1255ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright error.string()); 1256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1259ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if ((depth == 4) && (tag == "intent-filter")) { 1260ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright hasIntentFilter = true; 1261ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright withinIntentFilter = true; 1262ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright actMainActivity = actWidgetReceivers = 1263ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright actImeService = actWallpaperService = false; 1264ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if ((depth == 5) && withinIntentFilter) { 1265ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright String8 action; 1266ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (tag == "action") { 1267ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright action = getAttribute(tree, NAME_ATTR, &error); 1268ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1269ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", 1270ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright error.string()); 1271ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1273ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (withinActivity) { 1274ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (action == "android.intent.action.MAIN") { 1275ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright isMainActivity = true; 1276ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright actMainActivity = true; 1277ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1278ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (withinReceiver) { 1279ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (action == "android.appwidget.action.APPWIDGET_UPDATE") { 1280ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright actWidgetReceivers = true; 1281ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1282ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (withinService) { 1283ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (action == "android.view.InputMethod") { 1284ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright actImeService = true; 1285ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } else if (action == "android.service.wallpaper.WallpaperService") { 1286ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright actWallpaperService = true; 1287ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1289ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (action == "android.intent.action.SEARCH") { 1290ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright isSearchable = true; 1291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1294ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (tag == "category") { 1295ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright String8 category = getAttribute(tree, NAME_ATTR, &error); 1296ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (error != "") { 1297ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright fprintf(stderr, "ERROR getting 'name' attribute: %s\n", 1298ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright error.string()); 1299ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright goto bail; 1300ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1301ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (withinActivity) { 1302ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright if (category == "android.intent.category.LAUNCHER") { 1303ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright isLauncherActivity = true; 1304ec4fdec76f2916b91a69d979f400cd69a3812631Michael Wright } 1305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Pre-1.6 implicitly granted permission compatibility logic 1312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (targetSdk < 4) { 1313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasWriteExternalStoragePermission) { 1314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-permission:'android.permission.WRITE_EXTERNAL_STORAGE'\n"); 1315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-permission:'android.permission.WRITE_EXTERNAL_STORAGE'," \ 1316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'targetSdkVersion < 4'\n"); 1317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasWriteExternalStoragePermission = true; 1318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasReadPhoneStatePermission) { 1320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-permission:'android.permission.READ_PHONE_STATE'\n"); 1321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-permission:'android.permission.READ_PHONE_STATE'," \ 1322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'targetSdkVersion < 4'\n"); 1323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If the application has requested WRITE_EXTERNAL_STORAGE, we will 1327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // force them to always take READ_EXTERNAL_STORAGE as well. We always 1328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // do this (regardless of target API version) because we can't have 1329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // an app with write permission but not read permission. 1330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasReadExternalStoragePermission && hasWriteExternalStoragePermission) { 1331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-permission:'android.permission.READ_EXTERNAL_STORAGE'\n"); 1332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-permission:'android.permission.READ_EXTERNAL_STORAGE'," \ 1333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'requested WRITE_EXTERNAL_STORAGE'\n"); 1334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Pre-JellyBean call log permission compatibility. 1337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (targetSdk < 16) { 1338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasReadCallLogPermission && hasReadContactsPermission) { 1339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-permission:'android.permission.READ_CALL_LOG'\n"); 1340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-permission:'android.permission.READ_CALL_LOG'," \ 1341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'targetSdkVersion < 16 and requested READ_CONTACTS'\n"); 1342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasWriteCallLogPermission && hasWriteContactsPermission) { 1344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-permission:'android.permission.WRITE_CALL_LOG'\n"); 1345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-permission:'android.permission.WRITE_CALL_LOG'," \ 1346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'targetSdkVersion < 16 and requested WRITE_CONTACTS'\n"); 1347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* The following blocks handle printing "inferred" uses-features, based 1351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * on whether related features or permissions are used by the app. 1352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Note that the various spec*Feature variables denote whether the 1353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * relevant tag was *present* in the AndroidManfest, not that it was 1354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * present and set to true. 1355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 1356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Camera-related back-compatibility logic 1357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!specCameraFeature) { 1358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqCameraFlashFeature) { 1359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if app requested a sub-feature (autofocus or flash) and didn't 1360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // request the base camera feature, we infer that it meant to 1361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.camera'\n"); 1362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-feature:'android.hardware.camera'," \ 1363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'requested android.hardware.camera.flash feature'\n"); 1364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (reqCameraAutofocusFeature) { 1365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if app requested a sub-feature (autofocus or flash) and didn't 1366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // request the base camera feature, we infer that it meant to 1367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.camera'\n"); 1368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-feature:'android.hardware.camera'," \ 1369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'requested android.hardware.camera.autofocus feature'\n"); 1370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (hasCameraPermission) { 1371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if app wants to use camera but didn't request the feature, we infer 1372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // that it meant to, and further that it wants autofocus 1373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // (which was the 1.0 - 1.5 behavior) 1374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.camera'\n"); 1375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!specCameraAutofocusFeature) { 1376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.camera.autofocus'\n"); 1377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-feature:'android.hardware.camera.autofocus'," \ 1378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'requested android.permission.CAMERA permission'\n"); 1379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Location-related back-compatibility logic 1384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!specLocationFeature && 1385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (hasMockLocPermission || hasCoarseLocPermission || hasGpsPermission || 1386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasGeneralLocPermission || reqNetworkLocFeature || reqGpsFeature)) { 1387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if app either takes a location-related permission or requests one of the 1388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // sub-features, we infer that it also meant to request the base location feature 1389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.location'\n"); 1390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-feature:'android.hardware.location'," \ 1391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'requested a location access permission'\n"); 1392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!specGpsFeature && hasGpsPermission) { 1394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if app takes GPS (FINE location) perm but does not request the GPS 1395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // feature, we infer that it meant to 1396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.location.gps'\n"); 1397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-feature:'android.hardware.location.gps'," \ 1398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'requested android.permission.ACCESS_FINE_LOCATION permission'\n"); 1399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!specNetworkLocFeature && hasCoarseLocPermission) { 1401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if app takes Network location (COARSE location) perm but does not request the 1402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // network location feature, we infer that it meant to 1403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.location.network'\n"); 1404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-feature:'android.hardware.location.network'," \ 1405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'requested android.permission.ACCESS_COARSE_LOCATION permission'\n"); 1406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Bluetooth-related compatibility logic 1409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!specBluetoothFeature && hasBluetoothPermission && (targetSdk > 4)) { 1410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if app takes a Bluetooth permission but does not request the Bluetooth 1411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // feature, we infer that it meant to 1412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.bluetooth'\n"); 1413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-feature:'android.hardware.bluetooth'," \ 1414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'requested android.permission.BLUETOOTH or android.permission.BLUETOOTH_ADMIN " \ 1415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "permission and targetSdkVersion > 4'\n"); 1416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Microphone-related compatibility logic 1419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!specMicrophoneFeature && hasRecordAudioPermission) { 1420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if app takes the record-audio permission but does not request the microphone 1421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // feature, we infer that it meant to 1422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.microphone'\n"); 1423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-feature:'android.hardware.microphone'," \ 1424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'requested android.permission.RECORD_AUDIO permission'\n"); 1425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // WiFi-related compatibility logic 1428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!specWiFiFeature && hasWiFiPermission) { 1429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if app takes one of the WiFi permissions but does not request the WiFi 1430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // feature, we infer that it meant to 1431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.wifi'\n"); 1432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-feature:'android.hardware.wifi'," \ 1433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'requested android.permission.ACCESS_WIFI_STATE, " \ 1434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "android.permission.CHANGE_WIFI_STATE, or " \ 1435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "android.permission.CHANGE_WIFI_MULTICAST_STATE permission'\n"); 1436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Telephony-related compatibility logic 1439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!specTelephonyFeature && (hasTelephonyPermission || reqTelephonySubFeature)) { 1440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if app takes one of the telephony permissions or requests a sub-feature but 1441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // does not request the base telephony feature, we infer that it meant to 1442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.telephony'\n"); 1443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-feature:'android.hardware.telephony'," \ 1444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'requested a telephony-related permission or feature'\n"); 1445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Touchscreen-related back-compatibility logic 1448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!specTouchscreenFeature) { // not a typo! 1449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // all apps are presumed to require a touchscreen, unless they explicitly say 1450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // <uses-feature android:name="android.hardware.touchscreen" android:required="false"/> 1451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Note that specTouchscreenFeature is true if the tag is present, regardless 1452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // of whether its value is true or false, so this is safe 1453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.touchscreen'\n"); 1454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-feature:'android.hardware.touchscreen'," \ 1455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'assumed you require a touch screen unless explicitly made optional'\n"); 1456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!specMultitouchFeature && reqDistinctMultitouchFeature) { 1458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if app takes one of the telephony permissions or requests a sub-feature but 1459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // does not request the base telephony feature, we infer that it meant to 1460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.touchscreen.multitouch'\n"); 1461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-feature:'android.hardware.touchscreen.multitouch'," \ 1462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'requested android.hardware.touchscreen.multitouch.distinct feature'\n"); 1463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Landscape/portrait-related compatibility logic 1466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!specScreenLandscapeFeature && !specScreenPortraitFeature) { 1467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If the app has specified any activities in its manifest 1468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // that request a specific orientation, then assume that 1469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // orientation is required. 1470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqScreenLandscapeFeature) { 1471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.screen.landscape'\n"); 1472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-feature:'android.hardware.screen.landscape'," \ 1473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'one or more activities have specified a landscape orientation'\n"); 1474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (reqScreenPortraitFeature) { 1476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-feature:'android.hardware.screen.portrait'\n"); 1477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("uses-implied-feature:'android.hardware.screen.portrait'," \ 1478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "'one or more activities have specified a portrait orientation'\n"); 1479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasMainActivity) { 1483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("main\n"); 1484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasWidgetReceivers) { 1486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("app-widget\n"); 1487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasImeService) { 1489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("ime\n"); 1490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasWallpaperService) { 1492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("wallpaper\n"); 1493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasOtherActivities) { 1495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("other-activities\n"); 1496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (isSearchable) { 1498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("search\n"); 1499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasOtherReceivers) { 1501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("other-receivers\n"); 1502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasOtherServices) { 1504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("other-services\n"); 1505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // For modern apps, if screen size buckets haven't been specified 1508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // but the new width ranges have, then infer the buckets from them. 1509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (smallScreen > 0 && normalScreen > 0 && largeScreen > 0 && xlargeScreen > 0 1510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && requiresSmallestWidthDp > 0) { 1511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int compatWidth = compatibleWidthLimitDp; 1512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (compatWidth <= 0) { 1513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski compatWidth = requiresSmallestWidthDp; 1514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (requiresSmallestWidthDp <= 240 && compatWidth >= 240) { 1516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski smallScreen = -1; 1517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski smallScreen = 0; 1519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (requiresSmallestWidthDp <= 320 && compatWidth >= 320) { 1521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski normalScreen = -1; 1522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski normalScreen = 0; 1524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (requiresSmallestWidthDp <= 480 && compatWidth >= 480) { 1526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski largeScreen = -1; 1527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski largeScreen = 0; 1529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (requiresSmallestWidthDp <= 720 && compatWidth >= 720) { 1531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski xlargeScreen = -1; 1532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski xlargeScreen = 0; 1534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Determine default values for any unspecified screen sizes, 1538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // based on the target SDK of the package. As of 4 (donut) 1539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the screen size support was introduced, so all default to 1540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // enabled. 1541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (smallScreen > 0) { 1542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski smallScreen = targetSdk >= 4 ? -1 : 0; 1543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (normalScreen > 0) { 1545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski normalScreen = -1; 1546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (largeScreen > 0) { 1548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski largeScreen = targetSdk >= 4 ? -1 : 0; 1549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (xlargeScreen > 0) { 1551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Introduced in Gingerbread. 1552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski xlargeScreen = targetSdk >= 9 ? -1 : 0; 1553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (anyDensity > 0) { 1555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski anyDensity = (targetSdk >= 4 || requiresSmallestWidthDp > 0 1556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || compatibleWidthLimitDp > 0) ? -1 : 0; 1557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("supports-screens:"); 1559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (smallScreen != 0) { 1560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" 'small'"); 1561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (normalScreen != 0) { 1563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" 'normal'"); 1564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (largeScreen != 0) { 1566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" 'large'"); 1567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (xlargeScreen != 0) { 1569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" 'xlarge'"); 1570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 1572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("supports-any-density: '%s'\n", anyDensity ? "true" : "false"); 1573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (requiresSmallestWidthDp > 0) { 1574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("requires-smallest-width:'%d'\n", requiresSmallestWidthDp); 1575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (compatibleWidthLimitDp > 0) { 1577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("compatible-width-limit:'%d'\n", compatibleWidthLimitDp); 1578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (largestWidthLimitDp > 0) { 1580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("largest-width-limit:'%d'\n", largestWidthLimitDp); 1581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("locales:"); 1584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NL = locales.size(); 1585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<NL; i++) { 1586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* localeStr = locales[i].string(); 1587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (localeStr == NULL || strlen(localeStr) == 0) { 1588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski localeStr = "--_--"; 1589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" '%s'", localeStr); 1591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 1593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("densities:"); 1595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t ND = densities.size(); 1596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<ND; i++) { 1597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" '%d'", densities[i]); 1598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 1600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AssetDir* dir = assets.openNonAssetDir(assetsCookie, "lib"); 1602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (dir != NULL) { 1603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (dir->getFileCount() > 0) { 1604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("native-code:"); 1605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<dir->getFileCount(); i++) { 1606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" '%s'", dir->getFileName(i).string()); 1607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 1609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete dir; 1611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("badger", option) == 0) { 1613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%s", CONSOLE_DATA); 1614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp("configurations", option) == 0) { 1615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<ResTable_config> configs; 1616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res.getConfigurations(&configs); 1617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = configs.size(); 1618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 1619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%s\n", configs[i].toString().string()); 1620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: unknown dump option '%s'\n", option); 1623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = NO_ERROR; 1628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 1630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (asset) { 1631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete asset; 1632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (result != NO_ERROR); 1634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 1638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Handle the "add" command, which wants to add files to a new or 1639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * pre-existing archive. 1640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 1641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doAdd(Bundle* bundle) 1642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipFile* zip = NULL; 1644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result = UNKNOWN_ERROR; 1645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* zipFileName; 1646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getUpdate()) { 1648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* avoid confusion */ 1649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: can't use '-u' with add\n"); 1650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 1) { 1654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: must specify zip file name\n"); 1655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zipFileName = bundle->getFileSpecEntry(0); 1658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 2) { 1660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "NOTE: nothing to do\n"); 1661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip = openReadWrite(zipFileName, true); 1665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (zip == NULL) { 1666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: failed opening/creating '%s' as Zip file\n", zipFileName); 1667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i = 1; i < bundle->getFileSpecCount(); i++) { 1671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* fileName = bundle->getFileSpecEntry(i); 1672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcasecmp(String8(fileName).getPathExtension().string(), ".gz") == 0) { 1674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" '%s'... (from gzip)\n", fileName); 1675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = zip->addGzip(fileName, String8(fileName).getBasePath().string(), NULL); 1676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getJunkPath()) { 1678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 storageName = String8(fileName).getPathLeaf(); 1679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" '%s' as '%s'...\n", fileName, storageName.string()); 1680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = zip->add(fileName, storageName.string(), 1681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bundle->getCompressionMethod(), NULL); 1682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" '%s'...\n", fileName); 1684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = zip->add(fileName, bundle->getCompressionMethod(), NULL); 1685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result != NO_ERROR) { 1688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "Unable to add '%s' to '%s'", bundle->getFileSpecEntry(i), zipFileName); 1689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result == NAME_NOT_FOUND) { 1690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, ": file not found\n"); 1691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (result == ALREADY_EXISTS) { 1692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, ": already exists in archive\n"); 1693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "\n"); 1695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = NO_ERROR; 1701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 1703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete zip; 1704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (result != NO_ERROR); 1705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 1709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Delete files from an existing archive. 1710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 1711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doRemove(Bundle* bundle) 1712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipFile* zip = NULL; 1714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result = UNKNOWN_ERROR; 1715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* zipFileName; 1716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 1) { 1718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: must specify zip file name\n"); 1719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zipFileName = bundle->getFileSpecEntry(0); 1722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getFileSpecCount() < 2) { 1724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "NOTE: nothing to do\n"); 1725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip = openReadWrite(zipFileName, false); 1729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (zip == NULL) { 1730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: failed opening Zip archive '%s'\n", 1731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zipFileName); 1732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i = 1; i < bundle->getFileSpecCount(); i++) { 1736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* fileName = bundle->getFileSpecEntry(i); 1737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry* entry; 1738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entry = zip->getEntryByName(fileName); 1740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (entry == NULL) { 1741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" '%s' NOT FOUND\n", fileName); 1742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = zip->remove(entry); 1746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result != NO_ERROR) { 1748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "Unable to delete '%s' from '%s'\n", 1749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bundle->getFileSpecEntry(i), zipFileName); 1750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* update the archive */ 1755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zip->flush(); 1756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 1758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete zip; 1759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (result != NO_ERROR); 1760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 1764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Package up an asset directory and associated application files. 1765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 1766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doPackage(Bundle* bundle) 1767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* outputAPKFile; 1769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int retVal = 1; 1770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err; 1771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptAssets> assets; 1772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int N; 1773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FILE* fp; 1774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 dependencyFile; 1775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // -c zz_ZZ means do pseudolocalization 1777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceFilter filter; 1778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = filter.parse(bundle->getConfigurations()); 1779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (filter.containsPseudo()) { 1783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bundle->setPseudolocalize(true); 1784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski N = bundle->getFileSpecCount(); 1787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (N < 1 && bundle->getResourceSourceDirs().size() == 0 && bundle->getJarFiles().size() == 0 1788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && bundle->getAndroidManifestFile() == NULL && bundle->getAssetSourceDir() == NULL) { 1789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: no input files\n"); 1790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outputAPKFile = bundle->getOutputAPKFile(); 1794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Make sure the filenames provided exist and are of the appropriate type. 1796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outputAPKFile) { 1797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FileType type; 1798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type = getFileType(outputAPKFile); 1799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (type != kFileTypeNonexistent && type != kFileTypeRegular) { 1800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, 1801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "ERROR: output file '%s' exists but is not regular file\n", 1802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outputAPKFile); 1803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Load the assets. 1808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets = new AaptAssets(); 1809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Set up the resource gathering in assets if we're going to generate 1811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // dependency files. Every time we encounter a resource while slurping 1812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the tree, we'll add it to these stores so we have full resource paths 1813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // to write to a dependency file. 1814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getGenDependencies()) { 1815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<FilePathStore> resPathStore = new FilePathStore; 1816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->setFullResPaths(resPathStore); 1817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<FilePathStore> assetPathStore = new FilePathStore; 1818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->setFullAssetPaths(assetPathStore); 1819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = assets->slurpFromArgs(bundle); 1822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 1823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 1827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->print(String8()); 1828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If they asked for any fileAs that need to be compiled, do so. 1831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getResourceSourceDirs().size() || bundle->getAndroidManifestFile()) { 1832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = buildResources(bundle, assets); 1833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != 0) { 1834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // At this point we've read everything and processed everything. From here 1839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // on out it's just writing output files. 1840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (SourcePos::hasErrors()) { 1841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Update symbols with information about which ones are needed as Java symbols. 1845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->applyJavaSymbols(); 1846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (SourcePos::hasErrors()) { 1847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If we've been asked to generate a dependency file, do that here 1851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getGenDependencies()) { 1852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If this is the packaging step, generate the dependency file next to 1853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the output apk (e.g. bin/resources.ap_.d) 1854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outputAPKFile) { 1855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dependencyFile = String8(outputAPKFile); 1856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Add the .d extension to the dependency file. 1857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dependencyFile.append(".d"); 1858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Else if this is the R.java dependency generation step, 1860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // generate the dependency file in the R.java package subdirectory 1861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // e.g. gen/com/foo/app/R.java.d 1862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dependencyFile = String8(bundle->getRClassDir()); 1863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dependencyFile.appendPath("R.java.d"); 1864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Make sure we have a clean dependency file to start with 1866282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fp = fopen(dependencyFile, "w"); 1867282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fclose(fp); 1868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write out R.java constants 1871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!assets->havePrivateSymbols()) { 1872282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getCustomPackage() == NULL) { 1873282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write the R.java file into the appropriate class directory 1874282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // e.g. gen/com/foo/app/R.java 1875282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeResourceSymbols(bundle, assets, assets->getPackage(), true); 1876282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1877282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8 customPkg(bundle->getCustomPackage()); 1878282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeResourceSymbols(bundle, assets, customPkg, true); 1879282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1880282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 1881282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1882282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1883282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If we have library files, we're going to write our R.java file into 1884282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the appropriate class directory for those libraries as well. 1885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // e.g. gen/com/foo/app/lib/R.java 1886282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getExtraPackages() != NULL) { 1887282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Split on colon 1888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 libs(bundle->getExtraPackages()); 1889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char* packageString = strtok(libs.lockBuffer(libs.length()), ":"); 1890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (packageString != NULL) { 1891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write the R.java file out with the correct package name 1892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeResourceSymbols(bundle, assets, String8(packageString), true); 1893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 1894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski packageString = strtok(NULL, ":"); 1897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski libs.unlockBuffer(); 1899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeResourceSymbols(bundle, assets, assets->getPackage(), false); 1902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 1903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeResourceSymbols(bundle, assets, assets->getSymbolsPrivatePackage(), true); 1906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 1907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write out the ProGuard file 1912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeProguardFile(bundle, assets); 1913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 1914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1916282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1917282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write the apk 1918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outputAPKFile) { 1919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeAPK(bundle, assets, String8(outputAPKFile)); 1920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: packaging of '%s' failed\n", outputAPKFile); 1922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If we've been asked to generate a dependency file, we need to finish up here. 1927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the writeResourceSymbols and writeAPK functions have already written the target 1928282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // half of the dependency file, now we need to write the prerequisites. (files that 1929282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the R.java file or .ap_ file depend on) 1930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getGenDependencies()) { 1931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Now that writeResourceSymbols or writeAPK has taken care of writing 1932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the targets to our dependency file, we'll write the prereqs 1933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fp = fopen(dependencyFile, "a+"); 1934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, " : "); 1935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool includeRaw = (outputAPKFile != NULL); 1936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeDependencyPreReqs(bundle, assets, fp, includeRaw); 1937282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Also manually add the AndroidManifeset since it's not under res/ or assets/ 1938282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // and therefore was not added to our pathstores during slurping 1939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s \\\n", bundle->getAndroidManifestFile()); 1940282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fclose(fp); 1941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1942282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski retVal = 0; 1944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 1945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (SourcePos::hasErrors()) { 1946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos::printErrors(stderr); 1947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return retVal; 1949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1950282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1951282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 1952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Do PNG Crunching 1953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * PRECONDITIONS 1954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * -S flag points to a source directory containing drawable* folders 1955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * -C flag points to destination directory. The folder structure in the 1956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * source directory will be mirrored to the destination (cache) directory 1957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 1958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * POSTCONDITIONS 1959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Destination directory will be updated to match the PNG files in 1960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * the source directory. 1961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 1962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doCrunch(Bundle* bundle) 1963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "Crunching PNG Files in "); 1965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "source dir: %s\n", bundle->getResourceSourceDirs()[0]); 1966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "To destination dir: %s\n", bundle->getCrunchedOutputDir()); 1967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski updatePreProcessedCache(bundle); 1969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 1971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 1974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Do PNG Crunching on a single flag 1975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * -i points to a single png file 1976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * -o points to a single png output file 1977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 1978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint doSingleCrunch(Bundle* bundle) 1979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "Crunching single PNG file: %s\n", bundle->getSingleCrunchInputFile()); 1981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "\tOutput file: %s\n", bundle->getSingleCrunchOutputFile()); 1982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 input(bundle->getSingleCrunchInputFile()); 1984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 output(bundle->getSingleCrunchOutputFile()); 1985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (preProcessImageToCache(bundle, input, output) != NO_ERROR) { 1987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // we can't return the status_t as it gets truncate to the lower 8 bits. 1988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 42; 1989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 1992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskichar CONSOLE_DATA[2925] = { 1995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 95, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 1999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 63, 2000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 86, 35, 40, 46, 46, 95, 95, 95, 95, 97, 97, 44, 32, 46, 124, 42, 33, 83, 2001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 62, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 46, 58, 59, 61, 59, 61, 81, 2004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 66, 96, 61, 61, 58, 46, 46, 46, 58, 32, 32, 32, 32, 32, 32, 2005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 2006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 46, 61, 59, 59, 59, 58, 106, 81, 81, 81, 81, 102, 59, 61, 59, 2008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 61, 61, 61, 58, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 2011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 58, 109, 81, 81, 81, 81, 61, 59, 59, 59, 59, 59, 58, 59, 59, 46, 32, 2012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 60, 81, 81, 81, 81, 87, 2015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 58, 59, 59, 59, 59, 59, 59, 61, 119, 44, 32, 32, 32, 32, 32, 32, 32, 32, 2016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 2017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 2018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 47, 61, 59, 59, 58, 100, 81, 81, 81, 81, 35, 58, 59, 59, 59, 59, 59, 58, 2019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 121, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 109, 58, 59, 59, 61, 81, 81, 2022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 109, 58, 59, 59, 59, 59, 61, 109, 81, 81, 76, 46, 32, 32, 32, 2023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 2024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 41, 87, 59, 61, 59, 41, 81, 81, 81, 81, 81, 81, 59, 61, 59, 2026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 58, 109, 81, 81, 87, 39, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 60, 81, 91, 59, 2029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 61, 81, 81, 81, 81, 81, 87, 43, 59, 58, 59, 60, 81, 81, 81, 76, 32, 2030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 52, 91, 58, 45, 59, 87, 81, 81, 81, 81, 2033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 70, 58, 58, 58, 59, 106, 81, 81, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32, 2034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 2035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 93, 40, 32, 46, 59, 100, 81, 81, 81, 81, 40, 58, 46, 46, 58, 100, 81, 2037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 68, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 46, 46, 46, 32, 46, 46, 46, 32, 46, 32, 46, 45, 91, 59, 61, 58, 109, 2040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 87, 46, 58, 61, 59, 60, 81, 81, 80, 32, 32, 32, 32, 32, 32, 2041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 2042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 46, 46, 61, 59, 61, 61, 61, 59, 61, 61, 59, 2043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 58, 58, 46, 46, 41, 58, 59, 58, 81, 81, 81, 81, 69, 58, 59, 59, 2044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 60, 81, 81, 68, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 58, 59, 2046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 61, 46, 2047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 59, 93, 81, 81, 81, 81, 107, 58, 59, 58, 109, 87, 68, 96, 32, 32, 32, 2048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 10, 32, 32, 32, 46, 60, 61, 61, 59, 59, 59, 59, 59, 59, 59, 59, 2050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 59, 59, 59, 58, 58, 58, 115, 109, 68, 41, 36, 81, 2051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 109, 46, 61, 61, 81, 69, 96, 46, 58, 58, 46, 58, 46, 46, 32, 32, 32, 32, 2052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 46, 32, 95, 81, 2053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 67, 61, 61, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 2054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 58, 68, 39, 61, 105, 61, 63, 81, 119, 58, 106, 80, 32, 58, 2055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 59, 59, 61, 59, 61, 59, 61, 46, 95, 32, 32, 32, 32, 32, 32, 32, 32, 2056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 10, 32, 32, 36, 81, 109, 105, 59, 61, 59, 59, 59, 2057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 46, 58, 37, 2058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 73, 108, 108, 62, 52, 81, 109, 34, 32, 61, 59, 59, 59, 59, 59, 59, 59, 59, 2059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 61, 59, 61, 61, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 2060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 46, 45, 57, 101, 43, 43, 61, 61, 59, 59, 59, 59, 59, 59, 61, 59, 59, 2061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 59, 58, 97, 46, 61, 108, 62, 126, 58, 106, 80, 96, 2062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46, 61, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 61, 2063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 97, 103, 97, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 45, 46, 32, 2064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45, 58, 59, 59, 59, 59, 61, 2065282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 119, 81, 97, 124, 105, 124, 124, 39, 126, 95, 119, 58, 61, 58, 59, 59, 59, 2066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 119, 81, 81, 99, 32, 32, 2067282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 58, 106, 81, 81, 81, 109, 119, 2069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 119, 119, 109, 109, 81, 81, 122, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 2070282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 58, 115, 81, 87, 81, 102, 32, 32, 32, 32, 32, 32, 10, 2071282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2072282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 61, 58, 59, 61, 81, 81, 81, 81, 81, 81, 87, 87, 81, 81, 81, 81, 2073282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 58, 59, 59, 59, 59, 59, 59, 59, 59, 58, 45, 45, 45, 59, 59, 59, 41, 2074282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 87, 66, 33, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 2075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 93, 81, 2076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 2077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 45, 32, 46, 32, 32, 32, 32, 32, 46, 32, 126, 96, 32, 32, 32, 32, 32, 32, 2078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 58, 61, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81, 2080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 2081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 2082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 2083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58, 2084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 60, 81, 81, 81, 81, 2087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 81, 81, 81, 81, 59, 61, 59, 59, 61, 32, 32, 32, 32, 2088282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2089282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 58, 59, 59, 93, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 2091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 40, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2092282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 2093282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 106, 2094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 76, 58, 59, 59, 59, 2095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2097282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 61, 58, 58, 81, 81, 81, 81, 81, 81, 81, 81, 2098282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 87, 58, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 2099282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 2100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 58, 59, 61, 41, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 87, 59, 2102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 58, 59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 61, 81, 81, 81, 2105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 81, 81, 81, 81, 81, 81, 81, 81, 107, 58, 59, 59, 59, 59, 58, 32, 32, 2106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 58, 59, 59, 58, 51, 81, 81, 81, 81, 81, 81, 81, 81, 81, 2109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81, 102, 94, 59, 59, 59, 59, 59, 61, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 2111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 2112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 43, 63, 36, 81, 81, 81, 87, 64, 86, 102, 58, 59, 59, 59, 59, 59, 2113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 59, 59, 43, 33, 2116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 58, 126, 126, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32, 32, 2117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 2118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 2119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 59, 59, 59, 58, 45, 58, 61, 59, 58, 58, 58, 61, 59, 59, 59, 59, 59, 2120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 2121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 2122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 58, 95, 2123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 45, 61, 59, 61, 59, 59, 59, 59, 59, 59, 59, 45, 58, 59, 59, 59, 59, 2124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 58, 61, 59, 59, 59, 59, 59, 61, 59, 61, 46, 46, 32, 45, 45, 45, 2127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 58, 45, 45, 46, 58, 59, 59, 59, 59, 59, 59, 61, 46, 32, 32, 32, 32, 2128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 2129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 58, 59, 59, 59, 59, 2130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 61, 59, 46, 32, 32, 46, 32, 46, 32, 58, 61, 59, 59, 2131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 59, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 45, 59, 59, 59, 59, 59, 59, 59, 59, 58, 32, 2134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 58, 32, 2135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 2136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46, 61, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 61, 2138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46, 61, 59, 59, 59, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 2140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 2141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 46, 61, 58, 59, 59, 59, 59, 2142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 58, 59, 59, 59, 59, 59, 59, 59, 59, 46, 46, 32, 32, 32, 2145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 45, 32, 32, 32, 32, 32, 2146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 2147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 32, 45, 61, 2148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 2149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59, 59, 59, 58, 45, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45, 45, 32, 46, 32, 2152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 61, 59, 58, 45, 45, 32, 32, 32, 2153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 46, 32, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10 2158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski }; 2159