Merge "fix GraphicBuffer::flatten crash issue when handle is null"
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index a86abe1..cfb80e3 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -387,7 +387,7 @@
     return data_disk_free() >= free_size ? 0 : -1;
 }
 
-int move_dex(const char *src, const char *dst)
+int move_dex(const char *src, const char *dst, const char *instruction_set)
 {
     char src_dex[PKG_PATH_MAX];
     char dst_dex[PKG_PATH_MAX];
@@ -395,8 +395,8 @@
     if (validate_apk_path(src)) return -1;
     if (validate_apk_path(dst)) return -1;
 
-    if (create_cache_path(src_dex, src)) return -1;
-    if (create_cache_path(dst_dex, dst)) return -1;
+    if (create_cache_path(src_dex, src, instruction_set)) return -1;
+    if (create_cache_path(dst_dex, dst, instruction_set)) return -1;
 
     ALOGV("move %s -> %s\n", src_dex, dst_dex);
     if (rename(src_dex, dst_dex) < 0) {
@@ -407,12 +407,12 @@
     }
 }
 
-int rm_dex(const char *path)
+int rm_dex(const char *path, const char *instruction_set)
 {
     char dex_path[PKG_PATH_MAX];
 
     if (validate_apk_path(path)) return -1;
-    if (create_cache_path(dex_path, path)) return -1;
+    if (create_cache_path(dex_path, path, instruction_set)) return -1;
 
     ALOGV("unlink %s\n", dex_path);
     if (unlink(dex_path) < 0) {
@@ -425,8 +425,8 @@
 
 int get_size(const char *pkgname, userid_t userid, const char *apkpath,
              const char *libdirpath, const char *fwdlock_apkpath, const char *asecpath,
-             int64_t *_codesize, int64_t *_datasize, int64_t *_cachesize,
-             int64_t* _asecsize)
+             const char *instruction_set, int64_t *_codesize, int64_t *_datasize,
+             int64_t *_cachesize, int64_t* _asecsize)
 {
     DIR *d;
     int dfd;
@@ -456,7 +456,7 @@
         }
     }
         /* count the cached dexfile as code */
-    if (!create_cache_path(path, apkpath)) {
+    if (!create_cache_path(path, apkpath, instruction_set)) {
         if (stat(path, &s) == 0) {
             codesize += stat_size(&s);
         }
@@ -543,7 +543,7 @@
 }
 
 
-int create_cache_path(char path[PKG_PATH_MAX], const char *src)
+int create_cache_path(char path[PKG_PATH_MAX], const char *src, const char *instruction_set)
 {
     char *tmp;
     int srclen;
@@ -561,18 +561,20 @@
     }
 
     dstlen = srclen + strlen(DALVIK_CACHE_PREFIX) +
-        strlen(DALVIK_CACHE_POSTFIX) + 1;
+        strlen(instruction_set) +
+        strlen(DALVIK_CACHE_POSTFIX) + 2;
 
     if (dstlen > PKG_PATH_MAX) {
         return -1;
     }
 
-    sprintf(path,"%s%s%s",
+    sprintf(path,"%s%s/%s%s",
             DALVIK_CACHE_PREFIX,
+            instruction_set,
             src + 1, /* skip the leading / */
             DALVIK_CACHE_POSTFIX);
 
-    for(tmp = path + strlen(DALVIK_CACHE_PREFIX); *tmp; tmp++) {
+    for(tmp = path + strlen(DALVIK_CACHE_PREFIX) + strlen(instruction_set) + 1; *tmp; tmp++) {
         if (*tmp == '/') {
             *tmp = '@';
         }
@@ -604,7 +606,7 @@
 }
 
 static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name,
-    const char* output_file_name, const char *pkgname)
+    const char* output_file_name, const char *pkgname, const char *instruction_set)
 {
     char dex2oat_flags[PROPERTY_VALUE_MAX];
     property_get("dalvik.vm.dex2oat-flags", dex2oat_flags, "");
@@ -612,28 +614,38 @@
 
     static const char* DEX2OAT_BIN = "/system/bin/dex2oat";
     static const int MAX_INT_LEN = 12;      // '-'+10dig+'\0' -OR- 0x+8dig
+    static const unsigned int MAX_INSTRUCTION_SET_LEN = 32;
+
+    if (strlen(instruction_set) >= MAX_INSTRUCTION_SET_LEN) {
+        ALOGE("Instruction set %s longer than max length of %d",
+              instruction_set, MAX_INSTRUCTION_SET_LEN);
+        return;
+    }
+
     char zip_fd_arg[strlen("--zip-fd=") + MAX_INT_LEN];
     char zip_location_arg[strlen("--zip-location=") + PKG_PATH_MAX];
     char oat_fd_arg[strlen("--oat-fd=") + MAX_INT_LEN];
     char oat_location_arg[strlen("--oat-name=") + PKG_PATH_MAX];
-    char profile_file[strlen("--profile-file=") + PKG_PATH_MAX];
+    char profile_file_arg[strlen("--profile-file=") + PKG_PATH_MAX];
+    char instruction_set_arg[strlen("--instruction-set=") + MAX_INSTRUCTION_SET_LEN];
 
     sprintf(zip_fd_arg, "--zip-fd=%d", zip_fd);
     sprintf(zip_location_arg, "--zip-location=%s", input_file_name);
     sprintf(oat_fd_arg, "--oat-fd=%d", oat_fd);
     sprintf(oat_location_arg, "--oat-location=%s", output_file_name);
+    sprintf(instruction_set_arg, "--instruction-set=%s", instruction_set);
     if (strcmp(pkgname, "*") != 0) {
-        snprintf(profile_file, sizeof(profile_file), "--profile-file=%s/%s",
+        snprintf(profile_file_arg, sizeof(profile_file_arg), "--profile-file=%s/%s",
                  DALVIK_CACHE_PREFIX "profiles", pkgname);
     } else {
-        strcpy(profile_file, "--no-profile-file");
+        strcpy(profile_file_arg, "--no-profile-file");
     }
 
     ALOGV("Running %s in=%s out=%s\n", DEX2OAT_BIN, input_file_name, output_file_name);
     execl(DEX2OAT_BIN, DEX2OAT_BIN,
           zip_fd_arg, zip_location_arg,
           oat_fd_arg, oat_location_arg,
-          profile_file,
+          profile_file_arg, instruction_set_arg,
           strlen(dex2oat_flags) > 0 ? dex2oat_flags : NULL,
           (char*) NULL);
     ALOGE("execl(%s) failed: %s\n", DEX2OAT_BIN, strerror(errno));
@@ -666,7 +678,7 @@
 }
 
 int dexopt(const char *apk_path, uid_t uid, int is_public,
-           const char *pkgname)
+           const char *pkgname, const char *instruction_set)
 {
     struct utimbuf ut;
     struct stat apk_stat, dex_stat;
@@ -694,7 +706,7 @@
         }
     }
 
-    if (create_cache_path(out_path, apk_path)) {
+    if (create_cache_path(out_path, apk_path, instruction_set)) {
         return -1;
     }
 
@@ -762,7 +774,7 @@
         if (strncmp(persist_sys_dalvik_vm_lib, "libdvm", 6) == 0) {
             run_dexopt(zip_fd, out_fd, apk_path, out_path);
         } else if (strncmp(persist_sys_dalvik_vm_lib, "libart", 6) == 0) {
-            run_dex2oat(zip_fd, out_fd, apk_path, out_path, pkgname);
+            run_dex2oat(zip_fd, out_fd, apk_path, out_path, pkgname, instruction_set);
         } else {
             exit(69);   /* Unexpected persist.sys.dalvik.vm.lib value */
         }
diff --git a/cmds/installd/installd.c b/cmds/installd/installd.c
index a078e1c..10bf5fa 100644
--- a/cmds/installd/installd.c
+++ b/cmds/installd/installd.c
@@ -38,18 +38,18 @@
 
 static int do_dexopt(char **arg, char reply[REPLY_MAX])
 {
-        /* apk_path, uid, is_public, pkgname */
-    return dexopt(arg[0], atoi(arg[1]), atoi(arg[2]), arg[3]);
+        /* apk_path, uid, is_public, pkgname, instruction_set */
+    return dexopt(arg[0], atoi(arg[1]), atoi(arg[2]), arg[3], arg[4]);
 }
 
 static int do_move_dex(char **arg, char reply[REPLY_MAX])
 {
-    return move_dex(arg[0], arg[1]); /* src, dst */
+    return move_dex(arg[0], arg[1], arg[2]); /* src, dst, instruction_set */
 }
 
 static int do_rm_dex(char **arg, char reply[REPLY_MAX])
 {
-    return rm_dex(arg[0]); /* pkgname */
+    return rm_dex(arg[0], arg[1]); /* pkgname, instruction_set */
 }
 
 static int do_remove(char **arg, char reply[REPLY_MAX])
@@ -87,7 +87,7 @@
 
         /* pkgdir, userid, apkpath */
     res = get_size(arg[0], atoi(arg[1]), arg[2], arg[3], arg[4], arg[5],
-            &codesize, &datasize, &cachesize, &asecsize);
+            arg[6], &codesize, &datasize, &cachesize, &asecsize);
 
     /*
      * Each int64_t can take up 22 characters printed out. Make sure it
@@ -144,15 +144,15 @@
 struct cmdinfo cmds[] = {
     { "ping",                 0, do_ping },
     { "install",              4, do_install },
-    { "dexopt",               4, do_dexopt },
-    { "movedex",              2, do_move_dex },
-    { "rmdex",                1, do_rm_dex },
+    { "dexopt",               5, do_dexopt },
+    { "movedex",              3, do_move_dex },
+    { "rmdex",                2, do_rm_dex },
     { "remove",               2, do_remove },
     { "rename",               2, do_rename },
     { "fixuid",               3, do_fixuid },
     { "freecache",            1, do_free_cache },
     { "rmcache",              2, do_rm_cache },
-    { "getsize",              6, do_get_size },
+    { "getsize",              7, do_get_size },
     { "rmuserdata",           2, do_rm_user_data },
     { "movefiles",            0, do_movefiles },
     { "linklib",              3, do_linklib },
diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h
index 3e9caf3..0f7119d 100644
--- a/cmds/installd/installd.h
+++ b/cmds/installd/installd.h
@@ -152,7 +152,8 @@
 
 int is_valid_package_name(const char* pkgname);
 
-int create_cache_path(char path[PKG_PATH_MAX], const char *src);
+int create_cache_path(char path[PKG_PATH_MAX], const char *src,
+                      const char *instruction_set);
 
 int delete_dir_contents(const char *pathname,
                         int also_delete_dir,
@@ -202,14 +203,15 @@
 int make_user_data(const char *pkgname, uid_t uid, userid_t userid, const char* seinfo);
 int delete_user(userid_t userid);
 int delete_cache(const char *pkgname, userid_t userid);
-int move_dex(const char *src, const char *dst);
-int rm_dex(const char *path);
+int move_dex(const char *src, const char *dst, const char *instruction_set);
+int rm_dex(const char *path, const char *instruction_set);
 int protect(char *pkgname, gid_t gid);
 int get_size(const char *pkgname, userid_t userid, const char *apkpath, const char *libdirpath,
-             const char *fwdlock_apkpath, const char *asecpath, int64_t *codesize,
-             int64_t *datasize, int64_t *cachesize, int64_t *asecsize);
+             const char *fwdlock_apkpath, const char *asecpath, const char *instruction_set,
+             int64_t *codesize, int64_t *datasize, int64_t *cachesize, int64_t *asecsize);
 int free_cache(int64_t free_size);
-int dexopt(const char *apk_path, uid_t uid, int is_public, const char *pkgName);
+int dexopt(const char *apk_path, uid_t uid, int is_public, const char *pkgName,
+           const char *instruction_set);
 int movefiles();
 int linklib(const char* target, const char* source, int userId);
 int idmap(const char *target_path, const char *overlay_path, uid_t uid);
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 159003d..169e503 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -25,6 +25,7 @@
 #include <binder/ProcessState.h>
 #include <binder/TextOutput.h>
 
+#include <errno.h>
 #include <utils/Debug.h>
 #include <utils/Log.h>
 #include <utils/String8.h>
@@ -1229,7 +1230,11 @@
     status_t err = NO_ERROR;
     for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
         fds[i] = dup(this->readFileDescriptor());
-        if (fds[i] < 0) err = BAD_VALUE;
+        if (fds[i] < 0) {
+            err = BAD_VALUE;
+            ALOGE("dup() failed in Parcel::read, i is %d, fds[i] is %d, fd_count is %d, error: %s",
+                i, fds[i], fd_count, strerror(errno));
+        }
     }
 
     if (err == NO_ERROR) {