AaptAssets.h revision 6c997a9e880e08c354ffd809bd62df9e25e9c4d4
1// 2// Copyright 2006 The Android Open Source Project 3// 4// Information about assets being operated on. 5// 6#ifndef __AAPT_ASSETS_H 7#define __AAPT_ASSETS_H 8 9#include <stdlib.h> 10#include <utils/AssetManager.h> 11#include <utils/KeyedVector.h> 12#include <utils/String8.h> 13#include <utils/ResourceTypes.h> 14#include <utils/SortedVector.h> 15#include <utils/String8.h> 16#include <utils/Vector.h> 17#include <utils/RefBase.h> 18#include "ZipFile.h" 19 20#include "Bundle.h" 21#include "SourcePos.h" 22 23using namespace android; 24 25bool valid_symbol_name(const String8& str); 26 27class AaptAssets; 28 29enum { 30 AXIS_NONE = 0, 31 AXIS_MCC = 1, 32 AXIS_MNC, 33 AXIS_LANGUAGE, 34 AXIS_REGION, 35 AXIS_SCREENLAYOUTSIZE, 36 AXIS_SCREENLAYOUTLONG, 37 AXIS_ORIENTATION, 38 AXIS_UIMODETYPE, 39 AXIS_UIMODENIGHT, 40 AXIS_DENSITY, 41 AXIS_TOUCHSCREEN, 42 AXIS_KEYSHIDDEN, 43 AXIS_KEYBOARD, 44 AXIS_NAVHIDDEN, 45 AXIS_NAVIGATION, 46 AXIS_SCREENSIZE, 47 AXIS_SMALLESTSCREENWIDTHDP, 48 AXIS_SCREENWIDTHDP, 49 AXIS_SCREENHEIGHTDP, 50 AXIS_VERSION, 51 52 AXIS_START = AXIS_MCC, 53 AXIS_END = AXIS_VERSION, 54}; 55 56/** 57 * This structure contains a specific variation of a single file out 58 * of all the variations it can have that we can have. 59 */ 60struct AaptGroupEntry 61{ 62public: 63 AaptGroupEntry() : mParamsChanged(true) { } 64 AaptGroupEntry(const String8& _locale, const String8& _vendor) 65 : locale(_locale), vendor(_vendor), mParamsChanged(true) { } 66 67 bool initFromDirName(const char* dir, String8* resType); 68 69 static status_t parseNamePart(const String8& part, int* axis, uint32_t* value); 70 71 static uint32_t getConfigValueForAxis(const ResTable_config& config, int axis); 72 73 static bool configSameExcept(const ResTable_config& config, 74 const ResTable_config& otherConfig, int axis); 75 76 static bool getMccName(const char* name, ResTable_config* out = NULL); 77 static bool getMncName(const char* name, ResTable_config* out = NULL); 78 static bool getLocaleName(const char* name, ResTable_config* out = NULL); 79 static bool getScreenLayoutSizeName(const char* name, ResTable_config* out = NULL); 80 static bool getScreenLayoutLongName(const char* name, ResTable_config* out = NULL); 81 static bool getOrientationName(const char* name, ResTable_config* out = NULL); 82 static bool getUiModeTypeName(const char* name, ResTable_config* out = NULL); 83 static bool getUiModeNightName(const char* name, ResTable_config* out = NULL); 84 static bool getDensityName(const char* name, ResTable_config* out = NULL); 85 static bool getTouchscreenName(const char* name, ResTable_config* out = NULL); 86 static bool getKeysHiddenName(const char* name, ResTable_config* out = NULL); 87 static bool getKeyboardName(const char* name, ResTable_config* out = NULL); 88 static bool getNavigationName(const char* name, ResTable_config* out = NULL); 89 static bool getNavHiddenName(const char* name, ResTable_config* out = NULL); 90 static bool getScreenSizeName(const char* name, ResTable_config* out = NULL); 91 static bool getSmallestScreenWidthDpName(const char* name, ResTable_config* out = NULL); 92 static bool getScreenWidthDpName(const char* name, ResTable_config* out = NULL); 93 static bool getScreenHeightDpName(const char* name, ResTable_config* out = NULL); 94 static bool getVersionName(const char* name, ResTable_config* out = NULL); 95 96 int compare(const AaptGroupEntry& o) const; 97 98 const ResTable_config& toParams() const; 99 100 inline bool operator<(const AaptGroupEntry& o) const { return compare(o) < 0; } 101 inline bool operator<=(const AaptGroupEntry& o) const { return compare(o) <= 0; } 102 inline bool operator==(const AaptGroupEntry& o) const { return compare(o) == 0; } 103 inline bool operator!=(const AaptGroupEntry& o) const { return compare(o) != 0; } 104 inline bool operator>=(const AaptGroupEntry& o) const { return compare(o) >= 0; } 105 inline bool operator>(const AaptGroupEntry& o) const { return compare(o) > 0; } 106 107 String8 toString() const; 108 String8 toDirName(const String8& resType) const; 109 110 const String8& getVersionString() const { return version; } 111 112private: 113 String8 mcc; 114 String8 mnc; 115 String8 locale; 116 String8 vendor; 117 String8 smallestScreenWidthDp; 118 String8 screenWidthDp; 119 String8 screenHeightDp; 120 String8 screenLayoutSize; 121 String8 screenLayoutLong; 122 String8 orientation; 123 String8 uiModeType; 124 String8 uiModeNight; 125 String8 density; 126 String8 touchscreen; 127 String8 keysHidden; 128 String8 keyboard; 129 String8 navHidden; 130 String8 navigation; 131 String8 screenSize; 132 String8 version; 133 134 mutable bool mParamsChanged; 135 mutable ResTable_config mParams; 136}; 137 138inline int compare_type(const AaptGroupEntry& lhs, const AaptGroupEntry& rhs) 139{ 140 return lhs.compare(rhs); 141} 142 143inline int strictly_order_type(const AaptGroupEntry& lhs, const AaptGroupEntry& rhs) 144{ 145 return compare_type(lhs, rhs) < 0; 146} 147 148class AaptGroup; 149class FilePathStore; 150 151/** 152 * A single asset file we know about. 153 */ 154class AaptFile : public RefBase 155{ 156public: 157 AaptFile(const String8& sourceFile, const AaptGroupEntry& groupEntry, 158 const String8& resType) 159 : mGroupEntry(groupEntry) 160 , mResourceType(resType) 161 , mSourceFile(sourceFile) 162 , mData(NULL) 163 , mDataSize(0) 164 , mBufferSize(0) 165 , mCompression(ZipEntry::kCompressStored) 166 { 167 //printf("new AaptFile created %s\n", (const char*)sourceFile); 168 } 169 virtual ~AaptFile() { 170 free(mData); 171 } 172 173 const String8& getPath() const { return mPath; } 174 const AaptGroupEntry& getGroupEntry() const { return mGroupEntry; } 175 176 // Data API. If there is data attached to the file, 177 // getSourceFile() is not used. 178 bool hasData() const { return mData != NULL; } 179 const void* getData() const { return mData; } 180 size_t getSize() const { return mDataSize; } 181 void* editData(size_t size); 182 void* editData(size_t* outSize = NULL); 183 void* padData(size_t wordSize); 184 status_t writeData(const void* data, size_t size); 185 void clearData(); 186 187 const String8& getResourceType() const { return mResourceType; } 188 189 // File API. If the file does not hold raw data, this is 190 // a full path to a file on the filesystem that holds its data. 191 const String8& getSourceFile() const { return mSourceFile; } 192 193 String8 getPrintableSource() const; 194 195 // Desired compression method, as per utils/ZipEntry.h. For example, 196 // no compression is ZipEntry::kCompressStored. 197 int getCompressionMethod() const { return mCompression; } 198 void setCompressionMethod(int c) { mCompression = c; } 199private: 200 friend class AaptGroup; 201 202 String8 mPath; 203 AaptGroupEntry mGroupEntry; 204 String8 mResourceType; 205 String8 mSourceFile; 206 void* mData; 207 size_t mDataSize; 208 size_t mBufferSize; 209 int mCompression; 210}; 211 212/** 213 * A group of related files (the same file, with different 214 * vendor/locale variations). 215 */ 216class AaptGroup : public RefBase 217{ 218public: 219 AaptGroup(const String8& leaf, const String8& path) 220 : mLeaf(leaf), mPath(path) { } 221 virtual ~AaptGroup() { } 222 223 const String8& getLeaf() const { return mLeaf; } 224 225 // Returns the relative path after the AaptGroupEntry dirs. 226 const String8& getPath() const { return mPath; } 227 228 const DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> >& getFiles() const 229 { return mFiles; } 230 231 status_t addFile(const sp<AaptFile>& file); 232 void removeFile(size_t index); 233 234 void print(const String8& prefix) const; 235 236 String8 getPrintableSource() const; 237 238private: 239 String8 mLeaf; 240 String8 mPath; 241 242 DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > mFiles; 243}; 244 245/** 246 * A single directory of assets, which can contain files and other 247 * sub-directories. 248 */ 249class AaptDir : public RefBase 250{ 251public: 252 AaptDir(const String8& leaf, const String8& path) 253 : mLeaf(leaf), mPath(path) { } 254 virtual ~AaptDir() { } 255 256 const String8& getLeaf() const { return mLeaf; } 257 258 const String8& getPath() const { return mPath; } 259 260 const DefaultKeyedVector<String8, sp<AaptGroup> >& getFiles() const { return mFiles; } 261 const DefaultKeyedVector<String8, sp<AaptDir> >& getDirs() const { return mDirs; } 262 263 virtual status_t addFile(const String8& name, const sp<AaptGroup>& file); 264 265 void removeFile(const String8& name); 266 void removeDir(const String8& name); 267 268 /* 269 * Perform some sanity checks on the names of files and directories here. 270 * In particular: 271 * - Check for illegal chars in filenames. 272 * - Check filename length. 273 * - Check for presence of ".gz" and non-".gz" copies of same file. 274 * - Check for multiple files whose names match in a case-insensitive 275 * fashion (problematic for some systems). 276 * 277 * Comparing names against all other names is O(n^2). We could speed 278 * it up some by sorting the entries and being smarter about what we 279 * compare against, but I'm not expecting to have enough files in a 280 * single directory to make a noticeable difference in speed. 281 * 282 * Note that sorting here is not enough to guarantee that the package 283 * contents are sorted -- subsequent updates can rearrange things. 284 */ 285 status_t validate() const; 286 287 void print(const String8& prefix) const; 288 289 String8 getPrintableSource() const; 290 291private: 292 friend class AaptAssets; 293 294 status_t addDir(const String8& name, const sp<AaptDir>& dir); 295 sp<AaptDir> makeDir(const String8& name); 296 status_t addLeafFile(const String8& leafName, 297 const sp<AaptFile>& file); 298 virtual ssize_t slurpFullTree(Bundle* bundle, 299 const String8& srcDir, 300 const AaptGroupEntry& kind, 301 const String8& resType, 302 sp<FilePathStore>& fullResPaths); 303 304 String8 mLeaf; 305 String8 mPath; 306 307 DefaultKeyedVector<String8, sp<AaptGroup> > mFiles; 308 DefaultKeyedVector<String8, sp<AaptDir> > mDirs; 309}; 310 311/** 312 * All information we know about a particular symbol. 313 */ 314class AaptSymbolEntry 315{ 316public: 317 AaptSymbolEntry() 318 : isPublic(false), typeCode(TYPE_UNKNOWN) 319 { 320 } 321 AaptSymbolEntry(const String8& _name) 322 : name(_name), isPublic(false), typeCode(TYPE_UNKNOWN) 323 { 324 } 325 AaptSymbolEntry(const AaptSymbolEntry& o) 326 : name(o.name), sourcePos(o.sourcePos), isPublic(o.isPublic) 327 , comment(o.comment), typeComment(o.typeComment) 328 , typeCode(o.typeCode), int32Val(o.int32Val), stringVal(o.stringVal) 329 { 330 } 331 AaptSymbolEntry operator=(const AaptSymbolEntry& o) 332 { 333 sourcePos = o.sourcePos; 334 isPublic = o.isPublic; 335 comment = o.comment; 336 typeComment = o.typeComment; 337 typeCode = o.typeCode; 338 int32Val = o.int32Val; 339 stringVal = o.stringVal; 340 return *this; 341 } 342 343 const String8 name; 344 345 SourcePos sourcePos; 346 bool isPublic; 347 348 String16 comment; 349 String16 typeComment; 350 351 enum { 352 TYPE_UNKNOWN = 0, 353 TYPE_INT32, 354 TYPE_STRING 355 }; 356 357 int typeCode; 358 359 // Value. May be one of these. 360 int32_t int32Val; 361 String8 stringVal; 362}; 363 364/** 365 * A group of related symbols (such as indices into a string block) 366 * that have been generated from the assets. 367 */ 368class AaptSymbols : public RefBase 369{ 370public: 371 AaptSymbols() { } 372 virtual ~AaptSymbols() { } 373 374 status_t addSymbol(const String8& name, int32_t value, const SourcePos& pos) { 375 if (!check_valid_symbol_name(name, pos, "symbol")) { 376 return BAD_VALUE; 377 } 378 AaptSymbolEntry& sym = edit_symbol(name, &pos); 379 sym.typeCode = AaptSymbolEntry::TYPE_INT32; 380 sym.int32Val = value; 381 return NO_ERROR; 382 } 383 384 status_t addStringSymbol(const String8& name, const String8& value, 385 const SourcePos& pos) { 386 if (!check_valid_symbol_name(name, pos, "symbol")) { 387 return BAD_VALUE; 388 } 389 AaptSymbolEntry& sym = edit_symbol(name, &pos); 390 sym.typeCode = AaptSymbolEntry::TYPE_STRING; 391 sym.stringVal = value; 392 return NO_ERROR; 393 } 394 395 status_t makeSymbolPublic(const String8& name, const SourcePos& pos) { 396 if (!check_valid_symbol_name(name, pos, "symbol")) { 397 return BAD_VALUE; 398 } 399 AaptSymbolEntry& sym = edit_symbol(name, &pos); 400 sym.isPublic = true; 401 return NO_ERROR; 402 } 403 404 void appendComment(const String8& name, const String16& comment, const SourcePos& pos) { 405 if (comment.size() <= 0) { 406 return; 407 } 408 AaptSymbolEntry& sym = edit_symbol(name, &pos); 409 if (sym.comment.size() == 0) { 410 sym.comment = comment; 411 } else { 412 sym.comment.append(String16("\n")); 413 sym.comment.append(comment); 414 } 415 } 416 417 void appendTypeComment(const String8& name, const String16& comment) { 418 if (comment.size() <= 0) { 419 return; 420 } 421 AaptSymbolEntry& sym = edit_symbol(name, NULL); 422 if (sym.typeComment.size() == 0) { 423 sym.typeComment = comment; 424 } else { 425 sym.typeComment.append(String16("\n")); 426 sym.typeComment.append(comment); 427 } 428 } 429 430 sp<AaptSymbols> addNestedSymbol(const String8& name, const SourcePos& pos) { 431 if (!check_valid_symbol_name(name, pos, "nested symbol")) { 432 return NULL; 433 } 434 435 sp<AaptSymbols> sym = mNestedSymbols.valueFor(name); 436 if (sym == NULL) { 437 sym = new AaptSymbols(); 438 mNestedSymbols.add(name, sym); 439 } 440 441 return sym; 442 } 443 444 const KeyedVector<String8, AaptSymbolEntry>& getSymbols() const 445 { return mSymbols; } 446 const DefaultKeyedVector<String8, sp<AaptSymbols> >& getNestedSymbols() const 447 { return mNestedSymbols; } 448 449 const String16& getComment(const String8& name) const 450 { return get_symbol(name).comment; } 451 const String16& getTypeComment(const String8& name) const 452 { return get_symbol(name).typeComment; } 453 454private: 455 bool check_valid_symbol_name(const String8& symbol, const SourcePos& pos, const char* label) { 456 if (valid_symbol_name(symbol)) { 457 return true; 458 } 459 pos.error("invalid %s: '%s'\n", label, symbol.string()); 460 return false; 461 } 462 AaptSymbolEntry& edit_symbol(const String8& symbol, const SourcePos* pos) { 463 ssize_t i = mSymbols.indexOfKey(symbol); 464 if (i < 0) { 465 i = mSymbols.add(symbol, AaptSymbolEntry(symbol)); 466 } 467 AaptSymbolEntry& sym = mSymbols.editValueAt(i); 468 if (pos != NULL && sym.sourcePos.line < 0) { 469 sym.sourcePos = *pos; 470 } 471 return sym; 472 } 473 const AaptSymbolEntry& get_symbol(const String8& symbol) const { 474 ssize_t i = mSymbols.indexOfKey(symbol); 475 if (i >= 0) { 476 return mSymbols.valueAt(i); 477 } 478 return mDefSymbol; 479 } 480 481 KeyedVector<String8, AaptSymbolEntry> mSymbols; 482 DefaultKeyedVector<String8, sp<AaptSymbols> > mNestedSymbols; 483 AaptSymbolEntry mDefSymbol; 484}; 485 486class ResourceTypeSet : public RefBase, 487 public KeyedVector<String8,sp<AaptGroup> > 488{ 489public: 490 ResourceTypeSet(); 491}; 492 493// Storage for lists of fully qualified paths for 494// resources encountered during slurping. 495class FilePathStore : public RefBase, 496 public Vector<String8> 497{ 498public: 499 FilePathStore(); 500}; 501 502/** 503 * Asset hierarchy being operated on. 504 */ 505class AaptAssets : public AaptDir 506{ 507public: 508 AaptAssets(); 509 virtual ~AaptAssets() { delete mRes; } 510 511 const String8& getPackage() const { return mPackage; } 512 void setPackage(const String8& package) { mPackage = package; mSymbolsPrivatePackage = package; } 513 514 const SortedVector<AaptGroupEntry>& getGroupEntries() const; 515 516 virtual status_t addFile(const String8& name, const sp<AaptGroup>& file); 517 518 sp<AaptFile> addFile(const String8& filePath, 519 const AaptGroupEntry& entry, 520 const String8& srcDir, 521 sp<AaptGroup>* outGroup, 522 const String8& resType); 523 524 void addResource(const String8& leafName, 525 const String8& path, 526 const sp<AaptFile>& file, 527 const String8& resType); 528 529 void addGroupEntry(const AaptGroupEntry& entry) { mGroupEntries.add(entry); } 530 531 ssize_t slurpFromArgs(Bundle* bundle); 532 533 sp<AaptSymbols> getSymbolsFor(const String8& name); 534 535 const DefaultKeyedVector<String8, sp<AaptSymbols> >& getSymbols() const { return mSymbols; } 536 537 String8 getSymbolsPrivatePackage() const { return mSymbolsPrivatePackage; } 538 void setSymbolsPrivatePackage(const String8& pkg) { mSymbolsPrivatePackage = pkg; } 539 540 status_t buildIncludedResources(Bundle* bundle); 541 status_t addIncludedResources(const sp<AaptFile>& file); 542 const ResTable& getIncludedResources() const; 543 544 void print(const String8& prefix) const; 545 546 inline const Vector<sp<AaptDir> >& resDirs() const { return mResDirs; } 547 sp<AaptDir> resDir(const String8& name) const; 548 549 inline sp<AaptAssets> getOverlay() { return mOverlay; } 550 inline void setOverlay(sp<AaptAssets>& overlay) { mOverlay = overlay; } 551 552 inline KeyedVector<String8, sp<ResourceTypeSet> >* getResources() { return mRes; } 553 inline void 554 setResources(KeyedVector<String8, sp<ResourceTypeSet> >* res) { delete mRes; mRes = res; } 555 556 inline sp<FilePathStore>& getFullResPaths() { return mFullResPaths; } 557 inline void 558 setFullResPaths(sp<FilePathStore>& res) { mFullResPaths = res; } 559 560 inline sp<FilePathStore>& getFullAssetPaths() { return mFullAssetPaths; } 561 inline void 562 setFullAssetPaths(sp<FilePathStore>& res) { mFullAssetPaths = res; } 563 564private: 565 virtual ssize_t slurpFullTree(Bundle* bundle, 566 const String8& srcDir, 567 const AaptGroupEntry& kind, 568 const String8& resType, 569 sp<FilePathStore>& fullResPaths); 570 571 ssize_t slurpResourceTree(Bundle* bundle, const String8& srcDir); 572 ssize_t slurpResourceZip(Bundle* bundle, const char* filename); 573 574 status_t filter(Bundle* bundle); 575 576 String8 mPackage; 577 SortedVector<AaptGroupEntry> mGroupEntries; 578 DefaultKeyedVector<String8, sp<AaptSymbols> > mSymbols; 579 String8 mSymbolsPrivatePackage; 580 581 Vector<sp<AaptDir> > mResDirs; 582 583 bool mChanged; 584 585 bool mHaveIncludedAssets; 586 AssetManager mIncludedAssets; 587 588 sp<AaptAssets> mOverlay; 589 KeyedVector<String8, sp<ResourceTypeSet> >* mRes; 590 591 sp<FilePathStore> mFullResPaths; 592 sp<FilePathStore> mFullAssetPaths; 593}; 594 595#endif // __AAPT_ASSETS_H 596 597