diff options
Diffstat (limited to 'libs/androidfw/AssetManager.cpp')
| -rw-r--r-- | libs/androidfw/AssetManager.cpp | 211 |
1 files changed, 137 insertions, 74 deletions
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp index 8bd805c..806e716 100644 --- a/libs/androidfw/AssetManager.cpp +++ b/libs/androidfw/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. @@ -152,7 +153,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); @@ -162,6 +163,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; @@ -516,9 +518,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; + } ALOGV("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; } @@ -550,9 +556,13 @@ Asset* AssetManager::openNonAsset(const char* fileName, AccessMode mode) size_t i = mAssetPaths.size(); while (i > 0) { i--; - ALOGV("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; + } + ALOGV("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; } @@ -631,76 +641,13 @@ const ResTable* AssetManager::getResTable(bool required) const if (mCacheMode != CACHE_OFF && !mCacheValid) const_cast<AssetManager*>(this)->loadFileNameCacheLocked(); + mResources = rt = new ResTable(); - 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); - ALOGV("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) { - ass = const_cast<AssetManager*>(this)-> - mZipSet.getZipResourceTableAsset(ap.path); - if (ass == NULL) { - ALOGV("loading resource table %s\n", ap.path.string()); - 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. - ALOGV("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); - } - } - } else { - ALOGV("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(); - } - ALOGV("Installing resource asset %p in to table %p\n", ass, mResources); - if (sharedRes != NULL) { - ALOGV("Copying existing resources for %s", ap.path.string()); - rt->add(sharedRes); - } else { - ALOGV("Parsing resources for %s", ap.path.string()); - rt->add(ass, (void*)(i+1), !shared, idmap); - } - - if (!shared) { - delete ass; - } - } - if (idmap != NULL) { - delete idmap; + 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)); } } @@ -708,9 +655,73 @@ const ResTable* AssetManager::getResTable(bool required) const 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; + ALOGV("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) { + ALOGV("loading resource table %s\n", ap.path.string()); + 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 (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. + ALOGV("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); + } + } + } else { + ALOGV("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(); + ALOGV("Installing resource asset %p in to table %p\n", ass, mResources); + if (sharedRes != NULL) { + ALOGV("Copying existing resources for %s", ap.path.string()); + rt->add(sharedRes); + } else { + ALOGV("Parsing resources for %s", ap.path.string()); + rt->add(ass, cookie, !shared); + } + if (!shared) { + delete ass; + } + } +} + void AssetManager::updateResourceParamsLocked() const { ResTable* res = mResources; @@ -1163,6 +1174,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) { ALOGV("Adding directory %s from zip %s", dirName, ap.path.string()); scanAndMergeZipLocked(pMergedInfo, ap, kAssetsRoot, dirName); @@ -2017,3 +2031,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) { + ALOGV("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(); +} |
