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