Merge "Don't rely on AppOpsManager in systems without applications"
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 81c8967..6549dde 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -545,17 +545,19 @@
     String8 funcList = String8::format("\n%s", buf);
 
     // Make sure that every function listed in funcs is in the list we just
-    // read from the kernel.
+    // read from the kernel, except for wildcard inputs.
     bool ok = true;
     char* myFuncs = strdup(funcs);
     char* func = strtok(myFuncs, ",");
     while (func) {
-        String8 fancyFunc = String8::format("\n%s\n", func);
-        bool found = funcList.find(fancyFunc.string(), 0) >= 0;
-        if (!found || func[0] == '\0') {
-            fprintf(stderr, "error: \"%s\" is not a valid kernel function "
-                "to trace.\n", func);
-            ok = false;
+        if (!strchr(func, '*')) {
+            String8 fancyFunc = String8::format("\n%s\n", func);
+            bool found = funcList.find(fancyFunc.string(), 0) >= 0;
+            if (!found || func[0] == '\0') {
+                fprintf(stderr, "error: \"%s\" is not a valid kernel function "
+                        "to trace.\n", func);
+                ok = false;
+            }
         }
         func = strtok(NULL, ",");
     }
diff --git a/cmds/dumpstate/Android.mk b/cmds/dumpstate/Android.mk
index 6442701..4d00d53 100644
--- a/cmds/dumpstate/Android.mk
+++ b/cmds/dumpstate/Android.mk
@@ -16,7 +16,7 @@
 
 LOCAL_SHARED_LIBRARIES := libcutils liblog libselinux
 LOCAL_HAL_STATIC_LIBRARIES := libdumpstate
-LOCAL_CFLAGS += -Wall -Wno-unused-parameter -std=gnu99
+LOCAL_CFLAGS += -Wall -Werror -Wno-unused-parameter
 LOCAL_INIT_RC := dumpstate.rc
 
 include $(BUILD_EXECUTABLE)
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 84a0100..792d7e8 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -113,8 +113,88 @@
 static const char mmcblk0[] = "/sys/block/mmcblk0/";
 unsigned long worst_write_perf = 20000; /* in KB/s */
 
+//
+//  stat offsets
+// Name            units         description
+// ----            -----         -----------
+// read I/Os       requests      number of read I/Os processed
+#define __STAT_READ_IOS      0
+// read merges     requests      number of read I/Os merged with in-queue I/O
+#define __STAT_READ_MERGES   1
+// read sectors    sectors       number of sectors read
+#define __STAT_READ_SECTORS  2
+// read ticks      milliseconds  total wait time for read requests
+#define __STAT_READ_TICKS    3
+// write I/Os      requests      number of write I/Os processed
+#define __STAT_WRITE_IOS     4
+// write merges    requests      number of write I/Os merged with in-queue I/O
+#define __STAT_WRITE_MERGES  5
+// write sectors   sectors       number of sectors written
+#define __STAT_WRITE_SECTORS 6
+// write ticks     milliseconds  total wait time for write requests
+#define __STAT_WRITE_TICKS   7
+// in_flight       requests      number of I/Os currently in flight
+#define __STAT_IN_FLIGHT     8
+// io_ticks        milliseconds  total time this block device has been active
+#define __STAT_IO_TICKS      9
+// time_in_queue   milliseconds  total wait time for all requests
+#define __STAT_IN_QUEUE     10
+#define __STAT_NUMBER_FIELD 11
+//
+// read I/Os, write I/Os
+// =====================
+//
+// These values increment when an I/O request completes.
+//
+// read merges, write merges
+// =========================
+//
+// These values increment when an I/O request is merged with an
+// already-queued I/O request.
+//
+// read sectors, write sectors
+// ===========================
+//
+// These values count the number of sectors read from or written to this
+// block device.  The "sectors" in question are the standard UNIX 512-byte
+// sectors, not any device- or filesystem-specific block size.  The
+// counters are incremented when the I/O completes.
+#define SECTOR_SIZE 512
+//
+// read ticks, write ticks
+// =======================
+//
+// These values count the number of milliseconds that I/O requests have
+// waited on this block device.  If there are multiple I/O requests waiting,
+// these values will increase at a rate greater than 1000/second; for
+// example, if 60 read requests wait for an average of 30 ms, the read_ticks
+// field will increase by 60*30 = 1800.
+//
+// in_flight
+// =========
+//
+// This value counts the number of I/O requests that have been issued to
+// the device driver but have not yet completed.  It does not include I/O
+// requests that are in the queue but not yet issued to the device driver.
+//
+// io_ticks
+// ========
+//
+// This value counts the number of milliseconds during which the device has
+// had I/O requests queued.
+//
+// time_in_queue
+// =============
+//
+// This value counts the number of milliseconds that I/O requests have waited
+// on this block device.  If there are multiple I/O requests waiting, this
+// value will increase as the product of the number of milliseconds times the
+// number of requests waiting (see "read ticks" above for an example).
+#define S_TO_MS 1000
+//
+
 static int dump_stat_from_fd(const char *title __unused, const char *path, int fd) {
-    unsigned long fields[11], read_perf, write_perf;
+    unsigned long long fields[__STAT_NUMBER_FIELD];
     bool z;
     char *cp, *buffer = NULL;
     size_t i = 0;
@@ -134,7 +214,7 @@
     }
     z = true;
     for (cp = buffer, i = 0; i < (sizeof(fields) / sizeof(fields[0])); ++i) {
-        fields[i] = strtol(cp, &cp, 0);
+        fields[i] = strtoull(cp, &cp, 10);
         if (fields[i] != 0) {
             z = false;
         }
@@ -151,17 +231,51 @@
     printf("%s: %s\n", path, buffer);
     free(buffer);
 
-    read_perf = 0;
-    if (fields[3]) {
-        read_perf = 512 * fields[2] / fields[3];
-    }
-    write_perf = 0;
-    if (fields[7]) {
-        write_perf = 512 * fields[6] / fields[7];
-    }
-    printf("%s: read: %luKB/s write: %luKB/s\n", path, read_perf, write_perf);
-    if ((write_perf > 1) && (write_perf < worst_write_perf)) {
-        worst_write_perf = write_perf;
+    if (fields[__STAT_IO_TICKS]) {
+        unsigned long read_perf = 0;
+        unsigned long read_ios = 0;
+        if (fields[__STAT_READ_TICKS]) {
+            unsigned long long divisor = fields[__STAT_READ_TICKS]
+                                       * fields[__STAT_IO_TICKS];
+            read_perf = ((unsigned long long)SECTOR_SIZE
+                           * fields[__STAT_READ_SECTORS]
+                           * fields[__STAT_IN_QUEUE] + (divisor >> 1))
+                                        / divisor;
+            read_ios = ((unsigned long long)S_TO_MS * fields[__STAT_READ_IOS]
+                           * fields[__STAT_IN_QUEUE] + (divisor >> 1))
+                                        / divisor;
+        }
+
+        unsigned long write_perf = 0;
+        unsigned long write_ios = 0;
+        if (fields[__STAT_WRITE_TICKS]) {
+            unsigned long long divisor = fields[__STAT_WRITE_TICKS]
+                                       * fields[__STAT_IO_TICKS];
+            write_perf = ((unsigned long long)SECTOR_SIZE
+                           * fields[__STAT_WRITE_SECTORS]
+                           * fields[__STAT_IN_QUEUE] + (divisor >> 1))
+                                        / divisor;
+            write_ios = ((unsigned long long)S_TO_MS * fields[__STAT_WRITE_IOS]
+                           * fields[__STAT_IN_QUEUE] + (divisor >> 1))
+                                        / divisor;
+        }
+
+        unsigned queue = (fields[__STAT_IN_QUEUE]
+                             + (fields[__STAT_IO_TICKS] >> 1))
+                                 / fields[__STAT_IO_TICKS];
+
+        if (!write_perf && !write_ios) {
+            printf("%s: perf(ios) rd: %luKB/s(%lu/s) q: %u\n",
+                   path, read_perf, read_ios, queue);
+        } else {
+            printf("%s: perf(ios) rd: %luKB/s(%lu/s) wr: %luKB/s(%lu/s) q: %u\n",
+                   path, read_perf, read_ios, write_perf, write_ios, queue);
+        }
+
+        /* bugreport timeout factor adjustment */
+        if ((write_perf > 1) && (write_perf < worst_write_perf)) {
+            worst_write_perf = write_perf;
+        }
     }
     return 0;
 }
@@ -323,6 +437,7 @@
     run_command("LIST OF OPEN FILES", 10, SU_PATH, "root", "lsof", NULL);
     for_each_pid(do_showmap, "SMAPS OF ALL PROCESSES");
     for_each_tid(show_wchan, "BLOCKED PROCESS WAIT-CHANNELS");
+    for_each_pid(show_showtime, "PROCESS TIMES (pid cmd user system iowait+percentage)");
 
     if (screenshot_path[0]) {
         ALOGI("taking screenshot\n");
@@ -771,11 +886,12 @@
 
     /* tell activity manager we're done */
     if (do_broadcast && use_outfile && do_fb) {
-        run_command(NULL, 5, "/system/bin/am", "broadcast", "--user", "0",
+        const char *args[] = { "/system/bin/am", "broadcast", "--user", "0",
                 "-a", "android.intent.action.BUGREPORT_FINISHED",
                 "--es", "android.intent.extra.BUGREPORT", path,
                 "--es", "android.intent.extra.SCREENSHOT", screenshot_path,
-                "--receiver-permission", "android.permission.DUMP", NULL);
+                "--receiver-permission", "android.permission.DUMP", NULL };
+        run_command_always(NULL, 5, args);
     }
 
     ALOGI("done\n");
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 3b6abc1..3063ec2 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -17,6 +17,18 @@
 #ifndef _DUMPSTATE_H_
 #define _DUMPSTATE_H_
 
+/* When defined, skips the real dumps and just print the section headers.
+   Useful when debugging dumpstate itself. */
+//#define _DUMPSTATE_DRY_RUN_
+
+#ifdef _DUMPSTATE_DRY_RUN_
+#define ON_DRY_RUN_RETURN(X) return X
+#endif
+#ifndef _DUMPSTATE_DRY_RUN_
+#define ON_DRY_RUN_RETURN(X)
+#endif
+
+
 #include <time.h>
 #include <unistd.h>
 #include <stdbool.h>
@@ -52,6 +64,11 @@
 /* forks a command and waits for it to finish -- terminate args with NULL */
 int run_command(const char *title, int timeout_seconds, const char *command, ...);
 
+/* forks a command and waits for it to finish
+   first element of args is the command, and last must be NULL.
+   command is always ran, even when _DUMPSTATE_DRY_RUN_ is defined. */
+int run_command_always(const char *title, int timeout_seconds, const char *args[]);
+
 /* prints all the system properties */
 void print_properties();
 
@@ -73,6 +90,9 @@
 /* Displays a blocked processes in-kernel wait channel */
 void show_wchan(int pid, int tid, const char *name);
 
+/* Displays a processes times */
+void show_showtime(int pid, const char *name);
+
 /* Runs "showmap" for a process */
 void do_showmap(int pid, const char *name);
 
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index c3e0262..e37fe78 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -26,6 +26,7 @@
 #include <string.h>
 #include <sys/inotify.h>
 #include <sys/stat.h>
+#include <sys/sysconf.h>
 #include <sys/time.h>
 #include <sys/wait.h>
 #include <sys/klog.h>
@@ -60,6 +61,7 @@
 }
 
 void for_each_userid(void (*func)(int), const char *header) {
+    ON_DRY_RUN_RETURN();
     DIR *d;
     struct dirent *de;
 
@@ -102,13 +104,32 @@
             continue;
         }
 
-        sprintf(cmdpath,"/proc/%d/cmdline", pid);
         memset(cmdline, 0, sizeof(cmdline));
-        if ((fd = TEMP_FAILURE_RETRY(open(cmdpath, O_RDONLY | O_CLOEXEC))) < 0) {
-            strcpy(cmdline, "N/A");
-        } else {
-            read(fd, cmdline, sizeof(cmdline) - 1);
+
+        snprintf(cmdpath, sizeof(cmdpath), "/proc/%d/cmdline", pid);
+        if ((fd = TEMP_FAILURE_RETRY(open(cmdpath, O_RDONLY | O_CLOEXEC))) >= 0) {
+            TEMP_FAILURE_RETRY(read(fd, cmdline, sizeof(cmdline) - 2));
             close(fd);
+            if (cmdline[0]) {
+                helper(pid, cmdline, arg);
+                continue;
+            }
+        }
+
+        // if no cmdline, a kernel thread has comm
+        snprintf(cmdpath, sizeof(cmdpath), "/proc/%d/comm", pid);
+        if ((fd = TEMP_FAILURE_RETRY(open(cmdpath, O_RDONLY | O_CLOEXEC))) >= 0) {
+            TEMP_FAILURE_RETRY(read(fd, cmdline + 1, sizeof(cmdline) - 4));
+            close(fd);
+            if (cmdline[1]) {
+                cmdline[0] = '[';
+                size_t len = strcspn(cmdline, "\f\b\r\n");
+                cmdline[len] = ']';
+                cmdline[len+1] = '\0';
+            }
+        }
+        if (!cmdline[0]) {
+            strcpy(cmdline, "N/A");
         }
         helper(pid, cmdline, arg);
     }
@@ -122,6 +143,7 @@
 }
 
 void for_each_pid(for_each_pid_func func, const char *header) {
+    ON_DRY_RUN_RETURN();
     __for_each_pid(for_each_pid_helper, header, (void *) func);
 }
 
@@ -159,7 +181,7 @@
             strcpy(comm, "N/A");
         } else {
             char *c;
-            read(fd, comm, sizeof(comm) - 1);
+            TEMP_FAILURE_RETRY(read(fd, comm, sizeof(comm) - 2));
             close(fd);
 
             c = strrchr(comm, '\n');
@@ -174,13 +196,15 @@
 }
 
 void for_each_tid(for_each_tid_func func, const char *header) {
+    ON_DRY_RUN_RETURN();
     __for_each_pid(for_each_tid_helper, header, (void *) func);
 }
 
 void show_wchan(int pid, int tid, const char *name) {
+    ON_DRY_RUN_RETURN();
     char path[255];
     char buffer[255];
-    int fd;
+    int fd, ret, save_errno;
     char name_buffer[255];
 
     memset(buffer, 0, sizeof(buffer));
@@ -191,9 +215,13 @@
         return;
     }
 
-    if (read(fd, buffer, sizeof(buffer)) < 0) {
-        printf("Failed to read '%s' (%s)\n", path, strerror(errno));
-        goto out_close;
+    ret = TEMP_FAILURE_RETRY(read(fd, buffer, sizeof(buffer)));
+    save_errno = errno;
+    close(fd);
+
+    if (ret < 0) {
+        printf("Failed to read '%s' (%s)\n", path, strerror(save_errno));
+        return;
     }
 
     snprintf(name_buffer, sizeof(name_buffer), "%*s%s",
@@ -201,13 +229,109 @@
 
     printf("%-7d %-32s %s\n", tid, name_buffer, buffer);
 
-out_close:
+    return;
+}
+
+// print time in centiseconds
+static void snprcent(char *buffer, size_t len, size_t spc,
+                     unsigned long long time) {
+    static long hz; // cache discovered hz
+
+    if (hz <= 0) {
+        hz = sysconf(_SC_CLK_TCK);
+        if (hz <= 0) {
+            hz = 1000;
+        }
+    }
+
+    // convert to centiseconds
+    time = (time * 100 + (hz / 2)) / hz;
+
+    char str[16];
+
+    snprintf(str, sizeof(str), " %llu.%02u",
+             time / 100, (unsigned)(time % 100));
+    size_t offset = strlen(buffer);
+    snprintf(buffer + offset, (len > offset) ? len - offset : 0,
+             "%*s", (spc > offset) ? (int)(spc - offset) : 0, str);
+}
+
+// print permille as a percent
+static void snprdec(char *buffer, size_t len, size_t spc, unsigned permille) {
+    char str[16];
+
+    snprintf(str, sizeof(str), " %u.%u%%", permille / 10, permille % 10);
+    size_t offset = strlen(buffer);
+    snprintf(buffer + offset, (len > offset) ? len - offset : 0,
+             "%*s", (spc > offset) ? (int)(spc - offset) : 0, str);
+}
+
+void show_showtime(int pid, const char *name) {
+    ON_DRY_RUN_RETURN();
+    char path[255];
+    char buffer[1023];
+    int fd, ret, save_errno;
+
+    memset(buffer, 0, sizeof(buffer));
+
+    sprintf(path, "/proc/%d/stat", pid);
+    if ((fd = TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_CLOEXEC))) < 0) {
+        printf("Failed to open '%s' (%s)\n", path, strerror(errno));
+        return;
+    }
+
+    ret = TEMP_FAILURE_RETRY(read(fd, buffer, sizeof(buffer)));
+    save_errno = errno;
     close(fd);
+
+    if (ret < 0) {
+        printf("Failed to read '%s' (%s)\n", path, strerror(save_errno));
+        return;
+    }
+
+    // field 14 is utime
+    // field 15 is stime
+    // field 42 is iotime
+    unsigned long long utime = 0, stime = 0, iotime = 0;
+    if (sscanf(buffer,
+               "%*u %*s %*s %*d %*d %*d %*d %*d %*d %*d %*d "
+               "%*d %*d %llu %llu %*d %*d %*d %*d %*d %*d "
+               "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d "
+               "%*d %*d %*d %*d %*d %*d %*d %*d %*d %llu ",
+               &utime, &stime, &iotime) != 3) {
+        return;
+    }
+
+    unsigned long long total = utime + stime;
+    if (!total) {
+        return;
+    }
+
+    unsigned permille = (iotime * 1000 + (total / 2)) / total;
+    if (permille > 1000) {
+        permille = 1000;
+    }
+
+    // try to beautify and stabilize columns at <80 characters
+    snprintf(buffer, sizeof(buffer), "%-6d%s", pid, name);
+    if ((name[0] != '[') || utime) {
+        snprcent(buffer, sizeof(buffer), 57, utime);
+    }
+    snprcent(buffer, sizeof(buffer), 65, stime);
+    if ((name[0] != '[') || iotime) {
+        snprcent(buffer, sizeof(buffer), 73, iotime);
+    }
+    if (iotime) {
+        snprdec(buffer, sizeof(buffer), 79, permille);
+    }
+    puts(buffer); // adds a trailing newline
+
     return;
 }
 
 void do_dmesg() {
     printf("------ KERNEL LOG (dmesg) ------\n");
+    ON_DRY_RUN_RETURN();
     /* Get size of kernel buffer */
     int size = klogctl(KLOG_SIZE_BUFFER, NULL, 0);
     if (size <= 0) {
@@ -299,10 +423,12 @@
 
 /* prints the contents of a file */
 int dump_file(const char *title, const char *path) {
+    if (title) printf("------ %s (%s) ------\n", title, path);
+    ON_DRY_RUN_RETURN(0);
+
     int fd = TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_NONBLOCK | O_CLOEXEC));
     if (fd < 0) {
         int err = errno;
-        if (title) printf("------ %s (%s) ------\n", title, path);
         printf("*** %s: %s\n", path, strerror(err));
         if (title) printf("\n");
         return -1;
@@ -328,6 +454,7 @@
     if (title) {
         printf("------ %s (%s) ------\n", title, dir);
     }
+    ON_DRY_RUN_RETURN(0);
 
     if (dir[strlen(dir) - 1] == '/') {
         ++slash;
@@ -384,6 +511,7 @@
  * stuck.
  */
 int dump_file_from_fd(const char *title, const char *path, int fd) {
+    ON_DRY_RUN_RETURN(0);
     int flags = fcntl(fd, F_GETFL);
     if (flags == -1) {
         printf("*** %s: failed to get flags on fd %d: %s\n", path, fd, strerror(errno));
@@ -442,6 +570,29 @@
 /* forks a command and waits for it to finish */
 int run_command(const char *title, int timeout_seconds, const char *command, ...) {
     fflush(stdout);
+
+    const char *args[1024] = {command};
+    size_t arg;
+    va_list ap;
+    va_start(ap, command);
+    if (title) printf("------ %s (%s", title, command);
+    for (arg = 1; arg < sizeof(args) / sizeof(args[0]); ++arg) {
+        args[arg] = va_arg(ap, const char *);
+        if (args[arg] == NULL) break;
+        if (title) printf(" %s", args[arg]);
+    }
+    if (title) printf(") ------\n");
+    fflush(stdout);
+
+    ON_DRY_RUN_RETURN(0);
+
+    return run_command_always(title, timeout_seconds, args);
+}
+
+/* forks a command and waits for it to finish */
+int run_command_always(const char *title, int timeout_seconds, const char *args[]) {
+    const char *command = args[0];
+
     uint64_t start = nanotime();
     pid_t pid = fork();
 
@@ -453,8 +604,6 @@
 
     /* handle child case */
     if (pid == 0) {
-        const char *args[1024] = {command};
-        size_t arg;
 
         /* make sure the child dies when dumpstate dies */
         prctl(PR_SET_PDEATHSIG, SIGKILL);
@@ -465,17 +614,6 @@
         sigact.sa_handler = SIG_IGN;
         sigaction(SIGPIPE, &sigact, NULL);
 
-        va_list ap;
-        va_start(ap, command);
-        if (title) printf("------ %s (%s", title, command);
-        for (arg = 1; arg < sizeof(args) / sizeof(args[0]); ++arg) {
-            args[arg] = va_arg(ap, const char *);
-            if (args[arg] == NULL) break;
-            if (title) printf(" %s", args[arg]);
-        }
-        if (title) printf(") ------\n");
-        fflush(stdout);
-
         execvp(command, (char**) args);
         printf("*** exec(%s): %s\n", command, strerror(errno));
         fflush(stdout);
@@ -532,12 +670,13 @@
 
 /* prints all the system properties */
 void print_properties() {
+    printf("------ SYSTEM PROPERTIES ------\n");
+    ON_DRY_RUN_RETURN();
     size_t i;
     num_props = 0;
     property_list(print_prop, NULL);
     qsort(&props, num_props, sizeof(props[0]), compare_prop);
 
-    printf("------ SYSTEM PROPERTIES ------\n");
     for (i = 0; i < num_props; ++i) {
         fputs(props[i], stdout);
         free(props[i]);
@@ -611,6 +750,7 @@
 
 /* dump Dalvik and native stack traces, return the trace file location (NULL if none) */
 const char *dump_traces() {
+    ON_DRY_RUN_RETURN(NULL);
     const char* result = NULL;
 
     char traces_path[PROPERTY_VALUE_MAX] = "";
@@ -764,6 +904,7 @@
 }
 
 void dump_route_tables() {
+    ON_DRY_RUN_RETURN();
     const char* const RT_TABLES_PATH = "/data/misc/net/rt_tables";
     dump_file("RT_TABLES", RT_TABLES_PATH);
     FILE* fp = fopen(RT_TABLES_PATH, "re");
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index 5956e13..44fd59e 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -126,6 +126,8 @@
 
     status_t            writeByteVector(const std::unique_ptr<std::vector<int8_t>>& val);
     status_t            writeByteVector(const std::vector<int8_t>& val);
+    status_t            writeByteVector(const std::unique_ptr<std::vector<uint8_t>>& val);
+    status_t            writeByteVector(const std::vector<uint8_t>& val);
     status_t            writeInt32Vector(const std::unique_ptr<std::vector<int32_t>>& val);
     status_t            writeInt32Vector(const std::vector<int32_t>& val);
     status_t            writeInt64Vector(const std::unique_ptr<std::vector<int64_t>>& val);
@@ -271,6 +273,8 @@
 
     status_t            readByteVector(std::unique_ptr<std::vector<int8_t>>* val) const;
     status_t            readByteVector(std::vector<int8_t>* val) const;
+    status_t            readByteVector(std::unique_ptr<std::vector<uint8_t>>* val) const;
+    status_t            readByteVector(std::vector<uint8_t>* val) const;
     status_t            readInt32Vector(std::unique_ptr<std::vector<int32_t>>* val) const;
     status_t            readInt32Vector(std::vector<int32_t>* val) const;
     status_t            readInt64Vector(std::unique_ptr<std::vector<int64_t>>* val) const;
diff --git a/include/binder/Status.h b/include/binder/Status.h
index 203a01e..ce947fa 100644
--- a/include/binder/Status.h
+++ b/include/binder/Status.h
@@ -141,6 +141,13 @@
     String8 mMessage;
 };  // class Status
 
+// For gtest output logging
+template<typename T>
+T& operator<< (T& stream, const Status& s) {
+    stream << s.toString8().string();
+    return stream;
+}
+
 }  // namespace binder
 }  // namespace android
 
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 2e9e658..cfe6bd2 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -18,7 +18,9 @@
 //#define LOG_NDEBUG 0
 
 #include <errno.h>
+#include <fcntl.h>
 #include <inttypes.h>
+#include <pthread.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -95,6 +97,32 @@
     BLOB_ASHMEM_MUTABLE = 2,
 };
 
+static dev_t ashmem_rdev()
+{
+    static dev_t __ashmem_rdev;
+    static pthread_mutex_t __ashmem_rdev_lock = PTHREAD_MUTEX_INITIALIZER;
+
+    pthread_mutex_lock(&__ashmem_rdev_lock);
+
+    dev_t rdev = __ashmem_rdev;
+    if (!rdev) {
+        int fd = TEMP_FAILURE_RETRY(open("/dev/ashmem", O_RDONLY));
+        if (fd >= 0) {
+            struct stat st;
+
+            int ret = TEMP_FAILURE_RETRY(fstat(fd, &st));
+            close(fd);
+            if ((ret >= 0) && S_ISCHR(st.st_mode)) {
+                rdev = __ashmem_rdev = st.st_rdev;
+            }
+        }
+    }
+
+    pthread_mutex_unlock(&__ashmem_rdev_lock);
+
+    return rdev;
+}
+
 void acquire_object(const sp<ProcessState>& proc,
     const flat_binder_object& obj, const void* who, size_t* outAshmemSize)
 {
@@ -126,7 +154,7 @@
             if ((obj.cookie != 0) && (outAshmemSize != NULL)) {
                 struct stat st;
                 int ret = fstat(obj.handle, &st);
-                if (!ret && S_ISCHR(st.st_mode)) {
+                if (!ret && S_ISCHR(st.st_mode) && (st.st_rdev == ashmem_rdev())) {
                     // If we own an ashmem fd, keep track of how much memory it refers to.
                     int size = ashmem_get_size_region(obj.handle);
                     if (size > 0) {
@@ -179,7 +207,7 @@
                 if (outAshmemSize != NULL) {
                     struct stat st;
                     int ret = fstat(obj.handle, &st);
-                    if (!ret && S_ISCHR(st.st_mode)) {
+                    if (!ret && S_ISCHR(st.st_mode) && (st.st_rdev == ashmem_rdev())) {
                         int size = ashmem_get_size_region(obj.handle);
                         if (size > 0) {
                             *outAshmemSize -= size;
@@ -782,16 +810,10 @@
   return writeUtf8AsUtf16(*str);
 }
 
-status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<int8_t>>& val)
-{
-    if (!val) {
-        return writeInt32(-1);
-    }
+namespace {
 
-    return writeByteVector(*val);
-}
-
-status_t Parcel::writeByteVector(const std::vector<int8_t>& val)
+template<typename T>
+status_t writeByteVectorInternal(Parcel* parcel, const std::vector<T>& val)
 {
     status_t status;
     if (val.size() > std::numeric_limits<int32_t>::max()) {
@@ -799,12 +821,12 @@
         return status;
     }
 
-    status = writeInt32(val.size());
+    status = parcel->writeInt32(val.size());
     if (status != OK) {
         return status;
     }
 
-    void* data = writeInplace(val.size());
+    void* data = parcel->writeInplace(val.size());
     if (!data) {
         status = BAD_VALUE;
         return status;
@@ -814,6 +836,37 @@
     return status;
 }
 
+template<typename T>
+status_t writeByteVectorInternalPtr(Parcel* parcel,
+                                    const std::unique_ptr<std::vector<T>>& val)
+{
+    if (!val) {
+        return parcel->writeInt32(-1);
+    }
+
+    return writeByteVectorInternal(parcel, *val);
+}
+
+}  // namespace
+
+status_t Parcel::writeByteVector(const std::vector<int8_t>& val) {
+    return writeByteVectorInternal(this, val);
+}
+
+status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<int8_t>>& val)
+{
+    return writeByteVectorInternalPtr(this, val);
+}
+
+status_t Parcel::writeByteVector(const std::vector<uint8_t>& val) {
+    return writeByteVectorInternal(this, val);
+}
+
+status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<uint8_t>>& val)
+{
+    return writeByteVectorInternalPtr(this, val);
+}
+
 status_t Parcel::writeInt32Vector(const std::vector<int32_t>& val)
 {
     return writeTypedVector(val, &Parcel::writeInt32);
@@ -1380,11 +1433,15 @@
     return err;
 }
 
-status_t Parcel::readByteVector(std::vector<int8_t>* val) const {
+namespace {
+
+template<typename T>
+status_t readByteVectorInternal(const Parcel* parcel,
+                                std::vector<T>* val) {
     val->clear();
 
     int32_t size;
-    status_t status = readInt32(&size);
+    status_t status = parcel->readInt32(&size);
 
     if (status != OK) {
         return status;
@@ -1394,12 +1451,12 @@
         status = UNEXPECTED_NULL;
         return status;
     }
-    if (size_t(size) > dataAvail()) {
+    if (size_t(size) > parcel->dataAvail()) {
         status = BAD_VALUE;
         return status;
     }
 
-    const void* data = readInplace(size);
+    const void* data = parcel->readInplace(size);
     if (!data) {
         status = BAD_VALUE;
         return status;
@@ -1410,20 +1467,23 @@
     return status;
 }
 
-status_t Parcel::readByteVector(std::unique_ptr<std::vector<int8_t>>* val) const {
-    const int32_t start = dataPosition();
+template<typename T>
+status_t readByteVectorInternalPtr(
+        const Parcel* parcel,
+        std::unique_ptr<std::vector<T>>* val) {
+    const int32_t start = parcel->dataPosition();
     int32_t size;
-    status_t status = readInt32(&size);
+    status_t status = parcel->readInt32(&size);
     val->reset();
 
     if (status != OK || size < 0) {
         return status;
     }
 
-    setDataPosition(start);
-    val->reset(new std::vector<int8_t>());
+    parcel->setDataPosition(start);
+    val->reset(new std::vector<T>());
 
-    status = readByteVector(val->get());
+    status = readByteVectorInternal(parcel, val->get());
 
     if (status != OK) {
         val->reset();
@@ -1432,6 +1492,24 @@
     return status;
 }
 
+}  // namespace
+
+status_t Parcel::readByteVector(std::vector<int8_t>* val) const {
+    return readByteVectorInternal(this, val);
+}
+
+status_t Parcel::readByteVector(std::vector<uint8_t>* val) const {
+    return readByteVectorInternal(this, val);
+}
+
+status_t Parcel::readByteVector(std::unique_ptr<std::vector<int8_t>>* val) const {
+    return readByteVectorInternalPtr(this, val);
+}
+
+status_t Parcel::readByteVector(std::unique_ptr<std::vector<uint8_t>>* val) const {
+    return readByteVectorInternalPtr(this, val);
+}
+
 status_t Parcel::readInt32Vector(std::unique_ptr<std::vector<int32_t>>* val) const {
     return readNullableTypedVector(val, &Parcel::readInt32);
 }
diff --git a/opengl/libs/EGL/egl_cache.cpp b/opengl/libs/EGL/egl_cache.cpp
index b0798a1..f368d75 100644
--- a/opengl/libs/EGL/egl_cache.cpp
+++ b/opengl/libs/EGL/egl_cache.cpp
@@ -21,6 +21,7 @@
 #include "egldefs.h"
 
 #include <fcntl.h>
+#include <inttypes.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -306,7 +307,8 @@
         // Sanity check the size before trying to mmap it.
         size_t fileSize = statBuf.st_size;
         if (fileSize > maxTotalSize * 2) {
-            ALOGE("cache file is too large: %#llx", statBuf.st_size);
+            ALOGE("cache file is too large: %#" PRIx64,
+                  static_cast<off64_t>(statBuf.st_size));
             close(fd);
             return;
         }
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index ec59235..e81621b 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -286,7 +286,7 @@
         // there are no reference to them, it which case, we're free to
         // delete them.
         size_t count = objects.size();
-        ALOGW_IF(count, "eglTerminate() called w/ %d objects remaining", count);
+        ALOGW_IF(count, "eglTerminate() called w/ %zu objects remaining", count);
         for (size_t i=0 ; i<count ; i++) {
             egl_object_t* o = objects.itemAt(i);
             o->destroy();
diff --git a/opengl/libs/EGL/egl_object.h b/opengl/libs/EGL/egl_object.h
index f5a9f58..17a8304 100644
--- a/opengl/libs/EGL/egl_object.h
+++ b/opengl/libs/EGL/egl_object.h
@@ -37,7 +37,7 @@
 namespace android {
 // ----------------------------------------------------------------------------
 
-struct egl_display_t;
+class egl_display_t;
 
 class egl_object_t {
     egl_display_t *display;
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index 0fba1bf..87c96ce 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -134,7 +134,7 @@
     case AMOTION_EVENT_ACTION_POINTER_DOWN:
     case AMOTION_EVENT_ACTION_POINTER_UP: {
         int32_t index = getMotionEventActionPointerIndex(action);
-        return index >= 0 && size_t(index) < pointerCount;
+        return index >= 0 && index < pointerCount;
     }
     case AMOTION_EVENT_ACTION_BUTTON_PRESS:
     case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 2d8eaef..7ae36d8 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -170,7 +170,7 @@
             << "Should reject motion events with pointer down index too large.";
 
     event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
-            AMOTION_EVENT_ACTION_POINTER_DOWN | (-1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+            AMOTION_EVENT_ACTION_POINTER_DOWN | (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
             0, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
             ARBITRARY_TIME, ARBITRARY_TIME,
             /*pointerCount*/ 1, pointerProperties, pointerCoords);
@@ -191,7 +191,7 @@
             << "Should reject motion events with pointer up index too large.";
 
     event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
-            AMOTION_EVENT_ACTION_POINTER_UP | (-1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+            AMOTION_EVENT_ACTION_POINTER_UP | (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
             0, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
             ARBITRARY_TIME, ARBITRARY_TIME,
             /*pointerCount*/ 1, pointerProperties, pointerCoords);
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 42bc865..a7fe69c 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -1528,8 +1528,8 @@
     NotifySwitchArgs args;
     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifySwitchWasCalled(&args));
     ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
-    ASSERT_EQ((1 << SW_LID) | (1 << SW_JACK_PHYSICAL_INSERT), args.switchValues);
-    ASSERT_EQ((1 << SW_LID) | (1 << SW_JACK_PHYSICAL_INSERT) | (1 << SW_HEADPHONE_INSERT),
+    ASSERT_EQ((1U << SW_LID) | (1U << SW_JACK_PHYSICAL_INSERT), args.switchValues);
+    ASSERT_EQ((1U << SW_LID) | (1U << SW_JACK_PHYSICAL_INSERT) | (1 << SW_HEADPHONE_INSERT),
             args.switchMask);
     ASSERT_EQ(uint32_t(0), args.policyFlags);
 }