• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
AccessorCookieAccessorCookie73     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 
getAssetsPackage()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      */
getWorkQueue()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 
makeResId(uint32_t packageId,uint32_t typeId,uint32_t nameId)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 
setCurrentXmlPos(const SourcePos & pos)272     void setCurrentXmlPos(const SourcePos& pos) { mCurrentXmlPos = pos; }
273 
274     class Item {
275     public:
Item()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);
Item(const Item & o)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         }
~Item()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:
Entry(const String16 & name,const SourcePos & pos)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 
~Entry()321         virtual ~Entry() { }
322 
323         enum type {
324             TYPE_UNKNOWN = 0,
325             TYPE_ITEM,
326             TYPE_BAG
327         };
328 
getName()329         String16 getName() const { return mName; }
getType()330         type getType() const { return mType; }
331 
setParent(const String16 & parent)332         void setParent(const String16& parent) { mParent = parent; }
getParent()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.
getNameIndex()354         int32_t getNameIndex() const { return mNameIndex; }
setNameIndex(int32_t index)355         void setNameIndex(int32_t index) { mNameIndex = index; }
356 
getItem()357         const Item* getItem() const { return mType == TYPE_ITEM ? &mItem : NULL; }
getBag()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 
getPos()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:
ConfigList(const String16 & name,const SourcePos & pos)389         ConfigList(const String16& name, const SourcePos& pos)
390             : mName(name), mPos(pos), mPublic(false), mEntryIndex(-1) { }
~ConfigList()391         virtual ~ConfigList() { }
392 
getName()393         String16 getName() const { return mName; }
getPos()394         const SourcePos& getPos() const { return mPos; }
395 
396         void appendComment(const String16& comment, bool onlyIfEmpty = false);
getComment()397         const String16& getComment() const { return mComment; }
398 
399         void appendTypeComment(const String16& comment);
getTypeComment()400         const String16& getTypeComment() const { return mTypeComment; }
401 
402         // Index of this entry in its Type.
getEntryIndex()403         int32_t getEntryIndex() const { return mEntryIndex; }
setEntryIndex(int32_t index)404         void setEntryIndex(int32_t index) { mEntryIndex = index; }
405 
setPublic(bool pub)406         void setPublic(bool pub) { mPublic = pub; }
getPublic()407         bool getPublic() const { return mPublic; }
setPublicSourcePos(const SourcePos & pos)408         void setPublicSourcePos(const SourcePos& pos) { mPublicSourcePos = pos; }
getPublicSourcePos()409         const SourcePos& getPublicSourcePos() { return mPublicSourcePos; }
410 
addEntry(const ResTable_config & config,const sp<Entry> & entry)411         void addEntry(const ResTable_config& config, const sp<Entry>& entry) {
412             mEntries.add(config, entry);
413         }
414 
getEntries()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:
Public()429         Public() : sourcePos(), ident(0) { }
Public(const SourcePos & pos,const String16 & _comment,uint32_t _ident)430         Public(const SourcePos& pos,
431                const String16& _comment,
432                uint32_t _ident)
433             : sourcePos(pos),
434             comment(_comment), ident(_ident) { }
Public(const Public & o)435         Public(const Public& o) : sourcePos(o.sourcePos),
436             comment(o.comment), ident(o.ident) { }
~Public()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:
Type(const String16 & name,const SourcePos & pos)453         Type(const String16& name, const SourcePos& pos)
454                 : mName(name), mFirstPublicSourcePos(NULL), mPublicIndex(-1), mIndex(-1), mPos(pos)
455         { }
~Type()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 
getName()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 
getFirstPublicSourcePos()472         const SourcePos& getFirstPublicSourcePos() const { return *mFirstPublicSourcePos; }
473 
getPublicIndex()474         int32_t getPublicIndex() const { return mPublicIndex; }
475 
getIndex()476         int32_t getIndex() const { return mIndex; }
setIndex(int32_t index)477         void setIndex(int32_t index) { mIndex = index; }
478 
479         status_t applyPublicEntryOrder();
480 
getUniqueConfigs()481         const SortedVector<ConfigDescription>& getUniqueConfigs() const { return mUniqueConfigs; }
482 
getConfigs()483         const DefaultKeyedVector<String16, sp<ConfigList> >& getConfigs() const { return mConfigs; }
getOrderedConfigs()484         const Vector<sp<ConfigList> >& getOrderedConfigs() const { return mOrderedConfigs; }
485 
getCanAddEntries()486         const SortedVector<String16>& getCanAddEntries() const { return mCanAddEntries; }
487 
getPos()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);
~Package()505         virtual ~Package() { }
506 
getName()507         String16 getName() const { return mName; }
508         sp<Type> getType(const String16& type,
509                          const SourcePos& pos,
510                          bool doSetIndex = false);
511 
getAssignedId()512         size_t getAssignedId() const { return mPackageId; }
513 
getTypeStrings()514         const ResStringPool& getTypeStrings() const { return mTypeStrings; }
indexOfTypeString(const String16 & s)515         uint32_t indexOfTypeString(const String16& s) const { return mTypeStringsMapping.valueFor(s); }
getTypeStringsData()516         const sp<AaptFile> getTypeStringsData() const { return mTypeStringsData; }
517         status_t setTypeStrings(const sp<AaptFile>& data);
518 
getKeyStrings()519         const ResStringPool& getKeyStrings() const { return mKeyStrings; }
indexOfKeyString(const String16 & s)520         uint32_t indexOfKeyString(const String16& s) const { return mKeyStringsMapping.valueFor(s); }
getKeyStringsData()521         const sp<AaptFile> getKeyStringsData() const { return mKeyStringsData; }
522         status_t setKeyStrings(const sp<AaptFile>& data);
523 
524         status_t applyPublicTypeOrder();
525 
getTypes()526         const DefaultKeyedVector<String16, sp<Type> >& getTypes() const { return mTypes; }
getOrderedTypes()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