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