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