Loading core/java/android/content/Context.java +10 −0 Original line number Diff line number Diff line Loading @@ -4333,6 +4333,16 @@ public abstract class Context { */ public static final String OVERLAY_SERVICE = "overlay"; /** * Use with {@link #getSystemService(String)} to retrieve a * {android.os.IIdmap2} for managing idmap files (used by overlay * packages). * * @see #getSystemService(String) * @hide */ public static final String IDMAP_SERVICE = "idmap"; /** * Use with {@link #getSystemService(String)} to retrieve a * {@link VrManager} for accessing the VR service. Loading core/java/android/content/res/AssetManager.java +15 −3 Original line number Diff line number Diff line Loading @@ -58,6 +58,7 @@ import java.util.HashMap; public final class AssetManager implements AutoCloseable { private static final String TAG = "AssetManager"; private static final boolean DEBUG_REFS = false; private static final boolean FEATURE_FLAG_IDMAP2 = false; private static final String FRAMEWORK_APK_PATH = "/system/framework/framework-res.apk"; Loading Loading @@ -195,13 +196,23 @@ public final class AssetManager implements AutoCloseable { return; } // Make sure that all IDMAPs are up to date. nativeVerifySystemIdmaps(); try { final ArrayList<ApkAssets> apkAssets = new ArrayList<>(); apkAssets.add(ApkAssets.loadFromPath(FRAMEWORK_APK_PATH, true /*system*/)); if (FEATURE_FLAG_IDMAP2) { final String[] systemIdmapPaths = nativeCreateIdmapsForStaticOverlaysTargetingAndroid(); if (systemIdmapPaths == null) { throw new IOException("idmap2 scan failed"); } for (String idmapPath : systemIdmapPaths) { apkAssets.add(ApkAssets.loadOverlayFromPath(idmapPath, true /*system*/)); } } else { nativeVerifySystemIdmaps(); loadStaticRuntimeOverlays(apkAssets); } sSystemApkAssetsSet = new ArraySet<>(apkAssets); sSystemApkAssets = apkAssets.toArray(new ApkAssets[apkAssets.size()]); Loading Loading @@ -1404,6 +1415,7 @@ public final class AssetManager implements AutoCloseable { private static native long nativeAssetGetRemainingLength(long assetPtr); private static native void nativeVerifySystemIdmaps(); private static native String[] nativeCreateIdmapsForStaticOverlaysTargetingAndroid(); // Global debug native methods. /** Loading core/jni/android_util_AssetManager.cpp +83 −4 Original line number Diff line number Diff line Loading @@ -24,9 +24,13 @@ #include <sys/system_properties.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <private/android_filesystem_config.h> // for AID_SYSTEM #include <sstream> #include <string> #include "android-base/logging.h" #include "android-base/properties.h" #include "android-base/stringprintf.h" Loading @@ -38,6 +42,7 @@ #include "androidfw/AssetManager2.h" #include "androidfw/AttributeResolution.h" #include "androidfw/MutexGuard.h" #include "androidfw/PosixUtils.h" #include "androidfw/ResourceTypes.h" #include "core_jni_helpers.h" #include "jni.h" Loading @@ -54,6 +59,7 @@ 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); using ::android::base::StringPrintf; using ::android::util::ExecuteBinary; namespace android { Loading Loading @@ -161,18 +167,20 @@ static void NativeVerifySystemIdmaps(JNIEnv* /*env*/, jclass /*clazz*/) { argv[argc++] = AssetManager::IDMAP_DIR; // Directories to scan for overlays: if OVERLAY_THEME_DIR_PROPERTY is defined, // use OVERLAY_DIR/<value of OVERLAY_THEME_DIR_PROPERTY> in addition to OVERLAY_DIR. // use VENDOR_OVERLAY_DIR/<value of OVERLAY_THEME_DIR_PROPERTY> in // addition to VENDOR_OVERLAY_DIR. std::string overlay_theme_path = base::GetProperty(AssetManager::OVERLAY_THEME_DIR_PROPERTY, ""); if (!overlay_theme_path.empty()) { overlay_theme_path = std::string(AssetManager::OVERLAY_DIR) + "/" + overlay_theme_path; overlay_theme_path = std::string(AssetManager::VENDOR_OVERLAY_DIR) + "/" + overlay_theme_path; if (stat(overlay_theme_path.c_str(), &st) == 0) { argv[argc++] = overlay_theme_path.c_str(); } } if (stat(AssetManager::OVERLAY_DIR, &st) == 0) { argv[argc++] = AssetManager::OVERLAY_DIR; if (stat(AssetManager::VENDOR_OVERLAY_DIR, &st) == 0) { argv[argc++] = AssetManager::VENDOR_OVERLAY_DIR; } if (stat(AssetManager::PRODUCT_OVERLAY_DIR, &st) == 0) { Loading Loading @@ -200,6 +208,75 @@ static void NativeVerifySystemIdmaps(JNIEnv* /*env*/, jclass /*clazz*/) { } } static jobjectArray NativeCreateIdmapsForStaticOverlaysTargetingAndroid(JNIEnv* env, jclass /*clazz*/) { // --input-directory can be given multiple times, but idmap2 expects the directory to exist std::vector<std::string> input_dirs; struct stat st; if (stat(AssetManager::VENDOR_OVERLAY_DIR, &st) == 0) { input_dirs.push_back(AssetManager::VENDOR_OVERLAY_DIR); } if (stat(AssetManager::PRODUCT_OVERLAY_DIR, &st) == 0) { input_dirs.push_back(AssetManager::PRODUCT_OVERLAY_DIR); } if (stat(AssetManager::PRODUCT_SERVICES_OVERLAY_DIR, &st) == 0) { input_dirs.push_back(AssetManager::PRODUCT_SERVICES_OVERLAY_DIR); } if (input_dirs.empty()) { LOG(WARNING) << "no directories for idmap2 to scan"; return env->NewObjectArray(0, g_stringClass, nullptr); } std::vector<std::string> argv{"/system/bin/idmap2", "scan", "--recursive", "--target-package-name", "android", "--target-apk-path", "/system/framework/framework-res.apk", "--output-directory", "/data/resource-cache"}; for (const auto& dir : input_dirs) { argv.push_back("--input-directory"); argv.push_back(dir); } const auto result = ExecuteBinary(argv); if (!result) { LOG(ERROR) << "failed to execute idmap2"; return nullptr; } if (result->status != 0) { LOG(ERROR) << "idmap2: " << result->stderr; return nullptr; } std::vector<std::string> idmap_paths; std::istringstream input(result->stdout); std::string path; while (std::getline(input, path)) { idmap_paths.push_back(path); } jobjectArray array = env->NewObjectArray(idmap_paths.size(), g_stringClass, nullptr); if (array == nullptr) { return nullptr; } for (size_t i = 0; i < idmap_paths.size(); i++) { const std::string path = idmap_paths[i]; jstring java_string = env->NewStringUTF(path.c_str()); if (env->ExceptionCheck()) { return nullptr; } env->SetObjectArrayElement(array, i, java_string); env->DeleteLocalRef(java_string); } return array; } static jint CopyValue(JNIEnv* env, ApkAssetsCookie cookie, const Res_value& value, uint32_t ref, uint32_t type_spec_flags, ResTable_config* config, jobject out_typed_value) { env->SetIntField(out_typed_value, gTypedValueOffsets.mType, value.dataType); Loading Loading @@ -1405,6 +1482,8 @@ static const JNINativeMethod gAssetManagerMethods[] = { // System/idmap related methods. {"nativeVerifySystemIdmaps", "()V", (void*)NativeVerifySystemIdmaps}, {"nativeCreateIdmapsForStaticOverlaysTargetingAndroid", "()[Ljava/lang/String;", (void*)NativeCreateIdmapsForStaticOverlaysTargetingAndroid}, // Global management/debug methods. {"getGlobalAssetCount", "()I", (void*)NativeGetGlobalAssetCount}, Loading core/jni/fd_utils.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -85,7 +85,7 @@ bool FileDescriptorWhitelist::IsAllowed(const std::string& path) const { // See AssetManager.cpp for more details on overlay-subdir. static const char* kOverlayDir = "/system/vendor/overlay/"; static const char* kVendorOverlayDir = "/vendor/overlay"; static const char* kOverlaySubdir = "/system/vendor/overlay-subdir/"; static const char* kVendorOverlaySubdir = "/system/vendor/overlay-subdir/"; static const char* kSystemProductOverlayDir = "/system/product/overlay/"; static const char* kProductOverlayDir = "/product/overlay"; static const char* kSystemProductServicesOverlayDir = "/system/product_services/overlay/"; Loading @@ -93,7 +93,7 @@ bool FileDescriptorWhitelist::IsAllowed(const std::string& path) const { static const char* kApkSuffix = ".apk"; if ((android::base::StartsWith(path, kOverlayDir) || android::base::StartsWith(path, kOverlaySubdir) || android::base::StartsWith(path, kVendorOverlaySubdir) || android::base::StartsWith(path, kVendorOverlayDir) || android::base::StartsWith(path, kSystemProductOverlayDir) || android::base::StartsWith(path, kProductOverlayDir) Loading libs/androidfw/AssetManager.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -72,7 +72,7 @@ static volatile int32_t gCount = 0; const char* AssetManager::RESOURCES_FILENAME = "resources.arsc"; const char* AssetManager::IDMAP_BIN = "/system/bin/idmap"; const char* AssetManager::OVERLAY_DIR = "/vendor/overlay"; const char* AssetManager::VENDOR_OVERLAY_DIR = "/vendor/overlay"; const char* AssetManager::PRODUCT_OVERLAY_DIR = "/product/overlay"; const char* AssetManager::PRODUCT_SERVICES_OVERLAY_DIR = "/product_services/overlay"; const char* AssetManager::OVERLAY_THEME_DIR_PROPERTY = "ro.boot.vendor.overlay.theme"; Loading Loading
core/java/android/content/Context.java +10 −0 Original line number Diff line number Diff line Loading @@ -4333,6 +4333,16 @@ public abstract class Context { */ public static final String OVERLAY_SERVICE = "overlay"; /** * Use with {@link #getSystemService(String)} to retrieve a * {android.os.IIdmap2} for managing idmap files (used by overlay * packages). * * @see #getSystemService(String) * @hide */ public static final String IDMAP_SERVICE = "idmap"; /** * Use with {@link #getSystemService(String)} to retrieve a * {@link VrManager} for accessing the VR service. Loading
core/java/android/content/res/AssetManager.java +15 −3 Original line number Diff line number Diff line Loading @@ -58,6 +58,7 @@ import java.util.HashMap; public final class AssetManager implements AutoCloseable { private static final String TAG = "AssetManager"; private static final boolean DEBUG_REFS = false; private static final boolean FEATURE_FLAG_IDMAP2 = false; private static final String FRAMEWORK_APK_PATH = "/system/framework/framework-res.apk"; Loading Loading @@ -195,13 +196,23 @@ public final class AssetManager implements AutoCloseable { return; } // Make sure that all IDMAPs are up to date. nativeVerifySystemIdmaps(); try { final ArrayList<ApkAssets> apkAssets = new ArrayList<>(); apkAssets.add(ApkAssets.loadFromPath(FRAMEWORK_APK_PATH, true /*system*/)); if (FEATURE_FLAG_IDMAP2) { final String[] systemIdmapPaths = nativeCreateIdmapsForStaticOverlaysTargetingAndroid(); if (systemIdmapPaths == null) { throw new IOException("idmap2 scan failed"); } for (String idmapPath : systemIdmapPaths) { apkAssets.add(ApkAssets.loadOverlayFromPath(idmapPath, true /*system*/)); } } else { nativeVerifySystemIdmaps(); loadStaticRuntimeOverlays(apkAssets); } sSystemApkAssetsSet = new ArraySet<>(apkAssets); sSystemApkAssets = apkAssets.toArray(new ApkAssets[apkAssets.size()]); Loading Loading @@ -1404,6 +1415,7 @@ public final class AssetManager implements AutoCloseable { private static native long nativeAssetGetRemainingLength(long assetPtr); private static native void nativeVerifySystemIdmaps(); private static native String[] nativeCreateIdmapsForStaticOverlaysTargetingAndroid(); // Global debug native methods. /** Loading
core/jni/android_util_AssetManager.cpp +83 −4 Original line number Diff line number Diff line Loading @@ -24,9 +24,13 @@ #include <sys/system_properties.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <private/android_filesystem_config.h> // for AID_SYSTEM #include <sstream> #include <string> #include "android-base/logging.h" #include "android-base/properties.h" #include "android-base/stringprintf.h" Loading @@ -38,6 +42,7 @@ #include "androidfw/AssetManager2.h" #include "androidfw/AttributeResolution.h" #include "androidfw/MutexGuard.h" #include "androidfw/PosixUtils.h" #include "androidfw/ResourceTypes.h" #include "core_jni_helpers.h" #include "jni.h" Loading @@ -54,6 +59,7 @@ 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); using ::android::base::StringPrintf; using ::android::util::ExecuteBinary; namespace android { Loading Loading @@ -161,18 +167,20 @@ static void NativeVerifySystemIdmaps(JNIEnv* /*env*/, jclass /*clazz*/) { argv[argc++] = AssetManager::IDMAP_DIR; // Directories to scan for overlays: if OVERLAY_THEME_DIR_PROPERTY is defined, // use OVERLAY_DIR/<value of OVERLAY_THEME_DIR_PROPERTY> in addition to OVERLAY_DIR. // use VENDOR_OVERLAY_DIR/<value of OVERLAY_THEME_DIR_PROPERTY> in // addition to VENDOR_OVERLAY_DIR. std::string overlay_theme_path = base::GetProperty(AssetManager::OVERLAY_THEME_DIR_PROPERTY, ""); if (!overlay_theme_path.empty()) { overlay_theme_path = std::string(AssetManager::OVERLAY_DIR) + "/" + overlay_theme_path; overlay_theme_path = std::string(AssetManager::VENDOR_OVERLAY_DIR) + "/" + overlay_theme_path; if (stat(overlay_theme_path.c_str(), &st) == 0) { argv[argc++] = overlay_theme_path.c_str(); } } if (stat(AssetManager::OVERLAY_DIR, &st) == 0) { argv[argc++] = AssetManager::OVERLAY_DIR; if (stat(AssetManager::VENDOR_OVERLAY_DIR, &st) == 0) { argv[argc++] = AssetManager::VENDOR_OVERLAY_DIR; } if (stat(AssetManager::PRODUCT_OVERLAY_DIR, &st) == 0) { Loading Loading @@ -200,6 +208,75 @@ static void NativeVerifySystemIdmaps(JNIEnv* /*env*/, jclass /*clazz*/) { } } static jobjectArray NativeCreateIdmapsForStaticOverlaysTargetingAndroid(JNIEnv* env, jclass /*clazz*/) { // --input-directory can be given multiple times, but idmap2 expects the directory to exist std::vector<std::string> input_dirs; struct stat st; if (stat(AssetManager::VENDOR_OVERLAY_DIR, &st) == 0) { input_dirs.push_back(AssetManager::VENDOR_OVERLAY_DIR); } if (stat(AssetManager::PRODUCT_OVERLAY_DIR, &st) == 0) { input_dirs.push_back(AssetManager::PRODUCT_OVERLAY_DIR); } if (stat(AssetManager::PRODUCT_SERVICES_OVERLAY_DIR, &st) == 0) { input_dirs.push_back(AssetManager::PRODUCT_SERVICES_OVERLAY_DIR); } if (input_dirs.empty()) { LOG(WARNING) << "no directories for idmap2 to scan"; return env->NewObjectArray(0, g_stringClass, nullptr); } std::vector<std::string> argv{"/system/bin/idmap2", "scan", "--recursive", "--target-package-name", "android", "--target-apk-path", "/system/framework/framework-res.apk", "--output-directory", "/data/resource-cache"}; for (const auto& dir : input_dirs) { argv.push_back("--input-directory"); argv.push_back(dir); } const auto result = ExecuteBinary(argv); if (!result) { LOG(ERROR) << "failed to execute idmap2"; return nullptr; } if (result->status != 0) { LOG(ERROR) << "idmap2: " << result->stderr; return nullptr; } std::vector<std::string> idmap_paths; std::istringstream input(result->stdout); std::string path; while (std::getline(input, path)) { idmap_paths.push_back(path); } jobjectArray array = env->NewObjectArray(idmap_paths.size(), g_stringClass, nullptr); if (array == nullptr) { return nullptr; } for (size_t i = 0; i < idmap_paths.size(); i++) { const std::string path = idmap_paths[i]; jstring java_string = env->NewStringUTF(path.c_str()); if (env->ExceptionCheck()) { return nullptr; } env->SetObjectArrayElement(array, i, java_string); env->DeleteLocalRef(java_string); } return array; } static jint CopyValue(JNIEnv* env, ApkAssetsCookie cookie, const Res_value& value, uint32_t ref, uint32_t type_spec_flags, ResTable_config* config, jobject out_typed_value) { env->SetIntField(out_typed_value, gTypedValueOffsets.mType, value.dataType); Loading Loading @@ -1405,6 +1482,8 @@ static const JNINativeMethod gAssetManagerMethods[] = { // System/idmap related methods. {"nativeVerifySystemIdmaps", "()V", (void*)NativeVerifySystemIdmaps}, {"nativeCreateIdmapsForStaticOverlaysTargetingAndroid", "()[Ljava/lang/String;", (void*)NativeCreateIdmapsForStaticOverlaysTargetingAndroid}, // Global management/debug methods. {"getGlobalAssetCount", "()I", (void*)NativeGetGlobalAssetCount}, Loading
core/jni/fd_utils.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -85,7 +85,7 @@ bool FileDescriptorWhitelist::IsAllowed(const std::string& path) const { // See AssetManager.cpp for more details on overlay-subdir. static const char* kOverlayDir = "/system/vendor/overlay/"; static const char* kVendorOverlayDir = "/vendor/overlay"; static const char* kOverlaySubdir = "/system/vendor/overlay-subdir/"; static const char* kVendorOverlaySubdir = "/system/vendor/overlay-subdir/"; static const char* kSystemProductOverlayDir = "/system/product/overlay/"; static const char* kProductOverlayDir = "/product/overlay"; static const char* kSystemProductServicesOverlayDir = "/system/product_services/overlay/"; Loading @@ -93,7 +93,7 @@ bool FileDescriptorWhitelist::IsAllowed(const std::string& path) const { static const char* kApkSuffix = ".apk"; if ((android::base::StartsWith(path, kOverlayDir) || android::base::StartsWith(path, kOverlaySubdir) || android::base::StartsWith(path, kVendorOverlaySubdir) || android::base::StartsWith(path, kVendorOverlayDir) || android::base::StartsWith(path, kSystemProductOverlayDir) || android::base::StartsWith(path, kProductOverlayDir) Loading
libs/androidfw/AssetManager.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -72,7 +72,7 @@ static volatile int32_t gCount = 0; const char* AssetManager::RESOURCES_FILENAME = "resources.arsc"; const char* AssetManager::IDMAP_BIN = "/system/bin/idmap"; const char* AssetManager::OVERLAY_DIR = "/vendor/overlay"; const char* AssetManager::VENDOR_OVERLAY_DIR = "/vendor/overlay"; const char* AssetManager::PRODUCT_OVERLAY_DIR = "/product/overlay"; const char* AssetManager::PRODUCT_SERVICES_OVERLAY_DIR = "/product_services/overlay"; const char* AssetManager::OVERLAY_THEME_DIR_PROPERTY = "ro.boot.vendor.overlay.theme"; Loading