OSDN Git Service

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