Merge "Add an installd command to prune dex files."
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index fca2357..566ce55 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -269,27 +269,40 @@
     return 0;
 }
 
-int delete_user(userid_t userid)
+int create_user(userid_t userid)
 {
-    char data_path[PKG_PATH_MAX];
-    if (create_user_path(data_path, userid)) {
-        return -1;
-    }
-    if (delete_dir_contents(data_path, 1, NULL)) {
-        return -1;
-    }
-
-    char media_path[PATH_MAX];
-    if (create_user_media_path(media_path, userid) == -1) {
-        return -1;
-    }
-    if (delete_dir_contents(media_path, 1, NULL) == -1) {
+    if (ensure_config_user_dirs(userid) == -1) {
         return -1;
     }
 
     return 0;
 }
 
+int delete_user(userid_t userid)
+{
+    int status = 0;
+
+    char data_path[PKG_PATH_MAX];
+    if ((create_user_path(data_path, userid) != 0)
+            || (delete_dir_contents(data_path, 1, NULL) != 0)) {
+        status = -1;
+    }
+
+    char media_path[PATH_MAX];
+    if ((create_user_media_path(media_path, userid) != 0)
+            || (delete_dir_contents(media_path, 1, NULL) != 0)) {
+        status = -1;
+    }
+
+    char config_path[PATH_MAX];
+    if ((create_user_config_path(config_path, userid) != 0)
+            || (delete_dir_contents(config_path, 1, NULL) != 0)) {
+        status = -1;
+    }
+
+    return status;
+}
+
 int delete_cache(const char *pkgname, userid_t userid)
 {
     char cachedir[PKG_PATH_MAX];
@@ -613,9 +626,12 @@
     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, "");
+    bool have_dex2oat_flags = property_get("dalvik.vm.dex2oat-flags", dex2oat_flags, NULL) > 0;
     ALOGV("dalvik.vm.dex2oat-flags=%s\n", dex2oat_flags);
 
+    char prop_buf[PROPERTY_VALUE_MAX];
+    bool profiler = (property_get("dalvik.vm.profiler", prop_buf, "0") > 0) && (prop_buf[0] == '1');
+
     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;
@@ -630,28 +646,59 @@
     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_arg[strlen("--profile-file=") + PKG_PATH_MAX];
     char instruction_set_arg[strlen("--instruction-set=") + MAX_INSTRUCTION_SET_LEN];
+    char profile_file_arg[strlen("--profile-file=") + PKG_PATH_MAX];
+    char top_k_profile_threshold_arg[strlen("--top-k-profile-threshold=") + PROPERTY_VALUE_MAX];
 
     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_arg, sizeof(profile_file_arg), "--profile-file=%s/%s",
+
+    bool have_profile_file = false;
+    bool have_top_k_profile_threshold = false;
+    if (profiler && (strcmp(pkgname, "*") != 0)) {
+        char profile_file[PKG_PATH_MAX];
+        snprintf(profile_file, sizeof(profile_file), "%s/%s",
                  DALVIK_CACHE_PREFIX "profiles", pkgname);
-    } else {
-        strcpy(profile_file_arg, "--no-profile-file");
+        struct stat st;
+        if ((stat(profile_file, &st) == 0) && (st.st_size > 0)) {
+            sprintf(profile_file_arg, "--profile-file=%s", profile_file);
+            have_profile_file = true;
+            if (property_get("dalvik.vm.profile.top-k-thr", prop_buf, NULL) > 0) {
+                snprintf(top_k_profile_threshold_arg, sizeof(top_k_profile_threshold_arg),
+                         "--top-k-profile-threshold=%s", prop_buf);
+                have_top_k_profile_threshold = true;
+            }
+        }
     }
 
     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_arg, instruction_set_arg,
-          strlen(dex2oat_flags) > 0 ? dex2oat_flags : NULL,
-          (char*) NULL);
+
+    char* argv[7  // program name, mandatory arguments and the final NULL
+               + (have_profile_file ? 1 : 0)
+               + (have_top_k_profile_threshold ? 1 : 0)
+               + (have_dex2oat_flags ? 1 : 0)];
+    int i = 0;
+    argv[i++] = (char*)DEX2OAT_BIN;
+    argv[i++] = zip_fd_arg;
+    argv[i++] = zip_location_arg;
+    argv[i++] = oat_fd_arg;
+    argv[i++] = oat_location_arg;
+    argv[i++] = instruction_set_arg;
+    if (have_profile_file) {
+        argv[i++] = profile_file_arg;
+    }
+    if (have_top_k_profile_threshold) {
+        argv[i++] = top_k_profile_threshold_arg;
+    }
+    if (have_dex2oat_flags) {
+        argv[i++] = dex2oat_flags;
+    }
+    argv[i] = NULL;
+
+    execv(DEX2OAT_BIN, (char* const *)argv);
     ALOGE("execl(%s) failed: %s\n", DEX2OAT_BIN, strerror(errno));
 }
 
diff --git a/cmds/installd/installd.c b/cmds/installd/installd.c
index 6775284..4368a9e 100644
--- a/cmds/installd/installd.c
+++ b/cmds/installd/installd.c
@@ -109,6 +109,11 @@
                              /* pkgname, uid, userid, seinfo */
 }
 
+static int do_mk_user(char **arg, char reply[REPLY_MAX])
+{
+    return create_user(atoi(arg[0])); /* userid */
+}
+
 static int do_rm_user(char **arg, char reply[REPLY_MAX])
 {
     return delete_user(atoi(arg[0])); /* userid */
@@ -163,6 +168,7 @@
     { "movefiles",            0, do_movefiles },
     { "linklib",              3, do_linklib },
     { "mkuserdata",           4, do_mk_user_data },
+    { "mkuser",               1, do_mk_user },
     { "rmuser",               1, do_rm_user },
     { "idmap",                3, do_idmap },
     { "restorecondata",       3, do_restorecon_data },
@@ -490,6 +496,66 @@
         goto fail;
     }
 
+    if (ensure_config_user_dirs(0) == -1) {
+        ALOGE("Failed to setup misc for user 0");
+        goto fail;
+    }
+
+    if (version == 2) {
+        ALOGD("Upgrading to /data/misc/user directories");
+
+        DIR *dir;
+        struct dirent *dirent;
+        char user_data_dir[PATH_MAX];
+
+        dir = opendir(user_data_dir);
+        if (dir != NULL) {
+            while ((dirent = readdir(dir))) {
+                if (dirent->d_type == DT_DIR) {
+                    const char *name = dirent->d_name;
+
+                    // skip "." and ".."
+                    if (name[0] == '.') {
+                        if (name[1] == 0) continue;
+                        if ((name[1] == '.') && (name[2] == 0)) continue;
+                    }
+
+                    // /data/misc/user/<user_id>
+                    if (ensure_config_user_dirs(atoi(name)) == -1) {
+                        goto fail;
+                    }
+                }
+            }
+            closedir(dir);
+        }
+
+        // Just rename keychain files into user/0; they should already have the right permissions
+        char misc_dir[PATH_MAX];
+        char keychain_added_dir[PATH_MAX];
+        char keychain_removed_dir[PATH_MAX];
+        char config_added_dir[PATH_MAX];
+        char config_removed_dir[PATH_MAX];
+
+        snprintf(misc_dir, PATH_MAX, "%s/misc", android_data_dir.path);
+        snprintf(keychain_added_dir, PATH_MAX, "%s/keychain/cacerts-added", misc_dir);
+        snprintf(keychain_removed_dir, PATH_MAX, "%s/keychain/cacerts-removed", misc_dir);
+        snprintf(config_added_dir, PATH_MAX, "%s/user/0/cacerts-added", misc_dir);
+        snprintf(config_removed_dir, PATH_MAX, "%s/user/0/cacerts-removed", misc_dir);
+
+        if (access(keychain_added_dir, F_OK) == 0) {
+            if (rename(keychain_added_dir, config_added_dir) != 0) {
+                goto fail;
+            }
+        }
+        if (access(keychain_removed_dir, F_OK) == 0) {
+            if (rename(keychain_removed_dir, config_removed_dir) != 0) {
+                goto fail;
+            }
+        }
+
+        version = 3;
+    }
+
     // Persist layout version if changed
     if (version != oldVersion) {
         if (fs_write_atomic_int(version_path, version) == -1) {
diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h
index 50ba39a..c1e6e0f 100644
--- a/cmds/installd/installd.h
+++ b/cmds/installd/installd.h
@@ -145,6 +145,8 @@
 
 int create_user_media_path(char path[PKG_PATH_MAX], userid_t userid);
 
+int create_user_config_path(char path[PKG_PATH_MAX], userid_t userid);
+
 int create_move_path(char path[PKG_PATH_MAX],
                      const char* pkgname,
                      const char* leaf,
@@ -190,6 +192,7 @@
 
 int ensure_dir(const char* path, mode_t mode, uid_t uid, gid_t gid);
 int ensure_media_user_dirs(userid_t userid);
+int ensure_config_user_dirs(userid_t userid);
 int create_profile_file(const char *pkgname, gid_t gid);
 void remove_profile_file(const char *pkgname);
 
@@ -201,6 +204,7 @@
 int fix_uid(const char *pkgname, uid_t uid, gid_t gid);
 int delete_user_data(const char *pkgname, userid_t userid);
 int make_user_data(const char *pkgname, uid_t uid, userid_t userid, const char* seinfo);
+int create_user(userid_t userid);
 int delete_user(userid_t userid);
 int delete_cache(const char *pkgname, userid_t userid);
 int move_dex(const char *src, const char *dst, const char *instruction_set);
diff --git a/cmds/installd/utils.c b/cmds/installd/utils.c
index cc3572d..35172de 100644
--- a/cmds/installd/utils.c
+++ b/cmds/installd/utils.c
@@ -149,6 +149,17 @@
     return 0;
 }
 
+/**
+ * Create the path name for config for a certain userid.
+ * Returns 0 on success, and -1 on failure.
+ */
+int create_user_config_path(char path[PATH_MAX], userid_t userid) {
+    if (snprintf(path, PATH_MAX, "%s%d", "/data/misc/user/", userid) > PATH_MAX) {
+        return -1;
+    }
+    return 0;
+}
+
 int create_move_path(char path[PKG_PATH_MAX],
     const char* pkgname,
     const char* leaf,
@@ -1009,52 +1020,46 @@
     return 0;
 }
 
+int ensure_config_user_dirs(userid_t userid) {
+    char config_user_path[PATH_MAX];
+    char path[PATH_MAX];
+
+    // writable by system, readable by any app within the same user
+    const int uid = (userid * AID_USER) + AID_SYSTEM;
+    const int gid = (userid * AID_USER) + AID_EVERYBODY;
+
+    // Ensure /data/misc/user/<userid> exists
+    create_user_config_path(config_user_path, userid);
+    if (fs_prepare_dir(config_user_path, 0750, uid, gid) == -1) {
+        return -1;
+    }
+
+   return 0;
+}
+
 int create_profile_file(const char *pkgname, gid_t gid) {
     const char *profile_dir = DALVIK_CACHE_PREFIX "profiles";
-    struct stat profileStat;
     char profile_file[PKG_PATH_MAX];
 
-    // If we don't have a profile directory under dalvik-cache we need to create one.
-    if (stat(profile_dir, &profileStat) < 0) {
-        // Create the profile directory under dalvik-cache.
-        if (mkdir(profile_dir, 0711) < 0) {
-            ALOGE("cannot make profile dir '%s': %s\n", profile_dir, strerror(errno));
-            return -1;
-        }
-
-        // Make the profile directory write-only for group and other. Owner can rwx it.
-        if (chmod(profile_dir, 0711) < 0) {
-            ALOGE("cannot chown profile dir '%s': %s\n", profile_dir, strerror(errno));
-            rmdir(profile_dir);
-            return -1;
-        }
-
-        if (selinux_android_restorecon(profile_dir, 0) < 0) {
-            ALOGE("cannot restorecon profile dir '%s': %s\n", profile_dir, strerror(errno));
-            rmdir(profile_dir);
-            return -1;
-        }
-    }
-
     snprintf(profile_file, sizeof(profile_file), "%s/%s", profile_dir, pkgname);
 
     // The 'system' user needs to be able to read the profile to determine if dex2oat
     // needs to be run.  This is done in dalvik.system.DexFile.isDexOptNeededInternal().  So
-    // we make it world readable.  Not a problem since the dalvik cache is world
-    // readable anyway.
+    // we assign ownership to AID_SYSTEM and ensure it's not world-readable.
 
-    int fd = open(profile_file, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW, 0664);
+    int fd = open(profile_file, O_WRONLY | O_CREAT | O_NOFOLLOW | O_CLOEXEC, 0660);
 
-    // Open will fail if the file already exists.  We want to ignore that.
+    // Always set the uid/gid/permissions. The file could have been previously created
+    // with different permissions.
     if (fd >= 0) {
-        if (fchown(fd, -1, gid) < 0) {
+        if (fchown(fd, AID_SYSTEM, gid) < 0) {
             ALOGE("cannot chown profile file '%s': %s\n", profile_file, strerror(errno));
             close(fd);
             unlink(profile_file);
             return -1;
         }
 
-        if (fchmod(fd, 0664) < 0) {
+        if (fchmod(fd, 0660) < 0) {
             ALOGE("cannot chmod profile file '%s': %s\n", profile_file, strerror(errno));
             close(fd);
             unlink(profile_file);
diff --git a/cmds/servicemanager/Android.mk b/cmds/servicemanager/Android.mk
index 4ab8df6..155cfc5 100644
--- a/cmds/servicemanager/Android.mk
+++ b/cmds/servicemanager/Android.mk
@@ -18,7 +18,7 @@
 include $(BUILD_EXECUTABLE)
 
 include $(CLEAR_VARS)
-LOCAL_SHARED_LIBRARIES := liblog
+LOCAL_SHARED_LIBRARIES := liblog libselinux
 LOCAL_SRC_FILES := service_manager.c binder.c
 LOCAL_CFLAGS += $(svc_c_flags)
 LOCAL_MODULE := servicemanager
diff --git a/cmds/servicemanager/service_manager.c b/cmds/servicemanager/service_manager.c
index 79ce6ed..939920a 100644
--- a/cmds/servicemanager/service_manager.c
+++ b/cmds/servicemanager/service_manager.c
@@ -8,6 +8,8 @@
 
 #include <private/android_filesystem_config.h>
 
+#include <selinux/android.h>
+
 #include "binder.h"
 
 #if 0
@@ -76,16 +78,67 @@
     return 1;
 }
 
-int svc_can_register(uid_t uid, const uint16_t *name)
+static struct selabel_handle* sehandle;
+
+static bool check_mac_perms(const char *name, pid_t spid)
+{
+    if (is_selinux_enabled() <= 0) {
+        return true;
+    }
+
+    bool allowed = false;
+
+    const char *class = "service_manager";
+    const char *perm = "add";
+
+    char *tctx = NULL;
+    char *sctx = NULL;
+
+    if (!sehandle) {
+        ALOGE("SELinux: Failed to find sehandle %s.\n", name);
+        return false;
+    }
+
+    if (getpidcon(spid, &sctx) < 0) {
+        ALOGE("SELinux: getpidcon failed to retrieve pid context.\n");
+        return false;
+    }
+
+    if (!sctx) {
+        ALOGE("SELinux: Failed to find sctx for %s.\n", name);
+        return false;
+    }
+
+    if (selabel_lookup(sehandle, &tctx, name, 1) != 0) {
+        ALOGE("SELinux: selabel_lookup failed to set tctx for %s.\n", name);
+        freecon(sctx);
+        return false;
+    }
+
+    if (!tctx) {
+        ALOGE("SELinux: Failed to find tctx for %s.\n", name);
+        freecon(sctx);
+        return false;
+    }
+
+    int result = selinux_check_access(sctx, tctx, class, perm, (void *) name);
+    allowed = (result == 0);
+
+    freecon(sctx);
+    freecon(tctx);
+    return allowed;
+}
+
+static int svc_can_register(uid_t uid, const uint16_t *name, pid_t spid)
 {
     size_t n;
 
     if ((uid == 0) || (uid == AID_SYSTEM))
-        return 1;
+        return check_mac_perms(str8(name), spid) ? 1 : 0;
 
     for (n = 0; n < sizeof(allowed) / sizeof(allowed[0]); n++)
         if ((uid == allowed[n].uid) && str16eq(name, allowed[n].name))
-            return 1;
+            return check_mac_perms(str8(name), spid) ? 1 : 0;
 
     return 0;
 }
@@ -155,7 +208,8 @@
 
 int do_add_service(struct binder_state *bs,
                    const uint16_t *s, size_t len,
-                   uint32_t handle, uid_t uid, int allow_isolated)
+                   uint32_t handle, uid_t uid, int allow_isolated,
+                   pid_t spid)
 {
     struct svcinfo *si;
 
@@ -165,7 +219,7 @@
     if (!handle || (len == 0) || (len > 127))
         return -1;
 
-    if (!svc_can_register(uid, s)) {
+    if (!svc_can_register(uid, s, spid)) {
         ALOGE("add_service('%s',%x) uid=%d - PERMISSION DENIED\n",
              str8(s), handle, uid);
         return -1;
@@ -235,6 +289,14 @@
         return -1;
     }
 
+    if (sehandle && selinux_status_updated() > 0) {
+        struct selabel_handle *tmp_sehandle = selinux_android_service_context_handle();
+        if (tmp_sehandle) {
+            selabel_close(sehandle);
+            sehandle = tmp_sehandle;
+        }
+    }
+
     switch(txn->code) {
     case SVC_MGR_GET_SERVICE:
     case SVC_MGR_CHECK_SERVICE:
@@ -249,7 +311,8 @@
         s = bio_get_string16(msg, &len);
         handle = bio_get_ref(msg);
         allow_isolated = bio_get_uint32(msg) ? 1 : 0;
-        if (do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated))
+        if (do_add_service(bs, s, len, handle, txn->sender_euid,
+            allow_isolated, txn->sender_pid))
             return -1;
         break;
 
@@ -274,6 +337,13 @@
     return 0;
 }
 
+
+static int audit_callback(void *data, security_class_t cls, char *buf, size_t len)
+{
+    snprintf(buf, len, "service=%s", !data ? "NULL" : (char *)data);
+    return 0;
+}
+
 int main(int argc, char **argv)
 {
     struct binder_state *bs;
@@ -289,6 +359,14 @@
         return -1;
     }
 
+    sehandle = selinux_android_service_context_handle();
+
+    union selinux_callback cb;
+    cb.func_audit = audit_callback;
+    selinux_set_callback(SELINUX_CB_AUDIT, cb);
+    cb.func_log = selinux_log_callback;
+    selinux_set_callback(SELINUX_CB_LOG, cb);
+
     svcmgr_handle = BINDER_SERVICE_MANAGER;
     binder_loop(bs, svcmgr_handler);
 
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index ce630bd..96aeee8 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -97,7 +97,6 @@
     status_t            writeInt64(int64_t val);
     status_t            writeFloat(float val);
     status_t            writeDouble(double val);
-    status_t            writeIntPtr(intptr_t val);
     status_t            writeCString(const char* str);
     status_t            writeString8(const String8& str);
     status_t            writeString16(const String16& str);
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index e83edd5..27a50a6 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -679,11 +679,6 @@
 
 #endif
 
-status_t Parcel::writeIntPtr(intptr_t val)
-{
-    return writeAligned(val);
-}
-
 status_t Parcel::writeCString(const char* str)
 {
     return write(str, strlen(str)+1);
diff --git a/libs/gui/BitTube.cpp b/libs/gui/BitTube.cpp
index 85a7de7..0282834 100644
--- a/libs/gui/BitTube.cpp
+++ b/libs/gui/BitTube.cpp
@@ -145,7 +145,7 @@
 
     // should never happen because of SOCK_SEQPACKET
     LOG_ALWAYS_FATAL_IF((size >= 0) && (size % objSize),
-            "BitTube::sendObjects(count=%d, size=%d), res=%d (partial events were sent!)",
+            "BitTube::sendObjects(count=%zu, size=%zu), res=%zd (partial events were sent!)",
             count, objSize, size);
 
     //ALOGE_IF(size<0, "error %d sending %d events", size, count);
@@ -160,7 +160,7 @@
 
     // should never happen because of SOCK_SEQPACKET
     LOG_ALWAYS_FATAL_IF((size >= 0) && (size % objSize),
-            "BitTube::recvObjects(count=%d, size=%d), res=%d (partial events were received!)",
+            "BitTube::recvObjects(count=%zu, size=%zu), res=%zd (partial events were received!)",
             count, objSize, size);
 
     //ALOGE_IF(size<0, "error %d receiving %d events", size, count);
diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp
index c4ec857..674ee5a 100644
--- a/libs/gui/ConsumerBase.cpp
+++ b/libs/gui/ConsumerBase.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include <inttypes.h>
+
 #define LOG_TAG "ConsumerBase"
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 //#define LOG_NDEBUG 0
@@ -188,7 +190,7 @@
     mSlots[item->mBuf].mFrameNumber = item->mFrameNumber;
     mSlots[item->mBuf].mFence = item->mFence;
 
-    CB_LOGV("acquireBufferLocked: -> slot=%d/%llu",
+    CB_LOGV("acquireBufferLocked: -> slot=%d/%" PRIu64,
             item->mBuf, item->mFrameNumber);
 
     return OK;
@@ -239,7 +241,7 @@
         return OK;
     }
 
-    CB_LOGV("releaseBufferLocked: slot=%d/%llu",
+    CB_LOGV("releaseBufferLocked: slot=%d/%" PRIu64,
             slot, mSlots[slot].mFrameNumber);
     status_t err = mConsumer->releaseBuffer(slot, mSlots[slot].mFrameNumber,
             display, eglFence, mSlots[slot].mFence);
diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp
index da6b0f9..e8948bb 100644
--- a/libs/gui/Sensor.cpp
+++ b/libs/gui/Sensor.cpp
@@ -134,11 +134,11 @@
         return NO_MEMORY;
     }
 
-    FlattenableUtils::write(buffer, size, mName.length());
+    FlattenableUtils::write(buffer, size, static_cast<uint32_t>(mName.length()));
     memcpy(static_cast<char*>(buffer), mName.string(), mName.length());
     FlattenableUtils::advance(buffer, size, FlattenableUtils::align<4>(mName.length()));
 
-    FlattenableUtils::write(buffer, size, mVendor.length());
+    FlattenableUtils::write(buffer, size, static_cast<uint32_t>(mVendor.length()));
     memcpy(static_cast<char*>(buffer), mVendor.string(), mVendor.length());
     FlattenableUtils::advance(buffer, size, FlattenableUtils::align<4>(mVendor.length()));
 
@@ -156,9 +156,9 @@
 }
 
 status_t Sensor::unflatten(void const* buffer, size_t size) {
-    size_t len;
+    uint32_t len;
 
-    if (size < sizeof(size_t)) {
+    if (size < sizeof(uint32_t)) {
         return NO_MEMORY;
     }
     FlattenableUtils::read(buffer, size, len);
@@ -169,7 +169,7 @@
     FlattenableUtils::advance(buffer, size, FlattenableUtils::align<4>(len));
 
 
-    if (size < sizeof(size_t)) {
+    if (size < sizeof(uint32_t)) {
         return NO_MEMORY;
     }
     FlattenableUtils::read(buffer, size, len);
@@ -179,7 +179,7 @@
     mVendor.setTo(static_cast<char const*>(buffer), len);
     FlattenableUtils::advance(buffer, size, FlattenableUtils::align<4>(len));
 
-    size_t fixedSize =
+    const size_t fixedSize =
             sizeof(int32_t) * 3 +
             sizeof(float) * 4 +
             sizeof(int32_t) * 3;
diff --git a/opengl/libs/EGL/getProcAddress.cpp b/opengl/libs/EGL/getProcAddress.cpp
index 5470d81..fc61134 100644
--- a/opengl/libs/EGL/getProcAddress.cpp
+++ b/opengl/libs/EGL/getProcAddress.cpp
@@ -53,9 +53,29 @@
             : [tls] "J"(TLS_SLOT_OPENGL_API*4),                 \
               [api] "J"(__builtin_offsetof(gl_hooks_t,          \
                                       ext.extensions[_api]))    \
-            :                                                   \
+            : "r12"                                             \
             );
 
+#elif defined(__aarch64__)
+
+    #define API_ENTRY(_api) __attribute__((noinline)) _api
+
+    #define CALL_GL_EXTENSION_API(_api)                             \
+        asm volatile(                                               \
+            "mrs x16, tpidr_el0\n"                                  \
+            "ldr x16, [x16, %[tls]]\n"                              \
+            "cbz x16, 1f\n"                                         \
+            "ldr x16, [x16, %[api]]\n"                              \
+            "cbz x16, 1f\n"                                         \
+            "br  x16\n"                                             \
+            "1:\n"                                                  \
+            :                                                       \
+            : [tls] "i" (TLS_SLOT_OPENGL_API * sizeof(void*)),      \
+              [api] "i" (__builtin_offsetof(gl_hooks_t,             \
+                                        ext.extensions[_api]))      \
+            : "x16"                                                 \
+        );
+
 #elif defined(__i386__)
 
     #define API_ENTRY(_api) __attribute__((noinline)) _api
diff --git a/opengl/libs/GLES2/gl2.cpp b/opengl/libs/GLES2/gl2.cpp
index ab6fb51..e112fec 100644
--- a/opengl/libs/GLES2/gl2.cpp
+++ b/opengl/libs/GLES2/gl2.cpp
@@ -40,7 +40,15 @@
 #undef CALL_GL_API
 #undef CALL_GL_API_RETURN
 
-#if defined(__arm__) && !USE_SLOW_BINDING
+#if USE_SLOW_BINDING
+
+    #define API_ENTRY(_api) _api
+
+    #define CALL_GL_API(_api, ...)                                       \
+        gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;  \
+        if (_c) return _c->_api(__VA_ARGS__);
+
+#elif defined(__arm__)
 
     #define GET_TLS(reg) "mrc p15, 0, " #reg ", c13, c0, 3 \n"
 
@@ -55,10 +63,28 @@
             :                                                   \
             : [tls] "J"(TLS_SLOT_OPENGL_API*4),                 \
               [api] "J"(__builtin_offsetof(gl_hooks_t, gl._api))    \
-            :                                                   \
+            : "r12"                                             \
             );
 
-#elif defined(__i386__) && !USE_SLOW_BINDING
+#elif defined(__aarch64__)
+
+    #define API_ENTRY(_api) __attribute__((noinline)) _api
+
+    #define CALL_GL_API(_api, ...)                                  \
+        asm volatile(                                               \
+            "mrs x16, tpidr_el0\n"                                  \
+            "ldr x16, [x16, %[tls]]\n"                              \
+            "cbz x16, 1f\n"                                         \
+            "ldr x16, [x16, %[api]]\n"                              \
+            "br  x16\n"                                             \
+            "1:\n"                                                  \
+            :                                                       \
+            : [tls] "i" (TLS_SLOT_OPENGL_API * sizeof(void*)),      \
+              [api] "i" (__builtin_offsetof(gl_hooks_t, gl._api))   \
+            : "x16"                                                 \
+        );
+
+#elif defined(__i386__)
 
     #define API_ENTRY(_api) __attribute__((noinline)) _api
 
@@ -77,7 +103,7 @@
             : "cc"                                                  \
             );
 
-#elif defined(__x86_64__) && !USE_SLOW_BINDING
+#elif defined(__x86_64__)
 
     #define API_ENTRY(_api) __attribute__((noinline)) _api
 
@@ -96,7 +122,7 @@
             : "cc"                                                  \
             );
 
-#elif defined(__mips__) && !USE_SLOW_BINDING
+#elif defined(__mips__)
 
     #define API_ENTRY(_api) __attribute__((noinline)) _api
 
@@ -128,14 +154,6 @@
             :                                                    \
             );
 
-#else
-
-    #define API_ENTRY(_api) _api
-
-    #define CALL_GL_API(_api, ...)                                       \
-        gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;  \
-        if (_c) return _c->_api(__VA_ARGS__);
-
 #endif
 
 #define CALL_GL_API_RETURN(_api, ...) \
diff --git a/opengl/libs/GLES_CM/gl.cpp b/opengl/libs/GLES_CM/gl.cpp
index 5873391..71fbed1 100644
--- a/opengl/libs/GLES_CM/gl.cpp
+++ b/opengl/libs/GLES_CM/gl.cpp
@@ -92,7 +92,15 @@
 #undef CALL_GL_API
 #undef CALL_GL_API_RETURN
 
-#if defined(__arm__) && !USE_SLOW_BINDING
+#if USE_SLOW_BINDING
+
+    #define API_ENTRY(_api) _api
+
+    #define CALL_GL_API(_api, ...)                                       \
+        gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;  \
+        if (_c) return _c->_api(__VA_ARGS__);
+
+#elif defined(__arm__)
 
     #define GET_TLS(reg) "mrc p15, 0, " #reg ", c13, c0, 3 \n"
 
@@ -107,10 +115,28 @@
             :                                                   \
             : [tls] "J"(TLS_SLOT_OPENGL_API*4),                 \
               [api] "J"(__builtin_offsetof(gl_hooks_t, gl._api))    \
-            :                                                   \
+            : "r12"                                             \
             );
 
-#elif defined(__i386__) && !USE_SLOW_BINDING
+#elif defined(__aarch64__)
+
+    #define API_ENTRY(_api) __attribute__((noinline)) _api
+
+    #define CALL_GL_API(_api, ...)                                  \
+        asm volatile(                                               \
+            "mrs x16, tpidr_el0\n"                                  \
+            "ldr x16, [x16, %[tls]]\n"                              \
+            "cbz x16, 1f\n"                                         \
+            "ldr x16, [x16, %[api]]\n"                              \
+            "br  x16\n"                                             \
+            "1:\n"                                                  \
+            :                                                       \
+            : [tls] "i" (TLS_SLOT_OPENGL_API * sizeof(void*)),      \
+              [api] "i" (__builtin_offsetof(gl_hooks_t, gl._api))   \
+            : "x16"                                                 \
+        );
+
+#elif defined(__i386__)
 
     #define API_ENTRY(_api) __attribute__((noinline)) _api
 
@@ -129,7 +155,7 @@
             : "cc"                                                  \
             );
 
-#elif defined(__x86_64__) && !USE_SLOW_BINDING
+#elif defined(__x86_64__)
 
     #define API_ENTRY(_api) __attribute__((noinline)) _api
 
@@ -148,7 +174,7 @@
             : "cc"                                                  \
             );
 
-#elif defined(__mips__) && !USE_SLOW_BINDING
+#elif defined(__mips__)
 
     #define API_ENTRY(_api) __attribute__((noinline)) _api
 
@@ -180,14 +206,6 @@
             :                                                    \
             );
 
-#else
-
-    #define API_ENTRY(_api) _api
-
-    #define CALL_GL_API(_api, ...)                                       \
-        gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;  \
-        if (_c) return _c->_api(__VA_ARGS__);
-
 #endif
 
 #define CALL_GL_API_RETURN(_api, ...) \
diff --git a/opengl/tests/hwc/Android.mk b/opengl/tests/hwc/Android.mk
index 2fdfcf8..86e1d46 100644
--- a/opengl/tests/hwc/Android.mk
+++ b/opengl/tests/hwc/Android.mk
@@ -57,7 +57,6 @@
 LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
 
 LOCAL_MODULE:= hwcStress
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativestresstest
 
 LOCAL_MODULE_TAGS := tests
 
@@ -88,7 +87,6 @@
 	$(call include-path-for, opengl-tests-includes)
 
 LOCAL_MODULE:= hwcRects
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativeutil
 
 LOCAL_MODULE_TAGS := tests
 
@@ -119,7 +117,6 @@
 	$(call include-path-for, opengl-tests-includes)
 
 LOCAL_MODULE:= hwcColorEquiv
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativeutil
 
 LOCAL_MODULE_TAGS := tests
 
@@ -150,7 +147,6 @@
 	$(call include-path-for, opengl-tests-includes)
 
 LOCAL_MODULE:= hwcCommit
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativebenchmark
 
 LOCAL_MODULE_TAGS := tests
 
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index 3b64f0a..35b7819 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -14,8 +14,9 @@
  * limitations under the License.
  */
 
-#include <stdint.h>
+#include <inttypes.h>
 #include <math.h>
+#include <stdint.h>
 #include <sys/types.h>
 
 #include <utils/Atomic.h>
@@ -134,11 +135,11 @@
     Info& info( mActivationCount.editValueFor(handle) );
 
     ALOGD_IF(DEBUG_CONNECTIONS,
-             "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%d",
+             "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%zu",
              ident, handle, enabled, info.batchParams.size());
 
     if (enabled) {
-        ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%d", info.batchParams.indexOfKey(ident));
+        ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%zd", info.batchParams.indexOfKey(ident));
 
         if (info.batchParams.indexOfKey(ident) >= 0) {
           if (info.batchParams.size() == 1) {
@@ -150,7 +151,7 @@
             ALOGE("\t >>>ERROR: activate called without batch");
         }
     } else {
-        ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%d", info.batchParams.indexOfKey(ident));
+        ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%zd", info.batchParams.indexOfKey(ident));
 
         if (info.removeBatchParamsForIdent(ident) >= 0) {
             if (info.batchParams.size() == 0) {
@@ -163,7 +164,7 @@
                     // batch_rate and timeout. One of the apps has unregistered for sensor
                     // events, and the best effort batch parameters might have changed.
                     ALOGD_IF(DEBUG_CONNECTIONS,
-                             "\t>>> actuating h/w batch %d %d %lld %lld ", handle,
+                             "\t>>> actuating h/w batch %d %d %" PRId64 " %" PRId64, handle,
                              info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
                              info.bestBatchParams.batchTimeout);
                     mSensorDevice->batch(mSensorDevice, handle,info.bestBatchParams.flags,
@@ -191,7 +192,7 @@
 
     // On older devices which do not support batch, call setDelay().
     if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1 && info.batchParams.size() > 0) {
-        ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w setDelay %d %lld ", handle,
+        ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w setDelay %d %" PRId64, handle,
                  info.bestBatchParams.batchDelay);
         mSensorDevice->setDelay(
                 reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
@@ -231,7 +232,7 @@
     }
 
     ALOGD_IF(DEBUG_CONNECTIONS,
-             "SensorDevice::batch: ident=%p, handle=0x%08x, flags=%d, period_ns=%lld timeout=%lld",
+             "SensorDevice::batch: ident=%p, handle=0x%08x, flags=%d, period_ns=%" PRId64 " timeout=%" PRId64,
              ident, handle, flags, samplingPeriodNs, maxBatchReportLatencyNs);
 
     Mutex::Autolock _l(mLock);
@@ -250,7 +251,8 @@
     info.selectBatchParams();
 
     ALOGD_IF(DEBUG_CONNECTIONS,
-             "\t>>> curr_period=%lld min_period=%lld curr_timeout=%lld min_timeout=%lld",
+             "\t>>> curr_period=%" PRId64 " min_period=%" PRId64
+             " curr_timeout=%" PRId64 " min_timeout=%" PRId64,
              prevBestBatchParams.batchDelay, info.bestBatchParams.batchDelay,
              prevBestBatchParams.batchTimeout, info.bestBatchParams.batchTimeout);
 
@@ -258,7 +260,7 @@
     // If the min period or min timeout has changed since the last batch call, call batch.
     if (prevBestBatchParams != info.bestBatchParams) {
         if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) {
-            ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH %d %d %lld %lld ", handle,
+            ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH %d %d %" PRId64 " %" PRId64, handle,
                      info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
                      info.bestBatchParams.batchTimeout);
             err = mSensorDevice->batch(mSensorDevice, handle, info.bestBatchParams.flags,
@@ -270,7 +272,8 @@
             // call setDelay in SensorDevice::activate() method.
         }
         if (err != NO_ERROR) {
-            ALOGE("sensor batch failed %p %d %d %lld %lld err=%s", mSensorDevice, handle,
+            ALOGE("sensor batch failed %p %d %d %" PRId64 " %" PRId64 " err=%s",
+                  mSensorDevice, handle,
                   info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
                   info.bestBatchParams.batchTimeout, strerror(-err));
             info.removeBatchParamsForIdent(ident);
@@ -324,7 +327,7 @@
                                                     int64_t maxBatchReportLatencyNs) {
     ssize_t index = batchParams.indexOfKey(ident);
     if (index < 0) {
-        ALOGE("Info::setBatchParamsForIdent(ident=%p, period_ns=%lld timeout=%lld) failed (%s)",
+        ALOGE("Info::setBatchParamsForIdent(ident=%p, period_ns=%" PRId64 " timeout=%" PRId64 ") failed (%s)",
               ident, samplingPeriodNs, maxBatchReportLatencyNs, strerror(-index));
         return BAD_INDEX;
     }
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 6df6315..d671951 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -370,7 +370,7 @@
                     for (size_t j=0 ; j<activeVirtualSensorCount ; j++) {
                         if (count + k >= minBufferSize) {
                             ALOGE("buffer too small to hold all events: "
-                                    "count=%u, k=%u, size=%u",
+                                    "count=%zd, k=%zu, size=%zu",
                                     count, k, minBufferSize);
                             break;
                         }
@@ -509,11 +509,11 @@
     Mutex::Autolock _l(mLock);
     const wp<SensorEventConnection> connection(c);
     size_t size = mActiveSensors.size();
-    ALOGD_IF(DEBUG_CONNECTIONS, "%d active sensors", size);
+    ALOGD_IF(DEBUG_CONNECTIONS, "%zu active sensors", size);
     for (size_t i=0 ; i<size ; ) {
         int handle = mActiveSensors.keyAt(i);
         if (c->hasSensor(handle)) {
-            ALOGD_IF(DEBUG_CONNECTIONS, "%i: disabling handle=0x%08x", i, handle);
+            ALOGD_IF(DEBUG_CONNECTIONS, "%zu: disabling handle=0x%08x", i, handle);
             SensorInterface* sensor = mSensorMap.valueFor( handle );
             ALOGE_IF(!sensor, "mSensorMap[handle=0x%08x] is null!", handle);
             if (sensor) {
@@ -521,9 +521,9 @@
             }
         }
         SensorRecord* rec = mActiveSensors.valueAt(i);
-        ALOGE_IF(!rec, "mActiveSensors[%d] is null (handle=0x%08x)!", i, handle);
+        ALOGE_IF(!rec, "mActiveSensors[%zu] is null (handle=0x%08x)!", i, handle);
         ALOGD_IF(DEBUG_CONNECTIONS,
-                "removing connection %p for sensor[%d].handle=0x%08x",
+                "removing connection %p for sensor[%zu].handle=0x%08x",
                 c, i, handle);
 
         if (rec && rec->removeConnection(connection)) {
@@ -591,7 +591,7 @@
         samplingPeriodNs = minDelayNs;
     }
 
-    ALOGD_IF(DEBUG_CONNECTIONS, "Calling batch handle==%d flags=%d rate=%lld timeout== %lld",
+    ALOGD_IF(DEBUG_CONNECTIONS, "Calling batch handle==%d flags=%d rate=%" PRId64 " timeout== %" PRId64,
              handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs);
 
     status_t err = sensor->batch(connection.get(), handle, reservedFlags, samplingPeriodNs,