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