diff options
author | Martin Kosiba <mkosiba@google.com> | 2014-01-16 16:25:56 +0000 |
---|---|---|
committer | Marcin Kosiba <mkosiba@google.com> | 2014-07-17 18:10:02 +0100 |
commit | 7df3625d5bb28d11cce9ac23429f5e3c6ebac030 (patch) | |
tree | 432f9013a91bede42c82486575b37507cd66718d | |
parent | 999d394adee533c55fce38bd632ffd4f1af91362 (diff) | |
download | frameworks_base-7df3625d5bb28d11cce9ac23429f5e3c6ebac030.zip frameworks_base-7df3625d5bb28d11cce9ac23429f5e3c6ebac030.tar.gz frameworks_base-7df3625d5bb28d11cce9ac23429f5e3c6ebac030.tar.bz2 |
Allow for appending of resources to an AssetManager.
BUG: 11505352
Change-Id: Ifa290580a6dc63c2f471d0bbf5f066db14aed4d7
-rw-r--r-- | core/java/android/content/pm/PackageParser.java | 4 | ||||
-rw-r--r-- | core/java/android/content/res/AssetManager.java | 19 | ||||
-rw-r--r-- | include/androidfw/AssetManager.h | 1 | ||||
-rw-r--r-- | libs/androidfw/AssetManager.cpp | 180 |
4 files changed, 108 insertions, 96 deletions
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index ab33d75..833dc21 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -836,10 +836,6 @@ public class PackageParser { pkg.baseCodePath = apkPath; pkg.mSignatures = null; - // TODO: Remove this when the WebView can load resources dynamically. b/11505352 - pkg.usesOptionalLibraries = ArrayUtils.add(pkg.usesOptionalLibraries, - "com.android.webview"); - return pkg; } catch (PackageParserException e) { diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java index 3a30123..2684e6c 100644 --- a/core/java/android/content/res/AssetManager.java +++ b/core/java/android/content/res/AssetManager.java @@ -100,7 +100,7 @@ public final class AssetManager implements AutoCloseable { synchronized (sSync) { if (sSystem == null) { AssetManager system = new AssetManager(true); - system.makeStringBlocks(false); + system.makeStringBlocks(null); sSystem = system; } } @@ -246,21 +246,21 @@ public final class AssetManager implements AutoCloseable { if (mStringBlocks == null) { synchronized (this) { if (mStringBlocks == null) { - makeStringBlocks(true); + makeStringBlocks(sSystem.mStringBlocks); } } } } - /*package*/ final void makeStringBlocks(boolean copyFromSystem) { - final int sysNum = copyFromSystem ? sSystem.mStringBlocks.length : 0; + /*package*/ final void makeStringBlocks(StringBlock[] seed) { + final int seedNum = (seed != null) ? seed.length : 0; final int num = getStringBlockCount(); mStringBlocks = new StringBlock[num]; if (localLOGV) Log.v(TAG, "Making string blocks for " + this + ": " + num); for (int i=0; i<num; i++) { - if (i < sysNum) { - mStringBlocks[i] = sSystem.mStringBlocks[i]; + if (i < seedNum) { + mStringBlocks[i] = seed[i]; } else { mStringBlocks[i] = new StringBlock(getNativeStringBlock(i), true); } @@ -610,8 +610,11 @@ public final class AssetManager implements AutoCloseable { * {@hide} */ public final int addAssetPath(String path) { - int res = addAssetPathNative(path); - return res; + synchronized (this) { + int res = addAssetPathNative(path); + makeStringBlocks(mStringBlocks); + return res; + } } private native final int addAssetPathNative(String path); diff --git a/include/androidfw/AssetManager.h b/include/androidfw/AssetManager.h index 610528c..99b3195 100644 --- a/include/androidfw/AssetManager.h +++ b/include/androidfw/AssetManager.h @@ -278,6 +278,7 @@ private: const ResTable* getResTable(bool required = true) const; void setLocaleLocked(const char* locale); void updateResourceParamsLocked() const; + bool appendPathToResTable(const asset_path& ap) const; Asset* openIdmapLocked(const struct asset_path& ap) const; diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp index 4ba20d7..de6a33c 100644 --- a/libs/androidfw/AssetManager.cpp +++ b/libs/androidfw/AssetManager.cpp @@ -231,6 +231,10 @@ bool AssetManager::addAssetPath(const String8& path, int32_t* cookie) } #endif + if (mResources != NULL) { + appendPathToResTable(ap); + } + return true; } @@ -596,6 +600,96 @@ FileType AssetManager::getFileType(const char* fileName) return kFileTypeRegular; } +bool AssetManager::appendPathToResTable(const asset_path& ap) const { + Asset* ass = NULL; + ResTable* sharedRes = NULL; + bool shared = true; + bool onlyEmptyResources = true; + MY_TRACE_BEGIN(ap.path.string()); + Asset* idmap = openIdmapLocked(ap); + size_t nextEntryIdx = mResources->getTableCount(); + ALOGV("Looking for resource asset in '%s'\n", ap.path.string()); + if (ap.type != kFileTypeDirectory) { + if (nextEntryIdx == 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) { + // skip ahead the number of system overlay packages preloaded + nextEntryIdx = sharedRes->getTableCount(); + } + } + 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 (nextEntryIdx == 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, idmap, nextEntryIdx + 1, false); +#ifdef HAVE_ANDROID_OS + const char* data = getenv("ANDROID_DATA"); + LOG_ALWAYS_FATAL_IF(data == NULL, "ANDROID_DATA not set"); + String8 overlaysListPath(data); + overlaysListPath.appendPath(kResourceCache); + overlaysListPath.appendPath("overlays.list"); + addSystemOverlays(overlaysListPath.string(), ap.path, sharedRes, nextEntryIdx); +#endif + sharedRes = const_cast<AssetManager*>(this)-> + mZipSet.setZipResourceTable(ap.path, sharedRes); + } + } + } else { + ALOGV("loading resource table %s\n", ap.path.string()); + ass = const_cast<AssetManager*>(this)-> + openNonAssetInPathLocked("resources.arsc", + Asset::ACCESS_BUFFER, + ap); + shared = false; + } + + if ((ass != NULL || sharedRes != NULL) && ass != kExcludedAsset) { + ALOGV("Installing resource asset %p in to table %p\n", ass, mResources); + if (sharedRes != NULL) { + ALOGV("Copying existing resources for %s", ap.path.string()); + mResources->add(sharedRes); + } else { + ALOGV("Parsing resources for %s", ap.path.string()); + mResources->add(ass, idmap, nextEntryIdx + 1, !shared); + } + onlyEmptyResources = false; + + if (!shared) { + delete ass; + } + } else { + ALOGV("Installing empty resources in to table %p\n", mResources); + mResources->addEmpty(nextEntryIdx + 1); + } + + if (idmap != NULL) { + delete idmap; + } + MY_TRACE_END(); + + return onlyEmptyResources; +} + const ResTable* AssetManager::getResTable(bool required) const { ResTable* rt = mResources; @@ -625,90 +719,8 @@ const ResTable* AssetManager::getResTable(bool required) const bool onlyEmptyResources = true; 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); - MY_TRACE_BEGIN(ap.path.string()); - 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) { - // skip ahead the number of system overlay packages preloaded - i += sharedRes->getTableCount() - 1; - } - } - 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, idmap, i + 1, false); -#ifdef HAVE_ANDROID_OS - const char* data = getenv("ANDROID_DATA"); - LOG_ALWAYS_FATAL_IF(data == NULL, "ANDROID_DATA not set"); - String8 overlaysListPath(data); - overlaysListPath.appendPath(kResourceCache); - overlaysListPath.appendPath("overlays.list"); - addSystemOverlays(overlaysListPath.string(), ap.path, sharedRes, i); -#endif - sharedRes = const_cast<AssetManager*>(this)-> - mZipSet.setZipResourceTable(ap.path, sharedRes); - } - } - } else { - ALOGV("loading resource table %s\n", ap.path.string()); - ass = const_cast<AssetManager*>(this)-> - openNonAssetInPathLocked("resources.arsc", - Asset::ACCESS_BUFFER, - ap); - shared = false; - } - - if ((ass != NULL || sharedRes != NULL) && ass != kExcludedAsset) { - ALOGV("Installing resource asset %p in to table %p\n", ass, mResources); - if (sharedRes != NULL) { - ALOGV("Copying existing resources for %s", ap.path.string()); - mResources->add(sharedRes); - } else { - ALOGV("Parsing resources for %s", ap.path.string()); - mResources->add(ass, idmap, i + 1, !shared); - } - onlyEmptyResources = false; - - if (!shared) { - delete ass; - } - } else { - ALOGV("Installing empty resources in to table %p\n", mResources); - mResources->addEmpty(i + 1); - } - - if (idmap != NULL) { - delete idmap; - } - MY_TRACE_END(); + bool empty = appendPathToResTable(mAssetPaths.itemAt(i)); + onlyEmptyResources = onlyEmptyResources && empty; } if (required && onlyEmptyResources) { |