summaryrefslogtreecommitdiffstats
path: root/cmds
diff options
context:
space:
mode:
Diffstat (limited to 'cmds')
-rw-r--r--cmds/atrace/atrace.cpp1
-rw-r--r--cmds/dumpstate/dumpstate.c22
-rw-r--r--cmds/installd/commands.cpp248
-rw-r--r--cmds/installd/installd.cpp22
-rw-r--r--cmds/installd/installd.h10
-rw-r--r--cmds/installd/utils.cpp2
6 files changed, 240 insertions, 65 deletions
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 26c5b4a..7201e77 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -93,6 +93,7 @@ static const TracingCategory k_categories[] = {
{ "sched", "CPU Scheduling", 0, {
{ REQ, "/sys/kernel/debug/tracing/events/sched/sched_switch/enable" },
{ REQ, "/sys/kernel/debug/tracing/events/sched/sched_wakeup/enable" },
+ { OPT, "/sys/kernel/debug/tracing/events/sched/sched_blocked_reason/enable" },
} },
{ "irq", "IRQ Events", 0, {
{ REQ, "/sys/kernel/debug/tracing/events/irq/enable" },
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 792f015..475f7e3 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -47,6 +47,7 @@ static char screenshot_path[PATH_MAX] = "";
#define PSTORE_LAST_KMSG "/sys/fs/pstore/console-ramoops"
+#define RAFT_DIR "/data/misc/raft/"
#define TOMBSTONE_DIR "/data/tombstones"
#define TOMBSTONE_FILE_PREFIX TOMBSTONE_DIR "/tombstone_"
/* Can accomodate a tombstone number up to 9999. */
@@ -261,6 +262,8 @@ static unsigned long logcat_timeout(char *name) {
/* End copy from system/core/logd/LogBuffer.cpp */
+static const unsigned long logcat_min_timeout = 40000; /* ms */
+
/* dumps the current system state to stdout */
static void dumpstate() {
unsigned long timeout;
@@ -269,7 +272,9 @@ static void dumpstate() {
char radio[PROPERTY_VALUE_MAX], bootloader[PROPERTY_VALUE_MAX];
char network[PROPERTY_VALUE_MAX], date[80];
char build_type[PROPERTY_VALUE_MAX];
+ char cm_version[PROPERTY_VALUE_MAX];
+ property_get("ro.cm.version", cm_version, "(unknown)");
property_get("ro.build.display.id", build, "(unknown)");
property_get("ro.build.fingerprint", fingerprint, "(unknown)");
property_get("ro.build.type", build_type, "(unknown)");
@@ -283,6 +288,7 @@ static void dumpstate() {
printf("========================================================\n");
printf("\n");
+ printf("CM Version: %s\n", cm_version);
printf("Build: %s\n", build);
printf("Build fingerprint: '%s'\n", fingerprint); /* format is important for other tools */
printf("Bootloader: %s\n", bootloader);
@@ -299,7 +305,7 @@ static void dumpstate() {
dump_files("UPTIME MMC PERF", mmcblk0, skip_not_stat, dump_stat_from_fd);
dump_file("MEMORY INFO", "/proc/meminfo");
run_command("CPU INFO", 10, "top", "-n", "1", "-d", "1", "-m", "30", "-t", NULL);
- run_command("PROCRANK", 20, "procrank", NULL);
+ run_command("PROCRANK", 20, SU_PATH, "root", "procrank", NULL);
dump_file("VIRTUAL MEMORY STATS", "/proc/vmstat");
dump_file("VMALLOC INFO", "/proc/vmallocinfo");
dump_file("SLAB INFO", "/proc/slabinfo");
@@ -333,23 +339,25 @@ static void dumpstate() {
// dump_file("EVENT LOG TAGS", "/etc/event-log-tags");
// calculate timeout
timeout = logcat_timeout("main") + logcat_timeout("system") + logcat_timeout("crash");
- if (timeout < 20000) {
- timeout = 20000;
+ if (timeout < logcat_min_timeout) {
+ timeout = logcat_min_timeout;
}
run_command("SYSTEM LOG", timeout / 1000, "logcat", "-v", "threadtime", "-d", "*:v", NULL);
timeout = logcat_timeout("events");
- if (timeout < 20000) {
- timeout = 20000;
+ if (timeout < logcat_min_timeout) {
+ timeout = logcat_min_timeout;
}
run_command("EVENT LOG", timeout / 1000, "logcat", "-b", "events", "-v", "threadtime", "-d", "*:v", NULL);
timeout = logcat_timeout("radio");
- if (timeout < 20000) {
- timeout = 20000;
+ if (timeout < logcat_min_timeout) {
+ timeout = logcat_min_timeout;
}
run_command("RADIO LOG", timeout / 1000, "logcat", "-b", "radio", "-v", "threadtime", "-d", "*:v", NULL);
run_command("LOG STATISTICS", 10, "logcat", "-b", "all", "-S", NULL);
+ run_command("RAFT LOGS", 600, SU_PATH, "root", "logcompressor", "-r", RAFT_DIR, NULL);
+
/* show the traces we collected in main(), if that was done */
if (dump_traces_path != NULL) {
dump_file("VM TRACES JUST NOW", dump_traces_path);
diff --git a/cmds/installd/commands.cpp b/cmds/installd/commands.cpp
index d4aa7d3..09369ce 100644
--- a/cmds/installd/commands.cpp
+++ b/cmds/installd/commands.cpp
@@ -39,6 +39,7 @@ dir_rec_t android_app_private_dir;
dir_rec_t android_app_lib_dir;
dir_rec_t android_media_dir;
dir_rec_t android_mnt_expand_dir;
+dir_rec_t android_prebundled_dir;
dir_rec_array_t android_system_dirs;
static const char* kCpPath = "/system/bin/cp";
@@ -770,24 +771,11 @@ static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name,
dex2oat_compiler_filter_flag, NULL) > 0;
char dex2oat_threads_buf[PROPERTY_VALUE_MAX];
- bool have_dex2oat_threads_flag = false;
- if (!post_bootcomplete) {
- have_dex2oat_threads_flag = property_get("dalvik.vm.boot-dex2oat-threads",
- dex2oat_threads_buf,
- NULL) > 0;
- // If there's no boot property, fall back to the image property.
- if (!have_dex2oat_threads_flag) {
- have_dex2oat_threads_flag = property_get("dalvik.vm.image-dex2oat-threads",
- dex2oat_threads_buf,
- NULL) > 0;
- }
- // If there's neither, fall back to the default property.
- }
- if (!have_dex2oat_threads_flag) {
- have_dex2oat_threads_flag = property_get("dalvik.vm.dex2oat-threads",
- dex2oat_threads_buf,
- NULL) > 0;
- }
+ bool have_dex2oat_threads_flag = property_get(post_bootcomplete
+ ? "dalvik.vm.dex2oat-threads"
+ : "dalvik.vm.boot-dex2oat-threads",
+ dex2oat_threads_buf,
+ NULL) > 0;
char dex2oat_threads_arg[PROPERTY_VALUE_MAX + 2];
if (have_dex2oat_threads_flag) {
sprintf(dex2oat_threads_arg, "-j%s", dex2oat_threads_buf);
@@ -1623,62 +1611,46 @@ out:
return rc;
}
-static void run_idmap(const char *target_apk, const char *overlay_apk, int idmap_fd)
+static void run_idmap(const char *target_apk, const char *overlay_apk, const char *cache_path,
+ int idmap_fd, uint32_t target_hash, uint32_t overlay_hash)
{
static const char *IDMAP_BIN = "/system/bin/idmap";
static const size_t MAX_INT_LEN = 32;
char idmap_str[MAX_INT_LEN];
+ char target_hash_str[MAX_INT_LEN];
+ char overlay_hash_str[MAX_INT_LEN];
snprintf(idmap_str, sizeof(idmap_str), "%d", idmap_fd);
+ snprintf(target_hash_str, sizeof(target_hash_str), "%d", target_hash);
+ snprintf(overlay_hash_str, sizeof(overlay_hash_str), "%d", overlay_hash);
- execl(IDMAP_BIN, IDMAP_BIN, "--fd", target_apk, overlay_apk, idmap_str, (char*)NULL);
+ execl(IDMAP_BIN, IDMAP_BIN, "--fd", target_apk, overlay_apk, cache_path, idmap_str,
+ target_hash_str, overlay_hash_str, (char*)NULL);
ALOGE("execl(%s) failed: %s\n", IDMAP_BIN, strerror(errno));
}
-// Transform string /a/b/c.apk to (prefix)/a@b@c.apk@(suffix)
-// eg /a/b/c.apk to /data/resource-cache/a@b@c.apk@idmap
-static int flatten_path(const char *prefix, const char *suffix,
- const char *overlay_path, char *idmap_path, size_t N)
+static int get_idmap_path(const char *prefix, const char *suffix, char *idmap_path, size_t N)
{
- if (overlay_path == NULL || idmap_path == NULL) {
- return -1;
- }
- const size_t len_overlay_path = strlen(overlay_path);
- // will access overlay_path + 1 further below; requires absolute path
- if (len_overlay_path < 2 || *overlay_path != '/') {
- return -1;
- }
- const size_t len_idmap_root = strlen(prefix);
- const size_t len_suffix = strlen(suffix);
- if (SIZE_MAX - len_idmap_root < len_overlay_path ||
- SIZE_MAX - (len_idmap_root + len_overlay_path) < len_suffix) {
- // additions below would cause overflow
- return -1;
- }
- if (N < len_idmap_root + len_overlay_path + len_suffix) {
- return -1;
- }
+ if (idmap_path == NULL) return -1;
+
memset(idmap_path, 0, N);
- snprintf(idmap_path, N, "%s%s%s", prefix, overlay_path + 1, suffix);
- char *ch = idmap_path + len_idmap_root;
- while (*ch != '\0') {
- if (*ch == '/') {
- *ch = '@';
- }
- ++ch;
+ int len = snprintf(idmap_path, N, "%s/%s", prefix, suffix);
+ if (len < 0 || (size_t)len >= N) {
+ return -1; // error or truncated
}
return 0;
}
-int idmap(const char *target_apk, const char *overlay_apk, uid_t uid)
+int idmap(const char *target_apk, const char *overlay_apk, const char *cache_path,
+ uid_t uid, uint32_t target_hash, uint32_t overlay_hash)
{
- ALOGV("idmap target_apk=%s overlay_apk=%s uid=%d\n", target_apk, overlay_apk, uid);
+ ALOGD("idmap target_apk=%s overlay_apk=%s cache_path=%s uid=%d\n", target_apk, overlay_apk,
+ cache_path, uid);
int idmap_fd = -1;
char idmap_path[PATH_MAX];
- if (flatten_path(IDMAP_PREFIX, IDMAP_SUFFIX, overlay_apk,
- idmap_path, sizeof(idmap_path)) == -1) {
+ if (get_idmap_path(cache_path, IDMAP_SUFFIX, idmap_path, sizeof(idmap_path)) == -1) {
ALOGE("idmap cannot generate idmap path for overlay %s\n", overlay_apk);
goto fail;
}
@@ -1715,7 +1687,7 @@ int idmap(const char *target_apk, const char *overlay_apk, uid_t uid)
exit(1);
}
- run_idmap(target_apk, overlay_apk, idmap_fd);
+ run_idmap(target_apk, overlay_apk, cache_path, idmap_fd, target_hash, overlay_hash);
exit(1); /* only if exec call to idmap failed */
} else {
int status = wait_child(pid);
@@ -1735,6 +1707,174 @@ fail:
return -1;
}
+static void run_aapt(const char *source_apk, const char *internal_path,
+ int resapk_fd, int pkgId, int min_sdk_version,
+ const char *app_res_path, const char *common_res_path)
+{
+ static const char *AAPT_BIN = "/system/bin/aapt";
+ static const char *MANIFEST = "/data/app/AndroidManifest.xml";
+ static const char *FRAMEWORK_RES = "/system/framework/framework-res.apk";
+
+ static const size_t MAX_INT_LEN = 32;
+ char resapk_str[MAX_INT_LEN];
+ char pkgId_str[MAX_INT_LEN];
+ char minSdkVersion_str[MAX_INT_LEN];
+
+ snprintf(resapk_str, sizeof(resapk_str), "%d", resapk_fd);
+ snprintf(pkgId_str, sizeof(pkgId_str), "%d", pkgId);
+ snprintf(minSdkVersion_str, sizeof(minSdkVersion_str), "%d", min_sdk_version);
+
+ bool hasCommonResources = (common_res_path != NULL && common_res_path[0] != '\0');
+ bool hasAppResources = (app_res_path != NULL && app_res_path[0] != '\0');
+
+ if (hasCommonResources) {
+ execl(AAPT_BIN, AAPT_BIN, "package",
+ "--min-sdk-version", minSdkVersion_str,
+ "-M", MANIFEST,
+ "-S", source_apk,
+ "-X", internal_path,
+ "-I", FRAMEWORK_RES,
+ "-r", resapk_str,
+ "-x", pkgId_str,
+ "-f",
+ "-I", common_res_path,
+ hasAppResources ? "-I" : (char*)NULL,
+ hasAppResources ? app_res_path : (char*) NULL,
+ (char*)NULL);
+ } else {
+ execl(AAPT_BIN, AAPT_BIN, "package",
+ "--min-sdk-version", minSdkVersion_str,
+ "-M", MANIFEST,
+ "-S", source_apk,
+ "-X", internal_path,
+ "-I", FRAMEWORK_RES,
+ "-r", resapk_str,
+ "-x", pkgId_str,
+ "-f",
+ hasAppResources ? "-I" : (char*)NULL,
+ hasAppResources ? app_res_path : (char*) NULL,
+ (char*)NULL);
+ }
+ ALOGE("execl(%s) failed: %s\n", AAPT_BIN, strerror(errno));
+}
+
+int aapt(const char *source_apk, const char *internal_path, const char *out_restable, uid_t uid,
+ int pkgId, int min_sdk_version, const char *app_res_path, const char *common_res_path)
+{
+ ALOGD("aapt source_apk=%s internal_path=%s out_restable=%s uid=%d, pkgId=%d,min_sdk_version=%d,\
+ app_res_path=%s, common_res_path=%s",
+ source_apk, internal_path, out_restable, uid, pkgId, min_sdk_version, app_res_path,
+ common_res_path);
+ static const int PARENT_READ_PIPE = 0;
+ static const int CHILD_WRITE_PIPE = 1;
+
+ int resapk_fd = -1;
+ char restable_path[PATH_MAX];
+ char resapk_path[PATH_MAX];
+
+ // create pipes for redirecting STDERR to a buffer that can be displayed in logcat
+ int pipefd[2];
+ if (pipe(pipefd) != 0) {
+ pipefd[0] = pipefd[1] = -1;
+ }
+
+ pid_t pid = fork();
+
+ if (pid == 0) {
+ // get file descriptor for resources.arsc
+ snprintf(restable_path, PATH_MAX, "%s/resources.arsc", out_restable);
+ unlink(restable_path);
+
+ // get file descriptor for resources.apk
+ snprintf(resapk_path, PATH_MAX, "%s/resources.apk", out_restable);
+ unlink(resapk_path);
+ resapk_fd = open(resapk_path, O_RDWR | O_CREAT | O_EXCL, 0644);
+ if (resapk_fd < 0) {
+ ALOGE("aapt cannot open '%s' for output: %s\n", resapk_path, strerror(errno));
+ goto fail;
+ }
+ if (fchown(resapk_fd, AID_SYSTEM, uid) < 0) {
+ ALOGE("aapt cannot chown '%s'\n", resapk_path);
+ goto fail;
+ }
+ if (fchmod(resapk_fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0) {
+ ALOGE("aapt cannot chmod '%s'\n", resapk_path);
+ goto fail;
+ }
+
+ /* child -- drop privileges before continuing */
+ if (setgid(uid) != 0) {
+ ALOGE("setgid(%d) failed during aapt\n", uid);
+ exit(1);
+ }
+ if (setuid(uid) != 0) {
+ ALOGE("setuid(%d) failed during aapt\n", uid);
+ exit(1);
+ }
+
+ if (flock(resapk_fd, LOCK_EX | LOCK_NB) != 0) {
+ ALOGE("flock(%s) failed during aapt: %s\n", out_restable, strerror(errno));
+ exit(1);
+ }
+
+ if (pipefd[PARENT_READ_PIPE] > 0 && pipefd[CHILD_WRITE_PIPE] > 0) {
+ close(pipefd[PARENT_READ_PIPE]); // close unused read end
+ if (dup2(pipefd[CHILD_WRITE_PIPE], STDERR_FILENO) != STDERR_FILENO) {
+ pipefd[CHILD_WRITE_PIPE] = -1;
+ }
+ }
+
+ run_aapt(source_apk, internal_path, resapk_fd, pkgId, min_sdk_version, app_res_path,
+ common_res_path);
+
+ close(resapk_fd);
+ if (pipefd[CHILD_WRITE_PIPE] > 0) {
+ close(pipefd[CHILD_WRITE_PIPE]);
+ }
+ exit(1); /* only if exec call to idmap failed */
+ } else {
+ int status, i;
+ char buffer[1024];
+ ssize_t readlen;
+
+ if (pipefd[CHILD_WRITE_PIPE] > 0) {
+ close(pipefd[CHILD_WRITE_PIPE]); // close unused write end
+ }
+
+ if (pipefd[PARENT_READ_PIPE] > 0) {
+ while ((readlen = read(pipefd[PARENT_READ_PIPE], buffer, sizeof(buffer) - 1)) > 0) {
+ // in case buffer has more than one string in it, replace '\0' with '\n'
+ for (i = 0; i < readlen; i++) {
+ if (buffer[i] == '\0') buffer[i] = '\n';
+ }
+ // null terminate buffer at readlen
+ buffer[readlen] = '\0';
+ ALOG(LOG_ERROR, "InstallTheme", "%s", buffer);
+ }
+ waitpid(pid, &status, 0);
+
+ if (pipefd[PARENT_READ_PIPE] > 0) {
+ close(pipefd[PARENT_READ_PIPE]);
+ }
+ } else {
+ status = wait_child(pid);
+ }
+
+ if (status != 0) {
+ ALOGE("aapt failed, status=0x%04x\n", status);
+ goto fail;
+ }
+ }
+
+ return 0;
+fail:
+ if (resapk_fd >= 0) {
+ close(resapk_fd);
+ unlink(resapk_path);
+ }
+ return -1;
+}
+
int restorecon_data(const char* uuid, const char* pkgName,
const char* seinfo, uid_t uid)
{
diff --git a/cmds/installd/installd.cpp b/cmds/installd/installd.cpp
index f67e838..df159e3 100644
--- a/cmds/installd/installd.cpp
+++ b/cmds/installd/installd.cpp
@@ -158,7 +158,17 @@ static int do_linklib(char **arg, char reply[REPLY_MAX] __unused)
static int do_idmap(char **arg, char reply[REPLY_MAX] __unused)
{
- return idmap(arg[0], arg[1], atoi(arg[2]));
+ return idmap(arg[0], arg[1], arg[2], atoi(arg[3]), atoi(arg[4]), atoi(arg[5]));
+}
+
+static int do_aapt(char **arg, char reply[REPLY_MAX] __unused)
+{
+ return aapt(arg[0], arg[1], arg[2], atoi(arg[3]), atoi(arg[4]), atoi(arg[5]), arg[6], "");
+}
+
+static int do_aapt_with_common(char **arg, char reply[REPLY_MAX] __unused)
+{
+ return aapt(arg[0], arg[1], arg[2], atoi(arg[3]), atoi(arg[4]), atoi(arg[5]), arg[6], arg[7]);
}
static int do_restorecon_data(char **arg, char reply[REPLY_MAX] __attribute__((unused)))
@@ -212,7 +222,9 @@ struct cmdinfo cmds[] = {
{ "mkuserdata", 5, do_mk_user_data },
{ "mkuserconfig", 1, do_mk_user_config },
{ "rmuser", 2, do_rm_user },
- { "idmap", 3, do_idmap },
+ { "idmap", 6, do_idmap },
+ { "aapt", 7, do_aapt },
+ { "aapt_with_common", 8, do_aapt_with_common },
{ "restorecondata", 4, do_restorecon_data },
{ "createoatdir", 2, do_create_oat_dir },
{ "rmpackagedir", 1, do_rm_package_dir },
@@ -373,6 +385,12 @@ int initialize_globals() {
return -1;
}
+ // Get the android external app directory.
+ if (get_path_from_string(&android_prebundled_dir, PREBUNDLED_APP_PREFIX) < 0) {
+ return -1;
+ }
+
+
// Take note of the system and vendor directories.
android_system_dirs.count = 4;
diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h
index 24b9084..b4c5961 100644
--- a/cmds/installd/installd.h
+++ b/cmds/installd/installd.h
@@ -80,7 +80,7 @@
#define UPDATE_COMMANDS_DIR_PREFIX "/system/etc/updatecmds/"
#define IDMAP_PREFIX "/data/resource-cache/"
-#define IDMAP_SUFFIX "@idmap"
+#define IDMAP_SUFFIX "idmap"
#define PKG_NAME_MAX 128 /* largest allowed package name */
#define PKG_PATH_MAX 256 /* max size of any path we use */
@@ -92,6 +92,8 @@
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
+#define PREBUNDLED_APP_PREFIX "/vendor/bundled-app/"
+
/* data structures */
typedef struct {
@@ -111,6 +113,7 @@ extern dir_rec_t android_data_dir;
extern dir_rec_t android_asec_dir;
extern dir_rec_t android_media_dir;
extern dir_rec_t android_mnt_expand_dir;
+extern dir_rec_t android_prebundled_dir;
extern dir_rec_array_t android_system_dirs;
typedef struct cache_dir_struct {
@@ -247,7 +250,10 @@ int dexopt(const char *apk_path, uid_t uid, bool is_public, const char *pkgName,
int mark_boot_complete(const char *instruction_set);
int movefiles();
int linklib(const char* uuid, const char* pkgname, const char* asecLibDir, int userId);
-int idmap(const char *target_path, const char *overlay_path, uid_t uid);
+int idmap(const char *target_path, const char *overlay_path, const char *cache_path, uid_t uid,
+ uint32_t target_hash, uint32_t overlay_hash);
+int aapt(const char *source_apk, const char *internal_path, const char *out_restable, uid_t uid,
+ int pkgId, int min_sdk_version, const char *app_res_path, const char *common_res_path);
int restorecon_data(const char *uuid, const char* pkgName, const char* seinfo, uid_t uid);
int create_oat_dir(const char* oat_dir, const char *instruction_set);
int rm_package_dir(const char* apk_path);
diff --git a/cmds/installd/utils.cpp b/cmds/installd/utils.cpp
index 7db3fb9..a32d1a0 100644
--- a/cmds/installd/utils.cpp
+++ b/cmds/installd/utils.cpp
@@ -1061,6 +1061,8 @@ static int validate_apk_path_internal(const char *path, int maxSubdirs) {
if (maxSubdirs < 2) {
maxSubdirs = 2;
}
+ } else if (!strncmp(path, android_prebundled_dir.path, android_prebundled_dir.len)) {
+ dir = &android_prebundled_dir;
} else {
return -1;
}