From 7df3625d5bb28d11cce9ac23429f5e3c6ebac030 Mon Sep 17 00:00:00 2001 From: Martin Kosiba Date: Thu, 16 Jan 2014 16:25:56 +0000 Subject: Allow for appending of resources to an AssetManager. BUG: 11505352 Change-Id: Ifa290580a6dc63c2f471d0bbf5f066db14aed4d7 --- core/java/android/content/pm/PackageParser.java | 4 - core/java/android/content/res/AssetManager.java | 19 +-- include/androidfw/AssetManager.h | 1 + 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; igetTableCount(); + 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(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(this)-> + mZipSet.getZipResourceTableAsset(ap.path); + if (ass == NULL) { + ALOGV("loading resource table %s\n", ap.path.string()); + ass = const_cast(this)-> + openNonAssetInPathLocked("resources.arsc", + Asset::ACCESS_BUFFER, + ap); + if (ass != NULL && ass != kExcludedAsset) { + ass = const_cast(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(this)-> + mZipSet.setZipResourceTable(ap.path, sharedRes); + } + } + } else { + ALOGV("loading resource table %s\n", ap.path.string()); + ass = const_cast(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(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(this)-> - mZipSet.getZipResourceTableAsset(ap.path); - if (ass == NULL) { - ALOGV("loading resource table %s\n", ap.path.string()); - ass = const_cast(this)-> - openNonAssetInPathLocked("resources.arsc", - Asset::ACCESS_BUFFER, - ap); - if (ass != NULL && ass != kExcludedAsset) { - ass = const_cast(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(this)-> - mZipSet.setZipResourceTable(ap.path, sharedRes); - } - } - } else { - ALOGV("loading resource table %s\n", ap.path.string()); - ass = const_cast(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) { -- cgit v1.1