2 // Copyright 2006 The Android Open Source Project
4 // Build resource files from raw assets.
7 #ifndef RESOURCE_TABLE_H
8 #define RESOURCE_TABLE_H
14 #include "ConfigDescription.h"
15 #include "ResourceFilter.h"
16 #include "SourcePos.h"
17 #include "StringPool.h"
24 XML_COMPILE_STRIP_COMMENTS = 1<<0,
25 XML_COMPILE_ASSIGN_ATTRIBUTE_IDS = 1<<1,
26 XML_COMPILE_PARSE_VALUES = 1 << 2,
27 XML_COMPILE_COMPACT_WHITESPACE = 1<<3,
28 XML_COMPILE_STRIP_WHITESPACE = 1<<4,
29 XML_COMPILE_STRIP_RAW_VALUES = 1<<5,
30 XML_COMPILE_UTF8 = 1<<6,
32 XML_COMPILE_STANDARD_RESOURCE =
33 XML_COMPILE_STRIP_COMMENTS | XML_COMPILE_ASSIGN_ATTRIBUTE_IDS | XML_COMPILE_PARSE_VALUES
34 | XML_COMPILE_STRIP_WHITESPACE | XML_COMPILE_STRIP_RAW_VALUES
37 status_t compileXmlFile(const Bundle* bundle,
38 const sp<AaptAssets>& assets,
39 const String16& resourceName,
40 const sp<AaptFile>& target,
42 int options = XML_COMPILE_STANDARD_RESOURCE);
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,
50 int options = XML_COMPILE_STANDARD_RESOURCE);
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,
58 int options = XML_COMPILE_STANDARD_RESOURCE);
60 status_t compileResourceFile(Bundle* bundle,
61 const sp<AaptAssets>& assets,
62 const sp<AaptFile>& in,
63 const ResTable_config& defParams,
65 ResourceTable* outTable);
73 AccessorCookie(const SourcePos&p, const String8& a, const String8& v)
81 // Holds the necessary information to compile the
83 struct CompileResourceWorkItem {
84 String16 resourceName;
88 bool needsCompiling = true;
91 class ResourceTable : public ResTable::Accessor
94 // The type of package to build.
108 * Exposed for testing. Determines whether a versioned resource should be generated
109 * based on the other available configurations for that resource.
111 static bool shouldGenerateVersionedResource(const sp<ConfigList>& configList,
112 const ConfigDescription& sourceConfig,
113 const int sdkVersionToGenerate);
115 ResourceTable(Bundle* bundle, const String16& assetsPackage, PackageType type);
117 const String16& getAssetsPackage() const {
118 return mAssetsPackage;
122 * Returns the queue of resources that need to be compiled.
123 * This is only used for resources that have been generated
124 * during the compilation phase. If they were just added
125 * to the AaptAssets, then they may be skipped over
126 * and would mess up iteration order for the existing
129 std::queue<CompileResourceWorkItem>& getWorkQueue() {
133 status_t addIncludedResources(Bundle* bundle, const sp<AaptAssets>& assets);
135 status_t addPublic(const SourcePos& pos,
136 const String16& package,
137 const String16& type,
138 const String16& name,
139 const uint32_t ident);
141 status_t addEntry(const SourcePos& pos,
142 const String16& package,
143 const String16& type,
144 const String16& name,
145 const String16& value,
146 const Vector<StringPool::entry_style_span>* style = NULL,
147 const ResTable_config* params = NULL,
148 const bool doSetIndex = false,
149 const int32_t format = ResTable_map::TYPE_ANY,
150 const bool overwrite = false);
152 status_t startBag(const SourcePos& pos,
153 const String16& package,
154 const String16& type,
155 const String16& name,
156 const String16& bagParent,
157 const ResTable_config* params = NULL,
158 bool overlay = false,
159 bool replace = false,
162 status_t addBag(const SourcePos& pos,
163 const String16& package,
164 const String16& type,
165 const String16& name,
166 const String16& bagParent,
167 const String16& bagKey,
168 const String16& value,
169 const Vector<StringPool::entry_style_span>* style = NULL,
170 const ResTable_config* params = NULL,
171 bool replace = false,
173 const int32_t format = ResTable_map::TYPE_ANY);
175 bool hasBagOrEntry(const String16& package,
176 const String16& type,
177 const String16& name) const;
179 bool hasBagOrEntry(const String16& package,
180 const String16& type,
181 const String16& name,
182 const ResTable_config& config) const;
184 bool hasBagOrEntry(const String16& ref,
185 const String16* defType = NULL,
186 const String16* defPackage = NULL);
188 bool appendComment(const String16& package,
189 const String16& type,
190 const String16& name,
191 const String16& comment,
192 bool onlyIfEmpty = false);
194 bool appendTypeComment(const String16& package,
195 const String16& type,
196 const String16& name,
197 const String16& comment);
199 void canAddEntry(const SourcePos& pos,
200 const String16& package, const String16& type, const String16& name);
203 size_t numLocalResources() const;
204 bool hasResources() const;
206 status_t modifyForCompat(const Bundle* bundle);
207 status_t modifyForCompat(const Bundle* bundle,
208 const String16& resourceName,
209 const sp<AaptFile>& file,
210 const sp<XMLNode>& root);
212 status_t processBundleFormat(const Bundle* bundle,
213 const String16& resourceName,
214 const sp<AaptFile>& file,
215 const sp<XMLNode>& parent);
218 sp<AaptFile> flatten(Bundle* bundle, const sp<const ResourceFilter>& filter,
221 static inline uint32_t makeResId(uint32_t packageId,
225 return nameId | (typeId<<16) | (packageId<<24);
228 static inline uint32_t getResId(const sp<Package>& p,
232 uint32_t getResId(const String16& package,
233 const String16& type,
234 const String16& name,
235 bool onlyPublic = true) const;
237 uint32_t getResId(const String16& ref,
238 const String16* defType = NULL,
239 const String16* defPackage = NULL,
240 const char** outErrorMsg = NULL,
241 bool onlyPublic = true) const;
243 static bool isValidResourceName(const String16& s);
245 bool stringToValue(Res_value* outValue, StringPool* pool,
247 bool preserveSpaces, bool coerceType,
249 const Vector<StringPool::entry_style_span>* style = NULL,
250 String16* outStr = NULL, void* accessorCookie = NULL,
251 uint32_t attrType = ResTable_map::TYPE_ANY,
252 const String8* configTypeName = NULL,
253 const ConfigDescription* config = NULL);
255 status_t assignResourceIds();
256 status_t addSymbols(const sp<AaptSymbols>& outSymbols = NULL,
257 bool skipSymbolsWithoutDefaultLocalization = false);
258 void addLocalization(const String16& name, const String8& locale, const SourcePos& src);
259 void addDefaultLocalization(const String16& name);
260 status_t validateLocalizations(void);
262 status_t flatten(Bundle* bundle, const sp<const ResourceFilter>& filter,
263 const sp<AaptFile>& dest, const bool isBase);
264 status_t flattenLibraryTable(const sp<AaptFile>& dest, const Vector<sp<Package> >& libs);
266 void writePublicDefinitions(const String16& package, FILE* fp);
268 virtual uint32_t getCustomResource(const String16& package,
269 const String16& type,
270 const String16& name) const;
271 virtual uint32_t getCustomResourceWithCreation(const String16& package,
272 const String16& type,
273 const String16& name,
274 const bool createIfNeeded);
275 virtual uint32_t getRemappedPackage(uint32_t origPackage) const;
276 virtual bool getAttributeType(uint32_t attrID, uint32_t* outType);
277 virtual bool getAttributeMin(uint32_t attrID, uint32_t* outMin);
278 virtual bool getAttributeMax(uint32_t attrID, uint32_t* outMax);
279 virtual bool getAttributeKeys(uint32_t attrID, Vector<String16>* outKeys);
280 virtual bool getAttributeEnum(uint32_t attrID,
281 const char16_t* name, size_t nameLen,
282 Res_value* outValue);
283 virtual bool getAttributeFlags(uint32_t attrID,
284 const char16_t* name, size_t nameLen,
285 Res_value* outValue);
286 virtual uint32_t getAttributeL10N(uint32_t attrID);
288 virtual bool getLocalizationSetting();
289 virtual void reportError(void* accessorCookie, const char* fmt, ...);
291 void setCurrentXmlPos(const SourcePos& pos) { mCurrentXmlPos = pos; }
295 Item() : isId(false), format(ResTable_map::TYPE_ANY), bagKeyId(0), evaluating(false)
296 { memset(&parsedValue, 0, sizeof(parsedValue)); }
297 Item(const SourcePos& pos,
299 const String16& _value,
300 const Vector<StringPool::entry_style_span>* _style = NULL,
301 int32_t format = ResTable_map::TYPE_ANY);
302 Item(const Item& o) : sourcePos(o.sourcePos),
303 isId(o.isId), value(o.value), style(o.style),
304 format(o.format), bagKeyId(o.bagKeyId), evaluating(false) {
305 memset(&parsedValue, 0, sizeof(parsedValue));
309 Item& operator=(const Item& o) {
310 sourcePos = o.sourcePos;
315 bagKeyId = o.bagKeyId;
316 parsedValue = o.parsedValue;
323 Vector<StringPool::entry_style_span> style;
326 mutable bool evaluating;
327 Res_value parsedValue;
330 class Entry : public RefBase {
332 Entry(const String16& name, const SourcePos& pos)
333 : mName(name), mType(TYPE_UNKNOWN),
334 mItemFormat(ResTable_map::TYPE_ANY), mNameIndex(-1), mPos(pos)
337 Entry(const Entry& entry);
338 Entry& operator=(const Entry& entry);
348 String16 getName() const { return mName; }
349 type getType() const { return mType; }
351 void setParent(const String16& parent) { mParent = parent; }
352 String16 getParent() const { return mParent; }
354 status_t makeItABag(const SourcePos& sourcePos);
356 status_t emptyBag(const SourcePos& sourcePos);
358 status_t setItem(const SourcePos& pos,
359 const String16& value,
360 const Vector<StringPool::entry_style_span>* style = NULL,
361 int32_t format = ResTable_map::TYPE_ANY,
362 const bool overwrite = false);
364 status_t addToBag(const SourcePos& pos,
365 const String16& key, const String16& value,
366 const Vector<StringPool::entry_style_span>* style = NULL,
367 bool replace=false, bool isId = false,
368 int32_t format = ResTable_map::TYPE_ANY);
370 status_t removeFromBag(const String16& key);
372 // Index of the entry's name string in the key pool.
373 int32_t getNameIndex() const { return mNameIndex; }
374 void setNameIndex(int32_t index) { mNameIndex = index; }
376 const Item* getItem() const { return mType == TYPE_ITEM ? &mItem : NULL; }
377 const KeyedVector<String16, Item>& getBag() const { return mBag; }
379 status_t generateAttributes(ResourceTable* table,
380 const String16& package);
382 status_t assignResourceIds(ResourceTable* table,
383 const String16& package);
385 status_t prepareFlatten(StringPool* strings, ResourceTable* table,
386 const String8* configTypeName, const ConfigDescription* config);
388 status_t remapStringValue(StringPool* strings);
390 ssize_t flatten(Bundle*, const sp<AaptFile>& data, bool isPublic);
392 const SourcePos& getPos() const { return mPos; }
400 KeyedVector<String16, Item> mBag;
406 class ConfigList : public RefBase {
408 ConfigList(const String16& name, const SourcePos& pos)
409 : mName(name), mPos(pos), mPublic(false), mEntryIndex(-1) { }
410 virtual ~ConfigList() { }
412 String16 getName() const { return mName; }
413 const SourcePos& getPos() const { return mPos; }
415 void appendComment(const String16& comment, bool onlyIfEmpty = false);
416 const String16& getComment() const { return mComment; }
418 void appendTypeComment(const String16& comment);
419 const String16& getTypeComment() const { return mTypeComment; }
421 // Index of this entry in its Type.
422 int32_t getEntryIndex() const { return mEntryIndex; }
423 void setEntryIndex(int32_t index) { mEntryIndex = index; }
425 void setPublic(bool pub) { mPublic = pub; }
426 bool getPublic() const { return mPublic; }
427 void setPublicSourcePos(const SourcePos& pos) { mPublicSourcePos = pos; }
428 const SourcePos& getPublicSourcePos() { return mPublicSourcePos; }
430 void addEntry(const ResTable_config& config, const sp<Entry>& entry) {
431 mEntries.add(config, entry);
434 const DefaultKeyedVector<ConfigDescription, sp<Entry> >& getEntries() const { return mEntries; }
436 const String16 mName;
437 const SourcePos mPos;
439 String16 mTypeComment;
441 SourcePos mPublicSourcePos;
443 DefaultKeyedVector<ConfigDescription, sp<Entry> > mEntries;
448 Public() : sourcePos(), ident(0) { }
449 Public(const SourcePos& pos,
450 const String16& _comment,
453 comment(_comment), ident(_ident) { }
454 Public(const Public& o) : sourcePos(o.sourcePos),
455 comment(o.comment), ident(o.ident) { }
458 Public& operator=(const Public& o) {
459 sourcePos = o.sourcePos;
470 class Type : public RefBase {
472 Type(const String16& name, const SourcePos& pos)
473 : mName(name), mFirstPublicSourcePos(NULL), mPublicIndex(-1), mIndex(-1), mPos(pos)
475 virtual ~Type() { delete mFirstPublicSourcePos; }
477 status_t addPublic(const SourcePos& pos,
478 const String16& name,
479 const uint32_t ident);
481 void canAddEntry(const String16& name);
483 String16 getName() const { return mName; }
484 sp<Entry> getEntry(const String16& entry,
485 const SourcePos& pos,
486 const ResTable_config* config = NULL,
487 bool doSetIndex = false,
488 bool overlay = false,
489 bool autoAddOverlay = false);
491 bool isPublic(const String16& entry) const {
492 return mPublic.indexOfKey(entry) >= 0;
495 sp<ConfigList> removeEntry(const String16& entry);
497 SortedVector<ConfigDescription> getUniqueConfigs() const;
499 const SourcePos& getFirstPublicSourcePos() const { return *mFirstPublicSourcePos; }
501 int32_t getPublicIndex() const { return mPublicIndex; }
503 int32_t getIndex() const { return mIndex; }
504 void setIndex(int32_t index) { mIndex = index; }
506 status_t applyPublicEntryOrder();
508 const DefaultKeyedVector<String16, sp<ConfigList> >& getConfigs() const { return mConfigs; }
509 const Vector<sp<ConfigList> >& getOrderedConfigs() const { return mOrderedConfigs; }
510 const SortedVector<String16>& getCanAddEntries() const { return mCanAddEntries; }
512 const SourcePos& getPos() const { return mPos; }
516 SourcePos* mFirstPublicSourcePos;
517 DefaultKeyedVector<String16, Public> mPublic;
518 DefaultKeyedVector<String16, sp<ConfigList> > mConfigs;
519 Vector<sp<ConfigList> > mOrderedConfigs;
520 SortedVector<String16> mCanAddEntries;
521 int32_t mPublicIndex;
526 class Package : public RefBase {
528 Package(const String16& name, size_t packageId);
529 virtual ~Package() { }
531 String16 getName() const { return mName; }
532 sp<Type> getType(const String16& type,
533 const SourcePos& pos,
534 bool doSetIndex = false);
536 size_t getAssignedId() const { return mPackageId; }
538 const ResStringPool& getTypeStrings() const { return mTypeStrings; }
539 uint32_t indexOfTypeString(const String16& s) const { return mTypeStringsMapping.valueFor(s); }
540 const sp<AaptFile> getTypeStringsData() const { return mTypeStringsData; }
541 status_t setTypeStrings(const sp<AaptFile>& data);
543 const ResStringPool& getKeyStrings() const { return mKeyStrings; }
544 uint32_t indexOfKeyString(const String16& s) const { return mKeyStringsMapping.valueFor(s); }
545 const sp<AaptFile> getKeyStringsData() const { return mKeyStringsData; }
546 status_t setKeyStrings(const sp<AaptFile>& data);
548 status_t applyPublicTypeOrder();
550 const DefaultKeyedVector<String16, sp<Type> >& getTypes() const { return mTypes; }
551 const Vector<sp<Type> >& getOrderedTypes() const { return mOrderedTypes; }
553 void movePrivateAttrs();
556 status_t setStrings(const sp<AaptFile>& data,
557 ResStringPool* strings,
558 DefaultKeyedVector<String16, uint32_t>* mappings);
560 const String16 mName;
561 const size_t mPackageId;
562 DefaultKeyedVector<String16, sp<Type> > mTypes;
563 Vector<sp<Type> > mOrderedTypes;
564 sp<AaptFile> mTypeStringsData;
565 sp<AaptFile> mKeyStringsData;
566 ResStringPool mTypeStrings;
567 ResStringPool mKeyStrings;
568 DefaultKeyedVector<String16, uint32_t> mTypeStringsMapping;
569 DefaultKeyedVector<String16, uint32_t> mKeyStringsMapping;
572 void getDensityVaryingResources(KeyedVector<Symbol, Vector<SymbolDefinition> >& resources);
575 * Make an attribute with the specified format. If another attribute with the same name but
576 * different format exists, this method returns false. If the name is not taken, or if the
577 * format is identical, this returns true.
579 bool makeAttribute(const String16& package,
580 const String16& name,
581 const SourcePos& source,
583 const String16& comment,
587 void writePublicDefinitions(const String16& package, FILE* fp, bool pub);
588 sp<Package> getPackage(const String16& package);
589 sp<Type> getType(const String16& package,
590 const String16& type,
591 const SourcePos& pos,
592 bool doSetIndex = false);
593 sp<Entry> getEntry(const String16& package,
594 const String16& type,
595 const String16& name,
596 const SourcePos& pos,
598 const ResTable_config* config = NULL,
599 bool doSetIndex = false);
600 sp<const Entry> getEntry(uint32_t resID,
601 const ResTable_config* config = NULL) const;
602 sp<ConfigList> getConfigList(const String16& package,
603 const String16& type,
604 const String16& name) const;
605 const Item* getItem(uint32_t resID, uint32_t attrID) const;
606 bool getItemValue(uint32_t resID, uint32_t attrID,
607 Res_value* outValue);
608 int getPublicAttributeSdkLevel(uint32_t attrId) const;
610 status_t processBundleFormatImpl(const Bundle* bundle,
611 const String16& resourceName,
612 const sp<AaptFile>& file,
613 const sp<XMLNode>& parent,
614 Vector<sp<XMLNode> >* namespaces);
616 String16 mAssetsPackage;
617 PackageType mPackageType;
618 sp<AaptAssets> mAssets;
619 uint32_t mTypeIdOffset;
620 DefaultKeyedVector<String16, sp<Package> > mPackages;
621 Vector<sp<Package> > mOrderedPackages;
623 SourcePos mCurrentXmlPos;
626 // key = string resource name, value = set of locales in which that name is defined
627 std::map<String16, std::map<String8, SourcePos>> mLocalizations;
628 // set of string resources names that have a default localization
629 std::set<String16> mHasDefaultLocalization;
630 std::queue<CompileResourceWorkItem> mWorkQueue;