Region: Detect malicious overflow in unflatten am: 1a65fccc50 am: fd579a51b5 am: 0e85f4d48d am: 0ec362e024
am: b82c6f52c0

Change-Id: Iae280f2d174a8144e7c9fa657cd346597658927c
diff --git a/cmds/atrace/Android.mk b/cmds/atrace/Android.mk
index a787e95..bfb3838 100644
--- a/cmds/atrace/Android.mk
+++ b/cmds/atrace/Android.mk
@@ -16,6 +16,7 @@
     libcutils \
     libutils \
     libz \
+    libbase
 
 LOCAL_INIT_RC := atrace.rc
 
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index facf300..b7208d3 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -41,6 +41,7 @@
 #include <utils/Timers.h>
 #include <utils/Tokenizer.h>
 #include <utils/Trace.h>
+#include <android-base/file.h>
 
 using namespace android;
 
@@ -532,11 +533,11 @@
 
 // Set the system property that indicates which apps should perform
 // application-level tracing.
-static bool setAppCmdlineProperty(const char* cmdline)
+static bool setAppCmdlineProperty(char* cmdline)
 {
     char buf[PROPERTY_KEY_MAX];
     int i = 0;
-    const char* start = cmdline;
+    char* start = cmdline;
     while (start != NULL) {
         if (i == MAX_PACKAGES) {
             fprintf(stderr, "error: only 16 packages could be traced at once\n");
@@ -586,24 +587,14 @@
 // kernel.
 static bool verifyKernelTraceFuncs(const char* funcs)
 {
-    int fd = open(k_ftraceFilterPath, O_RDONLY);
-    if (fd == -1) {
-        fprintf(stderr, "error opening %s: %s (%d)\n", k_ftraceFilterPath,
+    std::string buf;
+    if (!android::base::ReadFileToString(k_ftraceFilterPath, &buf)) {
+         fprintf(stderr, "error opening %s: %s (%d)\n", k_ftraceFilterPath,
             strerror(errno), errno);
-        return false;
+         return false;
     }
 
-    char buf[4097];
-    ssize_t n = read(fd, buf, 4096);
-    close(fd);
-    if (n == -1) {
-        fprintf(stderr, "error reading %s: %s (%d)\n", k_ftraceFilterPath,
-            strerror(errno), errno);
-        return false;
-    }
-
-    buf[n] = '\0';
-    String8 funcList = String8::format("\n%s", buf);
+    String8 funcList = String8::format("\n%s",buf.c_str());
 
     // Make sure that every function listed in funcs is in the list we just
     // read from the kernel, except for wildcard inputs.
@@ -623,7 +614,6 @@
         func = strtok(NULL, ",");
     }
     free(myFuncs);
-
     return ok;
 }
 
@@ -753,7 +743,7 @@
         }
         packageList += value;
     }
-    ok &= setAppCmdlineProperty(packageList.data());
+    ok &= setAppCmdlineProperty(&packageList[0]);
     ok &= pokeBinderServices();
 
     // Disable all the sysfs enables.  This is done as a separate loop from
diff --git a/cmds/dumpstate/Android.mk b/cmds/dumpstate/Android.mk
index a588ef4..2dc8787 100644
--- a/cmds/dumpstate/Android.mk
+++ b/cmds/dumpstate/Android.mk
@@ -14,9 +14,9 @@
 
 LOCAL_MODULE := dumpstate
 
-LOCAL_SHARED_LIBRARIES := libcutils liblog libselinux
+LOCAL_SHARED_LIBRARIES := libcutils liblog libselinux libbase
 # ZipArchive support, the order matters here to get all symbols.
-LOCAL_STATIC_LIBRARIES := libziparchive libz libbase libmincrypt
+LOCAL_STATIC_LIBRARIES := libziparchive libz libcrypto_static
 LOCAL_HAL_STATIC_LIBRARIES := libdumpstate
 LOCAL_CFLAGS += -Wall -Werror -Wno-unused-parameter
 LOCAL_INIT_RC := dumpstate.rc
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 5c31d6b..48a1b10 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -46,7 +46,7 @@
 #include "ScopedFd.h"
 #include "ziparchive/zip_writer.h"
 
-#include "mincrypt/sha256.h"
+#include <openssl/sha.h>
 
 using android::base::StringPrintf;
 
@@ -644,7 +644,8 @@
     dump_files("UPTIME MMC PERF", mmcblk0, skip_not_stat, dump_stat_from_fd);
     dump_emmc_ecsd("/d/mmc0/mmc0:0001/ext_csd");
     dump_file("MEMORY INFO", "/proc/meminfo");
-    run_command("CPU INFO", 10, "top", "-n", "1", "-d", "1", "-m", "30", "-H", NULL);
+    run_command("CPU INFO", 10, "top", "-b", "-n", "1", "-H", "-s", "6",
+                "-o", "pid,tid,user,pr,ni,%cpu,s,virt,res,pcy,cmd,name", NULL);
     run_command("PROCRANK", 20, SU_PATH, "root", "procrank", NULL);
     dump_file("VIRTUAL MEMORY STATS", "/proc/vmstat");
     dump_file("VMALLOC INFO", "/proc/vmallocinfo");
@@ -658,7 +659,8 @@
     dump_file("KERNEL CPUFREQ", "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state");
     dump_file("KERNEL SYNC", "/d/sync");
 
-    run_command("PROCESSES AND THREADS", 10, "ps", "-Z", "-t", "-p", "-P", NULL);
+    run_command("PROCESSES AND THREADS", 10, "ps", "-A", "-T", "-Z",
+                "-O", "pri,nice,rtprio,sched,pcy", NULL);
     run_command("LIBRANK", 10, SU_PATH, "root", "librank", NULL);
 
     run_command("PRINTENV", 10, "printenv", NULL);
@@ -1004,7 +1006,7 @@
     }
 
     SHA256_CTX ctx;
-    SHA256_init(&ctx);
+    SHA256_Init(&ctx);
 
     std::vector<uint8_t> buffer(65536);
     while (1) {
@@ -1016,13 +1018,14 @@
             return NULL;
         }
 
-        SHA256_update(&ctx, buffer.data(), bytes_read);
+        SHA256_Update(&ctx, buffer.data(), bytes_read);
     }
 
-    uint8_t hash[SHA256_DIGEST_SIZE];
-    memcpy(hash, SHA256_final(&ctx), SHA256_DIGEST_SIZE);
-    char hash_buffer[SHA256_DIGEST_SIZE * 2 + 1];
-    for(size_t i = 0; i < SHA256_DIGEST_SIZE; i++) {
+    uint8_t hash[SHA256_DIGEST_LENGTH];
+    SHA256_Final(hash, &ctx);
+
+    char hash_buffer[SHA256_DIGEST_LENGTH * 2 + 1];
+    for(size_t i = 0; i < SHA256_DIGEST_LENGTH; i++) {
         sprintf(hash_buffer + (i * 2), "%02x", hash[i]);
     }
     hash_buffer[sizeof(hash_buffer) - 1] = 0;
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index 09c2e7f..b33d7ab 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -28,7 +28,6 @@
 #include <sys/capability.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>
@@ -38,6 +37,8 @@
 #include <sys/prctl.h>
 
 #define LOG_TAG "dumpstate"
+
+#include <android-base/file.h>
 #include <cutils/debugger.h>
 #include <cutils/log.h>
 #include <cutils/properties.h>
@@ -179,7 +180,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);
+    __for_each_pid(for_each_pid_helper, header, (void *) func);
 }
 
 static void for_each_tid_helper(int pid, const char *cmdline, void *arg) {
@@ -576,6 +577,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));
@@ -1246,52 +1248,38 @@
 }
 
 void dump_emmc_ecsd(const char *ext_csd_path) {
-    static const size_t EXT_CSD_REV = 192;
-    static const size_t EXT_PRE_EOL_INFO = 267;
-    static const size_t EXT_DEVICE_LIFE_TIME_EST_TYP_A = 268;
-    static const size_t EXT_DEVICE_LIFE_TIME_EST_TYP_B = 269;
+    // List of interesting offsets
     struct hex {
         char str[2];
-    } buffer[512];
-    int fd, ext_csd_rev, ext_pre_eol_info;
-    ssize_t bytes_read;
-    static const char *ver_str[] = {
-        "4.0", "4.1", "4.2", "4.3", "Obsolete", "4.41", "4.5", "5.0"
     };
-    static const char *eol_str[] = {
-        "Undefined",
-        "Normal",
-        "Warning (consumed 80% of reserve)",
-        "Urgent (consumed 90% of reserve)"
-    };
+    static const size_t EXT_CSD_REV = 192 * sizeof(hex);
+    static const size_t EXT_PRE_EOL_INFO = 267 * sizeof(hex);
+    static const size_t EXT_DEVICE_LIFE_TIME_EST_TYP_A = 268 * sizeof(hex);
+    static const size_t EXT_DEVICE_LIFE_TIME_EST_TYP_B = 269 * sizeof(hex);
+
+    std::string buffer;
+    if (!android::base::ReadFileToString(ext_csd_path, &buffer)) {
+        return;
+    }
 
     printf("------ %s Extended CSD ------\n", ext_csd_path);
 
-    fd = TEMP_FAILURE_RETRY(open(ext_csd_path,
-                                 O_RDONLY | O_NONBLOCK | O_CLOEXEC));
-    if (fd < 0) {
-        printf("*** %s: %s\n\n", ext_csd_path, strerror(errno));
+    if (buffer.length() < (EXT_CSD_REV + sizeof(hex))) {
+        printf("*** %s: truncated content %zu\n\n", ext_csd_path, buffer.length());
         return;
     }
 
-    bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer, sizeof(buffer)));
-    close(fd);
-    if (bytes_read < 0) {
-        printf("*** %s: %s\n\n", ext_csd_path, strerror(errno));
-        return;
-    }
-    if (bytes_read < (ssize_t)(EXT_CSD_REV * sizeof(struct hex))) {
-        printf("*** %s: truncated content %zd\n\n", ext_csd_path, bytes_read);
+    int ext_csd_rev = 0;
+    std::string sub = buffer.substr(EXT_CSD_REV, sizeof(hex));
+    if (sscanf(sub.c_str(), "%2x", &ext_csd_rev) != 1) {
+        printf("*** %s: EXT_CSD_REV parse error \"%s\"\n\n",
+               ext_csd_path, sub.c_str());
         return;
     }
 
-    ext_csd_rev = 0;
-    if (sscanf(buffer[EXT_CSD_REV].str, "%02x", &ext_csd_rev) != 1) {
-        printf("*** %s: EXT_CSD_REV parse error \"%.2s\"\n\n",
-               ext_csd_path, buffer[EXT_CSD_REV].str);
-        return;
-    }
-
+    static const char *ver_str[] = {
+        "4.0", "4.1", "4.2", "4.3", "Obsolete", "4.41", "4.5", "5.0"
+    };
     printf("rev 1.%d (MMC %s)\n",
            ext_csd_rev,
            (ext_csd_rev < (int)(sizeof(ver_str) / sizeof(ver_str[0]))) ?
@@ -1302,17 +1290,25 @@
         return;
     }
 
-    if (bytes_read < (ssize_t)(EXT_PRE_EOL_INFO * sizeof(struct hex))) {
-        printf("*** %s: truncated content %zd\n\n", ext_csd_path, bytes_read);
+    if (buffer.length() < (EXT_PRE_EOL_INFO + sizeof(hex))) {
+        printf("*** %s: truncated content %zu\n\n", ext_csd_path, buffer.length());
         return;
     }
 
-    ext_pre_eol_info = 0;
-    if (sscanf(buffer[EXT_PRE_EOL_INFO].str, "%02x", &ext_pre_eol_info) != 1) {
-        printf("*** %s: PRE_EOL_INFO parse error \"%.2s\"\n\n",
-               ext_csd_path, buffer[EXT_PRE_EOL_INFO].str);
+    int ext_pre_eol_info = 0;
+    sub = buffer.substr(EXT_PRE_EOL_INFO, sizeof(hex));
+    if (sscanf(sub.c_str(), "%2x", &ext_pre_eol_info) != 1) {
+        printf("*** %s: PRE_EOL_INFO parse error \"%s\"\n\n",
+               ext_csd_path, sub.c_str());
         return;
     }
+
+    static const char *eol_str[] = {
+        "Undefined",
+        "Normal",
+        "Warning (consumed 80% of reserve)",
+        "Urgent (consumed 90% of reserve)"
+    };
     printf("PRE_EOL_INFO %d (MMC %s)\n",
            ext_pre_eol_info,
            eol_str[(ext_pre_eol_info < (int)
@@ -1321,7 +1317,7 @@
 
     for (size_t lifetime = EXT_DEVICE_LIFE_TIME_EST_TYP_A;
             lifetime <= EXT_DEVICE_LIFE_TIME_EST_TYP_B;
-            ++lifetime) {
+            lifetime += sizeof(hex)) {
         int ext_device_life_time_est;
         static const char *est_str[] = {
             "Undefined",
@@ -1338,21 +1334,24 @@
             "Exceeded the maximum estimated device lifetime",
         };
 
-        if (bytes_read < (ssize_t)(lifetime * sizeof(struct hex))) {
-            printf("*** %s: truncated content %zd\n", ext_csd_path, bytes_read);
+        if (buffer.length() < (lifetime + sizeof(hex))) {
+            printf("*** %s: truncated content %zu\n", ext_csd_path, buffer.length());
             break;
         }
 
         ext_device_life_time_est = 0;
-        if (sscanf(buffer[lifetime].str, "%02x", &ext_device_life_time_est) != 1) {
-            printf("*** %s: DEVICE_LIFE_TIME_EST_TYP_%c parse error \"%.2s\"\n",
+        sub = buffer.substr(lifetime, sizeof(hex));
+        if (sscanf(sub.c_str(), "%2x", &ext_device_life_time_est) != 1) {
+            printf("*** %s: DEVICE_LIFE_TIME_EST_TYP_%c parse error \"%s\"\n",
                    ext_csd_path,
-                   (unsigned)(lifetime - EXT_DEVICE_LIFE_TIME_EST_TYP_A) + 'A',
-                   buffer[lifetime].str);
+                   (unsigned)((lifetime - EXT_DEVICE_LIFE_TIME_EST_TYP_A) /
+                              sizeof(hex)) + 'A',
+                   sub.c_str());
             continue;
         }
         printf("DEVICE_LIFE_TIME_EST_TYP_%c %d (MMC %s)\n",
-               (unsigned)(lifetime - EXT_DEVICE_LIFE_TIME_EST_TYP_A) + 'A',
+               (unsigned)((lifetime - EXT_DEVICE_LIFE_TIME_EST_TYP_A) /
+                          sizeof(hex)) + 'A',
                ext_device_life_time_est,
                est_str[(ext_device_life_time_est < (int)
                            (sizeof(est_str) / sizeof(est_str[0]))) ?
diff --git a/cmds/installd/commands.cpp b/cmds/installd/commands.cpp
index 2a9950a..e6680ed 100644
--- a/cmds/installd/commands.cpp
+++ b/cmds/installd/commands.cpp
@@ -1922,7 +1922,6 @@
         PLOG(ERROR) << "Could not rename " << from << " to " << to;
         return false;
     }
-
     return true;
 }
 
diff --git a/cmds/installd/installd.cpp b/cmds/installd/installd.cpp
index 061359e..1583f86 100644
--- a/cmds/installd/installd.cpp
+++ b/cmds/installd/installd.cpp
@@ -65,8 +65,8 @@
                              const char *oat_dir,
                              const char *apk_path,
                              const char *instruction_set) {
-    char *file_name_start;
-    char *file_name_end;
+    const char *file_name_start;
+    const char *file_name_end;
 
     file_name_start = strrchr(apk_path, '/');
     if (file_name_start == NULL) {
diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp
index ac511ec..3f76770 100644
--- a/cmds/installd/otapreopt.cpp
+++ b/cmds/installd/otapreopt.cpp
@@ -506,8 +506,8 @@
                              const char *apk_path,
                              const char *instruction_set) {
     // TODO: Insert B directory.
-    char *file_name_start;
-    char *file_name_end;
+    const char *file_name_start;
+    const char *file_name_end;
 
     file_name_start = strrchr(apk_path, '/');
     if (file_name_start == nullptr) {
diff --git a/include/binder/IInterface.h b/include/binder/IInterface.h
index 4ce3613..48c8b3b 100644
--- a/include/binder/IInterface.h
+++ b/include/binder/IInterface.h
@@ -105,7 +105,7 @@
 
 
 #define CHECK_INTERFACE(interface, data, reply)                         \
-    if (!data.checkInterface(this)) { return PERMISSION_DENIED; }       \
+    if (!(data).checkInterface(this)) { return PERMISSION_DENIED; }     \
 
 
 // ----------------------------------------------------------------------
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index 1c355c4..42ed148 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -20,8 +20,8 @@
 #include <string>
 #include <vector>
 
+#include <android-base/unique_fd.h>
 #include <cutils/native_handle.h>
-#include <nativehelper/ScopedFd.h>
 #include <utils/Errors.h>
 #include <utils/RefBase.h>
 #include <utils/String16.h>
@@ -186,14 +186,14 @@
     // semantics of the smart file descriptor. A new descriptor will be
     // created, and will be closed when the parcel is destroyed.
     status_t            writeUniqueFileDescriptor(
-                            const ScopedFd& fd);
+                            const base::unique_fd& fd);
 
     // Place a vector of file desciptors into the parcel. Each descriptor is
     // dup'd as in writeDupFileDescriptor
     status_t            writeUniqueFileDescriptorVector(
-                            const std::unique_ptr<std::vector<ScopedFd>>& val);
+                            const std::unique_ptr<std::vector<base::unique_fd>>& val);
     status_t            writeUniqueFileDescriptorVector(
-                            const std::vector<ScopedFd>& val);
+                            const std::vector<base::unique_fd>& val);
 
     // Writes a blob to the parcel.
     // If the blob is small, then it is stored in-place, otherwise it is
@@ -252,6 +252,7 @@
     const char16_t*     readString16Inplace(size_t* outLen) const;
     sp<IBinder>         readStrongBinder() const;
     status_t            readStrongBinder(sp<IBinder>* val) const;
+    status_t            readNullableStrongBinder(sp<IBinder>* val) const;
     wp<IBinder>         readWeakBinder() const;
 
     template<typename T>
@@ -268,6 +269,9 @@
     template<typename T>
     status_t            readStrongBinder(sp<T>* val) const;
 
+    template<typename T>
+    status_t            readNullableStrongBinder(sp<T>* val) const;
+
     status_t            readStrongBinderVector(std::unique_ptr<std::vector<sp<IBinder>>>* val) const;
     status_t            readStrongBinderVector(std::vector<sp<IBinder>>* val) const;
 
@@ -320,14 +324,14 @@
 
     // Retrieve a smart file descriptor from the parcel.
     status_t            readUniqueFileDescriptor(
-                            ScopedFd* val) const;
+                            base::unique_fd* val) const;
 
 
     // Retrieve a vector of smart file descriptors from the parcel.
     status_t            readUniqueFileDescriptorVector(
-                            std::unique_ptr<std::vector<ScopedFd>>* val) const;
+                            std::unique_ptr<std::vector<base::unique_fd>>* val) const;
     status_t            readUniqueFileDescriptorVector(
-                            std::vector<ScopedFd>* val) const;
+                            std::vector<base::unique_fd>* val) const;
 
     // Reads a blob from the parcel.
     // The caller should call release() on the blob after reading its contents.
@@ -574,6 +578,20 @@
     return ret;
 }
 
+template<typename T>
+status_t Parcel::readNullableStrongBinder(sp<T>* val) const {
+    sp<IBinder> tmp;
+    status_t ret = readNullableStrongBinder(&tmp);
+
+    if (ret == OK) {
+        *val = interface_cast<T>(tmp);
+
+        if (val->get() == nullptr) {
+            return UNKNOWN_ERROR;
+        }
+    }
+}
+
 template<typename T, typename U>
 status_t Parcel::unsafeReadTypedVector(
         std::vector<T>* val,
diff --git a/include/binder/PersistableBundle.h b/include/binder/PersistableBundle.h
index fe5619f..322fef9 100644
--- a/include/binder/PersistableBundle.h
+++ b/include/binder/PersistableBundle.h
@@ -18,6 +18,7 @@
 #define ANDROID_PERSISTABLE_BUNDLE_H
 
 #include <map>
+#include <set>
 #include <vector>
 
 #include <binder/Parcelable.h>
@@ -79,6 +80,19 @@
     bool getStringVector(const String16& key, std::vector<String16>* out) const;
     bool getPersistableBundle(const String16& key, PersistableBundle* out) const;
 
+    /* Getters for all keys for each value type */
+    std::set<String16> getBooleanKeys() const;
+    std::set<String16> getIntKeys() const;
+    std::set<String16> getLongKeys() const;
+    std::set<String16> getDoubleKeys() const;
+    std::set<String16> getStringKeys() const;
+    std::set<String16> getBooleanVectorKeys() const;
+    std::set<String16> getIntVectorKeys() const;
+    std::set<String16> getLongVectorKeys() const;
+    std::set<String16> getDoubleVectorKeys() const;
+    std::set<String16> getStringVectorKeys() const;
+    std::set<String16> getPersistableBundleKeys() const;
+
     friend bool operator==(const PersistableBundle& lhs, const PersistableBundle& rhs) {
         return (lhs.mBoolMap == rhs.mBoolMap && lhs.mIntMap == rhs.mIntMap &&
                 lhs.mLongMap == rhs.mLongMap && lhs.mDoubleMap == rhs.mDoubleMap &&
diff --git a/include/binder/Status.h b/include/binder/Status.h
index ce947fa..dd61616 100644
--- a/include/binder/Status.h
+++ b/include/binder/Status.h
@@ -18,6 +18,7 @@
 #define ANDROID_BINDER_STATUS_H
 
 #include <cstdint>
+#include <sstream>
 
 #include <binder/Parcel.h>
 #include <utils/String8.h>
@@ -71,6 +72,7 @@
 
     // A more readable alias for the default constructor.
     static Status ok();
+
     // Authors should explicitly pick whether their integer is:
     //  - an exception code (EX_* above)
     //  - service specific error code
@@ -83,9 +85,15 @@
     static Status fromExceptionCode(int32_t exceptionCode);
     static Status fromExceptionCode(int32_t exceptionCode,
                                     const String8& message);
+    static Status fromExceptionCode(int32_t exceptionCode,
+                                    const char* message);
+
     static Status fromServiceSpecificError(int32_t serviceSpecificErrorCode);
     static Status fromServiceSpecificError(int32_t serviceSpecificErrorCode,
                                            const String8& message);
+    static Status fromServiceSpecificError(int32_t serviceSpecificErrorCode,
+                                           const char* message);
+
     static Status fromStatusT(status_t status);
 
     Status() = default;
@@ -142,11 +150,7 @@
 };  // class Status
 
 // For gtest output logging
-template<typename T>
-T& operator<< (T& stream, const Status& s) {
-    stream << s.toString8().string();
-    return stream;
-}
+std::stringstream& operator<< (std::stringstream& stream, const Status& s);
 
 }  // namespace binder
 }  // namespace android
diff --git a/include/media/openmax/OMX_Core.h b/include/media/openmax/OMX_Core.h
index 99a7622..eeacf43 100644
--- a/include/media/openmax/OMX_Core.h
+++ b/include/media/openmax/OMX_Core.h
@@ -735,7 +735,7 @@
         pComponentVersion,                                  \
         pSpecVersion,                                       \
         pComponentUUID)                                     \
-    ((OMX_COMPONENTTYPE*)hComponent)->GetComponentVersion(  \
+    ((OMX_COMPONENTTYPE*)(hComponent))->GetComponentVersion(\
         hComponent,                                         \
         pComponentName,                                     \
         pComponentVersion,                                  \
@@ -795,7 +795,7 @@
          Cmd,                                               \
          nParam,                                            \
          pCmdData)                                          \
-     ((OMX_COMPONENTTYPE*)hComponent)->SendCommand(         \
+     ((OMX_COMPONENTTYPE*)(hComponent))->SendCommand(       \
          hComponent,                                        \
          Cmd,                                               \
          nParam,                                            \
@@ -834,8 +834,8 @@
 #define OMX_GetParameter(                                   \
         hComponent,                                         \
         nParamIndex,                                        \
-        pComponentParameterStructure)                        \
-    ((OMX_COMPONENTTYPE*)hComponent)->GetParameter(         \
+        pComponentParameterStructure)                       \
+    ((OMX_COMPONENTTYPE*)(hComponent))->GetParameter(       \
         hComponent,                                         \
         nParamIndex,                                        \
         pComponentParameterStructure)    /* Macro End */
@@ -873,8 +873,8 @@
 #define OMX_SetParameter(                                   \
         hComponent,                                         \
         nParamIndex,                                        \
-        pComponentParameterStructure)                        \
-    ((OMX_COMPONENTTYPE*)hComponent)->SetParameter(         \
+        pComponentParameterStructure)                       \
+    ((OMX_COMPONENTTYPE*)(hComponent))->SetParameter(       \
         hComponent,                                         \
         nParamIndex,                                        \
         pComponentParameterStructure)    /* Macro End */
@@ -909,8 +909,8 @@
 #define OMX_GetConfig(                                      \
         hComponent,                                         \
         nConfigIndex,                                       \
-        pComponentConfigStructure)                           \
-    ((OMX_COMPONENTTYPE*)hComponent)->GetConfig(            \
+        pComponentConfigStructure)                          \
+    ((OMX_COMPONENTTYPE*)(hComponent))->GetConfig(          \
         hComponent,                                         \
         nConfigIndex,                                       \
         pComponentConfigStructure)       /* Macro End */
@@ -945,8 +945,8 @@
 #define OMX_SetConfig(                                      \
         hComponent,                                         \
         nConfigIndex,                                       \
-        pComponentConfigStructure)                           \
-    ((OMX_COMPONENTTYPE*)hComponent)->SetConfig(            \
+        pComponentConfigStructure)                          \
+    ((OMX_COMPONENTTYPE*)(hComponent))->SetConfig(          \
         hComponent,                                         \
         nConfigIndex,                                       \
         pComponentConfigStructure)       /* Macro End */
@@ -980,7 +980,7 @@
         hComponent,                                         \
         cParameterName,                                     \
         pIndexType)                                         \
-    ((OMX_COMPONENTTYPE*)hComponent)->GetExtensionIndex(    \
+    ((OMX_COMPONENTTYPE*)(hComponent))->GetExtensionIndex(  \
         hComponent,                                         \
         cParameterName,                                     \
         pIndexType)                     /* Macro End */
@@ -1006,7 +1006,7 @@
 #define OMX_GetState(                                       \
         hComponent,                                         \
         pState)                                             \
-    ((OMX_COMPONENTTYPE*)hComponent)->GetState(             \
+    ((OMX_COMPONENTTYPE*)(hComponent))->GetState(           \
         hComponent,                                         \
         pState)                         /* Macro End */
 
@@ -1037,7 +1037,7 @@
            pAppPrivate,                                     \
            nSizeBytes,                                      \
            pBuffer)                                         \
-    ((OMX_COMPONENTTYPE*)hComponent)->UseBuffer(            \
+    ((OMX_COMPONENTTYPE*)(hComponent))->UseBuffer(          \
            hComponent,                                      \
            ppBufferHdr,                                     \
            nPortIndex,                                      \
@@ -1079,7 +1079,7 @@
         nPortIndex,                                         \
         pAppPrivate,                                        \
         nSizeBytes)                                         \
-    ((OMX_COMPONENTTYPE*)hComponent)->AllocateBuffer(       \
+    ((OMX_COMPONENTTYPE*)(hComponent))->AllocateBuffer(     \
         hComponent,                                         \
         ppBuffer,                                           \
         nPortIndex,                                         \
@@ -1113,7 +1113,7 @@
         hComponent,                                         \
         nPortIndex,                                         \
         pBuffer)                                            \
-    ((OMX_COMPONENTTYPE*)hComponent)->FreeBuffer(           \
+    ((OMX_COMPONENTTYPE*)(hComponent))->FreeBuffer(         \
         hComponent,                                         \
         nPortIndex,                                         \
         pBuffer)                        /* Macro End */
@@ -1144,7 +1144,7 @@
 #define OMX_EmptyThisBuffer(                                \
         hComponent,                                         \
         pBuffer)                                            \
-    ((OMX_COMPONENTTYPE*)hComponent)->EmptyThisBuffer(      \
+    ((OMX_COMPONENTTYPE*)(hComponent))->EmptyThisBuffer(    \
         hComponent,                                         \
         pBuffer)                        /* Macro End */
 
@@ -1174,7 +1174,7 @@
 #define OMX_FillThisBuffer(                                 \
         hComponent,                                         \
         pBuffer)                                            \
-    ((OMX_COMPONENTTYPE*)hComponent)->FillThisBuffer(       \
+    ((OMX_COMPONENTTYPE*)(hComponent))->FillThisBuffer(     \
         hComponent,                                         \
         pBuffer)                        /* Macro End */
 
@@ -1216,7 +1216,7 @@
            nPortIndex,                                      \
            pAppPrivate,                                     \
            eglImage)                                        \
-    ((OMX_COMPONENTTYPE*)hComponent)->UseEGLImage(          \
+    ((OMX_COMPONENTTYPE*)(hComponent))->UseEGLImage(        \
            hComponent,                                      \
            ppBufferHdr,                                     \
            nPortIndex,                                      \
diff --git a/libs/binder/Android.mk b/libs/binder/Android.mk
index 14be920..74bad7a 100644
--- a/libs/binder/Android.mk
+++ b/libs/binder/Android.mk
@@ -46,7 +46,8 @@
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := libbinder
-LOCAL_SHARED_LIBRARIES := liblog libcutils libutils
+LOCAL_SHARED_LIBRARIES := libbase liblog libcutils libutils
+LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := libbase libutils
 
 LOCAL_CLANG := true
 LOCAL_SANITIZE := integer
@@ -61,7 +62,8 @@
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := libbinder
-LOCAL_STATIC_LIBRARIES += libutils
+LOCAL_STATIC_LIBRARIES := libbase libutils
+LOCAL_EXPORT_STATIC_LIBRARY_HEADERS := libbase libutils
 LOCAL_SRC_FILES := $(sources)
 ifneq ($(TARGET_USES_64_BIT_BINDER),true)
 ifneq ($(TARGET_IS_64_BIT),true)
diff --git a/libs/binder/AppOpsManager.cpp b/libs/binder/AppOpsManager.cpp
index 9a061a0..f3b86ae 100644
--- a/libs/binder/AppOpsManager.cpp
+++ b/libs/binder/AppOpsManager.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <mutex>
 #include <binder/AppOpsManager.h>
 #include <binder/Binder.h>
 #include <binder/IServiceManager.h>
@@ -22,6 +23,19 @@
 
 namespace android {
 
+namespace {
+
+#if defined(__BRILLO__)
+// Because Brillo has no application model, security policy is managed
+// statically (at build time) with SELinux controls.
+// As a consequence, it also never runs the AppOpsManager service.
+const int APP_OPS_MANAGER_UNAVAILABLE_MODE = AppOpsManager::MODE_ALLOWED;
+#else
+const int APP_OPS_MANAGER_UNAVAILABLE_MODE = AppOpsManager::MODE_IGNORED;
+#endif  // defined(__BRILLO__)
+
+}  // namespace
+
 static String16 _appops("appops");
 static pthread_mutex_t gTokenMutex = PTHREAD_MUTEX_INITIALIZER;
 static sp<IBinder> gToken;
@@ -39,10 +53,15 @@
 {
 }
 
+#if defined(__BRILLO__)
+// There is no AppOpsService on Brillo
+sp<IAppOpsService> AppOpsManager::getService() { return NULL; }
+#else
 sp<IAppOpsService> AppOpsManager::getService()
 {
+
+    std::lock_guard<Mutex> scoped_lock(mLock);
     int64_t startTime = 0;
-    mLock.lock();
     sp<IAppOpsService> service = mService;
     while (service == NULL || !IInterface::asBinder(service)->isBinderAlive()) {
         sp<IBinder> binder = defaultServiceManager()->checkService(_appops);
@@ -53,7 +72,8 @@
                 ALOGI("Waiting for app ops service");
             } else if ((uptimeMillis()-startTime) > 10000) {
                 ALOGW("Waiting too long for app ops service, giving up");
-                return NULL;
+                service = NULL;
+                break;
             }
             sleep(1);
         } else {
@@ -61,25 +81,30 @@
             mService = service;
         }
     }
-    mLock.unlock();
     return service;
 }
+#endif  // defined(__BRILLO__)
 
 int32_t AppOpsManager::checkOp(int32_t op, int32_t uid, const String16& callingPackage)
 {
     sp<IAppOpsService> service = getService();
-    return service != NULL ? service->checkOperation(op, uid, callingPackage) : MODE_IGNORED;
+    return service != NULL
+            ? service->checkOperation(op, uid, callingPackage)
+            : APP_OPS_MANAGER_UNAVAILABLE_MODE;
 }
 
 int32_t AppOpsManager::noteOp(int32_t op, int32_t uid, const String16& callingPackage) {
     sp<IAppOpsService> service = getService();
-    return service != NULL ? service->noteOperation(op, uid, callingPackage) : MODE_IGNORED;
+    return service != NULL
+            ? service->noteOperation(op, uid, callingPackage)
+            : APP_OPS_MANAGER_UNAVAILABLE_MODE;
 }
 
 int32_t AppOpsManager::startOp(int32_t op, int32_t uid, const String16& callingPackage) {
     sp<IAppOpsService> service = getService();
-    return service != NULL ? service->startOperation(getToken(service), op, uid, callingPackage)
-            : MODE_IGNORED;
+    return service != NULL
+            ? service->startOperation(getToken(service), op, uid, callingPackage)
+            : APP_OPS_MANAGER_UNAVAILABLE_MODE;
 }
 
 void AppOpsManager::finishOp(int32_t op, int32_t uid, const String16& callingPackage) {
diff --git a/libs/binder/BufferedTextOutput.cpp b/libs/binder/BufferedTextOutput.cpp
index 1339a67..a2443c0 100644
--- a/libs/binder/BufferedTextOutput.cpp
+++ b/libs/binder/BufferedTextOutput.cpp
@@ -34,7 +34,7 @@
 
 struct BufferedTextOutput::BufferState : public RefBase
 {
-    BufferState(int32_t _seq)
+    explicit BufferState(int32_t _seq)
         : seq(_seq)
         , buffer(NULL)
         , bufferPos(0)
diff --git a/libs/binder/IAppOpsCallback.cpp b/libs/binder/IAppOpsCallback.cpp
index 2aaf566..f9ec593 100644
--- a/libs/binder/IAppOpsCallback.cpp
+++ b/libs/binder/IAppOpsCallback.cpp
@@ -31,7 +31,7 @@
 class BpAppOpsCallback : public BpInterface<IAppOpsCallback>
 {
 public:
-    BpAppOpsCallback(const sp<IBinder>& impl)
+    explicit BpAppOpsCallback(const sp<IBinder>& impl)
         : BpInterface<IAppOpsCallback>(impl)
     {
     }
diff --git a/libs/binder/IAppOpsService.cpp b/libs/binder/IAppOpsService.cpp
index 9558376..638ae5c 100644
--- a/libs/binder/IAppOpsService.cpp
+++ b/libs/binder/IAppOpsService.cpp
@@ -31,7 +31,7 @@
 class BpAppOpsService : public BpInterface<IAppOpsService>
 {
 public:
-    BpAppOpsService(const sp<IBinder>& impl)
+    explicit BpAppOpsService(const sp<IBinder>& impl)
         : BpInterface<IAppOpsService>(impl)
     {
     }
diff --git a/libs/binder/IBatteryStats.cpp b/libs/binder/IBatteryStats.cpp
index e32c628..ad1e69f 100644
--- a/libs/binder/IBatteryStats.cpp
+++ b/libs/binder/IBatteryStats.cpp
@@ -29,7 +29,7 @@
 class BpBatteryStats : public BpInterface<IBatteryStats>
 {
 public:
-    BpBatteryStats(const sp<IBinder>& impl)
+    explicit BpBatteryStats(const sp<IBinder>& impl)
         : BpInterface<IBatteryStats>(impl)
     {
     }
diff --git a/libs/binder/IMemory.cpp b/libs/binder/IMemory.cpp
index 5f345cf..55ad6cc 100644
--- a/libs/binder/IMemory.cpp
+++ b/libs/binder/IMemory.cpp
@@ -75,7 +75,7 @@
 class BpMemoryHeap : public BpInterface<IMemoryHeap>
 {
 public:
-    BpMemoryHeap(const sp<IBinder>& impl);
+    explicit BpMemoryHeap(const sp<IBinder>& impl);
     virtual ~BpMemoryHeap();
 
     virtual int getHeapID() const;
@@ -123,7 +123,7 @@
 class BpMemory : public BpInterface<IMemory>
 {
 public:
-    BpMemory(const sp<IBinder>& impl);
+    explicit BpMemory(const sp<IBinder>& impl);
     virtual ~BpMemory();
     virtual sp<IMemoryHeap> getMemory(ssize_t* offset=0, size_t* size=0) const;
 
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index d90798f..9b5f0d7 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -330,6 +330,7 @@
             delete st;
             pthread_setspecific(gTLS, NULL);
         }
+        pthread_key_delete(gTLS);
         gHaveTLS = false;
     }
 }
diff --git a/libs/binder/IPermissionController.cpp b/libs/binder/IPermissionController.cpp
index 6bba996..674bddf 100644
--- a/libs/binder/IPermissionController.cpp
+++ b/libs/binder/IPermissionController.cpp
@@ -31,7 +31,7 @@
 class BpPermissionController : public BpInterface<IPermissionController>
 {
 public:
-    BpPermissionController(const sp<IBinder>& impl)
+    explicit BpPermissionController(const sp<IBinder>& impl)
         : BpInterface<IPermissionController>(impl)
     {
     }
diff --git a/libs/binder/IProcessInfoService.cpp b/libs/binder/IProcessInfoService.cpp
index 76508b8..96e1a8c 100644
--- a/libs/binder/IProcessInfoService.cpp
+++ b/libs/binder/IProcessInfoService.cpp
@@ -25,7 +25,7 @@
 
 class BpProcessInfoService : public BpInterface<IProcessInfoService> {
 public:
-    BpProcessInfoService(const sp<IBinder>& impl)
+    explicit BpProcessInfoService(const sp<IBinder>& impl)
         : BpInterface<IProcessInfoService>(impl) {}
 
     virtual status_t getProcessStatesFromPids(size_t length, /*in*/ int32_t* pids,
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 61f24d6..2062b3b 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -67,11 +67,6 @@
 
 bool checkPermission(const String16& permission, pid_t pid, uid_t uid)
 {
-#ifdef __BRILLO__
-    // Brillo doesn't currently run ActivityManager or support framework permissions.
-    return true;
-#endif
-
     sp<IPermissionController> pc;
     gDefaultServiceManagerLock.lock();
     pc = gPermissionController;
@@ -131,7 +126,7 @@
 class BpServiceManager : public BpInterface<IServiceManager>
 {
 public:
-    BpServiceManager(const sp<IBinder>& impl)
+    explicit BpServiceManager(const sp<IBinder>& impl)
         : BpInterface<IServiceManager>(impl)
     {
     }
diff --git a/libs/binder/MemoryDealer.cpp b/libs/binder/MemoryDealer.cpp
index 51eac11..2a15773 100644
--- a/libs/binder/MemoryDealer.cpp
+++ b/libs/binder/MemoryDealer.cpp
@@ -126,7 +126,7 @@
         PAGE_ALIGNED = 0x00000001
     };
 public:
-    SimpleBestFitAllocator(size_t size);
+    explicit SimpleBestFitAllocator(size_t size);
     ~SimpleBestFitAllocator();
 
     size_t      allocate(size_t size, uint32_t flags = 0);
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index e88ae29..5a2492e 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -1112,7 +1112,7 @@
 }
 
 status_t Parcel::readStrongBinderVector(std::unique_ptr<std::vector<sp<IBinder>>>* val) const {
-    return readNullableTypedVector(val, &Parcel::readStrongBinder);
+    return readNullableTypedVector(val, &Parcel::readNullableStrongBinder);
 }
 
 status_t Parcel::readStrongBinderVector(std::vector<sp<IBinder>>* val) const {
@@ -1187,15 +1187,15 @@
     return err;
 }
 
-status_t Parcel::writeUniqueFileDescriptor(const ScopedFd& fd) {
+status_t Parcel::writeUniqueFileDescriptor(const base::unique_fd& fd) {
     return writeDupFileDescriptor(fd.get());
 }
 
-status_t Parcel::writeUniqueFileDescriptorVector(const std::vector<ScopedFd>& val) {
+status_t Parcel::writeUniqueFileDescriptorVector(const std::vector<base::unique_fd>& val) {
     return writeTypedVector(val, &Parcel::writeUniqueFileDescriptor);
 }
 
-status_t Parcel::writeUniqueFileDescriptorVector(const std::unique_ptr<std::vector<ScopedFd>>& val) {
+status_t Parcel::writeUniqueFileDescriptorVector(const std::unique_ptr<std::vector<base::unique_fd>>& val) {
     return writeNullableTypedVector(val, &Parcel::writeUniqueFileDescriptor);
 }
 
@@ -1913,13 +1913,25 @@
 
 status_t Parcel::readStrongBinder(sp<IBinder>* val) const
 {
+    status_t status = readNullableStrongBinder(val);
+    if (status == OK && !val->get()) {
+        status = UNEXPECTED_NULL;
+    }
+    return status;
+}
+
+status_t Parcel::readNullableStrongBinder(sp<IBinder>* val) const
+{
     return unflatten_binder(ProcessState::self(), *this, val);
 }
 
 sp<IBinder> Parcel::readStrongBinder() const
 {
     sp<IBinder> val;
-    readStrongBinder(&val);
+    // Note that a lot of code in Android reads binders by hand with this
+    // method, and that code has historically been ok with getting nullptr
+    // back (while ignoring error codes).
+    readNullableStrongBinder(&val);
     return val;
 }
 
@@ -1994,7 +2006,7 @@
     return BAD_TYPE;
 }
 
-status_t Parcel::readUniqueFileDescriptor(ScopedFd* val) const
+status_t Parcel::readUniqueFileDescriptor(base::unique_fd* val) const
 {
     int got = readFileDescriptor();
 
@@ -2012,11 +2024,11 @@
 }
 
 
-status_t Parcel::readUniqueFileDescriptorVector(std::unique_ptr<std::vector<ScopedFd>>* val) const {
+status_t Parcel::readUniqueFileDescriptorVector(std::unique_ptr<std::vector<base::unique_fd>>* val) const {
     return readNullableTypedVector(val, &Parcel::readUniqueFileDescriptor);
 }
 
-status_t Parcel::readUniqueFileDescriptorVector(std::vector<ScopedFd>* val) const {
+status_t Parcel::readUniqueFileDescriptorVector(std::vector<base::unique_fd>* val) const {
     return readTypedVector(val, &Parcel::readUniqueFileDescriptor);
 }
 
diff --git a/libs/binder/PersistableBundle.cpp b/libs/binder/PersistableBundle.cpp
index aef791c..5c5651c 100644
--- a/libs/binder/PersistableBundle.cpp
+++ b/libs/binder/PersistableBundle.cpp
@@ -32,6 +32,9 @@
 using android::sp;
 using android::status_t;
 using android::UNEXPECTED_NULL;
+using std::map;
+using std::set;
+using std::vector;
 
 enum {
     // Keep in sync with BUNDLE_MAGIC in frameworks/base/core/java/android/os/BaseBundle.java.
@@ -55,12 +58,22 @@
 
 namespace {
 template <typename T>
-bool getValue(const android::String16& key, T* out, const std::map<android::String16, T>& map) {
+bool getValue(const android::String16& key, T* out, const map<android::String16, T>& map) {
     const auto& it = map.find(key);
     if (it == map.end()) return false;
     *out = it->second;
     return true;
 }
+
+template <typename T>
+set<android::String16> getKeys(const map<android::String16, T>& map) {
+    if (map.empty()) return set<android::String16>();
+    set<android::String16> keys;
+    for (const auto& key_value_pair : map) {
+        keys.emplace(key_value_pair.first);
+    }
+    return keys;
+}
 }  // namespace
 
 namespace android {
@@ -78,7 +91,7 @@
 
 #define RETURN_IF_ENTRY_ERASED(map, key)                                 \
     {                                                                    \
-        size_t num_erased = map.erase(key);                              \
+        size_t num_erased = (map).erase(key);                            \
         if (num_erased) {                                                \
             ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \
             return num_erased;                                           \
@@ -188,27 +201,27 @@
     mStringMap[key] = value;
 }
 
-void PersistableBundle::putBooleanVector(const String16& key, const std::vector<bool>& value) {
+void PersistableBundle::putBooleanVector(const String16& key, const vector<bool>& value) {
     erase(key);
     mBoolVectorMap[key] = value;
 }
 
-void PersistableBundle::putIntVector(const String16& key, const std::vector<int32_t>& value) {
+void PersistableBundle::putIntVector(const String16& key, const vector<int32_t>& value) {
     erase(key);
     mIntVectorMap[key] = value;
 }
 
-void PersistableBundle::putLongVector(const String16& key, const std::vector<int64_t>& value) {
+void PersistableBundle::putLongVector(const String16& key, const vector<int64_t>& value) {
     erase(key);
     mLongVectorMap[key] = value;
 }
 
-void PersistableBundle::putDoubleVector(const String16& key, const std::vector<double>& value) {
+void PersistableBundle::putDoubleVector(const String16& key, const vector<double>& value) {
     erase(key);
     mDoubleVectorMap[key] = value;
 }
 
-void PersistableBundle::putStringVector(const String16& key, const std::vector<String16>& value) {
+void PersistableBundle::putStringVector(const String16& key, const vector<String16>& value) {
     erase(key);
     mStringVectorMap[key] = value;
 }
@@ -238,23 +251,23 @@
     return getValue(key, out, mStringMap);
 }
 
-bool PersistableBundle::getBooleanVector(const String16& key, std::vector<bool>* out) const {
+bool PersistableBundle::getBooleanVector(const String16& key, vector<bool>* out) const {
     return getValue(key, out, mBoolVectorMap);
 }
 
-bool PersistableBundle::getIntVector(const String16& key, std::vector<int32_t>* out) const {
+bool PersistableBundle::getIntVector(const String16& key, vector<int32_t>* out) const {
     return getValue(key, out, mIntVectorMap);
 }
 
-bool PersistableBundle::getLongVector(const String16& key, std::vector<int64_t>* out) const {
+bool PersistableBundle::getLongVector(const String16& key, vector<int64_t>* out) const {
     return getValue(key, out, mLongVectorMap);
 }
 
-bool PersistableBundle::getDoubleVector(const String16& key, std::vector<double>* out) const {
+bool PersistableBundle::getDoubleVector(const String16& key, vector<double>* out) const {
     return getValue(key, out, mDoubleVectorMap);
 }
 
-bool PersistableBundle::getStringVector(const String16& key, std::vector<String16>* out) const {
+bool PersistableBundle::getStringVector(const String16& key, vector<String16>* out) const {
     return getValue(key, out, mStringVectorMap);
 }
 
@@ -262,6 +275,50 @@
     return getValue(key, out, mPersistableBundleMap);
 }
 
+set<String16> PersistableBundle::getBooleanKeys() const {
+    return getKeys(mBoolMap);
+}
+
+set<String16> PersistableBundle::getIntKeys() const {
+    return getKeys(mIntMap);
+}
+
+set<String16> PersistableBundle::getLongKeys() const {
+    return getKeys(mLongMap);
+}
+
+set<String16> PersistableBundle::getDoubleKeys() const {
+    return getKeys(mDoubleMap);
+}
+
+set<String16> PersistableBundle::getStringKeys() const {
+    return getKeys(mStringMap);
+}
+
+set<String16> PersistableBundle::getBooleanVectorKeys() const {
+    return getKeys(mBoolVectorMap);
+}
+
+set<String16> PersistableBundle::getIntVectorKeys() const {
+    return getKeys(mIntVectorMap);
+}
+
+set<String16> PersistableBundle::getLongVectorKeys() const {
+    return getKeys(mLongVectorMap);
+}
+
+set<String16> PersistableBundle::getDoubleVectorKeys() const {
+    return getKeys(mDoubleVectorMap);
+}
+
+set<String16> PersistableBundle::getStringVectorKeys() const {
+    return getKeys(mStringVectorMap);
+}
+
+set<String16> PersistableBundle::getPersistableBundleKeys() const {
+    return getKeys(mPersistableBundleMap);
+}
+
 status_t PersistableBundle::writeToParcelInner(Parcel* parcel) const {
     /*
      * To keep this implementation in sync with writeArrayMapInternal() in
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index f13f49f..319d1d9 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -52,7 +52,7 @@
 class PoolThread : public Thread
 {
 public:
-    PoolThread(bool isMain)
+    explicit PoolThread(bool isMain)
         : mIsMain(isMain)
     {
     }
@@ -366,6 +366,13 @@
 
 ProcessState::~ProcessState()
 {
+    if (mDriverFD >= 0) {
+        if (mVMStart != MAP_FAILED) {
+            munmap(mVMStart, BINDER_VM_SIZE);
+        }
+        close(mDriverFD);
+    }
+    mDriverFD = -1;
 }
         
 }; // namespace android
diff --git a/libs/binder/Static.cpp b/libs/binder/Static.cpp
index cd9509f..f0613d1 100644
--- a/libs/binder/Static.cpp
+++ b/libs/binder/Static.cpp
@@ -48,7 +48,7 @@
 class FdTextOutput : public BufferedTextOutput
 {
 public:
-    FdTextOutput(int fd) : BufferedTextOutput(MULTITHREADED), mFD(fd) { }
+    explicit FdTextOutput(int fd) : BufferedTextOutput(MULTITHREADED), mFD(fd) { }
     virtual ~FdTextOutput() { };
 
 protected:
diff --git a/libs/binder/Status.cpp b/libs/binder/Status.cpp
index d3520d6..8466863 100644
--- a/libs/binder/Status.cpp
+++ b/libs/binder/Status.cpp
@@ -32,6 +32,11 @@
     return Status(exceptionCode, OK, message);
 }
 
+Status Status::fromExceptionCode(int32_t exceptionCode,
+                                 const char* message) {
+    return fromExceptionCode(exceptionCode, String8(message));
+}
+
 Status Status::fromServiceSpecificError(int32_t serviceSpecificErrorCode) {
     return Status(EX_SERVICE_SPECIFIC, serviceSpecificErrorCode);
 }
@@ -41,6 +46,11 @@
     return Status(EX_SERVICE_SPECIFIC, serviceSpecificErrorCode, message);
 }
 
+Status Status::fromServiceSpecificError(int32_t serviceSpecificErrorCode,
+                                        const char* message) {
+    return fromServiceSpecificError(serviceSpecificErrorCode, String8(message));
+}
+
 Status Status::fromStatusT(status_t status) {
     Status ret;
     ret.setFromStatusT(status);
@@ -158,5 +168,10 @@
     return ret;
 }
 
+std::stringstream& operator<< (std::stringstream& stream, const Status& s) {
+    stream << s.toString8().string();
+    return stream;
+}
+
 }  // namespace binder
 }  // namespace android
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 3df3acf..17479ca 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -252,14 +252,10 @@
             int ret;
             pthread_mutex_lock(&m_waitMutex);
             if (!m_eventTriggered) {
-#if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE)
-                pthread_cond_timeout_np(&m_waitCond, &m_waitMutex, timeout_s * 1000);
-#else
                 struct timespec ts;
                 clock_gettime(CLOCK_REALTIME, &ts);
                 ts.tv_sec += timeout_s;
                 pthread_cond_timedwait(&m_waitCond, &m_waitMutex, &ts);
-#endif
             }
             ret = m_eventTriggered ? NO_ERROR : TIMED_OUT;
             pthread_mutex_unlock(&m_waitMutex);
@@ -739,14 +735,10 @@
                 }
                 if (ret > 0) {
                     if (m_serverStartRequested) {
-#if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE)
-                        ret = pthread_cond_timeout_np(&m_serverWaitCond, &m_serverWaitMutex, 5000);
-#else
                         struct timespec ts;
                         clock_gettime(CLOCK_REALTIME, &ts);
                         ts.tv_sec += 5;
                         ret = pthread_cond_timedwait(&m_serverWaitCond, &m_serverWaitMutex, &ts);
-#endif
                     }
                     if (m_serverStartRequested) {
                         m_serverStartRequested = false;
diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk
index 635020e..799b2b5 100644
--- a/libs/gui/Android.mk
+++ b/libs/gui/Android.mk
@@ -83,6 +83,7 @@
 	libutils \
 	liblog
 
+LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := libbinder
 
 LOCAL_MODULE := libgui
 
@@ -93,6 +94,10 @@
 	LOCAL_CFLAGS += -DDONT_USE_FENCE_SYNC
 endif
 
+ifeq ($(TARGET_BOARD_HAS_NO_SURFACE_FLINGER), true)
+	LOCAL_CFLAGS += -DHAVE_NO_SURFACE_FLINGER
+endif
+
 include $(BUILD_SHARED_LIBRARY)
 
 ifeq (,$(ONE_SHOT_MAKEFILE))
diff --git a/libs/gui/BufferQueueCore.cpp b/libs/gui/BufferQueueCore.cpp
index 569b8f9..b574f9d 100644
--- a/libs/gui/BufferQueueCore.cpp
+++ b/libs/gui/BufferQueueCore.cpp
@@ -28,8 +28,11 @@
 
 #include <inttypes.h>
 
+#include <cutils/properties.h>
+
 #include <gui/BufferItem.h>
 #include <gui/BufferQueueCore.h>
+#include <gui/GraphicBufferAlloc.h>
 #include <gui/IConsumerListener.h>
 #include <gui/IGraphicBufferAlloc.h>
 #include <gui/IProducerListener.h>
@@ -92,8 +95,24 @@
     mUniqueId(getUniqueId())
 {
     if (allocator == NULL) {
-        sp<ISurfaceComposer> composer(ComposerService::getComposerService());
-        mAllocator = composer->createGraphicBufferAlloc();
+
+#ifdef HAVE_NO_SURFACE_FLINGER
+        // Without a SurfaceFlinger, allocate in-process.  This only makes
+        // sense in systems with static SELinux configurations and no
+        // applications (since applications need dynamic SELinux policy).
+        mAllocator = new GraphicBufferAlloc();
+#else
+        // Run time check for headless, where we also allocate in-process.
+        char value[PROPERTY_VALUE_MAX];
+        property_get("config.headless", value, "0");
+        if (atoi(value) == 1) {
+            mAllocator = new GraphicBufferAlloc();
+        } else {
+            sp<ISurfaceComposer> composer(ComposerService::getComposerService());
+            mAllocator = composer->createGraphicBufferAlloc();
+        }
+#endif  // HAVE_NO_SURFACE_FLINGER
+
         if (mAllocator == NULL) {
             BQ_LOGE("createGraphicBufferAlloc failed");
         }
diff --git a/libs/gui/IConsumerListener.cpp b/libs/gui/IConsumerListener.cpp
index cab7dc3..9a0b7a4 100644
--- a/libs/gui/IConsumerListener.cpp
+++ b/libs/gui/IConsumerListener.cpp
@@ -36,7 +36,7 @@
 class BpConsumerListener : public BpInterface<IConsumerListener>
 {
 public:
-    BpConsumerListener(const sp<IBinder>& impl)
+    explicit BpConsumerListener(const sp<IBinder>& impl)
         : BpInterface<IConsumerListener>(impl) {
     }
 
diff --git a/libs/gui/IDisplayEventConnection.cpp b/libs/gui/IDisplayEventConnection.cpp
index 9890f44..b1d3b00 100644
--- a/libs/gui/IDisplayEventConnection.cpp
+++ b/libs/gui/IDisplayEventConnection.cpp
@@ -39,7 +39,7 @@
 class BpDisplayEventConnection : public BpInterface<IDisplayEventConnection>
 {
 public:
-    BpDisplayEventConnection(const sp<IBinder>& impl)
+    explicit BpDisplayEventConnection(const sp<IBinder>& impl)
         : BpInterface<IDisplayEventConnection>(impl)
     {
     }
diff --git a/libs/gui/IGraphicBufferAlloc.cpp b/libs/gui/IGraphicBufferAlloc.cpp
index 3009989..d4d4702 100644
--- a/libs/gui/IGraphicBufferAlloc.cpp
+++ b/libs/gui/IGraphicBufferAlloc.cpp
@@ -37,7 +37,7 @@
 class BpGraphicBufferAlloc : public BpInterface<IGraphicBufferAlloc>
 {
 public:
-    BpGraphicBufferAlloc(const sp<IBinder>& impl)
+    explicit BpGraphicBufferAlloc(const sp<IBinder>& impl)
         : BpInterface<IGraphicBufferAlloc>(impl)
     {
     }
@@ -90,7 +90,7 @@
     class BufferReference : public BBinder {
         sp<GraphicBuffer> mBuffer;
     public:
-        BufferReference(const sp<GraphicBuffer>& buffer) : mBuffer(buffer) {}
+        explicit BufferReference(const sp<GraphicBuffer>& buffer) : mBuffer(buffer) {}
     };
 
 
diff --git a/libs/gui/IGraphicBufferConsumer.cpp b/libs/gui/IGraphicBufferConsumer.cpp
index cb1ad35..d926b20 100644
--- a/libs/gui/IGraphicBufferConsumer.cpp
+++ b/libs/gui/IGraphicBufferConsumer.cpp
@@ -58,7 +58,7 @@
 class BpGraphicBufferConsumer : public BpInterface<IGraphicBufferConsumer>
 {
 public:
-    BpGraphicBufferConsumer(const sp<IBinder>& impl)
+    explicit BpGraphicBufferConsumer(const sp<IBinder>& impl)
         : BpInterface<IGraphicBufferConsumer>(impl)
     {
     }
diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp
index 7d7d09d..531bb53 100644
--- a/libs/gui/IGraphicBufferProducer.cpp
+++ b/libs/gui/IGraphicBufferProducer.cpp
@@ -61,7 +61,7 @@
 class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer>
 {
 public:
-    BpGraphicBufferProducer(const sp<IBinder>& impl)
+    explicit BpGraphicBufferProducer(const sp<IBinder>& impl)
         : BpInterface<IGraphicBufferProducer>(impl)
     {
     }
diff --git a/libs/gui/IProducerListener.cpp b/libs/gui/IProducerListener.cpp
index 81adc95..9d18ea2 100644
--- a/libs/gui/IProducerListener.cpp
+++ b/libs/gui/IProducerListener.cpp
@@ -27,7 +27,7 @@
 class BpProducerListener : public BpInterface<IProducerListener>
 {
 public:
-    BpProducerListener(const sp<IBinder>& impl)
+    explicit BpProducerListener(const sp<IBinder>& impl)
         : BpInterface<IProducerListener>(impl) {}
 
     virtual ~BpProducerListener();
diff --git a/libs/gui/ISensorEventConnection.cpp b/libs/gui/ISensorEventConnection.cpp
index dc7a35c..59ecee7 100644
--- a/libs/gui/ISensorEventConnection.cpp
+++ b/libs/gui/ISensorEventConnection.cpp
@@ -40,7 +40,7 @@
 class BpSensorEventConnection : public BpInterface<ISensorEventConnection>
 {
 public:
-    BpSensorEventConnection(const sp<IBinder>& impl)
+    explicit BpSensorEventConnection(const sp<IBinder>& impl)
         : BpInterface<ISensorEventConnection>(impl)
     {
     }
diff --git a/libs/gui/ISensorServer.cpp b/libs/gui/ISensorServer.cpp
index 3a4c7e4..07c507a 100644
--- a/libs/gui/ISensorServer.cpp
+++ b/libs/gui/ISensorServer.cpp
@@ -42,7 +42,7 @@
 class BpSensorServer : public BpInterface<ISensorServer>
 {
 public:
-    BpSensorServer(const sp<IBinder>& impl)
+    explicit BpSensorServer(const sp<IBinder>& impl)
         : BpInterface<ISensorServer>(impl)
     {
     }
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index a8b4fa8..015945a 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -47,7 +47,7 @@
 class BpSurfaceComposer : public BpInterface<ISurfaceComposer>
 {
 public:
-    BpSurfaceComposer(const sp<IBinder>& impl)
+    explicit BpSurfaceComposer(const sp<IBinder>& impl)
         : BpInterface<ISurfaceComposer>(impl)
     {
     }
diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp
index 2ecb908..decffbf 100644
--- a/libs/gui/ISurfaceComposerClient.cpp
+++ b/libs/gui/ISurfaceComposerClient.cpp
@@ -47,7 +47,7 @@
 class BpSurfaceComposerClient : public BpInterface<ISurfaceComposerClient>
 {
 public:
-    BpSurfaceComposerClient(const sp<IBinder>& impl)
+    explicit BpSurfaceComposerClient(const sp<IBinder>& impl)
         : BpInterface<ISurfaceComposerClient>(impl) {
     }
 
diff --git a/libs/gui/SensorManager.cpp b/libs/gui/SensorManager.cpp
index 225bfa8..5338034 100644
--- a/libs/gui/SensorManager.cpp
+++ b/libs/gui/SensorManager.cpp
@@ -139,7 +139,7 @@
                 mSensorManager.sensorManagerDied();
             }
         public:
-            DeathObserver(SensorManager& mgr) : mSensorManager(mgr) { }
+            explicit DeathObserver(SensorManager& mgr) : mSensorManager(mgr) { }
         };
 
         LOG_ALWAYS_FATAL_IF(mSensorServer.get() == NULL, "getService(SensorService) NULL");
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 92ae41e..2189047 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -67,7 +67,7 @@
             mComposerService.composerServiceDied();
         }
      public:
-        DeathObserver(ComposerService& mgr) : mComposerService(mgr) { }
+        explicit DeathObserver(ComposerService& mgr) : mComposerService(mgr) { }
     };
 
     mDeathObserver = new DeathObserver(*const_cast<ComposerService*>(this));
diff --git a/libs/gui/tests/Android.mk b/libs/gui/tests/Android.mk
index 6ad9986..7d984a4 100644
--- a/libs/gui/tests/Android.mk
+++ b/libs/gui/tests/Android.mk
@@ -28,6 +28,7 @@
     TextureRenderer.cpp \
 
 LOCAL_SHARED_LIBRARIES := \
+	liblog \
 	libEGL \
 	libGLESv1_CM \
 	libGLESv2 \
diff --git a/libs/gui/tests/CpuConsumer_test.cpp b/libs/gui/tests/CpuConsumer_test.cpp
index 289cc74..9c2e838 100644
--- a/libs/gui/tests/CpuConsumer_test.cpp
+++ b/libs/gui/tests/CpuConsumer_test.cpp
@@ -160,7 +160,7 @@
 };
 
 #define ASSERT_NO_ERROR(err, msg) \
-    ASSERT_EQ(NO_ERROR, err) << msg << strerror(-err)
+    ASSERT_EQ(NO_ERROR, err) << (msg) << strerror(-(err))
 
 void checkPixel(const CpuConsumer::LockedBuffer &buf,
         uint32_t x, uint32_t y, uint32_t r, uint32_t g=0, uint32_t b=0) {
diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp
index a1578f6..b10d4eb 100644
--- a/libs/gui/tests/SurfaceTextureClient_test.cpp
+++ b/libs/gui/tests/SurfaceTextureClient_test.cpp
@@ -535,7 +535,7 @@
             return false;
         }
     public:
-        MyThread(const sp<GLConsumer>& mST)
+        explicit MyThread(const sp<GLConsumer>& mST)
             : mST(mST), mBufferRetired(false) {
             ctx = eglGetCurrentContext();
             sur = eglGetCurrentSurface(EGL_DRAW);
diff --git a/libs/gui/tests/SurfaceTextureGL_test.cpp b/libs/gui/tests/SurfaceTextureGL_test.cpp
index dddcf92..81d5a57 100644
--- a/libs/gui/tests/SurfaceTextureGL_test.cpp
+++ b/libs/gui/tests/SurfaceTextureGL_test.cpp
@@ -437,7 +437,7 @@
 
     class ProducerThread : public Thread {
     public:
-        ProducerThread(const sp<ANativeWindow>& anw):
+        explicit ProducerThread(const sp<ANativeWindow>& anw):
                 mANW(anw) {
         }
 
@@ -620,7 +620,7 @@
 TEST_F(SurfaceTextureGLTest, AbandonUnblocksDequeueBuffer) {
     class ProducerThread : public Thread {
     public:
-        ProducerThread(const sp<ANativeWindow>& anw):
+        explicit ProducerThread(const sp<ANativeWindow>& anw):
                 mANW(anw),
                 mDequeueError(NO_ERROR) {
         }
diff --git a/libs/input/IInputFlinger.cpp b/libs/input/IInputFlinger.cpp
index e009731..003e73d 100644
--- a/libs/input/IInputFlinger.cpp
+++ b/libs/input/IInputFlinger.cpp
@@ -28,7 +28,7 @@
 
 class BpInputFlinger : public BpInterface<IInputFlinger> {
 public:
-    BpInputFlinger(const sp<IBinder>& impl) :
+    explicit BpInputFlinger(const sp<IBinder>& impl) :
             BpInterface<IInputFlinger>(impl) { }
 
     virtual status_t doSomething() {
diff --git a/libs/input/tests/StructLayout_test.cpp b/libs/input/tests/StructLayout_test.cpp
index 8d73f45..81b9953 100644
--- a/libs/input/tests/StructLayout_test.cpp
+++ b/libs/input/tests/StructLayout_test.cpp
@@ -20,7 +20,7 @@
 namespace android {
 
 #define CHECK_OFFSET(type, member, expected_offset) \
-  static_assert((offsetof(type, member) == expected_offset), "")
+  static_assert((offsetof(type, member) == (expected_offset)), "")
 
 struct Foo {
   uint32_t dummy;
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index ee152bf..fb2b857 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -424,7 +424,7 @@
     Vector<Rect> span;
     Rect* cur;
 public:
-    rasterizer(Region& reg)
+    explicit rasterizer(Region& reg)
         : bounds(INT_MAX, 0, INT_MIN, 0), storage(reg.mStorage), head(), tail(), cur() {
         storage.clear();
     }
@@ -489,7 +489,8 @@
                     merge = false;
                     break;
                 }
-                p++, q++;
+                p++;
+                q++;
             }
         }
     }
diff --git a/opengl/include/EGL/eglext.h b/opengl/include/EGL/eglext.h
index bef5f02..83b8d86 100644
--- a/opengl/include/EGL/eglext.h
+++ b/opengl/include/EGL/eglext.h
@@ -545,7 +545,7 @@
 #define EGL_SYNC_NATIVE_FENCE_ANDROID		0x3144
 #define EGL_SYNC_NATIVE_FENCE_FD_ANDROID	0x3145
 #define EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID	0x3146
-#define EGL_NO_NATIVE_FENCE_FD_ANDROID		-1
+#define EGL_NO_NATIVE_FENCE_FD_ANDROID		(-1)
 #ifdef EGL_EGLEXT_PROTOTYPES
 EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID( EGLDisplay dpy, EGLSyncKHR);
 #endif /* EGL_EGLEXT_PROTOTYPES */
diff --git a/opengl/libagl/arch-mips/fixed_asm.S b/opengl/libagl/arch-mips/fixed_asm.S
index e1a53bc..a30ffc5 100644
--- a/opengl/libagl/arch-mips/fixed_asm.S
+++ b/opengl/libagl/arch-mips/fixed_asm.S
@@ -17,7 +17,7 @@
 
 
     .text
-    .align
+    .align 4
 
 /*
  * this version rounds-to-nearest and saturates numbers
diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk
index eb86860..5074fd0 100644
--- a/opengl/libs/Android.mk
+++ b/opengl/libs/Android.mk
@@ -77,7 +77,6 @@
 	GLES_CM/gl.cpp.arm 	\
 #
 
-LOCAL_CLANG := false
 LOCAL_SHARED_LIBRARIES += libcutils liblog libEGL
 LOCAL_MODULE:= libGLESv1_CM
 
@@ -105,7 +104,6 @@
 	GLES2/gl2.cpp   \
 #
 
-LOCAL_CLANG := false
 LOCAL_ARM_MODE := arm
 LOCAL_SHARED_LIBRARIES += libcutils libutils liblog libEGL
 LOCAL_MODULE:= libGLESv2
@@ -133,7 +131,6 @@
 	GLES2/gl2.cpp   \
 #
 
-LOCAL_CLANG := false
 LOCAL_ARM_MODE := arm
 LOCAL_SHARED_LIBRARIES += libcutils libutils liblog libEGL
 LOCAL_MODULE:= libGLESv3
diff --git a/opengl/libs/GLES2/gl2.cpp b/opengl/libs/GLES2/gl2.cpp
index 6034a8e..6dd87c2 100644
--- a/opengl/libs/GLES2/gl2.cpp
+++ b/opengl/libs/GLES2/gl2.cpp
@@ -34,39 +34,65 @@
 
 #undef API_ENTRY
 #undef CALL_GL_API
+#undef CALL_GL_API_INTERNAL_CALL
+#undef CALL_GL_API_INTERNAL_SET_RETURN_VALUE
+#undef CALL_GL_API_INTERNAL_DO_RETURN
 #undef CALL_GL_API_RETURN
 
 #if USE_SLOW_BINDING
 
     #define API_ENTRY(_api) _api
 
-    #define CALL_GL_API(_api, ...)                                       \
+    #define CALL_GL_API_INTERNAL_CALL(_api, ...)                         \
         gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;  \
         if (_c) return _c->_api(__VA_ARGS__);
 
+    #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE return 0;
+
+    // This stays blank, since void functions will implicitly return, and
+    // all of the other functions will return 0 based on the previous macro.
+    #define CALL_GL_API_INTERNAL_DO_RETURN
+
 #elif defined(__arm__)
 
     #define GET_TLS(reg) "mrc p15, 0, " #reg ", c13, c0, 3 \n"
 
-    #define API_ENTRY(_api) __attribute__((noinline)) _api
+    #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
 
-    #define CALL_GL_API(_api, ...)                              \
-         asm volatile(                                          \
-            GET_TLS(r12)                                        \
-            "ldr   r12, [r12, %[tls]] \n"                       \
-            "cmp   r12, #0            \n"                       \
-            "ldrne pc,  [r12, %[api]] \n"                       \
-            :                                                   \
-            : [tls] "J"(TLS_SLOT_OPENGL_API*4),                 \
-              [api] "J"(__builtin_offsetof(gl_hooks_t, gl._api))    \
-            : "r12"                                             \
-            );
+    #define CALL_GL_API_INTERNAL_CALL(_api, ...)                 \
+        asm volatile(                                            \
+            GET_TLS(r12)                                         \
+            "ldr   r12, [r12, %[tls]] \n"                        \
+            "cmp   r12, #0            \n"                        \
+            "ldrne pc,  [r12, %[api]] \n"                        \
+            :                                                    \
+            : [tls] "J"(TLS_SLOT_OPENGL_API*4),                  \
+              [api] "J"(__builtin_offsetof(gl_hooks_t, gl._api)) \
+            : "r0", "r1", "r2", "r3", "r12"                      \
+        );
+
+    #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \
+        asm volatile(                             \
+            "mov r0, #0 \n"                       \
+            :                                     \
+            :                                     \
+            : "r0"                                \
+        );
+
+
+    #define CALL_GL_API_INTERNAL_DO_RETURN \
+        asm volatile(                      \
+            "bx lr \n"                     \
+            :                              \
+            :                              \
+            : "r0"                         \
+        );
 
 #elif defined(__aarch64__)
 
-    #define API_ENTRY(_api) __attribute__((noinline)) _api
+    #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
 
-    #define CALL_GL_API(_api, ...)                                  \
+    #define CALL_GL_API_INTERNAL_CALL(_api, ...)                    \
         asm volatile(                                               \
             "mrs x16, tpidr_el0\n"                                  \
             "ldr x16, [x16, %[tls]]\n"                              \
@@ -77,121 +103,173 @@
             :                                                       \
             : [tls] "i" (TLS_SLOT_OPENGL_API * sizeof(void*)),      \
               [api] "i" (__builtin_offsetof(gl_hooks_t, gl._api))   \
-            : "x16"                                                 \
+            : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x16" \
+        );
+
+    #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \
+        asm volatile(                             \
+            "mov w0, wzr \n"                      \
+            :                                     \
+            :                                     \
+            : "w0"                                \
+        );
+
+    #define CALL_GL_API_INTERNAL_DO_RETURN \
+        asm volatile(                      \
+            "ret \n"                       \
+            :                              \
+            :                              \
+            :                              \
         );
 
 #elif defined(__i386__)
 
-    #define API_ENTRY(_api) __attribute__((noinline,optimize("omit-frame-pointer"))) _api
+    #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
 
-    #define CALL_GL_API(_api, ...)                                  \
-        register void** fn;                                         \
+    #define CALL_GL_API_INTERNAL_CALL(_api, ...)                    \
         __asm__ volatile(                                           \
-            "mov %%gs:0, %[fn]\n"                                   \
-            "mov %P[tls](%[fn]), %[fn]\n"                           \
-            "test %[fn], %[fn]\n"                                   \
+            "mov %%gs:0, %%eax\n"                                   \
+            "mov %P[tls](%%eax), %%eax\n"                           \
+            "test %%eax, %%eax\n"                                   \
             "je 1f\n"                                               \
-            "jmp *%P[api](%[fn])\n"                                 \
+            "jmp *%P[api](%%eax)\n"                                 \
             "1:\n"                                                  \
-            : [fn] "=r" (fn)                                        \
+            :                                                       \
             : [tls] "i" (TLS_SLOT_OPENGL_API*sizeof(void*)),        \
               [api] "i" (__builtin_offsetof(gl_hooks_t, gl._api))   \
-            : "cc"                                                  \
+            : "cc", "%eax"                                          \
             );
 
+    #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \
+        __asm__ volatile(                         \
+            "xor %%eax, %%eax\n"                  \
+            :                                     \
+            :                                     \
+            : "%eax"                              \
+        );
+
+    #define CALL_GL_API_INTERNAL_DO_RETURN \
+        __asm__ volatile(                  \
+            "ret\n"                        \
+            :                              \
+            :                              \
+            :                              \
+        );
+
 #elif defined(__x86_64__)
 
-    #define API_ENTRY(_api) __attribute__((noinline,optimize("omit-frame-pointer"))) _api
+    #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
 
-    #define CALL_GL_API(_api, ...)                                  \
-         register void** fn;                                        \
-         __asm__ volatile(                                          \
-            "mov %%fs:0, %[fn]\n"                                   \
-            "mov %P[tls](%[fn]), %[fn]\n"                           \
-            "test %[fn], %[fn]\n"                                   \
+    #define CALL_GL_API_INTERNAL_CALL(_api, ...)                    \
+        __asm__ volatile(                                           \
+            "mov %%fs:0, %%rax\n"                                   \
+            "mov %P[tls](%%rax), %%rax\n"                           \
+            "test %%rax, %%rax\n"                                   \
             "je 1f\n"                                               \
-            "jmp *%P[api](%[fn])\n"                                 \
+            "jmp *%P[api](%%rax)\n"                                 \
             "1:\n"                                                  \
-            : [fn] "=r" (fn)                                        \
+            :                                                       \
             : [tls] "i" (TLS_SLOT_OPENGL_API*sizeof(void*)),        \
               [api] "i" (__builtin_offsetof(gl_hooks_t, gl._api))   \
-            : "cc"                                                  \
-            );
+            : "cc", "%rdi", "%rsi", "%rdx", "%rcx", "%r8", "%r9",   \
+              "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", \
+              "%xmm6", "%xmm7"                                      \
+        );
+
+    #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \
+        __asm__ volatile(                         \
+            "xor %%eax, %%eax\n"                  \
+            :                                     \
+            :                                     \
+            : "%eax"                              \
+        );
+
+    #define CALL_GL_API_INTERNAL_DO_RETURN \
+        __asm__ volatile(                  \
+            "retq\n"                       \
+            :                              \
+            :                              \
+            :                              \
+        );
 
 #elif defined(__mips64)
 
-    #define API_ENTRY(_api) __attribute__((noinline)) _api
+    #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
 
-    #define CALL_GL_API(_api, ...)                            \
-    register unsigned long _t0 asm("$12");                    \
-    register unsigned long _fn asm("$25");                    \
-    register unsigned long _tls asm("$3");                    \
-    register unsigned long _v0 asm("$2");                     \
-    asm volatile(                                             \
-        ".set  push\n\t"                                      \
-        ".set  noreorder\n\t"                                 \
-        "rdhwr %[tls], $29\n\t"                               \
-        "ld    %[t0], %[OPENGL_API](%[tls])\n\t"              \
-        "beqz  %[t0], 1f\n\t"                                 \
-        " move %[fn], $ra\n\t"                                \
-        "ld    %[t0], %[API](%[t0])\n\t"                      \
-        "beqz  %[t0], 1f\n\t"                                 \
-        " nop\n\t"                                            \
-        "move  %[fn], %[t0]\n\t"                              \
-        "1:\n\t"                                              \
-        "jalr  $0, %[fn]\n\t"                                 \
-        " move %[v0], $0\n\t"                                 \
-        ".set  pop\n\t"                                       \
-        : [fn] "=c"(_fn),                                     \
-          [tls] "=&r"(_tls),                                  \
-          [t0] "=&r"(_t0),                                    \
-          [v0] "=&r"(_v0)                                     \
-        : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*sizeof(void*)),\
-          [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api))  \
-        :                                                     \
+    // t0:  $12
+    // fn:  $25
+    // tls: $3
+    // v0:  $2
+    #define CALL_GL_API_INTERNAL_CALL(_api, ...)                  \
+        asm volatile(                                             \
+            ".set  push\n\t"                                      \
+            ".set  noreorder\n\t"                                 \
+            "rdhwr $3, $29\n\t"                                   \
+            "ld    $12, %[OPENGL_API]($3)\n\t"                    \
+            "beqz  $12, 1f\n\t"                                   \
+            " move $25, $ra\n\t"                                  \
+            "ld    $12, %[API]($12)\n\t"                          \
+            "beqz  $12, 1f\n\t"                                   \
+            " nop\n\t"                                            \
+            "move  $25, $12\n\t"                                  \
+            "1:\n\t"                                              \
+            "jalr  $0, $25\n\t"                                   \
+            " move $2, $0\n\t"                                    \
+            ".set  pop\n\t"                                       \
+            :                                                     \
+            : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*sizeof(void*)),\
+              [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api))  \
+            : "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9",     \
+              "$10", "$11", "$12", "$25"                          \
         );
 
+    #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE
+    #define CALL_GL_API_INTERNAL_DO_RETURN
+
 #elif defined(__mips__)
 
-    #define API_ENTRY(_api) __attribute__((noinline)) _api
+    #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
 
-    #define CALL_GL_API(_api, ...)                               \
-        register unsigned int _t0 asm("$8");                     \
-        register unsigned int _fn asm("$25");                    \
-        register unsigned int _tls asm("$3");                    \
-        register unsigned int _v0 asm("$2");                     \
+    // t0:  $8
+    // fn:  $25
+    // tls: $3
+    // v0:  $2
+    #define CALL_GL_API_INTERNAL_CALL(_api, ...)                 \
         asm volatile(                                            \
             ".set  push\n\t"                                     \
             ".set  noreorder\n\t"                                \
             ".set  mips32r2\n\t"                                 \
-            "rdhwr %[tls], $29\n\t"                              \
-            "lw    %[t0], %[OPENGL_API](%[tls])\n\t"             \
-            "beqz  %[t0], 1f\n\t"                                \
-            " move %[fn],$ra\n\t"                                \
-            "lw    %[t0], %[API](%[t0])\n\t"                     \
-            "beqz  %[t0], 1f\n\t"                                \
+            "rdhwr $3, $29\n\t"                                  \
+            "lw    $3, %[OPENGL_API]($3)\n\t"                    \
+            "beqz  $3, 1f\n\t"                                   \
+            " move $25,$ra\n\t"                                  \
+            "lw    $3, %[API]($3)\n\t"                           \
+            "beqz  $3, 1f\n\t"                                   \
             " nop\n\t"                                           \
-            "move  %[fn], %[t0]\n\t"                             \
+            "move  $25, $3\n\t"                                  \
             "1:\n\t"                                             \
-            "jalr  $0, %[fn]\n\t"                                \
-            " move %[v0], $0\n\t"                                \
+            "jalr  $0, $25\n\t"                                  \
+            " move $2, $0\n\t"                                   \
             ".set  pop\n\t"                                      \
-            : [fn] "=c"(_fn),                                    \
-              [tls] "=&r"(_tls),                                 \
-              [t0] "=&r"(_t0),                                   \
-              [v0] "=&r"(_v0)                                    \
+            :                                                    \
             : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*4),           \
               [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api)) \
-            :                                                    \
-            );
+            : "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$25"    \
+        );
+
+    #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE
+    #define CALL_GL_API_INTERNAL_DO_RETURN
 
 #endif
 
+#define CALL_GL_API(_api, ...) \
+    CALL_GL_API_INTERNAL_CALL(_api, __VA_ARGS__) \
+    CALL_GL_API_INTERNAL_DO_RETURN
+
 #define CALL_GL_API_RETURN(_api, ...) \
-    CALL_GL_API(_api, __VA_ARGS__) \
-    return 0;
-
-
+    CALL_GL_API_INTERNAL_CALL(_api, __VA_ARGS__) \
+    CALL_GL_API_INTERNAL_SET_RETURN_VALUE \
+    CALL_GL_API_INTERNAL_DO_RETURN
 
 extern "C" {
 #pragma GCC diagnostic ignored "-Wunused-parameter"
@@ -202,6 +280,9 @@
 
 #undef API_ENTRY
 #undef CALL_GL_API
+#undef CALL_GL_API_INTERNAL_CALL
+#undef CALL_GL_API_INTERNAL_SET_RETURN_VALUE
+#undef CALL_GL_API_INTERNAL_DO_RETURN
 #undef CALL_GL_API_RETURN
 
 /*
diff --git a/opengl/libs/GLES_CM/gl.cpp b/opengl/libs/GLES_CM/gl.cpp
index b1b31f8..8bde4e5 100644
--- a/opengl/libs/GLES_CM/gl.cpp
+++ b/opengl/libs/GLES_CM/gl.cpp
@@ -90,39 +90,65 @@
 
 #undef API_ENTRY
 #undef CALL_GL_API
+#undef CALL_GL_API_INTERNAL_CALL
+#undef CALL_GL_API_INTERNAL_SET_RETURN_VALUE
+#undef CALL_GL_API_INTERNAL_DO_RETURN
 #undef CALL_GL_API_RETURN
 
 #if USE_SLOW_BINDING
 
     #define API_ENTRY(_api) _api
 
-    #define CALL_GL_API(_api, ...)                                       \
+    #define CALL_GL_API_INTERNAL_CALL(_api, ...)                         \
         gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;  \
         if (_c) return _c->_api(__VA_ARGS__);
 
+    #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE return 0;
+
+    // This stays blank, since void functions will implicitly return, and
+    // all of the other functions will return 0 based on the previous macro.
+    #define CALL_GL_API_INTERNAL_DO_RETURN
+
 #elif defined(__arm__)
 
     #define GET_TLS(reg) "mrc p15, 0, " #reg ", c13, c0, 3 \n"
 
-    #define API_ENTRY(_api) __attribute__((noinline)) _api
+    #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
 
-    #define CALL_GL_API(_api, ...)                              \
-         asm volatile(                                          \
-            GET_TLS(r12)                                        \
-            "ldr   r12, [r12, %[tls]] \n"                       \
-            "cmp   r12, #0            \n"                       \
-            "ldrne pc,  [r12, %[api]] \n"                       \
-            :                                                   \
-            : [tls] "J"(TLS_SLOT_OPENGL_API*4),                 \
-              [api] "J"(__builtin_offsetof(gl_hooks_t, gl._api))    \
-            : "r12"                                             \
-            );
+    #define CALL_GL_API_INTERNAL_CALL(_api, ...)                 \
+        asm volatile(                                            \
+            GET_TLS(r12)                                         \
+            "ldr   r12, [r12, %[tls]] \n"                        \
+            "cmp   r12, #0            \n"                        \
+            "ldrne pc,  [r12, %[api]] \n"                        \
+            :                                                    \
+            : [tls] "J"(TLS_SLOT_OPENGL_API*4),                  \
+              [api] "J"(__builtin_offsetof(gl_hooks_t, gl._api)) \
+            : "r0", "r1", "r2", "r3", "r12"                      \
+        );
+
+    #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \
+        asm volatile(                             \
+            "mov r0, #0 \n"                       \
+            :                                     \
+            :                                     \
+            : "r0"                                \
+        );
+
+
+    #define CALL_GL_API_INTERNAL_DO_RETURN \
+        asm volatile(                      \
+            "bx lr \n"                     \
+            :                              \
+            :                              \
+            : "r0"                         \
+        );
 
 #elif defined(__aarch64__)
 
-    #define API_ENTRY(_api) __attribute__((noinline)) _api
+    #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
 
-    #define CALL_GL_API(_api, ...)                                  \
+    #define CALL_GL_API_INTERNAL_CALL(_api, ...)                    \
         asm volatile(                                               \
             "mrs x16, tpidr_el0\n"                                  \
             "ldr x16, [x16, %[tls]]\n"                              \
@@ -133,120 +159,173 @@
             :                                                       \
             : [tls] "i" (TLS_SLOT_OPENGL_API * sizeof(void*)),      \
               [api] "i" (__builtin_offsetof(gl_hooks_t, gl._api))   \
-            : "x16"                                                 \
+            : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x16" \
+        );
+
+    #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \
+        asm volatile(                             \
+            "mov w0, wzr \n"                      \
+            :                                     \
+            :                                     \
+            : "w0"                                \
+        );
+
+    #define CALL_GL_API_INTERNAL_DO_RETURN \
+        asm volatile(                      \
+            "ret \n"                       \
+            :                              \
+            :                              \
+            :                              \
         );
 
 #elif defined(__i386__)
 
-    #define API_ENTRY(_api) __attribute__((noinline,optimize("omit-frame-pointer"))) _api
+    #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
 
-    #define CALL_GL_API(_api, ...)                                  \
-        register void* fn;                                          \
+    #define CALL_GL_API_INTERNAL_CALL(_api, ...)                    \
         __asm__ volatile(                                           \
-            "mov %%gs:0, %[fn]\n"                                   \
-            "mov %P[tls](%[fn]), %[fn]\n"                           \
-            "test %[fn], %[fn]\n"                                   \
+            "mov %%gs:0, %%eax\n"                                   \
+            "mov %P[tls](%%eax), %%eax\n"                           \
+            "test %%eax, %%eax\n"                                   \
             "je 1f\n"                                               \
-            "jmp *%P[api](%[fn])\n"                                 \
+            "jmp *%P[api](%%eax)\n"                                 \
             "1:\n"                                                  \
-            : [fn] "=r" (fn)                                        \
+            :                                                       \
             : [tls] "i" (TLS_SLOT_OPENGL_API*sizeof(void*)),        \
               [api] "i" (__builtin_offsetof(gl_hooks_t, gl._api))   \
-            : "cc"                                                  \
-            );
+            : "cc", "%eax"                                          \
+        );
+
+    #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \
+        __asm__ volatile(                         \
+            "xor %%eax, %%eax\n"                  \
+            :                                     \
+            :                                     \
+            : "%eax"                              \
+        );
+
+    #define CALL_GL_API_INTERNAL_DO_RETURN \
+        __asm__ volatile(                  \
+            "ret\n"                        \
+            :                              \
+            :                              \
+            :                              \
+        );
 
 #elif defined(__x86_64__)
 
-    #define API_ENTRY(_api) __attribute__((noinline,optimize("omit-frame-pointer"))) _api
+    #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
 
-    #define CALL_GL_API(_api, ...)                                  \
-         register void** fn;                                        \
-         __asm__ volatile(                                          \
-            "mov %%fs:0, %[fn]\n"                                   \
-            "mov %P[tls](%[fn]), %[fn]\n"                           \
-            "test %[fn], %[fn]\n"                                   \
+    #define CALL_GL_API_INTERNAL_CALL(_api, ...)                    \
+        __asm__ volatile(                                           \
+            "mov %%fs:0, %%rax\n"                                   \
+            "mov %P[tls](%%rax), %%rax\n"                           \
+            "test %%rax, %%rax\n"                                   \
             "je 1f\n"                                               \
-            "jmp *%P[api](%[fn])\n"                                 \
+            "jmp *%P[api](%%rax)\n"                                 \
             "1:\n"                                                  \
-            : [fn] "=r" (fn)                                        \
+            :                                                       \
             : [tls] "i" (TLS_SLOT_OPENGL_API*sizeof(void*)),        \
               [api] "i" (__builtin_offsetof(gl_hooks_t, gl._api))   \
-            : "cc"                                                  \
-            );
+            : "cc", "%rdi", "%rsi", "%rdx", "%rcx", "%r8", "%r9",   \
+              "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", \
+              "%xmm6", "%xmm7"                                      \
+        );
+
+    #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \
+        __asm__ volatile(                         \
+            "xor %%eax, %%eax\n"                  \
+            :                                     \
+            :                                     \
+            : "%eax"                              \
+        );
+
+    #define CALL_GL_API_INTERNAL_DO_RETURN \
+        __asm__ volatile(                  \
+            "retq\n"                       \
+            :                              \
+            :                              \
+            :                              \
+        );
 
 #elif defined(__mips64)
 
-    #define API_ENTRY(_api) __attribute__((noinline)) _api
+    #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
 
-    #define CALL_GL_API(_api, ...)                            \
-    register unsigned long _t0 asm("$12");                    \
-    register unsigned long _fn asm("$25");                    \
-    register unsigned long _tls asm("$3");                    \
-    register unsigned long _v0 asm("$2");                     \
-    asm volatile(                                             \
-        ".set  push\n\t"                                      \
-        ".set  noreorder\n\t"                                 \
-        "rdhwr %[tls], $29\n\t"                               \
-        "ld    %[t0], %[OPENGL_API](%[tls])\n\t"              \
-        "beqz  %[t0], 1f\n\t"                                 \
-        " move %[fn], $ra\n\t"                                \
-        "ld    %[t0], %[API](%[t0])\n\t"                      \
-        "beqz  %[t0], 1f\n\t"                                 \
-        " nop\n\t"                                            \
-        "move  %[fn], %[t0]\n\t"                              \
-        "1:\n\t"                                              \
-        "jalr  $0, %[fn]\n\t"                                 \
-        " move %[v0], $0\n\t"                                 \
-        ".set  pop\n\t"                                       \
-        : [fn] "=c"(_fn),                                     \
-          [tls] "=&r"(_tls),                                  \
-          [t0] "=&r"(_t0),                                    \
-          [v0] "=&r"(_v0)                                     \
-        : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*sizeof(void*)),\
-          [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api))  \
-        :                                                     \
+    // t0:  $12
+    // fn:  $25
+    // tls: $3
+    // v0:  $2
+    #define CALL_GL_API_INTERNAL_CALL(_api, ...)                  \
+        asm volatile(                                             \
+            ".set  push\n\t"                                      \
+            ".set  noreorder\n\t"                                 \
+            "rdhwr $3, $29\n\t"                                   \
+            "ld    $12, %[OPENGL_API]($3)\n\t"                    \
+            "beqz  $12, 1f\n\t"                                   \
+            " move $25, $ra\n\t"                                  \
+            "ld    $12, %[API]($12)\n\t"                          \
+            "beqz  $12, 1f\n\t"                                   \
+            " nop\n\t"                                            \
+            "move  $25, $12\n\t"                                  \
+            "1:\n\t"                                              \
+            "jalr  $0, $25\n\t"                                   \
+            " move $2, $0\n\t"                                    \
+            ".set  pop\n\t"                                       \
+            :                                                     \
+            : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*sizeof(void*)),\
+              [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api))  \
+            : "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9",     \
+              "$10", "$11", "$12", "$25"                          \
         );
 
+    #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE
+    #define CALL_GL_API_INTERNAL_DO_RETURN
+
 #elif defined(__mips__)
 
-    #define API_ENTRY(_api) __attribute__((noinline)) _api
+    #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
 
-    #define CALL_GL_API(_api, ...)                               \
-        register unsigned int _t0 asm("$8");                     \
-        register unsigned int _fn asm("$25");                    \
-        register unsigned int _tls asm("$3");                    \
-        register unsigned int _v0 asm("$2");                     \
+    // t0:  $8
+    // fn:  $25
+    // tls: $3
+    // v0:  $2
+    #define CALL_GL_API_INTERNAL_CALL(_api, ...)                 \
         asm volatile(                                            \
             ".set  push\n\t"                                     \
             ".set  noreorder\n\t"                                \
             ".set  mips32r2\n\t"                                 \
-            "rdhwr %[tls], $29\n\t"                              \
-            "lw    %[t0], %[OPENGL_API](%[tls])\n\t"             \
-            "beqz  %[t0], 1f\n\t"                                \
-            " move %[fn], $ra\n\t"                               \
-            "lw    %[t0], %[API](%[t0])\n\t"                     \
-            "beqz  %[t0], 1f\n\t"                                \
+            "rdhwr $3, $29\n\t"                                  \
+            "lw    $3, %[OPENGL_API]($3)\n\t"                    \
+            "beqz  $3, 1f\n\t"                                   \
+            " move $25,$ra\n\t"                                  \
+            "lw    $3, %[API]($3)\n\t"                           \
+            "beqz  $3, 1f\n\t"                                   \
             " nop\n\t"                                           \
-            "move  %[fn], %[t0]\n\t"                             \
+            "move  $25, $3\n\t"                                  \
             "1:\n\t"                                             \
-            "jalr  $0, %[fn]\n\t"                                \
-            " move %[v0], $0\n\t"                                \
+            "jalr  $0, $25\n\t"                                  \
+            " move $2, $0\n\t"                                   \
             ".set  pop\n\t"                                      \
-            : [fn] "=c"(_fn),                                    \
-              [tls] "=&r"(_tls),                                 \
-              [t0] "=&r"(_t0),                                   \
-              [v0] "=&r"(_v0)                                    \
+            :                                                    \
             : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*4),           \
               [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api)) \
-            :                                                    \
-            );
+            : "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$25"    \
+        );
+
+    #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE
+    #define CALL_GL_API_INTERNAL_DO_RETURN
 
 #endif
 
-#define CALL_GL_API_RETURN(_api, ...) \
-    CALL_GL_API(_api, __VA_ARGS__) \
-    return 0;
+#define CALL_GL_API(_api, ...) \
+    CALL_GL_API_INTERNAL_CALL(_api, __VA_ARGS__) \
+    CALL_GL_API_INTERNAL_DO_RETURN
 
+#define CALL_GL_API_RETURN(_api, ...) \
+    CALL_GL_API_INTERNAL_CALL(_api, __VA_ARGS__) \
+    CALL_GL_API_INTERNAL_SET_RETURN_VALUE \
+    CALL_GL_API_INTERNAL_DO_RETURN
 
 extern "C" {
 #pragma GCC diagnostic ignored "-Wunused-parameter"
@@ -257,6 +336,9 @@
 
 #undef API_ENTRY
 #undef CALL_GL_API
+#undef CALL_GL_API_INTERNAL_CALL
+#undef CALL_GL_API_INTERNAL_SET_RETURN_VALUE
+#undef CALL_GL_API_INTERNAL_DO_RETURN
 #undef CALL_GL_API_RETURN
 
 /*
diff --git a/opengl/libs/hooks.h b/opengl/libs/hooks.h
index e14075c..81dbe0e 100644
--- a/opengl/libs/hooks.h
+++ b/opengl/libs/hooks.h
@@ -56,8 +56,8 @@
 
 #undef GL_ENTRY
 #undef EGL_ENTRY
-#define GL_ENTRY(_r, _api, ...) _r (*_api)(__VA_ARGS__);
-#define EGL_ENTRY(_r, _api, ...) _r (*_api)(__VA_ARGS__);
+#define GL_ENTRY(_r, _api, ...) _r (*(_api))(__VA_ARGS__);
+#define EGL_ENTRY(_r, _api, ...) _r (*(_api))(__VA_ARGS__);
 
 struct egl_t {
     #include "EGL/egl_entries.in"
diff --git a/opengl/tests/angeles/demo.c b/opengl/tests/angeles/demo.c
index 802f398..39d871e 100644
--- a/opengl/tests/angeles/demo.c
+++ b/opengl/tests/angeles/demo.c
@@ -666,7 +666,7 @@
         y[2] /= mag;
     }
 
-#define M(row,col)  m[col*4+row]
+#define M(row,col)  m[(col)*4+(row)]
     M(0, 0) = x[0];
     M(0, 1) = x[1];
     M(0, 2) = x[2];
diff --git a/opengl/tests/hwc/hwcColorEquiv.cpp b/opengl/tests/hwc/hwcColorEquiv.cpp
index f1361b8..a9bbcb6 100644
--- a/opengl/tests/hwc/hwcColorEquiv.cpp
+++ b/opengl/tests/hwc/hwcColorEquiv.cpp
@@ -116,7 +116,7 @@
 #define CMD_START_FRAMEWORK  "start 2>&1"
 
 // Macros
-#define NUMA(a) (sizeof(a) / sizeof(a [0])) // Num elements in an array
+#define NUMA(a) (sizeof(a) / sizeof((a)[0])) // Num elements in an array
 #define MEMCLR(addr, size) do { \
         memset((addr), 0, (size)); \
     } while (0)
diff --git a/opengl/tests/hwc/hwcCommit.cpp b/opengl/tests/hwc/hwcCommit.cpp
index 6b287e9..3686dab 100644
--- a/opengl/tests/hwc/hwcCommit.cpp
+++ b/opengl/tests/hwc/hwcCommit.cpp
@@ -156,12 +156,12 @@
 #define CMD_START_FRAMEWORK  "start 2>&1"
 
 // Macros
-#define NUMA(a) (sizeof(a) / sizeof(a [0])) // Num elements in an array
+#define NUMA(a) (sizeof(a) / sizeof((a)[0])) // Num elements in an array
 
 // Local types
 class Rectangle {
 public:
-    Rectangle(uint32_t graphicFormat = defaultFormat,
+    explicit Rectangle(uint32_t graphicFormat = defaultFormat,
               HwcTestDim dfDim = HwcTestDim(1, 1),
               HwcTestDim sDim = HwcTestDim(1, 1));
     void setSourceDim(HwcTestDim dim);
diff --git a/opengl/tests/hwc/hwcRects.cpp b/opengl/tests/hwc/hwcRects.cpp
index 2e2b204..69e56ff 100644
--- a/opengl/tests/hwc/hwcRects.cpp
+++ b/opengl/tests/hwc/hwcRects.cpp
@@ -137,7 +137,7 @@
 #define CMD_START_FRAMEWORK  "start 2>&1"
 
 // Macros
-#define NUMA(a) (sizeof(a) / sizeof(a [0])) // Num elements in an array
+#define NUMA(a) (sizeof(a) / sizeof((a)[0])) // Num elements in an array
 
 // Local types
 class Rectangle {
diff --git a/opengl/tests/hwc/hwcStress.cpp b/opengl/tests/hwc/hwcStress.cpp
index 60c29ef..1469f7c 100644
--- a/opengl/tests/hwc/hwcStress.cpp
+++ b/opengl/tests/hwc/hwcStress.cpp
@@ -162,7 +162,7 @@
 #define CMD_STOP_FRAMEWORK   "stop 2>&1"
 #define CMD_START_FRAMEWORK  "start 2>&1"
 
-#define NUMA(a) (sizeof(a) / sizeof(a [0]))
+#define NUMA(a) (sizeof(a) / sizeof((a)[0]))
 #define MEMCLR(addr, size) do { \
         memset((addr), 0, (size)); \
     } while (0)
diff --git a/services/batteryservice/IBatteryPropertiesListener.cpp b/services/batteryservice/IBatteryPropertiesListener.cpp
index 8aff26c..7555f4b 100644
--- a/services/batteryservice/IBatteryPropertiesListener.cpp
+++ b/services/batteryservice/IBatteryPropertiesListener.cpp
@@ -24,7 +24,7 @@
 class BpBatteryPropertiesListener : public BpInterface<IBatteryPropertiesListener>
 {
 public:
-    BpBatteryPropertiesListener(const sp<IBinder>& impl)
+    explicit BpBatteryPropertiesListener(const sp<IBinder>& impl)
         : BpInterface<IBatteryPropertiesListener>(impl)
     {
     }
diff --git a/services/batteryservice/IBatteryPropertiesRegistrar.cpp b/services/batteryservice/IBatteryPropertiesRegistrar.cpp
index 46934e0..1fdda43 100644
--- a/services/batteryservice/IBatteryPropertiesRegistrar.cpp
+++ b/services/batteryservice/IBatteryPropertiesRegistrar.cpp
@@ -28,7 +28,7 @@
 
 class BpBatteryPropertiesRegistrar : public BpInterface<IBatteryPropertiesRegistrar> {
 public:
-    BpBatteryPropertiesRegistrar(const sp<IBinder>& impl)
+    explicit BpBatteryPropertiesRegistrar(const sp<IBinder>& impl)
         : BpInterface<IBatteryPropertiesRegistrar>(impl) {}
 
         void registerListener(const sp<IBatteryPropertiesListener>& listener) {
diff --git a/services/inputflinger/EventHub.cpp b/services/inputflinger/EventHub.cpp
index 2a53dec..d2f8995 100644
--- a/services/inputflinger/EventHub.cpp
+++ b/services/inputflinger/EventHub.cpp
@@ -55,10 +55,10 @@
  * operation with a byte that only has the relevant bit set.
  * eg. to check for the 12th bit, we do (array[1] & 1<<4)
  */
-#define test_bit(bit, array)    (array[bit/8] & (1<<(bit%8)))
+#define test_bit(bit, array)    ((array)[(bit)/8] & (1<<((bit)%8)))
 
 /* this macro computes the number of bytes needed to represent a bit array of the specified size */
-#define sizeof_bit_array(bits)  ((bits + 7) / 8)
+#define sizeof_bit_array(bits)  (((bits) + 7) / 8)
 
 #define INDENT "  "
 #define INDENT2 "    "
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index a7fe69c..f12320d 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -325,7 +325,7 @@
         KeyedVector<int32_t, bool> leds;
         Vector<VirtualKeyDefinition> virtualKeys;
 
-        Device(uint32_t classes) :
+        explicit Device(uint32_t classes) :
                 classes(classes) {
         }
     };
diff --git a/services/nativeperms/.clang-format b/services/nativeperms/.clang-format
new file mode 100644
index 0000000..6006e6f
--- /dev/null
+++ b/services/nativeperms/.clang-format
@@ -0,0 +1,13 @@
+BasedOnStyle: Google
+AllowShortFunctionsOnASingleLine: Inline
+AllowShortIfStatementsOnASingleLine: true
+AllowShortLoopsOnASingleLine: true
+BinPackArguments: true
+BinPackParameters: true
+ColumnLimit: 80
+CommentPragmas: NOLINT:.*
+ContinuationIndentWidth: 8
+DerivePointerAlignment: false
+IndentWidth: 4
+PointerAlignment: Left
+TabWidth: 4
diff --git a/services/nativeperms/Android.mk b/services/nativeperms/Android.mk
new file mode 100644
index 0000000..34ccd0b
--- /dev/null
+++ b/services/nativeperms/Android.mk
@@ -0,0 +1,31 @@
+# Copyright 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := nativeperms
+LOCAL_SRC_FILES := \
+    nativeperms.cpp \
+    android/os/IPermissionController.aidl
+LOCAL_CFLAGS := -Wall -Werror
+LOCAL_SHARED_LIBRARIES := \
+    libbinder \
+    libbrillo \
+    libbrillo-binder \
+    libchrome \
+    libutils
+LOCAL_INIT_RC := nativeperms.rc
+include $(BUILD_EXECUTABLE)
diff --git a/services/nativeperms/android/os/IPermissionController.aidl b/services/nativeperms/android/os/IPermissionController.aidl
new file mode 100644
index 0000000..89db85c
--- /dev/null
+++ b/services/nativeperms/android/os/IPermissionController.aidl
@@ -0,0 +1,25 @@
+/* //device/java/android/android/os/IPowerManager.aidl
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.os;
+
+/** @hide */
+interface IPermissionController {
+    boolean checkPermission(String permission, int pid, int uid);
+    String[] getPackagesForUid(int uid);
+    boolean isRuntimePermission(String permission);
+}
diff --git a/services/nativeperms/android/os/README b/services/nativeperms/android/os/README
new file mode 100644
index 0000000..e414499
--- /dev/null
+++ b/services/nativeperms/android/os/README
@@ -0,0 +1,4 @@
+IPermissionController.aidl in this directory is a verbatim copy of
+https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/os/IPermissionController.aidl,
+because some Brillo manifests do not currently include the frameworks/base repo.
+TODO(jorgelo): Figure out a way to use the .aidl file in frameworks/base.
diff --git a/services/nativeperms/nativeperms.cpp b/services/nativeperms/nativeperms.cpp
new file mode 100644
index 0000000..7f03bed
--- /dev/null
+++ b/services/nativeperms/nativeperms.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <base/at_exit.h>
+#include <base/logging.h>
+#include <base/message_loop/message_loop.h>
+#include <binder/IServiceManager.h>
+#include <binder/Status.h>
+#include <brillo/binder_watcher.h>
+#include <brillo/message_loops/base_message_loop.h>
+#include <brillo/syslog_logging.h>
+#include <utils/String16.h>
+
+#include "android/os/BnPermissionController.h"
+
+namespace {
+static android::String16 serviceName("permission");
+}
+
+namespace android {
+
+class PermissionService : public android::os::BnPermissionController {
+   public:
+    ::android::binder::Status checkPermission(
+            const ::android::String16& permission, int32_t pid, int32_t uid,
+            bool* _aidl_return) {
+        (void)permission;
+        (void)pid;
+        (void)uid;
+        *_aidl_return = true;
+        return binder::Status::ok();
+    }
+
+    ::android::binder::Status getPackagesForUid(
+            int32_t uid, ::std::vector<::android::String16>* _aidl_return) {
+        (void)uid;
+        // Brillo doesn't currently have installable packages.
+        if (_aidl_return) {
+            _aidl_return->clear();
+        }
+        return binder::Status::ok();
+    }
+
+    ::android::binder::Status isRuntimePermission(
+            const ::android::String16& permission, bool* _aidl_return) {
+        (void)permission;
+        // Brillo doesn't currently have runtime permissions.
+        *_aidl_return = false;
+        return binder::Status::ok();
+    }
+};
+
+}  // namespace android
+
+int main() {
+    base::AtExitManager atExitManager;
+    brillo::InitLog(brillo::kLogToSyslog);
+    // Register the service with servicemanager.
+    android::status_t status = android::defaultServiceManager()->addService(
+            serviceName, new android::PermissionService());
+    CHECK(status == android::OK) << "Failed to get IPermissionController "
+                                    "binder from servicemanager.";
+
+    // Create a message loop.
+    base::MessageLoopForIO messageLoopForIo;
+    brillo::BaseMessageLoop messageLoop{&messageLoopForIo};
+
+    // Initialize a binder watcher.
+    brillo::BinderWatcher watcher(&messageLoop);
+    watcher.Init();
+
+    // Run the message loop.
+    messageLoop.Run();
+}
diff --git a/services/nativeperms/nativeperms.rc b/services/nativeperms/nativeperms.rc
new file mode 100644
index 0000000..704c0a2
--- /dev/null
+++ b/services/nativeperms/nativeperms.rc
@@ -0,0 +1,4 @@
+service nativeperms /system/bin/nativeperms
+    class main
+    user system
+    group system
diff --git a/services/powermanager/IPowerManager.cpp b/services/powermanager/IPowerManager.cpp
index bff8719..ea3a831 100644
--- a/services/powermanager/IPowerManager.cpp
+++ b/services/powermanager/IPowerManager.cpp
@@ -30,7 +30,7 @@
 class BpPowerManager : public BpInterface<IPowerManager>
 {
 public:
-    BpPowerManager(const sp<IBinder>& impl)
+    explicit BpPowerManager(const sp<IBinder>& impl)
         : BpInterface<IPowerManager>(impl)
     {
     }
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index c8de621..dc49b06 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -49,9 +49,9 @@
 #define IGNORE_HARDWARE_FUSION  false
 #define DEBUG_CONNECTIONS   false
 // Max size is 100 KB which is enough to accept a batch of about 1000 events.
-#define MAX_SOCKET_BUFFER_SIZE_BATCHED 100 * 1024
+#define MAX_SOCKET_BUFFER_SIZE_BATCHED (100 * 1024)
 // For older HALs which don't support batching, use a smaller socket buffer size.
-#define SOCKET_BUFFER_SIZE_NON_BATCHED 4 * 1024
+#define SOCKET_BUFFER_SIZE_NON_BATCHED (4 * 1024)
 
 #define SENSOR_REGISTRATIONS_BUF_SIZE 20
 
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 0247723..44db852 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -160,9 +160,7 @@
     mSurfaceFlingerConsumer->setContentsChangedListener(this);
     mSurfaceFlingerConsumer->setName(mName);
 
-#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
-#warning "disabling triple buffering"
-#else
+#ifndef TARGET_DISABLE_TRIPLE_BUFFERING
     mProducer->setMaxDequeuedBufferCount(2);
 #endif
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index a10a813..c700116 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -90,6 +90,19 @@
 
 EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
 
+// Workaround for b/30067360: /proc/self/environ inaccessible in SurfaceFlinger
+// => ASan fails to read ASAN_OPTIONS => alloc-dealloc-mismatch bug is not
+// suppressed and prevents the device from booting.
+#ifndef __has_feature
+#define __has_feature(x) 0
+#endif
+#if __has_feature(address_sanitizer)
+__attribute__((visibility("default")))
+extern "C" const char* __asan_default_options() {
+  return "alloc_dealloc_mismatch=0";
+}
+#endif
+
 namespace android {
 
 // This is the phase offset in nanoseconds of the software vsync event