diff options
-rw-r--r-- | core/jni/android_util_AssetManager.cpp | 18 | ||||
-rw-r--r-- | core/jni/fd_utils-inl.h | 37 | ||||
-rw-r--r-- | include/androidfw/AssetManager.h | 7 | ||||
-rw-r--r-- | libs/androidfw/AssetManager.cpp | 2 |
4 files changed, 55 insertions, 9 deletions
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp index 3473d9dab732..77d03433134b 100644 --- a/core/jni/android_util_AssetManager.cpp +++ b/core/jni/android_util_AssetManager.cpp @@ -25,6 +25,7 @@ #include <sys/types.h> #include <sys/wait.h> #include <sys/stat.h> +#include <sys/system_properties.h> #include <private/android_filesystem_config.h> // for AID_SYSTEM @@ -41,6 +42,7 @@ #include "ScopedUtfChars.h" #include "utils/Log.h" #include "utils/misc.h" +#include "utils/String8.h" extern "C" int capget(cap_user_header_t hdrp, cap_user_data_t datap); extern "C" int capset(cap_user_header_t hdrp, const cap_user_data_t datap); @@ -184,11 +186,19 @@ static void verifySystemIdmaps() argv[argc++] = AssetManager::TARGET_APK_PATH; argv[argc++] = AssetManager::IDMAP_DIR; - // Directories to scan for overlays - // /vendor/overlay - if (stat(AssetManager::OVERLAY_DIR, &st) == 0) { + // Directories to scan for overlays: if OVERLAY_SUBDIR_PROPERTY is defined, + // use OVERLAY_SUBDIR/<value of OVERLAY_SUBDIR_PROPERTY>/ if exists, otherwise + // use OVERLAY_DIR if exists. + char subdir[PROP_VALUE_MAX]; + int len = __system_property_get(AssetManager::OVERLAY_SUBDIR_PROPERTY, subdir); + if (len > 0) { + String8 subdirPath = String8(AssetManager::OVERLAY_SUBDIR) + "/" + subdir; + if (stat(subdirPath.string(), &st) == 0) { + argv[argc++] = subdirPath.string(); + } + } else if (stat(AssetManager::OVERLAY_DIR, &st) == 0) { argv[argc++] = AssetManager::OVERLAY_DIR; - } + } // Finally, invoke idmap (if any overlay directory exists) if (argc > 5) { diff --git a/core/jni/fd_utils-inl.h b/core/jni/fd_utils-inl.h index c67662bd8a88..5c17b23adacd 100644 --- a/core/jni/fd_utils-inl.h +++ b/core/jni/fd_utils-inl.h @@ -20,6 +20,7 @@ #include <vector> #include <algorithm> +#include <android-base/strings.h> #include <dirent.h> #include <fcntl.h> #include <grp.h> @@ -241,7 +242,8 @@ class FileDescriptorInfo { // Returns true iff. a given path is whitelisted. A path is whitelisted // if it belongs to the whitelist (see kPathWhitelist) or if it's a path - // under /system/framework that ends with ".jar". + // under /system/framework that ends with ".jar" or if it is a system + // framework overlay. static bool IsWhitelisted(const std::string& path) { for (size_t i = 0; i < (sizeof(kPathWhitelist) / sizeof(kPathWhitelist[0])); ++i) { if (kPathWhitelist[i] == path) { @@ -249,12 +251,37 @@ class FileDescriptorInfo { } } - static const std::string kFrameworksPrefix = "/system/framework/"; - static const std::string kJarSuffix = ".jar"; - if (path.compare(0, kFrameworksPrefix.size(), kFrameworksPrefix) == 0 && - path.compare(path.size() - kJarSuffix.size(), kJarSuffix.size(), kJarSuffix) == 0) { + static const char* kFrameworksPrefix = "/system/framework/"; + static const char* kJarSuffix = ".jar"; + if (android::base::StartsWith(path, kFrameworksPrefix) + && android::base::EndsWith(path, kJarSuffix)) { return true; } + + // Whitelist files needed for Runtime Resource Overlay, like these: + // /system/vendor/overlay/framework-res.apk + // /system/vendor/overlay-subdir/pg/framework-res.apk + // /data/resource-cache/system@vendor@overlay@framework-res.apk@idmap + // /data/resource-cache/system@vendor@overlay-subdir@pg@framework-res.apk@idmap + // See AssetManager.cpp for more details on overlay-subdir. + static const char* kOverlayDir = "/system/vendor/overlay/"; + static const char* kOverlaySubdir = "/system/vendor/overlay-subdir/"; + static const char* kApkSuffix = ".apk"; + + if ((android::base::StartsWith(path, kOverlayDir) + || android::base::StartsWith(path, kOverlaySubdir)) + && android::base::EndsWith(path, kApkSuffix) + && path.find("/../") == std::string::npos) { + return true; + } + + static const char* kOverlayIdmapPrefix = "/data/resource-cache/"; + static const char* kOverlayIdmapSuffix = ".apk@idmap"; + if (android::base::StartsWith(path, kOverlayIdmapPrefix) + && android::base::EndsWith(path, kOverlayIdmapSuffix)) { + return true; + } + return false; } diff --git a/include/androidfw/AssetManager.h b/include/androidfw/AssetManager.h index 914ac3d52421..0b2280239260 100644 --- a/include/androidfw/AssetManager.h +++ b/include/androidfw/AssetManager.h @@ -72,6 +72,13 @@ public: static const char* RESOURCES_FILENAME; static const char* IDMAP_BIN; static const char* OVERLAY_DIR; + /* + * If OVERLAY_SUBDIR_PROPERTY is set, search for runtime resource overlay + * APKs in OVERLAY_SUBDIR/<value of OVERLAY_SUBDIR_PROPERTY>/ rather than in + * OVERLAY_DIR. + */ + static const char* OVERLAY_SUBDIR; + static const char* OVERLAY_SUBDIR_PROPERTY; static const char* TARGET_PACKAGE_NAME; static const char* TARGET_APK_PATH; static const char* IDMAP_DIR; diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp index f50cff4387d2..6fb57fafe5c0 100644 --- a/libs/androidfw/AssetManager.cpp +++ b/libs/androidfw/AssetManager.cpp @@ -78,6 +78,8 @@ const char* AssetManager::IDMAP_BIN = "/system/bin/idmap"; const char* AssetManager::OVERLAY_DIR = "/vendor/overlay"; const char* AssetManager::TARGET_PACKAGE_NAME = "android"; const char* AssetManager::TARGET_APK_PATH = "/system/framework/framework-res.apk"; +const char* AssetManager::OVERLAY_SUBDIR = "/system/vendor/overlay-subdir"; +const char* AssetManager::OVERLAY_SUBDIR_PROPERTY = "ro.boot.vendor.overlay.subdir"; const char* AssetManager::IDMAP_DIR = "/data/resource-cache"; namespace { |