diff options
Diffstat (limited to 'libs/utils/AssetManager.cpp')
-rw-r--r-- | libs/utils/AssetManager.cpp | 210 |
1 files changed, 138 insertions, 72 deletions
diff --git a/libs/utils/AssetManager.cpp b/libs/utils/AssetManager.cpp index 22034c5..4733e78 100644 --- a/libs/utils/AssetManager.cpp +++ b/libs/utils/AssetManager.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2006 The Android Open Source Project + * This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -134,7 +135,7 @@ AssetManager::~AssetManager(void) delete[] mVendor; } -bool AssetManager::addAssetPath(const String8& path, void** cookie) +bool AssetManager::addAssetPath(const String8& path, void** cookie, bool asSkin) { AutoMutex _l(mLock); @@ -144,6 +145,7 @@ bool AssetManager::addAssetPath(const String8& path, void** cookie) if (kAppZipName) { realPath.appendPath(kAppZipName); } + ap.asSkin = asSkin; ap.type = ::getFileType(realPath.string()); if (ap.type == kFileTypeRegular) { ap.path = realPath; @@ -498,9 +500,13 @@ Asset* AssetManager::open(const char* fileName, AccessMode mode) size_t i = mAssetPaths.size(); while (i > 0) { i--; + const asset_path& ap = mAssetPaths.itemAt(i); + if (ap.asSkin) { + continue; + } LOGV("Looking for asset '%s' in '%s'\n", - assetName.string(), mAssetPaths.itemAt(i).path.string()); - Asset* pAsset = openNonAssetInPathLocked(assetName.string(), mode, mAssetPaths.itemAt(i)); + assetName.string(), ap.path.string()); + Asset* pAsset = openNonAssetInPathLocked(assetName.string(), mode, ap); if (pAsset != NULL) { return pAsset != kExcludedAsset ? pAsset : NULL; } @@ -532,9 +538,13 @@ Asset* AssetManager::openNonAsset(const char* fileName, AccessMode mode) size_t i = mAssetPaths.size(); while (i > 0) { i--; - LOGV("Looking for non-asset '%s' in '%s'\n", fileName, mAssetPaths.itemAt(i).path.string()); + const asset_path& ap = mAssetPaths.itemAt(i); + if (ap.asSkin) { + continue; + } + LOGV("Looking for non-asset '%s' in '%s'\n", fileName, ap.path.string()); Asset* pAsset = openNonAssetInPathLocked( - fileName, mode, mAssetPaths.itemAt(i)); + fileName, mode, ap); if (pAsset != NULL) { return pAsset != kExcludedAsset ? pAsset : NULL; } @@ -614,83 +624,87 @@ const ResTable* AssetManager::getResTable(bool required) const if (mCacheMode != CACHE_OFF && !mCacheValid) const_cast<AssetManager*>(this)->loadFileNameCacheLocked(); - const size_t N = mAssetPaths.size(); - for (size_t i=0; i<N; i++) { - Asset* ass = NULL; - ResTable* sharedRes = NULL; - bool shared = true; - const asset_path& ap = mAssetPaths.itemAt(i); - Asset* idmap = openIdmapLocked(ap); - LOGV("Looking for resource asset in '%s'\n", ap.path.string()); - if (ap.type != kFileTypeDirectory) { - if (i == 0) { - // The first item is typically the framework resources, - // which we want to avoid parsing every time. - sharedRes = const_cast<AssetManager*>(this)-> - mZipSet.getZipResourceTable(ap.path); - } - if (sharedRes == NULL) { + mResources = rt = new ResTable(); + + if (rt) { + const size_t N = mAssetPaths.size(); + for (size_t i=0; i<N; i++) { + const asset_path& ap = mAssetPaths.itemAt(i); + updateResTableFromAssetPath(rt, ap, (void*)(i+1)); + } + } + + if (required && !rt) LOGW("Unable to find resources file resources.arsc"); + if (!rt) { + mResources = rt = new ResTable(); + } + + return rt; +} + +void AssetManager::updateResTableFromAssetPath(ResTable *rt, const asset_path& ap, void *cookie) const +{ + Asset* ass = NULL; + ResTable* sharedRes = NULL; + bool shared = true; + size_t cookiePos = (size_t)cookie; + LOGV("Looking for resource asset in '%s'\n", ap.path.string()); + if (ap.type != kFileTypeDirectory) { + if (cookiePos == 1) { + // The first item is typically the framework resources, + // which we want to avoid parsing every time. + sharedRes = const_cast<AssetManager*>(this)-> + mZipSet.getZipResourceTable(ap.path); + } + if (sharedRes == NULL) { + ass = const_cast<AssetManager*>(this)-> + mZipSet.getZipResourceTableAsset(ap.path); + if (ass == NULL) { + LOGV("loading resource table %s\n", ap.path.string()); ass = const_cast<AssetManager*>(this)-> - mZipSet.getZipResourceTableAsset(ap.path); - if (ass == NULL) { - LOGV("loading resource table %s\n", ap.path.string()); + openNonAssetInPathLocked("resources.arsc", + Asset::ACCESS_BUFFER, + ap); + if (ass != NULL && ass != kExcludedAsset) { ass = const_cast<AssetManager*>(this)-> - openNonAssetInPathLocked("resources.arsc", - Asset::ACCESS_BUFFER, - ap); - if (ass != NULL && ass != kExcludedAsset) { - ass = const_cast<AssetManager*>(this)-> - mZipSet.setZipResourceTableAsset(ap.path, ass); - } - } - - if (i == 0 && ass != NULL) { - // If this is the first resource table in the asset - // manager, then we are going to cache it so that we - // can quickly copy it out for others. - LOGV("Creating shared resources for %s", ap.path.string()); - sharedRes = new ResTable(); - sharedRes->add(ass, (void*)(i+1), false, idmap); - sharedRes = const_cast<AssetManager*>(this)-> - mZipSet.setZipResourceTable(ap.path, sharedRes); + mZipSet.setZipResourceTableAsset(ap.path, ass); } } - } else { - LOGV("loading resource table %s\n", ap.path.string()); - Asset* ass = const_cast<AssetManager*>(this)-> - openNonAssetInPathLocked("resources.arsc", - Asset::ACCESS_BUFFER, - ap); - shared = false; - } - if ((ass != NULL || sharedRes != NULL) && ass != kExcludedAsset) { - if (rt == NULL) { - mResources = rt = new ResTable(); - updateResourceParamsLocked(); - } - LOGV("Installing resource asset %p in to table %p\n", ass, mResources); - if (sharedRes != NULL) { - LOGV("Copying existing resources for %s", ap.path.string()); - rt->add(sharedRes); - } else { - LOGV("Parsing resources for %s", ap.path.string()); - rt->add(ass, (void*)(i+1), !shared, idmap); - } - if (!shared) { - delete ass; + if (cookiePos == 0 && ass != NULL) { + // If this is the first resource table in the asset + // manager, then we are going to cache it so that we + // can quickly copy it out for others. + LOGV("Creating shared resources for %s", ap.path.string()); + sharedRes = new ResTable(); + sharedRes->add(ass, cookie, false); + sharedRes = const_cast<AssetManager*>(this)-> + mZipSet.setZipResourceTable(ap.path, sharedRes); } } - if (idmap != NULL) { - delete idmap; + } else { + LOGV("loading resource table %s\n", ap.path.string()); + Asset* ass = const_cast<AssetManager*>(this)-> + openNonAssetInPathLocked("resources.arsc", + Asset::ACCESS_BUFFER, + ap); + shared = false; + } + if ((ass != NULL || sharedRes != NULL) && ass != kExcludedAsset) { + updateResourceParamsLocked(); + LOGV("Installing resource asset %p in to table %p\n", ass, mResources); + if (sharedRes != NULL) { + LOGV("Copying existing resources for %s", ap.path.string()); + rt->add(sharedRes); + } else { + LOGV("Parsing resources for %s", ap.path.string()); + rt->add(ass, cookie, !shared); } - } - if (required && !rt) LOGW("Unable to find resources file resources.arsc"); - if (!rt) { - mResources = rt = new ResTable(); + if (!shared) { + delete ass; + } } - return rt; } void AssetManager::updateResourceParamsLocked() const @@ -1145,6 +1159,9 @@ AssetDir* AssetManager::openDir(const char* dirName) while (i > 0) { i--; const asset_path& ap = mAssetPaths.itemAt(i); + if (ap.asSkin) { + continue; + } if (ap.type == kFileTypeRegular) { LOGV("Adding directory %s from zip %s", dirName, ap.path.string()); scanAndMergeZipLocked(pMergedInfo, ap, kAssetsRoot, dirName); @@ -1999,3 +2016,52 @@ int AssetManager::ZipSet::getIndex(const String8& zip) const return mZipPath.size()-1; } + +bool AssetManager::attachThemePath(const String8& path, void** cookie) +{ + bool res = addAssetPath(path, cookie, true); + ResTable* rt = mResources; + if (res && rt != NULL && ((size_t)*cookie == mAssetPaths.size())) { + AutoMutex _l(mLock); + const asset_path& ap = mAssetPaths.itemAt((size_t)*cookie - 1); + updateResTableFromAssetPath(rt, ap, *cookie); + } + return res; +} + +bool AssetManager::detachThemePath(const String8 &packageName, void* cookie) +{ + AutoMutex _l(mLock); + + const size_t which = ((size_t)cookie)-1; + if (which >= mAssetPaths.size()) { + return false; + } + + /* TODO: Ensure that this cookie is added with asSkin == true. */ + mAssetPaths.removeAt(which); + + ResTable* rt = mResources; + if (rt == NULL) { + LOGV("ResTable must not be NULL"); + return false; + } + + rt->removeAssetsByCookie(packageName, (void *)cookie); + + return true; +} + +void AssetManager::addRedirections(PackageRedirectionMap* resMap) +{ + getResources(); + ResTable* rt = mResources; + rt->addRedirections(resMap); +} + +void AssetManager::clearRedirections() +{ + getResources(); + ResTable* rt = mResources; + rt->clearRedirections(); +} |