blob: eac5dd3f919fbb465b1099ae7b6a93070b8e6e03 [file] [log] [blame]
Adam Lesinski282e1812014-01-23 18:17:42 -08001//
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
Adam Lesinskifab50872014-04-16 14:40:42 -070010#include "ConfigDescription.h"
Adam Lesinski282e1812014-01-23 18:17:42 -080011#include "StringPool.h"
12#include "SourcePos.h"
Adam Lesinskifab50872014-04-16 14:40:42 -070013#include "ResourceFilter.h"
Adam Lesinski282e1812014-01-23 18:17:42 -080014
Adam Lesinski282e1812014-01-23 18:17:42 -080015#include <map>
Adam Lesinskie572c012014-09-19 15:10:04 -070016#include <queue>
17#include <set>
Adam Lesinski282e1812014-01-23 18:17:42 -080018
19using namespace std;
20
21class XMLNode;
22class ResourceTable;
23
24enum {
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
Adam Lesinskie572c012014-09-19 15:10:04 -070037status_t compileXmlFile(const Bundle* bundle,
38 const sp<AaptAssets>& assets,
39 const String16& resourceName,
Adam Lesinski282e1812014-01-23 18:17:42 -080040 const sp<AaptFile>& target,
41 ResourceTable* table,
42 int options = XML_COMPILE_STANDARD_RESOURCE);
43
Adam Lesinskie572c012014-09-19 15:10:04 -070044status_t compileXmlFile(const Bundle* bundle,
45 const sp<AaptAssets>& assets,
46 const String16& resourceName,
Adam Lesinski282e1812014-01-23 18:17:42 -080047 const sp<AaptFile>& target,
48 const sp<AaptFile>& outTarget,
49 ResourceTable* table,
50 int options = XML_COMPILE_STANDARD_RESOURCE);
51
Adam Lesinskie572c012014-09-19 15:10:04 -070052status_t compileXmlFile(const Bundle* bundle,
53 const sp<AaptAssets>& assets,
54 const String16& resourceName,
Adam Lesinski282e1812014-01-23 18:17:42 -080055 const sp<XMLNode>& xmlTree,
56 const sp<AaptFile>& target,
57 ResourceTable* table,
58 int options = XML_COMPILE_STANDARD_RESOURCE);
59
60status_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
67struct 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
Adam Lesinskie572c012014-09-19 15:10:04 -070081// Holds the necessary information to compile the
82// resource.
83struct CompileResourceWorkItem {
84 String16 resourceName;
85 String8 resPath;
86 sp<AaptFile> file;
87};
88
Adam Lesinski282e1812014-01-23 18:17:42 -080089class ResourceTable : public ResTable::Accessor
90{
91public:
Adam Lesinski833f3cc2014-06-18 15:06:01 -070092 // The type of package to build.
93 enum PackageType {
94 App,
95 System,
96 SharedLibrary,
97 AppFeature
98 };
99
Adam Lesinski282e1812014-01-23 18:17:42 -0800100 class Package;
101 class Type;
102 class Entry;
103
Adam Lesinski833f3cc2014-06-18 15:06:01 -0700104 ResourceTable(Bundle* bundle, const String16& assetsPackage, PackageType type);
105
106 const String16& getAssetsPackage() const {
107 return mAssetsPackage;
108 }
Adam Lesinski282e1812014-01-23 18:17:42 -0800109
Adam Lesinskie572c012014-09-19 15:10:04 -0700110 /**
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
Adam Lesinski282e1812014-01-23 18:17:42 -0800122 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
Adam Lesinski82a2dd82014-09-17 18:34:15 -0700195 status_t modifyForCompat(const Bundle* bundle);
Adam Lesinskie572c012014-09-19 15:10:04 -0700196 status_t modifyForCompat(const Bundle* bundle,
197 const String16& resourceName,
198 const sp<AaptFile>& file,
199 const sp<XMLNode>& root);
Adam Lesinski82a2dd82014-09-17 18:34:15 -0700200
Adam Lesinski27f69f42014-08-21 13:19:12 -0700201 sp<AaptFile> flatten(Bundle* bundle, const sp<const ResourceFilter>& filter,
202 const bool isBase);
Adam Lesinski282e1812014-01-23 18:17:42 -0800203
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);
Adam Lesinskia01a9372014-03-20 18:04:57 -0700240 void addLocalization(const String16& name, const String8& locale, const SourcePos& src);
Adam Lesinski282e1812014-01-23 18:17:42 -0800241 status_t validateLocalizations(void);
242
Adam Lesinski27f69f42014-08-21 13:19:12 -0700243 status_t flatten(Bundle* bundle, const sp<const ResourceFilter>& filter,
244 const sp<AaptFile>& dest, const bool isBase);
Adam Lesinskide898ff2014-01-29 18:20:45 -0800245 status_t flattenLibraryTable(const sp<AaptFile>& dest, const Vector<sp<Package> >& libs);
Adam Lesinski282e1812014-01-23 18:17:42 -0800246
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 { }
Adam Lesinski82a2dd82014-09-17 18:34:15 -0700317
318 Entry(const Entry& entry);
Adam Lesinski978ab9d2014-09-24 19:02:52 -0700319 Entry& operator=(const Entry& entry);
Adam Lesinski82a2dd82014-09-17 18:34:15 -0700320
Adam Lesinski282e1812014-01-23 18:17:42 -0800321 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
Adam Lesinski82a2dd82014-09-17 18:34:15 -0700351 status_t removeFromBag(const String16& key);
352
Adam Lesinski282e1812014-01-23 18:17:42 -0800353 // 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:
Adam Lesinski833f3cc2014-06-18 15:06:01 -0700504 Package(const String16& name, size_t packageId);
Adam Lesinski282e1812014-01-23 18:17:42 -0800505 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
Adam Lesinski833f3cc2014-06-18 15:06:01 -0700512 size_t getAssignedId() const { return mPackageId; }
Adam Lesinski282e1812014-01-23 18:17:42 -0800513
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;
Adam Lesinski833f3cc2014-06-18 15:06:01 -0700535 const size_t mPackageId;
Adam Lesinski282e1812014-01-23 18:17:42 -0800536 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
546private:
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;
Adam Lesinskie572c012014-09-19 15:10:04 -0700562 sp<ConfigList> getConfigList(const String16& package,
563 const String16& type,
564 const String16& name) const;
Adam Lesinski282e1812014-01-23 18:17:42 -0800565 const Item* getItem(uint32_t resID, uint32_t attrID) const;
566 bool getItemValue(uint32_t resID, uint32_t attrID,
567 Res_value* outValue);
Adam Lesinski82a2dd82014-09-17 18:34:15 -0700568 bool isAttributeFromL(uint32_t attrId);
Adam Lesinski282e1812014-01-23 18:17:42 -0800569
570
571 String16 mAssetsPackage;
Adam Lesinski833f3cc2014-06-18 15:06:01 -0700572 PackageType mPackageType;
Adam Lesinski282e1812014-01-23 18:17:42 -0800573 sp<AaptAssets> mAssets;
Adam Lesinski833f3cc2014-06-18 15:06:01 -0700574 uint32_t mTypeIdOffset;
Adam Lesinski282e1812014-01-23 18:17:42 -0800575 DefaultKeyedVector<String16, sp<Package> > mPackages;
576 Vector<sp<Package> > mOrderedPackages;
Adam Lesinski282e1812014-01-23 18:17:42 -0800577 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
Adam Lesinskia01a9372014-03-20 18:04:57 -0700582 map<String16, map<String8, SourcePos> > mLocalizations;
Adam Lesinskie572c012014-09-19 15:10:04 -0700583 queue<CompileResourceWorkItem> mWorkQueue;
Adam Lesinski282e1812014-01-23 18:17:42 -0800584};
585
586#endif