Home | History | Annotate | Download | only in aapt
      1 //
      2 // Copyright 2006 The Android Open Source Project
      3 //
      4 // Build resource files from raw assets.
      5 //
      6 
      7 #ifndef RESOURCE_TABLE_H
      8 #define RESOURCE_TABLE_H
      9 
     10 #include <map>
     11 #include <queue>
     12 #include <set>
     13 
     14 #include "ConfigDescription.h"
     15 #include "ResourceFilter.h"
     16 #include "SourcePos.h"
     17 #include "StringPool.h"
     18 #include "Symbol.h"
     19 
     20 class XMLNode;
     21 class ResourceTable;
     22 
     23 enum {
     24     XML_COMPILE_STRIP_COMMENTS = 1<<0,
     25     XML_COMPILE_ASSIGN_ATTRIBUTE_IDS = 1<<1,
     26     XML_COMPILE_PARSE_VALUES = 1 << 2,
     27     XML_COMPILE_COMPACT_WHITESPACE = 1<<3,
     28     XML_COMPILE_STRIP_WHITESPACE = 1<<4,
     29     XML_COMPILE_STRIP_RAW_VALUES = 1<<5,
     30     XML_COMPILE_UTF8 = 1<<6,
     31 
     32     XML_COMPILE_STANDARD_RESOURCE =
     33             XML_COMPILE_STRIP_COMMENTS | XML_COMPILE_ASSIGN_ATTRIBUTE_IDS | XML_COMPILE_PARSE_VALUES
     34             | XML_COMPILE_STRIP_WHITESPACE | XML_COMPILE_STRIP_RAW_VALUES
     35 };
     36 
     37 status_t compileXmlFile(const Bundle* bundle,
     38                         const sp<AaptAssets>& assets,
     39                         const String16& resourceName,
     40                         const sp<AaptFile>& target,
     41                         ResourceTable* table,
     42                         int options = XML_COMPILE_STANDARD_RESOURCE);
     43 
     44 status_t compileXmlFile(const Bundle* bundle,
     45                         const sp<AaptAssets>& assets,
     46                         const String16& resourceName,
     47                         const sp<AaptFile>& target,
     48                         const sp<AaptFile>& outTarget,
     49                         ResourceTable* table,
     50                         int options = XML_COMPILE_STANDARD_RESOURCE);
     51 
     52 status_t compileXmlFile(const Bundle* bundle,
     53                         const sp<AaptAssets>& assets,
     54                         const String16& resourceName,
     55                         const sp<XMLNode>& xmlTree,
     56                         const sp<AaptFile>& target,
     57                         ResourceTable* table,
     58                         int options = XML_COMPILE_STANDARD_RESOURCE);
     59 
     60 status_t compileResourceFile(Bundle* bundle,
     61                              const sp<AaptAssets>& assets,
     62                              const sp<AaptFile>& in,
     63                              const ResTable_config& defParams,
     64                              const bool overwrite,
     65                              ResourceTable* outTable);
     66 
     67 struct AccessorCookie
     68 {
     69     SourcePos sourcePos;
     70     String8 attr;
     71     String8 value;
     72 
     73     AccessorCookie(const SourcePos&p, const String8& a, const String8& v)
     74         :sourcePos(p),
     75          attr(a),
     76          value(v)
     77     {
     78     }
     79 };
     80 
     81 // Holds the necessary information to compile the
     82 // resource.
     83 struct CompileResourceWorkItem {
     84     String16 resourceName;
     85     String8 resPath;
     86     sp<AaptFile> file;
     87     sp<XMLNode> xmlRoot;
     88     bool needsCompiling = true;
     89 };
     90 
     91 class ResourceTable : public ResTable::Accessor
     92 {
     93 public:
     94     // The type of package to build.
     95     enum PackageType {
     96         App,
     97         System,
     98         SharedLibrary,
     99         AppFeature
    100     };
    101 
    102     class Package;
    103     class Type;
    104     class Entry;
    105     class ConfigList;
    106 
    107     /**
    108      * Exposed for testing. Determines whether a versioned resource should be generated
    109      * based on the other available configurations for that resource.
    110      */
    111     static bool shouldGenerateVersionedResource(const sp<ConfigList>& configList,
    112                                                 const ConfigDescription& sourceConfig,
    113                                                 const int sdkVersionToGenerate);
    114 
    115     ResourceTable(Bundle* bundle, const String16& assetsPackage, PackageType type);
    116 
    117     const String16& getAssetsPackage() const {
    118         return mAssetsPackage;
    119     }
    120 
    121     /**
    122      * Returns the queue of resources that need to be compiled.
    123      * This is only used for resources that have been generated
    124      * during the compilation phase. If they were just added
    125      * to the AaptAssets, then they may be skipped over
    126      * and would mess up iteration order for the existing
    127      * resources.
    128      */
    129     std::queue<CompileResourceWorkItem>& getWorkQueue() {
    130         return mWorkQueue;
    131     }
    132 
    133     status_t addIncludedResources(Bundle* bundle, const sp<AaptAssets>& assets);
    134 
    135     status_t addPublic(const SourcePos& pos,
    136                        const String16& package,
    137                        const String16& type,
    138                        const String16& name,
    139                        const uint32_t ident);
    140 
    141     status_t addEntry(const SourcePos& pos,
    142                       const String16& package,
    143                       const String16& type,
    144                       const String16& name,
    145                       const String16& value,
    146                       const Vector<StringPool::entry_style_span>* style = NULL,
    147                       const ResTable_config* params = NULL,
    148                       const bool doSetIndex = false,
    149                       const int32_t format = ResTable_map::TYPE_ANY,
    150                       const bool overwrite = false);
    151 
    152     status_t startBag(const SourcePos& pos,
    153                     const String16& package,
    154                     const String16& type,
    155                     const String16& name,
    156                     const String16& bagParent,
    157                     const ResTable_config* params = NULL,
    158                     bool overlay = false,
    159                     bool replace = false,
    160                     bool isId = false);
    161 
    162     status_t addBag(const SourcePos& pos,
    163                     const String16& package,
    164                     const String16& type,
    165                     const String16& name,
    166                     const String16& bagParent,
    167                     const String16& bagKey,
    168                     const String16& value,
    169                     const Vector<StringPool::entry_style_span>* style = NULL,
    170                     const ResTable_config* params = NULL,
    171                     bool replace = false,
    172                     bool isId = false,
    173                     const int32_t format = ResTable_map::TYPE_ANY);
    174 
    175     bool hasBagOrEntry(const String16& package,
    176                        const String16& type,
    177                        const String16& name) const;
    178 
    179     bool hasBagOrEntry(const String16& package,
    180                        const String16& type,
    181                        const String16& name,
    182                        const ResTable_config& config) const;
    183 
    184     bool hasBagOrEntry(const String16& ref,
    185                        const String16* defType = NULL,
    186                        const String16* defPackage = NULL);
    187 
    188     bool appendComment(const String16& package,
    189                        const String16& type,
    190                        const String16& name,
    191                        const String16& comment,
    192                        bool onlyIfEmpty = false);
    193 
    194     bool appendTypeComment(const String16& package,
    195                            const String16& type,
    196                            const String16& name,
    197                            const String16& comment);
    198 
    199     void canAddEntry(const SourcePos& pos,
    200         const String16& package, const String16& type, const String16& name);
    201 
    202     size_t size() const;
    203     size_t numLocalResources() const;
    204     bool hasResources() const;
    205 
    206     bool versionForCompat(const Bundle* bundle, const String16& resourceName,
    207                           const sp<AaptFile>& file, const sp<XMLNode>& root);
    208 
    209     status_t modifyForCompat(const Bundle* bundle);
    210     status_t modifyForCompat(const Bundle* bundle,
    211                              const String16& resourceName,
    212                              const sp<AaptFile>& file,
    213                              const sp<XMLNode>& root);
    214 
    215     status_t processBundleFormat(const Bundle* bundle,
    216                                  const String16& resourceName,
    217                                  const sp<AaptFile>& file,
    218                                  const sp<XMLNode>& parent);
    219 
    220 
    221     sp<AaptFile> flatten(Bundle* bundle, const sp<const ResourceFilter>& filter,
    222             const bool isBase);
    223 
    224     static inline uint32_t makeResId(uint32_t packageId,
    225                                      uint32_t typeId,
    226                                      uint32_t nameId)
    227     {
    228         return nameId | (typeId<<16) | (packageId<<24);
    229     }
    230 
    231     static inline uint32_t getResId(const sp<Package>& p,
    232                                     const sp<Type>& t,
    233                                     uint32_t nameId);
    234 
    235     uint32_t getResId(const String16& package,
    236                       const String16& type,
    237                       const String16& name,
    238                       bool onlyPublic = true) const;
    239 
    240     uint32_t getResId(const String16& ref,
    241                       const String16* defType = NULL,
    242                       const String16* defPackage = NULL,
    243                       const char** outErrorMsg = NULL,
    244                       bool onlyPublic = true) const;
    245 
    246     static bool isValidResourceName(const String16& s);
    247 
    248     bool stringToValue(Res_value* outValue, StringPool* pool,
    249                        const String16& str,
    250                        bool preserveSpaces, bool coerceType,
    251                        uint32_t attrID,
    252                        const Vector<StringPool::entry_style_span>* style = NULL,
    253                        String16* outStr = NULL, void* accessorCookie = NULL,
    254                        uint32_t attrType = ResTable_map::TYPE_ANY,
    255                        const String8* configTypeName = NULL,
    256                        const ConfigDescription* config = NULL);
    257 
    258     status_t assignResourceIds();
    259     status_t addSymbols(const sp<AaptSymbols>& outSymbols = NULL,
    260                         bool skipSymbolsWithoutDefaultLocalization = false);
    261     void addLocalization(const String16& name, const String8& locale, const SourcePos& src);
    262     void addDefaultLocalization(const String16& name);
    263     status_t validateLocalizations(void);
    264 
    265     status_t flatten(Bundle* bundle, const sp<const ResourceFilter>& filter,
    266             const sp<AaptFile>& dest, const bool isBase);
    267     status_t flattenLibraryTable(const sp<AaptFile>& dest, const Vector<sp<Package> >& libs);
    268 
    269     void writePublicDefinitions(const String16& package, FILE* fp);
    270 
    271     virtual uint32_t getCustomResource(const String16& package,
    272                                        const String16& type,
    273                                        const String16& name) const;
    274     virtual uint32_t getCustomResourceWithCreation(const String16& package,
    275                                                    const String16& type,
    276                                                    const String16& name,
    277                                                    const bool createIfNeeded);
    278     virtual uint32_t getRemappedPackage(uint32_t origPackage) const;
    279     virtual bool getAttributeType(uint32_t attrID, uint32_t* outType);
    280     virtual bool getAttributeMin(uint32_t attrID, uint32_t* outMin);
    281     virtual bool getAttributeMax(uint32_t attrID, uint32_t* outMax);
    282     virtual bool getAttributeKeys(uint32_t attrID, Vector<String16>* outKeys);
    283     virtual bool getAttributeEnum(uint32_t attrID,
    284                                   const char16_t* name, size_t nameLen,
    285                                   Res_value* outValue);
    286     virtual bool getAttributeFlags(uint32_t attrID,
    287                                    const char16_t* name, size_t nameLen,
    288                                    Res_value* outValue);
    289     virtual uint32_t getAttributeL10N(uint32_t attrID);
    290 
    291     virtual bool getLocalizationSetting();
    292     virtual void reportError(void* accessorCookie, const char* fmt, ...);
    293 
    294     void setCurrentXmlPos(const SourcePos& pos) { mCurrentXmlPos = pos; }
    295 
    296     class Item {
    297     public:
    298         Item() : isId(false), format(ResTable_map::TYPE_ANY), bagKeyId(0), evaluating(false)
    299             { memset(&parsedValue, 0, sizeof(parsedValue)); }
    300         Item(const SourcePos& pos,
    301              bool _isId,
    302              const String16& _value,
    303              const Vector<StringPool::entry_style_span>* _style = NULL,
    304              int32_t format = ResTable_map::TYPE_ANY);
    305         Item(const Item& o) : sourcePos(o.sourcePos),
    306             isId(o.isId), value(o.value), style(o.style),
    307             format(o.format), bagKeyId(o.bagKeyId), evaluating(false) {
    308             memset(&parsedValue, 0, sizeof(parsedValue));
    309         }
    310         ~Item() { }
    311 
    312         Item& operator=(const Item& o) {
    313             sourcePos = o.sourcePos;
    314             isId = o.isId;
    315             value = o.value;
    316             style = o.style;
    317             format = o.format;
    318             bagKeyId = o.bagKeyId;
    319             parsedValue = o.parsedValue;
    320             return *this;
    321         }
    322 
    323         SourcePos                               sourcePos;
    324         mutable bool                            isId;
    325         String16                                value;
    326         Vector<StringPool::entry_style_span>    style;
    327         int32_t                                 format;
    328         uint32_t                                bagKeyId;
    329         mutable bool                            evaluating;
    330         Res_value                               parsedValue;
    331     };
    332 
    333     class Entry : public RefBase {
    334     public:
    335         Entry(const String16& name, const SourcePos& pos)
    336             : mName(name), mType(TYPE_UNKNOWN),
    337               mItemFormat(ResTable_map::TYPE_ANY), mNameIndex(-1), mPos(pos)
    338         { }
    339 
    340         Entry(const Entry& entry);
    341         Entry& operator=(const Entry& entry);
    342 
    343         virtual ~Entry() { }
    344 
    345         enum type {
    346             TYPE_UNKNOWN = 0,
    347             TYPE_ITEM,
    348             TYPE_BAG
    349         };
    350 
    351         String16 getName() const { return mName; }
    352         type getType() const { return mType; }
    353 
    354         void setParent(const String16& parent) { mParent = parent; }
    355         String16 getParent() const { return mParent; }
    356 
    357         status_t makeItABag(const SourcePos& sourcePos);
    358 
    359         status_t emptyBag(const SourcePos& sourcePos);
    360 
    361         status_t setItem(const SourcePos& pos,
    362                          const String16& value,
    363                          const Vector<StringPool::entry_style_span>* style = NULL,
    364                          int32_t format = ResTable_map::TYPE_ANY,
    365                          const bool overwrite = false);
    366 
    367         status_t addToBag(const SourcePos& pos,
    368                           const String16& key, const String16& value,
    369                           const Vector<StringPool::entry_style_span>* style = NULL,
    370                           bool replace=false, bool isId = false,
    371                           int32_t format = ResTable_map::TYPE_ANY);
    372 
    373         status_t removeFromBag(const String16& key);
    374 
    375         // Index of the entry's name string in the key pool.
    376         int32_t getNameIndex() const { return mNameIndex; }
    377         void setNameIndex(int32_t index) { mNameIndex = index; }
    378 
    379         const Item* getItem() const { return mType == TYPE_ITEM ? &mItem : NULL; }
    380         const KeyedVector<String16, Item>& getBag() const { return mBag; }
    381 
    382         status_t generateAttributes(ResourceTable* table,
    383                                     const String16& package);
    384 
    385         status_t assignResourceIds(ResourceTable* table,
    386                                    const String16& package);
    387 
    388         status_t prepareFlatten(StringPool* strings, ResourceTable* table,
    389                const String8* configTypeName, const ConfigDescription* config);
    390 
    391         status_t remapStringValue(StringPool* strings);
    392 
    393         ssize_t flatten(Bundle*, const sp<AaptFile>& data, bool isPublic);
    394 
    395         const SourcePos& getPos() const { return mPos; }
    396 
    397     private:
    398         String16 mName;
    399         String16 mParent;
    400         type mType;
    401         Item mItem;
    402         int32_t mItemFormat;
    403         KeyedVector<String16, Item> mBag;
    404         int32_t mNameIndex;
    405         uint32_t mParentId;
    406         SourcePos mPos;
    407     };
    408 
    409     class ConfigList : public RefBase {
    410     public:
    411         ConfigList(const String16& name, const SourcePos& pos)
    412             : mName(name), mPos(pos), mPublic(false), mEntryIndex(-1) { }
    413         virtual ~ConfigList() { }
    414 
    415         String16 getName() const { return mName; }
    416         const SourcePos& getPos() const { return mPos; }
    417 
    418         void appendComment(const String16& comment, bool onlyIfEmpty = false);
    419         const String16& getComment() const { return mComment; }
    420 
    421         void appendTypeComment(const String16& comment);
    422         const String16& getTypeComment() const { return mTypeComment; }
    423 
    424         // Index of this entry in its Type.
    425         int32_t getEntryIndex() const { return mEntryIndex; }
    426         void setEntryIndex(int32_t index) { mEntryIndex = index; }
    427 
    428         void setPublic(bool pub) { mPublic = pub; }
    429         bool getPublic() const { return mPublic; }
    430         void setPublicSourcePos(const SourcePos& pos) { mPublicSourcePos = pos; }
    431         const SourcePos& getPublicSourcePos() { return mPublicSourcePos; }
    432 
    433         void addEntry(const ResTable_config& config, const sp<Entry>& entry) {
    434             mEntries.add(config, entry);
    435         }
    436 
    437         void removeEntry(const ResTable_config& config) {
    438             mEntries.removeItem(config);
    439         }
    440 
    441         const DefaultKeyedVector<ConfigDescription, sp<Entry> >& getEntries() const { return mEntries; }
    442     private:
    443         const String16 mName;
    444         const SourcePos mPos;
    445         String16 mComment;
    446         String16 mTypeComment;
    447         bool mPublic;
    448         SourcePos mPublicSourcePos;
    449         int32_t mEntryIndex;
    450         DefaultKeyedVector<ConfigDescription, sp<Entry> > mEntries;
    451     };
    452 
    453     class Public {
    454     public:
    455         Public() : sourcePos(), ident(0) { }
    456         Public(const SourcePos& pos,
    457                const String16& _comment,
    458                uint32_t _ident)
    459             : sourcePos(pos),
    460             comment(_comment), ident(_ident) { }
    461         Public(const Public& o) : sourcePos(o.sourcePos),
    462             comment(o.comment), ident(o.ident) { }
    463         ~Public() { }
    464 
    465         Public& operator=(const Public& o) {
    466             sourcePos = o.sourcePos;
    467             comment = o.comment;
    468             ident = o.ident;
    469             return *this;
    470         }
    471 
    472         SourcePos   sourcePos;
    473         String16    comment;
    474         uint32_t    ident;
    475     };
    476 
    477     class Type : public RefBase {
    478     public:
    479         Type(const String16& name, const SourcePos& pos)
    480                 : mName(name), mFirstPublicSourcePos(NULL), mPublicIndex(-1), mIndex(-1), mPos(pos)
    481         { }
    482         virtual ~Type() { delete mFirstPublicSourcePos; }
    483 
    484         status_t addPublic(const SourcePos& pos,
    485                            const String16& name,
    486                            const uint32_t ident);
    487 
    488         void canAddEntry(const String16& name);
    489 
    490         String16 getName() const { return mName; }
    491         sp<Entry> getEntry(const String16& entry,
    492                            const SourcePos& pos,
    493                            const ResTable_config* config = NULL,
    494                            bool doSetIndex = false,
    495                            bool overlay = false,
    496                            bool autoAddOverlay = false);
    497 
    498         bool isPublic(const String16& entry) const {
    499             return mPublic.indexOfKey(entry) >= 0;
    500         }
    501 
    502         sp<ConfigList> removeEntry(const String16& entry);
    503 
    504         SortedVector<ConfigDescription> getUniqueConfigs() const;
    505 
    506         const SourcePos& getFirstPublicSourcePos() const { return *mFirstPublicSourcePos; }
    507 
    508         int32_t getPublicIndex() const { return mPublicIndex; }
    509 
    510         int32_t getIndex() const { return mIndex; }
    511         void setIndex(int32_t index) { mIndex = index; }
    512 
    513         status_t applyPublicEntryOrder();
    514 
    515         const DefaultKeyedVector<String16, sp<ConfigList> >& getConfigs() const { return mConfigs; }
    516         const Vector<sp<ConfigList> >& getOrderedConfigs() const { return mOrderedConfigs; }
    517         const SortedVector<String16>& getCanAddEntries() const { return mCanAddEntries; }
    518 
    519         const SourcePos& getPos() const { return mPos; }
    520 
    521     private:
    522         String16 mName;
    523         SourcePos* mFirstPublicSourcePos;
    524         DefaultKeyedVector<String16, Public> mPublic;
    525         DefaultKeyedVector<String16, sp<ConfigList> > mConfigs;
    526         Vector<sp<ConfigList> > mOrderedConfigs;
    527         SortedVector<String16> mCanAddEntries;
    528         int32_t mPublicIndex;
    529         int32_t mIndex;
    530         SourcePos mPos;
    531     };
    532 
    533     class Package : public RefBase {
    534     public:
    535         Package(const String16& name, size_t packageId);
    536         virtual ~Package() { }
    537 
    538         String16 getName() const { return mName; }
    539         sp<Type> getType(const String16& type,
    540                          const SourcePos& pos,
    541                          bool doSetIndex = false);
    542 
    543         size_t getAssignedId() const { return mPackageId; }
    544 
    545         const ResStringPool& getTypeStrings() const { return mTypeStrings; }
    546         uint32_t indexOfTypeString(const String16& s) const { return mTypeStringsMapping.valueFor(s); }
    547         const sp<AaptFile> getTypeStringsData() const { return mTypeStringsData; }
    548         status_t setTypeStrings(const sp<AaptFile>& data);
    549 
    550         const ResStringPool& getKeyStrings() const { return mKeyStrings; }
    551         uint32_t indexOfKeyString(const String16& s) const { return mKeyStringsMapping.valueFor(s); }
    552         const sp<AaptFile> getKeyStringsData() const { return mKeyStringsData; }
    553         status_t setKeyStrings(const sp<AaptFile>& data);
    554 
    555         status_t applyPublicTypeOrder();
    556 
    557         const DefaultKeyedVector<String16, sp<Type> >& getTypes() const { return mTypes; }
    558         const Vector<sp<Type> >& getOrderedTypes() const { return mOrderedTypes; }
    559 
    560         void movePrivateAttrs();
    561 
    562     private:
    563         status_t setStrings(const sp<AaptFile>& data,
    564                             ResStringPool* strings,
    565                             DefaultKeyedVector<String16, uint32_t>* mappings);
    566 
    567         const String16 mName;
    568         const size_t mPackageId;
    569         DefaultKeyedVector<String16, sp<Type> > mTypes;
    570         Vector<sp<Type> > mOrderedTypes;
    571         sp<AaptFile> mTypeStringsData;
    572         sp<AaptFile> mKeyStringsData;
    573         ResStringPool mTypeStrings;
    574         ResStringPool mKeyStrings;
    575         DefaultKeyedVector<String16, uint32_t> mTypeStringsMapping;
    576         DefaultKeyedVector<String16, uint32_t> mKeyStringsMapping;
    577     };
    578 
    579     void getDensityVaryingResources(KeyedVector<Symbol, Vector<SymbolDefinition> >& resources);
    580 
    581     /**
    582      * Make an attribute with the specified format. If another attribute with the same name but
    583      * different format exists, this method returns false. If the name is not taken, or if the
    584      * format is identical, this returns true.
    585      */
    586     bool makeAttribute(const String16& package,
    587                        const String16& name,
    588                        const SourcePos& source,
    589                        int32_t format,
    590                        const String16& comment,
    591                        bool appendComment);
    592 
    593     sp<Package> getPackage(const String16& package);
    594 
    595 private:
    596     void writePublicDefinitions(const String16& package, FILE* fp, bool pub);
    597     sp<Type> getType(const String16& package,
    598                      const String16& type,
    599                      const SourcePos& pos,
    600                      bool doSetIndex = false);
    601     sp<Entry> getEntry(const String16& package,
    602                        const String16& type,
    603                        const String16& name,
    604                        const SourcePos& pos,
    605                        bool overlay,
    606                        const ResTable_config* config = NULL,
    607                        bool doSetIndex = false);
    608     sp<const Entry> getEntry(uint32_t resID,
    609                              const ResTable_config* config = NULL) const;
    610     sp<ConfigList> getConfigList(const String16& package,
    611                                  const String16& type,
    612                                  const String16& name) const;
    613     const Item* getItem(uint32_t resID, uint32_t attrID) const;
    614     bool getItemValue(uint32_t resID, uint32_t attrID,
    615                       Res_value* outValue);
    616     int getPublicAttributeSdkLevel(uint32_t attrId) const;
    617 
    618     status_t processBundleFormatImpl(const Bundle* bundle,
    619                                      const String16& resourceName,
    620                                      const sp<AaptFile>& file,
    621                                      const sp<XMLNode>& parent,
    622                                      Vector<sp<XMLNode> >* namespaces);
    623 
    624     String16 mAssetsPackage;
    625     PackageType mPackageType;
    626     sp<AaptAssets> mAssets;
    627     uint32_t mTypeIdOffset;
    628     DefaultKeyedVector<String16, sp<Package> > mPackages;
    629     Vector<sp<Package> > mOrderedPackages;
    630     size_t mNumLocal;
    631     SourcePos mCurrentXmlPos;
    632     Bundle* mBundle;
    633 
    634     // key = string resource name, value = set of locales in which that name is defined
    635     std::map<String16, std::map<String8, SourcePos>> mLocalizations;
    636     // set of string resources names that have a default localization
    637     std::set<String16> mHasDefaultLocalization;
    638     std::queue<CompileResourceWorkItem> mWorkQueue;
    639 };
    640 
    641 #endif
    642