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 "ConfigDescription.h" 11 #include "StringPool.h" 12 #include "SourcePos.h" 13 #include "ResourceFilter.h" 14 15 #include <map> 16 #include <queue> 17 #include <set> 18 19 using namespace std; 20 21 class XMLNode; 22 class ResourceTable; 23 24 enum { 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 37 status_t compileXmlFile(const Bundle* bundle, 38 const sp<AaptAssets>& assets, 39 const String16& resourceName, 40 const sp<AaptFile>& target, 41 ResourceTable* table, 42 int options = XML_COMPILE_STANDARD_RESOURCE); 43 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, 49 ResourceTable* table, 50 int options = XML_COMPILE_STANDARD_RESOURCE); 51 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, 57 ResourceTable* table, 58 int options = XML_COMPILE_STANDARD_RESOURCE); 59 60 status_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 67 struct AccessorCookie 68 { 69 SourcePos sourcePos; 70 String8 attr; 71 String8 value; 72 AccessorCookieAccessorCookie73 AccessorCookie(const SourcePos&p, const String8& a, const String8& v) 74 :sourcePos(p), 75 attr(a), 76 value(v) 77 { 78 } 79 }; 80 81 // Holds the necessary information to compile the 82 // resource. 83 struct CompileResourceWorkItem { 84 String16 resourceName; 85 String8 resPath; 86 sp<AaptFile> file; 87 }; 88 89 class ResourceTable : public ResTable::Accessor 90 { 91 public: 92 // The type of package to build. 93 enum PackageType { 94 App, 95 System, 96 SharedLibrary, 97 AppFeature 98 }; 99 100 class Package; 101 class Type; 102 class Entry; 103 104 ResourceTable(Bundle* bundle, const String16& assetsPackage, PackageType type); 105 getAssetsPackage()106 const String16& getAssetsPackage() const { 107 return mAssetsPackage; 108 } 109 110 /** 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 */ getWorkQueue()118 queue<CompileResourceWorkItem>& getWorkQueue() { 119 return mWorkQueue; 120 } 121 122 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 195 status_t modifyForCompat(const Bundle* bundle); 196 status_t modifyForCompat(const Bundle* bundle, 197 const String16& resourceName, 198 const sp<AaptFile>& file, 199 const sp<XMLNode>& root); 200 201 sp<AaptFile> flatten(Bundle* bundle, const sp<const ResourceFilter>& filter, 202 const bool isBase); 203 makeResId(uint32_t packageId,uint32_t typeId,uint32_t nameId)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); 240 void addLocalization(const String16& name, const String8& locale, const SourcePos& src); 241 status_t validateLocalizations(void); 242 243 status_t flatten(Bundle* bundle, const sp<const ResourceFilter>& filter, 244 const sp<AaptFile>& dest, const bool isBase); 245 status_t flattenLibraryTable(const sp<AaptFile>& dest, const Vector<sp<Package> >& libs); 246 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 setCurrentXmlPos(const SourcePos & pos)272 void setCurrentXmlPos(const SourcePos& pos) { mCurrentXmlPos = pos; } 273 274 class Item { 275 public: Item()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); Item(const Item & o)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 } ~Item()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: Entry(const String16 & name,const SourcePos & pos)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 { } 317 318 Entry(const Entry& entry); 319 Entry& operator=(const Entry& entry); 320 ~Entry()321 virtual ~Entry() { } 322 323 enum type { 324 TYPE_UNKNOWN = 0, 325 TYPE_ITEM, 326 TYPE_BAG 327 }; 328 getName()329 String16 getName() const { return mName; } getType()330 type getType() const { return mType; } 331 setParent(const String16 & parent)332 void setParent(const String16& parent) { mParent = parent; } getParent()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 351 status_t removeFromBag(const String16& key); 352 353 // Index of the entry's name string in the key pool. getNameIndex()354 int32_t getNameIndex() const { return mNameIndex; } setNameIndex(int32_t index)355 void setNameIndex(int32_t index) { mNameIndex = index; } 356 getItem()357 const Item* getItem() const { return mType == TYPE_ITEM ? &mItem : NULL; } getBag()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 getPos()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: ConfigList(const String16 & name,const SourcePos & pos)389 ConfigList(const String16& name, const SourcePos& pos) 390 : mName(name), mPos(pos), mPublic(false), mEntryIndex(-1) { } ~ConfigList()391 virtual ~ConfigList() { } 392 getName()393 String16 getName() const { return mName; } getPos()394 const SourcePos& getPos() const { return mPos; } 395 396 void appendComment(const String16& comment, bool onlyIfEmpty = false); getComment()397 const String16& getComment() const { return mComment; } 398 399 void appendTypeComment(const String16& comment); getTypeComment()400 const String16& getTypeComment() const { return mTypeComment; } 401 402 // Index of this entry in its Type. getEntryIndex()403 int32_t getEntryIndex() const { return mEntryIndex; } setEntryIndex(int32_t index)404 void setEntryIndex(int32_t index) { mEntryIndex = index; } 405 setPublic(bool pub)406 void setPublic(bool pub) { mPublic = pub; } getPublic()407 bool getPublic() const { return mPublic; } setPublicSourcePos(const SourcePos & pos)408 void setPublicSourcePos(const SourcePos& pos) { mPublicSourcePos = pos; } getPublicSourcePos()409 const SourcePos& getPublicSourcePos() { return mPublicSourcePos; } 410 addEntry(const ResTable_config & config,const sp<Entry> & entry)411 void addEntry(const ResTable_config& config, const sp<Entry>& entry) { 412 mEntries.add(config, entry); 413 } 414 getEntries()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: Public()429 Public() : sourcePos(), ident(0) { } Public(const SourcePos & pos,const String16 & _comment,uint32_t _ident)430 Public(const SourcePos& pos, 431 const String16& _comment, 432 uint32_t _ident) 433 : sourcePos(pos), 434 comment(_comment), ident(_ident) { } Public(const Public & o)435 Public(const Public& o) : sourcePos(o.sourcePos), 436 comment(o.comment), ident(o.ident) { } ~Public()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: Type(const String16 & name,const SourcePos & pos)453 Type(const String16& name, const SourcePos& pos) 454 : mName(name), mFirstPublicSourcePos(NULL), mPublicIndex(-1), mIndex(-1), mPos(pos) 455 { } ~Type()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 getName()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 getFirstPublicSourcePos()472 const SourcePos& getFirstPublicSourcePos() const { return *mFirstPublicSourcePos; } 473 getPublicIndex()474 int32_t getPublicIndex() const { return mPublicIndex; } 475 getIndex()476 int32_t getIndex() const { return mIndex; } setIndex(int32_t index)477 void setIndex(int32_t index) { mIndex = index; } 478 479 status_t applyPublicEntryOrder(); 480 getUniqueConfigs()481 const SortedVector<ConfigDescription>& getUniqueConfigs() const { return mUniqueConfigs; } 482 getConfigs()483 const DefaultKeyedVector<String16, sp<ConfigList> >& getConfigs() const { return mConfigs; } getOrderedConfigs()484 const Vector<sp<ConfigList> >& getOrderedConfigs() const { return mOrderedConfigs; } 485 getCanAddEntries()486 const SortedVector<String16>& getCanAddEntries() const { return mCanAddEntries; } 487 getPos()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: 504 Package(const String16& name, size_t packageId); ~Package()505 virtual ~Package() { } 506 getName()507 String16 getName() const { return mName; } 508 sp<Type> getType(const String16& type, 509 const SourcePos& pos, 510 bool doSetIndex = false); 511 getAssignedId()512 size_t getAssignedId() const { return mPackageId; } 513 getTypeStrings()514 const ResStringPool& getTypeStrings() const { return mTypeStrings; } indexOfTypeString(const String16 & s)515 uint32_t indexOfTypeString(const String16& s) const { return mTypeStringsMapping.valueFor(s); } getTypeStringsData()516 const sp<AaptFile> getTypeStringsData() const { return mTypeStringsData; } 517 status_t setTypeStrings(const sp<AaptFile>& data); 518 getKeyStrings()519 const ResStringPool& getKeyStrings() const { return mKeyStrings; } indexOfKeyString(const String16 & s)520 uint32_t indexOfKeyString(const String16& s) const { return mKeyStringsMapping.valueFor(s); } getKeyStringsData()521 const sp<AaptFile> getKeyStringsData() const { return mKeyStringsData; } 522 status_t setKeyStrings(const sp<AaptFile>& data); 523 524 status_t applyPublicTypeOrder(); 525 getTypes()526 const DefaultKeyedVector<String16, sp<Type> >& getTypes() const { return mTypes; } getOrderedTypes()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; 535 const size_t mPackageId; 536 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 546 private: 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; 562 sp<ConfigList> getConfigList(const String16& package, 563 const String16& type, 564 const String16& name) const; 565 const Item* getItem(uint32_t resID, uint32_t attrID) const; 566 bool getItemValue(uint32_t resID, uint32_t attrID, 567 Res_value* outValue); 568 bool isAttributeFromL(uint32_t attrId); 569 570 571 String16 mAssetsPackage; 572 PackageType mPackageType; 573 sp<AaptAssets> mAssets; 574 uint32_t mTypeIdOffset; 575 DefaultKeyedVector<String16, sp<Package> > mPackages; 576 Vector<sp<Package> > mOrderedPackages; 577 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 582 map<String16, map<String8, SourcePos> > mLocalizations; 583 queue<CompileResourceWorkItem> mWorkQueue; 584 }; 585 586 #endif 587