From 7de2f9c73fbe93bfb7dff3c046cf7a3137599f6c Mon Sep 17 00:00:00 2001 From: Jaekyun Seok Date: Thu, 2 Mar 2017 12:45:10 +0900 Subject: Reinstate codes to enable RRO on system server Test: building succeeded and tested with sailfish Bug: 35742444 Change-Id: I99d0f1d097525d3eb46255d6cf823f6ae2a02385 --- libs/androidfw/AssetManager.cpp | 104 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) (limited to 'libs/androidfw/AssetManager.cpp') diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp index 84111ae0d499..acacd7654cf1 100644 --- a/libs/androidfw/AssetManager.cpp +++ b/libs/androidfw/AssetManager.cpp @@ -202,6 +202,15 @@ bool AssetManager::addAssetPath( *cookie = static_cast(mAssetPaths.size()); } +#ifdef __ANDROID__ + // Load overlays, if any + asset_path oap; + for (size_t idx = 0; mZipSet.getOverlay(ap.path, idx, &oap); idx++) { + oap.isSystemAsset = isSystemAsset; + mAssetPaths.add(oap); + } +#endif + if (mResources != NULL) { appendPathToResTable(ap, appAsLib); } @@ -484,6 +493,11 @@ FileType AssetManager::getFileType(const char* fileName) } bool AssetManager::appendPathToResTable(const asset_path& ap, bool appAsLib) const { + // skip those ap's that correspond to system overlays + if (ap.isSystemOverlay) { + return true; + } + Asset* ass = NULL; ResTable* sharedRes = NULL; bool shared = true; @@ -525,6 +539,14 @@ bool AssetManager::appendPathToResTable(const asset_path& ap, bool appAsLib) con ALOGV("Creating shared resources for %s", ap.path.string()); sharedRes = new ResTable(); sharedRes->add(ass, idmap, nextEntryIdx + 1, false); +#ifdef __ANDROID__ + 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); } @@ -633,6 +655,58 @@ Asset* AssetManager::openIdmapLocked(const struct asset_path& ap) const return ass; } +void AssetManager::addSystemOverlays(const char* pathOverlaysList, + const String8& targetPackagePath, ResTable* sharedRes, size_t offset) const +{ + FILE* fin = fopen(pathOverlaysList, "r"); + if (fin == NULL) { + return; + } + +#ifndef _WIN32 + if (TEMP_FAILURE_RETRY(flock(fileno(fin), LOCK_SH)) != 0) { + fclose(fin); + return; + } +#endif + char buf[1024]; + while (fgets(buf, sizeof(buf), fin)) { + // format of each line: + // + char* space = strchr(buf, ' '); + char* newline = strchr(buf, '\n'); + asset_path oap; + + if (space == NULL || newline == NULL || newline < space) { + continue; + } + + oap.path = String8(buf, space - buf); + oap.type = kFileTypeRegular; + oap.idmap = String8(space + 1, newline - space - 1); + oap.isSystemOverlay = true; + + Asset* oass = const_cast(this)-> + openNonAssetInPathLocked("resources.arsc", + Asset::ACCESS_BUFFER, + oap); + + if (oass != NULL) { + Asset* oidmap = openIdmapLocked(oap); + offset++; + sharedRes->add(oass, oidmap, offset + 1, false); + const_cast(this)->mAssetPaths.add(oap); + const_cast(this)->mZipSet.addOverlay(targetPackagePath, oap); + delete oidmap; + } + } + +#ifndef _WIN32 + TEMP_FAILURE_RETRY(flock(fileno(fin), LOCK_UN)); +#endif + fclose(fin); +} + const ResTable& AssetManager::getResources(bool required) const { const ResTable* rt = getResTable(required); @@ -1372,6 +1446,20 @@ bool AssetManager::SharedZip::isUpToDate() return mModWhen == modWhen; } +void AssetManager::SharedZip::addOverlay(const asset_path& ap) +{ + mOverlays.add(ap); +} + +bool AssetManager::SharedZip::getOverlay(size_t idx, asset_path* out) const +{ + if (idx >= mOverlays.size()) { + return false; + } + *out = mOverlays[idx]; + return true; +} + AssetManager::SharedZip::~SharedZip() { if (kIsDebug) { @@ -1490,6 +1578,22 @@ bool AssetManager::ZipSet::isUpToDate() return true; } +void AssetManager::ZipSet::addOverlay(const String8& path, const asset_path& overlay) +{ + int idx = getIndex(path); + sp zip = mZipFile[idx]; + zip->addOverlay(overlay); +} + +bool AssetManager::ZipSet::getOverlay(const String8& path, size_t idx, asset_path* out) const +{ + sp zip = SharedZip::get(path, false); + if (zip == NULL) { + return false; + } + return zip->getOverlay(idx, out); +} + /* * Compute the zip file's index. * -- cgit v1.2.3