diff options
author | yingying <yingying@codeaurora.org> | 2014-09-04 10:36:54 +0800 |
---|---|---|
committer | Shaoxu Liu <shaoxu@codeaurora.org> | 2015-10-23 17:33:59 +0800 |
commit | f1642d87c5cc6783f5ef16e3cbadbd098f086111 (patch) | |
tree | fa7a57c0891ef35e19eed6ec40bed775adc44c40 | |
parent | caaba96fcb34849406e362759931ffa4340a89c5 (diff) | |
download | frameworks_base-f1642d87c5cc6783f5ef16e3cbadbd098f086111.zip frameworks_base-f1642d87c5cc6783f5ef16e3cbadbd098f086111.tar.gz frameworks_base-f1642d87c5cc6783f5ef16e3cbadbd098f086111.tar.bz2 |
base: Fix the problems for runtime overlay.
- There is no need to make the string blocking when adding the asset
path, as it will be made by the resources.
- After adding the overlay path, it also needs to update the string
blocks.
- Scan all the sub folders for framework overlay res.
Change-Id: Iaad019111ae364c319e58dce57dbf4647b38d4c3
CRs-Fixed: 763809
-rw-r--r-- | cmds/idmap/scan.cpp | 99 | ||||
-rw-r--r-- | core/java/android/content/res/AssetManager.java | 9 | ||||
-rw-r--r-- | include/androidfw/AssetManager.h | 2 | ||||
-rw-r--r-- | libs/androidfw/AssetManager.cpp | 31 |
4 files changed, 83 insertions, 58 deletions
diff --git a/cmds/idmap/scan.cpp b/cmds/idmap/scan.cpp index 612a7eb..6a6d8dc 100644 --- a/cmds/idmap/scan.cpp +++ b/cmds/idmap/scan.cpp @@ -165,6 +165,62 @@ namespace { delete dataMap; return priority; } + + int idmap_scan(const char *overlay_dir, const char *target_package_name, + const char *target_apk_path, const char *idmap_dir, + SortedVector<Overlay>& overlayVector) + { + DIR *dir = opendir(overlay_dir); + if (dir == NULL) { + return EXIT_FAILURE; + } + + struct dirent *dirent; + while ((dirent = readdir(dir)) != NULL) { + struct stat st; + char overlay_apk_path[PATH_MAX + 1]; + snprintf(overlay_apk_path, PATH_MAX, "%s/%s", overlay_dir, dirent->d_name); + if (stat(overlay_apk_path, &st) < 0) { + continue; + } + if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) { + continue; + } + + if (S_ISDIR(st.st_mode)) { + String8 dir_name = String8(overlay_apk_path).getPathLeaf(); + if (dir_name == "." || dir_name == "..") { + // Skip the "." and ".." dir. + continue; + } + idmap_scan(overlay_apk_path, target_package_name, target_apk_path, idmap_dir, + overlayVector); + } else { + int priority = parse_apk(overlay_apk_path, target_package_name); + if (priority < 0) { + continue; + } + + String8 idmap_path(idmap_dir); + idmap_path.appendPath(flatten_path(overlay_apk_path + 1)); + idmap_path.append("@idmap"); + + if (idmap_create_path(target_apk_path, overlay_apk_path, + idmap_path.string()) != 0) { + ALOGE("error: failed to create idmap for target=%s overlay=%s idmap=%s\n", + target_apk_path, overlay_apk_path, idmap_path.string()); + continue; + } + + Overlay overlay(String8(overlay_apk_path), idmap_path, priority); + overlayVector.add(overlay); + } + } + + closedir(dir); + + return EXIT_SUCCESS; + } } int idmap_scan(const char *overlay_dir, const char *target_package_name, @@ -176,48 +232,13 @@ int idmap_scan(const char *overlay_dir, const char *target_package_name, return EXIT_FAILURE; } - DIR *dir = opendir(overlay_dir); - if (dir == NULL) { - return EXIT_FAILURE; - } - SortedVector<Overlay> overlayVector; - struct dirent *dirent; - while ((dirent = readdir(dir)) != NULL) { - struct stat st; - char overlay_apk_path[PATH_MAX + 1]; - snprintf(overlay_apk_path, PATH_MAX, "%s/%s", overlay_dir, dirent->d_name); - if (stat(overlay_apk_path, &st) < 0) { - continue; - } - if (!S_ISREG(st.st_mode)) { - continue; - } - - int priority = parse_apk(overlay_apk_path, target_package_name); - if (priority < 0) { - continue; - } - - String8 idmap_path(idmap_dir); - idmap_path.appendPath(flatten_path(overlay_apk_path + 1)); - idmap_path.append("@idmap"); - - if (idmap_create_path(target_apk_path, overlay_apk_path, idmap_path.string()) != 0) { - ALOGE("error: failed to create idmap for target=%s overlay=%s idmap=%s\n", - target_apk_path, overlay_apk_path, idmap_path.string()); - continue; - } - - Overlay overlay(String8(overlay_apk_path), idmap_path, priority); - overlayVector.add(overlay); - } - - closedir(dir); + int res = idmap_scan(overlay_dir, target_package_name, target_apk_path, idmap_dir, + overlayVector); - if (!writePackagesList(filename.string(), overlayVector)) { + if (res == EXIT_FAILURE || !writePackagesList(filename.string(), overlayVector)) { return EXIT_FAILURE; } - return EXIT_SUCCESS; + return res; } diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java index 8d96f5c..17b662a 100644 --- a/core/java/android/content/res/AssetManager.java +++ b/core/java/android/content/res/AssetManager.java @@ -612,7 +612,9 @@ public final class AssetManager implements AutoCloseable { public final int addAssetPath(String path) { synchronized (this) { int res = addAssetPathNative(path); - makeStringBlocks(mStringBlocks); + if (mStringBlocks != null) { + makeStringBlocks(mStringBlocks); + } return res; } } @@ -627,11 +629,12 @@ public final class AssetManager implements AutoCloseable { * * {@hide} */ - public final int addOverlayPath(String idmapPath) { synchronized (this) { int res = addOverlayPathNative(idmapPath); - makeStringBlocks(mStringBlocks); + if (mStringBlocks != null) { + makeStringBlocks(mStringBlocks); + } return res; } } diff --git a/include/androidfw/AssetManager.h b/include/androidfw/AssetManager.h index 0cfd2b1..0cfc270 100644 --- a/include/androidfw/AssetManager.h +++ b/include/androidfw/AssetManager.h @@ -280,7 +280,7 @@ private: const ResTable* getResTable(bool required = true) const; void setLocaleLocked(const char* locale); void updateResourceParamsLocked() const; - bool appendPathToResTable(const asset_path& ap) const; + bool appendPathToResTable(const asset_path& ap, size_t* entryIdx) const; Asset* openIdmapLocked(const struct asset_path& ap) const; diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp index 2dc1c96..4f62204 100644 --- a/libs/androidfw/AssetManager.cpp +++ b/libs/androidfw/AssetManager.cpp @@ -224,6 +224,11 @@ bool AssetManager::addAssetPath(const String8& path, int32_t* cookie) mAssetPaths.add(ap); + if (mResources != NULL) { + size_t index = mAssetPaths.size() - 1; + appendPathToResTable(ap, &index); + } + // new paths are always added at the end if (cookie) { *cookie = static_cast<int32_t>(mAssetPaths.size()); @@ -237,10 +242,6 @@ bool AssetManager::addAssetPath(const String8& path, int32_t* cookie) } #endif - if (mResources != NULL) { - appendPathToResTable(ap); - } - return true; } @@ -303,7 +304,8 @@ bool AssetManager::addOverlayPath(const String8& packagePath, int32_t* cookie) *cookie = static_cast<int32_t>(mAssetPaths.size()); if (mResources != NULL) { - appendPathToResTable(oap); + size_t index = mAssetPaths.size() - 1; + appendPathToResTable(oap, &index); } return true; @@ -610,7 +612,7 @@ FileType AssetManager::getFileType(const char* fileName) return kFileTypeRegular; } -bool AssetManager::appendPathToResTable(const asset_path& ap) const { +bool AssetManager::appendPathToResTable(const asset_path& ap, size_t* entryIdx) const { // skip those ap's that correspond to system overlays if (ap.isSystemOverlay) { return true; @@ -622,17 +624,16 @@ bool AssetManager::appendPathToResTable(const asset_path& ap) const { 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) { + if (*entryIdx == 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(); + *entryIdx += sharedRes->getTableCount() - 1; } } if (sharedRes == NULL) { @@ -650,20 +651,20 @@ bool AssetManager::appendPathToResTable(const asset_path& ap) const { } } - if (nextEntryIdx == 0 && ass != NULL) { + if (*entryIdx == 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); + sharedRes->add(ass, idmap, *entryIdx + 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); + addSystemOverlays(overlaysListPath.string(), ap.path, sharedRes, *entryIdx); #endif sharedRes = const_cast<AssetManager*>(this)-> mZipSet.setZipResourceTable(ap.path, sharedRes); @@ -685,7 +686,7 @@ bool AssetManager::appendPathToResTable(const asset_path& ap) const { mResources->add(sharedRes); } else { ALOGV("Parsing resources for %s", ap.path.string()); - mResources->add(ass, idmap, nextEntryIdx + 1, !shared); + mResources->add(ass, idmap, *entryIdx + 1, !shared); } onlyEmptyResources = false; @@ -694,7 +695,7 @@ bool AssetManager::appendPathToResTable(const asset_path& ap) const { } } else { ALOGV("Installing empty resources in to table %p\n", mResources); - mResources->addEmpty(nextEntryIdx + 1); + mResources->addEmpty(*entryIdx + 1); } if (idmap != NULL) { @@ -734,7 +735,7 @@ const ResTable* AssetManager::getResTable(bool required) const bool onlyEmptyResources = true; const size_t N = mAssetPaths.size(); for (size_t i=0; i<N; i++) { - bool empty = appendPathToResTable(mAssetPaths.itemAt(i)); + bool empty = appendPathToResTable(mAssetPaths.itemAt(i), &i); onlyEmptyResources = onlyEmptyResources && empty; } |