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