OSDN Git Service

resolve merge conflicts of 56a2b529373b to nyc-dev am: d7dcc3e227 am: 34377e0357
[android-x86/frameworks-base.git] / include / androidfw / AssetManager.h
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 //
18 // Asset management class.  AssetManager objects are thread-safe.
19 //
20 #ifndef __LIBS_ASSETMANAGER_H
21 #define __LIBS_ASSETMANAGER_H
22
23 #include <androidfw/Asset.h>
24 #include <androidfw/AssetDir.h>
25 #include <androidfw/ZipFileRO.h>
26 #include <utils/KeyedVector.h>
27 #include <utils/SortedVector.h>
28 #include <utils/String16.h>
29 #include <utils/String8.h>
30 #include <utils/threads.h>
31 #include <utils/Vector.h>
32
33 /*
34  * Native-app access is via the opaque typedef struct AAssetManager in the C namespace.
35  */
36 #ifdef __cplusplus
37 extern "C" {
38 #endif
39
40 struct AAssetManager { };
41
42 #ifdef __cplusplus
43 };
44 #endif
45
46
47 /*
48  * Now the proper C++ android-namespace definitions
49  */
50
51 namespace android {
52
53 class Asset;        // fwd decl for things that include Asset.h first
54 class ResTable;
55 struct ResTable_config;
56
57 /*
58  * Every application that uses assets needs one instance of this.  A
59  * single instance may be shared across multiple threads, and a single
60  * thread may have more than one instance (the latter is discouraged).
61  *
62  * The purpose of the AssetManager is to create Asset objects.  To do
63  * this efficiently it may cache information about the locations of
64  * files it has seen.  This can be controlled with the "cacheMode"
65  * argument.
66  *
67  * The asset hierarchy may be examined like a filesystem, using
68  * AssetDir objects to peruse a single directory.
69  */
70 class AssetManager : public AAssetManager {
71 public:
72     static const char* RESOURCES_FILENAME;
73     static const char* IDMAP_BIN;
74     static const char* OVERLAY_DIR;
75     /*
76      * If OVERLAY_THEME_DIR_PROPERTY is set, search for runtime resource overlay
77      * APKs in OVERLAY_DIR/<value of OVERLAY_THEME_DIR_PROPERTY> in addition to
78      * OVERLAY_DIR.
79      */
80     static const char* OVERLAY_THEME_DIR_PROPERTY;
81     static const char* TARGET_PACKAGE_NAME;
82     static const char* TARGET_APK_PATH;
83     static const char* IDMAP_DIR;
84
85     typedef enum CacheMode {
86         CACHE_UNKNOWN = 0,
87         CACHE_OFF,          // don't try to cache file locations
88         CACHE_DEFER,        // construct cache as pieces are needed
89         //CACHE_SCAN,         // scan full(!) asset hierarchy at init() time
90     } CacheMode;
91
92     AssetManager(CacheMode cacheMode = CACHE_OFF);
93     virtual ~AssetManager(void);
94
95     static int32_t getGlobalCount();
96     
97     /*                                                                       
98      * Add a new source for assets.  This can be called multiple times to
99      * look in multiple places for assets.  It can be either a directory (for
100      * finding assets as raw files on the disk) or a ZIP file.  This newly
101      * added asset path will be examined first when searching for assets,
102      * before any that were previously added, the assets are added as shared
103      * library if appAsLib is true.
104      *
105      * Returns "true" on success, "false" on failure.  If 'cookie' is non-NULL,
106      * then on success, *cookie is set to the value corresponding to the
107      * newly-added asset source.
108      */
109     bool addAssetPath(const String8& path, int32_t* cookie,
110         bool appAsLib=false, bool isSystemAsset=false);
111     bool addOverlayPath(const String8& path, int32_t* cookie);
112
113     /*
114      * Convenience for adding the standard system assets.  Uses the
115      * ANDROID_ROOT environment variable to find them.
116      */
117     bool addDefaultAssets();
118
119     /*
120      * Iterate over the asset paths in this manager.  (Previously
121      * added via addAssetPath() and addDefaultAssets().)  On first call,
122      * 'cookie' must be 0, resulting in the first cookie being returned.
123      * Each next cookie will be returned there-after, until -1 indicating
124      * the end has been reached.
125      */
126     int32_t nextAssetPath(const int32_t cookie) const;
127
128     /*
129      * Return an asset path in the manager.  'which' must be between 0 and
130      * countAssetPaths().
131      */
132     String8 getAssetPath(const int32_t cookie) const;
133
134     /*
135      * Set the current locale and vendor.  The locale can change during
136      * the lifetime of an AssetManager if the user updates the device's
137      * language setting.  The vendor is less likely to change.
138      *
139      * Pass in NULL to indicate no preference.
140      */
141     void setLocale(const char* locale);
142     void setVendor(const char* vendor);
143
144     /*
145      * Choose screen orientation for resources values returned.
146      */
147     void setConfiguration(const ResTable_config& config, const char* locale = NULL);
148
149     void getConfiguration(ResTable_config* outConfig) const;
150
151     typedef Asset::AccessMode AccessMode;       // typing shortcut
152
153     /*
154      * Open an asset.
155      *
156      * This will search through locale-specific and vendor-specific
157      * directories and packages to find the file.
158      *
159      * The object returned does not depend on the AssetManager.  It should
160      * be freed by calling Asset::close().
161      */
162     Asset* open(const char* fileName, AccessMode mode);
163
164     /*
165      * Open a non-asset file as an asset.
166      *
167      * This is for opening files that are included in an asset package
168      * but aren't assets.  These sit outside the usual "locale/vendor"
169      * path hierarchy, and will not be seen by "AssetDir" or included
170      * in our filename cache.
171      */
172     Asset* openNonAsset(const char* fileName, AccessMode mode, int32_t* outCookie = NULL);
173
174     /*
175      * Explicit non-asset file.  The file explicitly named by the cookie (the
176      * resource set to look in) and fileName will be opened and returned.
177      */
178     Asset* openNonAsset(const int32_t cookie, const char* fileName, AccessMode mode);
179
180     /*
181      * Open a directory within the asset hierarchy.
182      *
183      * The contents of the directory are an amalgam of vendor-specific,
184      * locale-specific, and generic assets stored loosely or in asset
185      * packages.  Depending on the cache setting and previous accesses,
186      * this call may incur significant disk overhead.
187      *
188      * To open the top-level directory, pass in "".
189      */
190     AssetDir* openDir(const char* dirName);
191
192     /*
193      * Open a directory within a particular path of the asset manager.
194      *
195      * The contents of the directory are an amalgam of vendor-specific,
196      * locale-specific, and generic assets stored loosely or in asset
197      * packages.  Depending on the cache setting and previous accesses,
198      * this call may incur significant disk overhead.
199      *
200      * To open the top-level directory, pass in "".
201      */
202     AssetDir* openNonAssetDir(const int32_t cookie, const char* dirName);
203
204     /*
205      * Get the type of a file in the asset hierarchy.  They will either
206      * be "regular" or "directory".  [Currently only works for "regular".]
207      *
208      * Can also be used as a quick test for existence of a file.
209      */
210     FileType getFileType(const char* fileName);
211
212     /*                                                                       
213      * Return the complete resource table to find things in the package.
214      */
215     const ResTable& getResources(bool required = true) const;
216
217     /*
218      * Discard cached filename information.  This only needs to be called
219      * if somebody has updated the set of "loose" files, and we want to
220      * discard our cached notion of what's where.
221      */
222     void purge(void) { purgeFileNameCacheLocked(); }
223
224     /*
225      * Return true if the files this AssetManager references are all
226      * up-to-date (have not been changed since it was created).  If false
227      * is returned, you will need to create a new AssetManager to get
228      * the current data.
229      */
230     bool isUpToDate();
231
232     /**
233      * Get the known locales for this asset manager object.
234      */
235     void getLocales(Vector<String8>* locales, bool includeSystemLocales=true) const;
236
237     /**
238      * Generate idmap data to translate resources IDs between a package and a
239      * corresponding overlay package.
240      */
241     bool createIdmap(const char* targetApkPath, const char* overlayApkPath,
242         uint32_t targetCrc, uint32_t overlayCrc, uint32_t** outData, size_t* outSize);
243
244 private:
245     struct asset_path
246     {
247         asset_path() : path(""), type(kFileTypeRegular), idmap(""),
248                        isSystemOverlay(false), isSystemAsset(false) {}
249         String8 path;
250         FileType type;
251         String8 idmap;
252         bool isSystemOverlay;
253         bool isSystemAsset;
254     };
255
256     Asset* openInPathLocked(const char* fileName, AccessMode mode,
257         const asset_path& path);
258     Asset* openNonAssetInPathLocked(const char* fileName, AccessMode mode,
259         const asset_path& path);
260     Asset* openInLocaleVendorLocked(const char* fileName, AccessMode mode,
261         const asset_path& path, const char* locale, const char* vendor);
262     String8 createPathNameLocked(const asset_path& path, const char* locale,
263         const char* vendor);
264     String8 createPathNameLocked(const asset_path& path, const char* rootDir);
265     String8 createZipSourceNameLocked(const String8& zipFileName,
266         const String8& dirName, const String8& fileName);
267
268     ZipFileRO* getZipFileLocked(const asset_path& path);
269     Asset* openAssetFromFileLocked(const String8& fileName, AccessMode mode);
270     Asset* openAssetFromZipLocked(const ZipFileRO* pZipFile,
271         const ZipEntryRO entry, AccessMode mode, const String8& entryName);
272
273     bool scanAndMergeDirLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
274         const asset_path& path, const char* rootDir, const char* dirName);
275     SortedVector<AssetDir::FileInfo>* scanDirLocked(const String8& path);
276     bool scanAndMergeZipLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
277         const asset_path& path, const char* rootDir, const char* dirName);
278     void mergeInfoLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
279         const SortedVector<AssetDir::FileInfo>* pContents);
280
281     void loadFileNameCacheLocked(void);
282     void fncScanLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
283         const char* dirName);
284     bool fncScanAndMergeDirLocked(
285         SortedVector<AssetDir::FileInfo>* pMergedInfo,
286         const asset_path& path, const char* locale, const char* vendor,
287         const char* dirName);
288     void purgeFileNameCacheLocked(void);
289
290     const ResTable* getResTable(bool required = true) const;
291     void setLocaleLocked(const char* locale);
292     void updateResourceParamsLocked() const;
293     bool appendPathToResTable(const asset_path& ap, bool appAsLib=false) const;
294
295     Asset* openIdmapLocked(const struct asset_path& ap) const;
296
297     void addSystemOverlays(const char* pathOverlaysList, const String8& targetPackagePath,
298             ResTable* sharedRes, size_t offset) const;
299
300     class SharedZip : public RefBase {
301     public:
302         static sp<SharedZip> get(const String8& path, bool createIfNotPresent = true);
303
304         ZipFileRO* getZip();
305
306         Asset* getResourceTableAsset();
307         Asset* setResourceTableAsset(Asset* asset);
308
309         ResTable* getResourceTable();
310         ResTable* setResourceTable(ResTable* res);
311         
312         bool isUpToDate();
313
314         void addOverlay(const asset_path& ap);
315         bool getOverlay(size_t idx, asset_path* out) const;
316         
317     protected:
318         ~SharedZip();
319
320     private:
321         SharedZip(const String8& path, time_t modWhen);
322         SharedZip(); // <-- not implemented
323
324         String8 mPath;
325         ZipFileRO* mZipFile;
326         time_t mModWhen;
327
328         Asset* mResourceTableAsset;
329         ResTable* mResourceTable;
330
331         Vector<asset_path> mOverlays;
332
333         static Mutex gLock;
334         static DefaultKeyedVector<String8, wp<SharedZip> > gOpen;
335     };
336
337     /*
338      * Manage a set of Zip files.  For each file we need a pointer to the
339      * ZipFile and a time_t with the file's modification date.
340      *
341      * We currently only have two zip files (current app, "common" app).
342      * (This was originally written for 8, based on app/locale/vendor.)
343      */
344     class ZipSet {
345     public:
346         ZipSet(void);
347         ~ZipSet(void);
348
349         /*
350          * Return a ZipFileRO structure for a ZipFileRO with the specified
351          * parameters.
352          */
353         ZipFileRO* getZip(const String8& path);
354
355         Asset* getZipResourceTableAsset(const String8& path);
356         Asset* setZipResourceTableAsset(const String8& path, Asset* asset);
357
358         ResTable* getZipResourceTable(const String8& path);
359         ResTable* setZipResourceTable(const String8& path, ResTable* res);
360
361         // generate path, e.g. "common/en-US-noogle.zip"
362         static String8 getPathName(const char* path);
363
364         bool isUpToDate();
365
366         void addOverlay(const String8& path, const asset_path& overlay);
367         bool getOverlay(const String8& path, size_t idx, asset_path* out) const;
368         
369     private:
370         void closeZip(int idx);
371
372         int getIndex(const String8& zip) const;
373         mutable Vector<String8> mZipPath;
374         mutable Vector<sp<SharedZip> > mZipFile;
375     };
376
377     // Protect all internal state.
378     mutable Mutex   mLock;
379
380     ZipSet          mZipSet;
381
382     Vector<asset_path> mAssetPaths;
383     char*           mLocale;
384     char*           mVendor;
385
386     mutable ResTable* mResources;
387     ResTable_config* mConfig;
388
389     /*
390      * Cached data for "loose" files.  This lets us avoid poking at the
391      * filesystem when searching for loose assets.  Each entry is the
392      * "extended partial" path, e.g. "default/default/foo/bar.txt".  The
393      * full set of files is present, including ".EXCLUDE" entries.
394      *
395      * We do not cache directory names.  We don't retain the ".gz",
396      * because to our clients "foo" and "foo.gz" both look like "foo".
397      */
398     CacheMode       mCacheMode;         // is the cache enabled?
399     bool            mCacheValid;        // clear when locale or vendor changes
400     SortedVector<AssetDir::FileInfo> mCache;
401 };
402
403 }; // namespace android
404
405 #endif // __LIBS_ASSETMANAGER_H