Resource.cpp revision de7de47fef1dcaa26d553665d89e4d3792325c3f
15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Copyright 2006 The Android Open Source Project
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Build resource files from raw assets.
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "AaptAssets.h"
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "AaptUtil.h"
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "AaptXml.h"
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "CacheUpdater.h"
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "CrunchCache.h"
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "FileFinder.h"
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "Images.h"
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "IndentPrinter.h"
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "Main.h"
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "ResourceTable.h"
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "StringPool.h"
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "Symbol.h"
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "WorkQueue.h"
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "XMLNode.h"
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <algorithm>
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if HAVE_PRINTF_ZD
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#  define ZD "%zd"
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#  define ZD_TYPE ssize_t
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#else
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#  define ZD "%ld"
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#  define ZD_TYPE long
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define NOISY(x) // x
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
33f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu// Number of threads to use for preprocessing images.
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const size_t MAX_THREADS = 4;
358abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
36926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// ==========================================================================
37926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// ==========================================================================
38aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch// ==========================================================================
3909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
40aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdochclass PackageInfo
41aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch{
4253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)public:
4343e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    PackageInfo()
4453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    {
450019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch    }
4653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ~PackageInfo()
471e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    {
48f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    }
4909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
50d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    status_t parsePackage(const sp<AaptGroup>& grp);
51d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)};
52d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
53e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch// ==========================================================================
54e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch// ==========================================================================
5553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)// ==========================================================================
5653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
5753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)String8 parseResourceName(const String8& leaf)
585267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles){
59d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const char* firstDot = strchr(leaf.string(), '.');
60f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    const char* str = leaf.string();
61d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
621e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (firstDot) {
631e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        return String8(str, firstDot-str);
64a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    } else {
655267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        return String8(str);
665267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    }
675267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)}
68bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
695267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)ResourceTypeSet::ResourceTypeSet()
70bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    :RefBase(),
71f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu     KeyedVector<String8,sp<AaptGroup> >()
72f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu{
73f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu}
74f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
75f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo LiuFilePathStore::FilePathStore()
76f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    :RefBase(),
77f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu     Vector<String8>()
78f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu{
79f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu}
80f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
81f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liuclass ResourceDirIterator
82f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu{
83f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liupublic:
84f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    ResourceDirIterator(const sp<ResourceTypeSet>& set, const String8& resType)
85f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        : mResType(resType), mSet(set), mSetPos(0), mGroupPos(0)
86f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    {
87f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        memset(&mParams, 0, sizeof(ResTable_config));
88f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    }
89f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
90f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    inline const sp<AaptGroup>& getGroup() const { return mGroup; }
91591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    inline const sp<AaptFile>& getFile() const { return mFile; }
92d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
93f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    inline const String8& getBaseName() const { return mBaseName; }
94f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    inline const String8& getLeafName() const { return mLeafName; }
951e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    inline String8 getPath() const { return mPath; }
96f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    inline const ResTable_config& getParams() const { return mParams; }
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    enum {
99926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        EOD = 1
100926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    };
101926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ssize_t next()
103591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    {
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        while (true) {
10551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            sp<AaptGroup> group;
10651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            sp<AaptFile> file;
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Try to get next file in this current group.
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (mGroup != NULL && mGroupPos < mGroup->getFiles().size()) {
110f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                group = mGroup;
111f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                file = group->getFiles().valueAt(mGroupPos++);
112926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
113926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            // Try to get the next group/file in this directory
114926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            } else if (mSetPos < mSet->size()) {
115926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                mGroup = group = mSet->valueAt(mSetPos++);
116926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                if (group->getFiles().size() < 1) {
117926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    continue;
118f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu                }
11953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                file = group->getFiles().valueAt(0);
12043e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)                mGroupPos = 1;
12153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
12253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            // All done!
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            } else {
1241e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                return EOD;
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
126926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
127926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            mFile = file;
128926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
129926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            String8 leaf(group->getLeaf());
130926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            mLeafName = String8(leaf);
131926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            mParams = file->getGroupEntry().toParams();
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            NOISY(printf("Dir %s: mcc=%d mnc=%d lang=%c%c cnt=%c%c orient=%d ui=%d density=%d touch=%d key=%d inp=%d nav=%d\n",
133926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                   group->getPath().string(), mParams.mcc, mParams.mnc,
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                   mParams.language[0] ? mParams.language[0] : '-',
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                   mParams.language[1] ? mParams.language[1] : '-',
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                   mParams.country[0] ? mParams.country[0] : '-',
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                   mParams.country[1] ? mParams.country[1] : '-',
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                   mParams.orientation, mParams.uiMode,
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                   mParams.density, mParams.touchscreen, mParams.keyboard,
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                   mParams.inputFlags, mParams.navigation));
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            mPath = "res";
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            mPath.appendPath(file->getGroupEntry().toDirName(mResType));
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            mPath.appendPath(leaf);
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            mBaseName = parseResourceName(leaf);
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (mBaseName == "") {
146aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch                fprintf(stderr, "Error: malformed resource filename %s\n",
147aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch                        file->getPrintableSource().string());
148aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch                return UNKNOWN_ERROR;
149aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch            }
150aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch
151aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch            NOISY(printf("file name=%s\n", mBaseName.string()));
152aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch
153aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch            return NO_ERROR;
154aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch        }
155aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    }
156aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch
157aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdochprivate:
1581e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    String8 mResType;
15953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1601e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    const sp<ResourceTypeSet> mSet;
1611e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    size_t mSetPos;
1621e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
1631e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    sp<AaptGroup> mGroup;
16453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    size_t mGroupPos;
16553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1661e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    sp<AaptFile> mFile;
1671e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    String8 mBaseName;
1681e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    String8 mLeafName;
1691e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    String8 mPath;
1701e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ResTable_config mParams;
1711e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)};
172c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
173f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)class AnnotationProcessor {
174f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)public:
175f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    AnnotationProcessor() : mDeprecated(false), mSystemApi(false) { }
176f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
177f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    void preprocessComment(String8& comment) {
178f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        if (comment.size() > 0) {
179f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)            if (comment.contains("@deprecated")) {
180f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)                mDeprecated = true;
181f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)            }
182f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)            if (comment.removeAll("@SystemApi")) {
183f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)                mSystemApi = true;
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1888abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    void printAnnotations(FILE* fp, const char* indentStr) {
1898abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        if (mDeprecated) {
1908abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            fprintf(fp, "%s@Deprecated\n", indentStr);
1918abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        }
1928abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        if (mSystemApi) {
1938abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            fprintf(fp, "%s@android.annotation.SystemApi\n", indentStr);
1948abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        }
1958abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    }
1968abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
1978abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)private:
1988abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    bool mDeprecated;
1998abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    bool mSystemApi;
2008abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)};
2018abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
2028abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)// ==========================================================================
2038abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)// ==========================================================================
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// ==========================================================================
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool isValidResourceType(const String8& type)
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return type == "anim" || type == "animator" || type == "interpolator"
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        || type == "transition"
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        || type == "drawable" || type == "layout"
2111e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        || type == "values" || type == "xml" || type == "raw"
2121e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        || type == "color" || type == "menu" || type == "mipmap";
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2151e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)static status_t parsePackage(Bundle* bundle, const sp<AaptAssets>& assets,
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const sp<AaptGroup>& grp)
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (grp->getFiles().size() != 1) {
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        fprintf(stderr, "warning: Multiple AndroidManifest.xml files found, using %s\n",
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                grp->getFiles().valueAt(0)->getPrintableSource().string());
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    sp<AaptFile> file = grp->getFiles().valueAt(0);
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ResXMLTree block;
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    status_t err = parseXMLResource(file, &block);
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (err != NO_ERROR) {
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return err;
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2301e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    //printXMLBlock(&block);
2311e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ResXMLTree::event_code_t code;
2338abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    while ((code=block.next()) != ResXMLTree::START_TAG
2346f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch           && code != ResXMLTree::END_DOCUMENT
2356f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch           && code != ResXMLTree::BAD_DOCUMENT) {
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    size_t len;
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (code != ResXMLTree::START_TAG) {
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        fprintf(stderr, "%s:%d: No start tag found\n",
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                file->getPrintableSource().string(), block.getLineNumber());
2421e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        return UNKNOWN_ERROR;
2431e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (strcmp16(block.getElementName(&len), String16("manifest").string()) != 0) {
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        fprintf(stderr, "%s:%d: Invalid start tag %s, expected <manifest>\n",
2461e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                file->getPrintableSource().string(), block.getLineNumber(),
2471e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                String8(block.getElementName(&len)).string());
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return UNKNOWN_ERROR;
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ssize_t nameIndex = block.indexOfAttribute(NULL, "package");
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (nameIndex < 0) {
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        fprintf(stderr, "%s:%d: <manifest> does not have package attribute.\n",
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                file->getPrintableSource().string(), block.getLineNumber());
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return UNKNOWN_ERROR;
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
25802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    assets->setPackage(String8(block.getAttributeStringValue(nameIndex, &len)));
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2601e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    String16 uses_sdk16("uses-sdk");
2611e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    while ((code=block.next()) != ResXMLTree::END_DOCUMENT
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)           && code != ResXMLTree::BAD_DOCUMENT) {
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (code == ResXMLTree::START_TAG) {
2641e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            if (strcmp16(block.getElementName(&len), uses_sdk16.string()) == 0) {
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                ssize_t minSdkIndex = block.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE,
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                             "minSdkVersion");
2671e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                if (minSdkIndex >= 0) {
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    const char16_t* minSdk16 = block.getAttributeStringValue(minSdkIndex, &len);
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    const char* minSdk8 = strdup(String8(minSdk16).string());
2701e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    bundle->setManifestMinSdkVersion(minSdk8);
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return NO_ERROR;
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2791e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)// ==========================================================================
2801e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)// ==========================================================================
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// ==========================================================================
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static status_t makeFileResources(Bundle* bundle, const sp<AaptAssets>& assets,
2841e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                                  ResourceTable* table,
2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                  const sp<ResourceTypeSet>& set,
2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                  const char* resType)
2871e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String8 type8(resType);
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String16 type16(resType);
2901e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool hasErrors = false;
2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ResourceDirIterator it(set, String8(resType));
294bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    ssize_t res;
295bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    while ((res=it.next()) == NO_ERROR) {
296bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        if (bundle->getVerbose()) {
297bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)            printf("    (new resource id %s from %s)\n",
298bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)                   it.getBaseName().string(), it.getFile()->getPrintableSource().string());
299bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        }
300bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        String16 baseName(it.getBaseName());
301bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        const char16_t* str = baseName.string();
302bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        const char16_t* const end = str + baseName.size();
303bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        while (str < end) {
304bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)            if (!((*str >= 'a' && *str <= 'z')
305bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)                    || (*str >= '0' && *str <= '9')
306bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)                    || *str == '_' || *str == '.')) {
307bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)                fprintf(stderr, "%s: Invalid file name: must contain only [a-z0-9_.]\n",
308bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)                        it.getPath().string());
309bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)                hasErrors = true;
310bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)            }
311bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)            str++;
312bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        }
313bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        String8 resPath = it.getPath();
314bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        resPath.convertToResPath();
315bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        table->addEntry(SourcePos(it.getPath(), 0), String16(assets->getPackage()),
316bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)                        type16,
317bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)                        baseName,
318bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)                        String16(resPath),
319bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)                        NULL,
320bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)                        &it.getParams());
321bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        assets->addResource(it.getLeafName(), resPath, it.getFile(), type8);
322bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    }
323bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
324bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
325bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)}
326bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
327bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)class PreProcessImageWorkUnit : public WorkQueue::WorkUnit {
328bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)public:
329bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    PreProcessImageWorkUnit(const Bundle* bundle, const sp<AaptAssets>& assets,
330bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)            const sp<AaptFile>& file, volatile bool* hasErrors) :
331bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)            mBundle(bundle), mAssets(assets), mFile(file), mHasErrors(hasErrors) {
332bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    }
333d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
3341e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    virtual bool run() {
3351e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        status_t status = preProcessImage(mBundle, mAssets, mFile, NULL);
336a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        if (status) {
3371e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            *mHasErrors = true;
338a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        }
3391e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        return true; // continue even if there are errors
3401e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
3411e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
342a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochprivate:
3431e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    const Bundle* mBundle;
3441e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    sp<AaptAssets> mAssets;
3451e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    sp<AaptFile> mFile;
3461e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    volatile bool* mHasErrors;
3471e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)};
3481e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
3491e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)static status_t preProcessImages(const Bundle* bundle, const sp<AaptAssets>& assets,
3501e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                          const sp<ResourceTypeSet>& set, const char* type)
3511e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){
3521e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    volatile bool hasErrors = false;
3531e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ssize_t res = NO_ERROR;
3541e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (bundle->getUseCrunchCache() == false) {
3551e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        WorkQueue wq(MAX_THREADS, false);
3561e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        ResourceDirIterator it(set, String8(type));
3571e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        while ((res=it.next()) == NO_ERROR) {
3581e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            PreProcessImageWorkUnit* w = new PreProcessImageWorkUnit(
3591e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    bundle, assets, it.getFile(), &hasErrors);
3601e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            status_t status = wq.schedule(w);
3611e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            if (status) {
3621e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                fprintf(stderr, "preProcessImages failed: schedule() returned %d\n", status);
363a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch                hasErrors = true;
3641e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                delete w;
3651e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                break;
3661e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            }
3671e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
3681e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        status_t status = wq.finish();
3691e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (status) {
3701e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            fprintf(stderr, "preProcessImages failed: finish() returned %d\n", status);
3711e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            hasErrors = true;
3721e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
3731e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
3741e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return (hasErrors || (res < NO_ERROR)) ? UNKNOWN_ERROR : NO_ERROR;
3751e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
3761e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
3771e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)static void collect_files(const sp<AaptDir>& dir,
3781e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        KeyedVector<String8, sp<ResourceTypeSet> >* resources)
3791e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){
3801e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    const DefaultKeyedVector<String8, sp<AaptGroup> >& groups = dir->getFiles();
3811e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    int N = groups.size();
3821e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    for (int i=0; i<N; i++) {
3831e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        String8 leafName = groups.keyAt(i);
3841e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        const sp<AaptGroup>& group = groups.valueAt(i);
3851e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
386d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        const DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> >& files
3871e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                = group->getFiles();
388d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
3891e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (files.size() == 0) {
3901e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            continue;
3911e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
3921e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
3931e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        String8 resType = files.valueAt(0)->getResourceType();
39409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
3951e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        ssize_t index = resources->indexOfKey(resType);
3961e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
3971e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (index < 0) {
3981e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            sp<ResourceTypeSet> set = new ResourceTypeSet();
3991e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            NOISY(printf("Creating new resource type set for leaf %s with group %s (%p)\n",
400a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch                    leafName.string(), group->getPath().string(), group.get()));
4011e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            set->add(leafName, group);
4021e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            resources->add(resType, set);
40351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        } else {
4041e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            sp<ResourceTypeSet> set = resources->valueAt(index);
4051e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            index = set->indexOfKey(leafName);
4061e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            if (index < 0) {
4071e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                NOISY(printf("Adding to resource type set for leaf %s group %s (%p)\n",
4081e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        leafName.string(), group->getPath().string(), group.get()));
4091e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                set->add(leafName, group);
4101e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            } else {
4111e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                sp<AaptGroup> existingGroup = set->valueAt(index);
4121e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                NOISY(printf("Extending to resource type set for leaf %s group %s (%p)\n",
4131e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        leafName.string(), group->getPath().string(), group.get()));
4141e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                for (size_t j=0; j<files.size(); j++) {
4151e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    NOISY(printf("Adding file %s in group %s resType %s\n",
4161e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        files.valueAt(j)->getSourceFile().string(),
4171e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        files.keyAt(j).toDirName(String8()).string(),
41809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                        resType.string()));
4191e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    status_t err = existingGroup->addFile(files.valueAt(j));
4201e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                }
4211e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            }
4221e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
4231e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
4241e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
4251e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
42609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)static void collect_files(const sp<AaptAssets>& ass,
4271e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        KeyedVector<String8, sp<ResourceTypeSet> >* resources)
4281e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){
4291e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    const Vector<sp<AaptDir> >& dirs = ass->resDirs();
4301e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    int N = dirs.size();
4311e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
4321e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    for (int i=0; i<N; i++) {
43309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        sp<AaptDir> d = dirs.itemAt(i);
4341e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        NOISY(printf("Collecting dir #%d %p: %s, leaf %s\n", i, d.get(), d->getPath().string(),
4351e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                d->getLeaf().string()));
4361e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        collect_files(d, resources);
4371e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
4381e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        // don't try to include the res dir
4391e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        NOISY(printf("Removing dir leaf %s\n", d->getLeaf().string()));
4401e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        ass->removeDir(d->getLeaf());
4411e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
4421e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
4431e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
4441e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)enum {
4451e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ATTR_OKAY = -1,
4461e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ATTR_NOT_FOUND = -2,
4471e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ATTR_LEADING_SPACES = -3,
4481e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ATTR_TRAILING_SPACES = -4
4491e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)};
4501e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)static int validateAttr(const String8& path, const ResTable& table,
4511e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        const ResXMLParser& parser,
4521e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        const char* ns, const char* attr, const char* validChars, bool required)
4531e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){
4541e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    size_t len;
4551e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
4561e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ssize_t index = parser.indexOfAttribute(ns, attr);
4571e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    const char16_t* str;
4581e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    Res_value value;
4591e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (index >= 0 && parser.getAttributeValue(index, &value) >= 0) {
4601e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        const ResStringPool* pool = &parser.getStrings();
4611e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (value.dataType == Res_value::TYPE_REFERENCE) {
4621e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            uint32_t specFlags = 0;
4631e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            int strIdx;
4641e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            if ((strIdx=table.resolveReference(&value, 0x10000000, NULL, &specFlags)) < 0) {
4651e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                fprintf(stderr, "%s:%d: Tag <%s> attribute %s references unknown resid 0x%08x.\n",
4661e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        path.string(), parser.getLineNumber(),
4671e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        String8(parser.getElementName(&len)).string(), attr,
4681e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        value.data);
4691e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                return ATTR_NOT_FOUND;
4701e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            }
4711e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
4721e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            pool = table.getTableStringBlock(strIdx);
4731e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            #if 0
4741e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            if (pool != NULL) {
4751e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                str = pool->stringAt(value.data, &len);
4761e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            }
4771e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            printf("***** RES ATTR: %s specFlags=0x%x strIdx=%d: %s\n", attr,
4781e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    specFlags, strIdx, str != NULL ? String8(str).string() : "???");
47951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            #endif
4801e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            if ((specFlags&~ResTable_typeSpec::SPEC_PUBLIC) != 0 && false) {
4811e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                fprintf(stderr, "%s:%d: Tag <%s> attribute %s varies by configurations 0x%x.\n",
4821e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        path.string(), parser.getLineNumber(),
4831e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        String8(parser.getElementName(&len)).string(), attr,
4841e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        specFlags);
4851e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                return ATTR_NOT_FOUND;
4861e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            }
4871e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
4881e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (value.dataType == Res_value::TYPE_STRING) {
4891e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            if (pool == NULL) {
4901e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                fprintf(stderr, "%s:%d: Tag <%s> attribute %s has no string block.\n",
4911e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        path.string(), parser.getLineNumber(),
4921e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        String8(parser.getElementName(&len)).string(), attr);
4931e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                return ATTR_NOT_FOUND;
4941e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            }
4951e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            if ((str=pool->stringAt(value.data, &len)) == NULL) {
4961e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                fprintf(stderr, "%s:%d: Tag <%s> attribute %s has corrupt string value.\n",
49751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                        path.string(), parser.getLineNumber(),
4981e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        String8(parser.getElementName(&len)).string(), attr);
4991e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                return ATTR_NOT_FOUND;
5001e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            }
5011e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        } else {
5021e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            fprintf(stderr, "%s:%d: Tag <%s> attribute %s has invalid type %d.\n",
5031e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    path.string(), parser.getLineNumber(),
5041e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    String8(parser.getElementName(&len)).string(), attr,
5051e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    value.dataType);
5061e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            return ATTR_NOT_FOUND;
5071e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
5081e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (validChars) {
5091e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            for (size_t i=0; i<len; i++) {
5101e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                char16_t c = str[i];
5111e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                const char* p = validChars;
5121e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                bool okay = false;
5131e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                while (*p) {
5141e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    if (c == *p) {
5151e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        okay = true;
5161e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        break;
5171e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    }
5181e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    p++;
5191e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                }
5201e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                if (!okay) {
5211e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    fprintf(stderr, "%s:%d: Tag <%s> attribute %s has invalid character '%c'.\n",
5221e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                            path.string(), parser.getLineNumber(),
5231e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                            String8(parser.getElementName(&len)).string(), attr, (char)str[i]);
5241e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    return (int)i;
5251e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                }
5261e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            }
5271e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
5281e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (*str == ' ') {
5291e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            fprintf(stderr, "%s:%d: Tag <%s> attribute %s can not start with a space.\n",
5301e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    path.string(), parser.getLineNumber(),
5311e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    String8(parser.getElementName(&len)).string(), attr);
5321e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            return ATTR_LEADING_SPACES;
5331e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
5341e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (str[len-1] == ' ') {
5351e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            fprintf(stderr, "%s:%d: Tag <%s> attribute %s can not end with a space.\n",
5361e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    path.string(), parser.getLineNumber(),
5371e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    String8(parser.getElementName(&len)).string(), attr);
5381e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            return ATTR_TRAILING_SPACES;
5391e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
5401e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        return ATTR_OKAY;
5411e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
5421e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (required) {
5431e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        fprintf(stderr, "%s:%d: Tag <%s> missing required attribute %s.\n",
5441e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                path.string(), parser.getLineNumber(),
5451e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                String8(parser.getElementName(&len)).string(), attr);
5461e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        return ATTR_NOT_FOUND;
5471e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
5481e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return ATTR_OKAY;
5491e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
5501e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
5511e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)static void checkForIds(const String8& path, ResXMLParser& parser)
55209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
5531e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ResXMLTree::event_code_t code;
5541e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    while ((code=parser.next()) != ResXMLTree::END_DOCUMENT
5551e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)           && code > ResXMLTree::BAD_DOCUMENT) {
5561e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (code == ResXMLTree::START_TAG) {
5571e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            ssize_t index = parser.indexOfAttribute(NULL, "id");
5581e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            if (index >= 0) {
5591e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                fprintf(stderr, "%s:%d: warning: found plain 'id' attribute; did you mean the new 'android:id' name?\n",
5601e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        path.string(), parser.getLineNumber());
5611e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            }
5621e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
5631e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
5641e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
5651e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
56651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)static bool applyFileOverlay(Bundle *bundle,
5671e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                             const sp<AaptAssets>& assets,
5681e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                             sp<ResourceTypeSet> *baseSet,
5691e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                             const char *resType)
5701e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){
5711e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (bundle->getVerbose()) {
5721e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        printf("applyFileOverlay for %s\n", resType);
5731e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
5741e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
5751e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    // Replace any base level files in this category with any found from the overlay
57609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // Also add any found only in the overlay.
5771e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    sp<AaptAssets> overlay = assets->getOverlay();
57809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    String8 resTypeString(resType);
5791e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
5801e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    // work through the linked list of overlays
5811e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    while (overlay.get()) {
5821e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        KeyedVector<String8, sp<ResourceTypeSet> >* overlayRes = overlay->getResources();
5831e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
5841e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        // get the overlay resources of the requested type
5851e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        ssize_t index = overlayRes->indexOfKey(resTypeString);
5861e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (index >= 0) {
5871e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            sp<ResourceTypeSet> overlaySet = overlayRes->valueAt(index);
5881e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
5891e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            // for each of the resources, check for a match in the previously built
5901e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            // non-overlay "baseset".
5911e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            size_t overlayCount = overlaySet->size();
5921e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            for (size_t overlayIndex=0; overlayIndex<overlayCount; overlayIndex++) {
59309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                if (bundle->getVerbose()) {
5941e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    printf("trying overlaySet Key=%s\n",overlaySet->keyAt(overlayIndex).string());
59509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                }
5961e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                ssize_t baseIndex = -1;
5971e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                if (baseSet->get() != NULL) {
5981e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    baseIndex = (*baseSet)->indexOfKey(overlaySet->keyAt(overlayIndex));
5991e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                }
6001e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                if (baseIndex >= 0) {
6015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    // look for same flavor.  For a given file (strings.xml, for example)
6025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    // there may be a locale specific or other flavors - we want to match
6035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    // the same flavor.
6045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    sp<AaptGroup> overlayGroup = overlaySet->valueAt(overlayIndex);
6055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    sp<AaptGroup> baseGroup = (*baseSet)->valueAt(baseIndex);
6061e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
6071e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > overlayFiles =
60802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch                            overlayGroup->getFiles();
6095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (bundle->getVerbose()) {
6105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > baseFiles =
6111e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                                baseGroup->getFiles();
6125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        for (size_t i=0; i < baseFiles.size(); i++) {
6135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            printf("baseFile " ZD " has flavor %s\n", (ZD_TYPE) i,
6145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                    baseFiles.keyAt(i).toString().string());
6151e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        }
6165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        for (size_t i=0; i < overlayFiles.size(); i++) {
6175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            printf("overlayFile " ZD " has flavor %s\n", (ZD_TYPE) i,
6185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                    overlayFiles.keyAt(i).toString().string());
6191e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        }
6205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    }
6215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6221e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    size_t overlayGroupSize = overlayFiles.size();
6235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    for (size_t overlayGroupIndex = 0;
6245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            overlayGroupIndex<overlayGroupSize;
6251e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                            overlayGroupIndex++) {
6265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        ssize_t baseFileIndex =
6275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                baseGroup->getFiles().indexOfKey(overlayFiles.
6285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                keyAt(overlayGroupIndex));
6295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        if (baseFileIndex >= 0) {
63009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                            if (bundle->getVerbose()) {
63109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                                printf("found a match (" ZD ") for overlay file %s, for flavor %s\n",
63209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                                        (ZD_TYPE) baseFileIndex,
63309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                                        overlayGroup->getLeaf().string(),
63409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                                        overlayFiles.keyAt(overlayGroupIndex).toString().string());
635d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                            }
63609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                            baseGroup->removeFile(baseFileIndex);
63709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                        } else {
63809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                            // didn't find a match fall through and add it..
63909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                            if (true || bundle->getVerbose()) {
64009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                                printf("nothing matches overlay file %s, for flavor %s\n",
64109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                                        overlayGroup->getLeaf().string(),
64209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                                        overlayFiles.keyAt(overlayGroupIndex).toString().string());
64309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                            }
64409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                        }
645f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu                        baseGroup->addFile(overlayFiles.valueAt(overlayGroupIndex));
6465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        assets->addGroupEntry(overlayFiles.keyAt(overlayGroupIndex));
6475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    }
6485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                } else {
6495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (baseSet->get() == NULL) {
6505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        *baseSet = new ResourceTypeSet();
6515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        assets->getResources()->add(String8(resType), *baseSet);
652a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                    }
653a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                    // this group doesn't exist (a file that's only in the overlay)
654a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                    (*baseSet)->add(overlaySet->keyAt(overlayIndex),
655a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                            overlaySet->valueAt(overlayIndex));
656a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                    // make sure all flavors are defined in the resources.
657a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                    sp<AaptGroup> overlayGroup = overlaySet->valueAt(overlayIndex);
658a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch                    DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > overlayFiles =
659a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                            overlayGroup->getFiles();
660a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                    size_t overlayGroupSize = overlayFiles.size();
661926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    for (size_t overlayGroupIndex = 0;
662926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                            overlayGroupIndex<overlayGroupSize;
663bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)                            overlayGroupIndex++) {
664926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                        assets->addGroupEntry(overlayFiles.keyAt(overlayGroupIndex));
665926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    }
666926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                }
667926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            }
668926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            // this overlay didn't have resources for this type
669926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
670926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // try next overlay
671926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        overlay = overlay->getOverlay();
6721e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
673a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    return true;
6741e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
6751e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
676926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)/*
677bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * Inserts an attribute in a given node.
6781e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) * If errorOnFailedInsert is true, and the attribute already exists, returns false.
679926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * If replaceExisting is true, the attribute will be updated if it already exists.
6801e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) * Returns true otherwise, even if the attribute already exists, and does not modify
6811e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) * the existing attribute's value.
6821e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) */
683926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool addTagAttribute(const sp<XMLNode>& node, const char* ns8,
6841e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        const char* attr8, const char* value, bool errorOnFailedInsert,
685926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        bool replaceExisting)
686926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
68707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    if (value == NULL) {
68807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        return true;
68907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    }
69007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
691d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    const String16 ns(ns8);
69207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    const String16 attr(attr8);
69307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
69407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    XMLNode::attribute_entry* existingEntry = node->editAttribute(ns, attr);
69507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    if (existingEntry != NULL) {
69607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        if (replaceExisting) {
69707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            NOISY(printf("Info: AndroidManifest.xml already defines %s (in %s);"
69807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                         " overwriting existing value from manifest.\n",
69907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                         String8(attr).string(), String8(ns).string()));
70007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            existingEntry->string = String16(value);
70107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            return true;
70207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        }
70307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
70407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        if (errorOnFailedInsert) {
70507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            fprintf(stderr, "Error: AndroidManifest.xml already defines %s (in %s);"
70607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                            " cannot insert new value %s.\n",
70707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                    String8(attr).string(), String8(ns).string(), value);
70807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            return false;
70907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        }
71007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
71107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        fprintf(stderr, "Warning: AndroidManifest.xml already defines %s (in %s);"
71207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                        " using existing value in manifest.\n",
71307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                String8(attr).string(), String8(ns).string());
7145267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
715bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        // don't stop the build.
7165267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        return true;
7175267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    }
7185267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
7195267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    node->addAttribute(ns, attr, String16(value));
7205267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    return true;
7215267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)}
7221e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
723a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)/*
7245267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) * Inserts an attribute in a given node, only if the attribute does not
7251e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) * exist.
7265267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) * If errorOnFailedInsert is true, and the attribute already exists, returns false.
7275267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) * Returns true otherwise, even if the attribute already exists.
7281e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) */
7291e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)bool addTagAttribute(const sp<XMLNode>& node, const char* ns8,
7305267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        const char* attr8, const char* value, bool errorOnFailedInsert)
73107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{
7325267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    return addTagAttribute(node, ns8, attr8, value, errorOnFailedInsert, false);
7331e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
7348abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
7351e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)static void fullyQualifyClassName(const String8& package, sp<XMLNode> node,
7361e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        const String16& attrName) {
737bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    XMLNode::attribute_entry* attr = node->editAttribute(
7385267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            String16("http://schemas.android.com/apk/res/android"), attrName);
73907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    if (attr != NULL) {
74007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        String8 name(attr->string);
74107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
742f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        // asdf     --> package.asdf
74307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        // .asdf  .a.b  --> package.asdf package.a.b
74407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        // asdf.adsf --> asdf.asdf
74507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        String8 className;
74607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        const char* p = name.string();
74707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        const char* q = strchr(p, '.');
74807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        if (p == q) {
74907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            className += package;
75007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            className += name;
75107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        } else if (q == NULL) {
75207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            className += package;
75307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            className += ".";
75407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            className += name;
75507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        } else {
75607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            className += name;
75707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        }
75807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        NOISY(printf("Qualifying class '%s' to '%s'", name.string(), className.string()));
75907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        attr->string.setTo(String16(className));
76007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    }
76107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch}
76207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
763f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liustatus_t massageManifest(Bundle* bundle, sp<XMLNode> root)
76407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{
765d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    root = root->searchElement(String16(), String16("manifest"));
766f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    if (root == NULL) {
767f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        fprintf(stderr, "No <manifest> tag.\n");
768f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        return UNKNOWN_ERROR;
769f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    }
77007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
77107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    bool errorOnFailedInsert = bundle->getErrorOnFailedInsert();
772f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    bool replaceVersion = bundle->getReplaceVersion();
773d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
774f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionCode",
775f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu            bundle->getVersionCode(), errorOnFailedInsert, replaceVersion)) {
776f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        return UNKNOWN_ERROR;
777f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    } else {
7785267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        const XMLNode::attribute_entry* attr = root->getAttribute(
7795267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)                String16(RESOURCES_ANDROID_NAMESPACE), String16("versionCode"));
7809bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        if (attr != NULL) {
7819bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)            bundle->setVersionCode(strdup(String8(attr->string).string()));
782bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        }
7839bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    }
7849bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
7859bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionName",
7869bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)            bundle->getVersionName(), errorOnFailedInsert, replaceVersion)) {
7879bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        return UNKNOWN_ERROR;
7889bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    } else {
7899bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        const XMLNode::attribute_entry* attr = root->getAttribute(
7909bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)                String16(RESOURCES_ANDROID_NAMESPACE), String16("versionName"));
7911e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (attr != NULL) {
792a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            bundle->setVersionName(strdup(String8(attr->string).string()));
7931e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
7941e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
7951e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
7969bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    sp<XMLNode> vers = root->getChildElement(String16(), String16("uses-sdk"));
797bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    if (bundle->getMinSdkVersion() != NULL
798bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)            || bundle->getTargetSdkVersion() != NULL
7999bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)            || bundle->getMaxSdkVersion() != NULL) {
8009bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        if (vers == NULL) {
8019bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)            vers = XMLNode::newElement(root->getFilename(), String16(), String16("uses-sdk"));
8029bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)            root->insertChildAt(vers, 0);
803bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        }
8049bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
8059bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "minSdkVersion",
8069bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)                bundle->getMinSdkVersion(), errorOnFailedInsert)) {
8079bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)            return UNKNOWN_ERROR;
8089bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        }
8099bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "targetSdkVersion",
8109bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)                bundle->getTargetSdkVersion(), errorOnFailedInsert)) {
8119bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)            return UNKNOWN_ERROR;
8121e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
813a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "maxSdkVersion",
8141e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                bundle->getMaxSdkVersion(), errorOnFailedInsert)) {
8151e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            return UNKNOWN_ERROR;
8161e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
8171e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
8189bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
8191e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (vers != NULL) {
8209bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        const XMLNode::attribute_entry* attr = vers->getAttribute(
8211e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                String16(RESOURCES_ANDROID_NAMESPACE), String16("minSdkVersion"));
8229bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        if (attr != NULL) {
8239bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)            bundle->setMinSdkVersion(strdup(String8(attr->string).string()));
8249bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        }
8259bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    }
826bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
8279bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    if (bundle->getPlatformBuildVersionCode() != "") {
8289bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        if (!addTagAttribute(root, "", "platformBuildVersionCode",
8299bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)                    bundle->getPlatformBuildVersionCode(), errorOnFailedInsert, true)) {
8309bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)            return UNKNOWN_ERROR;
8319bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        }
8329bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    }
8339bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
8349bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    if (bundle->getPlatformBuildVersionName() != "") {
8351e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (!addTagAttribute(root, "", "platformBuildVersionName",
836a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                    bundle->getPlatformBuildVersionName(), errorOnFailedInsert, true)) {
8371e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            return UNKNOWN_ERROR;
8381e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
8391e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
8401e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
8419bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    if (bundle->getDebugMode()) {
8421e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        sp<XMLNode> application = root->getChildElement(String16(), String16("application"));
8431e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (application != NULL) {
8449bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)            if (!addTagAttribute(application, RESOURCES_ANDROID_NAMESPACE, "debuggable", "true",
8451e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    errorOnFailedInsert)) {
8469bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)                return UNKNOWN_ERROR;
8479bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)            }
8489bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        }
8499bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    }
850bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
8519bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    // Deal with manifest package name overrides
8529bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    const char* manifestPackageNameOverride = bundle->getManifestPackageNameOverride();
8539bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    if (manifestPackageNameOverride != NULL) {
8549bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        // Update the actual package name
8559bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        XMLNode::attribute_entry* attr = root->editAttribute(String16(), String16("package"));
8569bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        if (attr == NULL) {
8579bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)            fprintf(stderr, "package name is required with --rename-manifest-package.\n");
8589bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)            return UNKNOWN_ERROR;
8599bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        }
8609bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        String8 origPackage(attr->string);
8619bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        attr->string.setTo(String16(manifestPackageNameOverride));
8629bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        NOISY(printf("Overriding package '%s' to be '%s'\n", origPackage.string(), manifestPackageNameOverride));
8631e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
864a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        // Make class names fully qualified
8651e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        sp<XMLNode> application = root->getChildElement(String16(), String16("application"));
8661e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (application != NULL) {
8671e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            fullyQualifyClassName(origPackage, application, String16("name"));
8689bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)            fullyQualifyClassName(origPackage, application, String16("backupAgent"));
8691e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
8701e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            Vector<sp<XMLNode> >& children = const_cast<Vector<sp<XMLNode> >&>(application->getChildren());
8719bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)            for (size_t i = 0; i < children.size(); i++) {
8721e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                sp<XMLNode> child = children.editItemAt(i);
8731e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                String8 tag(child->getElementName());
8749bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)                if (tag == "activity" || tag == "service" || tag == "receiver" || tag == "provider") {
8759bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)                    fullyQualifyClassName(origPackage, child, String16("name"));
8769bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)                } else if (tag == "activity-alias") {
8779bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)                    fullyQualifyClassName(origPackage, child, String16("name"));
878bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)                    fullyQualifyClassName(origPackage, child, String16("targetActivity"));
8799bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)                }
8809bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)            }
8819bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        }
8829bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    }
8839bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
8849bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    // Deal with manifest package name overrides
8859bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    const char* instrumentationPackageNameOverride = bundle->getInstrumentationPackageNameOverride();
8861e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (instrumentationPackageNameOverride != NULL) {
887a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        // Fix up instrumentation targets.
888aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch        Vector<sp<XMLNode> >& children = const_cast<Vector<sp<XMLNode> >&>(root->getChildren());
8891e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        for (size_t i = 0; i < children.size(); i++) {
8901e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            sp<XMLNode> child = children.editItemAt(i);
8911e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            String8 tag(child->getElementName());
8921e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            if (tag == "instrumentation") {
8931e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                XMLNode::attribute_entry* attr = child->editAttribute(
8941e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        String16("http://schemas.android.com/apk/res/android"), String16("targetPackage"));
8951e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                if (attr != NULL) {
8961e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    attr->string.setTo(String16(instrumentationPackageNameOverride));
8971e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                }
8981e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            }
8991e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
9001e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
9011e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
9029bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    // Generate split name if feature is present.
9039bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    const XMLNode::attribute_entry* attr = root->getAttribute(String16(), String16("featureName"));
904d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (attr != NULL) {
905d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        String16 splitName("feature_");
906d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        splitName.append(attr->string);
907d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        status_t err = root->addAttribute(String16(), String16("split"), splitName);
908d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (err != NO_ERROR) {
909d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            ALOGE("Failed to insert split name into AndroidManifest.xml");
910d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            return err;
911d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        }
912d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
913d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
914d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return NO_ERROR;
915d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
916d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
917d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)static int32_t getPlatformAssetCookie(const AssetManager& assets) {
918d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // Find the system package (0x01). AAPT always generates attributes
919d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // with the type 0x01, so we're looking for the first attribute
920d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // resource in the system package.
9215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const ResTable& table = assets.getResources(true);
9225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Res_value val;
923bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    ssize_t idx = table.getResource(0x01010000, &val, true);
9245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (idx != NO_ERROR) {
9255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Try as a bag.
9265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const ResTable::bag_entry* entry;
9275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ssize_t cnt = table.lockBag(0x01010000, &entry);
9285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (cnt >= 0) {
9295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            idx = entry->stringBlock;
930926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
9315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        table.unlockBag(entry);
9321e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
933a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
9345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (idx < 0) {
9351e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        return 0;
9361e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
9375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return table.getTableCookie(idx);
9381e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
9395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
940926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)enum {
9411e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    VERSION_CODE_ATTR = 0x0101021b,
94210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    VERSION_NAME_ATTR = 0x0101021c,
9431e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)};
9441e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
9455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static ssize_t extractPlatformBuildVersion(ResXMLTree& tree, Bundle* bundle) {
9465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    size_t len;
9471e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ResXMLTree::event_code_t code;
9485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while ((code = tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
9495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (code != ResXMLTree::START_TAG) {
95093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            continue;
9515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
9528abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
95393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        const char16_t* ctag16 = tree.getElementName(&len);
9545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (ctag16 == NULL) {
9555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            fprintf(stderr, "ERROR: failed to get XML element name (bad string pool)\n");
9565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return UNKNOWN_ERROR;
957926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
9585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        String8 tag(ctag16, len);
9605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (tag != "manifest") {
9615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
9625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
9631e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
964a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        String8 error;
9651e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        int32_t versionCode = AaptXml::getIntegerAttribute(tree, VERSION_CODE_ATTR, &error);
9665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (error != "") {
9675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            fprintf(stderr, "ERROR: failed to get platform version code\n");
9685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return UNKNOWN_ERROR;
9691e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
9701e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
97193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        if (versionCode >= 0 && bundle->getPlatformBuildVersionCode() == "") {
97293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            bundle->setPlatformBuildVersionCode(String8::format("%d", versionCode));
97393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        }
97410f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch
9751e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        String8 versionName = AaptXml::getAttribute(tree, VERSION_NAME_ATTR, &error);
97693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        if (error != "") {
97793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            fprintf(stderr, "ERROR: failed to get platform version name\n");
978bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)            return UNKNOWN_ERROR;
9791e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
9801e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
98193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        if (versionName != "" && bundle->getPlatformBuildVersionName() == "") {
98293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            bundle->setPlatformBuildVersionName(versionName);
9831e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
9841e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        return NO_ERROR;
98593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
98693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
98793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    fprintf(stderr, "ERROR: no <manifest> tag found in platform AndroidManifest.xml\n");
98893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return UNKNOWN_ERROR;
9898abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)}
99093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
99193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)static ssize_t extractPlatformBuildVersion(AssetManager& assets, Bundle* bundle) {
99293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    int32_t cookie = getPlatformAssetCookie(assets);
99393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (cookie == 0) {
99493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        // No platform was loaded.
99593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return NO_ERROR;
99693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
99793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
99893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    ResXMLTree tree;
99993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    Asset* asset = assets.openNonAsset(cookie, "AndroidManifest.xml", Asset::ACCESS_STREAMING);
10001e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (asset == NULL) {
1001a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        fprintf(stderr, "ERROR: Platform AndroidManifest.xml not found\n");
10021e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        return UNKNOWN_ERROR;
100393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
100493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
100593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    ssize_t result = NO_ERROR;
10061e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (tree.setTo(asset->getBuffer(true), asset->getLength()) != NO_ERROR) {
10071e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        fprintf(stderr, "ERROR: Platform AndroidManifest.xml is corrupt\n");
10085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result = UNKNOWN_ERROR;
10095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else {
10105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result = extractPlatformBuildVersion(tree, bundle);
101110f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    }
10121e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
10135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    delete asset;
10145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result;
1015bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)}
10161e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
10171e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#define ASSIGN_IT(n) \
10185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        do { \
10195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ssize_t index = resources->indexOfKey(String8(#n)); \
10201e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            if (index >= 0) { \
10211e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                n ## s = resources->valueAt(index); \
1022926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            } \
1023926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        } while (0)
102451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
102551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)status_t updatePreProcessedCache(Bundle* bundle)
102651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
102751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    #if BENCHMARK
102851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    fprintf(stdout, "BENCHMARK: Starting PNG PreProcessing \n");
102951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    long startPNGTime = clock();
103051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    #endif /* BENCHMARK */
103151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
103251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    String8 source(bundle->getResourceSourceDirs()[0]);
103351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    String8 dest(bundle->getCrunchedOutputDir());
103451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
1035a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    FileFinder* ff = new SystemFileFinder();
103651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CrunchCache cc(source,dest,ff);
103751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
103851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CacheUpdater* cu = new SystemCacheUpdater(bundle);
103951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    size_t numFiles = cc.crunch(cu);
104051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
104151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (bundle->getVerbose())
104251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        fprintf(stdout, "Crunched %d PNG files to update cache\n", (int)numFiles);
104351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
104451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    delete ff;
104551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    delete cu;
104651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
104751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    #if BENCHMARK
104893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    fprintf(stdout, "BENCHMARK: End PNG PreProcessing. Time Elapsed: %f ms \n"
1049926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            ,(clock() - startPNGTime)/1000.0);
1050bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    #endif /* BENCHMARK */
1051926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return 0;
1052926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
1053926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1054926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)status_t generateAndroidManifestForSplit(Bundle* bundle, const sp<AaptAssets>& assets,
1055926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        const sp<ApkSplit>& split, sp<AaptFile>& outFile, ResourceTable* table) {
1056926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    const String8 filename("AndroidManifest.xml");
1057926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    const String16 androidPrefix("android");
10581e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    const String16 androidNSUri("http://schemas.android.com/apk/res/android");
1059a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    sp<XMLNode> root = XMLNode::newNamespace(filename, androidPrefix, androidNSUri);
10601e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
10611e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    // Build the <manifest> tag
10621e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    sp<XMLNode> manifest = XMLNode::newElement(filename, String16(), String16("manifest"));
1063926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1064926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // Add the 'package' attribute which is set to the package name.
10651e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    const char* packageName = assets->getPackage();
1066926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    const char* manifestPackageNameOverride = bundle->getManifestPackageNameOverride();
1067926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (manifestPackageNameOverride != NULL) {
106893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        packageName = manifestPackageNameOverride;
106953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
1070bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    manifest->addAttribute(String16(), String16("package"), String16(packageName));
107153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
107253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // Add the 'versionCode' attribute which is set to the original version code.
107353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!addTagAttribute(manifest, RESOURCES_ANDROID_NAMESPACE, "versionCode",
107453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            bundle->getVersionCode(), true, true)) {
107553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return UNKNOWN_ERROR;
107653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
107753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
10781e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    // Add the 'split' attribute which describes the configurations included.
1079a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    String8 splitName("config.");
10801e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    splitName.append(split->getPackageSafeName());
10811e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    manifest->addAttribute(String16(), String16("split"), String16(splitName));
10821e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
10831e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    // Build an empty <application> tag (required).
108453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    sp<XMLNode> app = XMLNode::newElement(filename, String16(), String16("application"));
108553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
10861e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    // Add the 'hasCode' attribute which is never true for resource splits.
108753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!addTagAttribute(app, RESOURCES_ANDROID_NAMESPACE, "hasCode",
108853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            "false", true, true)) {
108953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return UNKNOWN_ERROR;
109053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
1091bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
109253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    manifest->addChild(app);
109353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    root->addChild(manifest);
109453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
109553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    int err = compileXmlFile(bundle, assets, String16(), root, outFile, table);
109653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (err < NO_ERROR) {
109753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return err;
109853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
10991e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    outFile->setCompressionMethod(ZipEntry::kCompressDeflated);
1100a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    return NO_ERROR;
11011e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
11021e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
11031e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuilder>& builder)
110453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
110553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // First, look for a package file to parse.  This is required to
11061e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    // be able to generate the resource information.
11071e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    sp<AaptGroup> androidManifestFile =
110853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            assets->getFiles().valueFor(String8("AndroidManifest.xml"));
110953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (androidManifestFile == NULL) {
111053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        fprintf(stderr, "ERROR: No AndroidManifest.xml file found.\n");
111153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return UNKNOWN_ERROR;
1112bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    }
111353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
111453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    status_t err = parsePackage(bundle, assets, androidManifestFile);
111553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (err != NO_ERROR) {
111653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return err;
111753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
111853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
111953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    NOISY(printf("Creating resources for package %s\n",
11201e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                 assets->getPackage().string()));
112151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
11221e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ResourceTable::PackageType packageType = ResourceTable::App;
11231e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (bundle->getBuildSharedLibrary()) {
11241e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        packageType = ResourceTable::SharedLibrary;
112553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    } else if (bundle->getExtending()) {
1126bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        packageType = ResourceTable::System;
112753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    } else if (!bundle->getFeatureOfPackage().isEmpty()) {
11281e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        packageType = ResourceTable::AppFeature;
11291e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
113053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
113153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ResourceTable table(bundle, String16(assets->getPackage()), packageType);
11328abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    err = table.addIncludedResources(bundle, assets);
11338abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    if (err != NO_ERROR) {
1134bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        return err;
11358abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    }
11368abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
11378abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    NOISY(printf("Found %d included resource packages\n", (int)table.size()));
11388abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
11398abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    // Standard flags for compiled XML and optional UTF-8 encoding
11408abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    int xmlFlags = XML_COMPILE_STANDARD_RESOURCE;
11418abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
11421e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    /* Only enable UTF-8 if the caller of aapt didn't specifically
1143a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)     * request UTF-16 encoding and the parameters of this package
1144aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch     * allow UTF-8 to be used.
11451e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)     */
11461e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (!bundle->getUTF16StringsOption()) {
11471e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        xmlFlags |= XML_COMPILE_UTF8;
11488abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    }
11491e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
11501e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    // --------------------------------------------------------------
11518abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    // First, gather all resource information.
11528abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    // --------------------------------------------------------------
11538abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
11548abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    // resType -> leafName -> group
1155bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    KeyedVector<String8, sp<ResourceTypeSet> > *resources =
11568abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            new KeyedVector<String8, sp<ResourceTypeSet> >;
11578abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    collect_files(assets, resources);
11588abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
11598abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    sp<ResourceTypeSet> drawables;
11608abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    sp<ResourceTypeSet> layouts;
11618abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    sp<ResourceTypeSet> anims;
11628abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    sp<ResourceTypeSet> animators;
11631e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    sp<ResourceTypeSet> interpolators;
1164a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    sp<ResourceTypeSet> transitions;
11651e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    sp<ResourceTypeSet> xmls;
11661e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    sp<ResourceTypeSet> raws;
11671e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    sp<ResourceTypeSet> colors;
11688abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    sp<ResourceTypeSet> menus;
11691e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    sp<ResourceTypeSet> mipmaps;
11708abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
11718abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    ASSIGN_IT(drawable);
117253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSIGN_IT(layout);
1173926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ASSIGN_IT(anim);
1174bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    ASSIGN_IT(animator);
1175926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ASSIGN_IT(interpolator);
1176926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ASSIGN_IT(transition);
1177926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ASSIGN_IT(xml);
1178926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ASSIGN_IT(raw);
1179926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ASSIGN_IT(color);
1180926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ASSIGN_IT(menu);
1181926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ASSIGN_IT(mipmap);
11821e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
1183a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    assets->setResources(resources);
1184aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    // now go through any resource overlays and collect their files
11851e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    sp<AaptAssets> current = assets->getOverlay();
11861e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    while(current.get()) {
11871e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        KeyedVector<String8, sp<ResourceTypeSet> > *resources =
118853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                new KeyedVector<String8, sp<ResourceTypeSet> >;
11891e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        current->setResources(resources);
11901e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        collect_files(current, resources);
119153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        current = current->getOverlay();
119253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
119393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // apply the overlay files to the base set
119453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!applyFileOverlay(bundle, assets, &drawables, "drawable") ||
1195bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)            !applyFileOverlay(bundle, assets, &layouts, "layout") ||
119653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            !applyFileOverlay(bundle, assets, &anims, "anim") ||
119753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            !applyFileOverlay(bundle, assets, &animators, "animator") ||
119853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            !applyFileOverlay(bundle, assets, &interpolators, "interpolator") ||
119953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            !applyFileOverlay(bundle, assets, &transitions, "transition") ||
120053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            !applyFileOverlay(bundle, assets, &xmls, "xml") ||
120153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            !applyFileOverlay(bundle, assets, &raws, "raw") ||
120253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            !applyFileOverlay(bundle, assets, &colors, "color") ||
12031e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            !applyFileOverlay(bundle, assets, &menus, "menu") ||
120451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            !applyFileOverlay(bundle, assets, &mipmaps, "mipmap")) {
12051e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        return UNKNOWN_ERROR;
12061e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
1207926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1208926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    bool hasErrors = false;
12091e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
1210926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (drawables != NULL) {
1211926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (bundle->getOutputAPKFile() != NULL) {
1212926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            err = preProcessImages(bundle, assets, drawables, "drawable");
1213926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
12148abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        if (err == NO_ERROR) {
121593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            err = makeFileResources(bundle, assets, &table, drawables, "drawable");
1216926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            if (err != NO_ERROR) {
1217926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                hasErrors = true;
1218926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            }
1219926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        } else {
122093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            hasErrors = true;
1221926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
12221e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
1223a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
1224aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    if (mipmaps != NULL) {
12251e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (bundle->getOutputAPKFile() != NULL) {
12261e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            err = preProcessImages(bundle, assets, mipmaps, "mipmap");
12271e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
12281e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (err == NO_ERROR) {
1229926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            err = makeFileResources(bundle, assets, &table, mipmaps, "mipmap");
12301e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            if (err != NO_ERROR) {
1231926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                hasErrors = true;
123293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            }
123393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        } else {
12341e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            hasErrors = true;
12351e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
1236926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
12371e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
1238926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (layouts != NULL) {
12391e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        err = makeFileResources(bundle, assets, &table, layouts, "layout");
12401e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (err != NO_ERROR) {
12411e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            hasErrors = true;
1242926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
1243926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
124493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
1245926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (anims != NULL) {
1246bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        err = makeFileResources(bundle, assets, &table, anims, "anim");
1247926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (err != NO_ERROR) {
1248926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            hasErrors = true;
1249926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
1250926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
1251926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1252926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (animators != NULL) {
125351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        err = makeFileResources(bundle, assets, &table, animators, "animator");
1254926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (err != NO_ERROR) {
12551e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            hasErrors = true;
125651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
12571e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
125851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
12591e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (transitions != NULL) {
1260926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        err = makeFileResources(bundle, assets, &table, transitions, "transition");
126151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (err != NO_ERROR) {
1262926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            hasErrors = true;
1263926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
1264926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
1265926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1266bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    if (interpolators != NULL) {
126753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        err = makeFileResources(bundle, assets, &table, interpolators, "interpolator");
1268926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (err != NO_ERROR) {
1269926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            hasErrors = true;
1270926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
1271926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
1272926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
127351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (xmls != NULL) {
127451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        err = makeFileResources(bundle, assets, &table, xmls, "xml");
127551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (err != NO_ERROR) {
127651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            hasErrors = true;
127751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
127851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
127951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
128051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (raws != NULL) {
128151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        err = makeFileResources(bundle, assets, &table, raws, "raw");
128251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (err != NO_ERROR) {
128351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            hasErrors = true;
128451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
128551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
128651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
128751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // compile resources
128851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    current = assets;
128951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    while(current.get()) {
129051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        KeyedVector<String8, sp<ResourceTypeSet> > *resources =
129151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                current->getResources();
129251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
129351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        ssize_t index = resources->indexOfKey(String8("values"));
129451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (index >= 0) {
129551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ResourceDirIterator it(resources->valueAt(index), String8("values"));
129651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ssize_t res;
129751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            while ((res=it.next()) == NO_ERROR) {
129851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                sp<AaptFile> file = it.getFile();
129951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                res = compileResourceFile(bundle, assets, file, it.getParams(),
130051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                          (current!=assets), &table);
130151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (res != NO_ERROR) {
130251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    hasErrors = true;
130351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                }
130451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            }
130551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
130651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        current = current->getOverlay();
1307a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    }
1308aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch
130951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (colors != NULL) {
131051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        err = makeFileResources(bundle, assets, &table, colors, "color");
131151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (err != NO_ERROR) {
131251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            hasErrors = true;
131351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
131451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
131551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
131651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (menus != NULL) {
131751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        err = makeFileResources(bundle, assets, &table, menus, "menu");
131851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (err != NO_ERROR) {
131951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            hasErrors = true;
132051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
132151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
132251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
132351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // --------------------------------------------------------------------
132451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // Assignment of resource IDs and initial generation of resource table.
132551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // --------------------------------------------------------------------
132651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
132751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (table.hasResources()) {
1328926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        err = table.assignResourceIds();
13291e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (err < NO_ERROR) {
1330a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            return err;
133151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
133251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
133351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
133451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // --------------------------------------------------------------
13351e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    // Finally, we can now we can compile XML files, which may reference
1336926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // resources.
133751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // --------------------------------------------------------------
133851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
1339926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (layouts != NULL) {
1340926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        ResourceDirIterator it(layouts, String8("layout"));
13418abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        while ((err=it.next()) == NO_ERROR) {
13428abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            String8 src = it.getFile()->getPrintableSource();
1343bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),
13448abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                    it.getFile(), &table, xmlFlags);
13458abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            if (err == NO_ERROR) {
13468abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                ResXMLTree block;
13478abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                block.setTo(it.getFile()->getData(), it.getFile()->getSize(), true);
13488abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                checkForIds(src, block);
13498abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            } else {
13508abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                hasErrors = true;
13511e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            }
135251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
13531e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
13541e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (err < NO_ERROR) {
13551e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            hasErrors = true;
13561e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
13578abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        err = NO_ERROR;
1358bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    }
135951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
136051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (anims != NULL) {
136151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        ResourceDirIterator it(anims, String8("anim"));
136251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        while ((err=it.next()) == NO_ERROR) {
136351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),
136451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    it.getFile(), &table, xmlFlags);
13651e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            if (err != NO_ERROR) {
13661e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                hasErrors = true;
13671e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            }
13681e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
1369bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
13701e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (err < NO_ERROR) {
13711e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            hasErrors = true;
13721e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
13731e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        err = NO_ERROR;
13741e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
13751e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
13761e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (animators != NULL) {
13771e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        ResourceDirIterator it(animators, String8("animator"));
137851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        while ((err=it.next()) == NO_ERROR) {
13791e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),
13801e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    it.getFile(), &table, xmlFlags);
13811e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            if (err != NO_ERROR) {
13821e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                hasErrors = true;
13831e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            }
13841e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
13851e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
13861e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (err < NO_ERROR) {
13871e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            hasErrors = true;
13881e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
13891e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        err = NO_ERROR;
13901e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
13918abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
13928abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    if (interpolators != NULL) {
139351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        ResourceDirIterator it(interpolators, String8("interpolator"));
139451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        while ((err=it.next()) == NO_ERROR) {
139551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),
139651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    it.getFile(), &table, xmlFlags);
139751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (err != NO_ERROR) {
139851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                hasErrors = true;
139951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            }
140051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
140151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
140251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (err < NO_ERROR) {
140351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            hasErrors = true;
1404a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        }
140551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        err = NO_ERROR;
140651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
140751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
140851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (transitions != NULL) {
140951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        ResourceDirIterator it(transitions, String8("transition"));
141051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        while ((err=it.next()) == NO_ERROR) {
141151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),
141251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    it.getFile(), &table, xmlFlags);
141351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (err != NO_ERROR) {
141451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                hasErrors = true;
141551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            }
141651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
141751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
141851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (err < NO_ERROR) {
141951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            hasErrors = true;
142051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
142151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        err = NO_ERROR;
142251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
142351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
142451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (xmls != NULL) {
142551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        ResourceDirIterator it(xmls, String8("xml"));
142651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        while ((err=it.next()) == NO_ERROR) {
142751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),
1428a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                    it.getFile(), &table, xmlFlags);
142951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (err != NO_ERROR) {
143051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                hasErrors = true;
143151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            }
143251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
143351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
143451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (err < NO_ERROR) {
143551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            hasErrors = true;
143651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
143751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        err = NO_ERROR;
143851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
143951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
144051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (drawables != NULL) {
144151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        ResourceDirIterator it(drawables, String8("drawable"));
144251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        while ((err=it.next()) == NO_ERROR) {
144351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            err = postProcessImage(bundle, assets, &table, it.getFile());
144451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (err != NO_ERROR) {
144551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                hasErrors = true;
144651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            }
144751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
144851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
144951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (err < NO_ERROR) {
145051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            hasErrors = true;
145151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
145251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        err = NO_ERROR;
145351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
145451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
145551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (colors != NULL) {
1456d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        ResourceDirIterator it(colors, String8("color"));
1457d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        while ((err=it.next()) == NO_ERROR) {
1458d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),
1459d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    it.getFile(), &table, xmlFlags);
1460d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if (err != NO_ERROR) {
1461d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                hasErrors = true;
1462d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            }
1463d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        }
1464d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1465d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (err < NO_ERROR) {
1466d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            hasErrors = true;
146751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
146851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        err = NO_ERROR;
14698abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    }
14708abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
1471bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    if (menus != NULL) {
14728abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        ResourceDirIterator it(menus, String8("menu"));
14738abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        while ((err=it.next()) == NO_ERROR) {
14748abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            String8 src = it.getFile()->getPrintableSource();
14758abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),
14768abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                    it.getFile(), &table, xmlFlags);
14778abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            if (err == NO_ERROR) {
14788abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                ResXMLTree block;
14791e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                block.setTo(it.getFile()->getData(), it.getFile()->getSize(), true);
148051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                checkForIds(src, block);
14811e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            } else {
14821e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                hasErrors = true;
148351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            }
14841e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
14851e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
14868abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        if (err < NO_ERROR) {
1487bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)            hasErrors = true;
14881e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
14898abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        err = NO_ERROR;
14901e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
14911e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
1492bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    // Now compile any generated resources.
14931e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    std::queue<CompileResourceWorkItem>& workQueue = table.getWorkQueue();
14948abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    while (!workQueue.empty()) {
14958abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        CompileResourceWorkItem& workItem = workQueue.front();
149606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        err = compileXmlFile(bundle, assets, workItem.resourceName, workItem.file, &table, xmlFlags);
149706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        if (err == NO_ERROR) {
149806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            assets->addResource(workItem.resPath.getPathLeaf(),
149906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                    workItem.resPath,
150006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                    workItem.file,
150106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                    workItem.file->getResourceType());
150206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        } else {
150306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            hasErrors = true;
150406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        }
15051e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        workQueue.pop();
15061e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
15071e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
15081e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (table.validateLocalizations()) {
150906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        hasErrors = true;
15101e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
151106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
151206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (hasErrors) {
151306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        return UNKNOWN_ERROR;
151406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    }
151506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
151606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    // If we're not overriding the platform build versions,
151706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    // extract them from the platform APK.
151806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (packageType != ResourceTable::System &&
151906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            (bundle->getPlatformBuildVersionCode() == "" ||
152006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            bundle->getPlatformBuildVersionName() == "")) {
152106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        err = extractPlatformBuildVersion(assets->getAssetManager(), bundle);
152206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        if (err != NO_ERROR) {
15231e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            return UNKNOWN_ERROR;
15241e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
15251e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
15261e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
15271e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    const sp<AaptFile> manifestFile(androidManifestFile->getFiles().valueAt(0));
152806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    String8 manifestPath(manifestFile->getPrintableSource());
15291e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
153006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    // Generate final compiled manifest file.
153106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    manifestFile->clearData();
153206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    sp<XMLNode> manifestTree = XMLNode::parse(manifestFile);
153306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (manifestTree == NULL) {
153406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        return UNKNOWN_ERROR;
1535bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    }
153606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    err = massageManifest(bundle, manifestTree);
153706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (err < NO_ERROR) {
153806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        return err;
153906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    }
154006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    err = compileXmlFile(bundle, assets, String16(), manifestTree, manifestFile, &table);
154106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (err < NO_ERROR) {
154206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        return err;
154306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    }
15441e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
154551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (table.modifyForCompat(bundle) != NO_ERROR) {
15461e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        return UNKNOWN_ERROR;
15471e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
15481e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
15491e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    //block.restart();
155006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    //printXMLBlock(&block);
1551bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
15521e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    // --------------------------------------------------------------
155306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    // Generate the final resource table.
15541e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    // Re-flatten because we may have added new resource IDs
15551e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    // --------------------------------------------------------------
1556bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
15571e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
155806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    ResTable finalResTable;
155906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    sp<AaptFile> resFile;
1560926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1561926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (table.hasResources()) {
1562bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R"));
1563926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        err = table.addSymbols(symbols);
1564926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (err < NO_ERROR) {
1565926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            return err;
1566926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
156753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
156853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        KeyedVector<Symbol, Vector<SymbolDefinition> > densityVaryingResources;
156953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (builder->getSplits().size() > 1) {
157053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            // Only look for density varying resources if we're generating
15711e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            // splits.
1572a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            table.getDensityVaryingResources(densityVaryingResources);
15731e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
15741e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
15751e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        Vector<sp<ApkSplit> >& splits = builder->getSplits();
15761e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        const size_t numSplits = splits.size();
157710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        for (size_t i = 0; i < numSplits; i++) {
15781e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            sp<ApkSplit>& split = splits.editItemAt(i);
15791e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            sp<AaptFile> flattenedTable = new AaptFile(String8("resources.arsc"),
158053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                    AaptGroupEntry(), String8());
158153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            err = table.flatten(bundle, split->getResourceFilter(),
158253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                    flattenedTable, split->isBase());
158353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            if (err != NO_ERROR) {
15848abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                fprintf(stderr, "Failed to generate resource table for split '%s'\n",
158553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                        split->getPrintableName().string());
158653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                return err;
158753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            }
158853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            split->addEntry(String8("resources.arsc"), flattenedTable);
158953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1590926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            if (split->isBase()) {
1591926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                resFile = flattenedTable;
1592926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                err = finalResTable.add(flattenedTable->getData(), flattenedTable->getSize());
15931e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                if (err != NO_ERROR) {
1594a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                    fprintf(stderr, "Generated resource table is corrupt.\n");
15951e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    return err;
15961e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                }
1597926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            } else {
15981e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                ResTable resTable;
159910f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch                err = resTable.add(flattenedTable->getData(), flattenedTable->getSize());
16001e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                if (err != NO_ERROR) {
16011e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    fprintf(stderr, "Generated resource table for split '%s' is corrupt.\n",
160253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                            split->getPrintableName().string());
160353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                    return err;
160453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                }
1605926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1606926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                bool hasError = false;
1607bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)                const std::set<ConfigDescription>& splitConfigs = split->getConfigs();
1608926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                for (std::set<ConfigDescription>::const_iterator iter = splitConfigs.begin();
1609926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                        iter != splitConfigs.end();
1610926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                        ++iter) {
1611926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    const ConfigDescription& config = *iter;
1612926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    if (AaptConfig::isDensityOnly(config)) {
1613926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                        // Each density only split must contain all
1614926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                        // density only resources.
16151e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        Res_value val;
1616a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                        resTable.setParameters(&config);
16171e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        const size_t densityVaryingResourceCount = densityVaryingResources.size();
16181e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        for (size_t k = 0; k < densityVaryingResourceCount; k++) {
16191e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                            const Symbol& symbol = densityVaryingResources.keyAt(k);
162010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch                            ssize_t block = resTable.getResource(symbol.id, &val, true);
1621d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                            if (block < 0) {
1622d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                                // Maybe it's in the base?
1623d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                                finalResTable.setParameters(&config);
1624d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                                block = finalResTable.getResource(symbol.id, &val, true);
1625d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                            }
1626d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1627d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                            if (block < 0) {
1628d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                                hasError = true;
1629d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                                SourcePos().error("%s has no definition for density split '%s'",
1630d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                                        symbol.toString().string(), config.toString().string());
1631d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1632d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                                if (bundle->getVerbose()) {
1633d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                                    const Vector<SymbolDefinition>& defs = densityVaryingResources[k];
1634d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                                    const size_t defCount = std::min(size_t(5), defs.size());
1635d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                                    for (size_t d = 0; d < defCount; d++) {
1636d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                                        const SymbolDefinition& def = defs[d];
1637d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                                        def.source.error("%s has definition for %s",
1638d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                                                symbol.toString().string(), def.config.toString().string());
1639d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                                    }
1640d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1641d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                                    if (defCount < defs.size()) {
1642926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                                        SourcePos().error("and %d more ...", (int) (defs.size() - defCount));
1643926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                                    }
1644926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                                }
1645926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                            }
1646bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)                        }
16478abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                    }
1648926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                }
1649926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1650926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                if (hasError) {
165153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                    return UNKNOWN_ERROR;
165253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                }
165353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1654926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                // Generate the AndroidManifest for this split.
16551e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                sp<AaptFile> generatedManifest = new AaptFile(String8("AndroidManifest.xml"),
1656a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                        AaptGroupEntry(), String8());
16571e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                err = generateAndroidManifestForSplit(bundle, assets, split,
16581e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        generatedManifest, &table);
1659926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                if (err != NO_ERROR) {
16601e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    fprintf(stderr, "Failed to generate AndroidManifest.xml for split '%s'\n",
166153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                            split->getPrintableName().string());
166253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                    return err;
1663926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                }
166410f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch                split->addEntry(String8("AndroidManifest.xml"), generatedManifest);
1665926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            }
1666d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        }
1667926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1668926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (bundle->getPublicOutputFile()) {
1669926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            FILE* fp = fopen(bundle->getPublicOutputFile(), "w+");
1670d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if (fp == NULL) {
1671926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                fprintf(stderr, "ERROR: Unable to open public definitions output file %s: %s\n",
1672926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                        (const char*)bundle->getPublicOutputFile(), strerror(errno));
1673926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                return UNKNOWN_ERROR;
1674926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            }
1675926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            if (bundle->getVerbose()) {
1676926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                printf("  Writing public definitions to %s.\n", bundle->getPublicOutputFile());
1677926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            }
1678926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            table.writePublicDefinitions(String16(assets->getPackage()), fp);
1679926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            fclose(fp);
1680926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
1681bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
1682926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (finalResTable.getTableCount() == 0 || resFile == NULL) {
1683926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            fprintf(stderr, "No resource table was generated.\n");
1684926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            return UNKNOWN_ERROR;
1685926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
1686926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
1687926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1688926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // Perform a basic validation of the manifest file.  This time we
16891e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    // parse it with the comments intact, so that we can use them to
1690a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    // generate java docs...  so we are not going to write this one
16911e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    // back out to the final manifest data.
16921e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    sp<AaptFile> outManifestFile = new AaptFile(manifestFile->getSourceFile(),
1693926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            manifestFile->getGroupEntry(),
169410f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch            manifestFile->getResourceType());
1695926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    err = compileXmlFile(bundle, assets, String16(), manifestFile,
16961e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            outManifestFile, &table,
16971e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            XML_COMPILE_ASSIGN_ATTRIBUTE_IDS
16985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            | XML_COMPILE_STRIP_WHITESPACE | XML_COMPILE_STRIP_RAW_VALUES);
169953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (err < NO_ERROR) {
170053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return err;
170153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
17028abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    ResXMLTree block;
170353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    block.setTo(outManifestFile->getData(), outManifestFile->getSize(), true);
170453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    String16 manifest16("manifest");
170553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    String16 permission16("permission");
17063c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    String16 permission_group16("permission-group");
17073c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    String16 uses_permission16("uses-permission");
17083c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    String16 instrumentation16("instrumentation");
170953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    String16 application16("application");
171053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    String16 provider16("provider");
171153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    String16 service16("service");
17123c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    String16 receiver16("receiver");
17133c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    String16 activity16("activity");
17143c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    String16 action16("action");
17153c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    String16 category16("category");
17163c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    String16 data16("scheme");
17171e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    String16 feature_group16("feature-group");
171851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    String16 uses_feature16("uses-feature");
17191e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    const char* packageIdentChars = "abcdefghijklmnopqrstuvwxyz"
17201e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789";
17211e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    const char* packageIdentCharsWithTheStupid = "abcdefghijklmnopqrstuvwxyz"
172253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789-";
17233c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    const char* classIdentChars = "abcdefghijklmnopqrstuvwxyz"
17243c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789$";
17253c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    const char* processIdentChars = "abcdefghijklmnopqrstuvwxyz"
1726bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789:";
1727bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    const char* authoritiesIdentChars = "abcdefghijklmnopqrstuvwxyz"
17281e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789-:;";
17293c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    const char* typeIdentChars = "abcdefghijklmnopqrstuvwxyz"
173053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789:-/*+";
173153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    const char* schemeIdentChars = "abcdefghijklmnopqrstuvwxyz"
173253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789-";
173353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ResXMLTree::event_code_t code;
17348abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    sp<AaptSymbols> permissionSymbols;
173553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    sp<AaptSymbols> permissionGroupSymbols;
173653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    while ((code=block.next()) != ResXMLTree::END_DOCUMENT
173753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)           && code > ResXMLTree::BAD_DOCUMENT) {
173853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (code == ResXMLTree::START_TAG) {
173953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            size_t len;
174053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            if (block.getElementNamespace(&len) != NULL) {
174153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                continue;
174253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            }
174353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            if (strcmp16(block.getElementName(&len), manifest16.string()) == 0) {
174453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                if (validateAttr(manifestPath, finalResTable, block, NULL, "package",
174553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                                 packageIdentChars, true) != ATTR_OKAY) {
17461e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    hasErrors = true;
174751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                }
17481e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,
17491e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                                 "sharedUserId", packageIdentChars, false) != ATTR_OKAY) {
17501e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    hasErrors = true;
17511e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                }
1752bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)            } else if (strcmp16(block.getElementName(&len), permission16.string()) == 0
1753bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)                    || strcmp16(block.getElementName(&len), permission_group16.string()) == 0) {
17541e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                const bool isGroup = strcmp16(block.getElementName(&len),
17551e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        permission_group16.string()) == 0;
17561e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,
17571e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                                 "name", isGroup ? packageIdentCharsWithTheStupid
17581e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                                 : packageIdentChars, true) != ATTR_OKAY) {
17591e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    hasErrors = true;
17601e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                }
17611e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                SourcePos srcPos(manifestPath, block.getLineNumber());
176253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                sp<AaptSymbols> syms;
17631e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                if (!isGroup) {
176453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                    syms = permissionSymbols;
17651e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    if (syms == NULL) {
17661e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        sp<AaptSymbols> symbols =
17671e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                                assets->getSymbolsFor(String8("Manifest"));
17681e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        syms = permissionSymbols = symbols->addNestedSymbol(
17691e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                                String8("permission"), srcPos);
17701e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    }
17711e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                } else {
17721e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    syms = permissionGroupSymbols;
177351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    if (syms == NULL) {
17741e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        sp<AaptSymbols> symbols =
17751e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                                assets->getSymbolsFor(String8("Manifest"));
17761e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        syms = permissionGroupSymbols = symbols->addNestedSymbol(
17771e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                                String8("permission_group"), srcPos);
17781e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    }
1779bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)                }
1780bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)                size_t len;
17811e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                ssize_t index = block.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, "name");
178253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                const char16_t* id = block.getAttributeStringValue(index, &len);
178353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                if (id == NULL) {
178453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                    fprintf(stderr, "%s:%d: missing name attribute in element <%s>.\n",
17851e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                            manifestPath.string(), block.getLineNumber(),
17861e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                            String8(block.getElementName(&len)).string());
17871e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    hasErrors = true;
17881e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    break;
17891e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                }
17901e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                String8 idStr(id);
17911e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                char* p = idStr.lockBuffer(idStr.size());
17921e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                char* e = p + idStr.size();
17931e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                bool begins_with_digit = true;  // init to true so an empty string fails
17941e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                while (e > p) {
17951e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    e--;
179651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    if (*e >= '0' && *e <= '9') {
17971e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                      begins_with_digit = true;
17981e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                      continue;
17991e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    }
18001e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    if ((*e >= 'a' && *e <= 'z') ||
18011e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        (*e >= 'A' && *e <= 'Z') ||
18021e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        (*e == '_')) {
1803bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)                      begins_with_digit = false;
1804bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)                      continue;
18051e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    }
18061e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    if (isGroup && (*e == '-')) {
18071e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        *e = '_';
18081e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        begins_with_digit = false;
18091e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        continue;
18101e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    }
18111e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    e++;
18121e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    break;
18131e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                }
18141e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                idStr.unlockBuffer();
18151e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                // verify that we stopped because we hit a period or
18161e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                // the beginning of the string, and that the
18171e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                // identifier didn't begin with a digit.
18181e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                if (begins_with_digit || (e != p && *(e-1) != '.')) {
181951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                  fprintf(stderr,
18201e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                          "%s:%d: Permission name <%s> is not a valid Java symbol\n",
18211e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                          manifestPath.string(), block.getLineNumber(), idStr.string());
18221e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                  hasErrors = true;
18231e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                }
18241e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                syms->addStringSymbol(String8(e), idStr, srcPos);
18251e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                const char16_t* cmt = block.getComment(&len);
18261e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                if (cmt != NULL && *cmt != 0) {
1827bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)                    //printf("Comment of %s: %s\n", String8(e).string(),
1828bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)                    //        String8(cmt).string());
18291e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    syms->appendComment(String8(e), String16(cmt), srcPos);
18301e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                } else {
18311e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    //printf("No comment for %s\n", String8(e).string());
183251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                }
183351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                syms->makeSymbolPublic(String8(e), srcPos);
183451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            } else if (strcmp16(block.getElementName(&len), uses_permission16.string()) == 0) {
183551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,
183651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                 "name", packageIdentChars, true) != ATTR_OKAY) {
183751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    hasErrors = true;
183851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                }
183951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            } else if (strcmp16(block.getElementName(&len), instrumentation16.string()) == 0) {
184051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,
184151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                 "name", classIdentChars, true) != ATTR_OKAY) {
184251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    hasErrors = true;
184351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                }
184451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (validateAttr(manifestPath, finalResTable, block,
184551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                 RESOURCES_ANDROID_NAMESPACE, "targetPackage",
184651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                 packageIdentChars, true) != ATTR_OKAY) {
184751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    hasErrors = true;
184851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                }
184951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            } else if (strcmp16(block.getElementName(&len), application16.string()) == 0) {
185051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,
185151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                 "name", classIdentChars, false) != ATTR_OKAY) {
185251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    hasErrors = true;
185351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                }
185451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (validateAttr(manifestPath, finalResTable, block,
185551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                 RESOURCES_ANDROID_NAMESPACE, "permission",
185651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                 packageIdentChars, false) != ATTR_OKAY) {
185751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    hasErrors = true;
185851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                }
185951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (validateAttr(manifestPath, finalResTable, block,
186051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                 RESOURCES_ANDROID_NAMESPACE, "process",
186151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                 processIdentChars, false) != ATTR_OKAY) {
186251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    hasErrors = true;
186351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                }
186451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (validateAttr(manifestPath, finalResTable, block,
1865a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                                 RESOURCES_ANDROID_NAMESPACE, "taskAffinity",
186651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                 processIdentChars, false) != ATTR_OKAY) {
186751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    hasErrors = true;
186851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                }
186951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            } else if (strcmp16(block.getElementName(&len), provider16.string()) == 0) {
187051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,
187151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                 "name", classIdentChars, true) != ATTR_OKAY) {
187251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    hasErrors = true;
187351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                }
187451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (validateAttr(manifestPath, finalResTable, block,
187551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                 RESOURCES_ANDROID_NAMESPACE, "authorities",
187651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                 authoritiesIdentChars, true) != ATTR_OKAY) {
187751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    hasErrors = true;
187851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                }
187951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (validateAttr(manifestPath, finalResTable, block,
188051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                 RESOURCES_ANDROID_NAMESPACE, "permission",
188151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                 packageIdentChars, false) != ATTR_OKAY) {
188251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    hasErrors = true;
188351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                }
188451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (validateAttr(manifestPath, finalResTable, block,
188551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                 RESOURCES_ANDROID_NAMESPACE, "process",
1886a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                                 processIdentChars, false) != ATTR_OKAY) {
188751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    hasErrors = true;
188851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                }
188951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            } else if (strcmp16(block.getElementName(&len), service16.string()) == 0
189051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                       || strcmp16(block.getElementName(&len), receiver16.string()) == 0
189151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                       || strcmp16(block.getElementName(&len), activity16.string()) == 0) {
189251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,
189351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                 "name", classIdentChars, true) != ATTR_OKAY) {
189451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    hasErrors = true;
189551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                }
189651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (validateAttr(manifestPath, finalResTable, block,
189751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                 RESOURCES_ANDROID_NAMESPACE, "permission",
189851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                 packageIdentChars, false) != ATTR_OKAY) {
189951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    hasErrors = true;
190051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                }
190151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (validateAttr(manifestPath, finalResTable, block,
190251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                 RESOURCES_ANDROID_NAMESPACE, "process",
190351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                 processIdentChars, false) != ATTR_OKAY) {
190451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    hasErrors = true;
190551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                }
190651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (validateAttr(manifestPath, finalResTable, block,
190751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                 RESOURCES_ANDROID_NAMESPACE, "taskAffinity",
190851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                 processIdentChars, false) != ATTR_OKAY) {
1909a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                    hasErrors = true;
191051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                }
191151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            } else if (strcmp16(block.getElementName(&len), action16.string()) == 0
191251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                       || strcmp16(block.getElementName(&len), category16.string()) == 0) {
191351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (validateAttr(manifestPath, finalResTable, block,
191451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                 RESOURCES_ANDROID_NAMESPACE, "name",
191551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                 packageIdentChars, true) != ATTR_OKAY) {
191651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    hasErrors = true;
191751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                }
191851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            } else if (strcmp16(block.getElementName(&len), data16.string()) == 0) {
191951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (validateAttr(manifestPath, finalResTable, block,
192009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                                 RESOURCES_ANDROID_NAMESPACE, "mimeType",
192109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                                 typeIdentChars, true) != ATTR_OKAY) {
192209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    hasErrors = true;
192309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                }
192409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                if (validateAttr(manifestPath, finalResTable, block,
192509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                                 RESOURCES_ANDROID_NAMESPACE, "scheme",
192609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                                 schemeIdentChars, true) != ATTR_OKAY) {
192709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    hasErrors = true;
192809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                }
192909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            } else if (strcmp16(block.getElementName(&len), feature_group16.string()) == 0) {
193009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                int depth = 1;
193109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                while ((code=block.next()) != ResXMLTree::END_DOCUMENT
193209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                       && code > ResXMLTree::BAD_DOCUMENT) {
193309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    if (code == ResXMLTree::START_TAG) {
193409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                        depth++;
193509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                        if (strcmp16(block.getElementName(&len), uses_feature16.string()) == 0) {
193609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                            ssize_t idx = block.indexOfAttribute(
193709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                                    RESOURCES_ANDROID_NAMESPACE, "required");
193809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                            if (idx < 0) {
193909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                                continue;
194053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                            }
194153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
194253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                            int32_t data = block.getAttributeData(idx);
194353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                            if (data == 0) {
194453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                                fprintf(stderr, "%s:%d: Tag <uses-feature> can not have "
194553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                                        "android:required=\"false\" when inside a "
194653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                                        "<feature-group> tag.\n",
194753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                                        manifestPath.string(), block.getLineNumber());
194853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                                hasErrors = true;
194953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                            }
195053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                        }
195153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                    } else if (code == ResXMLTree::END_TAG) {
195253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                        depth--;
195353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                        if (depth == 0) {
195453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                            break;
1955bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)                        }
195653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                    }
195753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                }
195853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            }
195953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
19601e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
196151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
196253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (hasErrors) {
196353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return UNKNOWN_ERROR;
196453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
19651e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
196610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    if (resFile != NULL) {
19671e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        // These resources are now considered to be a part of the included
19681e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        // resources, for others to reference.
19691e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        err = assets->addIncludedResources(resFile);
197053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (err < NO_ERROR) {
19711e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            fprintf(stderr, "ERROR: Unable to parse generated resources, aborting.\n");
19721e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            return err;
197353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
197453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
19758abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
197653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return err;
19771e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
197810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch
197910f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdochstatic const char* getIndentSpace(int indent)
19801e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){
19811e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)static const char whitespace[] =
19821e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)"                                                                                       ";
19831e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
19841e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return whitespace + sizeof(whitespace) - 1 - indent*4;
19851e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
19861e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
19871e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)static String8 flattenSymbol(const String8& symbol) {
198853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    String8 result(symbol);
198953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ssize_t first;
199053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if ((first = symbol.find(":", 0)) >= 0
199153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            || (first = symbol.find(".", 0)) >= 0) {
199253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        size_t size = symbol.size();
19931e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        char* buf = result.lockBuffer(size);
19941e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        for (size_t i = first; i < size; i++) {
19951e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            if (buf[i] == ':' || buf[i] == '.') {
199653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                buf[i] = '_';
19971e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            }
19981e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
199953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        result.unlockBuffer(size);
200053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
2001d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    return result;
200253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
200353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
20041e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)static String8 getSymbolPackage(const String8& symbol, const sp<AaptAssets>& assets, bool pub) {
200553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ssize_t colon = symbol.find(":", 0);
200653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (colon >= 0) {
20071e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        return String8(symbol.string(), colon);
20081e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
200953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return pub ? assets->getPackage() : assets->getSymbolsPrivatePackage();
201053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
201153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
201253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)static String8 getSymbolName(const String8& symbol) {
20131e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ssize_t colon = symbol.find(":", 0);
201453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (colon >= 0) {
201553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return String8(symbol.string() + colon + 1);
201653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
201753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return symbol;
201853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
201953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
202053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)static String16 getAttributeComment(const sp<AaptAssets>& assets,
202153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                                    const String8& name,
202253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                                    String16* outTypeComment = NULL)
202353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
20248abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    sp<AaptSymbols> asym = assets->getSymbolsFor(String8("R"));
202553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (asym != NULL) {
202653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        //printf("Got R symbols!\n");
202753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        asym = asym->getNestedSymbols().valueFor(String8("attr"));
202853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (asym != NULL) {
202953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            //printf("Got attrs symbols! comment %s=%s\n",
203053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            //     name.string(), String8(asym->getComment(name)).string());
203153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            if (outTypeComment != NULL) {
203253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                *outTypeComment = asym->getTypeComment(name);
203353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            }
203453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            return asym->getComment(name);
203553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
203653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
203753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return String16();
203853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
203953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
204053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)static status_t writeResourceLoadedCallbackForLayoutClasses(
204153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    FILE* fp, const sp<AaptAssets>& assets,
204253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    const sp<AaptSymbols>& symbols, int indent, bool includePrivate)
204353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
204453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    String16 attr16("attr");
204553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    String16 package16(assets->getPackage());
204653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
204753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    const char* indentStr = getIndentSpace(indent);
204853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    bool hasErrors = false;
204953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
205053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    size_t i;
205153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    size_t N = symbols->getNestedSymbols().size();
205253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    for (i=0; i<N; i++) {
205353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);
205453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        String8 realClassName(symbols->getNestedSymbols().keyAt(i));
205553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        String8 nclassName(flattenSymbol(realClassName));
205653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
20575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        fprintf(fp,
2058926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                "%sfor(int i = 0; i < styleable.%s.length; ++i) {\n"
2059926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                "%sstyleable.%s[i] = (styleable.%s[i] & 0x00ffffff) | (packageId << 24);\n"
20608abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                "%s}\n",
20618abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                indentStr, nclassName.string(),
2062926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                getIndentSpace(indent+1), nclassName.string(), nclassName.string(),
2063926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                indentStr);
2064926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
2065926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
2066926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
2067926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
20681e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
20691e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)static status_t writeResourceLoadedCallback(
2070a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    FILE* fp, const sp<AaptAssets>& assets, bool includePrivate,
2071a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    const sp<AaptSymbols>& symbols, const String8& className, int indent)
2072a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles){
20731e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    size_t i;
20741e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    status_t err = NO_ERROR;
20751e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
2076926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    size_t N = symbols->getSymbols().size();
2077926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    for (i=0; i<N; i++) {
2078926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i);
207910f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        if (sym.typeCode == AaptSymbolEntry::TYPE_UNKNOWN) {
2080926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            continue;
2081926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
208207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        if (!assets->isJavaSymbol(sym, includePrivate)) {
2083926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            continue;
2084926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
2085926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        String8 flat_name(flattenSymbol(sym.name));
208653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        fprintf(fp,
208753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                "%s%s.%s = (%s.%s & 0x00ffffff) | (packageId << 24);\n",
2088926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                getIndentSpace(indent), className.string(), flat_name.string(),
208953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                className.string(), flat_name.string());
2090926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
20911e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
2092926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    N = symbols->getNestedSymbols().size();
2093926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    for (i=0; i<N; i++) {
2094926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);
2095f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        String8 nclassName(symbols->getNestedSymbols().keyAt(i));
2096f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        if (nclassName == "styleable") {
2097f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu            err = writeResourceLoadedCallbackForLayoutClasses(
2098f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu                    fp, assets, nsymbols, indent, includePrivate);
2099f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        } else {
2100926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            err = writeResourceLoadedCallback(fp, assets, includePrivate, nsymbols,
2101926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    nclassName, indent);
2102926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
210353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (err != NO_ERROR) {
2104f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu            return err;
210553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
210653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
210753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
210853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return NO_ERROR;
21098abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)}
211053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
211153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)static status_t writeLayoutClasses(
211253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    FILE* fp, const sp<AaptAssets>& assets,
211353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    const sp<AaptSymbols>& symbols, int indent, bool includePrivate, bool nonConstantId)
211453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
211553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    const char* indentStr = getIndentSpace(indent);
211653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!includePrivate) {
21171e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        fprintf(fp, "%s/** @doconly */\n", indentStr);
2118a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    }
21191e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    fprintf(fp, "%spublic static final class styleable {\n", indentStr);
21201e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    indent++;
212153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
21221e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    String16 attr16("attr");
212353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    String16 package16(assets->getPackage());
212453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
212553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    indentStr = getIndentSpace(indent);
212610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    bool hasErrors = false;
212753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
212853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    size_t i;
212953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    size_t N = symbols->getNestedSymbols().size();
2130926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    for (i=0; i<N; i++) {
2131926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);
213293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        String8 realClassName(symbols->getNestedSymbols().keyAt(i));
21335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        String8 nclassName(flattenSymbol(realClassName));
21348abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
213593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        SortedVector<uint32_t> idents;
21365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Vector<uint32_t> origOrder;
21375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Vector<bool> publicFlags;
21385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2139926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        size_t a;
21405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        size_t NA = nsymbols->getSymbols().size();
21415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (a=0; a<NA; a++) {
21425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            const AaptSymbolEntry& sym(nsymbols->getSymbols().valueAt(a));
21431e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            int32_t code = sym.typeCode == AaptSymbolEntry::TYPE_INT32
214451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    ? sym.int32Val : 0;
21451e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            bool isPublic = true;
21465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (code == 0) {
21471e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                String16 name16(sym.name);
21481e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                uint32_t typeSpecFlags;
214993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                code = assets->getIncludedResources().identifierForName(
21501e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    name16.string(), name16.size(),
21511e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    attr16.string(), attr16.size(),
215293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                    package16.string(), package16.size(), &typeSpecFlags);
21531e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                if (code == 0) {
21541e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    fprintf(stderr, "ERROR: In <declare-styleable> %s, unable to find attribute %s\n",
21555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            nclassName.string(), sym.name.string());
21561e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    hasErrors = true;
21571e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                }
21585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                isPublic = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;
21591e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            }
21601e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            idents.add(code);
21615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            origOrder.add(code);
21625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            publicFlags.add(isPublic);
216353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
216453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
21658abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        NA = idents.size();
216653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
216753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        String16 comment = symbols->getComment(realClassName);
216853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        AnnotationProcessor ann;
216953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        fprintf(fp, "%s/** ", indentStr);
217053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (comment.size() > 0) {
217153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            String8 cmt(comment);
21721e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            ann.preprocessComment(cmt);
21731e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            fprintf(fp, "%s\n", cmt.string());
217409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        } else {
21751e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            fprintf(fp, "Attributes that can be used with a %s.\n", nclassName.string());
2176d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        }
21771e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        bool hasTable = false;
21781e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        for (a=0; a<NA; a++) {
217953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            ssize_t pos = idents.indexOf(origOrder.itemAt(a));
21801e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            if (pos >= 0) {
218153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                if (!hasTable) {
218253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                    hasTable = true;
218353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                    fprintf(fp,
21841e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                            "%s   <p>Includes the following attributes:</p>\n"
21851e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                            "%s   <table>\n"
218653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                            "%s   <colgroup align=\"left\" />\n"
218753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                            "%s   <colgroup align=\"left\" />\n"
218853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                            "%s   <tr><th>Attribute</th><th>Description</th></tr>\n",
218953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                            indentStr,
219051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                            indentStr,
21915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            indentStr,
219210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch                            indentStr,
219310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch                            indentStr);
21945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
21955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a);
21965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (!publicFlags.itemAt(a) && !includePrivate) {
21975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    continue;
21985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
21995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                String8 name8(sym.name);
22005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                String16 comment(sym.comment);
2201926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                if (comment.size() <= 0) {
2202926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    comment = getAttributeComment(assets, name8);
2203926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                }
22048abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                if (comment.size() > 0) {
22051e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    const char16_t* p = comment.string();
22061e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    while (*p != 0 && *p != '.') {
22071e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        if (*p == '{') {
22081e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                            while (*p != 0 && *p != '}') {
220910f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch                                p++;
22101e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                            }
22111e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        } else {
22125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            p++;
22135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        }
22145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    }
2215f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                    if (*p == '.') {
2216f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                        p++;
2217f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                    }
2218f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                    comment = String16(comment.string(), p-comment.string());
22195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
22205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                fprintf(fp, "%s   <tr><td><code>{@link #%s_%s %s:%s}</code></td><td>%s</td></tr>\n",
22218abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                        indentStr, nclassName.string(),
22221e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        flattenSymbol(name8).string(),
22235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        getSymbolPackage(name8, assets, true).string(),
22245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        getSymbolName(name8).string(),
22251e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        String8(comment).string());
22261e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            }
22275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
22285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (hasTable) {
22295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            fprintf(fp, "%s   </table>\n", indentStr);
2230926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
2231926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        for (a=0; a<NA; a++) {
22325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ssize_t pos = idents.indexOf(origOrder.itemAt(a));
22331e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            if (pos >= 0) {
22345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a);
22355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (!publicFlags.itemAt(a) && !includePrivate) {
22361e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    continue;
22371e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                }
22385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                fprintf(fp, "%s   @see #%s_%s\n",
22391e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        indentStr, nclassName.string(),
22401e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        flattenSymbol(sym.name).string());
22415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
22425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
22431e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        fprintf(fp, "%s */\n", getIndentSpace(indent));
22441e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
22455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ann.printAnnotations(fp, indentStr);
22465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2247926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        fprintf(fp,
2248926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                "%spublic static final int[] %s = {\n"
22495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                "%s",
22505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                indentStr, nclassName.string(),
22515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                getIndentSpace(indent+1));
22521e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
22535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (a=0; a<NA; a++) {
22545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (a != 0) {
22555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if ((a&3) == 0) {
2256f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                    fprintf(fp, ",\n%s", getIndentSpace(indent+1));
22575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                } else {
2258f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                    fprintf(fp, ", ");
2259f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                }
2260926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            }
22615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            fprintf(fp, "0x%08x", idents[a]);
22625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
22635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2264f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        fprintf(fp, "\n%s};\n", indentStr);
2265f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
2266f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        for (a=0; a<NA; a++) {
2267f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)            ssize_t pos = idents.indexOf(origOrder.itemAt(a));
2268f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)            if (pos >= 0) {
2269f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a);
2270f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                if (!publicFlags.itemAt(a) && !includePrivate) {
2271f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                    continue;
2272f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                }
2273f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                String8 name8(sym.name);
2274f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                String16 comment(sym.comment);
2275f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                String16 typeComment;
2276f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                if (comment.size() <= 0) {
22778abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                    comment = getAttributeComment(assets, name8, &typeComment);
22788abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                } else {
22798abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                    getAttributeComment(assets, name8, &typeComment);
22808abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                }
22818abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
22828abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                uint32_t typeSpecFlags = 0;
22838abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                String16 name16(sym.name);
22848abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                assets->getIncludedResources().identifierForName(
22851e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    name16.string(), name16.size(),
22861e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    attr16.string(), attr16.size(),
22871e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    package16.string(), package16.size(), &typeSpecFlags);
22881e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                //printf("%s:%s/%s: 0x%08x\n", String8(package16).string(),
22891e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                //    String8(attr16).string(), String8(name16).string(), typeSpecFlags);
229010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch                const bool pub = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;
22911e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
22928abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                AnnotationProcessor ann;
22931e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                fprintf(fp, "%s/**\n", indentStr);
22948abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                if (comment.size() > 0) {
22951e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    String8 cmt(comment);
22968abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                    ann.preprocessComment(cmt);
22978abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                    fprintf(fp, "%s  <p>\n%s  @attr description\n", indentStr, indentStr);
22988abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                    fprintf(fp, "%s  %s\n", indentStr, cmt.string());
22998abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                } else {
23001e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    fprintf(fp,
23018abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                            "%s  <p>This symbol is the offset where the {@link %s.R.attr#%s}\n"
23021e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                            "%s  attribute's value can be found in the {@link #%s} array.\n",
23038abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                            indentStr,
23041e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                            getSymbolPackage(name8, assets, pub).string(),
23051e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                            getSymbolName(name8).string(),
23068abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                            indentStr, nclassName.string());
23078abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                }
230806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                if (typeComment.size() > 0) {
230906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                    String8 cmt(typeComment);
231006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                    ann.preprocessComment(cmt);
231106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                    fprintf(fp, "\n\n%s  %s\n", indentStr, cmt.string());
231206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                }
231306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                if (comment.size() > 0) {
231406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                    if (pub) {
231506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                        fprintf(fp,
231606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                                "%s  <p>This corresponds to the global attribute\n"
231706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                                "%s  resource symbol {@link %s.R.attr#%s}.\n",
23181e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                                indentStr, indentStr,
2319a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                                getSymbolPackage(name8, assets, true).string(),
23201e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                                getSymbolName(name8).string());
23211e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    } else {
23221e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        fprintf(fp,
232310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch                                "%s  <p>This is a private symbol.\n", indentStr);
23241e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    }
232506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                }
232606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                fprintf(fp, "%s  @attr name %s:%s\n", indentStr,
232706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                        getSymbolPackage(name8, assets, pub).string(),
232806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                        getSymbolName(name8).string());
232906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                fprintf(fp, "%s*/\n", indentStr);
233006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                ann.printAnnotations(fp, indentStr);
23311e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
23321e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                const char * id_format = nonConstantId ?
233306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                        "%spublic static int %s_%s = %d;\n" :
233406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                        "%spublic static final int %s_%s = %d;\n";
233506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
233606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                fprintf(fp,
23375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        id_format,
23385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        indentStr, nclassName.string(),
23395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        flattenSymbol(name8).string(), (int)pos);
23405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
2341926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
2342926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
2343926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
23445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    indent--;
23451e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    fprintf(fp, "%s};\n", getIndentSpace(indent));
23461e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
23471e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
23481e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
23491e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)static status_t writeTextLayoutClasses(
235010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    FILE* fp, const sp<AaptAssets>& assets,
23511e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    const sp<AaptSymbols>& symbols, bool includePrivate)
2352926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
23531e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    String16 attr16("attr");
23545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String16 package16(assets->getPackage());
23555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
23565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool hasErrors = false;
23575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
23585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    size_t i;
23595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    size_t N = symbols->getNestedSymbols().size();
23601e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    for (i=0; i<N; i++) {
23615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);
23625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        String8 realClassName(symbols->getNestedSymbols().keyAt(i));
23635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        String8 nclassName(flattenSymbol(realClassName));
23641e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
2365926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        SortedVector<uint32_t> idents;
23661e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        Vector<uint32_t> origOrder;
23671e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        Vector<bool> publicFlags;
23685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
23695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        size_t a;
23701e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        size_t NA = nsymbols->getSymbols().size();
2371926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        for (a=0; a<NA; a++) {
23721e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            const AaptSymbolEntry& sym(nsymbols->getSymbols().valueAt(a));
23731e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            int32_t code = sym.typeCode == AaptSymbolEntry::TYPE_INT32
2374926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    ? sym.int32Val : 0;
23751e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            bool isPublic = true;
23761e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            if (code == 0) {
2377926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                String16 name16(sym.name);
2378926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                uint32_t typeSpecFlags;
23791e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                code = assets->getIncludedResources().identifierForName(
23801e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    name16.string(), name16.size(),
23811e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    attr16.string(), attr16.size(),
23821e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    package16.string(), package16.size(), &typeSpecFlags);
23831e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                if (code == 0) {
23845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    fprintf(stderr, "ERROR: In <declare-styleable> %s, unable to find attribute %s\n",
23855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            nclassName.string(), sym.name.string());
23865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    hasErrors = true;
23875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
23885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                isPublic = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;
23895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
2390926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            idents.add(code);
23915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            origOrder.add(code);
23925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            publicFlags.add(isPublic);
23931e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
23941e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
23951e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        NA = idents.size();
23961e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
23971e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        fprintf(fp, "int[] styleable %s {", nclassName.string());
2398926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
23991e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        for (a=0; a<NA; a++) {
24005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (a != 0) {
2401926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                fprintf(fp, ",");
2402926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            }
2403926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            fprintf(fp, " 0x%08x", idents[a]);
2404926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
2405926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
2406926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        fprintf(fp, " }\n");
24071e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
24081e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        for (a=0; a<NA; a++) {
24091e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            ssize_t pos = idents.indexOf(origOrder.itemAt(a));
24101e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            if (pos >= 0) {
24111e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a);
2412926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                if (!publicFlags.itemAt(a) && !includePrivate) {
24131e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    continue;
24141e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                }
24151e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                String8 name8(sym.name);
2416926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                String16 comment(sym.comment);
2417926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                String16 typeComment;
2418926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                if (comment.size() <= 0) {
24191e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    comment = getAttributeComment(assets, name8, &typeComment);
2420926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                } else {
24211e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    getAttributeComment(assets, name8, &typeComment);
24221e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                }
24231e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
24241e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                uint32_t typeSpecFlags = 0;
24251e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                String16 name16(sym.name);
2426926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                assets->getIncludedResources().identifierForName(
24271e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    name16.string(), name16.size(),
24281e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    attr16.string(), attr16.size(),
24291e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    package16.string(), package16.size(), &typeSpecFlags);
24308abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                //printf("%s:%s/%s: 0x%08x\n", String8(package16).string(),
2431926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                //    String8(attr16).string(), String8(name16).string(), typeSpecFlags);
2432926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                const bool pub = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;
24331e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
2434926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                fprintf(fp,
24351e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        "int styleable %s_%s %d\n",
24361e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        nclassName.string(),
24371e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        flattenSymbol(name8).string(), (int)pos);
24381e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            }
24391e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
2440926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
24411e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
24421e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
24431e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
24448abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
2445926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static status_t writeSymbolClass(
2446926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    FILE* fp, const sp<AaptAssets>& assets, bool includePrivate,
2447926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    const sp<AaptSymbols>& symbols, const String8& className, int indent,
2448926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    bool nonConstantId, bool emitCallback)
2449926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
2450926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    fprintf(fp, "%spublic %sfinal class %s {\n",
2451926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            getIndentSpace(indent),
2452926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            indent != 0 ? "static " : "", className.string());
2453926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    indent++;
245451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
24551e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    size_t i;
24561e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    status_t err = NO_ERROR;
24571e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
24581e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    const char * id_format = nonConstantId ?
2459926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            "%spublic static int %s=0x%08x;\n" :
24601e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            "%spublic static final int %s=0x%08x;\n";
24611e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
246251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    size_t N = symbols->getSymbols().size();
24635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (i=0; i<N; i++) {
24645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i);
24655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (sym.typeCode != AaptSymbolEntry::TYPE_INT32) {
24665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
24675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
24685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!assets->isJavaSymbol(sym, includePrivate)) {
246951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            continue;
247051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
24711e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        String8 name8(sym.name);
24721e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        String16 comment(sym.comment);
24731e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        bool haveComment = false;
24741e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        AnnotationProcessor ann;
24751e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (comment.size() > 0) {
2476926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            haveComment = true;
24771e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            String8 cmt(comment);
24781e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            ann.preprocessComment(cmt);
24791e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            fprintf(fp,
2480926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    "%s/** %s\n",
24815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    getIndentSpace(indent), cmt.string());
24825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else if (sym.isPublic && !includePrivate) {
24831e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            sym.sourcePos.warning("No comment for public symbol %s:%s/%s",
248451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                assets->getPackage().string(), className.string(),
24851e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                String8(sym.name).string());
24861e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
24871e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        String16 typeComment(sym.typeComment);
24881e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (typeComment.size() > 0) {
24891e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            String8 cmt(typeComment);
24905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ann.preprocessComment(cmt);
24911e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            if (!haveComment) {
24921e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                haveComment = true;
24931e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                fprintf(fp,
24948abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                        "%s/** %s\n", getIndentSpace(indent), cmt.string());
24955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            } else {
24965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                fprintf(fp,
24971e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        "%s %s\n", getIndentSpace(indent), cmt.string());
249851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            }
24991e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
25001e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (haveComment) {
25011e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            fprintf(fp,"%s */\n", getIndentSpace(indent));
25021e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
25031e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        ann.printAnnotations(fp, getIndentSpace(indent));
25045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        fprintf(fp, id_format,
25051e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                getIndentSpace(indent),
25061e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                flattenSymbol(name8).string(), (int)sym.int32Val);
25071e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
25088abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
2509926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    for (i=0; i<N; i++) {
2510926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i);
25111e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (sym.typeCode != AaptSymbolEntry::TYPE_STRING) {
251251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            continue;
25131e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
25141e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (!assets->isJavaSymbol(sym, includePrivate)) {
25151e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            continue;
25161e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
25171e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        String8 name8(sym.name);
2518926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        String16 comment(sym.comment);
25191e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        AnnotationProcessor ann;
25201e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (comment.size() > 0) {
25211e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            String8 cmt(comment);
2522926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            ann.preprocessComment(cmt);
25235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            fprintf(fp,
25245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    "%s/** %s\n"
2525f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                     "%s */\n",
2526f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                    getIndentSpace(indent), cmt.string(),
2527f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                    getIndentSpace(indent));
2528f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        } else if (sym.isPublic && !includePrivate) {
2529f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)            sym.sourcePos.warning("No comment for public symbol %s:%s/%s",
2530f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                assets->getPackage().string(), className.string(),
2531f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                String8(sym.name).string());
2532f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        }
25331e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        ann.printAnnotations(fp, getIndentSpace(indent));
25341e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        fprintf(fp, "%spublic static final String %s=\"%s\";\n",
25351e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                getIndentSpace(indent),
25361e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                flattenSymbol(name8).string(), sym.stringVal.string());
25371e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
253810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch
25391e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    sp<AaptSymbols> styleableSymbols;
2540f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
25411e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    N = symbols->getNestedSymbols().size();
2542f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    for (i=0; i<N; i++) {
2543f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);
2544f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        String8 nclassName(symbols->getNestedSymbols().keyAt(i));
2545f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        if (nclassName == "styleable") {
2546f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)            styleableSymbols = nsymbols;
25471e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        } else {
2548f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)            err = writeSymbolClass(fp, assets, includePrivate, nsymbols, nclassName,
25491e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    indent, nonConstantId, false);
2550f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        }
25511e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (err != NO_ERROR) {
2552f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)            return err;
25531e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
2554f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    }
255510f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch
25561e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (styleableSymbols != NULL) {
2557f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        err = writeLayoutClasses(fp, assets, styleableSymbols, indent, includePrivate, nonConstantId);
2558f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        if (err != NO_ERROR) {
2559f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)            return err;
2560926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
25615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
25625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
25635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (emitCallback) {
2564926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        fprintf(fp, "%spublic static void onResourcesLoaded(int packageId) {\n",
2565926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                getIndentSpace(indent));
25665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        writeResourceLoadedCallback(fp, assets, includePrivate, symbols, className, indent + 1);
25675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        fprintf(fp, "%s}\n", getIndentSpace(indent));
2568926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
25691e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
25701e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    indent--;
25711e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    fprintf(fp, "%s}\n", getIndentSpace(indent));
25721e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return NO_ERROR;
25731e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
25741e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
25751e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)static status_t writeTextSymbolClass(
2576926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    FILE* fp, const sp<AaptAssets>& assets, bool includePrivate,
25771e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    const sp<AaptSymbols>& symbols, const String8& className)
25785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
25795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    size_t i;
25805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    status_t err = NO_ERROR;
25815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
25825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    size_t N = symbols->getSymbols().size();
25835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (i=0; i<N; i++) {
25841e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i);
2585926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (sym.typeCode != AaptSymbolEntry::TYPE_INT32) {
25861e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            continue;
25871e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
25885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
25891e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (!assets->isJavaSymbol(sym, includePrivate)) {
2590926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            continue;
2591926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
2592926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
2593926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        String8 name8(sym.name);
25941e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        fprintf(fp, "int %s %s 0x%08x\n",
2595926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                className.string(),
25965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                flattenSymbol(name8).string(), (int)sym.int32Val);
2597926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
2598926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
2599926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    N = symbols->getNestedSymbols().size();
2600926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    for (i=0; i<N; i++) {
2601926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);
26025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        String8 nclassName(symbols->getNestedSymbols().keyAt(i));
26035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (nclassName == "styleable") {
2604926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            err = writeTextLayoutClasses(fp, assets, nsymbols, includePrivate);
2605926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        } else {
26061e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            err = writeTextSymbolClass(fp, assets, includePrivate, nsymbols, nclassName);
26071e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
26081e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (err != NO_ERROR) {
26091e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            return err;
2610926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
26115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2612926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
2613926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return NO_ERROR;
2614926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
26155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
26161e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)status_t writeResourceSymbols(Bundle* bundle, const sp<AaptAssets>& assets,
26175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const String8& package, bool includePrivate, bool emitCallback)
26181e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){
26191e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (!bundle->getRClassDir()) {
26201e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        return NO_ERROR;
2621926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
26225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2623926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    const char* textSymbolsDest = bundle->getOutputTextSymbols();
2624926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
2625926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    String8 R("R");
2626926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    const size_t N = assets->getSymbols().size();
2627926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    for (size_t i=0; i<N; i++) {
2628926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        sp<AaptSymbols> symbols = assets->getSymbols().valueAt(i);
26291e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        String8 className(assets->getSymbols().keyAt(i));
26305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        String8 dest(bundle->getRClassDir());
26315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
26321e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (bundle->getMakePackageDirs()) {
26331e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            String8 pkg(package);
26345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            const char* last = pkg.string();
2635926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            const char* s = last-1;
26365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            do {
2637926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                s++;
2638d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if (s > last && (*s == '.' || *s == 0)) {
26395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    String8 part(last, s-last);
26405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    dest.appendPath(part);
2641a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#ifdef HAVE_MS_C_RUNTIME
2642e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)                    _mkdir(dest.string());
26435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#else
26445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    mkdir(dest.string(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);
26455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
26465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    last = s+1;
26475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
26485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            } while (*s);
26495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
26505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        dest.appendPath(className);
26515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        dest.append(".java");
26525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        FILE* fp = fopen(dest.string(), "w+");
26535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (fp == NULL) {
26545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            fprintf(stderr, "ERROR: Unable to open class file %s: %s\n",
26555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    dest.string(), strerror(errno));
26561e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            return UNKNOWN_ERROR;
26571e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
26585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (bundle->getVerbose()) {
26591e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            printf("  Writing symbols for class %s.\n", className.string());
2660d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        }
2661d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
26625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        fprintf(fp,
26635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            "/* AUTO-GENERATED FILE.  DO NOT MODIFY.\n"
2664d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            " *\n"
2665d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            " * This class was automatically generated by the\n"
2666d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            " * aapt tool from the resource data it found.  It\n"
2667d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            " * should not be modified by hand.\n"
2668d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            " */\n"
2669d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            "\n"
2670d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            "package %s;\n\n", package.string());
2671d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
2672d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        status_t err = writeSymbolClass(fp, assets, includePrivate, symbols,
2673d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                className, 0, bundle->getNonConstantId(), emitCallback);
2674d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        fclose(fp);
2675d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        if (err != NO_ERROR) {
2676d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            return err;
2677d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        }
2678d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
2679d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        if (textSymbolsDest != NULL && R == className) {
2680d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            String8 textDest(textSymbolsDest);
2681d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            textDest.appendPath(className);
26825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            textDest.append(".txt");
26835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
26845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            FILE* fp = fopen(textDest.string(), "w+");
26855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (fp == NULL) {
26865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                fprintf(stderr, "ERROR: Unable to open text symbol file %s: %s\n",
26875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        textDest.string(), strerror(errno));
26885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return UNKNOWN_ERROR;
26895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
26905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (bundle->getVerbose()) {
26915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                printf("  Writing text symbols for class %s.\n", className.string());
26925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
26935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
26945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            status_t err = writeTextSymbolClass(fp, assets, includePrivate, symbols,
26951e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    className);
26961e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            fclose(fp);
26971e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            if (err != NO_ERROR) {
26981e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                return err;
269910f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch            }
27005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
27011e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
27021e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        // If we were asked to generate a dependency file, we'll go ahead and add this R.java
27035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // as a target in the dependency file right next to it.
27045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (bundle->getGenDependencies() && R == className) {
2705d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            // Add this R.java to the dependency file
2706d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            String8 dependencyFile(bundle->getRClassDir());
2707d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            dependencyFile.appendPath("R.java.d");
27081e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
27091e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            FILE *fp = fopen(dependencyFile.string(), "a");
27105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            fprintf(fp,"%s \\\n", dest.string());
27115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            fclose(fp);
2712d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        }
2713d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    }
2714d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
27151e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return NO_ERROR;
27161e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
27175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
27185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
271993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)class ProguardKeepSet
272093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
272193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)public:
272293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // { rule --> { file locations } }
272393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    KeyedVector<String8, SortedVector<String8> > rules;
272493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
27251e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    void add(const String8& rule, const String8& where);
272609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)};
2727d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
2728d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void ProguardKeepSet::add(const String8& rule, const String8& where)
2729d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){
2730d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    ssize_t index = rules.indexOfKey(rule);
273193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (index < 0) {
2732d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        index = rules.add(rule, SortedVector<String8>());
273309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
273409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    rules.editValueAt(index).add(where);
273509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
273609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
273793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)void
273893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)addProguardKeepRule(ProguardKeepSet* keep, const String8& inClassName,
2739f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        const char* pkg, const String8& srcName, int line)
2740f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles){
2741f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    String8 className(inClassName);
2742f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    if (pkg != NULL) {
2743f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        // asdf     --> package.asdf
2744f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        // .asdf  .a.b  --> package.asdf package.a.b
2745f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        // asdf.adsf --> asdf.asdf
2746f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        const char* p = className.string();
2747f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        const char* q = strchr(p, '.');
2748f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        if (p == q) {
2749f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            className = pkg;
2750f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            className.append(inClassName);
2751f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        } else if (q == NULL) {
2752f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            className = pkg;
2753f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            className.append(".");
2754f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            className.append(inClassName);
2755f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        }
2756f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    }
2757f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
27585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String8 rule("-keep class ");
27595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    rule += className;
27605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    rule += " { <init>(...); }";
27615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
27625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String8 location("view ");
27631e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    location += srcName;
27641e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    char lineno[20];
2765d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    sprintf(lineno, ":%d", line);
2766d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    location += lineno;
27675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
27681e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    keep->add(rule, location);
27695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
27705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
27715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void
27725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)addProguardKeepMethodRule(ProguardKeepSet* keep, const String8& memberName,
27735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const char* pkg, const String8& srcName, int line)
27745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
27755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String8 rule("-keepclassmembers class * { *** ");
27765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    rule += memberName;
27775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    rule += "(...); }";
27785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
27795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String8 location("onClick ");
27805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    location += srcName;
27815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    char lineno[20];
27825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    sprintf(lineno, ":%d", line);
27835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    location += lineno;
27841e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
27851e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    keep->add(rule, location);
27865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
27875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2788d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)status_t
27895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)writeProguardForAndroidManifest(ProguardKeepSet* keep, const sp<AaptAssets>& assets)
27905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
27911e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    status_t err;
27925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ResXMLTree tree;
27935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    size_t len;
27945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ResXMLTree::event_code_t code;
27955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int depth = 0;
279609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    bool inApplication = false;
27975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String8 error;
27985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    sp<AaptGroup> assGroup;
27995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    sp<AaptFile> assFile;
2800a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    String8 pkg;
2801926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
280253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // First, look for a package file to parse.  This is required to
2803926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // be able to generate the resource information.
28045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    assGroup = assets->getFiles().valueFor(String8("AndroidManifest.xml"));
28055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (assGroup == NULL) {
28065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        fprintf(stderr, "ERROR: No AndroidManifest.xml file found.\n");
28075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return -1;
28085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2809a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
28105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (assGroup->getFiles().size() != 1) {
28115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        fprintf(stderr, "warning: Multiple AndroidManifest.xml files found, using %s\n",
28125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                assGroup->getFiles().valueAt(0)->getPrintableSource().string());
28135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
28145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
28155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    assFile = assGroup->getFiles().valueAt(0);
28165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2817a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    err = parseXMLResource(assFile, &tree);
28185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (err != NO_ERROR) {
28195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return err;
28205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
28215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2822926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    tree.restart();
28235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
28245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
28255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (code == ResXMLTree::END_TAG) {
28265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (/* name == "Application" && */ depth == 2) {
28275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                inApplication = false;
28285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
28295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            depth--;
28305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
28315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
28325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (code != ResXMLTree::START_TAG) {
28335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
28345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
28355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        depth++;
28365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        String8 tag(tree.getElementName(&len));
28375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // printf("Depth %d tag %s\n", depth, tag.string());
28385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool keepTag = false;
28395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (depth == 1) {
28405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (tag != "manifest") {
28415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                fprintf(stderr, "ERROR: manifest does not start with <manifest> tag\n");
28425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return -1;
2843a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            }
28445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            pkg = AaptXml::getAttribute(tree, NULL, "package");
28455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else if (depth == 2) {
28465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (tag == "application") {
28475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                inApplication = true;
2848a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch                keepTag = true;
28495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
28505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                String8 agent = AaptXml::getAttribute(tree,
28515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        "http://schemas.android.com/apk/res/android",
28525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        "backupAgent", &error);
28535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (agent.length() > 0) {
28547757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                    addProguardKeepRule(keep, agent, pkg.string(),
28557757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                            assFile->getPrintableSource(), tree.getLineNumber());
28565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
28578abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            } else if (tag == "instrumentation") {
28585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                keepTag = true;
28595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
28605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
28615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!keepTag && inApplication && depth == 3) {
28625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (tag == "activity" || tag == "service" || tag == "receiver" || tag == "provider") {
28635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                keepTag = true;
28641e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            }
28651e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
28665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (keepTag) {
28671e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            String8 name = AaptXml::getAttribute(tree,
28685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    "http://schemas.android.com/apk/res/android", "name", &error);
28695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (error != "") {
28705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                fprintf(stderr, "ERROR: %s\n", error.string());
28715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return -1;
28725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
28735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (name.length() > 0) {
28745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                addProguardKeepRule(keep, name, pkg.string(),
28755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        assFile->getPrintableSource(), tree.getLineNumber());
28765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
28775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
28785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
28795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
28805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return NO_ERROR;
28815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
28825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
28835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct NamespaceAttributePair {
28845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const char* ns;
28851e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    const char* attr;
28865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
28875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    NamespaceAttributePair(const char* n, const char* a) : ns(n), attr(a) {}
28885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    NamespaceAttributePair() : ns(NULL), attr(NULL) {}
28895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
28905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
28915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)status_t
28925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)writeProguardForXml(ProguardKeepSet* keep, const sp<AaptFile>& layoutFile,
28935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const Vector<String8>& startTags, const KeyedVector<String8, Vector<NamespaceAttributePair> >* tagAttrPairs)
28945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
28955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    status_t err;
28965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ResXMLTree tree;
28978abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    size_t len;
28985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ResXMLTree::event_code_t code;
28995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
29005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    err = parseXMLResource(layoutFile, &tree);
29015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (err != NO_ERROR) {
29025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return err;
29031e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
29041e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
29055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    tree.restart();
29065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2907d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (!startTags.isEmpty()) {
29085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool haveStart = false;
29095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
29105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (code != ResXMLTree::START_TAG) {
29115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                continue;
29125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
29135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            String8 tag(tree.getElementName(&len));
29145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            const size_t numStartTags = startTags.size();
29155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            for (size_t i = 0; i < numStartTags; i++) {
29165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (tag == startTags[i]) {
29175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    haveStart = true;
29181e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                }
29195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
29205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
29215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
29225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!haveStart) {
29235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return NO_ERROR;
29245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
29255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
29265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
29275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
29285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (code != ResXMLTree::START_TAG) {
29295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
29305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
29315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        String8 tag(tree.getElementName(&len));
29325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
29335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If there is no '.', we'll assume that it's one of the built in names.
29345267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        if (strchr(tag.string(), '.')) {
29355267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            addProguardKeepRule(keep, tag, NULL,
29365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    layoutFile->getPrintableSource(), tree.getLineNumber());
29375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else if (tagAttrPairs != NULL) {
29385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ssize_t tagIndex = tagAttrPairs->indexOfKey(tag);
29395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (tagIndex >= 0) {
29405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                const Vector<NamespaceAttributePair>& nsAttrVector = tagAttrPairs->valueAt(tagIndex);
29411e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                for (size_t i = 0; i < nsAttrVector.size(); i++) {
29421e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    const NamespaceAttributePair& nsAttr = nsAttrVector[i];
29435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
29445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    ssize_t attrIndex = tree.indexOfAttribute(nsAttr.ns, nsAttr.attr);
29455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (attrIndex < 0) {
29465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        // fprintf(stderr, "%s:%d: <%s> does not have attribute %s:%s.\n",
29475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        //        layoutFile->getPrintableSource().string(), tree.getLineNumber(),
29485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        //        tag.string(), nsAttr.ns, nsAttr.attr);
29495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    } else {
29505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        size_t len;
29511e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        addProguardKeepRule(keep,
29525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                            String8(tree.getAttributeStringValue(attrIndex, &len)), NULL,
29535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                            layoutFile->getPrintableSource(), tree.getLineNumber());
29545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    }
29555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
29565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
29571e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
29585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ssize_t attrIndex = tree.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, "onClick");
29595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (attrIndex >= 0) {
29601e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            size_t len;
29615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            addProguardKeepMethodRule(keep,
29621e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                                String8(tree.getAttributeStringValue(attrIndex, &len)), NULL,
29635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                layoutFile->getPrintableSource(), tree.getLineNumber());
29645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
29655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
29665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
29675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return NO_ERROR;
29685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
29695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
29705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void addTagAttrPair(KeyedVector<String8, Vector<NamespaceAttributePair> >* dest,
29715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const char* tag, const char* ns, const char* attr) {
29725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String8 tagStr(tag);
29735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ssize_t index = dest->indexOfKey(tagStr);
29745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
29755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (index < 0) {
29765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Vector<NamespaceAttributePair> vector;
29775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        vector.add(NamespaceAttributePair(ns, attr));
29785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        dest->add(tagStr, vector);
29791e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    } else {
29801e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        dest->editValueAt(index).add(NamespaceAttributePair(ns, attr));
29811e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
29825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
29835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
29845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)status_t
29855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)writeProguardForLayouts(ProguardKeepSet* keep, const sp<AaptAssets>& assets)
29865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
29875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    status_t err;
29885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
29895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // tag:attribute pairs that should be checked in layout files.
29905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    KeyedVector<String8, Vector<NamespaceAttributePair> > kLayoutTagAttrPairs;
2991d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    addTagAttrPair(&kLayoutTagAttrPairs, "view", NULL, "class");
29925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    addTagAttrPair(&kLayoutTagAttrPairs, "fragment", NULL, "class");
29935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    addTagAttrPair(&kLayoutTagAttrPairs, "fragment", RESOURCES_ANDROID_NAMESPACE, "name");
29945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
29955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // tag:attribute pairs that should be checked in xml files.
29965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    KeyedVector<String8, Vector<NamespaceAttributePair> > kXmlTagAttrPairs;
29975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    addTagAttrPair(&kXmlTagAttrPairs, "PreferenceScreen", RESOURCES_ANDROID_NAMESPACE, "fragment");
29985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    addTagAttrPair(&kXmlTagAttrPairs, "header", RESOURCES_ANDROID_NAMESPACE, "fragment");
29995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
30005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const Vector<sp<AaptDir> >& dirs = assets->resDirs();
3001d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const size_t K = dirs.size();
30025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t k=0; k<K; k++) {
30035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const sp<AaptDir>& d = dirs.itemAt(k);
30045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const String8& dirName = d->getLeaf();
30055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Vector<String8> startTags;
30065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const char* startTag = NULL;
30075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const KeyedVector<String8, Vector<NamespaceAttributePair> >* tagAttrPairs = NULL;
30085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if ((dirName == String8("layout")) || (strncmp(dirName.string(), "layout-", 7) == 0)) {
30095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            tagAttrPairs = &kLayoutTagAttrPairs;
30105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else if ((dirName == String8("xml")) || (strncmp(dirName.string(), "xml-", 4) == 0)) {
3011d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            startTags.add(String8("PreferenceScreen"));
30125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            startTags.add(String8("preference-headers"));
30135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            tagAttrPairs = &kXmlTagAttrPairs;
30145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else if ((dirName == String8("menu")) || (strncmp(dirName.string(), "menu-", 5) == 0)) {
30155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            startTags.add(String8("menu"));
30165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            tagAttrPairs = NULL;
30175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else {
30185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
30195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
30205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
30215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const KeyedVector<String8,sp<AaptGroup> > groups = d->getFiles();
3022d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        const size_t N = groups.size();
30235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (size_t i=0; i<N; i++) {
3024926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            const sp<AaptGroup>& group = groups.valueAt(i);
3025926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            const DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> >& files = group->getFiles();
3026926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            const size_t M = files.size();
3027926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            for (size_t j=0; j<M; j++) {
3028926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                err = writeProguardForXml(keep, files.valueAt(j), startTags, tagAttrPairs);
3029926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                if (err < 0) {
3030926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    return err;
30315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
30325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
30335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
30345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
30351e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    // Handle the overlays
30361e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    sp<AaptAssets> overlay = assets->getOverlay();
30375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (overlay.get()) {
30385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return writeProguardForLayouts(keep, overlay);
30391e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
30401e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
30415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return NO_ERROR;
30425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
30435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
30445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)status_t
3045d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)writeProguardFile(Bundle* bundle, const sp<AaptAssets>& assets)
30465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
30475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    status_t err = -1;
30485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
30495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!bundle->getProguardFile()) {
30501e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        return NO_ERROR;
30515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
30525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
30535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ProguardKeepSet keep;
30545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
30551e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    err = writeProguardForAndroidManifest(&keep, assets);
30565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (err < 0) {
30575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return err;
30585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3059d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
30605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    err = writeProguardForLayouts(&keep, assets);
30615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (err < 0) {
3062aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch        return err;
30635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3064d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
30655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    FILE* fp = fopen(bundle->getProguardFile(), "w+");
30665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (fp == NULL) {
30671e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        fprintf(stderr, "ERROR: Unable to open class file %s: %s\n",
30685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                bundle->getProguardFile(), strerror(errno));
30695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return UNKNOWN_ERROR;
30705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
30715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
30721e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    const KeyedVector<String8, SortedVector<String8> >& rules = keep.rules;
30735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const size_t N = rules.size();
30745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i=0; i<N; i++) {
30755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const SortedVector<String8>& locations = rules.valueAt(i);
30765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const size_t M = locations.size();
30771e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        for (size_t j=0; j<M; j++) {
30781e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            fprintf(fp, "# %s\n", locations.itemAt(j).string());
30791e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
30805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        fprintf(fp, "%s\n\n", rules.keyAt(i).string());
30815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
30825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    fclose(fp);
30835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3084d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    return err;
30855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
30865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
30871e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)// Loops through the string paths and writes them to the file pointer
30885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Each file path is written on its own line with a terminating backslash.
30891e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)status_t writePathsToFile(const sp<FilePathStore>& files, FILE* fp)
30905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
30915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    status_t deps = -1;
3092d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    for (size_t file_i = 0; file_i < files->size(); ++file_i) {
30935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Add the full file path to the dependency file
30941e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        fprintf(fp, "%s \\\n", files->itemAt(file_i).string());
30955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        deps++;
30965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
30971e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return deps;
30985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
30995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
31005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)status_t
31015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)writeDependencyPreReqs(Bundle* bundle, const sp<AaptAssets>& assets, FILE* fp, bool includeRaw)
31025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
31035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    status_t deps = -1;
31045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    deps += writePathsToFile(assets->getFullResPaths(), fp);
31055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (includeRaw) {
31065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        deps += writePathsToFile(assets->getFullAssetPaths(), fp);
31075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
31085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return deps;
3109d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
31105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)