Merge "openmax: Use unsigned 32bit integer for intra refresh period."
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 4d4e0ce..87f637c 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -550,17 +550,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/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 22fd2c3..ba4f8f9 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -185,8 +185,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;
@@ -206,7 +286,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;
         }
@@ -223,17 +303,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;
 }
diff --git a/cmds/installd/commands.cpp b/cmds/installd/commands.cpp
index e9ec3d3..df80eb6 100644
--- a/cmds/installd/commands.cpp
+++ b/cmds/installd/commands.cpp
@@ -57,7 +57,7 @@
         appid_t appid, const char* seinfo, int target_sdk_version) {
     uid_t uid = multiuser_get_uid(userid, appid);
     int target_mode = target_sdk_version >= MIN_RESTRICTED_HOME_SDK_VERSION ? 0700 : 0751;
-    if (flags & FLAG_CE_STORAGE) {
+    if (flags & FLAG_STORAGE_CE) {
         auto path = create_data_user_package_path(uuid, userid, pkgname);
         if (fs_prepare_dir_strict(path.c_str(), target_mode, uid, uid) != 0) {
             PLOG(ERROR) << "Failed to prepare " << path;
@@ -68,7 +68,7 @@
             return -1;
         }
     }
-    if (flags & FLAG_DE_STORAGE) {
+    if (flags & FLAG_STORAGE_DE) {
         auto path = create_data_user_de_package_path(uuid, userid, pkgname);
         if (fs_prepare_dir_strict(path.c_str(), target_mode, uid, uid) == -1) {
             PLOG(ERROR) << "Failed to prepare " << path;
@@ -93,13 +93,13 @@
     }
 
     int res = 0;
-    if (flags & FLAG_CE_STORAGE) {
+    if (flags & FLAG_STORAGE_CE) {
         auto path = create_data_user_package_path(uuid, userid, pkgname) + suffix;
         if (access(path.c_str(), F_OK) == 0) {
             res |= delete_dir_contents(path);
         }
     }
-    if (flags & FLAG_DE_STORAGE) {
+    if (flags & FLAG_STORAGE_DE) {
         auto path = create_data_user_de_package_path(uuid, userid, pkgname) + suffix;
         if (access(path.c_str(), F_OK) == 0) {
             // TODO: include result once 25796509 is fixed
@@ -111,11 +111,11 @@
 
 int destroy_app_data(const char *uuid, const char *pkgname, userid_t userid, int flags) {
     int res = 0;
-    if (flags & FLAG_CE_STORAGE) {
+    if (flags & FLAG_STORAGE_CE) {
         res |= delete_dir_contents_and_dir(
                 create_data_user_package_path(uuid, userid, pkgname));
     }
-    if (flags & FLAG_DE_STORAGE) {
+    if (flags & FLAG_STORAGE_DE) {
         // TODO: include result once 25796509 is fixed
         delete_dir_contents_and_dir(
                 create_data_user_de_package_path(uuid, userid, pkgname));
@@ -178,7 +178,7 @@
             goto fail;
         }
 
-        if (create_app_data(to_uuid, package_name, user, FLAG_CE_STORAGE | FLAG_DE_STORAGE,
+        if (create_app_data(to_uuid, package_name, user, FLAG_STORAGE_CE | FLAG_STORAGE_DE,
                 appid, seinfo, target_sdk_version) != 0) {
             LOG(ERROR) << "Failed to create package target " << to;
             goto fail;
@@ -204,7 +204,7 @@
             goto fail;
         }
 
-        if (restorecon_app_data(to_uuid, package_name, user, FLAG_CE_STORAGE | FLAG_DE_STORAGE,
+        if (restorecon_app_data(to_uuid, package_name, user, FLAG_STORAGE_CE | FLAG_STORAGE_DE,
                 appid, seinfo) != 0) {
             LOG(ERROR) << "Failed to restorecon";
             goto fail;
@@ -453,7 +453,7 @@
 
     for (auto user : users) {
         // TODO: handle user_de directories
-        if (!(flags & FLAG_CE_STORAGE)) continue;
+        if (!(flags & FLAG_STORAGE_CE)) continue;
 
         std::string _pkgdir(create_data_user_package_path(uuid, user, pkgname));
         const char* pkgdir = _pkgdir.c_str();
@@ -1194,7 +1194,14 @@
             || dexopt_needed == DEXOPT_SELF_PATCHOAT_NEEDED) {
             run_patchoat(input_fd, out_fd, input_file, out_path, pkgname, instruction_set);
         } else if (dexopt_needed == DEXOPT_DEX2OAT_NEEDED) {
-            run_dex2oat(input_fd, out_fd, image_fd, input_file, out_path, swap_fd,
+            // Pass dex2oat the relative path to the input file.
+            const char *input_file_name = strrchr(input_file, '/');
+            if (input_file_name == NULL) {
+                input_file_name = input_file;
+            } else {
+                input_file_name++;
+            }
+            run_dex2oat(input_fd, out_fd, image_fd, input_file_name, out_path, swap_fd,
                         instruction_set, vm_safe_mode, debuggable, boot_complete, extract_only,
                         profile_files_fd, reference_profile_files_fd);
         } else {
@@ -1482,14 +1489,14 @@
     }
 
     uid_t uid = multiuser_get_uid(userid, appid);
-    if (flags & FLAG_CE_STORAGE) {
+    if (flags & FLAG_STORAGE_CE) {
         auto path = create_data_user_package_path(uuid, userid, pkgName);
         if (selinux_android_restorecon_pkgdir(path.c_str(), seinfo, uid, seflags) < 0) {
             PLOG(ERROR) << "restorecon failed for " << path;
             res = -1;
         }
     }
-    if (flags & FLAG_DE_STORAGE) {
+    if (flags & FLAG_STORAGE_DE) {
         auto path = create_data_user_de_package_path(uuid, userid, pkgName);
         if (selinux_android_restorecon_pkgdir(path.c_str(), seinfo, uid, seflags) < 0) {
             PLOG(ERROR) << "restorecon failed for " << path;
diff --git a/cmds/installd/installd_constants.h b/cmds/installd/installd_constants.h
index 0d21519..4e1d38f 100644
--- a/cmds/installd/installd_constants.h
+++ b/cmds/installd/installd_constants.h
@@ -56,10 +56,13 @@
 constexpr size_t PKG_NAME_MAX = 128u;   /* largest allowed package name */
 constexpr size_t PKG_PATH_MAX = 256u;   /* max size of any path we use */
 
-constexpr int FLAG_DE_STORAGE = 1 << 0;
-constexpr int FLAG_CE_STORAGE = 1 << 1;
-constexpr int FLAG_CLEAR_CACHE_ONLY = 1 << 2;
-constexpr int FLAG_CLEAR_CODE_CACHE_ONLY = 1 << 3;
+// NOTE: keep in sync with StorageManager
+constexpr int FLAG_STORAGE_DE = 1 << 0;
+constexpr int FLAG_STORAGE_CE = 1 << 1;
+
+// NOTE: keep in sync with Installer
+constexpr int FLAG_CLEAR_CACHE_ONLY = 1 << 8;
+constexpr int FLAG_CLEAR_CODE_CACHE_ONLY = 1 << 9;
 
 /* dexopt needed flags matching those in dalvik.system.DexFile */
 constexpr int DEXOPT_DEX2OAT_NEEDED       = 1;
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index d3fe158..1008f02 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;