• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 struct AAssetManager { };
37 
38 /*
39  * Now the proper C++ android-namespace definitions
40  */
41 
42 namespace android {
43 
44 class Asset;        // fwd decl for things that include Asset.h first
45 class ResTable;
46 struct ResTable_config;
47 
48 /*
49  * Every application that uses assets needs one instance of this.  A
50  * single instance may be shared across multiple threads, and a single
51  * thread may have more than one instance (the latter is discouraged).
52  *
53  * The purpose of the AssetManager is to create Asset objects.
54  *
55  * The asset hierarchy may be examined like a filesystem, using
56  * AssetDir objects to peruse a single directory.
57  */
58 class AssetManager : public AAssetManager {
59 public:
60     static const char* RESOURCES_FILENAME;
61     static const char* IDMAP_BIN;
62     static const char* OVERLAY_DIR;
63     /*
64      * If OVERLAY_THEME_DIR_PROPERTY is set, search for runtime resource overlay
65      * APKs in OVERLAY_DIR/<value of OVERLAY_THEME_DIR_PROPERTY> in addition to
66      * OVERLAY_DIR.
67      */
68     static const char* OVERLAY_THEME_DIR_PROPERTY;
69     static const char* TARGET_PACKAGE_NAME;
70     static const char* TARGET_APK_PATH;
71     static const char* IDMAP_DIR;
72 
73     AssetManager();
74     virtual ~AssetManager(void);
75 
76     static int32_t getGlobalCount();
77 
78     /*
79      * Add a new source for assets.  This can be called multiple times to
80      * look in multiple places for assets.  It can be either a directory (for
81      * finding assets as raw files on the disk) or a ZIP file.  This newly
82      * added asset path will be examined first when searching for assets,
83      * before any that were previously added, the assets are added as shared
84      * library if appAsLib is true.
85      *
86      * Returns "true" on success, "false" on failure.  If 'cookie' is non-NULL,
87      * then on success, *cookie is set to the value corresponding to the
88      * newly-added asset source.
89      */
90     bool addAssetPath(const String8& path, int32_t* cookie,
91         bool appAsLib=false, bool isSystemAsset=false);
92     bool addOverlayPath(const String8& path, int32_t* cookie);
93 
94     /*
95      * Convenience for adding the standard system assets.  Uses the
96      * ANDROID_ROOT environment variable to find them.
97      */
98     bool addDefaultAssets();
99 
100     /*
101      * Iterate over the asset paths in this manager.  (Previously
102      * added via addAssetPath() and addDefaultAssets().)  On first call,
103      * 'cookie' must be 0, resulting in the first cookie being returned.
104      * Each next cookie will be returned there-after, until -1 indicating
105      * the end has been reached.
106      */
107     int32_t nextAssetPath(const int32_t cookie) const;
108 
109     /*
110      * Return an asset path in the manager.  'cookie' must be a non-negative value
111      * previously returned from addAssetPath() or nextAssetPath().
112      */
113     String8 getAssetPath(const int32_t cookie) const;
114 
115     /*
116      * Sets various device configuration parameters, like screen orientation, layout,
117      * size, locale, etc.
118      * The optional 'locale' string takes precedence over the locale within 'config'
119      * and must be in bcp47 format.
120      */
121     void setConfiguration(const ResTable_config& config, const char* locale = NULL);
122 
123     void getConfiguration(ResTable_config* outConfig) const;
124 
125     typedef Asset::AccessMode AccessMode;       // typing shortcut
126 
127     /*
128      * Open an asset.
129      *
130      * The object returned does not depend on the AssetManager.  It should
131      * be freed by calling Asset::close().
132      */
133     Asset* open(const char* fileName, AccessMode mode);
134 
135     /*
136      * Open a non-asset file as an asset.
137      *
138      * This is for opening files that are included in an asset package
139      * but aren't assets.  These sit outside the usual "assets/"
140      * path hierarchy, and will not be seen by "AssetDir".
141      */
142     Asset* openNonAsset(const char* fileName, AccessMode mode, int32_t* outCookie = NULL);
143 
144     /*
145      * Explicit non-asset file.  The file explicitly named by the cookie (the
146      * resource set to look in) and fileName will be opened and returned.
147      */
148     Asset* openNonAsset(const int32_t cookie, const char* fileName, AccessMode mode);
149 
150     /*
151      * Open a directory within the asset hierarchy.
152      *
153      * To open the top-level directory, pass in "".
154      */
155     AssetDir* openDir(const char* dirName);
156 
157     /*
158      * Open a directory within a particular path of the asset manager.
159      *
160      * To open the top-level directory, pass in "".
161      */
162     AssetDir* openNonAssetDir(const int32_t cookie, const char* dirName);
163 
164     /*
165      * Get the type of a file in the asset hierarchy.  They will either
166      * be "regular" or "directory".  [Currently only works for "regular".]
167      *
168      * Can also be used as a quick test for existence of a file.
169      */
170     FileType getFileType(const char* fileName);
171 
172     /*
173      * Return the complete resource table to find things in the package.
174      */
175     const ResTable& getResources(bool required = true) const;
176 
177     /*
178      * Return true if the files this AssetManager references are all
179      * up-to-date (have not been changed since it was created).  If false
180      * is returned, you will need to create a new AssetManager to get
181      * the current data.
182      */
183     bool isUpToDate();
184 
185     /**
186      * Get the known locales for this asset manager object.
187      */
188     void getLocales(Vector<String8>* locales, bool includeSystemLocales=true) const;
189 
190     /**
191      * Generate idmap data to translate resources IDs between a package and a
192      * corresponding overlay package.
193      */
194     bool createIdmap(const char* targetApkPath, const char* overlayApkPath,
195         uint32_t targetCrc, uint32_t overlayCrc, uint32_t** outData, size_t* outSize);
196 
197 private:
198     struct asset_path
199     {
asset_pathasset_path200         asset_path() : path(""), type(kFileTypeRegular), idmap(""),
201                        isSystemOverlay(false), isSystemAsset(false) {}
202         String8 path;
203         FileType type;
204         String8 idmap;
205         bool isSystemOverlay;
206         bool isSystemAsset;
207     };
208 
209     Asset* openNonAssetInPathLocked(const char* fileName, AccessMode mode,
210         const asset_path& path);
211     String8 createPathNameLocked(const asset_path& path, const char* rootDir);
212     String8 createZipSourceNameLocked(const String8& zipFileName,
213         const String8& dirName, const String8& fileName);
214 
215     ZipFileRO* getZipFileLocked(const asset_path& path);
216     Asset* openAssetFromFileLocked(const String8& fileName, AccessMode mode);
217     Asset* openAssetFromZipLocked(const ZipFileRO* pZipFile,
218         const ZipEntryRO entry, AccessMode mode, const String8& entryName);
219 
220     bool scanAndMergeDirLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
221         const asset_path& path, const char* rootDir, const char* dirName);
222     SortedVector<AssetDir::FileInfo>* scanDirLocked(const String8& path);
223     bool scanAndMergeZipLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
224         const asset_path& path, const char* rootDir, const char* dirName);
225     void mergeInfoLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
226         const SortedVector<AssetDir::FileInfo>* pContents);
227 
228     const ResTable* getResTable(bool required = true) const;
229     void setLocaleLocked(const char* locale);
230     void updateResourceParamsLocked() const;
231     bool appendPathToResTable(const asset_path& ap, bool appAsLib=false) const;
232 
233     Asset* openIdmapLocked(const struct asset_path& ap) const;
234 
235     void addSystemOverlays(const char* pathOverlaysList, const String8& targetPackagePath,
236             ResTable* sharedRes, size_t offset) const;
237 
238     class SharedZip : public RefBase {
239     public:
240         static sp<SharedZip> get(const String8& path, bool createIfNotPresent = true);
241 
242         ZipFileRO* getZip();
243 
244         Asset* getResourceTableAsset();
245         Asset* setResourceTableAsset(Asset* asset);
246 
247         ResTable* getResourceTable();
248         ResTable* setResourceTable(ResTable* res);
249 
250         bool isUpToDate();
251 
252         void addOverlay(const asset_path& ap);
253         bool getOverlay(size_t idx, asset_path* out) const;
254 
255     protected:
256         ~SharedZip();
257 
258     private:
259         SharedZip(const String8& path, time_t modWhen);
260         SharedZip(); // <-- not implemented
261 
262         String8 mPath;
263         ZipFileRO* mZipFile;
264         time_t mModWhen;
265 
266         Asset* mResourceTableAsset;
267         ResTable* mResourceTable;
268 
269         Vector<asset_path> mOverlays;
270 
271         static Mutex gLock;
272         static DefaultKeyedVector<String8, wp<SharedZip> > gOpen;
273     };
274 
275     /*
276      * Manage a set of Zip files.  For each file we need a pointer to the
277      * ZipFile and a time_t with the file's modification date.
278      *
279      * We currently only have two zip files (current app, "common" app).
280      * (This was originally written for 8, based on app/locale/vendor.)
281      */
282     class ZipSet {
283     public:
284         ZipSet() = default;
285         ~ZipSet();
286 
287         /*
288          * Return a ZipFileRO structure for a ZipFileRO with the specified
289          * parameters.
290          */
291         ZipFileRO* getZip(const String8& path);
292 
293         Asset* getZipResourceTableAsset(const String8& path);
294         Asset* setZipResourceTableAsset(const String8& path, Asset* asset);
295 
296         ResTable* getZipResourceTable(const String8& path);
297         ResTable* setZipResourceTable(const String8& path, ResTable* res);
298 
299         // generate path, e.g. "common/en-US-noogle.zip"
300         static String8 getPathName(const char* path);
301 
302         bool isUpToDate();
303 
304         void addOverlay(const String8& path, const asset_path& overlay);
305         bool getOverlay(const String8& path, size_t idx, asset_path* out) const;
306 
307     private:
308         void closeZip(int idx);
309 
310         int getIndex(const String8& zip) const;
311         mutable Vector<String8> mZipPath;
312         mutable Vector<sp<SharedZip> > mZipFile;
313     };
314 
315     // Protect all internal state.
316     mutable Mutex   mLock;
317 
318     ZipSet          mZipSet;
319 
320     Vector<asset_path> mAssetPaths;
321     char*           mLocale;
322 
323     mutable ResTable* mResources;
324     ResTable_config* mConfig;
325 };
326 
327 }; // namespace android
328 
329 #endif // __LIBS_ASSETMANAGER_H
330