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