19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Copyright 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Android Asset Packaging Tool main entry point.
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "Main.h"
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "Bundle.h"
8e6b680364dd992907a8d2037685a2e500d188dfbDianne Hackborn#include "ResourceFilter.h"
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "ResourceTable.h"
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "XMLNode.h"
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
123b4062eeb01be33951ba214e027da523cf09f8b1Mathias Agopian#include <utils/Log.h>
133b4062eeb01be33951ba214e027da523cf09f8b1Mathias Agopian#include <utils/threads.h>
143b4062eeb01be33951ba214e027da523cf09f8b1Mathias Agopian#include <utils/List.h>
153b4062eeb01be33951ba214e027da523cf09f8b1Mathias Agopian#include <utils/Errors.h>
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <fcntl.h>
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <errno.h>
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectusing namespace android;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Show version info.  All the cool kids do it.
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint doVersion(Bundle* bundle)
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (bundle->getFileSpecCount() != 0)
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        printf("(ignoring extra arguments)\n");
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    printf("Android Asset Packaging Tool, v0.2\n");
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return 0;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open the file read only.  The call fails if the file doesn't exist.
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns NULL on failure.
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectZipFile* openReadOnly(const char* fileName)
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ZipFile* zip;
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t result;
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    zip = new ZipFile;
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    result = zip->open(fileName, ZipFile::kOpenReadOnly);
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (result != NO_ERROR) {
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (result == NAME_NOT_FOUND)
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "ERROR: '%s' not found\n", fileName);
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        else if (result == PERMISSION_DENIED)
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "ERROR: '%s' access denied\n", fileName);
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        else
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "ERROR: failed opening '%s' as Zip file\n",
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fileName);
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        delete zip;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return zip;
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open the file read-write.  The file will be created if it doesn't
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * already exist and "okayToCreate" is set.
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns NULL on failure.
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectZipFile* openReadWrite(const char* fileName, bool okayToCreate)
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ZipFile* zip = NULL;
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t result;
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int flags;
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    flags = ZipFile::kOpenReadWrite;
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (okayToCreate)
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        flags |= ZipFile::kOpenCreate;
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    zip = new ZipFile;
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    result = zip->open(fileName, flags);
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (result != NO_ERROR) {
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        delete zip;
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        zip = NULL;
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto bail;
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbail:
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return zip;
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return a short string describing the compression method.
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst char* compressionName(int method)
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (method == ZipEntry::kCompressStored)
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return "Stored";
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    else if (method == ZipEntry::kCompressDeflated)
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return "Deflated";
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    else
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return "Unknown";
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the percent reduction in size (0% == no compression).
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint calcPercent(long uncompressedLen, long compressedLen)
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!uncompressedLen)
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0;
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    else
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return (int) (100.0 - (compressedLen * 100.0) / uncompressedLen + 0.5);
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Handle the "list" command, which can be a simple file dump or
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a verbose listing.
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The verbose listing closely matches the output of the Info-ZIP "unzip"
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * command.
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint doList(Bundle* bundle)
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int result = 1;
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ZipFile* zip = NULL;
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const ZipEntry* entry;
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    long totalUncLen, totalCompLen;
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* zipFileName;
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (bundle->getFileSpecCount() != 1) {
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "ERROR: specify zip file name (only)\n");
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto bail;
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    zipFileName = bundle->getFileSpecEntry(0);
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    zip = openReadOnly(zipFileName);
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (zip == NULL)
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto bail;
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int count, i;
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (bundle->getVerbose()) {
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        printf("Archive:  %s\n", zipFileName);
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        printf(
145fb2a9467ad77336edbf2a1a272dbe6ec30ef8a1bKenny Root            " Length   Method    Size  Ratio   Offset      Date  Time  CRC-32    Name\n");
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        printf(
147fb2a9467ad77336edbf2a1a272dbe6ec30ef8a1bKenny Root            "--------  ------  ------- -----  -------      ----  ----  ------    ----\n");
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    totalUncLen = totalCompLen = 0;
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    count = zip->getNumEntries();
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (i = 0; i < count; i++) {
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        entry = zip->getEntryByIndex(i);
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (bundle->getVerbose()) {
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            char dateBuf[32];
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            time_t when;
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            when = entry->getModWhen();
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            strftime(dateBuf, sizeof(dateBuf), "%m-%d-%y %H:%M",
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                localtime(&when));
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
163fb2a9467ad77336edbf2a1a272dbe6ec30ef8a1bKenny Root            printf("%8ld  %-7.7s %7ld %3d%%  %8zd  %s  %08lx  %s\n",
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                (long) entry->getUncompressedLen(),
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                compressionName(entry->getCompressionMethod()),
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                (long) entry->getCompressedLen(),
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                calcPercent(entry->getUncompressedLen(),
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            entry->getCompressedLen()),
169fb2a9467ad77336edbf2a1a272dbe6ec30ef8a1bKenny Root                (size_t) entry->getLFHOffset(),
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dateBuf,
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                entry->getCRC32(),
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                entry->getFileName());
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            printf("%s\n", entry->getFileName());
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        totalUncLen += entry->getUncompressedLen();
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        totalCompLen += entry->getCompressedLen();
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (bundle->getVerbose()) {
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        printf(
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        "--------          -------  ---                            -------\n");
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        printf("%8ld          %7ld  %2d%%                            %d files\n",
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            totalUncLen,
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            totalCompLen,
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            calcPercent(totalUncLen, totalCompLen),
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            zip->getNumEntries());
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (bundle->getAndroidList()) {
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AssetManager assets;
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!assets.addAssetPath(String8(zipFileName), NULL)) {
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "ERROR: list -a failed because assets could not be loaded\n");
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            goto bail;
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1977ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const ResTable& res = assets.getResources(false);
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (&res == NULL) {
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            printf("\nNo resource table found.\n");
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
202f1ff21ac62a51f5ba8ca0821ea8a90f70957e25dSteve Block#ifndef HAVE_ANDROID_OS
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            printf("\nResource table:\n");
204e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn            res.print(false);
205f1ff21ac62a51f5ba8ca0821ea8a90f70957e25dSteve Block#endif
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2077ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Asset* manifestAsset = assets.openNonAsset("AndroidManifest.xml",
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                   Asset::ACCESS_BUFFER);
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (manifestAsset == NULL) {
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            printf("\nNo AndroidManifest.xml found.\n");
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            printf("\nAndroid manifest:\n");
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ResXMLTree tree;
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            tree.setTo(manifestAsset->getBuffer(true),
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                       manifestAsset->getLength());
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            printXMLBlock(&tree);
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        delete manifestAsset;
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2217ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    result = 0;
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbail:
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    delete zip;
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return result;
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic ssize_t indexOfAttribute(const ResXMLTree& tree, uint32_t attrRes)
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t N = tree.getAttributeCount();
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (size_t i=0; i<N; i++) {
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (tree.getAttributeNameResID(i) == attrRes) {
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return (ssize_t)i;
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return -1;
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2401553c82e084ac5763fb393857224145506771b99Joe OnoratoString8 getAttribute(const ResXMLTree& tree, const char* ns,
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            const char* attr, String8* outError)
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t idx = tree.indexOfAttribute(ns, attr);
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (idx < 0) {
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return String8();
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Res_value value;
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (tree.getAttributeValue(idx, &value) != NO_ERROR) {
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (value.dataType != Res_value::TYPE_STRING) {
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (outError != NULL) *outError = "attribute is not a string value";
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return String8();
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t len;
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const uint16_t* str = tree.getAttributeStringValue(idx, &len);
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return str ? String8(str, len) : String8();
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic String8 getAttribute(const ResXMLTree& tree, uint32_t attrRes, String8* outError)
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t idx = indexOfAttribute(tree, attrRes);
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (idx < 0) {
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return String8();
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Res_value value;
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (tree.getAttributeValue(idx, &value) != NO_ERROR) {
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (value.dataType != Res_value::TYPE_STRING) {
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (outError != NULL) *outError = "attribute is not a string value";
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return String8();
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t len;
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const uint16_t* str = tree.getAttributeStringValue(idx, &len);
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return str ? String8(str, len) : String8();
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
277bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackbornstatic int32_t getIntegerAttribute(const ResXMLTree& tree, uint32_t attrRes,
278bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn        String8* outError, int32_t defValue = -1)
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t idx = indexOfAttribute(tree, attrRes);
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (idx < 0) {
282bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn        return defValue;
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Res_value value;
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (tree.getAttributeValue(idx, &value) != NO_ERROR) {
286bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn        if (value.dataType < Res_value::TYPE_FIRST_INT
287bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                || value.dataType > Res_value::TYPE_LAST_INT) {
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (outError != NULL) *outError = "attribute is not an integer value";
289bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn            return defValue;
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return value.data;
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
295f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackbornstatic int32_t getResolvedIntegerAttribute(const ResTable* resTable, const ResXMLTree& tree,
296f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn        uint32_t attrRes, String8* outError, int32_t defValue = -1)
297f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn{
298f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn    ssize_t idx = indexOfAttribute(tree, attrRes);
299f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn    if (idx < 0) {
300f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn        return defValue;
301f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn    }
302f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn    Res_value value;
303f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn    if (tree.getAttributeValue(idx, &value) != NO_ERROR) {
304f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn        if (value.dataType == Res_value::TYPE_REFERENCE) {
305f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn            resTable->resolveReference(&value, 0);
306f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn        }
307f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn        if (value.dataType < Res_value::TYPE_FIRST_INT
308f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn                || value.dataType > Res_value::TYPE_LAST_INT) {
309f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn            if (outError != NULL) *outError = "attribute is not an integer value";
310f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn            return defValue;
311f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn        }
312f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn    }
313f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn    return value.data;
314f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn}
315f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic String8 getResolvedAttribute(const ResTable* resTable, const ResXMLTree& tree,
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        uint32_t attrRes, String8* outError)
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t idx = indexOfAttribute(tree, attrRes);
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (idx < 0) {
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return String8();
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Res_value value;
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (tree.getAttributeValue(idx, &value) != NO_ERROR) {
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (value.dataType == Res_value::TYPE_STRING) {
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            size_t len;
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const uint16_t* str = tree.getAttributeStringValue(idx, &len);
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return str ? String8(str, len) : String8();
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        resTable->resolveReference(&value, 0);
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (value.dataType != Res_value::TYPE_STRING) {
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (outError != NULL) *outError = "attribute is not a string value";
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return String8();
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t len;
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const Res_value* value2 = &value;
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char16_t* str = const_cast<ResTable*>(resTable)->valueToString(value2, 0, NULL, &len);
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return str ? String8(str, len) : String8();
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// These are attribute resource constants for the platform, as found
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// in android.R.attr
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectenum {
345f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn    LABEL_ATTR = 0x01010001,
346f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn    ICON_ATTR = 0x01010002,
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NAME_ATTR = 0x01010003,
348b6ec11ef372a498c4d5fd2317a015b808495a2edDan Morrill    DEBUGGABLE_ATTR = 0x0101000f,
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    VERSION_CODE_ATTR = 0x0101021b,
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    VERSION_NAME_ATTR = 0x0101021c,
351f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn    SCREEN_ORIENTATION_ATTR = 0x0101001e,
352bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn    MIN_SDK_VERSION_ATTR = 0x0101020c,
35375c498426a17b47d445711bb9e36794b05876a56Suchi Amalapurapu    MAX_SDK_VERSION_ATTR = 0x01010271,
354bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn    REQ_TOUCH_SCREEN_ATTR = 0x01010227,
355bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn    REQ_KEYBOARD_TYPE_ATTR = 0x01010228,
356bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn    REQ_HARD_KEYBOARD_ATTR = 0x01010229,
357bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn    REQ_NAVIGATION_ATTR = 0x0101022a,
358bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn    REQ_FIVE_WAY_NAV_ATTR = 0x01010232,
359bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn    TARGET_SDK_VERSION_ATTR = 0x01010270,
360bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn    TEST_ONLY_ATTR = 0x01010272,
361a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn    ANY_DENSITY_ATTR = 0x0101026c,
362e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn    GL_ES_VERSION_ATTR = 0x01010281,
363723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn    SMALL_SCREEN_ATTR = 0x01010284,
364723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn    NORMAL_SCREEN_ATTR = 0x01010285,
365723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn    LARGE_SCREEN_ATTR = 0x01010286,
366f43489d7d5e1c0c5c9a7e54c22845fcb99765f81Dianne Hackborn    XLARGE_SCREEN_ATTR = 0x010102bf,
367e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn    REQUIRED_ATTR = 0x0101028e,
368a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn    SCREEN_SIZE_ATTR = 0x010102ca,
369a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn    SCREEN_DENSITY_ATTR = 0x010102cb,
370e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn    REQUIRES_SMALLEST_WIDTH_DP_ATTR = 0x01010364,
371e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn    COMPATIBLE_WIDTH_LIMIT_DP_ATTR = 0x01010365,
372e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn    LARGEST_WIDTH_LIMIT_DP_ATTR = 0x01010366,
37356088a55ca6c9277f09040a7883117cb127e1e56Kenny Root    PUBLIC_KEY_ATTR = 0x010103a6,
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3767ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapuconst char *getComponentName(String8 &pkgName, String8 &componentName) {
3777ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu    ssize_t idx = componentName.find(".");
3787ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu    String8 retStr(pkgName);
3797ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu    if (idx == 0) {
3807ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu        retStr += componentName;
3817ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu    } else if (idx < 0) {
3827ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu        retStr += ".";
3837ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu        retStr += componentName;
3847ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu    } else {
3857ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu        return componentName.string();
3867ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu    }
3877ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu    return retStr.string();
3887ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu}
3897ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu
390a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackbornstatic void printCompatibleScreens(ResXMLTree& tree) {
391a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn    size_t len;
392a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn    ResXMLTree::event_code_t code;
393a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn    int depth = 0;
394a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn    bool first = true;
395a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn    printf("compatible-screens:");
396a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn    while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
397a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn        if (code == ResXMLTree::END_TAG) {
398a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn            depth--;
399a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn            if (depth < 0) {
400a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn                break;
401a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn            }
402a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn            continue;
403a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn        }
404a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn        if (code != ResXMLTree::START_TAG) {
405a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn            continue;
406a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn        }
407a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn        depth++;
408a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn        String8 tag(tree.getElementName(&len));
409a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn        if (tag == "screen") {
410a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn            int32_t screenSize = getIntegerAttribute(tree,
411a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn                    SCREEN_SIZE_ATTR, NULL, -1);
412a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn            int32_t screenDensity = getIntegerAttribute(tree,
413a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn                    SCREEN_DENSITY_ATTR, NULL, -1);
414a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn            if (screenSize > 0 && screenDensity > 0) {
415a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn                if (!first) {
416a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn                    printf(",");
417a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn                }
418a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn                first = false;
419a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn                printf("'%d/%d'", screenSize, screenDensity);
420a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn            }
421a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn        }
422a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn    }
423a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn    printf("\n");
424a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn}
425a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Handle the "dump" command, to extract select data from an archive.
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
429e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrillextern char CONSOLE_DATA[2925]; // see EOF
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint doDump(Bundle* bundle)
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t result = UNKNOWN_ERROR;
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Asset* asset = NULL;
4347ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (bundle->getFileSpecCount() < 1) {
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "ERROR: no dump option specified\n");
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 1;
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4397ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (bundle->getFileSpecCount() < 2) {
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "ERROR: no dump file specified\n");
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 1;
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4447ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* option = bundle->getFileSpecEntry(0);
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* filename = bundle->getFileSpecEntry(1);
4477ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    AssetManager assets;
449bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn    void* assetsCookie;
450bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn    if (!assets.addAssetPath(String8(filename), &assetsCookie)) {
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "ERROR: dump failed because assets could not be loaded\n");
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 1;
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4547ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu
455e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn    // Make a dummy config for retrieving resources...  we need to supply
456e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn    // non-default values for some configs so that we can retrieve resources
457e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn    // in the app that don't have a default.  The most important of these is
458e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn    // the API version because key resources like icons will have an implicit
459e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn    // version if they are using newer config types like density.
460e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn    ResTable_config config;
461e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn    config.language[0] = 'e';
462e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn    config.language[1] = 'n';
463e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn    config.country[0] = 'U';
464e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn    config.country[1] = 'S';
465e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn    config.orientation = ResTable_config::ORIENTATION_PORT;
466e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn    config.density = ResTable_config::DENSITY_MEDIUM;
467e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn    config.sdkVersion = 10000; // Very high.
468e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn    config.screenWidthDp = 320;
469e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn    config.screenHeightDp = 480;
470e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn    config.smallestScreenWidthDp = 320;
471e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn    assets.setConfiguration(config);
472e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const ResTable& res = assets.getResources(false);
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (&res == NULL) {
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "ERROR: dump failed because no resource table was found\n");
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto bail;
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4787ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (strcmp("resources", option) == 0) {
480f1ff21ac62a51f5ba8ca0821ea8a90f70957e25dSteve Block#ifndef HAVE_ANDROID_OS
481e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn        res.print(bundle->getValues());
482f1ff21ac62a51f5ba8ca0821ea8a90f70957e25dSteve Block#endif
4836c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn
4846c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn    } else if (strcmp("strings", option) == 0) {
4856c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn        const ResStringPool* pool = res.getTableStringBlock(0);
4866c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn        printStringPool(pool);
4876c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (strcmp("xmltree", option) == 0) {
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (bundle->getFileSpecCount() < 3) {
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "ERROR: no dump xmltree resource file specified\n");
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            goto bail;
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4937ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i=2; i<bundle->getFileSpecCount(); i++) {
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const char* resname = bundle->getFileSpecEntry(i);
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ResXMLTree tree;
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            asset = assets.openNonAsset(resname, Asset::ACCESS_BUFFER);
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (asset == NULL) {
49944b283dc27ed8ba5a946d809489f29b4ae88cb15Kenny Root                fprintf(stderr, "ERROR: dump failed because resource %s found\n", resname);
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                goto bail;
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5027ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (tree.setTo(asset->getBuffer(true),
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           asset->getLength()) != NO_ERROR) {
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fprintf(stderr, "ERROR: Resource %s is corrupt\n", resname);
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                goto bail;
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            tree.restart();
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            printXMLBlock(&tree);
51019138468caf7050d482dc15f35a344eab11bb756Kenny Root            tree.uninit();
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            delete asset;
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            asset = NULL;
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5147ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (strcmp("xmlstrings", option) == 0) {
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (bundle->getFileSpecCount() < 3) {
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "ERROR: no dump xmltree resource file specified\n");
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            goto bail;
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5207ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i=2; i<bundle->getFileSpecCount(); i++) {
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const char* resname = bundle->getFileSpecEntry(i);
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ResXMLTree tree;
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            asset = assets.openNonAsset(resname, Asset::ACCESS_BUFFER);
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (asset == NULL) {
52644b283dc27ed8ba5a946d809489f29b4ae88cb15Kenny Root                fprintf(stderr, "ERROR: dump failed because resource %s found\n", resname);
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                goto bail;
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5297ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (tree.setTo(asset->getBuffer(true),
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           asset->getLength()) != NO_ERROR) {
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fprintf(stderr, "ERROR: Resource %s is corrupt\n", resname);
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                goto bail;
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            printStringPool(&tree.getStrings());
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            delete asset;
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            asset = NULL;
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5397ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ResXMLTree tree;
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        asset = assets.openNonAsset("AndroidManifest.xml",
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                            Asset::ACCESS_BUFFER);
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (asset == NULL) {
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "ERROR: dump failed because no AndroidManifest.xml found\n");
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            goto bail;
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5487ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (tree.setTo(asset->getBuffer(true),
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                       asset->getLength()) != NO_ERROR) {
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "ERROR: AndroidManifest.xml is corrupt\n");
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            goto bail;
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        tree.restart();
5557ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (strcmp("permissions", option) == 0) {
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            size_t len;
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ResXMLTree::event_code_t code;
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int depth = 0;
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (code == ResXMLTree::END_TAG) {
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    depth--;
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (code != ResXMLTree::START_TAG) {
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                depth++;
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String8 tag(tree.getElementName(&len));
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                //printf("Depth %d tag %s\n", depth, tag.string());
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (depth == 1) {
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (tag != "manifest") {
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        fprintf(stderr, "ERROR: manifest does not start with <manifest> tag\n");
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        goto bail;
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8 pkg = getAttribute(tree, NULL, "package", NULL);
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    printf("package: %s\n", pkg.string());
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (depth == 2 && tag == "permission") {
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8 error;
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8 name = getAttribute(tree, NAME_ATTR, &error);
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (error != "") {
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        fprintf(stderr, "ERROR: %s\n", error.string());
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        goto bail;
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    printf("permission: %s\n", name.string());
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (depth == 2 && tag == "uses-permission") {
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8 error;
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8 name = getAttribute(tree, NAME_ATTR, &error);
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (error != "") {
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        fprintf(stderr, "ERROR: %s\n", error.string());
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        goto bail;
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    printf("uses-permission: %s\n", name.string());
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (strcmp("badging", option) == 0) {
597e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn            Vector<String8> locales;
598e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn            res.getLocales(&locales);
599e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn
600e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn            Vector<ResTable_config> configs;
601e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn            res.getConfigurations(&configs);
602e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn            SortedVector<int> densities;
603e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn            const size_t NC = configs.size();
604e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn            for (size_t i=0; i<NC; i++) {
605e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                int dens = configs[i].density;
606e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                if (dens == 0) dens = 160;
607e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                densities.add(dens);
608e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn            }
609e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            size_t len;
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ResXMLTree::event_code_t code;
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int depth = 0;
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String8 error;
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bool withinActivity = false;
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bool isMainActivity = false;
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bool isLauncherActivity = false;
6171b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            bool isSearchable = false;
6187ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu            bool withinApplication = false;
6197ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu            bool withinReceiver = false;
6201b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            bool withinService = false;
6211b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            bool withinIntentFilter = false;
6221b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            bool hasMainActivity = false;
6231b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            bool hasOtherActivities = false;
6241b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            bool hasOtherReceivers = false;
6251b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            bool hasOtherServices = false;
6261b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            bool hasWallpaperService = false;
6271b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            bool hasImeService = false;
6281b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            bool hasWidgetReceivers = false;
6291b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            bool hasIntentFilter = false;
6301b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            bool actMainActivity = false;
6311b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            bool actWidgetReceivers = false;
6321b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            bool actImeService = false;
6331b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            bool actWallpaperService = false;
63489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill
635063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root            // These two implement the implicit permissions that are granted
636063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root            // to pre-1.6 applications.
637063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root            bool hasWriteExternalStoragePermission = false;
638063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root            bool hasReadPhoneStatePermission = false;
639063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root
6407924512aa12c6af37d90e8ccfcdf04eb78a294a3Dianne Hackborn            // If an app requests write storage, they will also get read storage.
6417924512aa12c6af37d90e8ccfcdf04eb78a294a3Dianne Hackborn            bool hasReadExternalStoragePermission = false;
6427924512aa12c6af37d90e8ccfcdf04eb78a294a3Dianne Hackborn
64331b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn            // Implement transition to read and write call log.
64431b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn            bool hasReadContactsPermission = false;
64531b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn            bool hasWriteContactsPermission = false;
64631b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn            bool hasReadCallLogPermission = false;
64731b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn            bool hasWriteCallLogPermission = false;
64831b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn
64989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            // This next group of variables is used to implement a group of
65089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            // backward-compatibility heuristics necessitated by the addition of
65189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            // some new uses-feature constants in 2.1 and 2.2. In most cases, the
65289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            // heuristic is "if an app requests a permission but doesn't explicitly
65389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            // request the corresponding <uses-feature>, presume it's there anyway".
65489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            bool specCameraFeature = false; // camera-related
65589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            bool specCameraAutofocusFeature = false;
65689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            bool reqCameraAutofocusFeature = false;
65789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            bool reqCameraFlashFeature = false;
658e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn            bool hasCameraPermission = false;
65989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            bool specLocationFeature = false; // location-related
66089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            bool specNetworkLocFeature = false;
66189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            bool reqNetworkLocFeature = false;
662ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn            bool specGpsFeature = false;
66389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            bool reqGpsFeature = false;
66489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            bool hasMockLocPermission = false;
66589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            bool hasCoarseLocPermission = false;
666ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn            bool hasGpsPermission = false;
66789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            bool hasGeneralLocPermission = false;
66889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            bool specBluetoothFeature = false; // Bluetooth API-related
66989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            bool hasBluetoothPermission = false;
67089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            bool specMicrophoneFeature = false; // microphone-related
67189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            bool hasRecordAudioPermission = false;
67289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            bool specWiFiFeature = false;
67389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            bool hasWiFiPermission = false;
67489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            bool specTelephonyFeature = false; // telephony-related
67589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            bool reqTelephonySubFeature = false;
67689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            bool hasTelephonyPermission = false;
67789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            bool specTouchscreenFeature = false; // touchscreen-related
67889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            bool specMultitouchFeature = false;
67989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            bool reqDistinctMultitouchFeature = false;
680e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn            bool specScreenPortraitFeature = false;
681e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn            bool specScreenLandscapeFeature = false;
682f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn            bool reqScreenPortraitFeature = false;
683f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn            bool reqScreenLandscapeFeature = false;
68489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            // 2.2 also added some other features that apps can request, but that
68589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            // have no corresponding permission, so we cannot implement any
68689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            // back-compatibility heuristic for them. The below are thus unnecessary
68789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            // (but are retained here for documentary purposes.)
68889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            //bool specCompassFeature = false;
68989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            //bool specAccelerometerFeature = false;
69089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            //bool specProximityFeature = false;
69189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            //bool specAmbientLightFeature = false;
69289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            //bool specLiveWallpaperFeature = false;
69389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill
694723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn            int targetSdk = 0;
695723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn            int smallScreen = 1;
696723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn            int normalScreen = 1;
697723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn            int largeScreen = 1;
698f43489d7d5e1c0c5c9a7e54c22845fcb99765f81Dianne Hackborn            int xlargeScreen = 1;
699a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn            int anyDensity = 1;
700e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn            int requiresSmallestWidthDp = 0;
701e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn            int compatibleWidthLimitDp = 0;
702e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn            int largestWidthLimitDp = 0;
7037ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu            String8 pkg;
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String8 activityName;
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String8 activityLabel;
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String8 activityIcon;
7077ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu            String8 receiverName;
7081b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            String8 serviceName;
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (code == ResXMLTree::END_TAG) {
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    depth--;
7121b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                    if (depth < 2) {
7131b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        withinApplication = false;
7141b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                    } else if (depth < 3) {
7151b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        if (withinActivity && isMainActivity && isLauncherActivity) {
7161b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                            const char *aName = getComponentName(pkg, activityName);
717e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                            printf("launchable-activity:");
7181b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                            if (aName != NULL) {
719e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                                printf(" name='%s' ", aName);
7201b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                            }
721e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                            printf(" label='%s' icon='%s'\n",
7221b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                                    activityLabel.string(),
7231b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                                    activityIcon.string());
7241b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        }
7251b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        if (!hasIntentFilter) {
7261b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                            hasOtherActivities |= withinActivity;
7271b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                            hasOtherReceivers |= withinReceiver;
7281b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                            hasOtherServices |= withinService;
7291b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        }
7301b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        withinActivity = false;
7311b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        withinService = false;
7321b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        withinReceiver = false;
7331b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        hasIntentFilter = false;
7341b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        isMainActivity = isLauncherActivity = false;
7351b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                    } else if (depth < 4) {
7361b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        if (withinIntentFilter) {
7371b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                            if (withinActivity) {
7381b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                                hasMainActivity |= actMainActivity;
7391b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                                hasOtherActivities |= !actMainActivity;
7401b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                            } else if (withinReceiver) {
7411b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                                hasWidgetReceivers |= actWidgetReceivers;
7421b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                                hasOtherReceivers |= !actWidgetReceivers;
7431b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                            } else if (withinService) {
7441b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                                hasImeService |= actImeService;
7451b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                                hasWallpaperService |= actWallpaperService;
7461b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                                hasOtherServices |= (!actImeService && !actWallpaperService);
7471b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                            }
7481b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        }
7491b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        withinIntentFilter = false;
7501b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                    }
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (code != ResXMLTree::START_TAG) {
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                depth++;
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String8 tag(tree.getElementName(&len));
7581b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                //printf("Depth %d,  %s\n", depth, tag.string());
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (depth == 1) {
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (tag != "manifest") {
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        fprintf(stderr, "ERROR: manifest does not start with <manifest> tag\n");
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        goto bail;
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
7647ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                    pkg = getAttribute(tree, NULL, "package", NULL);
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    printf("package: name='%s' ", pkg.string());
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    int32_t versionCode = getIntegerAttribute(tree, VERSION_CODE_ATTR, &error);
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (error != "") {
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        fprintf(stderr, "ERROR getting 'android:versionCode' attribute: %s\n", error.string());
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        goto bail;
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (versionCode > 0) {
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        printf("versionCode='%d' ", versionCode);
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        printf("versionCode='' ");
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
776cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn                    String8 versionName = getResolvedAttribute(&res, tree, VERSION_NAME_ATTR, &error);
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (error != "") {
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        fprintf(stderr, "ERROR getting 'android:versionName' attribute: %s\n", error.string());
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        goto bail;
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    printf("versionName='%s'\n", versionName.string());
7827ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                } else if (depth == 2) {
7837ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                    withinApplication = false;
7847ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                    if (tag == "application") {
7857ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                        withinApplication = true;
786e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn
787e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                        String8 label;
788e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                        const size_t NL = locales.size();
789e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                        for (size_t i=0; i<NL; i++) {
790e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                            const char* localeStr =  locales[i].string();
791e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                            assets.setLocale(localeStr != NULL ? localeStr : "");
792e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                            String8 llabel = getResolvedAttribute(&res, tree, LABEL_ATTR, &error);
793e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                            if (llabel != "") {
794e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                                if (localeStr == NULL || strlen(localeStr) == 0) {
795e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                                    label = llabel;
796e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                                    printf("application-label:'%s'\n", llabel.string());
797e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                                } else {
798e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                                    if (label == "") {
799e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                                        label = llabel;
800e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                                    }
801e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                                    printf("application-label-%s:'%s'\n", localeStr,
802e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                                            llabel.string());
803e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                                }
804e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                            }
8057ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                        }
806e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn
807e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                        ResTable_config tmpConfig = config;
808e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                        const size_t ND = densities.size();
809e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                        for (size_t i=0; i<ND; i++) {
810e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                            tmpConfig.density = densities[i];
811e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                            assets.setConfiguration(tmpConfig);
812e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                            String8 icon = getResolvedAttribute(&res, tree, ICON_ATTR, &error);
813e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                            if (icon != "") {
814e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                                printf("application-icon-%d:'%s'\n", densities[i], icon.string());
815e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                            }
816e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                        }
817e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                        assets.setConfiguration(config);
818e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn
8197ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                        String8 icon = getResolvedAttribute(&res, tree, ICON_ATTR, &error);
8207ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                        if (error != "") {
8217ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                            fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n", error.string());
8227ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                            goto bail;
8237ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                        }
824bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                        int32_t testOnly = getIntegerAttribute(tree, TEST_ONLY_ATTR, &error, 0);
8257ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                        if (error != "") {
826bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                            fprintf(stderr, "ERROR getting 'android:testOnly' attribute: %s\n", error.string());
8277ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                            goto bail;
8287ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                        }
829e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                        printf("application: label='%s' ", label.string());
830e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                        printf("icon='%s'\n", icon.string());
831bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                        if (testOnly != 0) {
832bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                            printf("testOnly='%d'\n", testOnly);
833bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                        }
834b6ec11ef372a498c4d5fd2317a015b808495a2edDan Morrill
835b6ec11ef372a498c4d5fd2317a015b808495a2edDan Morrill                        int32_t debuggable = getResolvedIntegerAttribute(&res, tree, DEBUGGABLE_ATTR, &error, 0);
836b6ec11ef372a498c4d5fd2317a015b808495a2edDan Morrill                        if (error != "") {
837b6ec11ef372a498c4d5fd2317a015b808495a2edDan Morrill                            fprintf(stderr, "ERROR getting 'android:debuggable' attribute: %s\n", error.string());
838b6ec11ef372a498c4d5fd2317a015b808495a2edDan Morrill                            goto bail;
839b6ec11ef372a498c4d5fd2317a015b808495a2edDan Morrill                        }
840b6ec11ef372a498c4d5fd2317a015b808495a2edDan Morrill                        if (debuggable != 0) {
841b6ec11ef372a498c4d5fd2317a015b808495a2edDan Morrill                            printf("application-debuggable\n");
842b6ec11ef372a498c4d5fd2317a015b808495a2edDan Morrill                        }
843bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                    } else if (tag == "uses-sdk") {
844bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                        int32_t code = getIntegerAttribute(tree, MIN_SDK_VERSION_ATTR, &error);
845bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                        if (error != "") {
846bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                            error = "";
847bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                            String8 name = getResolvedAttribute(&res, tree, MIN_SDK_VERSION_ATTR, &error);
848bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                            if (error != "") {
849bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                                fprintf(stderr, "ERROR getting 'android:minSdkVersion' attribute: %s\n",
850bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                                        error.string());
851bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                                goto bail;
852bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                            }
853723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn                            if (name == "Donut") targetSdk = 4;
854bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                            printf("sdkVersion:'%s'\n", name.string());
855bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                        } else if (code != -1) {
856723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn                            targetSdk = code;
857bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                            printf("sdkVersion:'%d'\n", code);
858bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                        }
85975c498426a17b47d445711bb9e36794b05876a56Suchi Amalapurapu                        code = getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR, NULL, -1);
86075c498426a17b47d445711bb9e36794b05876a56Suchi Amalapurapu                        if (code != -1) {
86175c498426a17b47d445711bb9e36794b05876a56Suchi Amalapurapu                            printf("maxSdkVersion:'%d'\n", code);
86275c498426a17b47d445711bb9e36794b05876a56Suchi Amalapurapu                        }
863bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                        code = getIntegerAttribute(tree, TARGET_SDK_VERSION_ATTR, &error);
864bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                        if (error != "") {
865bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                            error = "";
866bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                            String8 name = getResolvedAttribute(&res, tree, TARGET_SDK_VERSION_ATTR, &error);
867bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                            if (error != "") {
868bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                                fprintf(stderr, "ERROR getting 'android:targetSdkVersion' attribute: %s\n",
869bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                                        error.string());
870bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                                goto bail;
871bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                            }
872723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn                            if (name == "Donut" && targetSdk < 4) targetSdk = 4;
873bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                            printf("targetSdkVersion:'%s'\n", name.string());
874bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                        } else if (code != -1) {
875723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn                            if (targetSdk < code) {
876723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn                                targetSdk = code;
877723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn                            }
878bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                            printf("targetSdkVersion:'%d'\n", code);
879bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                        }
880bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                    } else if (tag == "uses-configuration") {
881bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                        int32_t reqTouchScreen = getIntegerAttribute(tree,
882bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                                REQ_TOUCH_SCREEN_ATTR, NULL, 0);
883bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                        int32_t reqKeyboardType = getIntegerAttribute(tree,
884bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                                REQ_KEYBOARD_TYPE_ATTR, NULL, 0);
885bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                        int32_t reqHardKeyboard = getIntegerAttribute(tree,
886bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                                REQ_HARD_KEYBOARD_ATTR, NULL, 0);
887bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                        int32_t reqNavigation = getIntegerAttribute(tree,
888bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                                REQ_NAVIGATION_ATTR, NULL, 0);
889bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                        int32_t reqFiveWayNav = getIntegerAttribute(tree,
890bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                                REQ_FIVE_WAY_NAV_ATTR, NULL, 0);
891cb2d50d0d6e2e37ae02b014999da23ecd32038b8Dianne Hackborn                        printf("uses-configuration:");
892bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                        if (reqTouchScreen != 0) {
893bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                            printf(" reqTouchScreen='%d'", reqTouchScreen);
894bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                        }
895bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                        if (reqKeyboardType != 0) {
896bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                            printf(" reqKeyboardType='%d'", reqKeyboardType);
897bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                        }
898bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                        if (reqHardKeyboard != 0) {
899bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                            printf(" reqHardKeyboard='%d'", reqHardKeyboard);
900bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                        }
901bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                        if (reqNavigation != 0) {
902bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                            printf(" reqNavigation='%d'", reqNavigation);
9037ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                        }
904bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                        if (reqFiveWayNav != 0) {
905bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                            printf(" reqFiveWayNav='%d'", reqFiveWayNav);
906bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                        }
907bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                        printf("\n");
908723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn                    } else if (tag == "supports-screens") {
909723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn                        smallScreen = getIntegerAttribute(tree,
910723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn                                SMALL_SCREEN_ATTR, NULL, 1);
911723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn                        normalScreen = getIntegerAttribute(tree,
912723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn                                NORMAL_SCREEN_ATTR, NULL, 1);
913723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn                        largeScreen = getIntegerAttribute(tree,
914723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn                                LARGE_SCREEN_ATTR, NULL, 1);
915f43489d7d5e1c0c5c9a7e54c22845fcb99765f81Dianne Hackborn                        xlargeScreen = getIntegerAttribute(tree,
916f43489d7d5e1c0c5c9a7e54c22845fcb99765f81Dianne Hackborn                                XLARGE_SCREEN_ATTR, NULL, 1);
917a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn                        anyDensity = getIntegerAttribute(tree,
918a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn                                ANY_DENSITY_ATTR, NULL, 1);
919e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                        requiresSmallestWidthDp = getIntegerAttribute(tree,
920e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                                REQUIRES_SMALLEST_WIDTH_DP_ATTR, NULL, 0);
921e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                        compatibleWidthLimitDp = getIntegerAttribute(tree,
922e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                                COMPATIBLE_WIDTH_LIMIT_DP_ATTR, NULL, 0);
923e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                        largestWidthLimitDp = getIntegerAttribute(tree,
924e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                                LARGEST_WIDTH_LIMIT_DP_ATTR, NULL, 0);
925e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn                    } else if (tag == "uses-feature") {
926e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn                        String8 name = getAttribute(tree, NAME_ATTR, &error);
92740b94725dc1c62ea66db0b9502dd81b97dd3e35fSuchi Amalapurapu
92840b94725dc1c62ea66db0b9502dd81b97dd3e35fSuchi Amalapurapu                        if (name != "" && error == "") {
929e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn                            int req = getIntegerAttribute(tree,
930e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn                                    REQUIRED_ATTR, NULL, 1);
93189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill
932e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn                            if (name == "android.hardware.camera") {
933e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn                                specCameraFeature = true;
93489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                            } else if (name == "android.hardware.camera.autofocus") {
93589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                // these have no corresponding permission to check for,
93689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                // but should imply the foundational camera permission
93789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                reqCameraAutofocusFeature = reqCameraAutofocusFeature || req;
93889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                specCameraAutofocusFeature = true;
93989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                            } else if (req && (name == "android.hardware.camera.flash")) {
94089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                // these have no corresponding permission to check for,
94189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                // but should imply the foundational camera permission
94289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                reqCameraFlashFeature = true;
94389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                            } else if (name == "android.hardware.location") {
94489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                specLocationFeature = true;
94589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                            } else if (name == "android.hardware.location.network") {
94689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                specNetworkLocFeature = true;
94789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                reqNetworkLocFeature = reqNetworkLocFeature || req;
948ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn                            } else if (name == "android.hardware.location.gps") {
949ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn                                specGpsFeature = true;
95089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                reqGpsFeature = reqGpsFeature || req;
95189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                            } else if (name == "android.hardware.bluetooth") {
95289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                specBluetoothFeature = true;
95389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                            } else if (name == "android.hardware.touchscreen") {
95489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                specTouchscreenFeature = true;
95589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                            } else if (name == "android.hardware.touchscreen.multitouch") {
95689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                specMultitouchFeature = true;
95789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                            } else if (name == "android.hardware.touchscreen.multitouch.distinct") {
95889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                reqDistinctMultitouchFeature = reqDistinctMultitouchFeature || req;
95989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                            } else if (name == "android.hardware.microphone") {
96089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                specMicrophoneFeature = true;
96189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                            } else if (name == "android.hardware.wifi") {
96289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                specWiFiFeature = true;
96389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                            } else if (name == "android.hardware.telephony") {
96489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                specTelephonyFeature = true;
96589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                            } else if (req && (name == "android.hardware.telephony.gsm" ||
96689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                               name == "android.hardware.telephony.cdma")) {
96789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                // these have no corresponding permission to check for,
96889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                // but should imply the foundational telephony permission
96989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                reqTelephonySubFeature = true;
970e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                            } else if (name == "android.hardware.screen.portrait") {
971e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                                specScreenPortraitFeature = true;
972e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                            } else if (name == "android.hardware.screen.landscape") {
973e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                                specScreenLandscapeFeature = true;
974e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn                            }
975e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn                            printf("uses-feature%s:'%s'\n",
976e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn                                    req ? "" : "-not-required", name.string());
977e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn                        } else {
978e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn                            int vers = getIntegerAttribute(tree,
979e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn                                    GL_ES_VERSION_ATTR, &error);
980e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn                            if (error == "") {
981e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn                                printf("uses-gl-es:'0x%x'\n", vers);
982e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn                            }
983e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn                        }
984e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn                    } else if (tag == "uses-permission") {
985e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn                        String8 name = getAttribute(tree, NAME_ATTR, &error);
98640b94725dc1c62ea66db0b9502dd81b97dd3e35fSuchi Amalapurapu                        if (name != "" && error == "") {
987e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn                            if (name == "android.permission.CAMERA") {
988e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn                                hasCameraPermission = true;
989ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn                            } else if (name == "android.permission.ACCESS_FINE_LOCATION") {
990ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn                                hasGpsPermission = true;
99189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                            } else if (name == "android.permission.ACCESS_MOCK_LOCATION") {
99289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                hasMockLocPermission = true;
99389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                            } else if (name == "android.permission.ACCESS_COARSE_LOCATION") {
99489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                hasCoarseLocPermission = true;
99589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                            } else if (name == "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" ||
99689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                       name == "android.permission.INSTALL_LOCATION_PROVIDER") {
99789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                hasGeneralLocPermission = true;
99889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                            } else if (name == "android.permission.BLUETOOTH" ||
99989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                       name == "android.permission.BLUETOOTH_ADMIN") {
100089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                hasBluetoothPermission = true;
100189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                            } else if (name == "android.permission.RECORD_AUDIO") {
100289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                hasRecordAudioPermission = true;
100389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                            } else if (name == "android.permission.ACCESS_WIFI_STATE" ||
100489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                       name == "android.permission.CHANGE_WIFI_STATE" ||
100589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                       name == "android.permission.CHANGE_WIFI_MULTICAST_STATE") {
100689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                hasWiFiPermission = true;
100789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                            } else if (name == "android.permission.CALL_PHONE" ||
100889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                       name == "android.permission.CALL_PRIVILEGED" ||
100989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                       name == "android.permission.MODIFY_PHONE_STATE" ||
101089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                       name == "android.permission.PROCESS_OUTGOING_CALLS" ||
101189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                       name == "android.permission.READ_SMS" ||
101289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                       name == "android.permission.RECEIVE_SMS" ||
101389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                       name == "android.permission.RECEIVE_MMS" ||
101489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                       name == "android.permission.RECEIVE_WAP_PUSH" ||
101589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                       name == "android.permission.SEND_SMS" ||
101689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                       name == "android.permission.WRITE_APN_SETTINGS" ||
101789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                       name == "android.permission.WRITE_SMS") {
101889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                                hasTelephonyPermission = true;
1019063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root                            } else if (name == "android.permission.WRITE_EXTERNAL_STORAGE") {
1020063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root                                hasWriteExternalStoragePermission = true;
10217924512aa12c6af37d90e8ccfcdf04eb78a294a3Dianne Hackborn                            } else if (name == "android.permission.READ_EXTERNAL_STORAGE") {
10227924512aa12c6af37d90e8ccfcdf04eb78a294a3Dianne Hackborn                                hasReadExternalStoragePermission = true;
1023063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root                            } else if (name == "android.permission.READ_PHONE_STATE") {
1024063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root                                hasReadPhoneStatePermission = true;
102531b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn                            } else if (name == "android.permission.READ_CONTACTS") {
102631b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn                                hasReadContactsPermission = true;
102731b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn                            } else if (name == "android.permission.WRITE_CONTACTS") {
102831b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn                                hasWriteContactsPermission = true;
102931b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn                            } else if (name == "android.permission.READ_CALL_LOG") {
103031b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn                                hasReadCallLogPermission = true;
103131b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn                            } else if (name == "android.permission.WRITE_CALL_LOG") {
103231b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn                                hasWriteCallLogPermission = true;
1033e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn                            }
1034e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn                            printf("uses-permission:'%s'\n", name.string());
1035e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn                        } else {
1036e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn                            fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n",
1037e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn                                    error.string());
1038e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn                            goto bail;
1039e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn                        }
104043b6803095e41e6a1cf844a77813c6cdbdc84ec3Dianne Hackborn                    } else if (tag == "uses-package") {
104143b6803095e41e6a1cf844a77813c6cdbdc84ec3Dianne Hackborn                        String8 name = getAttribute(tree, NAME_ATTR, &error);
104243b6803095e41e6a1cf844a77813c6cdbdc84ec3Dianne Hackborn                        if (name != "" && error == "") {
104343b6803095e41e6a1cf844a77813c6cdbdc84ec3Dianne Hackborn                            printf("uses-package:'%s'\n", name.string());
104443b6803095e41e6a1cf844a77813c6cdbdc84ec3Dianne Hackborn                        } else {
104543b6803095e41e6a1cf844a77813c6cdbdc84ec3Dianne Hackborn                            fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n",
104643b6803095e41e6a1cf844a77813c6cdbdc84ec3Dianne Hackborn                                    error.string());
104743b6803095e41e6a1cf844a77813c6cdbdc84ec3Dianne Hackborn                                goto bail;
104843b6803095e41e6a1cf844a77813c6cdbdc84ec3Dianne Hackborn                        }
1049e2c17f9174144a6eca3fdbed8d5d1370f318f549Jeff Hamilton                    } else if (tag == "original-package") {
1050e2c17f9174144a6eca3fdbed8d5d1370f318f549Jeff Hamilton                        String8 name = getAttribute(tree, NAME_ATTR, &error);
1051e2c17f9174144a6eca3fdbed8d5d1370f318f549Jeff Hamilton                        if (name != "" && error == "") {
1052e2c17f9174144a6eca3fdbed8d5d1370f318f549Jeff Hamilton                            printf("original-package:'%s'\n", name.string());
1053e2c17f9174144a6eca3fdbed8d5d1370f318f549Jeff Hamilton                        } else {
1054e2c17f9174144a6eca3fdbed8d5d1370f318f549Jeff Hamilton                            fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n",
1055e2c17f9174144a6eca3fdbed8d5d1370f318f549Jeff Hamilton                                    error.string());
1056e2c17f9174144a6eca3fdbed8d5d1370f318f549Jeff Hamilton                                goto bail;
1057e2c17f9174144a6eca3fdbed8d5d1370f318f549Jeff Hamilton                        }
1058096b67f65510a5076f1f845f9e19dda2b30ea6bbDan Morrill                    } else if (tag == "supports-gl-texture") {
10596f51fc14d0c3df8f9153ae5df992cc2731f099c8Dan Morrill                        String8 name = getAttribute(tree, NAME_ATTR, &error);
10606f51fc14d0c3df8f9153ae5df992cc2731f099c8Dan Morrill                        if (name != "" && error == "") {
1061096b67f65510a5076f1f845f9e19dda2b30ea6bbDan Morrill                            printf("supports-gl-texture:'%s'\n", name.string());
10626f51fc14d0c3df8f9153ae5df992cc2731f099c8Dan Morrill                        } else {
10636f51fc14d0c3df8f9153ae5df992cc2731f099c8Dan Morrill                            fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n",
10646f51fc14d0c3df8f9153ae5df992cc2731f099c8Dan Morrill                                    error.string());
10656f51fc14d0c3df8f9153ae5df992cc2731f099c8Dan Morrill                                goto bail;
10666f51fc14d0c3df8f9153ae5df992cc2731f099c8Dan Morrill                        }
1067a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn                    } else if (tag == "compatible-screens") {
1068a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn                        printCompatibleScreens(tree);
1069a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn                        depth--;
107056088a55ca6c9277f09040a7883117cb127e1e56Kenny Root                    } else if (tag == "package-verifier") {
107156088a55ca6c9277f09040a7883117cb127e1e56Kenny Root                        String8 name = getAttribute(tree, NAME_ATTR, &error);
107256088a55ca6c9277f09040a7883117cb127e1e56Kenny Root                        if (name != "" && error == "") {
107356088a55ca6c9277f09040a7883117cb127e1e56Kenny Root                            String8 publicKey = getAttribute(tree, PUBLIC_KEY_ATTR, &error);
107456088a55ca6c9277f09040a7883117cb127e1e56Kenny Root                            if (publicKey != "" && error == "") {
107556088a55ca6c9277f09040a7883117cb127e1e56Kenny Root                                printf("package-verifier: name='%s' publicKey='%s'\n",
107656088a55ca6c9277f09040a7883117cb127e1e56Kenny Root                                        name.string(), publicKey.string());
107756088a55ca6c9277f09040a7883117cb127e1e56Kenny Root                            }
107856088a55ca6c9277f09040a7883117cb127e1e56Kenny Root                        }
10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
10807ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                } else if (depth == 3 && withinApplication) {
10817ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                    withinActivity = false;
10827ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                    withinReceiver = false;
10831b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                    withinService = false;
10841b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                    hasIntentFilter = false;
10857ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                    if(tag == "activity") {
10867ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                        withinActivity = true;
10877ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                        activityName = getAttribute(tree, NAME_ATTR, &error);
10887ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                        if (error != "") {
10897ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                            fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", error.string());
10907ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                            goto bail;
10917ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                        }
10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10937ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                        activityLabel = getResolvedAttribute(&res, tree, LABEL_ATTR, &error);
10947ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                        if (error != "") {
10957ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                            fprintf(stderr, "ERROR getting 'android:label' attribute: %s\n", error.string());
10967ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                            goto bail;
10977ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                        }
10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10997ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                        activityIcon = getResolvedAttribute(&res, tree, ICON_ATTR, &error);
11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (error != "") {
11017ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                            fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n", error.string());
11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            goto bail;
11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
1104f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn
1105f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn                        int32_t orien = getResolvedIntegerAttribute(&res, tree,
1106f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn                                SCREEN_ORIENTATION_ATTR, &error);
1107f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn                        if (error == "") {
1108f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn                            if (orien == 0 || orien == 6 || orien == 8) {
1109f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn                                // Requests landscape, sensorLandscape, or reverseLandscape.
1110f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn                                reqScreenLandscapeFeature = true;
1111f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn                            } else if (orien == 1 || orien == 7 || orien == 9) {
1112f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn                                // Requests portrait, sensorPortrait, or reversePortrait.
1113f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn                                reqScreenPortraitFeature = true;
1114f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn                            }
1115f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn                        }
11167ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                    } else if (tag == "uses-library") {
11177ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                        String8 libraryName = getAttribute(tree, NAME_ATTR, &error);
11187ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                        if (error != "") {
11197ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                            fprintf(stderr, "ERROR getting 'android:name' attribute for uses-library: %s\n", error.string());
11207ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                            goto bail;
11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
112249237345d83e62fdb9eb8d50b13ad086636a04faDianne Hackborn                        int req = getIntegerAttribute(tree,
112349237345d83e62fdb9eb8d50b13ad086636a04faDianne Hackborn                                REQUIRED_ATTR, NULL, 1);
112449237345d83e62fdb9eb8d50b13ad086636a04faDianne Hackborn                        printf("uses-library%s:'%s'\n",
112549237345d83e62fdb9eb8d50b13ad086636a04faDianne Hackborn                                req ? "" : "-not-required", libraryName.string());
11267ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                    } else if (tag == "receiver") {
11277ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                        withinReceiver = true;
11287ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                        receiverName = getAttribute(tree, NAME_ATTR, &error);
11297ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu
11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (error != "") {
11317ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                            fprintf(stderr, "ERROR getting 'android:name' attribute for receiver: %s\n", error.string());
11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            goto bail;
11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
11341b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                    } else if (tag == "service") {
11351b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        withinService = true;
11361b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        serviceName = getAttribute(tree, NAME_ATTR, &error);
11371b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu
11381b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        if (error != "") {
11391b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                            fprintf(stderr, "ERROR getting 'android:name' attribute for service: %s\n", error.string());
11401b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                            goto bail;
11411b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        }
11427ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                    }
11431b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                } else if ((depth == 4) && (tag == "intent-filter")) {
11441b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                    hasIntentFilter = true;
11451b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                    withinIntentFilter = true;
11461b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                    actMainActivity = actWidgetReceivers = actImeService = actWallpaperService = false;
11471b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                } else if ((depth == 5) && withinIntentFilter){
11481b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                    String8 action;
11491b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                    if (tag == "action") {
11501b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        action = getAttribute(tree, NAME_ATTR, &error);
11511b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        if (error != "") {
11521b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                            fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", error.string());
11531b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                            goto bail;
11541b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        }
11551b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        if (withinActivity) {
1156bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                            if (action == "android.intent.action.MAIN") {
1157bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                                isMainActivity = true;
11581b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                                actMainActivity = true;
1159bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                            }
11601b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        } else if (withinReceiver) {
11611b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                            if (action == "android.appwidget.action.APPWIDGET_UPDATE") {
11621b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                                actWidgetReceivers = true;
11637ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                            }
11641b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        } else if (withinService) {
11651b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                            if (action == "android.view.InputMethod") {
11661b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                                actImeService = true;
11671b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                            } else if (action == "android.service.wallpaper.WallpaperService") {
11681b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                                actWallpaperService = true;
11697ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                            }
11707ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                        }
11711b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        if (action == "android.intent.action.SEARCH") {
11721b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                            isSearchable = true;
11737ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                        }
11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11761b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                    if (tag == "category") {
11771b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        String8 category = getAttribute(tree, NAME_ATTR, &error);
11781b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        if (error != "") {
11791b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                            fprintf(stderr, "ERROR getting 'name' attribute: %s\n", error.string());
11801b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                            goto bail;
11811b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        }
11821b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        if (withinActivity) {
11831b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                            if (category == "android.intent.category.LAUNCHER") {
11841b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                                isLauncherActivity = true;
11851b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                            }
11861b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                        }
11877ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu                    }
11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1190063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root
1191063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root            // Pre-1.6 implicitly granted permission compatibility logic
1192063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root            if (targetSdk < 4) {
1193063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root                if (!hasWriteExternalStoragePermission) {
1194063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root                    printf("uses-permission:'android.permission.WRITE_EXTERNAL_STORAGE'\n");
11954aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                    printf("uses-implied-permission:'android.permission.WRITE_EXTERNAL_STORAGE'," \
11964aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                            "'targetSdkVersion < 4'\n");
11977924512aa12c6af37d90e8ccfcdf04eb78a294a3Dianne Hackborn                    hasWriteExternalStoragePermission = true;
1198063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root                }
1199063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root                if (!hasReadPhoneStatePermission) {
1200063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root                    printf("uses-permission:'android.permission.READ_PHONE_STATE'\n");
12014aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                    printf("uses-implied-permission:'android.permission.READ_PHONE_STATE'," \
12024aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                            "'targetSdkVersion < 4'\n");
1203063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root                }
1204063a44e541335819b673fb1c20a338bbcaf3a3f5Kenny Root            }
12051b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu
12067924512aa12c6af37d90e8ccfcdf04eb78a294a3Dianne Hackborn            // If the application has requested WRITE_EXTERNAL_STORAGE, we will
12072bd8d0403be62df679f0f94ab4d84c9ae9a2e918Dianne Hackborn            // force them to always take READ_EXTERNAL_STORAGE as well.  We always
12082bd8d0403be62df679f0f94ab4d84c9ae9a2e918Dianne Hackborn            // do this (regardless of target API version) because we can't have
12092bd8d0403be62df679f0f94ab4d84c9ae9a2e918Dianne Hackborn            // an app with write permission but not read permission.
12107924512aa12c6af37d90e8ccfcdf04eb78a294a3Dianne Hackborn            if (!hasReadExternalStoragePermission && hasWriteExternalStoragePermission) {
12117924512aa12c6af37d90e8ccfcdf04eb78a294a3Dianne Hackborn                printf("uses-permission:'android.permission.READ_EXTERNAL_STORAGE'\n");
12124aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                printf("uses-implied-permission:'android.permission.READ_EXTERNAL_STORAGE'," \
12134aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                        "'requested WRITE_EXTERNAL_STORAGE'\n");
12147924512aa12c6af37d90e8ccfcdf04eb78a294a3Dianne Hackborn            }
12157924512aa12c6af37d90e8ccfcdf04eb78a294a3Dianne Hackborn
121631b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn            // Pre-JellyBean call log permission compatibility.
121731b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn            if (targetSdk < 16) {
121831b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn                if (!hasReadCallLogPermission && hasReadContactsPermission) {
121931b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn                    printf("uses-permission:'android.permission.READ_CALL_LOG'\n");
12204aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                    printf("uses-implied-permission:'android.permission.READ_CALL_LOG'," \
12214aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                            "'targetSdkVersion < 16 and requested READ_CONTACTS'\n");
122231b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn                }
122331b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn                if (!hasWriteCallLogPermission && hasWriteContactsPermission) {
122431b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn                    printf("uses-permission:'android.permission.WRITE_CALL_LOG'\n");
12254aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                    printf("uses-implied-permission:'android.permission.WRITE_CALL_LOG'," \
12264aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                            "'targetSdkVersion < 16 and requested WRITE_CONTACTS'\n");
122731b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn                }
122831b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn            }
122931b0e0e86ad061cd8005e80817bcad017e2d56ddDianne Hackborn
123089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            /* The following blocks handle printing "inferred" uses-features, based
123189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill             * on whether related features or permissions are used by the app.
123289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill             * Note that the various spec*Feature variables denote whether the
123389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill             * relevant tag was *present* in the AndroidManfest, not that it was
123489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill             * present and set to true.
123589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill             */
123689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            // Camera-related back-compatibility logic
123789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            if (!specCameraFeature) {
12384aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                if (reqCameraFlashFeature) {
123989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                    // if app requested a sub-feature (autofocus or flash) and didn't
124089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                    // request the base camera feature, we infer that it meant to
124189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                    printf("uses-feature:'android.hardware.camera'\n");
12424aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                    printf("uses-implied-feature:'android.hardware.camera'," \
12434aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                            "'requested android.hardware.camera.flash feature'\n");
12444aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                } else if (reqCameraAutofocusFeature) {
12454aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                    // if app requested a sub-feature (autofocus or flash) and didn't
12464aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                    // request the base camera feature, we infer that it meant to
12474aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                    printf("uses-feature:'android.hardware.camera'\n");
12484aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                    printf("uses-implied-feature:'android.hardware.camera'," \
12494aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                            "'requested android.hardware.camera.autofocus feature'\n");
125089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                } else if (hasCameraPermission) {
125189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                    // if app wants to use camera but didn't request the feature, we infer
125289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                    // that it meant to, and further that it wants autofocus
125389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                    // (which was the 1.0 - 1.5 behavior)
125489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                    printf("uses-feature:'android.hardware.camera'\n");
125589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                    if (!specCameraAutofocusFeature) {
125689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                        printf("uses-feature:'android.hardware.camera.autofocus'\n");
12574aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                        printf("uses-implied-feature:'android.hardware.camera.autofocus'," \
12584aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                                "'requested android.permission.CAMERA permission'\n");
125989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                    }
126089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                }
1261e5276a74746b5e8f09b05a50155e7aa0bbb4a747Dianne Hackborn            }
1262dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker
126389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            // Location-related back-compatibility logic
126489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            if (!specLocationFeature &&
126589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                (hasMockLocPermission || hasCoarseLocPermission || hasGpsPermission ||
126689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                 hasGeneralLocPermission || reqNetworkLocFeature || reqGpsFeature)) {
126789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                // if app either takes a location-related permission or requests one of the
126889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                // sub-features, we infer that it also meant to request the base location feature
126989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                printf("uses-feature:'android.hardware.location'\n");
12704aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                printf("uses-implied-feature:'android.hardware.location'," \
12714aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                        "'requested a location access permission'\n");
127289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            }
1273ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn            if (!specGpsFeature && hasGpsPermission) {
127489d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                // if app takes GPS (FINE location) perm but does not request the GPS
127589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                // feature, we infer that it meant to
1276ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn                printf("uses-feature:'android.hardware.location.gps'\n");
12774aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                printf("uses-implied-feature:'android.hardware.location.gps'," \
12784aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                        "'requested android.permission.ACCESS_FINE_LOCATION permission'\n");
1279ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn            }
128089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            if (!specNetworkLocFeature && hasCoarseLocPermission) {
128189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                // if app takes Network location (COARSE location) perm but does not request the
128289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                // network location feature, we infer that it meant to
128389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                printf("uses-feature:'android.hardware.location.network'\n");
12844aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                printf("uses-implied-feature:'android.hardware.location.network'," \
12854aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                        "'requested android.permission.ACCESS_COURSE_LOCATION permission'\n");
128689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            }
128789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill
128889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            // Bluetooth-related compatibility logic
12896b22d81aa35d9a9b32670995c002e92588b2fe09Dan Morrill            if (!specBluetoothFeature && hasBluetoothPermission && (targetSdk > 4)) {
129089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                // if app takes a Bluetooth permission but does not request the Bluetooth
129189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                // feature, we infer that it meant to
129289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                printf("uses-feature:'android.hardware.bluetooth'\n");
12934aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                printf("uses-implied-feature:'android.hardware.bluetooth'," \
12944aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                        "'requested android.permission.BLUETOOTH or android.permission.BLUETOOTH_ADMIN " \
12954aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                        "permission and targetSdkVersion > 4'\n");
129689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            }
129789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill
129889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            // Microphone-related compatibility logic
129989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            if (!specMicrophoneFeature && hasRecordAudioPermission) {
130089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                // if app takes the record-audio permission but does not request the microphone
130189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                // feature, we infer that it meant to
130289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                printf("uses-feature:'android.hardware.microphone'\n");
13034aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                printf("uses-implied-feature:'android.hardware.microphone'," \
13044aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                        "'requested android.permission.RECORD_AUDIO permission'\n");
130589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            }
130689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill
130789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            // WiFi-related compatibility logic
130889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            if (!specWiFiFeature && hasWiFiPermission) {
130989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                // if app takes one of the WiFi permissions but does not request the WiFi
131089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                // feature, we infer that it meant to
131189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                printf("uses-feature:'android.hardware.wifi'\n");
13124aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                printf("uses-implied-feature:'android.hardware.wifi'," \
13134aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                        "'requested android.permission.ACCESS_WIFI_STATE, " \
13144aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                        "android.permission.CHANGE_WIFI_STATE, or " \
13154aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                        "android.permission.CHANGE_WIFI_MULTICAST_STATE permission'\n");
131689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            }
131789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill
131889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            // Telephony-related compatibility logic
131989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            if (!specTelephonyFeature && (hasTelephonyPermission || reqTelephonySubFeature)) {
132089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                // if app takes one of the telephony permissions or requests a sub-feature but
132189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                // does not request the base telephony feature, we infer that it meant to
132289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                printf("uses-feature:'android.hardware.telephony'\n");
13234aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                printf("uses-implied-feature:'android.hardware.telephony'," \
13244aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                        "'requested a telephony-related permission or feature'\n");
132589d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            }
132689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill
132789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            // Touchscreen-related back-compatibility logic
132889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            if (!specTouchscreenFeature) { // not a typo!
132989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                // all apps are presumed to require a touchscreen, unless they explicitly say
133089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                // <uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
133189d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                // Note that specTouchscreenFeature is true if the tag is present, regardless
133289d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                // of whether its value is true or false, so this is safe
133389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                printf("uses-feature:'android.hardware.touchscreen'\n");
13344aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                printf("uses-implied-feature:'android.hardware.touchscreen'," \
13354aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                        "'assumed you require a touch screen unless explicitly made optional'\n");
133689d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            }
133789d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            if (!specMultitouchFeature && reqDistinctMultitouchFeature) {
133889d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                // if app takes one of the telephony permissions or requests a sub-feature but
133989d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                // does not request the base telephony feature, we infer that it meant to
134089d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill                printf("uses-feature:'android.hardware.touchscreen.multitouch'\n");
13414aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                printf("uses-implied-feature:'android.hardware.touchscreen.multitouch'," \
13424aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                        "'requested android.hardware.touchscreen.multitouch.distinct feature'\n");
134389d97c1418c7a8b54fd57cc90daa1b1a98848bf6Dan Morrill            }
1344ef05e076ced1a32c5c0aaee28403779834adb2baDianne Hackborn
1345e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn            // Landscape/portrait-related compatibility logic
1346f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn            if (!specScreenLandscapeFeature && !specScreenPortraitFeature) {
1347f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn                // If the app has specified any activities in its manifest
1348f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn                // that request a specific orientation, then assume that
1349f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn                // orientation is required.
1350f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn                if (reqScreenLandscapeFeature) {
1351f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn                    printf("uses-feature:'android.hardware.screen.landscape'\n");
13524aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                    printf("uses-implied-feature:'android.hardware.screen.landscape'," \
13534aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                            "'one or more activities have specified a landscape orientation'\n");
1354f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn                }
1355f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn                if (reqScreenPortraitFeature) {
1356f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn                    printf("uses-feature:'android.hardware.screen.portrait'\n");
13574aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                    printf("uses-implied-feature:'android.hardware.screen.portrait'," \
13584aa14b912fa7b0e8f2f1deb3e66dab4668de1e12Dianne Hackborn                            "'one or more activities have specified a portrait orientation'\n");
1359f77ae6e65a7ab47e7ab0ee1536d708b6e56fe45bDianne Hackborn                }
1360e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn            }
1361e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn
13621b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            if (hasMainActivity) {
13631b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                printf("main\n");
13641b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            }
13651b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            if (hasWidgetReceivers) {
13661b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                printf("app-widget\n");
13671b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            }
13681b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            if (hasImeService) {
13691b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                printf("ime\n");
13701b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            }
13711b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            if (hasWallpaperService) {
13721b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                printf("wallpaper\n");
13731b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            }
13741b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            if (hasOtherActivities) {
13751b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                printf("other-activities\n");
13761b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            }
13771b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            if (isSearchable) {
13781b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                printf("search\n");
13791b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            }
13801b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            if (hasOtherReceivers) {
13811b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                printf("other-receivers\n");
13821b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            }
13831b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            if (hasOtherServices) {
13841b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu                printf("other-services\n");
13851b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu            }
13861b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu
1387e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn            // For modern apps, if screen size buckets haven't been specified
1388e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn            // but the new width ranges have, then infer the buckets from them.
1389e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn            if (smallScreen > 0 && normalScreen > 0 && largeScreen > 0 && xlargeScreen > 0
1390e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                    && requiresSmallestWidthDp > 0) {
1391e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                int compatWidth = compatibleWidthLimitDp;
1392e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                if (compatWidth <= 0) compatWidth = requiresSmallestWidthDp;
1393e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                if (requiresSmallestWidthDp <= 240 && compatWidth >= 240) {
1394e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                    smallScreen = -1;
1395e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                } else {
1396e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                    smallScreen = 0;
1397e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                }
1398e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                if (requiresSmallestWidthDp <= 320 && compatWidth >= 320) {
1399e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                    normalScreen = -1;
1400e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                } else {
1401e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                    normalScreen = 0;
1402e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                }
1403e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                if (requiresSmallestWidthDp <= 480 && compatWidth >= 480) {
1404e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                    largeScreen = -1;
1405e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                } else {
1406e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                    largeScreen = 0;
1407e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                }
1408e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                if (requiresSmallestWidthDp <= 720 && compatWidth >= 720) {
1409e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                    xlargeScreen = -1;
1410e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                } else {
1411e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                    xlargeScreen = 0;
1412e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                }
1413e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn            }
1414e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn
1415723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn            // Determine default values for any unspecified screen sizes,
1416723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn            // based on the target SDK of the package.  As of 4 (donut)
1417723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn            // the screen size support was introduced, so all default to
1418723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn            // enabled.
1419723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn            if (smallScreen > 0) {
1420723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn                smallScreen = targetSdk >= 4 ? -1 : 0;
1421723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn            }
1422723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn            if (normalScreen > 0) {
1423723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn                normalScreen = -1;
1424723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn            }
1425723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn            if (largeScreen > 0) {
1426723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn                largeScreen = targetSdk >= 4 ? -1 : 0;
1427723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn            }
1428f43489d7d5e1c0c5c9a7e54c22845fcb99765f81Dianne Hackborn            if (xlargeScreen > 0) {
1429d58fb97ddf052b3ceac921ac7e936af990392b2cScott Main                // Introduced in Gingerbread.
1430d58fb97ddf052b3ceac921ac7e936af990392b2cScott Main                xlargeScreen = targetSdk >= 9 ? -1 : 0;
1431f43489d7d5e1c0c5c9a7e54c22845fcb99765f81Dianne Hackborn            }
1432a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn            if (anyDensity > 0) {
1433e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                anyDensity = (targetSdk >= 4 || requiresSmallestWidthDp > 0
1434e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                        || compatibleWidthLimitDp > 0) ? -1 : 0;
1435a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn            }
1436723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn            printf("supports-screens:");
1437723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn            if (smallScreen != 0) printf(" 'small'");
1438723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn            if (normalScreen != 0) printf(" 'normal'");
1439723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn            if (largeScreen != 0) printf(" 'large'");
1440f43489d7d5e1c0c5c9a7e54c22845fcb99765f81Dianne Hackborn            if (xlargeScreen != 0) printf(" 'xlarge'");
1441723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn            printf("\n");
1442a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn            printf("supports-any-density: '%s'\n", anyDensity ? "true" : "false");
1443e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn            if (requiresSmallestWidthDp > 0) {
1444e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                printf("requires-smallest-width:'%d'\n", requiresSmallestWidthDp);
1445e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn            }
1446e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn            if (compatibleWidthLimitDp > 0) {
1447e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                printf("compatible-width-limit:'%d'\n", compatibleWidthLimitDp);
1448e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn            }
1449e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn            if (largestWidthLimitDp > 0) {
1450e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn                printf("largest-width-limit:'%d'\n", largestWidthLimitDp);
1451e289bff0ec2b1af4ba773e0c8d49d5fd46eb9921Dianne Hackborn            }
1452a0b46c9c441f017a2008ca8ee2c864987465996bDianne Hackborn
14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            printf("locales:");
1454e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn            const size_t NL = locales.size();
1455e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn            for (size_t i=0; i<NL; i++) {
14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                const char* localeStr =  locales[i].string();
14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (localeStr == NULL || strlen(localeStr) == 0) {
14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    localeStr = "--_--";
14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                printf(" '%s'", localeStr);
14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            printf("\n");
14631b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu
1464e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn            printf("densities:");
1465e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn            const size_t ND = densities.size();
1466e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn            for (size_t i=0; i<ND; i++) {
1467e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn                printf(" '%d'", densities[i]);
1468e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn            }
1469e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn            printf("\n");
14701b125980c5de597c18a179b9b02b9a5afe106895Suchi Amalapurapu
1471bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn            AssetDir* dir = assets.openNonAssetDir(assetsCookie, "lib");
1472bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn            if (dir != NULL) {
1473bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                if (dir->getFileCount() > 0) {
1474bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                    printf("native-code:");
1475bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                    for (size_t i=0; i<dir->getFileCount(); i++) {
1476bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                        printf(" '%s'", dir->getFileName(i).string());
1477bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                    }
1478bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                    printf("\n");
1479bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                }
1480bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn                delete dir;
1481bb9ea30ea9e390e69602935571795d2c80dc7b91Dianne Hackborn            }
1482e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill        } else if (strcmp("badger", option) == 0) {
14836c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn            printf("%s", CONSOLE_DATA);
14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (strcmp("configurations", option) == 0) {
14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Vector<ResTable_config> configs;
14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            res.getConfigurations(&configs);
14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t N = configs.size();
14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (size_t i=0; i<N; i++) {
14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                printf("%s\n", configs[i].toString().string());
14909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
14929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "ERROR: unknown dump option '%s'\n", option);
14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            goto bail;
14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    result = NO_ERROR;
14987ef189d0a90f3c9a409512ab7dce9304639df481Suchi Amalapurapu
14999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbail:
15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (asset) {
15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        delete asset;
15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return (result != NO_ERROR);
15049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Handle the "add" command, which wants to add files to a new or
15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * pre-existing archive.
15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint doAdd(Bundle* bundle)
15129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
15139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ZipFile* zip = NULL;
15149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t result = UNKNOWN_ERROR;
15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* zipFileName;
15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (bundle->getUpdate()) {
15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /* avoid confusion */
15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "ERROR: can't use '-u' with add\n");
15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto bail;
15219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (bundle->getFileSpecCount() < 1) {
15249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "ERROR: must specify zip file name\n");
15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto bail;
15269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    zipFileName = bundle->getFileSpecEntry(0);
15289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (bundle->getFileSpecCount() < 2) {
15309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "NOTE: nothing to do\n");
15319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto bail;
15329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    zip = openReadWrite(zipFileName, true);
15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (zip == NULL) {
15369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "ERROR: failed opening/creating '%s' as Zip file\n", zipFileName);
15379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto bail;
15389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (int i = 1; i < bundle->getFileSpecCount(); i++) {
15419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const char* fileName = bundle->getFileSpecEntry(i);
15429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (strcasecmp(String8(fileName).getPathExtension().string(), ".gz") == 0) {
15449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            printf(" '%s'... (from gzip)\n", fileName);
15459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            result = zip->addGzip(fileName, String8(fileName).getBasePath().string(), NULL);
15469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
1547dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker            if (bundle->getJunkPath()) {
1548dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker                String8 storageName = String8(fileName).getPathLeaf();
1549dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker                printf(" '%s' as '%s'...\n", fileName, storageName.string());
1550dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker                result = zip->add(fileName, storageName.string(),
1551dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker                                  bundle->getCompressionMethod(), NULL);
1552dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker            } else {
1553dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker                printf(" '%s'...\n", fileName);
1554dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker                result = zip->add(fileName, bundle->getCompressionMethod(), NULL);
1555dbe7a68cc13ae135b33769918932838d2d447169Doug Zongker            }
15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (result != NO_ERROR) {
15589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "Unable to add '%s' to '%s'", bundle->getFileSpecEntry(i), zipFileName);
15599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (result == NAME_NOT_FOUND)
15609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fprintf(stderr, ": file not found\n");
15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            else if (result == ALREADY_EXISTS)
15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fprintf(stderr, ": already exists in archive\n");
15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            else
15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fprintf(stderr, "\n");
15659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            goto bail;
15669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    result = NO_ERROR;
15709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbail:
15729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    delete zip;
15739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return (result != NO_ERROR);
15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
15759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
15789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Delete files from an existing archive.
15799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
15809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint doRemove(Bundle* bundle)
15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
15829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ZipFile* zip = NULL;
15839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t result = UNKNOWN_ERROR;
15849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* zipFileName;
15859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (bundle->getFileSpecCount() < 1) {
15879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "ERROR: must specify zip file name\n");
15889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto bail;
15899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    zipFileName = bundle->getFileSpecEntry(0);
15919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (bundle->getFileSpecCount() < 2) {
15939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "NOTE: nothing to do\n");
15949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto bail;
15959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    zip = openReadWrite(zipFileName, false);
15989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (zip == NULL) {
15999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "ERROR: failed opening Zip archive '%s'\n",
16009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            zipFileName);
16019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto bail;
16029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (int i = 1; i < bundle->getFileSpecCount(); i++) {
16059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const char* fileName = bundle->getFileSpecEntry(i);
16069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ZipEntry* entry;
16079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        entry = zip->getEntryByName(fileName);
16099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (entry == NULL) {
16109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            printf(" '%s' NOT FOUND\n", fileName);
16119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            continue;
16129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        result = zip->remove(entry);
16159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (result != NO_ERROR) {
16179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "Unable to delete '%s' from '%s'\n",
16189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                bundle->getFileSpecEntry(i), zipFileName);
16199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            goto bail;
16209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* update the archive */
16249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    zip->flush();
16259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbail:
16279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    delete zip;
16289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return (result != NO_ERROR);
16299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
16309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
16339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Package up an asset directory and associated application files.
16349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
16359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint doPackage(Bundle* bundle)
16369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
16379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* outputAPKFile;
16389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int retVal = 1;
16399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err;
16409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<AaptAssets> assets;
16419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int N;
16429bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin    FILE* fp;
16439bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin    String8 dependencyFile;
16449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // -c zz_ZZ means do pseudolocalization
16469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ResourceFilter filter;
16479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err = filter.parse(bundle->getConfigurations());
16489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
16499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto bail;
16509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (filter.containsPseudo()) {
16529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bundle->setPseudolocalize(true);
16539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    N = bundle->getFileSpecCount();
16569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (N < 1 && bundle->getResourceSourceDirs().size() == 0 && bundle->getJarFiles().size() == 0
16579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            && bundle->getAndroidManifestFile() == NULL && bundle->getAssetSourceDir() == NULL) {
16589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "ERROR: no input files\n");
16599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto bail;
16609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    outputAPKFile = bundle->getOutputAPKFile();
16639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Make sure the filenames provided exist and are of the appropriate type.
16659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (outputAPKFile) {
16669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        FileType type;
16679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        type = getFileType(outputAPKFile);
16689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (type != kFileTypeNonexistent && type != kFileTypeRegular) {
16699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr,
16709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "ERROR: output file '%s' exists but is not regular file\n",
16719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                outputAPKFile);
16729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            goto bail;
16739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Load the assets.
16779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    assets = new AaptAssets();
16789bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin
167903589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin    // Set up the resource gathering in assets if we're going to generate
1680b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin    // dependency files. Every time we encounter a resource while slurping
1681b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin    // the tree, we'll add it to these stores so we have full resource paths
1682b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin    // to write to a dependency file.
16839bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin    if (bundle->getGenDependencies()) {
168403589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin        sp<FilePathStore> resPathStore = new FilePathStore;
168503589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin        assets->setFullResPaths(resPathStore);
168603589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin        sp<FilePathStore> assetPathStore = new FilePathStore;
168703589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin        assets->setFullAssetPaths(assetPathStore);
16889bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin    }
16899bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin
16909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err = assets->slurpFromArgs(bundle);
16919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err < 0) {
16929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto bail;
16939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (bundle->getVerbose()) {
1696e6b680364dd992907a8d2037685a2e500d188dfbDianne Hackborn        assets->print(String8());
16979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16999bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin    // If they asked for any fileAs that need to be compiled, do so.
17009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (bundle->getResourceSourceDirs().size() || bundle->getAndroidManifestFile()) {
17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        err = buildResources(bundle, assets);
17029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != 0) {
17039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            goto bail;
17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // At this point we've read everything and processed everything.  From here
17089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // on out it's just writing output files.
17099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (SourcePos::hasErrors()) {
17109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto bail;
17119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17131644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn    // Update symbols with information about which ones are needed as Java symbols.
17141644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn    assets->applyJavaSymbols();
17151644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn    if (SourcePos::hasErrors()) {
17161644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn        goto bail;
17171644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn    }
17181644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn
1719b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin    // If we've been asked to generate a dependency file, do that here
17209bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin    if (bundle->getGenDependencies()) {
1721b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin        // If this is the packaging step, generate the dependency file next to
1722b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin        // the output apk (e.g. bin/resources.ap_.d)
172303589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin        if (outputAPKFile) {
172403589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin            dependencyFile = String8(outputAPKFile);
1725b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin            // Add the .d extension to the dependency file.
172603589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin            dependencyFile.append(".d");
172703589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin        } else {
1728b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin            // Else if this is the R.java dependency generation step,
1729b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin            // generate the dependency file in the R.java package subdirectory
1730b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin            // e.g. gen/com/foo/app/R.java.d
173103589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin            dependencyFile = String8(bundle->getRClassDir());
1732b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin            dependencyFile.appendPath("R.java.d");
173303589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin        }
17349bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin        // Make sure we have a clean dependency file to start with
17359bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin        fp = fopen(dependencyFile, "w");
17369bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin        fclose(fp);
17379bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin    }
17389bf34ca6f85309c65b0ebdf614cb8266401b49baJosiah Gaskin
17399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Write out R.java constants
17401644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn    if (!assets->havePrivateSymbols()) {
174163459ad555c10de1f316d6de01fc3cd0c0aaa457Xavier Ducrohet        if (bundle->getCustomPackage() == NULL) {
1742b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin            // Write the R.java file into the appropriate class directory
1743b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin            // e.g. gen/com/foo/app/R.java
174463459ad555c10de1f316d6de01fc3cd0c0aaa457Xavier Ducrohet            err = writeResourceSymbols(bundle, assets, assets->getPackage(), true);
174563459ad555c10de1f316d6de01fc3cd0c0aaa457Xavier Ducrohet        } else {
174663459ad555c10de1f316d6de01fc3cd0c0aaa457Xavier Ducrohet            const String8 customPkg(bundle->getCustomPackage());
174763459ad555c10de1f316d6de01fc3cd0c0aaa457Xavier Ducrohet            err = writeResourceSymbols(bundle, assets, customPkg, true);
174863459ad555c10de1f316d6de01fc3cd0c0aaa457Xavier Ducrohet        }
17499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err < 0) {
17509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            goto bail;
17519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1752002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang        // If we have library files, we're going to write our R.java file into
1753002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang        // the appropriate class directory for those libraries as well.
1754002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang        // e.g. gen/com/foo/app/lib/R.java
1755002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang        if (bundle->getExtraPackages() != NULL) {
1756002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang            // Split on colon
1757002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang            String8 libs(bundle->getExtraPackages());
1758002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang            char* packageString = strtok(libs.lockBuffer(libs.length()), ":");
1759002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang            while (packageString != NULL) {
1760002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang                // Write the R.java file out with the correct package name
1761002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang                err = writeResourceSymbols(bundle, assets, String8(packageString), true);
1762002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang                if (err < 0) {
1763002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang                    goto bail;
1764002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang                }
1765002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang                packageString = strtok(NULL, ":");
1766002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang            }
1767002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang            libs.unlockBuffer();
1768002f53770a7f6850eab4d7e381e91dc94d28968fYing Wang        }
17699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
17709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        err = writeResourceSymbols(bundle, assets, assets->getPackage(), false);
17719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err < 0) {
17729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            goto bail;
17739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        err = writeResourceSymbols(bundle, assets, assets->getSymbolsPrivatePackage(), true);
17759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err < 0) {
17769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            goto bail;
17779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17801553c82e084ac5763fb393857224145506771b99Joe Onorato    // Write out the ProGuard file
17811553c82e084ac5763fb393857224145506771b99Joe Onorato    err = writeProguardFile(bundle, assets);
17821553c82e084ac5763fb393857224145506771b99Joe Onorato    if (err < 0) {
17831553c82e084ac5763fb393857224145506771b99Joe Onorato        goto bail;
17841553c82e084ac5763fb393857224145506771b99Joe Onorato    }
17851553c82e084ac5763fb393857224145506771b99Joe Onorato
17869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Write the apk
17879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (outputAPKFile) {
17889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        err = writeAPK(bundle, assets, String8(outputAPKFile));
17899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
17909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "ERROR: packaging of '%s' failed\n", outputAPKFile);
17919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            goto bail;
17929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1795b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin    // If we've been asked to generate a dependency file, we need to finish up here.
1796b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin    // the writeResourceSymbols and writeAPK functions have already written the target
1797b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin    // half of the dependency file, now we need to write the prerequisites. (files that
1798b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin    // the R.java file or .ap_ file depend on)
179903589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin    if (bundle->getGenDependencies()) {
180003589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin        // Now that writeResourceSymbols or writeAPK has taken care of writing
180103589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin        // the targets to our dependency file, we'll write the prereqs
180203589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin        fp = fopen(dependencyFile, "a+");
180303589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin        fprintf(fp, " : ");
180403589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin        bool includeRaw = (outputAPKFile != NULL);
180503589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin        err = writeDependencyPreReqs(bundle, assets, fp, includeRaw);
1806b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin        // Also manually add the AndroidManifeset since it's not under res/ or assets/
1807b711f3f7ee0544685ef26a1a4b4755d5a6233dbaJosiah Gaskin        // and therefore was not added to our pathstores during slurping
180803589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin        fprintf(fp, "%s \\\n", bundle->getAndroidManifestFile());
180903589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin        fclose(fp);
181003589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin    }
181103589cc65355220e0a4a0c816189a9fa25cc81fcJosiah Gaskin
18129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    retVal = 0;
18139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbail:
18149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (SourcePos::hasErrors()) {
18159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SourcePos::printErrors(stderr);
18169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return retVal;
18189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
18198a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin
18208a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin/*
18218a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin * Do PNG Crunching
18228a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin * PRECONDITIONS
18238a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin *  -S flag points to a source directory containing drawable* folders
18248a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin *  -C flag points to destination directory. The folder structure in the
18258a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin *     source directory will be mirrored to the destination (cache) directory
18268a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin *
18278a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin * POSTCONDITIONS
18288a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin *  Destination directory will be updated to match the PNG files in
18298a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin *  the source directory.
18308a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin */
18318a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskinint doCrunch(Bundle* bundle)
18328a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin{
18338a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin    fprintf(stdout, "Crunching PNG Files in ");
18348a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin    fprintf(stdout, "source dir: %s\n", bundle->getResourceSourceDirs()[0]);
18358a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin    fprintf(stdout, "To destination dir: %s\n", bundle->getCrunchedOutputDir());
18368a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin
18378a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin    updatePreProcessedCache(bundle);
18388a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin
18398a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin    return NO_ERROR;
18408a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin}
1841e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill
1842e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrillchar CONSOLE_DATA[2925] = {
1843e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1844e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 95, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1845e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1846e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32,
1847e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 63,
1848e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    86, 35, 40, 46, 46, 95, 95, 95, 95, 97, 97, 44, 32, 46, 124, 42, 33, 83,
1849e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    62, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1850e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1851e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 46, 58, 59, 61, 59, 61, 81,
1852e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    81, 81, 81, 66, 96, 61, 61, 58, 46, 46, 46, 58, 32, 32, 32, 32, 32, 32,
1853e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32,
1854e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1855e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 46, 61, 59, 59, 59, 58, 106, 81, 81, 81, 81, 102, 59, 61, 59,
1856e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    59, 61, 61, 61, 58, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1857e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1858e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59,
1859e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    59, 58, 109, 81, 81, 81, 81, 61, 59, 59, 59, 59, 59, 58, 59, 59, 46, 32,
1860e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1861e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1862e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 60, 81, 81, 81, 81, 87,
1863e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    58, 59, 59, 59, 59, 59, 59, 61, 119, 44, 32, 32, 32, 32, 32, 32, 32, 32,
1864e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32,
1865e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46,
1866e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    47, 61, 59, 59, 58, 100, 81, 81, 81, 81, 35, 58, 59, 59, 59, 59, 59, 58,
1867e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    121, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1868e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1869e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 109, 58, 59, 59, 61, 81, 81,
1870e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    81, 81, 81, 109, 58, 59, 59, 59, 59, 61, 109, 81, 81, 76, 46, 32, 32, 32,
1871e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32,
1872e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1873e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 41, 87, 59, 61, 59, 41, 81, 81, 81, 81, 81, 81, 59, 61, 59,
1874e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    59, 58, 109, 81, 81, 87, 39, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1875e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1876e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 60, 81, 91, 59,
1877e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    59, 61, 81, 81, 81, 81, 81, 87, 43, 59, 58, 59, 60, 81, 81, 81, 76, 32,
1878e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1879e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1880e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 52, 91, 58, 45, 59, 87, 81, 81, 81, 81,
1881e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    70, 58, 58, 58, 59, 106, 81, 81, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32,
1882e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32,
1883e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1884e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 93, 40, 32, 46, 59, 100, 81, 81, 81, 81, 40, 58, 46, 46, 58, 100, 81,
1885e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    81, 68, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1886e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1887e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 46, 46, 46, 32, 46, 46, 46, 32, 46, 32, 46, 45, 91, 59, 61, 58, 109,
1888e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    81, 81, 81, 87, 46, 58, 61, 59, 60, 81, 81, 80, 32, 32, 32, 32, 32, 32,
1889e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32,
1890e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 46, 46, 61, 59, 61, 61, 61, 59, 61, 61, 59,
1891e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    59, 59, 58, 58, 46, 46, 41, 58, 59, 58, 81, 81, 81, 81, 69, 58, 59, 59,
1892e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    60, 81, 81, 68, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1893e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 58, 59,
1894e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 61, 46,
1895e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    61, 59, 93, 81, 81, 81, 81, 107, 58, 59, 58, 109, 87, 68, 96, 32, 32, 32,
1896e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1897e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 10, 32, 32, 32, 46, 60, 61, 61, 59, 59, 59, 59, 59, 59, 59, 59,
1898e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    59, 59, 59, 59, 59, 59, 59, 59, 59, 58, 58, 58, 115, 109, 68, 41, 36, 81,
1899e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    109, 46, 61, 61, 81, 69, 96, 46, 58, 58, 46, 58, 46, 46, 32, 32, 32, 32,
1900e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 46, 32, 95, 81,
1901e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    67, 61, 61, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
1902e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    59, 59, 59, 59, 58, 68, 39, 61, 105, 61, 63, 81, 119, 58, 106, 80, 32, 58,
1903e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    61, 59, 59, 61, 59, 61, 59, 61, 46, 95, 32, 32, 32, 32, 32, 32, 32, 32,
1904e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 10, 32, 32, 36, 81, 109, 105, 59, 61, 59, 59, 59,
1905e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 46, 58, 37,
1906e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    73, 108, 108, 62, 52, 81, 109, 34, 32, 61, 59, 59, 59, 59, 59, 59, 59, 59,
1907e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    59, 61, 59, 61, 61, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10,
1908e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 46, 45, 57, 101, 43, 43, 61, 61, 59, 59, 59, 59, 59, 59, 61, 59, 59,
1909e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    59, 59, 59, 59, 59, 59, 59, 58, 97, 46, 61, 108, 62, 126, 58, 106, 80, 96,
1910e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    46, 61, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 61,
1911e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    97, 103, 97, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 45, 46, 32,
1912e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    46, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45, 58, 59, 59, 59, 59, 61,
1913e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    119, 81, 97, 124, 105, 124, 124, 39, 126, 95, 119, 58, 61, 58, 59, 59, 59,
1914e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 119, 81, 81, 99, 32, 32,
1915e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1916e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 58, 106, 81, 81, 81, 109, 119,
1917e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    119, 119, 109, 109, 81, 81, 122, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59,
1918e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    59, 59, 59, 59, 59, 58, 115, 81, 87, 81, 102, 32, 32, 32, 32, 32, 32, 10,
1919e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1920e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 61, 58, 59, 61, 81, 81, 81, 81, 81, 81, 87, 87, 81, 81, 81, 81,
1921e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    81, 58, 59, 59, 59, 59, 59, 59, 59, 59, 58, 45, 45, 45, 59, 59, 59, 41,
1922e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    87, 66, 33, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32,
1923e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 93, 81,
1924e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58,
1925e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    45, 32, 46, 32, 32, 32, 32, 32, 46, 32, 126, 96, 32, 32, 32, 32, 32, 32,
1926e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1927e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 58, 61, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81,
1928e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32,
1929e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32,
1930e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58,
1931e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    59, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58,
1932e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    59, 59, 59, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1933e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1934e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 60, 81, 81, 81, 81,
1935e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    81, 81, 81, 81, 81, 81, 81, 81, 81, 59, 61, 59, 59, 61, 32, 32, 32, 32,
1936e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1937e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1938e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 58, 59, 59, 93, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
1939e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    81, 81, 40, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1940e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32,
1941e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 106,
1942e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 76, 58, 59, 59, 59,
1943e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1944e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1945e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 61, 58, 58, 81, 81, 81, 81, 81, 81, 81, 81,
1946e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    81, 81, 81, 81, 81, 87, 58, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32,
1947e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32,
1948e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1949e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    58, 59, 61, 41, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 87, 59,
1950e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    61, 58, 59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1951e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1952e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 61, 81, 81, 81,
1953e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    81, 81, 81, 81, 81, 81, 81, 81, 81, 107, 58, 59, 59, 59, 59, 58, 32, 32,
1954e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1955e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1956e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 58, 59, 59, 58, 51, 81, 81, 81, 81, 81, 81, 81, 81, 81,
1957e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    81, 102, 94, 59, 59, 59, 59, 59, 61, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1958e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32,
1959e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59,
1960e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    59, 59, 43, 63, 36, 81, 81, 81, 87, 64, 86, 102, 58, 59, 59, 59, 59, 59,
1961e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1962e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1963e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 59, 59, 43, 33,
1964e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    58, 126, 126, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32, 32,
1965e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32,
1966e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46,
1967e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    61, 59, 59, 59, 58, 45, 58, 61, 59, 58, 58, 58, 61, 59, 59, 59, 59, 59,
1968e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    59, 59, 59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32,
1969e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32,
1970e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 58, 95,
1971e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 45, 61, 59, 61, 59, 59, 59, 59, 59, 59, 59, 45, 58, 59, 59, 59, 59,
1972e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    61, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1973e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1974e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 58, 61, 59, 59, 59, 59, 59, 61, 59, 61, 46, 46, 32, 45, 45, 45,
1975e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    59, 58, 45, 45, 46, 58, 59, 59, 59, 59, 59, 59, 61, 46, 32, 32, 32, 32,
1976e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32,
1977e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 58, 59, 59, 59, 59,
1978e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    59, 59, 59, 59, 59, 61, 59, 46, 32, 32, 46, 32, 46, 32, 58, 61, 59, 59,
1979e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    59, 59, 59, 59, 59, 59, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1980e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1981e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 45, 59, 59, 59, 59, 59, 59, 59, 59, 58, 32,
1982e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 58, 32,
1983e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10,
1984e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1985e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    46, 61, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 61,
1986e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    46, 61, 59, 59, 59, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1987e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32,
1988e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59,
1989e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 46, 61, 58, 59, 59, 59, 59,
1990e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1991e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1992e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 58, 59, 59, 59, 59, 59, 59, 59, 59, 46, 46, 32, 32, 32,
1993e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 45, 32, 32, 32, 32, 32,
1994e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32,
1995e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 32, 45, 61,
1996e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59,
1997e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    59, 59, 59, 58, 45, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1998e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1999e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45, 45, 32, 46, 32,
2000e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 61, 59, 58, 45, 45, 32, 32, 32,
2001e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
2002e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
2003e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
2004e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 46, 32, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
2005e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10
2006e74763e26f760e8de23a4edfbe599a166ef6bb53Dan Morrill  };
2007