blob: c548a851fb2e659b269c880f408d8ad322d390fb [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);
319
Adam Lesinski282e1812014-01-23 18:17:42 -0800320 virtual ~Entry() { }
321
322 enum type {
323 TYPE_UNKNOWN = 0,
324 TYPE_ITEM,
325 TYPE_BAG
326 };
327
328 String16 getName() const { return mName; }
329 type getType() const { return mType; }
330
331 void setParent(const String16& parent) { mParent = parent; }
332 String16 getParent() const { return mParent; }
333
334 status_t makeItABag(const SourcePos& sourcePos);
335
336 status_t emptyBag(const SourcePos& sourcePos);
337
338 status_t setItem(const SourcePos& pos,
339 const String16& value,
340 const Vector<StringPool::entry_style_span>* style = NULL,
341 int32_t format = ResTable_map::TYPE_ANY,
342 const bool overwrite = false);
343
344 status_t addToBag(const SourcePos& pos,
345 const String16& key, const String16& value,
346 const Vector<StringPool::entry_style_span>* style = NULL,
347 bool replace=false, bool isId = false,
348 int32_t format = ResTable_map::TYPE_ANY);
349
Adam Lesinski82a2dd82014-09-17 18:34:15 -0700350 status_t removeFromBag(const String16& key);
351
Adam Lesinski282e1812014-01-23 18:17:42 -0800352 // Index of the entry's name string in the key pool.
353 int32_t getNameIndex() const { return mNameIndex; }
354 void setNameIndex(int32_t index) { mNameIndex = index; }
355
356 const Item* getItem() const { return mType == TYPE_ITEM ? &mItem : NULL; }
357 const KeyedVector<String16, Item>& getBag() const { return mBag; }
358
359 status_t generateAttributes(ResourceTable* table,
360 const String16& package);
361
362 status_t assignResourceIds(ResourceTable* table,
363 const String16& package);
364
365 status_t prepareFlatten(StringPool* strings, ResourceTable* table,
366 const String8* configTypeName, const ConfigDescription* config);
367
368 status_t remapStringValue(StringPool* strings);
369
370 ssize_t flatten(Bundle*, const sp<AaptFile>& data, bool isPublic);
371
372 const SourcePos& getPos() const { return mPos; }
373
374 private:
375 String16 mName;
376 String16 mParent;
377 type mType;
378 Item mItem;
379 int32_t mItemFormat;
380 KeyedVector<String16, Item> mBag;
381 int32_t mNameIndex;
382 uint32_t mParentId;
383 SourcePos mPos;
384 };
385
386 class ConfigList : public RefBase {
387 public:
388 ConfigList(const String16& name, const SourcePos& pos)
389 : mName(name), mPos(pos), mPublic(false), mEntryIndex(-1) { }
390 virtual ~ConfigList() { }
391
392 String16 getName() const { return mName; }
393 const SourcePos& getPos() const { return mPos; }
394
395 void appendComment(const String16& comment, bool onlyIfEmpty = false);
396 const String16& getComment() const { return mComment; }
397
398 void appendTypeComment(const String16& comment);
399 const String16& getTypeComment() const { return mTypeComment; }
400
401 // Index of this entry in its Type.
402 int32_t getEntryIndex() const { return mEntryIndex; }
403 void setEntryIndex(int32_t index) { mEntryIndex = index; }
404
405 void setPublic(bool pub) { mPublic = pub; }
406 bool getPublic() const { return mPublic; }
407 void setPublicSourcePos(const SourcePos& pos) { mPublicSourcePos = pos; }
408 const SourcePos& getPublicSourcePos() { return mPublicSourcePos; }
409
410 void addEntry(const ResTable_config& config, const sp<Entry>& entry) {
411 mEntries.add(config, entry);
412 }
413
414 const DefaultKeyedVector<ConfigDescription, sp<Entry> >& getEntries() const { return mEntries; }
415 private:
416 const String16 mName;
417 const SourcePos mPos;
418 String16 mComment;
419 String16 mTypeComment;
420 bool mPublic;
421 SourcePos mPublicSourcePos;
422 int32_t mEntryIndex;
423 DefaultKeyedVector<ConfigDescription, sp<Entry> > mEntries;
424 };
425
426 class Public {
427 public:
428 Public() : sourcePos(), ident(0) { }
429 Public(const SourcePos& pos,
430 const String16& _comment,
431 uint32_t _ident)
432 : sourcePos(pos),
433 comment(_comment), ident(_ident) { }
434 Public(const Public& o) : sourcePos(o.sourcePos),
435 comment(o.comment), ident(o.ident) { }
436 ~Public() { }
437
438 Public& operator=(const Public& o) {
439 sourcePos = o.sourcePos;
440 comment = o.comment;
441 ident = o.ident;
442 return *this;
443 }
444
445 SourcePos sourcePos;
446 String16 comment;
447 uint32_t ident;
448 };
449
450 class Type : public RefBase {
451 public:
452 Type(const String16& name, const SourcePos& pos)
453 : mName(name), mFirstPublicSourcePos(NULL), mPublicIndex(-1), mIndex(-1), mPos(pos)
454 { }
455 virtual ~Type() { delete mFirstPublicSourcePos; }
456
457 status_t addPublic(const SourcePos& pos,
458 const String16& name,
459 const uint32_t ident);
460
461 void canAddEntry(const String16& name);
462
463 String16 getName() const { return mName; }
464 sp<Entry> getEntry(const String16& entry,
465 const SourcePos& pos,
466 const ResTable_config* config = NULL,
467 bool doSetIndex = false,
468 bool overlay = false,
469 bool autoAddOverlay = false);
470
471 const SourcePos& getFirstPublicSourcePos() const { return *mFirstPublicSourcePos; }
472
473 int32_t getPublicIndex() const { return mPublicIndex; }
474
475 int32_t getIndex() const { return mIndex; }
476 void setIndex(int32_t index) { mIndex = index; }
477
478 status_t applyPublicEntryOrder();
479
480 const SortedVector<ConfigDescription>& getUniqueConfigs() const { return mUniqueConfigs; }
481
482 const DefaultKeyedVector<String16, sp<ConfigList> >& getConfigs() const { return mConfigs; }
483 const Vector<sp<ConfigList> >& getOrderedConfigs() const { return mOrderedConfigs; }
484
485 const SortedVector<String16>& getCanAddEntries() const { return mCanAddEntries; }
486
487 const SourcePos& getPos() const { return mPos; }
488 private:
489 String16 mName;
490 SourcePos* mFirstPublicSourcePos;
491 DefaultKeyedVector<String16, Public> mPublic;
492 SortedVector<ConfigDescription> mUniqueConfigs;
493 DefaultKeyedVector<String16, sp<ConfigList> > mConfigs;
494 Vector<sp<ConfigList> > mOrderedConfigs;
495 SortedVector<String16> mCanAddEntries;
496 int32_t mPublicIndex;
497 int32_t mIndex;
498 SourcePos mPos;
499 };
500
501 class Package : public RefBase {
502 public:
Adam Lesinski833f3cc2014-06-18 15:06:01 -0700503 Package(const String16& name, size_t packageId);
Adam Lesinski282e1812014-01-23 18:17:42 -0800504 virtual ~Package() { }
505
506 String16 getName() const { return mName; }
507 sp<Type> getType(const String16& type,
508 const SourcePos& pos,
509 bool doSetIndex = false);
510
Adam Lesinski833f3cc2014-06-18 15:06:01 -0700511 size_t getAssignedId() const { return mPackageId; }
Adam Lesinski282e1812014-01-23 18:17:42 -0800512
513 const ResStringPool& getTypeStrings() const { return mTypeStrings; }
514 uint32_t indexOfTypeString(const String16& s) const { return mTypeStringsMapping.valueFor(s); }
515 const sp<AaptFile> getTypeStringsData() const { return mTypeStringsData; }
516 status_t setTypeStrings(const sp<AaptFile>& data);
517
518 const ResStringPool& getKeyStrings() const { return mKeyStrings; }
519 uint32_t indexOfKeyString(const String16& s) const { return mKeyStringsMapping.valueFor(s); }
520 const sp<AaptFile> getKeyStringsData() const { return mKeyStringsData; }
521 status_t setKeyStrings(const sp<AaptFile>& data);
522
523 status_t applyPublicTypeOrder();
524
525 const DefaultKeyedVector<String16, sp<Type> >& getTypes() const { return mTypes; }
526 const Vector<sp<Type> >& getOrderedTypes() const { return mOrderedTypes; }
527
528 private:
529 status_t setStrings(const sp<AaptFile>& data,
530 ResStringPool* strings,
531 DefaultKeyedVector<String16, uint32_t>* mappings);
532
533 const String16 mName;
Adam Lesinski833f3cc2014-06-18 15:06:01 -0700534 const size_t mPackageId;
Adam Lesinski282e1812014-01-23 18:17:42 -0800535 DefaultKeyedVector<String16, sp<Type> > mTypes;
536 Vector<sp<Type> > mOrderedTypes;
537 sp<AaptFile> mTypeStringsData;
538 sp<AaptFile> mKeyStringsData;
539 ResStringPool mTypeStrings;
540 ResStringPool mKeyStrings;
541 DefaultKeyedVector<String16, uint32_t> mTypeStringsMapping;
542 DefaultKeyedVector<String16, uint32_t> mKeyStringsMapping;
543 };
544
545private:
546 void writePublicDefinitions(const String16& package, FILE* fp, bool pub);
547 sp<Package> getPackage(const String16& package);
548 sp<Type> getType(const String16& package,
549 const String16& type,
550 const SourcePos& pos,
551 bool doSetIndex = false);
552 sp<Entry> getEntry(const String16& package,
553 const String16& type,
554 const String16& name,
555 const SourcePos& pos,
556 bool overlay,
557 const ResTable_config* config = NULL,
558 bool doSetIndex = false);
559 sp<const Entry> getEntry(uint32_t resID,
560 const ResTable_config* config = NULL) const;
Adam Lesinskie572c012014-09-19 15:10:04 -0700561 sp<ConfigList> getConfigList(const String16& package,
562 const String16& type,
563 const String16& name) const;
Adam Lesinski282e1812014-01-23 18:17:42 -0800564 const Item* getItem(uint32_t resID, uint32_t attrID) const;
565 bool getItemValue(uint32_t resID, uint32_t attrID,
566 Res_value* outValue);
Adam Lesinski82a2dd82014-09-17 18:34:15 -0700567 bool isAttributeFromL(uint32_t attrId);
Adam Lesinski282e1812014-01-23 18:17:42 -0800568
569
570 String16 mAssetsPackage;
Adam Lesinski833f3cc2014-06-18 15:06:01 -0700571 PackageType mPackageType;
Adam Lesinski282e1812014-01-23 18:17:42 -0800572 sp<AaptAssets> mAssets;
Adam Lesinski833f3cc2014-06-18 15:06:01 -0700573 uint32_t mTypeIdOffset;
Adam Lesinski282e1812014-01-23 18:17:42 -0800574 DefaultKeyedVector<String16, sp<Package> > mPackages;
575 Vector<sp<Package> > mOrderedPackages;
Adam Lesinski282e1812014-01-23 18:17:42 -0800576 size_t mNumLocal;
577 SourcePos mCurrentXmlPos;
578 Bundle* mBundle;
579
580 // key = string resource name, value = set of locales in which that name is defined
Adam Lesinskia01a9372014-03-20 18:04:57 -0700581 map<String16, map<String8, SourcePos> > mLocalizations;
Adam Lesinskie572c012014-09-19 15:10:04 -0700582 queue<CompileResourceWorkItem> mWorkQueue;
Adam Lesinski282e1812014-01-23 18:17:42 -0800583};
584
585#endif