diff options
| author | 2015-03-20 12:57:36 +0100 | |
|---|---|---|
| committer | 2015-10-07 19:45:09 +0200 | |
| commit | 83ab0d7c1824f3a29e41af8a95a954c73f48c287 (patch) | |
| tree | ee7747ed680a46cfc90ec83c3b1b243a2514aea1 | |
| parent | c9390c8baf0a41633c176d6d9a2d7e5d0c61c387 (diff) | |
Make 'idmap --scan' accept more than one input directory
The 'idmap --scan' command was limited to only scan a single directory
for overlay packages. Update idmap to support any number of directories.
Change-Id: I851f5720a3c1d844235911a0833670652a20a3c8
| -rw-r--r-- | cmds/idmap/idmap.cpp | 37 | ||||
| -rw-r--r-- | cmds/idmap/idmap.h | 6 | ||||
| -rw-r--r-- | cmds/idmap/scan.cpp | 70 | ||||
| -rw-r--r-- | core/jni/android_util_AssetManager.cpp | 32 |
4 files changed, 91 insertions, 54 deletions
diff --git a/cmds/idmap/idmap.cpp b/cmds/idmap/idmap.cpp index 90cfa2c610f0..3ab191553625 100644 --- a/cmds/idmap/idmap.cpp +++ b/cmds/idmap/idmap.cpp @@ -13,7 +13,8 @@ SYNOPSIS \n\ idmap --help \n\ idmap --fd target overlay fd \n\ idmap --path target overlay idmap \n\ - idmap --scan dir-to-scan target-to-look-for target dir-to-hold-idmaps \n\ + idmap --scan target-package-name-to-look-for path-to-target-apk dir-to-hold-idmaps \\\ + dir-to-scan [additional-dir-to-scan [additional-dir-to-scan [...]]]\n\ idmap --inspect idmap \n\ \n\ DESCRIPTION \n\ @@ -49,9 +50,9 @@ OPTIONS \n\ 'overlay' (path to apk); write results to 'idmap' (path). \n\ \n\ --scan: non-recursively search directory 'dir-to-scan' (path) for overlay packages with \n\ - target package 'target-to-look-for' (package name) present at 'target' (path to \n\ - apk). For each overlay package found, create an idmap file in 'dir-to-hold-idmaps' \n\ - (path). \n\ + target package 'target-package-name-to-look-for' (package name) present at\n\ + 'path-to-target-apk' (path to apk). For each overlay package found, create an\n\ + idmap file in 'dir-to-hold-idmaps' (path). \n\ \n\ --inspect: decode the binary format of 'idmap' (path) and display the contents in a \n\ debug-friendly format. \n\ @@ -166,19 +167,14 @@ NOTES \n\ return idmap_create_path(target_apk_path, overlay_apk_path, idmap_path); } - int maybe_scan(const char *overlay_dir, const char *target_package_name, - const char *target_apk_path, const char *idmap_dir) + int maybe_scan(const char *target_package_name, const char *target_apk_path, + const char *idmap_dir, const android::Vector<const char *> *overlay_dirs) { if (!verify_root_or_system()) { fprintf(stderr, "error: permission denied: not user root or user system\n"); return -1; } - if (!verify_directory_readable(overlay_dir)) { - ALOGD("error: no read access to %s: %s\n", overlay_dir, strerror(errno)); - return -1; - } - if (!verify_file_readable(target_apk_path)) { ALOGD("error: failed to read apk %s: %s\n", target_apk_path, strerror(errno)); return -1; @@ -189,7 +185,16 @@ NOTES \n\ return -1; } - return idmap_scan(overlay_dir, target_package_name, target_apk_path, idmap_dir); + const size_t N = overlay_dirs->size(); + for (size_t i = 0; i < N; i++) { + const char *dir = overlay_dirs->itemAt(i); + if (!verify_directory_readable(dir)) { + ALOGD("error: no read access to %s: %s\n", dir, strerror(errno)); + return -1; + } + } + + return idmap_scan(target_package_name, target_apk_path, idmap_dir, overlay_dirs); } int maybe_inspect(const char *idmap_path) @@ -230,8 +235,12 @@ int main(int argc, char **argv) return maybe_create_path(argv[2], argv[3], argv[4]); } - if (argc == 6 && !strcmp(argv[1], "--scan")) { - return maybe_scan(argv[2], argv[3], argv[4], argv[5]); + if (argc >= 6 && !strcmp(argv[1], "--scan")) { + android::Vector<const char *> v; + for (int i = 5; i < argc; i++) { + v.push(argv[i]); + } + return maybe_scan(argv[2], argv[3], argv[4], &v); } if (argc == 3 && !strcmp(argv[1], "--inspect")) { diff --git a/cmds/idmap/idmap.h b/cmds/idmap/idmap.h index f507dd8530ac..8d4210bcb443 100644 --- a/cmds/idmap/idmap.h +++ b/cmds/idmap/idmap.h @@ -1,9 +1,11 @@ + #ifndef _IDMAP_H_ #define _IDMAP_H_ #define LOG_TAG "idmap" #include <utils/Log.h> +#include <utils/Vector.h> #include <errno.h> #include <stdio.h> @@ -26,8 +28,8 @@ int idmap_create_fd(const char *target_apk_path, const char *overlay_apk_path, i // Regarding target_package_name: the idmap_scan implementation should // be able to extract this from the manifest in target_apk_path, // simplifying the external API. -int idmap_scan(const char *overlay_dir, const char *target_package_name, - const char *target_apk_path, const char *idmap_dir); +int idmap_scan(const char *target_package_name, const char *target_apk_path, + const char *idmap_dir, const android::Vector<const char *> *overlay_dirs); int idmap_inspect(const char *idmap_path); diff --git a/cmds/idmap/scan.cpp b/cmds/idmap/scan.cpp index 612a7ebb5489..a33c403683de 100644 --- a/cmds/idmap/scan.cpp +++ b/cmds/idmap/scan.cpp @@ -167,8 +167,8 @@ namespace { } } -int idmap_scan(const char *overlay_dir, const char *target_package_name, - const char *target_apk_path, const char *idmap_dir) +int idmap_scan(const char *target_package_name, const char *target_apk_path, + const char *idmap_dir, const android::Vector<const char *> *overlay_dirs) { String8 filename = String8(idmap_dir); filename.appendPath("overlays.list"); @@ -176,45 +176,49 @@ 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; - } + const size_t N = overlay_dirs->size(); + for (size_t i = 0; i < N; ++i) { + const char *overlay_dir = overlay_dirs->itemAt(i); + 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)) { + continue; + } - int priority = parse_apk(overlay_apk_path, target_package_name); - if (priority < 0) { - 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"); + 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; + 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); } - Overlay overlay(String8(overlay_apk_path), idmap_path, priority); - overlayVector.add(overlay); + closedir(dir); } - closedir(dir); - if (!writePackagesList(filename.string(), overlayVector)) { return EXIT_FAILURE; } diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp index 0ff2524d8ec8..8385f75e4a66 100644 --- a/core/jni/android_util_AssetManager.cpp +++ b/core/jni/android_util_AssetManager.cpp @@ -24,6 +24,7 @@ #include <stdio.h> #include <sys/types.h> #include <sys/wait.h> +#include <sys/stat.h> #include <private/android_filesystem_config.h> // for AID_SYSTEM @@ -162,11 +163,32 @@ static void verifySystemIdmaps() exit(1); } - execl(AssetManager::IDMAP_BIN, AssetManager::IDMAP_BIN, "--scan", - AssetManager::OVERLAY_DIR, AssetManager::TARGET_PACKAGE_NAME, - AssetManager::TARGET_APK_PATH, AssetManager::IDMAP_DIR, (char*)NULL); - ALOGE("failed to execl for idmap: %s", strerror(errno)); - exit(1); // should never get here + // Generic idmap parameters + const char* argv[7]; + int argc = 0; + struct stat st; + + memset(argv, NULL, sizeof(argv)); + argv[argc++] = AssetManager::IDMAP_BIN; + argv[argc++] = "--scan"; + argv[argc++] = AssetManager::TARGET_PACKAGE_NAME; + 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) { + argv[argc++] = AssetManager::OVERLAY_DIR; + } + + // Finally, invoke idmap (if any overlay directory exists) + if (argc > 5) { + execv(AssetManager::IDMAP_BIN, (char* const*)argv); + ALOGE("failed to execl for idmap: %s", strerror(errno)); + exit(1); // should never get here + } else { + exit(0); + } } break; default: // parent |