blob: 025a868254ee1e76734a33ef22bff1423001b4cb [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
15#include <set>
16#include <map>
17
18using namespace std;
19
20class XMLNode;
21class ResourceTable;
22
23enum {
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
36status_t compileXmlFile(const sp<AaptAssets>& assets,
37 const sp<AaptFile>& target,
38 ResourceTable* table,
39 int options = XML_COMPILE_STANDARD_RESOURCE);
40
41status_t compileXmlFile(const sp<AaptAssets>& assets,
42 const sp<AaptFile>& target,
43 const sp<AaptFile>& outTarget,
44 ResourceTable* table,
45 int options = XML_COMPILE_STANDARD_RESOURCE);
46
47status_t compileXmlFile(const sp<AaptAssets>& assets,
48 const sp<XMLNode>& xmlTree,
49 const sp<AaptFile>& target,
50 ResourceTable* table,
51 int options = XML_COMPILE_STANDARD_RESOURCE);
52
53status_t compileResourceFile(Bundle* bundle,
54 const sp<AaptAssets>& assets,
55 const sp<AaptFile>& in,
56 const ResTable_config& defParams,
57 const bool overwrite,
58 ResourceTable* outTable);
59
60struct AccessorCookie
61{
62 SourcePos sourcePos;
63 String8 attr;
64 String8 value;
65
66 AccessorCookie(const SourcePos&p, const String8& a, const String8& v)
67 :sourcePos(p),
68 attr(a),
69 value(v)
70 {
71 }
72};
73
74class ResourceTable : public ResTable::Accessor
75{
76public:
Adam Lesinski833f3cc2014-06-18 15:06:01 -070077 // The type of package to build.
78 enum PackageType {
79 App,
80 System,
81 SharedLibrary,
82 AppFeature
83 };
84
Adam Lesinski282e1812014-01-23 18:17:42 -080085 class Package;
86 class Type;
87 class Entry;
88
Adam Lesinski833f3cc2014-06-18 15:06:01 -070089 ResourceTable(Bundle* bundle, const String16& assetsPackage, PackageType type);
90
91 const String16& getAssetsPackage() const {
92 return mAssetsPackage;
93 }
Adam Lesinski282e1812014-01-23 18:17:42 -080094
95 status_t addIncludedResources(Bundle* bundle, const sp<AaptAssets>& assets);
96
97 status_t addPublic(const SourcePos& pos,
98 const String16& package,
99 const String16& type,
100 const String16& name,
101 const uint32_t ident);
102
103 status_t addEntry(const SourcePos& pos,
104 const String16& package,
105 const String16& type,
106 const String16& name,
107 const String16& value,
108 const Vector<StringPool::entry_style_span>* style = NULL,
109 const ResTable_config* params = NULL,
110 const bool doSetIndex = false,
111 const int32_t format = ResTable_map::TYPE_ANY,
112 const bool overwrite = false);
113
114 status_t startBag(const SourcePos& pos,
115 const String16& package,
116 const String16& type,
117 const String16& name,
118 const String16& bagParent,
119 const ResTable_config* params = NULL,
120 bool overlay = false,
121 bool replace = false,
122 bool isId = false);
123
124 status_t addBag(const SourcePos& pos,
125 const String16& package,
126 const String16& type,
127 const String16& name,
128 const String16& bagParent,
129 const String16& bagKey,
130 const String16& value,
131 const Vector<StringPool::entry_style_span>* style = NULL,
132 const ResTable_config* params = NULL,
133 bool replace = false,
134 bool isId = false,
135 const int32_t format = ResTable_map::TYPE_ANY);
136
137 bool hasBagOrEntry(const String16& package,
138 const String16& type,
139 const String16& name) const;
140
141 bool hasBagOrEntry(const String16& package,
142 const String16& type,
143 const String16& name,
144 const ResTable_config& config) const;
145
146 bool hasBagOrEntry(const String16& ref,
147 const String16* defType = NULL,
148 const String16* defPackage = NULL);
149
150 bool appendComment(const String16& package,
151 const String16& type,
152 const String16& name,
153 const String16& comment,
154 bool onlyIfEmpty = false);
155
156 bool appendTypeComment(const String16& package,
157 const String16& type,
158 const String16& name,
159 const String16& comment);
160
161 void canAddEntry(const SourcePos& pos,
162 const String16& package, const String16& type, const String16& name);
163
164 size_t size() const;
165 size_t numLocalResources() const;
166 bool hasResources() const;
167
Adam Lesinski82a2dd82014-09-17 18:34:15 -0700168 status_t modifyForCompat(const Bundle* bundle);
169
Adam Lesinski27f69f42014-08-21 13:19:12 -0700170 sp<AaptFile> flatten(Bundle* bundle, const sp<const ResourceFilter>& filter,
171 const bool isBase);
Adam Lesinski282e1812014-01-23 18:17:42 -0800172
173 static inline uint32_t makeResId(uint32_t packageId,
174 uint32_t typeId,
175 uint32_t nameId)
176 {
177 return nameId | (typeId<<16) | (packageId<<24);
178 }
179
180 static inline uint32_t getResId(const sp<Package>& p,
181 const sp<Type>& t,
182 uint32_t nameId);
183
184 uint32_t getResId(const String16& package,
185 const String16& type,
186 const String16& name,
187 bool onlyPublic = true) const;
188
189 uint32_t getResId(const String16& ref,
190 const String16* defType = NULL,
191 const String16* defPackage = NULL,
192 const char** outErrorMsg = NULL,
193 bool onlyPublic = true) const;
194
195 static bool isValidResourceName(const String16& s);
196
197 bool stringToValue(Res_value* outValue, StringPool* pool,
198 const String16& str,
199 bool preserveSpaces, bool coerceType,
200 uint32_t attrID,
201 const Vector<StringPool::entry_style_span>* style = NULL,
202 String16* outStr = NULL, void* accessorCookie = NULL,
203 uint32_t attrType = ResTable_map::TYPE_ANY,
204 const String8* configTypeName = NULL,
205 const ConfigDescription* config = NULL);
206
207 status_t assignResourceIds();
208 status_t addSymbols(const sp<AaptSymbols>& outSymbols = NULL);
Adam Lesinskia01a9372014-03-20 18:04:57 -0700209 void addLocalization(const String16& name, const String8& locale, const SourcePos& src);
Adam Lesinski282e1812014-01-23 18:17:42 -0800210 status_t validateLocalizations(void);
211
Adam Lesinski27f69f42014-08-21 13:19:12 -0700212 status_t flatten(Bundle* bundle, const sp<const ResourceFilter>& filter,
213 const sp<AaptFile>& dest, const bool isBase);
Adam Lesinskide898ff2014-01-29 18:20:45 -0800214 status_t flattenLibraryTable(const sp<AaptFile>& dest, const Vector<sp<Package> >& libs);
Adam Lesinski282e1812014-01-23 18:17:42 -0800215
216 void writePublicDefinitions(const String16& package, FILE* fp);
217
218 virtual uint32_t getCustomResource(const String16& package,
219 const String16& type,
220 const String16& name) const;
221 virtual uint32_t getCustomResourceWithCreation(const String16& package,
222 const String16& type,
223 const String16& name,
224 const bool createIfNeeded);
225 virtual uint32_t getRemappedPackage(uint32_t origPackage) const;
226 virtual bool getAttributeType(uint32_t attrID, uint32_t* outType);
227 virtual bool getAttributeMin(uint32_t attrID, uint32_t* outMin);
228 virtual bool getAttributeMax(uint32_t attrID, uint32_t* outMax);
229 virtual bool getAttributeKeys(uint32_t attrID, Vector<String16>* outKeys);
230 virtual bool getAttributeEnum(uint32_t attrID,
231 const char16_t* name, size_t nameLen,
232 Res_value* outValue);
233 virtual bool getAttributeFlags(uint32_t attrID,
234 const char16_t* name, size_t nameLen,
235 Res_value* outValue);
236 virtual uint32_t getAttributeL10N(uint32_t attrID);
237
238 virtual bool getLocalizationSetting();
239 virtual void reportError(void* accessorCookie, const char* fmt, ...);
240
241 void setCurrentXmlPos(const SourcePos& pos) { mCurrentXmlPos = pos; }
242
243 class Item {
244 public:
245 Item() : isId(false), format(ResTable_map::TYPE_ANY), bagKeyId(0), evaluating(false)
246 { memset(&parsedValue, 0, sizeof(parsedValue)); }
247 Item(const SourcePos& pos,
248 bool _isId,
249 const String16& _value,
250 const Vector<StringPool::entry_style_span>* _style = NULL,
251 int32_t format = ResTable_map::TYPE_ANY);
252 Item(const Item& o) : sourcePos(o.sourcePos),
253 isId(o.isId), value(o.value), style(o.style),
254 format(o.format), bagKeyId(o.bagKeyId), evaluating(false) {
255 memset(&parsedValue, 0, sizeof(parsedValue));
256 }
257 ~Item() { }
258
259 Item& operator=(const Item& o) {
260 sourcePos = o.sourcePos;
261 isId = o.isId;
262 value = o.value;
263 style = o.style;
264 format = o.format;
265 bagKeyId = o.bagKeyId;
266 parsedValue = o.parsedValue;
267 return *this;
268 }
269
270 SourcePos sourcePos;
271 mutable bool isId;
272 String16 value;
273 Vector<StringPool::entry_style_span> style;
274 int32_t format;
275 uint32_t bagKeyId;
276 mutable bool evaluating;
277 Res_value parsedValue;
278 };
279
280 class Entry : public RefBase {
281 public:
282 Entry(const String16& name, const SourcePos& pos)
283 : mName(name), mType(TYPE_UNKNOWN),
284 mItemFormat(ResTable_map::TYPE_ANY), mNameIndex(-1), mPos(pos)
285 { }
Adam Lesinski82a2dd82014-09-17 18:34:15 -0700286
287 Entry(const Entry& entry);
288
Adam Lesinski282e1812014-01-23 18:17:42 -0800289 virtual ~Entry() { }
290
291 enum type {
292 TYPE_UNKNOWN = 0,
293 TYPE_ITEM,
294 TYPE_BAG
295 };
296
297 String16 getName() const { return mName; }
298 type getType() const { return mType; }
299
300 void setParent(const String16& parent) { mParent = parent; }
301 String16 getParent() const { return mParent; }
302
303 status_t makeItABag(const SourcePos& sourcePos);
304
305 status_t emptyBag(const SourcePos& sourcePos);
306
307 status_t setItem(const SourcePos& pos,
308 const String16& value,
309 const Vector<StringPool::entry_style_span>* style = NULL,
310 int32_t format = ResTable_map::TYPE_ANY,
311 const bool overwrite = false);
312
313 status_t addToBag(const SourcePos& pos,
314 const String16& key, const String16& value,
315 const Vector<StringPool::entry_style_span>* style = NULL,
316 bool replace=false, bool isId = false,
317 int32_t format = ResTable_map::TYPE_ANY);
318
Adam Lesinski82a2dd82014-09-17 18:34:15 -0700319 status_t removeFromBag(const String16& key);
320
Adam Lesinski282e1812014-01-23 18:17:42 -0800321 // Index of the entry's name string in the key pool.
322 int32_t getNameIndex() const { return mNameIndex; }
323 void setNameIndex(int32_t index) { mNameIndex = index; }
324
325 const Item* getItem() const { return mType == TYPE_ITEM ? &mItem : NULL; }
326 const KeyedVector<String16, Item>& getBag() const { return mBag; }
327
328 status_t generateAttributes(ResourceTable* table,
329 const String16& package);
330
331 status_t assignResourceIds(ResourceTable* table,
332 const String16& package);
333
334 status_t prepareFlatten(StringPool* strings, ResourceTable* table,
335 const String8* configTypeName, const ConfigDescription* config);
336
337 status_t remapStringValue(StringPool* strings);
338
339 ssize_t flatten(Bundle*, const sp<AaptFile>& data, bool isPublic);
340
341 const SourcePos& getPos() const { return mPos; }
342
343 private:
344 String16 mName;
345 String16 mParent;
346 type mType;
347 Item mItem;
348 int32_t mItemFormat;
349 KeyedVector<String16, Item> mBag;
350 int32_t mNameIndex;
351 uint32_t mParentId;
352 SourcePos mPos;
353 };
354
355 class ConfigList : public RefBase {
356 public:
357 ConfigList(const String16& name, const SourcePos& pos)
358 : mName(name), mPos(pos), mPublic(false), mEntryIndex(-1) { }
359 virtual ~ConfigList() { }
360
361 String16 getName() const { return mName; }
362 const SourcePos& getPos() const { return mPos; }
363
364 void appendComment(const String16& comment, bool onlyIfEmpty = false);
365 const String16& getComment() const { return mComment; }
366
367 void appendTypeComment(const String16& comment);
368 const String16& getTypeComment() const { return mTypeComment; }
369
370 // Index of this entry in its Type.
371 int32_t getEntryIndex() const { return mEntryIndex; }
372 void setEntryIndex(int32_t index) { mEntryIndex = index; }
373
374 void setPublic(bool pub) { mPublic = pub; }
375 bool getPublic() const { return mPublic; }
376 void setPublicSourcePos(const SourcePos& pos) { mPublicSourcePos = pos; }
377 const SourcePos& getPublicSourcePos() { return mPublicSourcePos; }
378
379 void addEntry(const ResTable_config& config, const sp<Entry>& entry) {
380 mEntries.add(config, entry);
381 }
382
383 const DefaultKeyedVector<ConfigDescription, sp<Entry> >& getEntries() const { return mEntries; }
384 private:
385 const String16 mName;
386 const SourcePos mPos;
387 String16 mComment;
388 String16 mTypeComment;
389 bool mPublic;
390 SourcePos mPublicSourcePos;
391 int32_t mEntryIndex;
392 DefaultKeyedVector<ConfigDescription, sp<Entry> > mEntries;
393 };
394
395 class Public {
396 public:
397 Public() : sourcePos(), ident(0) { }
398 Public(const SourcePos& pos,
399 const String16& _comment,
400 uint32_t _ident)
401 : sourcePos(pos),
402 comment(_comment), ident(_ident) { }
403 Public(const Public& o) : sourcePos(o.sourcePos),
404 comment(o.comment), ident(o.ident) { }
405 ~Public() { }
406
407 Public& operator=(const Public& o) {
408 sourcePos = o.sourcePos;
409 comment = o.comment;
410 ident = o.ident;
411 return *this;
412 }
413
414 SourcePos sourcePos;
415 String16 comment;
416 uint32_t ident;
417 };
418
419 class Type : public RefBase {
420 public:
421 Type(const String16& name, const SourcePos& pos)
422 : mName(name), mFirstPublicSourcePos(NULL), mPublicIndex(-1), mIndex(-1), mPos(pos)
423 { }
424 virtual ~Type() { delete mFirstPublicSourcePos; }
425
426 status_t addPublic(const SourcePos& pos,
427 const String16& name,
428 const uint32_t ident);
429
430 void canAddEntry(const String16& name);
431
432 String16 getName() const { return mName; }
433 sp<Entry> getEntry(const String16& entry,
434 const SourcePos& pos,
435 const ResTable_config* config = NULL,
436 bool doSetIndex = false,
437 bool overlay = false,
438 bool autoAddOverlay = false);
439
440 const SourcePos& getFirstPublicSourcePos() const { return *mFirstPublicSourcePos; }
441
442 int32_t getPublicIndex() const { return mPublicIndex; }
443
444 int32_t getIndex() const { return mIndex; }
445 void setIndex(int32_t index) { mIndex = index; }
446
447 status_t applyPublicEntryOrder();
448
449 const SortedVector<ConfigDescription>& getUniqueConfigs() const { return mUniqueConfigs; }
450
451 const DefaultKeyedVector<String16, sp<ConfigList> >& getConfigs() const { return mConfigs; }
452 const Vector<sp<ConfigList> >& getOrderedConfigs() const { return mOrderedConfigs; }
453
454 const SortedVector<String16>& getCanAddEntries() const { return mCanAddEntries; }
455
456 const SourcePos& getPos() const { return mPos; }
457 private:
458 String16 mName;
459 SourcePos* mFirstPublicSourcePos;
460 DefaultKeyedVector<String16, Public> mPublic;
461 SortedVector<ConfigDescription> mUniqueConfigs;
462 DefaultKeyedVector<String16, sp<ConfigList> > mConfigs;
463 Vector<sp<ConfigList> > mOrderedConfigs;
464 SortedVector<String16> mCanAddEntries;
465 int32_t mPublicIndex;
466 int32_t mIndex;
467 SourcePos mPos;
468 };
469
470 class Package : public RefBase {
471 public:
Adam Lesinski833f3cc2014-06-18 15:06:01 -0700472 Package(const String16& name, size_t packageId);
Adam Lesinski282e1812014-01-23 18:17:42 -0800473 virtual ~Package() { }
474
475 String16 getName() const { return mName; }
476 sp<Type> getType(const String16& type,
477 const SourcePos& pos,
478 bool doSetIndex = false);
479
Adam Lesinski833f3cc2014-06-18 15:06:01 -0700480 size_t getAssignedId() const { return mPackageId; }
Adam Lesinski282e1812014-01-23 18:17:42 -0800481
482 const ResStringPool& getTypeStrings() const { return mTypeStrings; }
483 uint32_t indexOfTypeString(const String16& s) const { return mTypeStringsMapping.valueFor(s); }
484 const sp<AaptFile> getTypeStringsData() const { return mTypeStringsData; }
485 status_t setTypeStrings(const sp<AaptFile>& data);
486
487 const ResStringPool& getKeyStrings() const { return mKeyStrings; }
488 uint32_t indexOfKeyString(const String16& s) const { return mKeyStringsMapping.valueFor(s); }
489 const sp<AaptFile> getKeyStringsData() const { return mKeyStringsData; }
490 status_t setKeyStrings(const sp<AaptFile>& data);
491
492 status_t applyPublicTypeOrder();
493
494 const DefaultKeyedVector<String16, sp<Type> >& getTypes() const { return mTypes; }
495 const Vector<sp<Type> >& getOrderedTypes() const { return mOrderedTypes; }
496
497 private:
498 status_t setStrings(const sp<AaptFile>& data,
499 ResStringPool* strings,
500 DefaultKeyedVector<String16, uint32_t>* mappings);
501
502 const String16 mName;
Adam Lesinski833f3cc2014-06-18 15:06:01 -0700503 const size_t mPackageId;
Adam Lesinski282e1812014-01-23 18:17:42 -0800504 DefaultKeyedVector<String16, sp<Type> > mTypes;
505 Vector<sp<Type> > mOrderedTypes;
506 sp<AaptFile> mTypeStringsData;
507 sp<AaptFile> mKeyStringsData;
508 ResStringPool mTypeStrings;
509 ResStringPool mKeyStrings;
510 DefaultKeyedVector<String16, uint32_t> mTypeStringsMapping;
511 DefaultKeyedVector<String16, uint32_t> mKeyStringsMapping;
512 };
513
514private:
515 void writePublicDefinitions(const String16& package, FILE* fp, bool pub);
516 sp<Package> getPackage(const String16& package);
517 sp<Type> getType(const String16& package,
518 const String16& type,
519 const SourcePos& pos,
520 bool doSetIndex = false);
521 sp<Entry> getEntry(const String16& package,
522 const String16& type,
523 const String16& name,
524 const SourcePos& pos,
525 bool overlay,
526 const ResTable_config* config = NULL,
527 bool doSetIndex = false);
528 sp<const Entry> getEntry(uint32_t resID,
529 const ResTable_config* config = NULL) const;
530 const Item* getItem(uint32_t resID, uint32_t attrID) const;
531 bool getItemValue(uint32_t resID, uint32_t attrID,
532 Res_value* outValue);
Adam Lesinski82a2dd82014-09-17 18:34:15 -0700533 bool isAttributeFromL(uint32_t attrId);
Adam Lesinski282e1812014-01-23 18:17:42 -0800534
535
536 String16 mAssetsPackage;
Adam Lesinski833f3cc2014-06-18 15:06:01 -0700537 PackageType mPackageType;
Adam Lesinski282e1812014-01-23 18:17:42 -0800538 sp<AaptAssets> mAssets;
Adam Lesinski833f3cc2014-06-18 15:06:01 -0700539 uint32_t mTypeIdOffset;
Adam Lesinski282e1812014-01-23 18:17:42 -0800540 DefaultKeyedVector<String16, sp<Package> > mPackages;
541 Vector<sp<Package> > mOrderedPackages;
Adam Lesinski282e1812014-01-23 18:17:42 -0800542 size_t mNumLocal;
543 SourcePos mCurrentXmlPos;
544 Bundle* mBundle;
545
546 // key = string resource name, value = set of locales in which that name is defined
Adam Lesinskia01a9372014-03-20 18:04:57 -0700547 map<String16, map<String8, SourcePos> > mLocalizations;
Adam Lesinski282e1812014-01-23 18:17:42 -0800548};
549
550#endif