Merge "Added Voltage and Current regulator ftrace events to atrace"
diff --git a/build/tablet-7in-hdpi-1024-dalvik-heap.mk b/build/tablet-7in-hdpi-1024-dalvik-heap.mk
index 5bbd2b0..7fd34b5 100644
--- a/build/tablet-7in-hdpi-1024-dalvik-heap.mk
+++ b/build/tablet-7in-hdpi-1024-dalvik-heap.mk
@@ -18,7 +18,7 @@
 
 PRODUCT_PROPERTY_OVERRIDES += \
     dalvik.vm.heapstartsize=8m \
-    dalvik.vm.heapgrowthlimit=64m \
+    dalvik.vm.heapgrowthlimit=80m \
     dalvik.vm.heapsize=384m \
     dalvik.vm.heaptargetutilization=0.75 \
     dalvik.vm.heapminfree=512k \
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index e90baf6..4100fa3 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -35,6 +35,7 @@
 #include <cutils/properties.h>
 
 #include <utils/String8.h>
+#include <utils/Timers.h>
 #include <utils/Trace.h>
 
 using namespace android;
@@ -78,7 +79,7 @@
     { "webview",    "WebView",          ATRACE_TAG_WEBVIEW, { } },
     { "wm",         "Window Manager",   ATRACE_TAG_WINDOW_MANAGER, { } },
     { "am",         "Activity Manager", ATRACE_TAG_ACTIVITY_MANAGER, { } },
-    { "sync",       "Sync Manager",     ATRACE_TAG_SYNC_MANAGER, { } },
+    { "sm",         "Sync Manager",     ATRACE_TAG_SYNC_MANAGER, { } },
     { "audio",      "Audio",            ATRACE_TAG_AUDIO, { } },
     { "video",      "Video",            ATRACE_TAG_VIDEO, { } },
     { "camera",     "Camera",           ATRACE_TAG_CAMERA, { } },
@@ -107,14 +108,14 @@
         { REQ,      "/sys/kernel/debug/tracing/events/power/cpu_idle/enable" },
     } },
     { "disk",       "Disk I/O",         0, {
-        { REQ,      "/sys/kernel/debug/tracing/events/f2fs/f2fs_sync_file_enter/enable" },
-        { REQ,      "/sys/kernel/debug/tracing/events/f2fs/f2fs_sync_file_exit/enable" },
-        { REQ,      "/sys/kernel/debug/tracing/events/f2fs/f2fs_write_begin/enable" },
-        { REQ,      "/sys/kernel/debug/tracing/events/f2fs/f2fs_write_end/enable" },
-        { REQ,      "/sys/kernel/debug/tracing/events/ext4/ext4_da_write_begin/enable" },
-        { REQ,      "/sys/kernel/debug/tracing/events/ext4/ext4_da_write_end/enable" },
-        { REQ,      "/sys/kernel/debug/tracing/events/ext4/ext4_sync_file_enter/enable" },
-        { REQ,      "/sys/kernel/debug/tracing/events/ext4/ext4_sync_file_exit/enable" },
+        { OPT,      "/sys/kernel/debug/tracing/events/f2fs/f2fs_sync_file_enter/enable" },
+        { OPT,      "/sys/kernel/debug/tracing/events/f2fs/f2fs_sync_file_exit/enable" },
+        { OPT,      "/sys/kernel/debug/tracing/events/f2fs/f2fs_write_begin/enable" },
+        { OPT,      "/sys/kernel/debug/tracing/events/f2fs/f2fs_write_end/enable" },
+        { OPT,      "/sys/kernel/debug/tracing/events/ext4/ext4_da_write_begin/enable" },
+        { OPT,      "/sys/kernel/debug/tracing/events/ext4/ext4_da_write_end/enable" },
+        { OPT,      "/sys/kernel/debug/tracing/events/ext4/ext4_sync_file_enter/enable" },
+        { OPT,      "/sys/kernel/debug/tracing/events/ext4/ext4_sync_file_exit/enable" },
         { REQ,      "/sys/kernel/debug/tracing/events/block/block_rq_issue/enable" },
         { REQ,      "/sys/kernel/debug/tracing/events/block/block_rq_complete/enable" },
     } },
@@ -195,6 +196,9 @@
 static const char* k_tracePath =
     "/sys/kernel/debug/tracing/trace";
 
+static const char* k_traceMarkerPath =
+    "/sys/kernel/debug/tracing/trace_marker";
+
 // Check whether a file exists.
 static bool fileExists(const char* filename) {
     return access(filename, F_OK) != -1;
@@ -257,6 +261,14 @@
     return _writeStr(filename, str, O_APPEND|O_WRONLY);
 }
 
+static void writeClockSyncMarker()
+{
+  char buffer[128];
+  float now_in_seconds = systemTime(CLOCK_MONOTONIC) / 1000000000.0f;
+  snprintf(buffer, 128, "trace_event_clock_sync: parent_ts=%f\n", now_in_seconds);
+  writeStr(k_traceMarkerPath, buffer);
+}
+
 // Enable or disable a kernel option by writing a "1" or a "0" into a /sys
 // file.
 static bool setKernelOptionEnable(const char* filename, bool enable)
@@ -634,6 +646,7 @@
 // Disable tracing in the kernel.
 static void stopTrace()
 {
+    writeClockSyncMarker();
     setTracingEnabled(false);
 }
 
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 1d33d71..ceb20dc 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <limits.h>
@@ -63,7 +64,8 @@
     time_t thirty_minutes_ago = time(NULL) - 60*30;
     for (size_t i = 0; i < NUM_TOMBSTONES; i++) {
         snprintf(data[i].name, sizeof(data[i].name), "%s%02zu", TOMBSTONE_FILE_PREFIX, i);
-        int fd = open(data[i].name, O_RDONLY | O_CLOEXEC | O_NOFOLLOW);
+        int fd = TEMP_FAILURE_RETRY(open(data[i].name,
+                                         O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK));
         struct stat st;
         if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode) &&
                 (time_t) st.st_mtime >= thirty_minutes_ago) {
@@ -75,6 +77,89 @@
     }
 }
 
+static void dump_dev_files(const char *title, const char *driverpath, const char *filename)
+{
+    DIR *d;
+    struct dirent *de;
+    char path[PATH_MAX];
+
+    d = opendir(driverpath);
+    if (d == NULL) {
+        return;
+    }
+
+    while ((de = readdir(d))) {
+        if (de->d_type != DT_LNK) {
+            continue;
+        }
+        snprintf(path, sizeof(path), "%s/%s/%s", driverpath, de->d_name, filename);
+        dump_file(title, path);
+    }
+
+    closedir(d);
+}
+
+static bool skip_not_stat(const char *path) {
+    static const char stat[] = "/stat";
+    size_t len = strlen(path);
+    if (path[len - 1] == '/') { /* Directory? */
+        return false;
+    }
+    return strcmp(path + len - sizeof(stat) + 1, stat); /* .../stat? */
+}
+
+static const char mmcblk0[] = "/sys/block/mmcblk0/";
+
+static int dump_stat_from_fd(const char *title __unused, const char *path, int fd) {
+    unsigned long fields[11], read_perf, write_perf;
+    bool z;
+    char *cp, *buffer = NULL;
+    size_t i = 0;
+    FILE *fp = fdopen(fd, "rb");
+    getline(&buffer, &i, fp);
+    fclose(fp);
+    if (!buffer) {
+        return -errno;
+    }
+    i = strlen(buffer);
+    while ((i > 0) && (buffer[i - 1] == '\n')) {
+        buffer[--i] = '\0';
+    }
+    if (!*buffer) {
+        free(buffer);
+        return 0;
+    }
+    z = true;
+    for (cp = buffer, i = 0; i < (sizeof(fields) / sizeof(fields[0])); ++i) {
+        fields[i] = strtol(cp, &cp, 0);
+        if (fields[i] != 0) {
+            z = false;
+        }
+    }
+    if (z) { /* never accessed */
+        free(buffer);
+        return 0;
+    }
+
+    if (!strncmp(path, mmcblk0, sizeof(mmcblk0) - 1)) {
+        path += sizeof(mmcblk0) - 1;
+    }
+
+    printf("%s: %s\n", path, buffer);
+    free(buffer);
+
+    read_perf = 0;
+    if (fields[3]) {
+        read_perf = 512 * fields[2] / fields[3];
+    }
+    write_perf = 0;
+    if (fields[7]) {
+        write_perf = 512 * fields[6] / fields[7];
+    }
+    printf("%s: read: %luKB/s write: %luKB/s\n", path, read_perf, write_perf);
+    return 0;
+}
+
 /* dumps the current system state to stdout */
 static void dumpstate() {
     time_t now = time(NULL);
@@ -107,7 +192,9 @@
     printf("Command line: %s\n", strtok(cmdline_buf, "\n"));
     printf("\n");
 
+    dump_dev_files("TRUSTY VERSION", "/sys/bus/platform/drivers/trusty", "trusty_version");
     run_command("UPTIME", 10, "uptime", NULL);
+    dump_files("UPTIME MMC PERF", mmcblk0, skip_not_stat, dump_stat_from_fd);
     dump_file("MEMORY INFO", "/proc/meminfo");
     run_command("CPU INFO", 10, "top", "-n", "1", "-d", "1", "-m", "30", "-t", NULL);
     run_command("PROCRANK", 20, "procrank", NULL);
@@ -159,7 +246,8 @@
     if (!anr_traces_path[0]) {
         printf("*** NO VM TRACES FILE DEFINED (dalvik.vm.stack-trace-file)\n\n");
     } else {
-      int fd = open(anr_traces_path, O_RDONLY | O_CLOEXEC | O_NOFOLLOW);
+      int fd = TEMP_FAILURE_RETRY(open(anr_traces_path,
+                                       O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK));
       if (fd < 0) {
           printf("*** NO ANR VM TRACES FILE (%s): %s\n\n", anr_traces_path, strerror(errno));
       } else {
@@ -211,8 +299,9 @@
         dump_file("LAST KMSG", "/proc/last_kmsg");
     }
 
-    dump_file("LAST PANIC CONSOLE", "/data/dontpanic/apanic_console");
-    dump_file("LAST PANIC THREADS", "/data/dontpanic/apanic_threads");
+    /* kernels must set CONFIG_PSTORE_PMSG, slice up pstore with device tree */
+    run_command("LAST LOGCAT", 10, "logcat", "-L", "-v", "threadtime",
+                                             "-b", "all", "-d", "*:v", NULL);
 
     for_each_userid(do_dump_settings, NULL);
 
@@ -271,9 +360,6 @@
 
     run_command("FILESYSTEMS & FREE SPACE", 10, "df", NULL);
 
-    run_command("PACKAGE SETTINGS", 20, SU_PATH, "root", "cat", "/data/system/packages.xml", NULL);
-    dump_file("PACKAGE UID ERRORS", "/data/system/uiderrors.txt");
-
     run_command("LAST RADIO LOG", 10, "parse_radio_log", "/proc/last_radio_log", NULL);
 
     printf("------ BACKLIGHTS ------\n");
@@ -412,7 +498,7 @@
 
     /* set as high priority, and protect from OOM killer */
     setpriority(PRIO_PROCESS, 0, -20);
-    FILE *oom_adj = fopen("/proc/self/oom_adj", "w");
+    FILE *oom_adj = fopen("/proc/self/oom_adj", "we");
     if (oom_adj) {
         fputs("-17", oom_adj);
         fclose(oom_adj);
@@ -445,15 +531,14 @@
     /* open the vibrator before dropping root */
     FILE *vibrator = 0;
     if (do_vibrate) {
-        vibrator = fopen("/sys/class/timed_output/vibrator/enable", "w");
+        vibrator = fopen("/sys/class/timed_output/vibrator/enable", "we");
         if (vibrator) {
-            fcntl(fileno(vibrator), F_SETFD, FD_CLOEXEC);
             vibrate(vibrator, 150);
         }
     }
 
     /* read /proc/cmdline before dropping root */
-    FILE *cmdline = fopen("/proc/cmdline", "r");
+    FILE *cmdline = fopen("/proc/cmdline", "re");
     if (cmdline != NULL) {
         fgets(cmdline_buf, sizeof(cmdline_buf), cmdline);
         fclose(cmdline);
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 2be340b..26bba1b 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -31,9 +31,21 @@
 /* prints the contents of a file */
 int dump_file(const char *title, const char *path);
 
-/* prints the contents of the fd */
+/* prints the contents of the fd
+ * fd must have been opened with the flag O_NONBLOCK.
+ */
 int dump_file_from_fd(const char *title, const char *path, int fd);
 
+/* calls skip to gate calling dump_from_fd recursively
+ * in the specified directory. dump_from_fd defaults to
+ * dump_file_from_fd above when set to NULL. skip defaults
+ * to false when set to NULL. dump_from_fd will always be
+ * called with title NULL.
+ */
+int dump_files(const char *title, const char *dir,
+        bool (*skip)(const char *path),
+        int (*dump_from_fd)(const char *title, const char *path, int fd));
+
 /* forks a command and waits for it to finish -- terminate args with NULL */
 int run_command(const char *title, int timeout_seconds, const char *command, ...);
 
diff --git a/cmds/dumpstate/utils.c b/cmds/dumpstate/utils.c
index 7ad9cf0..4fc23aa 100644
--- a/cmds/dumpstate/utils.c
+++ b/cmds/dumpstate/utils.c
@@ -53,6 +53,12 @@
         NULL,
 };
 
+static uint64_t nanotime() {
+    struct timespec ts;
+    clock_gettime(CLOCK_MONOTONIC, &ts);
+    return (uint64_t)ts.tv_sec * NANOS_PER_SEC + ts.tv_nsec;
+}
+
 void for_each_userid(void (*func)(int), const char *header) {
     DIR *d;
     struct dirent *de;
@@ -98,7 +104,7 @@
 
         sprintf(cmdpath,"/proc/%d/cmdline", pid);
         memset(cmdline, 0, sizeof(cmdline));
-        if ((fd = open(cmdpath, O_RDONLY)) < 0) {
+        if ((fd = TEMP_FAILURE_RETRY(open(cmdpath, O_RDONLY | O_CLOEXEC))) < 0) {
             strcpy(cmdline, "N/A");
         } else {
             read(fd, cmdline, sizeof(cmdline) - 1);
@@ -149,7 +155,7 @@
 
         sprintf(commpath,"/proc/%d/comm", tid);
         memset(comm, 0, sizeof(comm));
-        if ((fd = open(commpath, O_RDONLY)) < 0) {
+        if ((fd = TEMP_FAILURE_RETRY(open(commpath, O_RDONLY | O_CLOEXEC))) < 0) {
             strcpy(comm, "N/A");
         } else {
             char *c;
@@ -180,7 +186,7 @@
     memset(buffer, 0, sizeof(buffer));
 
     sprintf(path, "/proc/%d/wchan", tid);
-    if ((fd = open(path, O_RDONLY)) < 0) {
+    if ((fd = TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_CLOEXEC))) < 0) {
         printf("Failed to open '%s' (%s)\n", path, strerror(errno));
         return;
     }
@@ -250,22 +256,7 @@
     run_command(title, 10, SU_PATH, "root", "showmap", arg, NULL);
 }
 
-/* prints the contents of a file */
-int dump_file(const char *title, const char *path) {
-    int fd = open(path, O_RDONLY);
-    if (fd < 0) {
-        int err = errno;
-        if (title) printf("------ %s (%s) ------\n", title, path);
-        printf("*** %s: %s\n", path, strerror(err));
-        if (title) printf("\n");
-        return -1;
-    }
-    return dump_file_from_fd(title, path, fd);
-}
-
-int dump_file_from_fd(const char *title, const char *path, int fd) {
-    char buffer[32768];
-
+static int _dump_file_from_fd(const char *title, const char *path, int fd) {
     if (title) printf("------ %s (%s", title, path);
 
     if (title) {
@@ -279,26 +270,145 @@
         printf(") ------\n");
     }
 
-    int newline = 0;
-    for (;;) {
-        int ret = read(fd, buffer, sizeof(buffer));
-        if (ret > 0) {
-            newline = (buffer[ret - 1] == '\n');
-            ret = fwrite(buffer, ret, 1, stdout);
+    bool newline = false;
+    fd_set read_set;
+    struct timeval tm;
+    while (1) {
+        FD_ZERO(&read_set);
+        FD_SET(fd, &read_set);
+        /* Timeout if no data is read for 30 seconds. */
+        tm.tv_sec = 30;
+        tm.tv_usec = 0;
+        uint64_t elapsed = nanotime();
+        int ret = TEMP_FAILURE_RETRY(select(fd + 1, &read_set, NULL, NULL, &tm));
+        if (ret == -1) {
+            printf("*** %s: select failed: %s\n", path, strerror(errno));
+            newline = true;
+            break;
+        } else if (ret == 0) {
+            elapsed = nanotime() - elapsed;
+            printf("*** %s: Timed out after %.3fs\n", path,
+                   (float) elapsed / NANOS_PER_SEC);
+            newline = true;
+            break;
+        } else {
+            char buffer[65536];
+            ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer, sizeof(buffer)));
+            if (bytes_read > 0) {
+                fwrite(buffer, bytes_read, 1, stdout);
+                newline = (buffer[bytes_read-1] == '\n');
+            } else {
+                if (bytes_read == -1) {
+                    printf("*** %s: Failed to read from fd: %s", path, strerror(errno));
+                    newline = true;
+                }
+                break;
+            }
         }
-        if (ret <= 0) break;
     }
-    close(fd);
+    TEMP_FAILURE_RETRY(close(fd));
 
     if (!newline) printf("\n");
     if (title) printf("\n");
     return 0;
 }
 
-static int64_t nanotime() {
-    struct timespec ts;
-    clock_gettime(CLOCK_MONOTONIC, &ts);
-    return (int64_t)ts.tv_sec * NANOS_PER_SEC + ts.tv_nsec;
+/* prints the contents of a file */
+int dump_file(const char *title, const char *path) {
+    int fd = TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_NONBLOCK | O_CLOEXEC));
+    if (fd < 0) {
+        int err = errno;
+        if (title) printf("------ %s (%s) ------\n", title, path);
+        printf("*** %s: %s\n", path, strerror(err));
+        if (title) printf("\n");
+        return -1;
+    }
+    return _dump_file_from_fd(title, path, fd);
+}
+
+/* calls skip to gate calling dump_from_fd recursively
+ * in the specified directory. dump_from_fd defaults to
+ * dump_file_from_fd above when set to NULL. skip defaults
+ * to false when set to NULL. dump_from_fd will always be
+ * called with title NULL.
+ */
+int dump_files(const char *title, const char *dir,
+        bool (*skip)(const char *path),
+        int (*dump_from_fd)(const char *title, const char *path, int fd)) {
+    DIR *dirp;
+    struct dirent *d;
+    char *newpath = NULL;
+    char *slash = "/";
+    int fd, retval = 0;
+
+    if (title) {
+        printf("------ %s (%s) ------\n", title, dir);
+    }
+
+    if (dir[strlen(dir) - 1] == '/') {
+        ++slash;
+    }
+    dirp = opendir(dir);
+    if (dirp == NULL) {
+        retval = -errno;
+        fprintf(stderr, "%s: %s\n", dir, strerror(errno));
+        return retval;
+    }
+
+    if (!dump_from_fd) {
+        dump_from_fd = dump_file_from_fd;
+    }
+    for (; ((d = readdir(dirp))); free(newpath), newpath = NULL) {
+        if ((d->d_name[0] == '.')
+         && (((d->d_name[1] == '.') && (d->d_name[2] == '\0'))
+          || (d->d_name[1] == '\0'))) {
+            continue;
+        }
+        asprintf(&newpath, "%s%s%s%s", dir, slash, d->d_name,
+                 (d->d_type == DT_DIR) ? "/" : "");
+        if (!newpath) {
+            retval = -errno;
+            continue;
+        }
+        if (skip && (*skip)(newpath)) {
+            continue;
+        }
+        if (d->d_type == DT_DIR) {
+            int ret = dump_files(NULL, newpath, skip, dump_from_fd);
+            if (ret < 0) {
+                retval = ret;
+            }
+            continue;
+        }
+        fd = TEMP_FAILURE_RETRY(open(newpath, O_RDONLY | O_NONBLOCK | O_CLOEXEC));
+        if (fd < 0) {
+            retval = fd;
+            printf("*** %s: %s\n", newpath, strerror(errno));
+            continue;
+        }
+        (*dump_from_fd)(NULL, newpath, fd);
+    }
+    closedir(dirp);
+    if (title) {
+        printf("\n");
+    }
+    return retval;
+}
+
+/* fd must have been opened with the flag O_NONBLOCK. With this flag set,
+ * it's possible to avoid issues where opening the file itself can get
+ * stuck.
+ */
+int dump_file_from_fd(const char *title, const char *path, int fd) {
+    int flags = fcntl(fd, F_GETFL);
+    if (flags == -1) {
+        printf("*** %s: failed to get flags on fd %d: %s\n", path, fd, strerror(errno));
+        return -1;
+    } else if (!(flags & O_NONBLOCK)) {
+        printf("*** %s: fd must have O_NONBLOCK set.\n", path);
+        return -1;
+    }
+    return _dump_file_from_fd(title, path, fd);
 }
 
 bool waitpid_with_timeout(pid_t pid, int timeout_seconds, int* status) {
@@ -348,7 +458,7 @@
 /* forks a command and waits for it to finish */
 int run_command(const char *title, int timeout_seconds, const char *command, ...) {
     fflush(stdout);
-    int64_t start = nanotime();
+    uint64_t start = nanotime();
     pid_t pid = fork();
 
     /* handle error case */
@@ -458,6 +568,7 @@
         fprintf(stderr, "android_get_control_socket(%s): %s\n", service, strerror(errno));
         exit(1);
     }
+    fcntl(s, F_SETFD, FD_CLOEXEC);
     if (listen(s, 4) < 0) {
         fprintf(stderr, "listen(control socket): %s\n", strerror(errno));
         exit(1);
@@ -494,7 +605,7 @@
         }
     }
 
-    int fd = TEMP_FAILURE_RETRY(open(path, O_WRONLY | O_CREAT | O_TRUNC,
+    int fd = TEMP_FAILURE_RETRY(open(path, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC,
                                      S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));
     if (fd < 0) {
         fprintf(stderr, "%s: %s\n", path, strerror(errno));
@@ -550,7 +661,8 @@
     }
 
     /* create a new, empty traces.txt file to receive stack dumps */
-    int fd = open(traces_path, O_CREAT | O_WRONLY | O_TRUNC | O_NOFOLLOW, 0666);  /* -rw-rw-rw- */
+    int fd = TEMP_FAILURE_RETRY(open(traces_path, O_CREAT | O_WRONLY | O_TRUNC | O_NOFOLLOW | O_CLOEXEC,
+                                     0666));  /* -rw-rw-rw- */
     if (fd < 0) {
         fprintf(stderr, "%s: %s\n", traces_path, strerror(errno));
         return NULL;
@@ -600,7 +712,7 @@
         if (!strncmp(data, "/system/bin/app_process", strlen("/system/bin/app_process"))) {
             /* skip zygote -- it won't dump its stack anyway */
             snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
-            int cfd = open(path, O_RDONLY);
+            int cfd = TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_CLOEXEC));
             len = read(cfd, data, sizeof(data) - 1);
             close(cfd);
             if (len <= 0) {
@@ -612,7 +724,7 @@
             }
 
             ++dalvik_found;
-            int64_t start = nanotime();
+            uint64_t start = nanotime();
             if (kill(pid, SIGQUIT)) {
                 fprintf(stderr, "kill(%d, SIGQUIT): %s\n", pid, strerror(errno));
                 continue;
@@ -642,7 +754,7 @@
                 fprintf(stderr, "lseek: %s\n", strerror(errno));
             } else {
                 static uint16_t timeout_failures = 0;
-                int64_t start = nanotime();
+                uint64_t start = nanotime();
 
                 /* If 3 backtrace dumps fail in a row, consider debuggerd dead. */
                 if (timeout_failures == 3) {
@@ -685,7 +797,7 @@
 void dump_route_tables() {
     const char* const RT_TABLES_PATH = "/data/misc/net/rt_tables";
     dump_file("RT_TABLES", RT_TABLES_PATH);
-    FILE* fp = fopen(RT_TABLES_PATH, "r");
+    FILE* fp = fopen(RT_TABLES_PATH, "re");
     if (!fp) {
         printf("*** %s: %s\n", RT_TABLES_PATH, strerror(errno));
         return;
diff --git a/cmds/installd/Android.mk b/cmds/installd/Android.mk
index 8224e94..6dec7f6 100644
--- a/cmds/installd/Android.mk
+++ b/cmds/installd/Android.mk
@@ -1,6 +1,6 @@
 LOCAL_PATH := $(call my-dir)
 
-common_src_files := commands.c utils.c
+common_src_files := commands.cpp utils.cpp
 common_cflags := -Wall -Werror
 
 #
@@ -12,7 +12,12 @@
 LOCAL_MODULE_TAGS := eng tests
 LOCAL_SRC_FILES := $(common_src_files)
 LOCAL_CFLAGS := $(common_cflags)
+LOCAL_SHARED_LIBRARIES := \
+    libbase \
+    liblogwrap \
+
 LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
+LOCAL_CLANG := true
 include $(BUILD_STATIC_LIBRARY)
 
 #
@@ -23,8 +28,15 @@
 LOCAL_MODULE := installd
 LOCAL_MODULE_TAGS := optional
 LOCAL_CFLAGS := $(common_cflags)
-LOCAL_SRC_FILES := installd.c $(common_src_files)
-LOCAL_SHARED_LIBRARIES := libcutils liblog libselinux
+LOCAL_SRC_FILES := installd.cpp $(common_src_files)
+LOCAL_SHARED_LIBRARIES := \
+    libbase \
+    libcutils \
+    liblog \
+    liblogwrap \
+    libselinux \
+
 LOCAL_STATIC_LIBRARIES := libdiskusage
 LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
+LOCAL_CLANG := true
 include $(BUILD_EXECUTABLE)
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.cpp
similarity index 77%
rename from cmds/installd/commands.c
rename to cmds/installd/commands.cpp
index 386d2f3..6aa2bb4 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.cpp
@@ -14,13 +14,22 @@
 ** limitations under the License.
 */
 
+#include "installd.h"
+
+#include <base/stringprintf.h>
+#include <base/logging.h>
+#include <cutils/sched_policy.h>
+#include <diskusage/dirsize.h>
+#include <logwrap/logwrap.h>
+#include <system/thread_defs.h>
+#include <selinux/android.h>
+
 #include <inttypes.h>
 #include <sys/capability.h>
 #include <sys/file.h>
-#include "installd.h"
-#include <cutils/sched_policy.h>
-#include <diskusage/dirsize.h>
-#include <selinux/android.h>
+#include <unistd.h>
+
+using android::base::StringPrintf;
 
 /* Directory records that are used in execution of commands. */
 dir_rec_t android_data_dir;
@@ -29,34 +38,20 @@
 dir_rec_t android_app_private_dir;
 dir_rec_t android_app_lib_dir;
 dir_rec_t android_media_dir;
+dir_rec_t android_mnt_expand_dir;
 dir_rec_array_t android_system_dirs;
 
-int install(const char *pkgname, uid_t uid, gid_t gid, const char *seinfo)
-{
-    char pkgdir[PKG_PATH_MAX];
-    char libsymlink[PKG_PATH_MAX];
-    char applibdir[PKG_PATH_MAX];
-    struct stat libStat;
+static const char* kCpPath = "/system/bin/cp";
 
+int install(const char *uuid, const char *pkgname, uid_t uid, gid_t gid, const char *seinfo)
+{
     if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) {
         ALOGE("invalid uid/gid: %d %d\n", uid, gid);
         return -1;
     }
 
-    if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, 0)) {
-        ALOGE("cannot create package path\n");
-        return -1;
-    }
-
-    if (create_pkg_path(libsymlink, pkgname, PKG_LIB_POSTFIX, 0)) {
-        ALOGE("cannot create package lib symlink origin path\n");
-        return -1;
-    }
-
-    if (create_pkg_path_in_dir(applibdir, &android_app_lib_dir, pkgname, PKG_DIR_POSTFIX)) {
-        ALOGE("cannot create package lib symlink dest path\n");
-        return -1;
-    }
+    std::string _pkgdir(create_package_data_path(uuid, pkgname, 0));
+    const char* pkgdir = _pkgdir.c_str();
 
     if (mkdir(pkgdir, 0751) < 0) {
         ALOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno));
@@ -68,42 +63,14 @@
         return -1;
     }
 
-    if (lstat(libsymlink, &libStat) < 0) {
-        if (errno != ENOENT) {
-            ALOGE("couldn't stat lib dir: %s\n", strerror(errno));
-            return -1;
-        }
-    } else {
-        if (S_ISDIR(libStat.st_mode)) {
-            if (delete_dir_contents(libsymlink, 1, NULL) < 0) {
-                ALOGE("couldn't delete lib directory during install for: %s", libsymlink);
-                return -1;
-            }
-        } else if (S_ISLNK(libStat.st_mode)) {
-            if (unlink(libsymlink) < 0) {
-                ALOGE("couldn't unlink lib directory during install for: %s", libsymlink);
-                return -1;
-            }
-        }
-    }
-
     if (selinux_android_setfilecon(pkgdir, pkgname, seinfo, uid) < 0) {
         ALOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));
-        unlink(libsymlink);
         unlink(pkgdir);
         return -errno;
     }
 
-    if (symlink(applibdir, libsymlink) < 0) {
-        ALOGE("couldn't symlink directory '%s' -> '%s': %s\n", libsymlink, applibdir,
-                strerror(errno));
-        unlink(pkgdir);
-        return -1;
-    }
-
     if (chown(pkgdir, uid, gid) < 0) {
         ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));
-        unlink(libsymlink);
         unlink(pkgdir);
         return -1;
     }
@@ -111,12 +78,10 @@
     return 0;
 }
 
-int uninstall(const char *pkgname, userid_t userid)
+int uninstall(const char *uuid, const char *pkgname, userid_t userid)
 {
-    char pkgdir[PKG_PATH_MAX];
-
-    if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userid))
-        return -1;
+    std::string _pkgdir(create_package_data_path(uuid, pkgname, userid));
+    const char* pkgdir = _pkgdir.c_str();
 
     remove_profile_file(pkgname);
 
@@ -141,9 +106,8 @@
     return 0;
 }
 
-int fix_uid(const char *pkgname, uid_t uid, gid_t gid)
+int fix_uid(const char *uuid, const char *pkgname, uid_t uid, gid_t gid)
 {
-    char pkgdir[PKG_PATH_MAX];
     struct stat s;
 
     if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) {
@@ -151,10 +115,8 @@
         return -1;
     }
 
-    if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, 0)) {
-        ALOGE("cannot create package path\n");
-        return -1;
-    }
+    std::string _pkgdir(create_package_data_path(uuid, pkgname, 0));
+    const char* pkgdir = _pkgdir.c_str();
 
     if (stat(pkgdir, &s) < 0) return -1;
 
@@ -177,35 +139,18 @@
     return 0;
 }
 
-int delete_user_data(const char *pkgname, userid_t userid)
+int delete_user_data(const char *uuid, const char *pkgname, userid_t userid)
 {
-    char pkgdir[PKG_PATH_MAX];
-
-    if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userid))
-        return -1;
+    std::string _pkgdir(create_package_data_path(uuid, pkgname, userid));
+    const char* pkgdir = _pkgdir.c_str();
 
     return delete_dir_contents(pkgdir, 0, NULL);
 }
 
-int make_user_data(const char *pkgname, uid_t uid, userid_t userid, const char* seinfo)
+int make_user_data(const char *uuid, const char *pkgname, uid_t uid, userid_t userid, const char* seinfo)
 {
-    char pkgdir[PKG_PATH_MAX];
-    char applibdir[PKG_PATH_MAX];
-    char libsymlink[PKG_PATH_MAX];
-    struct stat libStat;
-
-    // Create the data dir for the package
-    if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userid)) {
-        return -1;
-    }
-    if (create_pkg_path(libsymlink, pkgname, PKG_LIB_POSTFIX, userid)) {
-        ALOGE("cannot create package lib symlink origin path\n");
-        return -1;
-    }
-    if (create_pkg_path_in_dir(applibdir, &android_app_lib_dir, pkgname, PKG_DIR_POSTFIX)) {
-        ALOGE("cannot create package lib symlink dest path\n");
-        return -1;
-    }
+    std::string _pkgdir(create_package_data_path(uuid, pkgname, userid));
+    const char* pkgdir = _pkgdir.c_str();
 
     if (mkdir(pkgdir, 0751) < 0) {
         ALOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno));
@@ -217,47 +162,14 @@
         return -errno;
     }
 
-    if (lstat(libsymlink, &libStat) < 0) {
-        if (errno != ENOENT) {
-            ALOGE("couldn't stat lib dir for non-primary: %s\n", strerror(errno));
-            unlink(pkgdir);
-            return -1;
-        }
-    } else {
-        if (S_ISDIR(libStat.st_mode)) {
-            if (delete_dir_contents(libsymlink, 1, NULL) < 0) {
-                ALOGE("couldn't delete lib directory during install for non-primary: %s",
-                        libsymlink);
-                unlink(pkgdir);
-                return -1;
-            }
-        } else if (S_ISLNK(libStat.st_mode)) {
-            if (unlink(libsymlink) < 0) {
-                ALOGE("couldn't unlink lib directory during install for non-primary: %s",
-                        libsymlink);
-                unlink(pkgdir);
-                return -1;
-            }
-        }
-    }
-
     if (selinux_android_setfilecon(pkgdir, pkgname, seinfo, uid) < 0) {
         ALOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));
-        unlink(libsymlink);
         unlink(pkgdir);
         return -errno;
     }
 
-    if (symlink(applibdir, libsymlink) < 0) {
-        ALOGE("couldn't symlink directory for non-primary '%s' -> '%s': %s\n", libsymlink,
-                applibdir, strerror(errno));
-        unlink(pkgdir);
-        return -1;
-    }
-
     if (chown(pkgdir, uid, uid) < 0) {
         ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));
-        unlink(libsymlink);
         unlink(pkgdir);
         return -errno;
     }
@@ -265,6 +177,80 @@
     return 0;
 }
 
+int move_user_data(const char *from_uuid, const char *to_uuid,
+        const char *package_name, appid_t appid, const char* seinfo) {
+    std::vector<userid_t> users = get_known_users(from_uuid);
+
+    // Copy package private data for all known users
+    for (auto user : users) {
+        std::string from(create_package_data_path(from_uuid, package_name, user));
+        std::string to(create_package_data_path(to_uuid, package_name, user));
+        std::string to_user(create_data_user_path(to_uuid, user));
+
+        // Data source may not exist for all users; that's okay
+        if (access(from.c_str(), F_OK) != 0) {
+            LOG(INFO) << "Missing source " << from;
+            continue;
+        }
+
+        std::string user_path(create_data_user_path(to_uuid, user));
+        if (fs_prepare_dir(user_path.c_str(), 0771, AID_SYSTEM, AID_SYSTEM) != 0) {
+            LOG(ERROR) << "Failed to prepare user target " << user_path;
+            goto fail;
+        }
+
+        uid_t uid = multiuser_get_uid(user, appid);
+        if (make_user_data(to_uuid, package_name, uid, user, seinfo) != 0) {
+            LOG(ERROR) << "Failed to create package target " << to;
+            goto fail;
+        }
+
+        char *argv[] = {
+            (char*) kCpPath,
+            (char*) "-F", /* delete any existing destination file first (--remove-destination) */
+            (char*) "-p", /* preserve timestamps, ownership, and permissions */
+            (char*) "-R", /* recurse into subdirectories (DEST must be a directory) */
+            (char*) "-P", /* Do not follow symlinks [default] */
+            (char*) "-d", /* don't dereference symlinks */
+            (char*) from.c_str(),
+            (char*) to_user.c_str()
+        };
+
+        LOG(DEBUG) << "Copying " << from << " to " << to;
+        int rc = android_fork_execvp(ARRAY_SIZE(argv), argv, NULL, false, true);
+
+        if (rc != 0) {
+            LOG(ERROR) << "Failed copying " << from << " to " << to
+                    << ": status " << rc;
+            goto fail;
+        }
+
+        if (restorecon_data(to_uuid, package_name, seinfo, uid) != 0) {
+            LOG(ERROR) << "Failed to restorecon " << to;
+            goto fail;
+        }
+    }
+
+    // Copy successful, so delete old data
+    for (auto user : users) {
+        std::string from(create_package_data_path(from_uuid, package_name, user));
+        if (delete_dir_contents(from.c_str(), 1, NULL) != 0) {
+            LOG(WARNING) << "Failed to delete " << from;
+        }
+    }
+    return 0;
+
+fail:
+    // Nuke everything we might have already copied
+    for (auto user : users) {
+        std::string to(create_package_data_path(to_uuid, package_name, user));
+        if (delete_dir_contents(to.c_str(), 1, NULL) != 0) {
+            LOG(WARNING) << "Failed to rollback " << to;
+        }
+    }
+    return -1;
+}
+
 int make_user_config(userid_t userid)
 {
     if (ensure_config_user_dirs(userid) == -1) {
@@ -274,49 +260,49 @@
     return 0;
 }
 
-int delete_user(userid_t userid)
+int delete_user(const char *uuid, userid_t userid)
 {
     int status = 0;
 
-    char data_path[PKG_PATH_MAX];
-    if ((create_user_path(data_path, userid) != 0)
-            || (delete_dir_contents(data_path, 1, NULL) != 0)) {
+    std::string data_path(create_data_user_path(uuid, userid));
+    if (delete_dir_contents(data_path.c_str(), 1, NULL) != 0) {
         status = -1;
     }
 
-    char media_path[PATH_MAX];
-    if ((create_user_media_path(media_path, userid) != 0)
-            || (delete_dir_contents(media_path, 1, NULL) != 0)) {
+    std::string media_path(create_data_media_path(uuid, userid));
+    if (delete_dir_contents(media_path.c_str(), 1, NULL) != 0) {
         status = -1;
     }
 
-    char config_path[PATH_MAX];
-    if ((create_user_config_path(config_path, userid) != 0)
-            || (delete_dir_contents(config_path, 1, NULL) != 0)) {
-        status = -1;
+    // Config paths only exist on internal storage
+    if (uuid == nullptr) {
+        char config_path[PATH_MAX];
+        if ((create_user_config_path(config_path, userid) != 0)
+                || (delete_dir_contents(config_path, 1, NULL) != 0)) {
+            status = -1;
+        }
     }
 
     return status;
 }
 
-int delete_cache(const char *pkgname, userid_t userid)
+int delete_cache(const char *uuid, const char *pkgname, userid_t userid)
 {
-    char cachedir[PKG_PATH_MAX];
-
-    if (create_pkg_path(cachedir, pkgname, CACHE_DIR_POSTFIX, userid))
-        return -1;
+    std::string _cachedir(
+            create_package_data_path(uuid, pkgname, userid) + CACHE_DIR_POSTFIX);
+    const char* cachedir = _cachedir.c_str();
 
     /* delete contents, not the directory, no exceptions */
     return delete_dir_contents(cachedir, 0, NULL);
 }
 
-int delete_code_cache(const char *pkgname, userid_t userid)
+int delete_code_cache(const char *uuid, const char *pkgname, userid_t userid)
 {
-    char codecachedir[PKG_PATH_MAX];
-    struct stat s;
+    std::string _codecachedir(
+            create_package_data_path(uuid, pkgname, userid) + CACHE_DIR_POSTFIX);
+    const char* codecachedir = _codecachedir.c_str();
 
-    if (create_pkg_path(codecachedir, pkgname, CODE_CACHE_DIR_POSTFIX, userid))
-        return -1;
+    struct stat s;
 
     /* it's okay if code cache is missing */
     if (lstat(codecachedir, &s) == -1 && errno == ENOENT) {
@@ -334,7 +320,7 @@
  * also require that apps constantly modify file metadata even
  * when just reading from the cache, which is pretty awful.
  */
-int free_cache(int64_t free_size)
+int free_cache(const char *uuid, int64_t free_size)
 {
     cache_t* cache;
     int64_t avail;
@@ -343,7 +329,9 @@
     char tmpdir[PATH_MAX];
     char *dirpos;
 
-    avail = data_disk_free();
+    std::string data_path(create_data_path(uuid));
+
+    avail = data_disk_free(data_path);
     if (avail < 0) return -1;
 
     ALOGI("free_cache(%" PRId64 ") avail %" PRId64 "\n", free_size, avail);
@@ -351,15 +339,16 @@
 
     cache = start_cache_collection();
 
-    // Collect cache files for primary user.
-    if (create_user_path(tmpdir, 0) == 0) {
-        //ALOGI("adding cache files from %s\n", tmpdir);
-        add_cache_files(cache, tmpdir, "cache");
+    // Special case for owner on internal storage
+    if (uuid == nullptr) {
+        std::string _tmpdir(create_data_user_path(nullptr, 0));
+        add_cache_files(cache, _tmpdir.c_str(), "cache");
     }
 
     // Search for other users and add any cache files from them.
-    snprintf(tmpdir, sizeof(tmpdir), "%s%s", android_data_dir.path,
-            SECONDARY_USER_PREFIX);
+    std::string _tmpdir(create_data_path(uuid) + "/" + SECONDARY_USER_PREFIX);
+    strcpy(tmpdir, _tmpdir.c_str());
+
     dirpos = tmpdir + strlen(tmpdir);
     d = opendir(tmpdir);
     if (d != NULL) {
@@ -411,10 +400,10 @@
         closedir(d);
     }
 
-    clear_cache_files(cache, free_size);
+    clear_cache_files(data_path, cache, free_size);
     finish_cache_collection(cache);
 
-    return data_disk_free() >= free_size ? 0 : -1;
+    return data_disk_free(data_path) >= free_size ? 0 : -1;
 }
 
 int move_dex(const char *src, const char *dst, const char *instruction_set)
@@ -465,7 +454,7 @@
     }
 }
 
-int get_size(const char *pkgname, userid_t userid, const char *apkpath,
+int get_size(const char *uuid, const char *pkgname, userid_t userid, const char *apkpath,
              const char *libdirpath, const char *fwdlock_apkpath, const char *asecpath,
              const char *instruction_set, int64_t *_codesize, int64_t *_datasize,
              int64_t *_cachesize, int64_t* _asecsize)
@@ -522,11 +511,10 @@
         }
     }
 
-    if (create_pkg_path(path, pkgname, PKG_DIR_POSTFIX, userid)) {
-        goto done;
-    }
+    std::string _pkgdir(create_package_data_path(uuid, pkgname, userid));
+    const char* pkgdir = _pkgdir.c_str();
 
-    d = opendir(path);
+    d = opendir(pkgdir);
     if (d == NULL) {
         goto done;
     }
@@ -696,9 +684,18 @@
     ALOGE("execv(%s) failed: %s\n", PATCHOAT_BIN, strerror(errno));
 }
 
+static bool check_boolean_property(const char* property_name, bool default_value = false) {
+    char tmp_property_value[PROPERTY_VALUE_MAX];
+    bool have_property = property_get(property_name, tmp_property_value, nullptr) > 0;
+    if (!have_property) {
+        return default_value;
+    }
+    return strcmp(tmp_property_value, "true") == 0;
+}
+
 static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name,
     const char* output_file_name, int swap_fd, const char *pkgname, const char *instruction_set,
-    bool vm_safe_mode)
+    bool vm_safe_mode, bool debuggable)
 {
     static const unsigned int MAX_INSTRUCTION_SET_LEN = 7;
 
@@ -721,6 +718,14 @@
     bool have_dex2oat_compiler_filter_flag = property_get("dalvik.vm.dex2oat-filter",
                                                           dex2oat_compiler_filter_flag, NULL) > 0;
 
+    char dex2oat_threads_buf[PROPERTY_VALUE_MAX];
+    bool have_dex2oat_threads_flag = property_get("dalvik.vm.dex2oat-threads", dex2oat_threads_buf,
+                                                  NULL) > 0;
+    char dex2oat_threads_arg[PROPERTY_VALUE_MAX + 2];
+    if (have_dex2oat_threads_flag) {
+        sprintf(dex2oat_threads_arg, "-j%s", dex2oat_threads_buf);
+    }
+
     char dex2oat_isa_features_key[PROPERTY_KEY_MAX];
     sprintf(dex2oat_isa_features_key, "dalvik.vm.isa.%s.features", instruction_set);
     char dex2oat_isa_features[PROPERTY_VALUE_MAX];
@@ -748,6 +753,9 @@
                              (strcmp(vold_decrypt, "trigger_restart_min_framework") == 0 ||
                              (strcmp(vold_decrypt, "1") == 0)));
 
+    bool use_jit = check_boolean_property("debug.usejit");
+    bool gen_cfi = check_boolean_property("debug.gencfi");
+
     static const char* DEX2OAT_BIN = "/system/bin/dex2oat";
 
     static const char* RUNTIME_ARG = "--runtime-arg";
@@ -812,10 +820,20 @@
     } else if (vm_safe_mode) {
         strcpy(dex2oat_compiler_filter_arg, "--compiler-filter=interpret-only");
         have_dex2oat_compiler_filter_flag = true;
+    } else if (use_jit) {
+        strcpy(dex2oat_compiler_filter_arg, "--compiler-filter=verify-at-runtime");
+        have_dex2oat_compiler_filter_flag = true;
     } else if (have_dex2oat_compiler_filter_flag) {
         sprintf(dex2oat_compiler_filter_arg, "--compiler-filter=%s", dex2oat_compiler_filter_flag);
     }
 
+    // Check whether all apps should be compiled debuggable.
+    if (!debuggable) {
+        debuggable =
+                (property_get("dalvik.vm.always_debuggable", prop_buf, "0") > 0) &&
+                (prop_buf[0] == '1');
+    }
+
     ALOGV("Running %s in=%s out=%s\n", DEX2OAT_BIN, input_file_name, output_file_name);
 
     const char* argv[7  // program name, mandatory arguments and the final NULL
@@ -826,8 +844,11 @@
                      + (have_dex2oat_Xms_flag ? 2 : 0)
                      + (have_dex2oat_Xmx_flag ? 2 : 0)
                      + (have_dex2oat_compiler_filter_flag ? 1 : 0)
+                     + (have_dex2oat_threads_flag ? 1 : 0)
                      + (have_dex2oat_swap_fd ? 1 : 0)
                      + (have_dex2oat_relocation_skip_flag ? 2 : 0)
+                     + (gen_cfi ? 1 : 0)
+                     + (debuggable ? 1 : 0)
                      + dex2oat_flags_count];
     int i = 0;
     argv[i++] = DEX2OAT_BIN;
@@ -859,9 +880,18 @@
     if (have_dex2oat_compiler_filter_flag) {
         argv[i++] = dex2oat_compiler_filter_arg;
     }
+    if (have_dex2oat_threads_flag) {
+        argv[i++] = dex2oat_threads_arg;
+    }
     if (have_dex2oat_swap_fd) {
         argv[i++] = dex2oat_swap_fd;
     }
+    if (gen_cfi) {
+        argv[i++] = "--include-cfi";
+    }
+    if (debuggable) {
+        argv[i++] = "--debuggable";
+    }
     if (dex2oat_flags_count) {
         i += split(dex2oat_flags, argv + i);
     }
@@ -919,15 +949,50 @@
     return (strcmp(low_mem_buf, "true") == 0);
 }
 
+/*
+ * Computes the odex file for the given apk_path and instruction_set.
+ * /system/framework/whatever.jar -> /system/framework/oat/<isa>/whatever.odex
+ *
+ * Returns false if it failed to determine the odex file path.
+ */
+static bool calculate_odex_file_path(char path[PKG_PATH_MAX],
+                                     const char *apk_path,
+                                     const char *instruction_set)
+{
+    if (strlen(apk_path) + strlen("oat/") + strlen(instruction_set)
+        + strlen("/") + strlen("odex") + 1 > PKG_PATH_MAX) {
+      ALOGE("apk_path '%s' may be too long to form odex file path.\n", apk_path);
+      return false;
+    }
+
+    strcpy(path, apk_path);
+    char *end = strrchr(path, '/');
+    if (end == NULL) {
+      ALOGE("apk_path '%s' has no '/'s in it?!\n", apk_path);
+      return false;
+    }
+    const char *apk_end = apk_path + (end - path); // strrchr(apk_path, '/');
+
+    strcpy(end + 1, "oat/");       // path = /system/framework/oat/\0
+    strcat(path, instruction_set); // path = /system/framework/oat/<isa>\0
+    strcat(path, apk_end);         // path = /system/framework/oat/<isa>/whatever.jar\0
+    end = strrchr(path, '.');
+    if (end == NULL) {
+      ALOGE("apk_path '%s' has no extension.\n", apk_path);
+      return false;
+    }
+    strcpy(end + 1, "odex");
+    return true;
+}
+
 int dexopt(const char *apk_path, uid_t uid, bool is_public,
-           const char *pkgname, const char *instruction_set,
-           bool vm_safe_mode, bool is_patchoat)
+           const char *pkgname, const char *instruction_set, int dexopt_needed,
+           bool vm_safe_mode, bool debuggable, const char* oat_dir)
 {
     struct utimbuf ut;
-    struct stat input_stat, dex_stat;
+    struct stat input_stat;
     char out_path[PKG_PATH_MAX];
     char swap_file_name[PKG_PATH_MAX];
-    char *end;
     const char *input_file;
     char in_odex_path[PKG_PATH_MAX];
     int res, input_fd=-1, out_fd=-1, swap_fd=-1;
@@ -936,46 +1001,43 @@
     // Note: the cache path will require an additional 5 bytes for ".swap", but we'll try to run
     // without a swap file, if necessary.
     if (strlen(apk_path) >= (PKG_PATH_MAX - 8)) {
+        ALOGE("apk_path too long '%s'\n", apk_path);
         return -1;
     }
 
-    /* Before anything else: is there a .odex file?  If so, we have
-     * precompiled the apk and there is nothing to do here.
-     *
-     * We skip this if we are doing a patchoat.
-     */
-    strcpy(out_path, apk_path);
-    end = strrchr(out_path, '.');
-    if (end != NULL && !is_patchoat) {
-        strcpy(end, ".odex");
-        if (stat(out_path, &dex_stat) == 0) {
-            return 0;
-        }
-    }
-
-    if (create_cache_path(out_path, apk_path, instruction_set)) {
-        return -1;
-    }
-
-    if (is_patchoat) {
-        /* /system/framework/whatever.jar -> /system/framework/<isa>/whatever.odex */
-        strcpy(in_odex_path, apk_path);
-        end = strrchr(in_odex_path, '/');
-        if (end == NULL) {
-            ALOGE("apk_path '%s' has no '/'s in it?!\n", apk_path);
+    if (oat_dir != NULL && oat_dir[0] != '!') {
+        if (validate_apk_path(oat_dir)) {
+            ALOGE("invalid oat_dir '%s'\n", oat_dir);
             return -1;
         }
-        const char *apk_end = apk_path + (end - in_odex_path); // strrchr(apk_path, '/');
-        strcpy(end + 1, instruction_set); // in_odex_path now is /system/framework/<isa>\0
-        strcat(in_odex_path, apk_end);
-        end = strrchr(in_odex_path, '.');
-        if (end == NULL) {
+        if (calculate_oat_file_path(out_path, oat_dir, apk_path, instruction_set)) {
             return -1;
         }
-        strcpy(end + 1, "odex");
-        input_file = in_odex_path;
     } else {
-        input_file = apk_path;
+        if (create_cache_path(out_path, apk_path, instruction_set)) {
+            return -1;
+        }
+    }
+
+    switch (dexopt_needed) {
+        case DEXOPT_DEX2OAT_NEEDED:
+            input_file = apk_path;
+            break;
+
+        case DEXOPT_PATCHOAT_NEEDED:
+            if (!calculate_odex_file_path(in_odex_path, apk_path, instruction_set)) {
+                return -1;
+            }
+            input_file = in_odex_path;
+            break;
+
+        case DEXOPT_SELF_PATCHOAT_NEEDED:
+            input_file = out_path;
+            break;
+
+        default:
+            ALOGE("Invalid dexopt needed: %d\n", dexopt_needed);
+            exit(72);
     }
 
     memset(&input_stat, 0, sizeof(input_stat));
@@ -1010,7 +1072,7 @@
     }
 
     // Create a swap file if necessary.
-    if (!is_patchoat && ShouldUseSwapFileForDexopt()) {
+    if (ShouldUseSwapFileForDexopt()) {
         // Make sure there really is enough space.
         size_t out_len = strlen(out_path);
         if (out_len + strlen(".swap") + 1 <= PKG_PATH_MAX) {
@@ -1060,16 +1122,30 @@
             ALOGE("set_sched_policy failed: %s\n", strerror(errno));
             exit(70);
         }
+        if (setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND) < 0) {
+            ALOGE("setpriority failed: %s\n", strerror(errno));
+            exit(71);
+        }
         if (flock(out_fd, LOCK_EX | LOCK_NB) != 0) {
             ALOGE("flock(%s) failed: %s\n", out_path, strerror(errno));
             exit(67);
         }
 
-        if (is_patchoat) {
+        if (dexopt_needed == DEXOPT_PATCHOAT_NEEDED
+            || dexopt_needed == DEXOPT_SELF_PATCHOAT_NEEDED) {
             run_patchoat(input_fd, out_fd, input_file, out_path, pkgname, instruction_set);
+        } else if (dexopt_needed == DEXOPT_DEX2OAT_NEEDED) {
+            const char *input_file_name = strrchr(input_file, '/');
+            if (input_file_name == NULL) {
+                input_file_name = input_file;
+            } else {
+                input_file_name++;
+            }
+            run_dex2oat(input_fd, out_fd, input_file_name, out_path, swap_fd, pkgname,
+                        instruction_set, vm_safe_mode, debuggable);
         } else {
-            run_dex2oat(input_fd, out_fd, input_file, out_path, swap_fd, pkgname, instruction_set,
-                        vm_safe_mode);
+            ALOGE("Invalid dexopt needed: %d\n", dexopt_needed);
+            exit(73);
         }
         exit(68);   /* only get here on exec failure */
     } else {
@@ -1379,21 +1455,16 @@
     return 0;
 }
 
-int linklib(const char* pkgname, const char* asecLibDir, int userId)
+int linklib(const char* uuid, const char* pkgname, const char* asecLibDir, int userId)
 {
-    char pkgdir[PKG_PATH_MAX];
-    char libsymlink[PKG_PATH_MAX];
     struct stat s, libStat;
     int rc = 0;
 
-    if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userId)) {
-        ALOGE("cannot create package path\n");
-        return -1;
-    }
-    if (create_pkg_path(libsymlink, pkgname, PKG_LIB_POSTFIX, userId)) {
-        ALOGE("cannot create package lib symlink origin path\n");
-        return -1;
-    }
+    std::string _pkgdir(create_package_data_path(uuid, pkgname, userId));
+    std::string _libsymlink(_pkgdir + PKG_LIB_POSTFIX);
+
+    const char* pkgdir = _pkgdir.c_str();
+    const char* libsymlink = _libsymlink.c_str();
 
     if (stat(pkgdir, &s) < 0) return -1;
 
@@ -1562,14 +1633,12 @@
     return -1;
 }
 
-int restorecon_data(const char* pkgName, const char* seinfo, uid_t uid)
+int restorecon_data(const char* uuid, const char* pkgName,
+                    const char* seinfo, uid_t uid)
 {
     struct dirent *entry;
     DIR *d;
     struct stat s;
-    char *userdir;
-    char *primarydir;
-    char *pkgdir;
     int ret = 0;
 
     // SELINUX_ANDROID_RESTORECON_DATADATA flag is set by libselinux. Not needed here.
@@ -1580,26 +1649,20 @@
         return -1;
     }
 
-    if (asprintf(&primarydir, "%s%s%s", android_data_dir.path, PRIMARY_USER_PREFIX, pkgName) < 0) {
-        return -1;
-    }
+    // Special case for owner on internal storage
+    if (uuid == nullptr) {
+        std::string path(create_package_data_path(nullptr, pkgName, 0));
 
-    // Relabel for primary user.
-    if (selinux_android_restorecon_pkgdir(primarydir, seinfo, uid, flags) < 0) {
-        ALOGE("restorecon failed for %s: %s\n", primarydir, strerror(errno));
-        ret |= -1;
-    }
-
-    if (asprintf(&userdir, "%s%s", android_data_dir.path, SECONDARY_USER_PREFIX) < 0) {
-        free(primarydir);
-        return -1;
+        if (selinux_android_restorecon_pkgdir(path.c_str(), seinfo, uid, flags) < 0) {
+            PLOG(ERROR) << "restorecon failed for " << path;
+            ret |= -1;
+        }
     }
 
     // Relabel package directory for all secondary users.
-    d = opendir(userdir);
+    std::string userdir(create_data_path(uuid) + "/" + SECONDARY_USER_PREFIX);
+    d = opendir(userdir.c_str());
     if (d == NULL) {
-        free(primarydir);
-        free(userdir);
         return -1;
     }
 
@@ -1620,25 +1683,75 @@
             continue;
         }
 
-        if (asprintf(&pkgdir, "%s%s/%s", userdir, user, pkgName) < 0) {
+        std::string pkgdir(StringPrintf("%s%s/%s", userdir.c_str(), user, pkgName));
+        if (stat(pkgdir.c_str(), &s) < 0) {
             continue;
         }
 
-        if (stat(pkgdir, &s) < 0) {
-            free(pkgdir);
-            continue;
-        }
-
-        if (selinux_android_restorecon_pkgdir(pkgdir, seinfo, s.st_uid, flags) < 0) {
-            ALOGE("restorecon failed for %s: %s\n", pkgdir, strerror(errno));
+        if (selinux_android_restorecon_pkgdir(pkgdir.c_str(), seinfo, s.st_uid, flags) < 0) {
+            PLOG(ERROR) << "restorecon failed for " << pkgdir;
             ret |= -1;
         }
-        free(pkgdir);
     }
 
     closedir(d);
-    free(primarydir);
-    free(userdir);
     return ret;
 }
 
+int create_oat_dir(const char* oat_dir, const char* instruction_set)
+{
+    char oat_instr_dir[PKG_PATH_MAX];
+
+    if (validate_apk_path(oat_dir)) {
+        ALOGE("invalid apk path '%s' (bad prefix)\n", oat_dir);
+        return -1;
+    }
+    if (fs_prepare_dir(oat_dir, S_IRWXU | S_IRWXG | S_IXOTH, AID_SYSTEM, AID_INSTALL)) {
+        return -1;
+    }
+    if (selinux_android_restorecon(oat_dir, 0)) {
+        ALOGE("cannot restorecon dir '%s': %s\n", oat_dir, strerror(errno));
+        return -1;
+    }
+    snprintf(oat_instr_dir, PKG_PATH_MAX, "%s/%s", oat_dir, instruction_set);
+    if (fs_prepare_dir(oat_instr_dir, S_IRWXU | S_IRWXG | S_IXOTH, AID_SYSTEM, AID_INSTALL)) {
+        return -1;
+    }
+    return 0;
+}
+
+int rm_package_dir(const char* apk_path)
+{
+    if (validate_apk_path(apk_path)) {
+        ALOGE("invalid apk path '%s' (bad prefix)\n", apk_path);
+        return -1;
+    }
+    return delete_dir_contents(apk_path, 1 /* also_delete_dir */ , NULL /* exclusion_predicate */);
+}
+
+int calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path,
+        const char *instruction_set) {
+    char *file_name_start;
+    char *file_name_end;
+
+    file_name_start = strrchr(apk_path, '/');
+    if (file_name_start == NULL) {
+         ALOGE("apk_path '%s' has no '/'s in it\n", apk_path);
+        return -1;
+    }
+    file_name_end = strrchr(apk_path, '.');
+    if (file_name_end < file_name_start) {
+        ALOGE("apk_path '%s' has no extension\n", apk_path);
+        return -1;
+    }
+
+    // Calculate file_name
+    int file_name_len = file_name_end - file_name_start - 1;
+    char file_name[file_name_len + 1];
+    memcpy(file_name, file_name_start + 1, file_name_len);
+    file_name[file_name_len] = '\0';
+
+    // <apk_parent_dir>/oat/<isa>/<file_name>.odex
+    snprintf(path, PKG_PATH_MAX, "%s/%s/%s.odex", oat_dir, instruction_set, file_name);
+    return 0;
+}
diff --git a/cmds/installd/installd.c b/cmds/installd/installd.cpp
similarity index 81%
rename from cmds/installd/installd.c
rename to cmds/installd/installd.cpp
index 4dd83ae..3a86181 100644
--- a/cmds/installd/installd.c
+++ b/cmds/installd/installd.cpp
@@ -1,31 +1,40 @@
 /*
 ** Copyright 2008, 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 
+** 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 
+**     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 
+** 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 "installd.h"
+
+#include <base/logging.h>
+
 #include <sys/capability.h>
 #include <sys/prctl.h>
 #include <selinux/android.h>
 #include <selinux/avc.h>
 
-#include "installd.h"
-
-
 #define BUFFER_MAX    1024  /* input buffer for commands */
-#define TOKEN_MAX     8     /* max number of arguments in buffer */
+#define TOKEN_MAX     16    /* max number of arguments in buffer */
 #define REPLY_MAX     256   /* largest reply allowed */
 
+static char* parse_null(char* arg) {
+    if (strcmp(arg, "!") == 0) {
+        return nullptr;
+    } else {
+        return arg;
+    }
+}
+
 static int do_ping(char **arg __unused, char reply[REPLY_MAX] __unused)
 {
     return 0;
@@ -33,13 +42,15 @@
 
 static int do_install(char **arg, char reply[REPLY_MAX] __unused)
 {
-    return install(arg[0], atoi(arg[1]), atoi(arg[2]), arg[3]); /* pkgname, uid, gid, seinfo */
+    return install(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]), arg[4]); /* uuid, pkgname, uid, gid, seinfo */
 }
 
 static int do_dexopt(char **arg, char reply[REPLY_MAX] __unused)
 {
-    /* apk_path, uid, is_public, pkgname, instruction_set, vm_safe_mode, should_relocate */
-    return dexopt(arg[0], atoi(arg[1]), atoi(arg[2]), arg[3], arg[4], atoi(arg[5]), 0);
+    /* apk_path, uid, is_public, pkgname, instruction_set,
+     * dexopt_needed, vm_safe_mode, debuggable, oat_dir */
+    return dexopt(arg[0], atoi(arg[1]), atoi(arg[2]), arg[3], arg[4], atoi(arg[5]),
+                  atoi(arg[6]), atoi(arg[7]), arg[8]);
 }
 
 static int do_mark_boot_complete(char **arg, char reply[REPLY_MAX] __unused)
@@ -59,7 +70,7 @@
 
 static int do_remove(char **arg, char reply[REPLY_MAX] __unused)
 {
-    return uninstall(arg[0], atoi(arg[1])); /* pkgname, userid */
+    return uninstall(parse_null(arg[0]), arg[1], atoi(arg[2])); /* uuid, pkgname, userid */
 }
 
 static int do_rename(char **arg, char reply[REPLY_MAX] __unused)
@@ -69,22 +80,22 @@
 
 static int do_fixuid(char **arg, char reply[REPLY_MAX] __unused)
 {
-    return fix_uid(arg[0], atoi(arg[1]), atoi(arg[2])); /* pkgname, uid, gid */
+    return fix_uid(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3])); /* uuid, pkgname, uid, gid */
 }
 
 static int do_free_cache(char **arg, char reply[REPLY_MAX] __unused) /* TODO int:free_size */
 {
-    return free_cache((int64_t)atoll(arg[0])); /* free_size */
+    return free_cache(parse_null(arg[0]), (int64_t)atoll(arg[1])); /* uuid, free_size */
 }
 
 static int do_rm_cache(char **arg, char reply[REPLY_MAX] __unused)
 {
-    return delete_cache(arg[0], atoi(arg[1])); /* pkgname, userid */
+    return delete_cache(parse_null(arg[0]), arg[1], atoi(arg[2])); /* uuid, pkgname, userid */
 }
 
 static int do_rm_code_cache(char **arg, char reply[REPLY_MAX] __unused)
 {
-    return delete_code_cache(arg[0], atoi(arg[1])); /* pkgname, userid */
+    return delete_code_cache(parse_null(arg[0]), arg[1], atoi(arg[2])); /* uuid, pkgname, userid */
 }
 
 static int do_get_size(char **arg, char reply[REPLY_MAX])
@@ -95,9 +106,9 @@
     int64_t asecsize = 0;
     int res = 0;
 
-        /* pkgdir, userid, apkpath */
-    res = get_size(arg[0], atoi(arg[1]), arg[2], arg[3], arg[4], arg[5],
-            arg[6], &codesize, &datasize, &cachesize, &asecsize);
+        /* uuid, pkgdir, userid, apkpath */
+    res = get_size(parse_null(arg[0]), arg[1], atoi(arg[2]), arg[3], arg[4], arg[5], arg[6],
+            arg[7], &codesize, &datasize, &cachesize, &asecsize);
 
     /*
      * Each int64_t can take up 22 characters printed out. Make sure it
@@ -110,13 +121,19 @@
 
 static int do_rm_user_data(char **arg, char reply[REPLY_MAX] __unused)
 {
-    return delete_user_data(arg[0], atoi(arg[1])); /* pkgname, userid */
+    return delete_user_data(parse_null(arg[0]), arg[1], atoi(arg[2])); /* uuid, pkgname, userid */
+}
+
+static int do_mv_user_data(char **arg, char reply[REPLY_MAX] __unused)
+{
+    // from_uuid, to_uuid, pkgname, appid, seinfo
+    return move_user_data(parse_null(arg[0]), parse_null(arg[1]), arg[2], atoi(arg[3]), arg[4]);
 }
 
 static int do_mk_user_data(char **arg, char reply[REPLY_MAX] __unused)
 {
-    return make_user_data(arg[0], atoi(arg[1]), atoi(arg[2]), arg[3]);
-                             /* pkgname, uid, userid, seinfo */
+    return make_user_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]), arg[4]);
+                             /* uuid, pkgname, uid, userid, seinfo */
 }
 
 static int do_mk_user_config(char **arg, char reply[REPLY_MAX] __unused)
@@ -126,7 +143,7 @@
 
 static int do_rm_user(char **arg, char reply[REPLY_MAX] __unused)
 {
-    return delete_user(atoi(arg[0])); /* userid */
+    return delete_user(parse_null(arg[0]), atoi(arg[1])); /* uuid, userid */
 }
 
 static int do_movefiles(char **arg __unused, char reply[REPLY_MAX] __unused)
@@ -136,7 +153,7 @@
 
 static int do_linklib(char **arg, char reply[REPLY_MAX] __unused)
 {
-    return linklib(arg[0], arg[1], atoi(arg[2]));
+    return linklib(parse_null(arg[0]), arg[1], arg[2], atoi(arg[3]));
 }
 
 static int do_idmap(char **arg, char reply[REPLY_MAX] __unused)
@@ -146,13 +163,20 @@
 
 static int do_restorecon_data(char **arg, char reply[REPLY_MAX] __attribute__((unused)))
 {
-    return restorecon_data(arg[0], arg[1], atoi(arg[2]));
-                             /* pkgName, seinfo, uid*/
+    return restorecon_data(parse_null(arg[0]), arg[1], arg[2], atoi(arg[3]));
+                             /* uuid, pkgName, seinfo, uid*/
 }
 
-static int do_patchoat(char **arg, char reply[REPLY_MAX] __unused) {
-    /* apk_path, uid, is_public, pkgname, instruction_set, vm_safe_mode, should_relocate */
-    return dexopt(arg[0], atoi(arg[1]), atoi(arg[2]), arg[3], arg[4], 0, 1);
+static int do_create_oat_dir(char **arg, char reply[REPLY_MAX] __unused)
+{
+    /* oat_dir, instruction_set */
+    return create_oat_dir(arg[0], arg[1]);
+}
+
+static int do_rm_package_dir(char **arg, char reply[REPLY_MAX] __unused)
+{
+    /* oat_dir */
+    return rm_package_dir(arg[0]);
 }
 
 struct cmdinfo {
@@ -163,32 +187,34 @@
 
 struct cmdinfo cmds[] = {
     { "ping",                 0, do_ping },
-    { "install",              4, do_install },
-    { "dexopt",               6, do_dexopt },
+    { "install",              5, do_install },
+    { "dexopt",               9, do_dexopt },
     { "markbootcomplete",     1, do_mark_boot_complete },
     { "movedex",              3, do_move_dex },
     { "rmdex",                2, do_rm_dex },
-    { "remove",               2, do_remove },
+    { "remove",               3, do_remove },
     { "rename",               2, do_rename },
-    { "fixuid",               3, do_fixuid },
-    { "freecache",            1, do_free_cache },
-    { "rmcache",              2, do_rm_cache },
-    { "rmcodecache",          2, do_rm_code_cache },
-    { "getsize",              7, do_get_size },
-    { "rmuserdata",           2, do_rm_user_data },
+    { "fixuid",               4, do_fixuid },
+    { "freecache",            2, do_free_cache },
+    { "rmcache",              3, do_rm_cache },
+    { "rmcodecache",          3, do_rm_code_cache },
+    { "getsize",              8, do_get_size },
+    { "rmuserdata",           3, do_rm_user_data },
+    { "mvuserdata",           5, do_mv_user_data },
     { "movefiles",            0, do_movefiles },
-    { "linklib",              3, do_linklib },
-    { "mkuserdata",           4, do_mk_user_data },
+    { "linklib",              4, do_linklib },
+    { "mkuserdata",           5, do_mk_user_data },
     { "mkuserconfig",         1, do_mk_user_config },
-    { "rmuser",               1, do_rm_user },
+    { "rmuser",               2, do_rm_user },
     { "idmap",                3, do_idmap },
-    { "restorecondata",       3, do_restorecon_data },
-    { "patchoat",             5, do_patchoat },
+    { "restorecondata",       4, do_restorecon_data },
+    { "createoatdir",         2, do_create_oat_dir },
+    { "rmpackagedir",         1, do_rm_package_dir},
 };
 
 static int readx(int s, void *_buf, int count)
 {
-    char *buf = _buf;
+    char *buf = (char *) _buf;
     int n = 0, r;
     if (count < 0) return -1;
     while (n < count) {
@@ -209,7 +235,7 @@
 
 static int writex(int s, const void *_buf, int count)
 {
-    const char *buf = _buf;
+    const char *buf = (const char *) _buf;
     int n = 0, r;
     if (count < 0) return -1;
     while (n < count) {
@@ -335,10 +361,15 @@
         return -1;
     }
 
+    // Get the android external app directory.
+    if (get_path_from_string(&android_mnt_expand_dir, "/mnt/expand/") < 0) {
+        return -1;
+    }
+
     // Take note of the system and vendor directories.
     android_system_dirs.count = 4;
 
-    android_system_dirs.dirs = calloc(android_system_dirs.count, sizeof(dir_rec_t));
+    android_system_dirs.dirs = (dir_rec_t*) calloc(android_system_dirs.count, sizeof(dir_rec_t));
     if (android_system_dirs.dirs == NULL) {
         ALOGE("Couldn't allocate array for dirs; aborting\n");
         return -1;
@@ -356,10 +387,10 @@
     android_system_dirs.dirs[1].path = build_string2(android_root_dir.path, PRIV_APP_SUBDIR);
     android_system_dirs.dirs[1].len = strlen(android_system_dirs.dirs[1].path);
 
-    android_system_dirs.dirs[2].path = "/vendor/app/";
+    android_system_dirs.dirs[2].path = strdup("/vendor/app/");
     android_system_dirs.dirs[2].len = strlen(android_system_dirs.dirs[2].path);
 
-    android_system_dirs.dirs[3].path = "/oem/app/";
+    android_system_dirs.dirs[3].path = strdup("/oem/app/");
     android_system_dirs.dirs[3].len = strlen(android_system_dirs.dirs[3].path);
 
     return 0;
@@ -503,7 +534,7 @@
         version = 2;
     }
 
-    if (ensure_media_user_dirs(0) == -1) {
+    if (ensure_media_user_dirs(nullptr, 0) == -1) {
         ALOGE("Failed to setup media for user 0");
         goto fail;
     }
@@ -598,46 +629,6 @@
     return res;
 }
 
-static void drop_privileges() {
-    if (prctl(PR_SET_KEEPCAPS, 1) < 0) {
-        ALOGE("prctl(PR_SET_KEEPCAPS) failed: %s\n", strerror(errno));
-        exit(1);
-    }
-
-    if (setgid(AID_INSTALL) < 0) {
-        ALOGE("setgid() can't drop privileges; exiting.\n");
-        exit(1);
-    }
-
-    if (setuid(AID_INSTALL) < 0) {
-        ALOGE("setuid() can't drop privileges; exiting.\n");
-        exit(1);
-    }
-
-    struct __user_cap_header_struct capheader;
-    struct __user_cap_data_struct capdata[2];
-    memset(&capheader, 0, sizeof(capheader));
-    memset(&capdata, 0, sizeof(capdata));
-    capheader.version = _LINUX_CAPABILITY_VERSION_3;
-    capheader.pid = 0;
-
-    capdata[CAP_TO_INDEX(CAP_DAC_OVERRIDE)].permitted |= CAP_TO_MASK(CAP_DAC_OVERRIDE);
-    capdata[CAP_TO_INDEX(CAP_CHOWN)].permitted        |= CAP_TO_MASK(CAP_CHOWN);
-    capdata[CAP_TO_INDEX(CAP_SETUID)].permitted       |= CAP_TO_MASK(CAP_SETUID);
-    capdata[CAP_TO_INDEX(CAP_SETGID)].permitted       |= CAP_TO_MASK(CAP_SETGID);
-    capdata[CAP_TO_INDEX(CAP_FOWNER)].permitted       |= CAP_TO_MASK(CAP_FOWNER);
-
-    capdata[0].effective = capdata[0].permitted;
-    capdata[1].effective = capdata[1].permitted;
-    capdata[0].inheritable = 0;
-    capdata[1].inheritable = 0;
-
-    if (capset(&capheader, &capdata[0]) < 0) {
-        ALOGE("capset failed: %s\n", strerror(errno));
-        exit(1);
-    }
-}
-
 static int log_callback(int type, const char *fmt, ...) {
     va_list ap;
     int priority;
@@ -659,13 +650,16 @@
     return 0;
 }
 
-int main(const int argc __unused, const char *argv[] __unused) {
+int main(const int argc __unused, char *argv[]) {
     char buf[BUFFER_MAX];
     struct sockaddr addr;
     socklen_t alen;
     int lsocket, s;
     int selinux_enabled = (is_selinux_enabled() > 0);
 
+    setenv("ANDROID_LOG_TAGS", "*:v", 1);
+    android::base::InitLogging(argv);
+
     ALOGI("installd firing up\n");
 
     union selinux_callback cb;
@@ -687,8 +681,6 @@
         exit(1);
     }
 
-    drop_privileges();
-
     lsocket = android_get_control_socket(SOCKET_PATH);
     if (lsocket < 0) {
         ALOGE("Failed to get socket from environment: %s\n", strerror(errno));
diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h
index a9a1999..f31bf4f 100644
--- a/cmds/installd/installd.h
+++ b/cmds/installd/installd.h
@@ -31,6 +31,8 @@
 #include <sys/socket.h>
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <string>
+#include <vector>
 
 #include <cutils/fs.h>
 #include <cutils/sockets.h>
@@ -83,6 +85,13 @@
 #define PKG_NAME_MAX  128   /* largest allowed package name */
 #define PKG_PATH_MAX  256   /* max size of any path we use */
 
+/* dexopt needed flags matching those in dalvik.system.DexFile */
+#define DEXOPT_DEX2OAT_NEEDED        1
+#define DEXOPT_PATCHOAT_NEEDED       2
+#define DEXOPT_SELF_PATCHOAT_NEEDED  3
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
+
 /* data structures */
 
 typedef struct {
@@ -101,6 +110,7 @@
 extern dir_rec_t android_data_dir;
 extern dir_rec_t android_asec_dir;
 extern dir_rec_t android_media_dir;
+extern dir_rec_t android_mnt_expand_dir;
 extern dir_rec_array_t android_system_dirs;
 
 typedef struct cache_dir_struct {
@@ -132,20 +142,22 @@
 
 /* util.c */
 
-int create_pkg_path_in_dir(char path[PKG_PATH_MAX],
-                                const dir_rec_t* dir,
-                                const char* pkgname,
-                                const char* postfix);
+// TODO: rename to create_data_user_package_path
+std::string create_package_data_path(const char* volume_uuid,
+        const char* package_name, userid_t user);
 
 int create_pkg_path(char path[PKG_PATH_MAX],
                     const char *pkgname,
                     const char *postfix,
                     userid_t userid);
 
-int create_user_path(char path[PKG_PATH_MAX],
-                    userid_t userid);
+std::string create_data_path(const char* volume_uuid);
 
-int create_user_media_path(char path[PKG_PATH_MAX], userid_t userid);
+std::string create_data_user_path(const char* volume_uuid, userid_t userid);
+
+std::string create_data_media_path(const char* volume_uuid, userid_t userid);
+
+std::vector<userid_t> get_known_users(const char* volume_uuid);
 
 int create_user_config_path(char path[PKG_PATH_MAX], userid_t userid);
 
@@ -169,13 +181,13 @@
 
 int lookup_media_dir(char basepath[PATH_MAX], const char *dir);
 
-int64_t data_disk_free();
+int64_t data_disk_free(const std::string& data_path);
 
 cache_t* start_cache_collection();
 
 void add_cache_files(cache_t* cache, const char *basepath, const char *cachedir);
 
-void clear_cache_files(cache_t* cache, int64_t free_size);
+void clear_cache_files(const std::string& data_path, cache_t* cache, int64_t free_size);
 
 void finish_cache_collection(cache_t* cache);
 
@@ -191,38 +203,48 @@
 
 int append_and_increment(char** dst, const char* src, size_t* dst_size);
 
-char *build_string2(char *s1, char *s2);
-char *build_string3(char *s1, char *s2, char *s3);
+char *build_string2(const char *s1, const char *s2);
+char *build_string3(const char *s1, const char *s2, const char *s3);
 
 int ensure_dir(const char* path, mode_t mode, uid_t uid, gid_t gid);
-int ensure_media_user_dirs(userid_t userid);
+int ensure_media_user_dirs(const char* uuid, userid_t userid);
 int ensure_config_user_dirs(userid_t userid);
 int create_profile_file(const char *pkgname, gid_t gid);
 void remove_profile_file(const char *pkgname);
 
 /* commands.c */
 
-int install(const char *pkgname, uid_t uid, gid_t gid, const char *seinfo);
-int uninstall(const char *pkgname, userid_t userid);
+int install(const char *uuid, const char *pkgname, uid_t uid, gid_t gid, const char *seinfo);
+int uninstall(const char *uuid, const char *pkgname, userid_t userid);
 int renamepkg(const char *oldpkgname, const char *newpkgname);
-int fix_uid(const char *pkgname, uid_t uid, gid_t gid);
-int delete_user_data(const char *pkgname, userid_t userid);
-int make_user_data(const char *pkgname, uid_t uid, userid_t userid, const char* seinfo);
+int fix_uid(const char *uuid, const char *pkgname, uid_t uid, gid_t gid);
+int delete_user_data(const char *uuid, const char *pkgname, userid_t userid);
+int make_user_data(const char *uuid, const char *pkgname, uid_t uid,
+        userid_t userid, const char* seinfo);
+int move_user_data(const char* from_uuid, const char *to_uuid,
+        const char *package_name, appid_t appid, const char* seinfo);
 int make_user_config(userid_t userid);
-int delete_user(userid_t userid);
-int delete_cache(const char *pkgname, userid_t userid);
-int delete_code_cache(const char *pkgname, userid_t userid);
+int delete_user(const char *uuid, userid_t userid);
+int delete_cache(const char *uuid, const char *pkgname, userid_t userid);
+int delete_code_cache(const char *uuid, const char *pkgname, userid_t userid);
 int move_dex(const char *src, const char *dst, const char *instruction_set);
 int rm_dex(const char *path, const char *instruction_set);
 int protect(char *pkgname, gid_t gid);
-int get_size(const char *pkgname, userid_t userid, const char *apkpath, const char *libdirpath,
+int get_size(const char *uuid, const char *pkgname, userid_t userid, const char *apkpath, const char *libdirpath,
              const char *fwdlock_apkpath, const char *asecpath, const char *instruction_set,
              int64_t *codesize, int64_t *datasize, int64_t *cachesize, int64_t *asecsize);
-int free_cache(int64_t free_size);
+int free_cache(const char *uuid, int64_t free_size);
 int dexopt(const char *apk_path, uid_t uid, bool is_public, const char *pkgName,
-           const char *instruction_set, bool vm_safe_mode, bool should_relocate);
+           const char *instruction_set, int dexopt_needed, bool vm_safe_mode,
+           bool debuggable, const char* oat_dir);
 int mark_boot_complete(const char *instruction_set);
 int movefiles();
-int linklib(const char* target, const char* source, int userId);
+int linklib(const char* uuid, const char* pkgname, const char* asecLibDir, int userId);
 int idmap(const char *target_path, const char *overlay_path, uid_t uid);
-int restorecon_data();
+int restorecon_data(const char *uuid, const char* pkgName, const char* seinfo, uid_t uid);
+int create_oat_dir(const char* oat_dir, const char *instruction_set);
+int rm_package_dir(const char* apk_path);
+int calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path,
+                            const char *instruction_set);
+int move_package_dir(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path,
+                            const char *instruction_set);
diff --git a/cmds/installd/tests/Android.mk b/cmds/installd/tests/Android.mk
index 7300b29..38a9f69 100644
--- a/cmds/installd/tests/Android.mk
+++ b/cmds/installd/tests/Android.mk
@@ -8,6 +8,7 @@
     installd_utils_test.cpp
 
 shared_libraries := \
+    libbase \
     libutils \
     libcutils \
 
@@ -25,5 +26,6 @@
     $(eval LOCAL_SRC_FILES := $(file)) \
     $(eval LOCAL_C_INCLUDES := $(c_includes)) \
     $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
+    $(eval LOCAL_CLANG := true) \
     $(eval include $(BUILD_NATIVE_TEST)) \
 )
diff --git a/cmds/installd/tests/installd_utils_test.cpp b/cmds/installd/tests/installd_utils_test.cpp
index 94e4792..4ce559d 100644
--- a/cmds/installd/tests/installd_utils_test.cpp
+++ b/cmds/installd/tests/installd_utils_test.cpp
@@ -17,19 +17,18 @@
 #include <stdlib.h>
 #include <string.h>
 
-#define LOG_TAG "utils_test"
-#include <utils/Log.h>
-
 #include <gtest/gtest.h>
 
-extern "C" {
 #include "installd.h"
-}
+
+#undef LOG_TAG
+#define LOG_TAG "utils_test"
 
 #define TEST_DATA_DIR "/data/"
 #define TEST_APP_DIR "/data/app/"
 #define TEST_APP_PRIVATE_DIR "/data/app-private/"
 #define TEST_ASEC_DIR "/mnt/asec/"
+#define TEST_EXPAND_DIR "/mnt/expand/"
 
 #define TEST_SYSTEM_DIR1 "/system/app/"
 #define TEST_SYSTEM_DIR2 "/vendor/app/"
@@ -49,25 +48,28 @@
 class UtilsTest : public testing::Test {
 protected:
     virtual void SetUp() {
-        android_app_dir.path = TEST_APP_DIR;
+        android_app_dir.path = (char*) TEST_APP_DIR;
         android_app_dir.len = strlen(TEST_APP_DIR);
 
-        android_app_private_dir.path = TEST_APP_PRIVATE_DIR;
+        android_app_private_dir.path = (char*) TEST_APP_PRIVATE_DIR;
         android_app_private_dir.len = strlen(TEST_APP_PRIVATE_DIR);
 
-        android_data_dir.path = TEST_DATA_DIR;
+        android_data_dir.path = (char*) TEST_DATA_DIR;
         android_data_dir.len = strlen(TEST_DATA_DIR);
 
-        android_asec_dir.path = TEST_ASEC_DIR;
+        android_asec_dir.path = (char*) TEST_ASEC_DIR;
         android_asec_dir.len = strlen(TEST_ASEC_DIR);
 
+        android_mnt_expand_dir.path = (char*) TEST_EXPAND_DIR;
+        android_mnt_expand_dir.len = strlen(TEST_EXPAND_DIR);
+
         android_system_dirs.count = 2;
 
         android_system_dirs.dirs = (dir_rec_t*) calloc(android_system_dirs.count, sizeof(dir_rec_t));
-        android_system_dirs.dirs[0].path = TEST_SYSTEM_DIR1;
+        android_system_dirs.dirs[0].path = (char*) TEST_SYSTEM_DIR1;
         android_system_dirs.dirs[0].len = strlen(TEST_SYSTEM_DIR1);
 
-        android_system_dirs.dirs[1].path = TEST_SYSTEM_DIR2;
+        android_system_dirs.dirs[1].path = (char*) TEST_SYSTEM_DIR2;
         android_system_dirs.dirs[1].len = strlen(TEST_SYSTEM_DIR2);
     }
 
@@ -319,6 +321,7 @@
 
     const char *prefix = TEST_DATA_DIR PRIMARY_USER_PREFIX;
     size_t offset = strlen(prefix);
+
     EXPECT_STREQ(pkgname, path + offset)
              << "Package path should be a really long string of a's";
 }
@@ -369,40 +372,6 @@
             << "Package path should be in /data/user/";
 }
 
-TEST_F(UtilsTest, CreatePkgPathInDir_ProtectedDir) {
-    char path[PKG_PATH_MAX];
-
-    dir_rec_t dir;
-    dir.path = "/data/app-private/";
-    dir.len = strlen(dir.path);
-
-    EXPECT_EQ(0, create_pkg_path_in_dir(path, &dir, "com.example.package", ".apk"))
-            << "Should successfully create package path.";
-
-    EXPECT_STREQ("/data/app-private/com.example.package.apk", path)
-            << "Package path should be in /data/app-private/";
-}
-
-TEST_F(UtilsTest, CreatePersonaPath_Primary) {
-    char path[PKG_PATH_MAX];
-
-    EXPECT_EQ(0, create_user_path(path, 0))
-            << "Should successfully build primary user path.";
-
-    EXPECT_STREQ("/data/data/", path)
-            << "Primary user should have correct path";
-}
-
-TEST_F(UtilsTest, CreatePersonaPath_Secondary) {
-    char path[PKG_PATH_MAX];
-
-    EXPECT_EQ(0, create_user_path(path, 1))
-            << "Should successfully build primary user path.";
-
-    EXPECT_STREQ("/data/user/1/", path)
-            << "Primary user should have correct path";
-}
-
 TEST_F(UtilsTest, CreateMovePath_Primary) {
     char path[PKG_PATH_MAX];
 
@@ -432,7 +401,7 @@
     dir_rec_t dst;
     dir_rec_t src;
 
-    src.path = "/data/";
+    src.path = (char*) "/data/";
     src.len = strlen(src.path);
 
     EXPECT_EQ(0, copy_and_append(&dst, &src, "app/"))
@@ -480,4 +449,40 @@
             << "String should fail because it's too large to fit";
 }
 
+TEST_F(UtilsTest, CreateDataPath) {
+    EXPECT_EQ("/data", create_data_path(nullptr));
+    EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b",
+            create_data_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b"));
+}
+
+TEST_F(UtilsTest, CreateDataUserPath) {
+    EXPECT_EQ("/data/data", create_data_user_path(nullptr, 0));
+    EXPECT_EQ("/data/user/10", create_data_user_path(nullptr, 10));
+
+    EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/user/0",
+            create_data_user_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", 0));
+    EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/user/10",
+            create_data_user_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", 10));
+}
+
+TEST_F(UtilsTest, CreateDataMediaPath) {
+    EXPECT_EQ("/data/media/0", create_data_media_path(nullptr, 0));
+    EXPECT_EQ("/data/media/10", create_data_media_path(nullptr, 10));
+
+    EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/media/0",
+            create_data_media_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", 0));
+    EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/media/10",
+            create_data_media_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", 10));
+}
+
+TEST_F(UtilsTest, CreatePackageDataPath) {
+    EXPECT_EQ("/data/data/com.example", create_package_data_path(nullptr, "com.example", 0));
+    EXPECT_EQ("/data/user/10/com.example", create_package_data_path(nullptr, "com.example", 10));
+
+    EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/user/0/com.example",
+            create_package_data_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", "com.example", 0));
+    EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/user/10/com.example",
+            create_package_data_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", "com.example", 10));
+}
+
 }
diff --git a/cmds/installd/utils.c b/cmds/installd/utils.cpp
similarity index 87%
rename from cmds/installd/utils.c
rename to cmds/installd/utils.cpp
index 8f366a0..ba411cd 100644
--- a/cmds/installd/utils.c
+++ b/cmds/installd/utils.cpp
@@ -16,137 +16,119 @@
 
 #include "installd.h"
 
+#include <base/stringprintf.h>
+#include <base/logging.h>
+
 #define CACHE_NOISY(x) //x
 
-int create_pkg_path_in_dir(char path[PKG_PATH_MAX],
-                                const dir_rec_t* dir,
-                                const char* pkgname,
-                                const char* postfix)
-{
-     const size_t postfix_len = strlen(postfix);
+using android::base::StringPrintf;
 
-     const size_t pkgname_len = strlen(pkgname);
-     if (pkgname_len > PKG_NAME_MAX) {
-         return -1;
-     }
-
-     if (is_valid_package_name(pkgname) < 0) {
-         return -1;
-     }
-
-     if ((pkgname_len + dir->len + postfix_len) >= PKG_PATH_MAX) {
-         return -1;
-     }
-
-     char *dst = path;
-     size_t dst_size = PKG_PATH_MAX;
-
-     if (append_and_increment(&dst, dir->path, &dst_size) < 0
-             || append_and_increment(&dst, pkgname, &dst_size) < 0
-             || append_and_increment(&dst, postfix, &dst_size) < 0) {
-         ALOGE("Error building APK path");
-         return -1;
-     }
-
-     return 0;
+/**
+ * Check that given string is valid filename, and that it attempts no
+ * parent or child directory traversal.
+ */
+static bool is_valid_filename(const std::string& name) {
+    if (name.empty() || (name == ".") || (name == "..")
+            || (name.find('/') != std::string::npos)) {
+        return false;
+    } else {
+        return true;
+    }
 }
 
 /**
- * Create the package path name for a given package name with a postfix for
- * a certain userid. Returns 0 on success, and -1 on failure.
+ * Create the path name where package data should be stored for the given
+ * volume UUID, package name, and user ID. An empty UUID is assumed to be
+ * internal storage.
  */
-int create_pkg_path(char path[PKG_PATH_MAX],
-                    const char *pkgname,
-                    const char *postfix,
-                    userid_t userid)
-{
-    size_t userid_len;
-    char* userid_prefix;
-    if (userid == 0) {
-        userid_prefix = PRIMARY_USER_PREFIX;
-        userid_len = 0;
-    } else {
-        userid_prefix = SECONDARY_USER_PREFIX;
-        userid_len = snprintf(NULL, 0, "%d", userid);
-    }
+std::string create_package_data_path(const char* volume_uuid,
+        const char* package_name, userid_t user) {
+    CHECK(is_valid_filename(package_name));
+    CHECK(is_valid_package_name(package_name) == 0);
 
-    const size_t prefix_len = android_data_dir.len + strlen(userid_prefix)
-            + userid_len + 1 /*slash*/;
-    char prefix[prefix_len + 1];
+    return StringPrintf("%s/%s", create_data_user_path(volume_uuid, user).c_str(), package_name);
+}
 
-    char *dst = prefix;
-    size_t dst_size = sizeof(prefix);
-
-    if (append_and_increment(&dst, android_data_dir.path, &dst_size) < 0
-            || append_and_increment(&dst, userid_prefix, &dst_size) < 0) {
-        ALOGE("Error building prefix for APK path");
+int create_pkg_path(char path[PKG_PATH_MAX], const char *pkgname,
+        const char *postfix, userid_t userid) {
+    if (is_valid_package_name(pkgname) != 0) {
+        path[0] = '\0';
         return -1;
     }
 
-    if (userid != 0) {
-        int ret = snprintf(dst, dst_size, "%d/", userid);
-        if (ret < 0 || (size_t) ret != userid_len + 1) {
-            ALOGW("Error appending UID to APK path");
-            return -1;
-        }
+    std::string _tmp(create_package_data_path(nullptr, pkgname, userid) + postfix);
+    const char* tmp = _tmp.c_str();
+    if (strlen(tmp) >= PKG_PATH_MAX) {
+        path[0] = '\0';
+        return -1;
+    } else {
+        strcpy(path, tmp);
+        return 0;
     }
+}
 
-    dir_rec_t dir;
-    dir.path = prefix;
-    dir.len = prefix_len;
-
-    return create_pkg_path_in_dir(path, &dir, pkgname, postfix);
+std::string create_data_path(const char* volume_uuid) {
+    if (volume_uuid == nullptr) {
+        return "/data";
+    } else {
+        CHECK(is_valid_filename(volume_uuid));
+        return StringPrintf("/mnt/expand/%s", volume_uuid);
+    }
 }
 
 /**
  * Create the path name for user data for a certain userid.
- * Returns 0 on success, and -1 on failure.
  */
-int create_user_path(char path[PKG_PATH_MAX],
-                    userid_t userid)
-{
-    size_t userid_len;
-    char* userid_prefix;
-    if (userid == 0) {
-        userid_prefix = PRIMARY_USER_PREFIX;
-        userid_len = 0;
+std::string create_data_user_path(const char* volume_uuid, userid_t userid) {
+    std::string data(create_data_path(volume_uuid));
+    if (volume_uuid == nullptr) {
+        if (userid == 0) {
+            return StringPrintf("%s/data", data.c_str());
+        } else {
+            return StringPrintf("%s/user/%u", data.c_str(), userid);
+        }
     } else {
-        userid_prefix = SECONDARY_USER_PREFIX;
-        userid_len = snprintf(NULL, 0, "%d/", userid);
+        return StringPrintf("%s/user/%u", data.c_str(), userid);
     }
-
-    char *dst = path;
-    size_t dst_size = PKG_PATH_MAX;
-
-    if (append_and_increment(&dst, android_data_dir.path, &dst_size) < 0
-            || append_and_increment(&dst, userid_prefix, &dst_size) < 0) {
-        ALOGE("Error building prefix for user path");
-        return -1;
-    }
-
-    if (userid != 0) {
-        if (dst_size < userid_len + 1) {
-            ALOGE("Error building user path");
-            return -1;
-        }
-        int ret = snprintf(dst, dst_size, "%d/", userid);
-        if (ret < 0 || (size_t) ret != userid_len) {
-            ALOGE("Error appending userid to path");
-            return -1;
-        }
-    }
-    return 0;
 }
 
 /**
  * Create the path name for media for a certain userid.
- * Returns 0 on success, and -1 on failure.
  */
-int create_user_media_path(char path[PATH_MAX], userid_t userid) {
-    if (snprintf(path, PATH_MAX, "%s%d", android_media_dir.path, userid) > PATH_MAX) {
-        return -1;
+std::string create_data_media_path(const char* volume_uuid, userid_t userid) {
+    return StringPrintf("%s/media/%u", create_data_path(volume_uuid).c_str(), userid);
+}
+
+std::vector<userid_t> get_known_users(const char* volume_uuid) {
+    std::vector<userid_t> users;
+
+    // We always have an owner
+    users.push_back(0);
+
+    std::string path(create_data_path(volume_uuid) + "/" + SECONDARY_USER_PREFIX);
+    DIR* dir = opendir(path.c_str());
+    if (dir == NULL) {
+        // Unable to discover other users, but at least return owner
+        PLOG(ERROR) << "Failed to opendir " << path;
+        return users;
     }
-    return 0;
+
+    struct dirent* ent;
+    while ((ent = readdir(dir))) {
+        if (ent->d_type != DT_DIR) {
+            continue;
+        }
+
+        char* end;
+        userid_t user = strtol(ent->d_name, &end, 10);
+        if (*end == '\0' && user != 0) {
+            LOG(DEBUG) << "Found valid user " << user;
+            users.push_back(user);
+        }
+    }
+    closedir(dir);
+
+    return users;
 }
 
 /**
@@ -182,6 +164,10 @@
     const char *x = pkgname;
     int alpha = -1;
 
+    if (strlen(pkgname) > PKG_NAME_MAX) {
+        return -1;
+    }
+
     while (*x) {
         if (isalnum(*x) || (*x == '_')) {
                 /* alphanumeric or underscore are fine */
@@ -472,13 +458,13 @@
     return -1;
 }
 
-int64_t data_disk_free()
+int64_t data_disk_free(const std::string& data_path)
 {
     struct statfs sfs;
-    if (statfs(android_data_dir.path, &sfs) == 0) {
+    if (statfs(data_path.c_str(), &sfs) == 0) {
         return sfs.f_bavail * sfs.f_bsize;
     } else {
-        ALOGE("Couldn't statfs %s: %s\n", android_data_dir.path, strerror(errno));
+        PLOG(ERROR) << "Couldn't statfs " << data_path;
         return -1;
     }
 }
@@ -516,7 +502,7 @@
     int8_t* res = cache->curMemBlockAvail;
     int8_t* nextPos = res + len;
     if (cache->memBlocks == NULL || nextPos > cache->curMemBlockEnd) {
-        int8_t* newBlock = malloc(CACHE_BLOCK_SIZE);
+        int8_t* newBlock = (int8_t*) malloc(CACHE_BLOCK_SIZE);
         if (newBlock == NULL) {
             return NULL;
         }
@@ -836,7 +822,7 @@
     return lhs->modTime < rhs->modTime ? -1 : (lhs->modTime > rhs->modTime ? 1 : 0);
 }
 
-void clear_cache_files(cache_t* cache, int64_t free_size)
+void clear_cache_files(const std::string& data_path, cache_t* cache, int64_t free_size)
 {
     size_t i;
     int skip = 0;
@@ -861,7 +847,7 @@
     for (i=0; i<cache->numFiles; i++) {
         skip++;
         if (skip > 10) {
-            if (data_disk_free() > free_size) {
+            if (data_disk_free(data_path) > free_size) {
                 return;
             }
             skip = 0;
@@ -910,14 +896,14 @@
  * The path is allowed to have at most one subdirectory and no indirections
  * to top level directories (i.e. have "..").
  */
-static int validate_path(const dir_rec_t* dir, const char* path) {
+static int validate_path(const dir_rec_t* dir, const char* path, int maxSubdirs) {
     size_t dir_len = dir->len;
     const char* subdir = strchr(path + dir_len, '/');
 
     // Only allow the path to have at most one subdirectory.
     if (subdir != NULL) {
         ++subdir;
-        if (strchr(subdir, '/') != NULL) {
+        if ((--maxSubdirs == 0) && strchr(subdir, '/') != NULL) {
             ALOGE("invalid apk path '%s' (subdir?)\n", path);
             return -1;
         }
@@ -942,7 +928,7 @@
     for (i = 0; i < android_system_dirs.count; i++) {
         const size_t dir_len = android_system_dirs.dirs[i].len;
         if (!strncmp(path, android_system_dirs.dirs[i].path, dir_len)) {
-            return validate_path(android_system_dirs.dirs + i, path);
+            return validate_path(android_system_dirs.dirs + i, path, 1);
         }
     }
 
@@ -1000,7 +986,7 @@
             // Add space for slash and terminating null.
             size_t dst_size = path_len + 2;
 
-            rec->path = malloc(dst_size);
+            rec->path = (char*) malloc(dst_size);
             if (rec->path == NULL) {
                 return -1;
             }
@@ -1042,6 +1028,7 @@
 int validate_apk_path(const char *path)
 {
     const dir_rec_t* dir = NULL;
+    int maxSubdirs = 1;
 
     if (!strncmp(path, android_app_dir.path, android_app_dir.len)) {
         dir = &android_app_dir;
@@ -1049,11 +1036,14 @@
         dir = &android_app_private_dir;
     } else if (!strncmp(path, android_asec_dir.path, android_asec_dir.len)) {
         dir = &android_asec_dir;
+    } else if (!strncmp(path, android_mnt_expand_dir.path, android_mnt_expand_dir.len)) {
+        dir = &android_mnt_expand_dir;
+        maxSubdirs = 2;
     } else {
         return -1;
     }
 
-    return validate_path(dir, path);
+    return validate_path(dir, path, maxSubdirs);
 }
 
 int append_and_increment(char** dst, const char* src, size_t* dst_size) {
@@ -1066,13 +1056,13 @@
     return 0;
 }
 
-char *build_string2(char *s1, char *s2) {
+char *build_string2(const char *s1, const char *s2) {
     if (s1 == NULL || s2 == NULL) return NULL;
 
     int len_s1 = strlen(s1);
     int len_s2 = strlen(s2);
     int len = len_s1 + len_s2 + 1;
-    char *result = malloc(len);
+    char *result = (char *) malloc(len);
     if (result == NULL) return NULL;
 
     strcpy(result, s1);
@@ -1081,14 +1071,14 @@
     return result;
 }
 
-char *build_string3(char *s1, char *s2, char *s3) {
+char *build_string3(const char *s1, const char *s2, const char *s3) {
     if (s1 == NULL || s2 == NULL || s3 == NULL) return NULL;
 
     int len_s1 = strlen(s1);
     int len_s2 = strlen(s2);
     int len_s3 = strlen(s3);
     int len = len_s1 + len_s2 + len_s3 + 1;
-    char *result = malloc(len);
+    char *result = (char *) malloc(len);
     if (result == NULL) return NULL;
 
     strcpy(result, s1);
@@ -1099,12 +1089,9 @@
 }
 
 /* Ensure that /data/media directories are prepared for given user. */
-int ensure_media_user_dirs(userid_t userid) {
-    char media_user_path[PATH_MAX];
-
-    // Ensure /data/media/<userid> exists
-    create_user_media_path(media_user_path, userid);
-    if (fs_prepare_dir(media_user_path, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
+int ensure_media_user_dirs(const char* uuid, userid_t userid) {
+    std::string media_user_path(create_data_media_path(uuid, userid));
+    if (fs_prepare_dir(media_user_path.c_str(), 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
         return -1;
     }
 
diff --git a/cmds/servicemanager/binder.c b/cmds/servicemanager/binder.c
index d1ab05f..6eecee1 100644
--- a/cmds/servicemanager/binder.c
+++ b/cmds/servicemanager/binder.c
@@ -113,7 +113,9 @@
 
     if ((ioctl(bs->fd, BINDER_VERSION, &vers) == -1) ||
         (vers.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION)) {
-        fprintf(stderr, "binder: driver version differs from user space\n");
+        fprintf(stderr,
+                "binder: kernel driver version (%d) differs from user space version (%d)\n",
+                vers.protocol_version, BINDER_CURRENT_PROTOCOL_VERSION);
         goto fail_open;
     }
 
diff --git a/cmds/servicemanager/service_manager.c b/cmds/servicemanager/service_manager.c
index f37427a..cacfe14 100644
--- a/cmds/servicemanager/service_manager.c
+++ b/cmds/servicemanager/service_manager.c
@@ -1,10 +1,12 @@
 /* Copyright 2008 The Android Open Source Project
  */
 
-#include <stdio.h>
-#include <stdlib.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
 #include <private/android_filesystem_config.h>
 
@@ -21,8 +23,6 @@
 #include <cutils/log.h>
 #endif
 
-uint32_t svcmgr_handle;
-
 const char *str8(const uint16_t *x, size_t x_len)
 {
     static char buf[128];
@@ -169,28 +169,26 @@
 
 uint32_t do_find_service(struct binder_state *bs, const uint16_t *s, size_t len, uid_t uid, pid_t spid)
 {
-    struct svcinfo *si;
+    struct svcinfo *si = find_svc(s, len);
+
+    if (!si || !si->handle) {
+        return 0;
+    }
+
+    if (!si->allow_isolated) {
+        // If this service doesn't allow access from isolated processes,
+        // then check the uid to see if it is isolated.
+        uid_t appid = uid % AID_USER;
+        if (appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END) {
+            return 0;
+        }
+    }
 
     if (!svc_can_find(s, len, spid)) {
-        ALOGE("find_service('%s') uid=%d - PERMISSION DENIED\n",
-             str8(s, len), uid);
         return 0;
     }
-    si = find_svc(s, len);
-    //ALOGI("check_service('%s') handle = %x\n", str8(s, len), si ? si->handle : 0);
-    if (si && si->handle) {
-        if (!si->allow_isolated) {
-            // If this service doesn't allow access from isolated processes,
-            // then check the uid to see if it is isolated.
-            uid_t appid = uid % AID_USER;
-            if (appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END) {
-                return 0;
-            }
-        }
-        return si->handle;
-    } else {
-        return 0;
-    }
+
+    return si->handle;
 }
 
 int do_add_service(struct binder_state *bs,
@@ -255,10 +253,10 @@
     uint32_t strict_policy;
     int allow_isolated;
 
-    //ALOGI("target=%x code=%d pid=%d uid=%d\n",
-    //  txn->target.handle, txn->code, txn->sender_pid, txn->sender_euid);
+    //ALOGI("target=%p code=%d pid=%d uid=%d\n",
+    //      (void*) txn->target.ptr, txn->code, txn->sender_pid, txn->sender_euid);
 
-    if (txn->target.handle != svcmgr_handle)
+    if (txn->target.ptr != BINDER_SERVICE_MANAGER)
         return -1;
 
     if (txn->code == PING_TRANSACTION)
@@ -382,7 +380,6 @@
     cb.func_log = selinux_log_callback;
     selinux_set_callback(SELINUX_CB_LOG, cb);
 
-    svcmgr_handle = BINDER_SERVICE_MANAGER;
     binder_loop(bs, svcmgr_handler);
 
     return 0;
diff --git a/data/etc/android.hardware.camera.manual_postprocessing.xml b/data/etc/android.hardware.camera.manual_postprocessing.xml
new file mode 100644
index 0000000..01796be
--- /dev/null
+++ b/data/etc/android.hardware.camera.manual_postprocessing.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<!-- This is the set of features required for a camera2 device that supports manual postprocessing capability -->
+<permissions>
+    <feature name="android.hardware.camera.any" />
+    <feature name="android.hardware.camera.capability.manual_post_processing" />
+</permissions>
diff --git a/data/etc/android.hardware.camera.manual_sensor.xml b/data/etc/android.hardware.camera.manual_sensor.xml
new file mode 100644
index 0000000..57db5ab
--- /dev/null
+++ b/data/etc/android.hardware.camera.manual_sensor.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<!-- This is the set of features required for a camera2 device that supports manual sensor capability-->
+<permissions>
+    <feature name="android.hardware.camera.any" />
+    <feature name="android.hardware.camera.capability.manual_sensor" />
+</permissions>
diff --git a/data/etc/android.software.voice_recognizers.xml b/data/etc/android.software.voice_recognizers.xml
index 7e72177..435eed4 100644
--- a/data/etc/android.software.voice_recognizers.xml
+++ b/data/etc/android.software.voice_recognizers.xml
@@ -15,5 +15,5 @@
 -->
 
 <permissions>
-    <feature name="android.software.voice_recognizers" />
+    <feature name="android.software.voice_recognizers" notLowRam="true" />
 </permissions>
diff --git a/data/etc/handheld_core_hardware.xml b/data/etc/handheld_core_hardware.xml
index eaf93fd..50cbe9e 100644
--- a/data/etc/handheld_core_hardware.xml
+++ b/data/etc/handheld_core_hardware.xml
@@ -38,7 +38,7 @@
     <!-- basic system services -->
     <feature name="android.software.app_widgets" />
     <feature name="android.software.connectionservice" />
-    <feature name="android.software.voice_recognizers" />
+    <feature name="android.software.voice_recognizers" notLowRam="true" />
     <feature name="android.software.backup" />
     <feature name="android.software.home_screen" />
     <feature name="android.software.input_methods" />
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index fee8090..a52e044 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -208,7 +208,11 @@
 
     // Explicitly close all file descriptors in the parcel.
     void                closeFileDescriptors();
-    
+
+    // Debugging: get metrics on current allocations.
+    static size_t       getGlobalAllocSize();
+    static size_t       getGlobalAllocCount();
+
 private:
     typedef void        (*release_func)(Parcel* parcel,
                                         const uint8_t* data, size_t dataSize,
diff --git a/include/gui/BufferItem.h b/include/gui/BufferItem.h
index 5effd10..000ef0e 100644
--- a/include/gui/BufferItem.h
+++ b/include/gui/BufferItem.h
@@ -20,9 +20,10 @@
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 
-#include <gui/IGraphicBufferConsumer.h>
-
 #include <ui/Rect.h>
+#include <ui/Region.h>
+
+#include <system/graphics.h>
 
 #include <utils/Flattenable.h>
 #include <utils/StrongPointer.h>
@@ -44,7 +45,7 @@
     // The default value of mBuf, used to indicate this doesn't correspond to a slot.
     enum { INVALID_BUFFER_SLOT = -1 };
     BufferItem();
-    operator IGraphicBufferConsumer::BufferItem() const;
+    ~BufferItem();
 
     static const char* scalingModeName(uint32_t scalingMode);
 
@@ -77,11 +78,21 @@
     // automatically when the buffer was queued.
     bool mIsAutoTimestamp;
 
+    // mDataSpace is the current dataSpace value for this buffer slot. This gets
+    // set by queueBuffer each time this slot is queued. The meaning of the
+    // dataSpace is format-dependent.
+    android_dataspace mDataSpace;
+
     // mFrameNumber is the number of the queued frame for this slot.
     uint64_t mFrameNumber;
 
-    // mSlot is the slot index of this buffer (default INVALID_BUFFER_SLOT).
-    int mSlot;
+    union {
+        // mSlot is the slot index of this buffer (default INVALID_BUFFER_SLOT).
+        int mSlot;
+
+        // mBuf is the former name for mSlot
+        int mBuf;
+    };
 
     // mIsDroppable whether this buffer was queued with the
     // property that it can be replaced by a new buffer for the purpose of
@@ -96,6 +107,10 @@
     // Indicates this buffer must be transformed by the inverse transform of the screen
     // it is displayed onto. This is applied after mTransform.
     bool mTransformToDisplayInverse;
+
+    // Describes the portion of the surface that has been modified since the
+    // previous frame
+    Region mSurfaceDamage;
 };
 
 } // namespace android
diff --git a/include/gui/BufferItemConsumer.h b/include/gui/BufferItemConsumer.h
index 869b470..930fabf 100644
--- a/include/gui/BufferItemConsumer.h
+++ b/include/gui/BufferItemConsumer.h
@@ -42,8 +42,6 @@
   public:
     typedef ConsumerBase::FrameAvailableListener FrameAvailableListener;
 
-    typedef BufferQueue::BufferItem BufferItem;
-
     enum { DEFAULT_MAX_BUFFERS = -1 };
     enum { INVALID_BUFFER_SLOT = BufferQueue::INVALID_BUFFER_SLOT };
     enum { NO_BUFFER_AVAILABLE = BufferQueue::NO_BUFFER_AVAILABLE };
@@ -76,8 +74,8 @@
     //
     // If waitForFence is true, and the acquired BufferItem has a valid fence object,
     // acquireBuffer will wait on the fence with no timeout before returning.
-    status_t acquireBuffer(BufferItem *item, nsecs_t presentWhen,
-        bool waitForFence = true);
+    status_t acquireBuffer(BufferItem* item, nsecs_t presentWhen,
+            bool waitForFence = true);
 
     // Returns an acquired buffer to the queue, allowing it to be reused. Since
     // only a fixed number of buffers may be acquired at a time, old buffers
@@ -96,6 +94,13 @@
     // GraphicBuffers of a defaultFormat if no format is specified
     // in dequeueBuffer
     status_t setDefaultBufferFormat(PixelFormat defaultFormat);
+
+    // setDefaultBufferDataSpace allows the BufferQueue to create
+    // GraphicBuffers of a defaultDataSpace if no data space is specified
+    // in queueBuffer.
+    // The initial default is HAL_DATASPACE_UNKNOWN
+    status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace);
+
 };
 
 } // namespace android
diff --git a/include/gui/BufferQueue.h b/include/gui/BufferQueue.h
index 3297b10..721b218 100644
--- a/include/gui/BufferQueue.h
+++ b/include/gui/BufferQueue.h
@@ -17,6 +17,7 @@
 #ifndef ANDROID_GUI_BUFFERQUEUE_H
 #define ANDROID_GUI_BUFFERQUEUE_H
 
+#include <gui/BufferItem.h>
 #include <gui/BufferQueueDefs.h>
 #include <gui/IGraphicBufferConsumer.h>
 #include <gui/IGraphicBufferProducer.h>
@@ -34,7 +35,7 @@
     // Attempts at runtime to increase the number of buffers past this will fail.
     enum { NUM_BUFFER_SLOTS = BufferQueueDefs::NUM_BUFFER_SLOTS };
     // Used as a placeholder slot# when the value isn't pointing to an existing buffer.
-    enum { INVALID_BUFFER_SLOT = IGraphicBufferConsumer::BufferItem::INVALID_BUFFER_SLOT };
+    enum { INVALID_BUFFER_SLOT = BufferItem::INVALID_BUFFER_SLOT };
     // Alias to <IGraphicBufferConsumer.h> -- please scope from there in future code!
     enum {
         NO_BUFFER_AVAILABLE = IGraphicBufferConsumer::NO_BUFFER_AVAILABLE,
@@ -47,7 +48,6 @@
 
     // for backward source compatibility
     typedef ::android::ConsumerListener ConsumerListener;
-    typedef IGraphicBufferConsumer::BufferItem BufferItem;
 
     // ProxyConsumerListener is a ConsumerListener implementation that keeps a weak
     // reference to the actual consumer object.  It forwards all calls to that
@@ -62,7 +62,7 @@
     public:
         ProxyConsumerListener(const wp<ConsumerListener>& consumerListener);
         virtual ~ProxyConsumerListener();
-        virtual void onFrameAvailable();
+        virtual void onFrameAvailable(const BufferItem& item);
         virtual void onBuffersReleased();
         virtual void onSidebandStreamChanged();
     private:
diff --git a/include/gui/BufferQueueConsumer.h b/include/gui/BufferQueueConsumer.h
index 898c451..0f42613 100644
--- a/include/gui/BufferQueueConsumer.h
+++ b/include/gui/BufferQueueConsumer.h
@@ -128,6 +128,13 @@
     // in dequeueBuffer. The initial default is HAL_PIXEL_FORMAT_RGBA_8888.
     virtual status_t setDefaultBufferFormat(PixelFormat defaultFormat);
 
+    // setDefaultBufferDataSpace allows the BufferQueue to create
+    // GraphicBuffers of a defaultDataSpace if no data space is specified
+    // in queueBuffer.
+    // The initial default is HAL_DATASPACE_UNKNOWN
+    virtual status_t setDefaultBufferDataSpace(
+            android_dataspace defaultDataSpace);
+
     // setConsumerUsageBits will turn on additional usage bits for dequeueBuffer.
     // These are merged with the bits passed to dequeueBuffer.  The values are
     // enumerated in gralloc.h, e.g. GRALLOC_USAGE_HW_RENDER; the default is 0.
@@ -141,6 +148,9 @@
     // Retrieve the sideband buffer stream, if any.
     virtual sp<NativeHandle> getSidebandStream() const;
 
+    // See IGraphicBufferConsumer::setShadowQueueSize
+    virtual void setShadowQueueSize(size_t size);
+
     // dump our state in a String
     virtual void dump(String8& result, const char* prefix) const;
 
diff --git a/include/gui/BufferQueueCore.h b/include/gui/BufferQueueCore.h
index b23cb08..a22015c 100644
--- a/include/gui/BufferQueueCore.h
+++ b/include/gui/BufferQueueCore.h
@@ -17,6 +17,7 @@
 #ifndef ANDROID_GUI_BUFFERQUEUECORE_H
 #define ANDROID_GUI_BUFFERQUEUECORE_H
 
+#include <gui/BufferItem.h>
 #include <gui/BufferQueueDefs.h>
 #include <gui/BufferSlot.h>
 
@@ -29,6 +30,9 @@
 #include <utils/Trace.h>
 #include <utils/Vector.h>
 
+#include <list>
+#include <set>
+
 #define BQ_LOGV(x, ...) ALOGV("[%s] " x, mConsumerName.string(), ##__VA_ARGS__)
 #define BQ_LOGD(x, ...) ALOGD("[%s] " x, mConsumerName.string(), ##__VA_ARGS__)
 #define BQ_LOGI(x, ...) ALOGI("[%s] " x, mConsumerName.string(), ##__VA_ARGS__)
@@ -45,7 +49,6 @@
 
 namespace android {
 
-class BufferItem;
 class IConsumerListener;
 class IGraphicBufferAlloc;
 class IProducerListener;
@@ -58,7 +61,7 @@
 public:
     // Used as a placeholder slot number when the value isn't pointing to an
     // existing buffer.
-    enum { INVALID_BUFFER_SLOT = -1 }; // TODO: Extract from IGBC::BufferItem
+    enum { INVALID_BUFFER_SLOT = BufferItem::INVALID_BUFFER_SLOT };
 
     // We reserve two slots in order to guarantee that the producer and
     // consumer can run asynchronously.
@@ -123,6 +126,10 @@
     // waitWhileAllocatingLocked blocks until mIsAllocating is false.
     void waitWhileAllocatingLocked() const;
 
+    // validateConsistencyLocked ensures that the free lists are in sync with
+    // the information stored in mSlots
+    void validateConsistencyLocked() const;
+
     // mAllocator is the connection to SurfaceFlinger that is used to allocate
     // new GraphicBuffer objects.
     sp<IGraphicBufferAlloc> mAllocator;
@@ -177,6 +184,14 @@
     // mQueue is a FIFO of queued buffers used in synchronous mode.
     Fifo mQueue;
 
+    // mFreeSlots contains all of the slots which are FREE and do not currently
+    // have a buffer attached
+    std::set<int> mFreeSlots;
+
+    // mFreeBuffers contains all of the slots which are FREE and currently have
+    // a buffer attached
+    std::list<int> mFreeBuffers;
+
     // mOverrideMaxBufferCount is the limit on the number of buffers that will
     // be allocated at one time. This value is set by the producer by calling
     // setBufferCount. The default is 0, which means that the producer doesn't
@@ -209,6 +224,11 @@
     // in dequeueBuffer if a width and height of 0 are specified.
     uint32_t mDefaultHeight;
 
+    // mDefaultBufferDataSpace holds the default dataSpace of queued buffers.
+    // It is used in queueBuffer if a dataspace of 0 (HAL_DATASPACE_UNKNOWN)
+    // is specified.
+    android_dataspace mDefaultBufferDataSpace;
+
     // mDefaultMaxBufferCount is the default limit on the number of buffers that
     // will be allocated at one time. This default limit is set by the consumer.
     // The limit (as opposed to the default limit) may be overriden by the
@@ -246,6 +266,21 @@
     // mIsAllocatingCondition is a condition variable used by producers to wait until mIsAllocating
     // becomes false.
     mutable Condition mIsAllocatingCondition;
+
+    // mAllowAllocation determines whether dequeueBuffer is allowed to allocate
+    // new buffers
+    bool mAllowAllocation;
+
+    // mBufferAge tracks the age of the contents of the most recently dequeued
+    // buffer as the number of frames that have elapsed since it was last queued
+    uint64_t mBufferAge;
+
+    // mConsumerHasShadowQueue determines if acquireBuffer should be more
+    // cautious about dropping buffers so that it always returns a buffer that
+    // is represented in the consumer's shadow queue.
+    bool mConsumerHasShadowQueue;
+    size_t mConsumerShadowQueueSize;
+
 }; // class BufferQueueCore
 
 } // namespace android
diff --git a/include/gui/BufferQueueProducer.h b/include/gui/BufferQueueProducer.h
index 34c32dc..ed660fb 100644
--- a/include/gui/BufferQueueProducer.h
+++ b/include/gui/BufferQueueProducer.h
@@ -172,6 +172,9 @@
     virtual void allocateBuffers(bool async, uint32_t width, uint32_t height,
             PixelFormat format, uint32_t usage);
 
+    // See IGraphicBufferProducer::allowAllocation
+    virtual status_t allowAllocation(bool allow);
+
 private:
     // This is required by the IBinder::DeathRecipient interface
     virtual void binderDied(const wp<IBinder>& who);
@@ -196,6 +199,22 @@
 
     uint32_t mStickyTransform;
 
+    // This saves the fence from the last queueBuffer, such that the
+    // next queueBuffer call can throttle buffer production. The prior
+    // queueBuffer's fence is not nessessarily available elsewhere,
+    // since the previous buffer might have already been acquired.
+    sp<Fence> mLastQueueBufferFence;
+
+    // Take-a-ticket system for ensuring that onFrame* callbacks are called in
+    // the order that frames are queued. While the BufferQueue lock
+    // (mCore->mMutex) is held, a ticket is retained by the producer. After
+    // dropping the BufferQueue lock, the producer must wait on the condition
+    // variable until the current callback ticket matches its retained ticket.
+    Mutex mCallbackMutex;
+    int mNextCallbackTicket; // Protected by mCore->mMutex
+    int mCurrentCallbackTicket; // Protected by mCallbackMutex
+    Condition mCallbackCondition;
+
 }; // class BufferQueueProducer
 
 } // namespace android
diff --git a/include/gui/ConsumerBase.h b/include/gui/ConsumerBase.h
index 100bb26..d56fa89 100644
--- a/include/gui/ConsumerBase.h
+++ b/include/gui/ConsumerBase.h
@@ -46,7 +46,7 @@
         //
         // This is called without any lock held and can be called concurrently
         // by multiple threads.
-        virtual void onFrameAvailable() = 0;
+        virtual void onFrameAvailable(const BufferItem& item) = 0;
     };
 
     virtual ~ConsumerBase();
@@ -76,6 +76,9 @@
     // when a new frame becomes available.
     void setFrameAvailableListener(const wp<FrameAvailableListener>& listener);
 
+    // See IGraphicBufferConsumer::detachBuffer
+    status_t detachBuffer(int slot);
+
 private:
     ConsumerBase(const ConsumerBase&);
     void operator=(const ConsumerBase&);
@@ -106,7 +109,7 @@
     // the ConsumerBase implementation must be called from the derived class.
     // The ConsumerBase version of onSidebandStreamChanged does nothing and can
     // be overriden by derived classes if they want the notification.
-    virtual void onFrameAvailable();
+    virtual void onFrameAvailable(const BufferItem& item);
     virtual void onBuffersReleased();
     virtual void onSidebandStreamChanged();
 
@@ -153,8 +156,7 @@
     // initialization that must take place the first time a buffer is assigned
     // to a slot.  If it is overridden the derived class's implementation must
     // call ConsumerBase::acquireBufferLocked.
-    virtual status_t acquireBufferLocked(IGraphicBufferConsumer::BufferItem *item,
-        nsecs_t presentWhen);
+    virtual status_t acquireBufferLocked(BufferItem *item, nsecs_t presentWhen);
 
     // releaseBufferLocked relinquishes control over a buffer, returning that
     // control to the BufferQueue.
diff --git a/include/gui/CpuConsumer.h b/include/gui/CpuConsumer.h
index 3414ede..c99ab29 100644
--- a/include/gui/CpuConsumer.h
+++ b/include/gui/CpuConsumer.h
@@ -53,9 +53,14 @@
         uint32_t    transform;
         uint32_t    scalingMode;
         int64_t     timestamp;
+        android_dataspace dataSpace;
         uint64_t    frameNumber;
-        // Values below are only valid when using
-        // HAL_PIXEL_FORMAT_YCbCr_420_888, in which case LockedBuffer::data
+        // this is the same as format, except for formats that are compatible with
+        // a flexible format (e.g. HAL_PIXEL_FORMAT_YCbCr_420_888). In the latter
+        // case this contains that flexible format
+        PixelFormat flexFormat;
+        // Values below are only valid when using HAL_PIXEL_FORMAT_YCbCr_420_888
+        // or compatible format, in which case LockedBuffer::data
         // contains the Y channel, and stride is the Y channel stride. For other
         // formats, these will all be 0.
         uint8_t    *dataCb;
@@ -86,6 +91,12 @@
     // The initial default is PIXEL_FORMAT_RGBA_8888.
     status_t setDefaultBufferFormat(PixelFormat defaultFormat);
 
+    // setDefaultBufferDataSpace allows the BufferQueue to create
+    // GraphicBuffers of a defaultDataSpace if no data space is specified
+    // in queueBuffer.
+    // The initial default is HAL_DATASPACE_UNKNOWN
+    status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace);
+
     // Gets the next graphics buffer from the producer and locks it for CPU use,
     // filling out the passed-in locked buffer structure with the native pointer
     // and metadata. Returns BAD_VALUE if no new buffer is available, and
diff --git a/include/gui/GLConsumer.h b/include/gui/GLConsumer.h
index 053d1ed..4912580 100644
--- a/include/gui/GLConsumer.h
+++ b/include/gui/GLConsumer.h
@@ -198,6 +198,7 @@
     // These functions call the corresponding BufferQueue implementation
     // so the refactoring can proceed smoothly
     status_t setDefaultBufferFormat(PixelFormat defaultFormat);
+    status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace);
     status_t setConsumerUsageBits(uint32_t usage);
     status_t setTransformHint(uint32_t hint);
 
@@ -240,8 +241,7 @@
 
     // acquireBufferLocked overrides the ConsumerBase method to update the
     // mEglSlots array in addition to the ConsumerBase behavior.
-    virtual status_t acquireBufferLocked(BufferQueue::BufferItem *item,
-        nsecs_t presentWhen);
+    virtual status_t acquireBufferLocked(BufferItem *item, nsecs_t presentWhen);
 
     // releaseBufferLocked overrides the ConsumerBase method to update the
     // mEglSlots array in addition to the ConsumerBase.
@@ -259,7 +259,7 @@
     // This releases the buffer in the slot referenced by mCurrentTexture,
     // then updates state to refer to the BufferItem, which must be a
     // newly-acquired buffer.
-    status_t updateAndReleaseLocked(const BufferQueue::BufferItem& item);
+    status_t updateAndReleaseLocked(const BufferItem& item);
 
     // Binds mTexName and the current buffer to mTexTarget.  Uses
     // mCurrentTexture if it's set, mCurrentTextureImage if not.  If the
diff --git a/include/gui/IConsumerListener.h b/include/gui/IConsumerListener.h
index 260099e..3f39799 100644
--- a/include/gui/IConsumerListener.h
+++ b/include/gui/IConsumerListener.h
@@ -28,6 +28,8 @@
 namespace android {
 // ----------------------------------------------------------------------------
 
+class BufferItem;
+
 // ConsumerListener is the interface through which the BufferQueue notifies
 // the consumer of events that the consumer may wish to react to.  Because
 // the consumer will generally have a mutex that is locked during calls from
@@ -43,11 +45,24 @@
     // frame becomes available for consumption. This means that frames that
     // are queued while in asynchronous mode only trigger the callback if no
     // previous frames are pending. Frames queued while in synchronous mode
-    // always trigger the callback.
+    // always trigger the callback. The item passed to the callback will contain
+    // all of the information about the queued frame except for its
+    // GraphicBuffer pointer, which will always be null.
     //
     // This is called without any lock held and can be called concurrently
     // by multiple threads.
-    virtual void onFrameAvailable() = 0; /* Asynchronous */
+    virtual void onFrameAvailable(const BufferItem& item) = 0; /* Asynchronous */
+
+    // onFrameReplaced is called from queueBuffer if the frame being queued is
+    // replacing an existing slot in the queue. Any call to queueBuffer that
+    // doesn't call onFrameAvailable will call this callback instead. The item
+    // passed to the callback will contain all of the information about the
+    // queued frame except for its GraphicBuffer pointer, which will always be
+    // null.
+    //
+    // This is called without any lock held and can be called concurrently
+    // by multiple threads.
+    virtual void onFrameReplaced(const BufferItem& /* item */) {} /* Asynchronous */
 
     // onBuffersReleased is called to notify the buffer consumer that the
     // BufferQueue has released its references to one or more GraphicBuffers
diff --git a/include/gui/IGraphicBufferConsumer.h b/include/gui/IGraphicBufferConsumer.h
index 9ac23c2..0be09a2 100644
--- a/include/gui/IGraphicBufferConsumer.h
+++ b/include/gui/IGraphicBufferConsumer.h
@@ -34,6 +34,7 @@
 namespace android {
 // ----------------------------------------------------------------------------
 
+class BufferItem;
 class Fence;
 class GraphicBuffer;
 class IConsumerListener;
@@ -42,71 +43,6 @@
 class IGraphicBufferConsumer : public IInterface {
 
 public:
-
-    // public facing structure for BufferSlot
-    class BufferItem : public Flattenable<BufferItem> {
-        friend class Flattenable<BufferItem>;
-        size_t getPodSize() const;
-        size_t getFlattenedSize() const;
-        size_t getFdCount() const;
-        status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const;
-        status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count);
-
-    public:
-        // The default value of mBuf, used to indicate this doesn't correspond to a slot.
-        enum { INVALID_BUFFER_SLOT = -1 };
-        BufferItem();
-
-        // mGraphicBuffer points to the buffer allocated for this slot, or is NULL
-        // if the buffer in this slot has been acquired in the past (see
-        // BufferSlot.mAcquireCalled).
-        sp<GraphicBuffer> mGraphicBuffer;
-
-        // mFence is a fence that will signal when the buffer is idle.
-        sp<Fence> mFence;
-
-        // mCrop is the current crop rectangle for this buffer slot.
-        Rect mCrop;
-
-        // mTransform is the current transform flags for this buffer slot.
-        // refer to NATIVE_WINDOW_TRANSFORM_* in <window.h>
-        uint32_t mTransform;
-
-        // mScalingMode is the current scaling mode for this buffer slot.
-        // refer to NATIVE_WINDOW_SCALING_* in <window.h>
-        uint32_t mScalingMode;
-
-        // mTimestamp is the current timestamp for this buffer slot. This gets
-        // to set by queueBuffer each time this slot is queued. This value
-        // is guaranteed to be monotonically increasing for each newly
-        // acquired buffer.
-        int64_t mTimestamp;
-
-        // mIsAutoTimestamp indicates whether mTimestamp was generated
-        // automatically when the buffer was queued.
-        bool mIsAutoTimestamp;
-
-        // mFrameNumber is the number of the queued frame for this slot.
-        uint64_t mFrameNumber;
-
-        // mBuf is the slot index of this buffer (default INVALID_BUFFER_SLOT).
-        int mBuf;
-
-        // mIsDroppable whether this buffer was queued with the
-        // property that it can be replaced by a new buffer for the purpose of
-        // making sure dequeueBuffer() won't block.
-        // i.e.: was the BufferQueue in "mDequeueBufferCannotBlock" when this buffer
-        // was queued.
-        bool mIsDroppable;
-
-        // Indicates whether this buffer has been seen by a consumer yet
-        bool mAcquireCalled;
-
-        // Indicates this buffer must be transformed by the inverse transform of the screen
-        // it is displayed onto. This is applied after mTransform.
-        bool mTransformToDisplayInverse;
-    };
-
     enum {
         // Returned by releaseBuffer, after which the consumer must
         // free any references to the just-released buffer that it might have.
@@ -287,6 +223,14 @@
     // Return of a value other than NO_ERROR means an unknown error has occurred.
     virtual status_t setDefaultBufferFormat(PixelFormat defaultFormat) = 0;
 
+    // setDefaultBufferDataSpace is a request to the producer to provide buffers
+    // of the indicated dataSpace. The producer may ignore this request.
+    // The initial default is HAL_DATASPACE_UNKNOWN.
+    //
+    // Return of a value other than NO_ERROR means an unknown error has occurred.
+    virtual status_t setDefaultBufferDataSpace(
+            android_dataspace defaultDataSpace) = 0;
+
     // setConsumerUsageBits will turn on additional usage bits for dequeueBuffer.
     // These are merged with the bits passed to dequeueBuffer.  The values are
     // enumerated in gralloc.h, e.g. GRALLOC_USAGE_HW_RENDER; the default is 0.
@@ -304,6 +248,11 @@
     // Retrieve the sideband buffer stream, if any.
     virtual sp<NativeHandle> getSidebandStream() const = 0;
 
+    // setShadowQueueSize notifies the BufferQueue that the consumer is
+    // shadowing its queue and allows it to limit the number of buffers it is
+    // permitted to drop during acquire so as to not get out of sync.
+    virtual void setShadowQueueSize(size_t size) = 0;
+
     // dump state into a string
     virtual void dump(String8& result, const char* prefix) const = 0;
 
diff --git a/include/gui/IGraphicBufferProducer.h b/include/gui/IGraphicBufferProducer.h
index 4d3cd9a..5c50b2b 100644
--- a/include/gui/IGraphicBufferProducer.h
+++ b/include/gui/IGraphicBufferProducer.h
@@ -28,6 +28,7 @@
 #include <ui/Fence.h>
 #include <ui/GraphicBuffer.h>
 #include <ui/Rect.h>
+#include <ui/Region.h>
 
 namespace android {
 // ----------------------------------------------------------------------------
@@ -265,6 +266,7 @@
         inline QueueBufferInput(const Parcel& parcel);
         // timestamp - a monotonically increasing value in nanoseconds
         // isAutoTimestamp - if the timestamp was synthesized at queue time
+        // dataSpace - description of the contents, interpretation depends on format
         // crop - a crop rectangle that's used as a hint to the consumer
         // scalingMode - a set of flags from NATIVE_WINDOW_SCALING_* in <window.h>
         // transform - a set of flags from NATIVE_WINDOW_TRANSFORM_* in <window.h>
@@ -274,17 +276,21 @@
         // sticky - the sticky transform set in Surface (only used by the LEGACY
         //          camera mode).
         inline QueueBufferInput(int64_t timestamp, bool isAutoTimestamp,
-                const Rect& crop, int scalingMode, uint32_t transform, bool async,
-                const sp<Fence>& fence, uint32_t sticky = 0)
-        : timestamp(timestamp), isAutoTimestamp(isAutoTimestamp), crop(crop),
-          scalingMode(scalingMode), transform(transform), stickyTransform(sticky),
-          async(async), fence(fence) { }
+                android_dataspace dataSpace, const Rect& crop, int scalingMode,
+                uint32_t transform, bool async, const sp<Fence>& fence,
+                uint32_t sticky = 0)
+                : timestamp(timestamp), isAutoTimestamp(isAutoTimestamp),
+                  dataSpace(dataSpace), crop(crop), scalingMode(scalingMode),
+                  transform(transform), stickyTransform(sticky),
+                  async(async), fence(fence), surfaceDamage() { }
         inline void deflate(int64_t* outTimestamp, bool* outIsAutoTimestamp,
-                Rect* outCrop, int* outScalingMode, uint32_t* outTransform,
-                bool* outAsync, sp<Fence>* outFence,
+                android_dataspace* outDataSpace,
+                Rect* outCrop, int* outScalingMode,
+                uint32_t* outTransform, bool* outAsync, sp<Fence>* outFence,
                 uint32_t* outStickyTransform = NULL) const {
             *outTimestamp = timestamp;
             *outIsAutoTimestamp = bool(isAutoTimestamp);
+            *outDataSpace = dataSpace;
             *outCrop = crop;
             *outScalingMode = scalingMode;
             *outTransform = transform;
@@ -301,15 +307,20 @@
         status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const;
         status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count);
 
+        const Region& getSurfaceDamage() const { return surfaceDamage; }
+        void setSurfaceDamage(const Region& damage) { surfaceDamage = damage; }
+
     private:
         int64_t timestamp;
         int isAutoTimestamp;
+        android_dataspace dataSpace;
         Rect crop;
         int scalingMode;
         uint32_t transform;
         uint32_t stickyTransform;
         int async;
         sp<Fence> fence;
+        Region surfaceDamage;
     };
 
     // QueueBufferOutput must be a POD structure
@@ -447,6 +458,18 @@
     // allocated, this function has no effect.
     virtual void allocateBuffers(bool async, uint32_t width, uint32_t height,
             PixelFormat format, uint32_t usage) = 0;
+
+    // Sets whether dequeueBuffer is allowed to allocate new buffers.
+    //
+    // Normally dequeueBuffer does not discriminate between free slots which
+    // already have an allocated buffer and those which do not, and will
+    // allocate a new buffer if the slot doesn't have a buffer or if the slot's
+    // buffer doesn't match the requested size, format, or usage. This method
+    // allows the producer to restrict the eligible slots to those which already
+    // have an allocated buffer of the correct size, format, and usage. If no
+    // eligible slot is available, dequeueBuffer will block or return an error
+    // as usual.
+    virtual status_t allowAllocation(bool allow) = 0;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/include/gui/StreamSplitter.h b/include/gui/StreamSplitter.h
index f927953..8f47eb4 100644
--- a/include/gui/StreamSplitter.h
+++ b/include/gui/StreamSplitter.h
@@ -74,7 +74,7 @@
     // can block if there are too many outstanding buffers. If it blocks, it
     // will resume when onBufferReleasedByOutput releases a buffer back to the
     // input.
-    virtual void onFrameAvailable();
+    virtual void onFrameAvailable(const BufferItem& item);
 
     // From IConsumerListener
     // We don't care about released buffers because we detach each buffer as
diff --git a/include/gui/Surface.h b/include/gui/Surface.h
index 98f4f4f..fd6d48c 100644
--- a/include/gui/Surface.h
+++ b/include/gui/Surface.h
@@ -146,6 +146,8 @@
     int dispatchLock(va_list args);
     int dispatchUnlockAndPost(va_list args);
     int dispatchSetSidebandStream(va_list args);
+    int dispatchSetBuffersDataSpace(va_list args);
+    int dispatchSetSurfaceDamage(va_list args);
 
 protected:
     virtual int dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd);
@@ -167,13 +169,20 @@
     virtual int setBuffersTransform(uint32_t transform);
     virtual int setBuffersStickyTransform(uint32_t transform);
     virtual int setBuffersTimestamp(int64_t timestamp);
+    virtual int setBuffersDataSpace(android_dataspace dataSpace);
     virtual int setCrop(Rect const* rect);
     virtual int setUsage(uint32_t reqUsage);
+    virtual void setSurfaceDamage(android_native_rect_t* rects, size_t numRects);
 
 public:
     virtual int lock(ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds);
     virtual int unlockAndPost();
 
+    virtual int connect(int api, const sp<IProducerListener>& listener);
+    virtual int detachNextBuffer(sp<GraphicBuffer>* outBuffer,
+            sp<Fence>* outFence);
+    virtual int attachBuffer(ANativeWindowBuffer*);
+
 protected:
     enum { NUM_BUFFER_SLOTS = BufferQueue::NUM_BUFFER_SLOTS };
     enum { DEFAULT_FORMAT = PIXEL_FORMAT_RGBA_8888 };
@@ -222,6 +231,11 @@
     // a timestamp is auto-generated when queueBuffer is called.
     int64_t mTimestamp;
 
+    // mDataSpace is the buffer dataSpace that will be used for the next buffer
+    // queue operation. It defaults to HAL_DATASPACE_UNKNOWN, which
+    // means that the buffer contains some type of color data.
+    android_dataspace mDataSpace;
+
     // mCrop is the crop rectangle that will be used for the next buffer
     // that gets queued. It is set by calling setCrop.
     Rect mCrop;
@@ -284,7 +298,12 @@
     sp<GraphicBuffer>           mPostedBuffer;
     bool                        mConnectedToCpu;
 
-    // must be accessed from lock/unlock thread only
+    // When a CPU producer is attached, this reflects the region that the
+    // producer wished to update as well as whether the Surface was able to copy
+    // the previous buffer back to allow a partial update.
+    //
+    // When a non-CPU producer is attached, this reflects the surface damage
+    // (the change since the previous frame) passed in by the producer.
     Region mDirtyRegion;
 };
 
diff --git a/include/media/drm/DrmAPI.h b/include/media/drm/DrmAPI.h
index 4633b7e..49939fd 100644
--- a/include/media/drm/DrmAPI.h
+++ b/include/media/drm/DrmAPI.h
@@ -209,7 +209,9 @@
         // confirmed. The persisted record on the client is only removed after positive
         // confirmation that the server received the message using releaseSecureStops().
         virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops) = 0;
+        virtual status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) = 0;
         virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease) = 0;
+        virtual status_t releaseAllSecureStops() = 0;
 
         // Read a property value given the device property string.  There are a few forms
         // of property access methods, depending on the data type returned.
diff --git a/include/media/hardware/HardwareAPI.h b/include/media/hardware/HardwareAPI.h
index 90150c6..d5f42be 100644
--- a/include/media/hardware/HardwareAPI.h
+++ b/include/media/hardware/HardwareAPI.h
@@ -174,8 +174,8 @@
 
     Type mType;
     size_t mNumPlanes;              // number of planes
-    size_t mWidth;                  // width of largest plane
-    size_t mHeight;                 // height of largest plane
+    size_t mWidth;                  // width of largest plane (unpadded, as in nFrameWidth)
+    size_t mHeight;                 // height of largest plane (unpadded, as in nFrameHeight)
     size_t mBitDepth;               // useable bit depth
     struct PlaneInfo {
         size_t mOffset;             // offset of first pixel of the plane in bytes
@@ -194,12 +194,26 @@
 // other than invalid.  The color-format, frame width/height, and stride/
 // slice-height parameters are ones that are associated with a raw video
 // port (input or output), but the stride/slice height parameters may be
-// incorrect.  The component shall fill out the MediaImage structure that
+// incorrect. bUsingNativeBuffers is OMX_TRUE if native android buffers will
+// be used (while specifying this color format).
+//
+// The component shall fill out the MediaImage structure that
 // corresponds to the described raw video format, and the potentially corrected
 // stride and slice-height info.
 //
-// For non-YUV packed planar/semiplanar image formats, the component shall set
-// mNumPlanes to 0, and mType to MEDIA_IMAGE_TYPE_UNKNOWN.
+// The behavior is slightly different if bUsingNativeBuffers is OMX_TRUE,
+// though most implementations can ignore this difference. When using native buffers,
+// the component may change the configured color format to an optimized format.
+// Additionally, when allocating these buffers for flexible usecase, the framework
+// will set the SW_READ/WRITE_OFTEN usage flags. In this case (if bUsingNativeBuffers
+// is OMX_TRUE), the component shall fill out the MediaImage information for the
+// scenario when these SW-readable/writable buffers are locked using gralloc_lock.
+// Note, that these buffers may also be locked using gralloc_lock_ycbcr, which must
+// be supported for vendor-specific formats.
+//
+// For non-YUV packed planar/semiplanar image formats, or if bUsingNativeBuffers
+// is OMX_TRUE and the component does not support this color format with native
+// buffers, the component shall set mNumPlanes to 0, and mType to MEDIA_IMAGE_TYPE_UNKNOWN.
 struct DescribeColorFormatParams {
     OMX_U32 nSize;
     OMX_VERSIONTYPE nVersion;
@@ -209,6 +223,7 @@
     OMX_U32 nFrameHeight;
     OMX_U32 nStride;
     OMX_U32 nSliceHeight;
+    OMX_BOOL bUsingNativeBuffers;
 
     // output: fill out the MediaImage fields
     MediaImage sMediaImage;
diff --git a/include/media/openmax/OMX_AsString.h b/include/media/openmax/OMX_AsString.h
new file mode 100644
index 0000000..0f177a1
--- /dev/null
+++ b/include/media/openmax/OMX_AsString.h
@@ -0,0 +1,943 @@
+/*
+ * Copyright 2014 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.
+ */
+
+/* NOTE: This file contains several sections for individual OMX include files.
+   Each section has its own include guard.  This file should be included AFTER
+   the OMX include files. */
+
+#ifdef OMX_Audio_h
+/* asString definitions if media/openmax/OMX_Audio.h was included */
+
+#ifndef AS_STRING_FOR_OMX_AUDIO_H
+#define AS_STRING_FOR_OMX_AUDIO_H
+
+inline static const char *asString(OMX_AUDIO_CODINGTYPE i, const char *def = "??") {
+    switch (i) {
+        case OMX_AUDIO_CodingUnused:     return "Unused";      // unused
+        case OMX_AUDIO_CodingAutoDetect: return "AutoDetect";  // unused
+        case OMX_AUDIO_CodingPCM:        return "PCM";
+        case OMX_AUDIO_CodingADPCM:      return "ADPCM";       // unused
+        case OMX_AUDIO_CodingAMR:        return "AMR";
+        case OMX_AUDIO_CodingGSMFR:      return "GSMFR";
+        case OMX_AUDIO_CodingGSMEFR:     return "GSMEFR";      // unused
+        case OMX_AUDIO_CodingGSMHR:      return "GSMHR";       // unused
+        case OMX_AUDIO_CodingPDCFR:      return "PDCFR";       // unused
+        case OMX_AUDIO_CodingPDCEFR:     return "PDCEFR";      // unused
+        case OMX_AUDIO_CodingPDCHR:      return "PDCHR";       // unused
+        case OMX_AUDIO_CodingTDMAFR:     return "TDMAFR";      // unused
+        case OMX_AUDIO_CodingTDMAEFR:    return "TDMAEFR";     // unused
+        case OMX_AUDIO_CodingQCELP8:     return "QCELP8";      // unused
+        case OMX_AUDIO_CodingQCELP13:    return "QCELP13";     // unused
+        case OMX_AUDIO_CodingEVRC:       return "EVRC";        // unused
+        case OMX_AUDIO_CodingSMV:        return "SMV";         // unused
+        case OMX_AUDIO_CodingG711:       return "G711";
+        case OMX_AUDIO_CodingG723:       return "G723";        // unused
+        case OMX_AUDIO_CodingG726:       return "G726";        // unused
+        case OMX_AUDIO_CodingG729:       return "G729";        // unused
+        case OMX_AUDIO_CodingAAC:        return "AAC";
+        case OMX_AUDIO_CodingMP3:        return "MP3";
+        case OMX_AUDIO_CodingSBC:        return "SBC";         // unused
+        case OMX_AUDIO_CodingVORBIS:     return "VORBIS";
+        case OMX_AUDIO_CodingWMA:        return "WMA";         // unused
+        case OMX_AUDIO_CodingRA:         return "RA";          // unused
+        case OMX_AUDIO_CodingMIDI:       return "MIDI";        // unused
+        case OMX_AUDIO_CodingFLAC:       return "FLAC";
+        default:                         return def;
+    }
+}
+
+inline static const char *asString(OMX_AUDIO_PCMMODETYPE i, const char *def = "??") {
+    switch (i) {
+        case OMX_AUDIO_PCMModeLinear: return "Linear";
+        case OMX_AUDIO_PCMModeALaw:   return "ALaw";
+        case OMX_AUDIO_PCMModeMULaw:  return "MULaw";
+        default:                      return def;
+    }
+}
+
+inline static const char *asString(OMX_AUDIO_CHANNELTYPE i, const char *def = "??") {
+    switch (i) {
+        case OMX_AUDIO_ChannelNone: return "None";  // unused
+        case OMX_AUDIO_ChannelLF:   return "LF";
+        case OMX_AUDIO_ChannelRF:   return "RF";
+        case OMX_AUDIO_ChannelCF:   return "CF";
+        case OMX_AUDIO_ChannelLS:   return "LS";
+        case OMX_AUDIO_ChannelRS:   return "RS";
+        case OMX_AUDIO_ChannelLFE:  return "LFE";
+        case OMX_AUDIO_ChannelCS:   return "CS";
+        case OMX_AUDIO_ChannelLR:   return "LR";
+        case OMX_AUDIO_ChannelRR:   return "RR";
+        default:                    return def;
+    }
+}
+
+inline static const char *asString(OMX_AUDIO_CHANNELMODETYPE i, const char *def = "??") {
+    switch (i) {
+        case OMX_AUDIO_ChannelModeStereo:      return "Stereo";
+//      case OMX_AUDIO_ChannelModeJointStereo: return "JointStereo";
+//      case OMX_AUDIO_ChannelModeDual:        return "Dual";
+        case OMX_AUDIO_ChannelModeMono:        return "Mono";
+        default:                               return def;
+    }
+}
+
+inline static const char *asString(OMX_AUDIO_AACSTREAMFORMATTYPE i, const char *def = "??") {
+    switch (i) {
+//      case OMX_AUDIO_AACStreamFormatMP2ADTS: return "MP2ADTS";
+        case OMX_AUDIO_AACStreamFormatMP4ADTS: return "MP4ADTS";
+//      case OMX_AUDIO_AACStreamFormatMP4LOAS: return "MP4LOAS";
+//      case OMX_AUDIO_AACStreamFormatMP4LATM: return "MP4LATM";
+//      case OMX_AUDIO_AACStreamFormatADIF:    return "ADIF";
+        case OMX_AUDIO_AACStreamFormatMP4FF:   return "MP4FF";
+//      case OMX_AUDIO_AACStreamFormatRAW:     return "RAW";
+        default:                               return def;
+    }
+}
+
+inline static const char *asString(OMX_AUDIO_AMRFRAMEFORMATTYPE i, const char *def = "??") {
+    switch (i) {
+//      case OMX_AUDIO_AMRFrameFormatConformance: return "Conformance";
+//      case OMX_AUDIO_AMRFrameFormatIF1:         return "IF1";
+//      case OMX_AUDIO_AMRFrameFormatIF2:         return "IF2";
+        case OMX_AUDIO_AMRFrameFormatFSF:         return "FSF";
+//      case OMX_AUDIO_AMRFrameFormatRTPPayload:  return "RTPPayload";
+//      case OMX_AUDIO_AMRFrameFormatITU:         return "ITU";
+        default:                                  return def;
+    }
+}
+
+inline static const char *asString(OMX_AUDIO_AMRBANDMODETYPE i, const char *def = "??") {
+    switch (i) {
+        case OMX_AUDIO_AMRBandModeUnused: return "Unused";
+        case OMX_AUDIO_AMRBandModeNB0:    return "NB0";
+        case OMX_AUDIO_AMRBandModeNB1:    return "NB1";
+        case OMX_AUDIO_AMRBandModeNB2:    return "NB2";
+        case OMX_AUDIO_AMRBandModeNB3:    return "NB3";
+        case OMX_AUDIO_AMRBandModeNB4:    return "NB4";
+        case OMX_AUDIO_AMRBandModeNB5:    return "NB5";
+        case OMX_AUDIO_AMRBandModeNB6:    return "NB6";
+        case OMX_AUDIO_AMRBandModeNB7:    return "NB7";
+        case OMX_AUDIO_AMRBandModeWB0:    return "WB0";
+        case OMX_AUDIO_AMRBandModeWB1:    return "WB1";
+        case OMX_AUDIO_AMRBandModeWB2:    return "WB2";
+        case OMX_AUDIO_AMRBandModeWB3:    return "WB3";
+        case OMX_AUDIO_AMRBandModeWB4:    return "WB4";
+        case OMX_AUDIO_AMRBandModeWB5:    return "WB5";
+        case OMX_AUDIO_AMRBandModeWB6:    return "WB6";
+        case OMX_AUDIO_AMRBandModeWB7:    return "WB7";
+        case OMX_AUDIO_AMRBandModeWB8:    return "WB8";
+        default:                          return def;
+    }
+}
+
+inline static const char *asString(OMX_AUDIO_AMRDTXMODETYPE i, const char *def = "??") {
+    switch (i) {
+        case OMX_AUDIO_AMRDTXModeOff:    return "ModeOff";
+//      case OMX_AUDIO_AMRDTXModeOnVAD1: return "ModeOnVAD1";
+//      case OMX_AUDIO_AMRDTXModeOnVAD2: return "ModeOnVAD2";
+//      case OMX_AUDIO_AMRDTXModeOnAuto: return "ModeOnAuto";
+//      case OMX_AUDIO_AMRDTXasEFR:      return "asEFR";
+        default:                         return def;
+    }
+}
+
+#endif // AS_STRING_FOR_OMX_AUDIO_H
+
+#endif // OMX_Audio_h
+
+#ifdef OMX_AudioExt_h
+/* asString definitions if media/openmax/OMX_AudioExt.h was included */
+
+#ifndef AS_STRING_FOR_OMX_AUDIOEXT_H
+#define AS_STRING_FOR_OMX_AUDIOEXT_H
+
+inline static const char *asString(OMX_AUDIO_CODINGEXTTYPE i, const char *def = "??") {
+    switch (i) {
+        case OMX_AUDIO_CodingAndroidAC3:  return "AndroidAC3";
+        case OMX_AUDIO_CodingAndroidOPUS: return "AndroidOPUS";
+        default:                          return asString((OMX_AUDIO_CODINGTYPE)i, def);
+    }
+}
+
+#endif // AS_STRING_FOR_OMX_AUDIOEXT_H
+
+#endif // OMX_AudioExt_h
+
+#ifdef OMX_Component_h
+/* asString definitions if media/openmax/OMX_Component.h was included */
+
+#ifndef AS_STRING_FOR_OMX_COMPONENT_H
+#define AS_STRING_FOR_OMX_COMPONENT_H
+
+inline static const char *asString(OMX_PORTDOMAINTYPE i, const char *def = "??") {
+    switch (i) {
+        case OMX_PortDomainAudio: return "Audio";
+        case OMX_PortDomainVideo: return "Video";
+        case OMX_PortDomainImage: return "Image";
+//      case OMX_PortDomainOther: return "Other";
+        default:                  return def;
+    }
+}
+
+#endif // AS_STRING_FOR_OMX_COMPONENT_H
+
+#endif // OMX_Component_h
+
+#ifdef OMX_Core_h
+/* asString definitions if media/openmax/OMX_Core.h was included */
+
+#ifndef AS_STRING_FOR_OMX_CORE_H
+#define AS_STRING_FOR_OMX_CORE_H
+
+inline static const char *asString(OMX_COMMANDTYPE i, const char *def = "??") {
+    switch (i) {
+        case OMX_CommandStateSet:    return "StateSet";
+        case OMX_CommandFlush:       return "Flush";
+        case OMX_CommandPortDisable: return "PortDisable";
+        case OMX_CommandPortEnable:  return "PortEnable";
+//      case OMX_CommandMarkBuffer:  return "MarkBuffer";
+        default:                     return def;
+    }
+}
+
+inline static const char *asString(OMX_STATETYPE i, const char *def = "??") {
+    switch (i) {
+        case OMX_StateInvalid:          return "Invalid";
+        case OMX_StateLoaded:           return "Loaded";
+        case OMX_StateIdle:             return "Idle";
+        case OMX_StateExecuting:        return "Executing";
+//      case OMX_StatePause:            return "Pause";
+//      case OMX_StateWaitForResources: return "WaitForResources";
+        default:                        return def;
+    }
+}
+
+inline static const char *asString(OMX_ERRORTYPE i, const char *def = "??") {
+    switch (i) {
+        case OMX_ErrorNone:                               return "None";
+        case OMX_ErrorInsufficientResources:              return "InsufficientResources";
+        case OMX_ErrorUndefined:                          return "Undefined";
+        case OMX_ErrorInvalidComponentName:               return "InvalidComponentName";
+        case OMX_ErrorComponentNotFound:                  return "ComponentNotFound";
+        case OMX_ErrorInvalidComponent:                   return "InvalidComponent";       // unused
+        case OMX_ErrorBadParameter:                       return "BadParameter";
+        case OMX_ErrorNotImplemented:                     return "NotImplemented";
+        case OMX_ErrorUnderflow:                          return "Underflow";              // unused
+        case OMX_ErrorOverflow:                           return "Overflow";               // unused
+        case OMX_ErrorHardware:                           return "Hardware";               // unused
+        case OMX_ErrorInvalidState:                       return "InvalidState";
+        case OMX_ErrorStreamCorrupt:                      return "StreamCorrupt";
+        case OMX_ErrorPortsNotCompatible:                 return "PortsNotCompatible";     // unused
+        case OMX_ErrorResourcesLost:                      return "ResourcesLost";
+        case OMX_ErrorNoMore:                             return "NoMore";
+        case OMX_ErrorVersionMismatch:                    return "VersionMismatch";        // unused
+        case OMX_ErrorNotReady:                           return "NotReady";               // unused
+        case OMX_ErrorTimeout:                            return "Timeout";                // unused
+        case OMX_ErrorSameState:                          return "SameState";              // unused
+        case OMX_ErrorResourcesPreempted:                 return "ResourcesPreempted";     // unused
+        case OMX_ErrorPortUnresponsiveDuringAllocation:
+            return "PortUnresponsiveDuringAllocation";    // unused
+        case OMX_ErrorPortUnresponsiveDuringDeallocation:
+            return "PortUnresponsiveDuringDeallocation";  // unused
+        case OMX_ErrorPortUnresponsiveDuringStop:
+            return "PortUnresponsiveDuringStop";          // unused
+        case OMX_ErrorIncorrectStateTransition:
+            return "IncorrectStateTransition";            // unused
+        case OMX_ErrorIncorrectStateOperation:
+            return "IncorrectStateOperation";             // unused
+        case OMX_ErrorUnsupportedSetting:                 return "UnsupportedSetting";
+        case OMX_ErrorUnsupportedIndex:                   return "UnsupportedIndex";
+        case OMX_ErrorBadPortIndex:                       return "BadPortIndex";
+        case OMX_ErrorPortUnpopulated:                    return "PortUnpopulated";        // unused
+        case OMX_ErrorComponentSuspended:                 return "ComponentSuspended";     // unused
+        case OMX_ErrorDynamicResourcesUnavailable:
+            return "DynamicResourcesUnavailable";         // unused
+        case OMX_ErrorMbErrorsInFrame:                    return "MbErrorsInFrame";        // unused
+        case OMX_ErrorFormatNotDetected:                  return "FormatNotDetected";      // unused
+        case OMX_ErrorContentPipeOpenFailed:              return "ContentPipeOpenFailed";  // unused
+        case OMX_ErrorContentPipeCreationFailed:
+            return "ContentPipeCreationFailed";           // unused
+        case OMX_ErrorSeperateTablesUsed:                 return "SeperateTablesUsed";     // unused
+        case OMX_ErrorTunnelingUnsupported:               return "TunnelingUnsupported";   // unused
+        default:                                          return def;
+    }
+}
+
+inline static const char *asString(OMX_EVENTTYPE i, const char *def = "??") {
+    switch (i) {
+        case OMX_EventCmdComplete:               return "CmdComplete";
+        case OMX_EventError:                     return "Error";
+//      case OMX_EventMark:                      return "Mark";
+        case OMX_EventPortSettingsChanged:       return "PortSettingsChanged";
+        case OMX_EventBufferFlag:                return "BufferFlag";
+//      case OMX_EventResourcesAcquired:         return "ResourcesAcquired";
+//      case OMX_EventComponentResumed:          return "ComponentResumed";
+//      case OMX_EventDynamicResourcesAvailable: return "DynamicResourcesAvailable";
+//      case OMX_EventPortFormatDetected:        return "PortFormatDetected";
+        default:                                 return def;
+    }
+}
+
+#endif // AS_STRING_FOR_OMX_CORE_H
+
+#endif // OMX_Core_h
+
+#ifdef OMX_Image_h
+/* asString definitions if media/openmax/OMX_Image.h was included */
+
+#ifndef AS_STRING_FOR_OMX_IMAGE_H
+#define AS_STRING_FOR_OMX_IMAGE_H
+
+inline static const char *asString(OMX_IMAGE_CODINGTYPE i, const char *def = "??") {
+    switch (i) {
+        case OMX_IMAGE_CodingUnused:     return "Unused";
+        case OMX_IMAGE_CodingAutoDetect: return "AutoDetect";  // unused
+        case OMX_IMAGE_CodingJPEG:       return "JPEG";
+        case OMX_IMAGE_CodingJPEG2K:     return "JPEG2K";      // unused
+        case OMX_IMAGE_CodingEXIF:       return "EXIF";        // unused
+        case OMX_IMAGE_CodingTIFF:       return "TIFF";        // unused
+        case OMX_IMAGE_CodingGIF:        return "GIF";         // unused
+        case OMX_IMAGE_CodingPNG:        return "PNG";         // unused
+        case OMX_IMAGE_CodingLZW:        return "LZW";         // unused
+        case OMX_IMAGE_CodingBMP:        return "BMP";         // unused
+        default:                         return def;
+    }
+}
+
+#endif // AS_STRING_FOR_OMX_IMAGE_H
+
+#endif // OMX_Image_h
+
+#ifdef OMX_Index_h
+/* asString definitions if media/openmax/OMX_Index.h was included */
+
+#ifndef AS_STRING_FOR_OMX_INDEX_H
+#define AS_STRING_FOR_OMX_INDEX_H
+
+inline static const char *asString(OMX_INDEXTYPE i, const char *def = "??") {
+    switch (i) {
+//      case OMX_IndexParamPriorityMgmt:                    return "ParamPriorityMgmt";
+//      case OMX_IndexParamAudioInit:                       return "ParamAudioInit";
+//      case OMX_IndexParamImageInit:                       return "ParamImageInit";
+//      case OMX_IndexParamVideoInit:                       return "ParamVideoInit";
+//      case OMX_IndexParamOtherInit:                       return "ParamOtherInit";
+//      case OMX_IndexParamNumAvailableStreams:             return "ParamNumAvailableStreams";
+//      case OMX_IndexParamActiveStream:                    return "ParamActiveStream";
+//      case OMX_IndexParamSuspensionPolicy:                return "ParamSuspensionPolicy";
+//      case OMX_IndexParamComponentSuspended:              return "ParamComponentSuspended";
+//      case OMX_IndexConfigCapturing:                      return "ConfigCapturing";
+//      case OMX_IndexConfigCaptureMode:                    return "ConfigCaptureMode";
+//      case OMX_IndexAutoPauseAfterCapture:                return "AutoPauseAfterCapture";
+//      case OMX_IndexParamContentURI:                      return "ParamContentURI";
+//      case OMX_IndexParamCustomContentPipe:               return "ParamCustomContentPipe";
+//      case OMX_IndexParamDisableResourceConcealment:
+//          return "ParamDisableResourceConcealment";
+//      case OMX_IndexConfigMetadataItemCount:              return "ConfigMetadataItemCount";
+//      case OMX_IndexConfigContainerNodeCount:             return "ConfigContainerNodeCount";
+//      case OMX_IndexConfigMetadataItem:                   return "ConfigMetadataItem";
+//      case OMX_IndexConfigCounterNodeID:                  return "ConfigCounterNodeID";
+//      case OMX_IndexParamMetadataFilterType:              return "ParamMetadataFilterType";
+//      case OMX_IndexParamMetadataKeyFilter:               return "ParamMetadataKeyFilter";
+//      case OMX_IndexConfigPriorityMgmt:                   return "ConfigPriorityMgmt";
+        case OMX_IndexParamStandardComponentRole:           return "ParamStandardComponentRole";
+        case OMX_IndexParamPortDefinition:                  return "ParamPortDefinition";
+//      case OMX_IndexParamCompBufferSupplier:              return "ParamCompBufferSupplier";
+        case OMX_IndexParamAudioPortFormat:                 return "ParamAudioPortFormat";
+        case OMX_IndexParamAudioPcm:                        return "ParamAudioPcm";
+        case OMX_IndexParamAudioAac:                        return "ParamAudioAac";
+//      case OMX_IndexParamAudioRa:                         return "ParamAudioRa";
+        case OMX_IndexParamAudioMp3:                        return "ParamAudioMp3";
+//      case OMX_IndexParamAudioAdpcm:                      return "ParamAudioAdpcm";
+//      case OMX_IndexParamAudioG723:                       return "ParamAudioG723";
+//      case OMX_IndexParamAudioG729:                       return "ParamAudioG729";
+        case OMX_IndexParamAudioAmr:                        return "ParamAudioAmr";
+//      case OMX_IndexParamAudioWma:                        return "ParamAudioWma";
+//      case OMX_IndexParamAudioSbc:                        return "ParamAudioSbc";
+//      case OMX_IndexParamAudioMidi:                       return "ParamAudioMidi";
+//      case OMX_IndexParamAudioGsm_FR:                     return "ParamAudioGsm_FR";
+//      case OMX_IndexParamAudioMidiLoadUserSound:          return "ParamAudioMidiLoadUserSound";
+//      case OMX_IndexParamAudioG726:                       return "ParamAudioG726";
+//      case OMX_IndexParamAudioGsm_EFR:                    return "ParamAudioGsm_EFR";
+//      case OMX_IndexParamAudioGsm_HR:                     return "ParamAudioGsm_HR";
+//      case OMX_IndexParamAudioPdc_FR:                     return "ParamAudioPdc_FR";
+//      case OMX_IndexParamAudioPdc_EFR:                    return "ParamAudioPdc_EFR";
+//      case OMX_IndexParamAudioPdc_HR:                     return "ParamAudioPdc_HR";
+//      case OMX_IndexParamAudioTdma_FR:                    return "ParamAudioTdma_FR";
+//      case OMX_IndexParamAudioTdma_EFR:                   return "ParamAudioTdma_EFR";
+//      case OMX_IndexParamAudioQcelp8:                     return "ParamAudioQcelp8";
+//      case OMX_IndexParamAudioQcelp13:                    return "ParamAudioQcelp13";
+//      case OMX_IndexParamAudioEvrc:                       return "ParamAudioEvrc";
+//      case OMX_IndexParamAudioSmv:                        return "ParamAudioSmv";
+        case OMX_IndexParamAudioVorbis:                     return "ParamAudioVorbis";
+        case OMX_IndexParamAudioFlac:                       return "ParamAudioFlac";
+//      case OMX_IndexConfigAudioMidiImmediateEvent:        return "ConfigAudioMidiImmediateEvent";
+//      case OMX_IndexConfigAudioMidiControl:               return "ConfigAudioMidiControl";
+//      case OMX_IndexConfigAudioMidiSoundBankProgram:
+//          return "ConfigAudioMidiSoundBankProgram";
+//      case OMX_IndexConfigAudioMidiStatus:                return "ConfigAudioMidiStatus";
+//      case OMX_IndexConfigAudioMidiMetaEvent:             return "ConfigAudioMidiMetaEvent";
+//      case OMX_IndexConfigAudioMidiMetaEventData:         return "ConfigAudioMidiMetaEventData";
+//      case OMX_IndexConfigAudioVolume:                    return "ConfigAudioVolume";
+//      case OMX_IndexConfigAudioBalance:                   return "ConfigAudioBalance";
+//      case OMX_IndexConfigAudioChannelMute:               return "ConfigAudioChannelMute";
+//      case OMX_IndexConfigAudioMute:                      return "ConfigAudioMute";
+//      case OMX_IndexConfigAudioLoudness:                  return "ConfigAudioLoudness";
+//      case OMX_IndexConfigAudioEchoCancelation:           return "ConfigAudioEchoCancelation";
+//      case OMX_IndexConfigAudioNoiseReduction:            return "ConfigAudioNoiseReduction";
+//      case OMX_IndexConfigAudioBass:                      return "ConfigAudioBass";
+//      case OMX_IndexConfigAudioTreble:                    return "ConfigAudioTreble";
+//      case OMX_IndexConfigAudioStereoWidening:            return "ConfigAudioStereoWidening";
+//      case OMX_IndexConfigAudioChorus:                    return "ConfigAudioChorus";
+//      case OMX_IndexConfigAudioEqualizer:                 return "ConfigAudioEqualizer";
+//      case OMX_IndexConfigAudioReverberation:             return "ConfigAudioReverberation";
+//      case OMX_IndexConfigAudioChannelVolume:             return "ConfigAudioChannelVolume";
+//      case OMX_IndexParamImagePortFormat:                 return "ParamImagePortFormat";
+//      case OMX_IndexParamFlashControl:                    return "ParamFlashControl";
+//      case OMX_IndexConfigFocusControl:                   return "ConfigFocusControl";
+//      case OMX_IndexParamQFactor:                         return "ParamQFactor";
+//      case OMX_IndexParamQuantizationTable:               return "ParamQuantizationTable";
+//      case OMX_IndexParamHuffmanTable:                    return "ParamHuffmanTable";
+//      case OMX_IndexConfigFlashControl:                   return "ConfigFlashControl";
+        case OMX_IndexParamVideoPortFormat:                 return "ParamVideoPortFormat";
+//      case OMX_IndexParamVideoQuantization:               return "ParamVideoQuantization";
+//      case OMX_IndexParamVideoFastUpdate:                 return "ParamVideoFastUpdate";
+        case OMX_IndexParamVideoBitrate:                    return "ParamVideoBitrate";
+//      case OMX_IndexParamVideoMotionVector:               return "ParamVideoMotionVector";
+        case OMX_IndexParamVideoIntraRefresh:               return "ParamVideoIntraRefresh";
+        case OMX_IndexParamVideoErrorCorrection:            return "ParamVideoErrorCorrection";
+//      case OMX_IndexParamVideoVBSMC:                      return "ParamVideoVBSMC";
+//      case OMX_IndexParamVideoMpeg2:                      return "ParamVideoMpeg2";
+        case OMX_IndexParamVideoMpeg4:                      return "ParamVideoMpeg4";
+//      case OMX_IndexParamVideoWmv:                        return "ParamVideoWmv";
+//      case OMX_IndexParamVideoRv:                         return "ParamVideoRv";
+        case OMX_IndexParamVideoAvc:                        return "ParamVideoAvc";
+        case OMX_IndexParamVideoH263:                       return "ParamVideoH263";
+        case OMX_IndexParamVideoProfileLevelQuerySupported:
+            return "ParamVideoProfileLevelQuerySupported";
+        case OMX_IndexParamVideoProfileLevelCurrent:        return "ParamVideoProfileLevelCurrent";
+        case OMX_IndexConfigVideoBitrate:                   return "ConfigVideoBitrate";
+//      case OMX_IndexConfigVideoFramerate:                 return "ConfigVideoFramerate";
+        case OMX_IndexConfigVideoIntraVOPRefresh:           return "ConfigVideoIntraVOPRefresh";
+//      case OMX_IndexConfigVideoIntraMBRefresh:            return "ConfigVideoIntraMBRefresh";
+//      case OMX_IndexConfigVideoMBErrorReporting:          return "ConfigVideoMBErrorReporting";
+//      case OMX_IndexParamVideoMacroblocksPerFrame:        return "ParamVideoMacroblocksPerFrame";
+//      case OMX_IndexConfigVideoMacroBlockErrorMap:        return "ConfigVideoMacroBlockErrorMap";
+//      case OMX_IndexParamVideoSliceFMO:                   return "ParamVideoSliceFMO";
+//      case OMX_IndexConfigVideoAVCIntraPeriod:            return "ConfigVideoAVCIntraPeriod";
+//      case OMX_IndexConfigVideoNalSize:                   return "ConfigVideoNalSize";
+//      case OMX_IndexParamCommonDeblocking:                return "ParamCommonDeblocking";
+//      case OMX_IndexParamCommonSensorMode:                return "ParamCommonSensorMode";
+//      case OMX_IndexParamCommonInterleave:                return "ParamCommonInterleave";
+//      case OMX_IndexConfigCommonColorFormatConversion:
+//          return "ConfigCommonColorFormatConversion";
+        case OMX_IndexConfigCommonScale:                    return "ConfigCommonScale";
+//      case OMX_IndexConfigCommonImageFilter:              return "ConfigCommonImageFilter";
+//      case OMX_IndexConfigCommonColorEnhancement:         return "ConfigCommonColorEnhancement";
+//      case OMX_IndexConfigCommonColorKey:                 return "ConfigCommonColorKey";
+//      case OMX_IndexConfigCommonColorBlend:               return "ConfigCommonColorBlend";
+//      case OMX_IndexConfigCommonFrameStabilisation:       return "ConfigCommonFrameStabilisation";
+//      case OMX_IndexConfigCommonRotate:                   return "ConfigCommonRotate";
+//      case OMX_IndexConfigCommonMirror:                   return "ConfigCommonMirror";
+//      case OMX_IndexConfigCommonOutputPosition:           return "ConfigCommonOutputPosition";
+        case OMX_IndexConfigCommonInputCrop:                return "ConfigCommonInputCrop";
+        case OMX_IndexConfigCommonOutputCrop:               return "ConfigCommonOutputCrop";
+//      case OMX_IndexConfigCommonDigitalZoom:              return "ConfigCommonDigitalZoom";
+//      case OMX_IndexConfigCommonOpticalZoom:              return "ConfigCommonOpticalZoom";
+//      case OMX_IndexConfigCommonWhiteBalance:             return "ConfigCommonWhiteBalance";
+//      case OMX_IndexConfigCommonExposure:                 return "ConfigCommonExposure";
+//      case OMX_IndexConfigCommonContrast:                 return "ConfigCommonContrast";
+//      case OMX_IndexConfigCommonBrightness:               return "ConfigCommonBrightness";
+//      case OMX_IndexConfigCommonBacklight:                return "ConfigCommonBacklight";
+//      case OMX_IndexConfigCommonGamma:                    return "ConfigCommonGamma";
+//      case OMX_IndexConfigCommonSaturation:               return "ConfigCommonSaturation";
+//      case OMX_IndexConfigCommonLightness:                return "ConfigCommonLightness";
+//      case OMX_IndexConfigCommonExclusionRect:            return "ConfigCommonExclusionRect";
+//      case OMX_IndexConfigCommonDithering:                return "ConfigCommonDithering";
+//      case OMX_IndexConfigCommonPlaneBlend:               return "ConfigCommonPlaneBlend";
+//      case OMX_IndexConfigCommonExposureValue:            return "ConfigCommonExposureValue";
+//      case OMX_IndexConfigCommonOutputSize:               return "ConfigCommonOutputSize";
+//      case OMX_IndexParamCommonExtraQuantData:            return "ParamCommonExtraQuantData";
+//      case OMX_IndexConfigCommonFocusRegion:              return "ConfigCommonFocusRegion";
+//      case OMX_IndexConfigCommonFocusStatus:              return "ConfigCommonFocusStatus";
+//      case OMX_IndexConfigCommonTransitionEffect:         return "ConfigCommonTransitionEffect";
+//      case OMX_IndexParamOtherPortFormat:                 return "ParamOtherPortFormat";
+//      case OMX_IndexConfigOtherPower:                     return "ConfigOtherPower";
+//      case OMX_IndexConfigOtherStats:                     return "ConfigOtherStats";
+//      case OMX_IndexConfigTimeScale:                      return "ConfigTimeScale";
+//      case OMX_IndexConfigTimeClockState:                 return "ConfigTimeClockState";
+//      case OMX_IndexConfigTimeActiveRefClock:             return "ConfigTimeActiveRefClock";
+//      case OMX_IndexConfigTimeCurrentMediaTime:           return "ConfigTimeCurrentMediaTime";
+//      case OMX_IndexConfigTimeCurrentWallTime:            return "ConfigTimeCurrentWallTime";
+//      case OMX_IndexConfigTimeCurrentAudioReference:
+//          return "ConfigTimeCurrentAudioReference";
+//      case OMX_IndexConfigTimeCurrentVideoReference:
+//          return "ConfigTimeCurrentVideoReference";
+//      case OMX_IndexConfigTimeMediaTimeRequest:           return "ConfigTimeMediaTimeRequest";
+//      case OMX_IndexConfigTimeClientStartTime:            return "ConfigTimeClientStartTime";
+//      case OMX_IndexConfigTimePosition:                   return "ConfigTimePosition";
+//      case OMX_IndexConfigTimeSeekMode:                   return "ConfigTimeSeekMode";
+        default:                                            return def;
+    }
+}
+
+#endif // AS_STRING_FOR_OMX_INDEX_H
+
+#endif // OMX_Index_h
+
+#ifdef OMX_IndexExt_h
+/* asString definitions if media/openmax/OMX_IndexExt.h was included */
+
+#ifndef AS_STRING_FOR_OMX_INDEXEXT_H
+#define AS_STRING_FOR_OMX_INDEXEXT_H
+
+inline static const char *asString(OMX_INDEXEXTTYPE i, const char *def = "??") {
+    switch (i) {
+//      case OMX_IndexConfigCallbackRequest:            return "ConfigCallbackRequest";
+//      case OMX_IndexConfigCommitMode:                 return "ConfigCommitMode";
+//      case OMX_IndexConfigCommit:                     return "ConfigCommit";
+        case OMX_IndexParamAudioAndroidAc3:             return "ParamAudioAndroidAc3";
+        case OMX_IndexParamAudioAndroidOpus:            return "ParamAudioAndroidOpus";
+        case OMX_IndexParamAudioAndroidAacPresentation: return "ParamAudioAndroidAacPresentation";
+//      case OMX_IndexParamNalStreamFormatSupported:    return "ParamNalStreamFormatSupported";
+//      case OMX_IndexParamNalStreamFormat:             return "ParamNalStreamFormat";
+//      case OMX_IndexParamNalStreamFormatSelect:       return "ParamNalStreamFormatSelect";
+        case OMX_IndexParamVideoVp8:                    return "ParamVideoVp8";
+//      case OMX_IndexConfigVideoVp8ReferenceFrame:     return "ConfigVideoVp8ReferenceFrame";
+//      case OMX_IndexConfigVideoVp8ReferenceFrameType: return "ConfigVideoVp8ReferenceFrameType";
+        case OMX_IndexParamVideoAndroidVp8Encoder:      return "ParamVideoAndroidVp8Encoder";
+        case OMX_IndexParamVideoHevc:                   return "ParamVideoHevc";
+//      case OMX_IndexParamSliceSegments:               return "ParamSliceSegments";
+        case OMX_IndexConfigAutoFramerateConversion:    return "ConfigAutoFramerateConversion";
+        default:                                        return asString((OMX_INDEXTYPE)i, def);
+    }
+}
+
+#endif // AS_STRING_FOR_OMX_INDEXEXT_H
+
+#endif // OMX_IndexExt_h
+
+#ifdef OMX_IVCommon_h
+/* asString definitions if media/openmax/OMX_IVCommon.h was included */
+
+#ifndef AS_STRING_FOR_OMX_IVCOMMON_H
+#define AS_STRING_FOR_OMX_IVCOMMON_H
+
+inline static const char *asString(OMX_COLOR_FORMATTYPE i, const char *def = "??") {
+    switch (i) {
+        case OMX_COLOR_FormatUnused:
+            return "COLOR_FormatUnused";
+        case OMX_COLOR_FormatMonochrome:
+            return "COLOR_FormatMonochrome";
+        case OMX_COLOR_Format8bitRGB332:
+            return "COLOR_Format8bitRGB332";
+        case OMX_COLOR_Format12bitRGB444:
+            return "COLOR_Format12bitRGB444";
+        case OMX_COLOR_Format16bitARGB4444:
+            return "COLOR_Format16bitARGB4444";
+        case OMX_COLOR_Format16bitARGB1555:
+            return "COLOR_Format16bitARGB1555";
+        case OMX_COLOR_Format16bitRGB565:
+            return "COLOR_Format16bitRGB565";
+        case OMX_COLOR_Format16bitBGR565:
+            return "COLOR_Format16bitBGR565";
+        case OMX_COLOR_Format18bitRGB666:
+            return "COLOR_Format18bitRGB666";
+        case OMX_COLOR_Format18bitARGB1665:
+            return "COLOR_Format18bitARGB1665";
+        case OMX_COLOR_Format19bitARGB1666:
+            return "COLOR_Format19bitARGB1666";
+        case OMX_COLOR_Format24bitRGB888:
+            return "COLOR_Format24bitRGB888";
+        case OMX_COLOR_Format24bitBGR888:
+            return "COLOR_Format24bitBGR888";
+        case OMX_COLOR_Format24bitARGB1887:
+            return "COLOR_Format24bitARGB1887";
+        case OMX_COLOR_Format25bitARGB1888:
+            return "COLOR_Format25bitARGB1888";
+        case OMX_COLOR_Format32bitBGRA8888:
+            return "COLOR_Format32bitBGRA8888";
+        case OMX_COLOR_Format32bitARGB8888:
+            return "COLOR_Format32bitARGB8888";
+        case OMX_COLOR_FormatYUV411Planar:
+            return "COLOR_FormatYUV411Planar";
+        case OMX_COLOR_FormatYUV411PackedPlanar:
+            return "COLOR_FormatYUV411PackedPlanar";
+        case OMX_COLOR_FormatYUV420Planar:
+            return "COLOR_FormatYUV420Planar";
+        case OMX_COLOR_FormatYUV420PackedPlanar:
+            return "COLOR_FormatYUV420PackedPlanar";
+        case OMX_COLOR_FormatYUV420SemiPlanar:
+            return "COLOR_FormatYUV420SemiPlanar";
+        case OMX_COLOR_FormatYUV422Planar:
+            return "COLOR_FormatYUV422Planar";
+        case OMX_COLOR_FormatYUV422PackedPlanar:
+            return "COLOR_FormatYUV422PackedPlanar";
+        case OMX_COLOR_FormatYUV422SemiPlanar:
+            return "COLOR_FormatYUV422SemiPlanar";
+        case OMX_COLOR_FormatYCbYCr:
+            return "COLOR_FormatYCbYCr";
+        case OMX_COLOR_FormatYCrYCb:
+            return "COLOR_FormatYCrYCb";
+        case OMX_COLOR_FormatCbYCrY:
+            return "COLOR_FormatCbYCrY";
+        case OMX_COLOR_FormatCrYCbY:
+            return "COLOR_FormatCrYCbY";
+        case OMX_COLOR_FormatYUV444Interleaved:
+            return "COLOR_FormatYUV444Interleaved";
+        case OMX_COLOR_FormatRawBayer8bit:
+            return "COLOR_FormatRawBayer8bit";
+        case OMX_COLOR_FormatRawBayer10bit:
+            return "COLOR_FormatRawBayer10bit";
+        case OMX_COLOR_FormatRawBayer8bitcompressed:
+            return "COLOR_FormatRawBayer8bitcompressed";
+        case OMX_COLOR_FormatL2:
+            return "COLOR_FormatL2";
+        case OMX_COLOR_FormatL4:
+            return "COLOR_FormatL4";
+        case OMX_COLOR_FormatL8:
+            return "COLOR_FormatL8";
+        case OMX_COLOR_FormatL16:
+            return "COLOR_FormatL16";
+        case OMX_COLOR_FormatL24:
+            return "COLOR_FormatL24";
+        case OMX_COLOR_FormatL32:
+            return "COLOR_FormatL32";
+        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
+            return "COLOR_FormatYUV420PackedSemiPlanar";
+        case OMX_COLOR_FormatYUV422PackedSemiPlanar:
+            return "COLOR_FormatYUV422PackedSemiPlanar";
+        case OMX_COLOR_Format18BitBGR666:
+            return "COLOR_Format18BitBGR666";
+        case OMX_COLOR_Format24BitARGB6666:
+            return "COLOR_Format24BitARGB6666";
+        case OMX_COLOR_Format24BitABGR6666:
+            return "COLOR_Format24BitABGR6666";
+        case OMX_COLOR_FormatAndroidOpaque:
+            return "COLOR_FormatAndroidOpaque";
+        case OMX_COLOR_FormatYUV420Flexible:
+            return "COLOR_FormatYUV420Flexible";
+        case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
+            return "TI_COLOR_FormatYUV420PackedSemiPlanar";
+        case OMX_QCOM_COLOR_FormatYVU420SemiPlanar:
+            return "QCOM_COLOR_FormatYVU420SemiPlanar";
+//      case OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka:
+//          return "QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka";
+//      case OMX_SEC_COLOR_FormatNV12Tiled:
+//          return "SEC_COLOR_FormatNV12Tiled";
+//      case OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m:
+//          return "QCOM_COLOR_FormatYUV420PackedSemiPlanar32m";
+        default:
+            return def;
+    }
+}
+
+#endif // AS_STRING_FOR_OMX_IVCOMMON_H
+
+#endif // OMX_IVCommon_h
+
+#ifdef OMX_Types_h
+/* asString definitions if media/openmax/OMX_Types.h was included */
+
+#ifndef AS_STRING_FOR_OMX_TYPES_H
+#define AS_STRING_FOR_OMX_TYPES_H
+
+inline static const char *asString(OMX_BOOL i, const char *def = "??") {
+    switch (i) {
+        case OMX_FALSE: return "FALSE";
+        case OMX_TRUE:  return "TRUE";
+        default:        return def;
+    }
+}
+
+inline static const char *asString(OMX_DIRTYPE i, const char *def = "??") {
+    switch (i) {
+        case OMX_DirInput:  return "Input";
+        case OMX_DirOutput: return "Output";
+        default:            return def;
+    }
+}
+
+inline static const char *asString(OMX_ENDIANTYPE i, const char *def = "??") {
+    switch (i) {
+        case OMX_EndianBig:    return "Big";
+//      case OMX_EndianLittle: return "Little";
+        default:               return def;
+    }
+}
+
+inline static const char *asString(OMX_NUMERICALDATATYPE i, const char *def = "??") {
+    switch (i) {
+        case OMX_NumericalDataSigned:   return "Signed";
+//      case OMX_NumericalDataUnsigned: return "Unsigned";
+        default:                        return def;
+    }
+}
+
+#endif // AS_STRING_FOR_OMX_TYPES_H
+
+#endif // OMX_Types_h
+
+#ifdef OMX_Video_h
+/* asString definitions if media/openmax/OMX_Video.h was included */
+
+#ifndef AS_STRING_FOR_OMX_VIDEO_H
+#define AS_STRING_FOR_OMX_VIDEO_H
+
+inline static const char *asString(OMX_VIDEO_CODINGTYPE i, const char *def = "??") {
+    switch (i) {
+        case OMX_VIDEO_CodingUnused:     return "Unused";
+        case OMX_VIDEO_CodingAutoDetect: return "AutoDetect";  // unused
+        case OMX_VIDEO_CodingMPEG2:      return "MPEG2";
+        case OMX_VIDEO_CodingH263:       return "H263";
+        case OMX_VIDEO_CodingMPEG4:      return "MPEG4";
+        case OMX_VIDEO_CodingWMV:        return "WMV";         // unused
+        case OMX_VIDEO_CodingRV:         return "RV";          // unused
+        case OMX_VIDEO_CodingAVC:        return "AVC";
+        case OMX_VIDEO_CodingMJPEG:      return "MJPEG";       // unused
+        case OMX_VIDEO_CodingVP8:        return "VP8";
+        case OMX_VIDEO_CodingVP9:        return "VP9";
+        case OMX_VIDEO_CodingHEVC:       return "HEVC";
+        default:                         return def;
+    }
+}
+
+inline static const char *asString(OMX_VIDEO_CONTROLRATETYPE i, const char *def = "??") {
+    switch (i) {
+//      case OMX_Video_ControlRateDisable:            return "Disable";
+        case OMX_Video_ControlRateVariable:           return "Variable";
+        case OMX_Video_ControlRateConstant:           return "Constant";
+//      case OMX_Video_ControlRateVariableSkipFrames: return "VariableSkipFrames";
+//      case OMX_Video_ControlRateConstantSkipFrames: return "ConstantSkipFrames";
+        default:                                      return def;
+    }
+}
+
+inline static const char *asString(OMX_VIDEO_INTRAREFRESHTYPE i, const char *def = "??") {
+    switch (i) {
+        case OMX_VIDEO_IntraRefreshCyclic:   return "Cyclic";
+        case OMX_VIDEO_IntraRefreshAdaptive: return "Adaptive";
+        case OMX_VIDEO_IntraRefreshBoth:     return "Both";
+        default:                             return def;
+    }
+}
+
+inline static const char *asString(OMX_VIDEO_H263PROFILETYPE i, const char *def = "??") {
+    switch (i) {
+        case OMX_VIDEO_H263ProfileBaseline:           return "Baseline";
+        case OMX_VIDEO_H263ProfileH320Coding:         return "H320Coding";
+        case OMX_VIDEO_H263ProfileBackwardCompatible: return "BackwardCompatible";
+        case OMX_VIDEO_H263ProfileISWV2:              return "ISWV2";
+        case OMX_VIDEO_H263ProfileISWV3:              return "ISWV3";
+        case OMX_VIDEO_H263ProfileHighCompression:    return "HighCompression";
+        case OMX_VIDEO_H263ProfileInternet:           return "Internet";
+        case OMX_VIDEO_H263ProfileInterlace:          return "Interlace";
+        case OMX_VIDEO_H263ProfileHighLatency:        return "HighLatency";
+        default:                                      return def;
+    }
+}
+
+inline static const char *asString(OMX_VIDEO_H263LEVELTYPE i, const char *def = "??") {
+    switch (i) {
+        case OMX_VIDEO_H263Level10: return "Level10";
+        case OMX_VIDEO_H263Level20: return "Level20";
+        case OMX_VIDEO_H263Level30: return "Level30";
+        case OMX_VIDEO_H263Level40: return "Level40";
+        case OMX_VIDEO_H263Level45: return "Level45";
+        case OMX_VIDEO_H263Level50: return "Level50";
+        case OMX_VIDEO_H263Level60: return "Level60";
+        case OMX_VIDEO_H263Level70: return "Level70";
+        default:                    return def;
+    }
+}
+
+inline static const char *asString(OMX_VIDEO_PICTURETYPE i, const char *def = "??") {
+    switch (i) {
+        case OMX_VIDEO_PictureTypeI:  return "I";
+        case OMX_VIDEO_PictureTypeP:  return "P";
+        case OMX_VIDEO_PictureTypeB:  return "B";
+//      case OMX_VIDEO_PictureTypeSI: return "SI";
+//      case OMX_VIDEO_PictureTypeSP: return "SP";
+//      case OMX_VIDEO_PictureTypeEI: return "EI";
+//      case OMX_VIDEO_PictureTypeEP: return "EP";
+//      case OMX_VIDEO_PictureTypeS:  return "S";
+        default:                      return def;
+    }
+}
+
+inline static const char *asString(OMX_VIDEO_MPEG4PROFILETYPE i, const char *def = "??") {
+    switch (i) {
+        case OMX_VIDEO_MPEG4ProfileSimple:           return "Simple";
+        case OMX_VIDEO_MPEG4ProfileSimpleScalable:   return "SimpleScalable";
+        case OMX_VIDEO_MPEG4ProfileCore:             return "Core";
+        case OMX_VIDEO_MPEG4ProfileMain:             return "Main";
+        case OMX_VIDEO_MPEG4ProfileNbit:             return "Nbit";
+        case OMX_VIDEO_MPEG4ProfileScalableTexture:  return "ScalableTexture";
+        case OMX_VIDEO_MPEG4ProfileSimpleFace:       return "SimpleFace";
+        case OMX_VIDEO_MPEG4ProfileSimpleFBA:        return "SimpleFBA";
+        case OMX_VIDEO_MPEG4ProfileBasicAnimated:    return "BasicAnimated";
+        case OMX_VIDEO_MPEG4ProfileHybrid:           return "Hybrid";
+        case OMX_VIDEO_MPEG4ProfileAdvancedRealTime: return "AdvancedRealTime";
+        case OMX_VIDEO_MPEG4ProfileCoreScalable:     return "CoreScalable";
+        case OMX_VIDEO_MPEG4ProfileAdvancedCoding:   return "AdvancedCoding";
+        case OMX_VIDEO_MPEG4ProfileAdvancedCore:     return "AdvancedCore";
+        case OMX_VIDEO_MPEG4ProfileAdvancedScalable: return "AdvancedScalable";
+        case OMX_VIDEO_MPEG4ProfileAdvancedSimple:   return "AdvancedSimple";
+        default:                                     return def;
+    }
+}
+
+inline static const char *asString(OMX_VIDEO_MPEG4LEVELTYPE i, const char *def = "??") {
+    switch (i) {
+        case OMX_VIDEO_MPEG4Level0:  return "Level0";
+        case OMX_VIDEO_MPEG4Level0b: return "Level0b";
+        case OMX_VIDEO_MPEG4Level1:  return "Level1";
+        case OMX_VIDEO_MPEG4Level2:  return "Level2";
+        case OMX_VIDEO_MPEG4Level3:  return "Level3";
+        case OMX_VIDEO_MPEG4Level4:  return "Level4";
+        case OMX_VIDEO_MPEG4Level4a: return "Level4a";
+        case OMX_VIDEO_MPEG4Level5:  return "Level5";
+        default:                     return def;
+    }
+}
+
+inline static const char *asString(OMX_VIDEO_AVCPROFILETYPE i, const char *def = "??") {
+    switch (i) {
+        case OMX_VIDEO_AVCProfileBaseline: return "Baseline";
+        case OMX_VIDEO_AVCProfileMain:     return "Main";
+        case OMX_VIDEO_AVCProfileExtended: return "Extended";
+        case OMX_VIDEO_AVCProfileHigh:     return "High";
+        case OMX_VIDEO_AVCProfileHigh10:   return "High10";
+        case OMX_VIDEO_AVCProfileHigh422:  return "High422";
+        case OMX_VIDEO_AVCProfileHigh444:  return "High444";
+        default:                           return def;
+    }
+}
+
+inline static const char *asString(OMX_VIDEO_AVCLEVELTYPE i, const char *def = "??") {
+    switch (i) {
+        case OMX_VIDEO_AVCLevel1:  return "Level1";
+        case OMX_VIDEO_AVCLevel1b: return "Level1b";
+        case OMX_VIDEO_AVCLevel11: return "Level11";
+        case OMX_VIDEO_AVCLevel12: return "Level12";
+        case OMX_VIDEO_AVCLevel13: return "Level13";
+        case OMX_VIDEO_AVCLevel2:  return "Level2";
+        case OMX_VIDEO_AVCLevel21: return "Level21";
+        case OMX_VIDEO_AVCLevel22: return "Level22";
+        case OMX_VIDEO_AVCLevel3:  return "Level3";
+        case OMX_VIDEO_AVCLevel31: return "Level31";
+        case OMX_VIDEO_AVCLevel32: return "Level32";
+        case OMX_VIDEO_AVCLevel4:  return "Level4";
+        case OMX_VIDEO_AVCLevel41: return "Level41";
+        case OMX_VIDEO_AVCLevel42: return "Level42";
+        case OMX_VIDEO_AVCLevel5:  return "Level5";
+        case OMX_VIDEO_AVCLevel51: return "Level51";
+        case OMX_VIDEO_AVCLevel52: return "Level52";
+        default:                   return def;
+    }
+}
+
+inline static const char *asString(OMX_VIDEO_AVCLOOPFILTERTYPE i, const char *def = "??") {
+    switch (i) {
+        case OMX_VIDEO_AVCLoopFilterEnable:               return "Enable";
+//      case OMX_VIDEO_AVCLoopFilterDisable:              return "Disable";
+//      case OMX_VIDEO_AVCLoopFilterDisableSliceBoundary: return "DisableSliceBoundary";
+        default:                                          return def;
+    }
+}
+
+#endif // AS_STRING_FOR_OMX_VIDEO_H
+
+#endif // OMX_Video_h
+
+#ifdef OMX_VideoExt_h
+/* asString definitions if media/openmax/OMX_VideoExt.h was included */
+
+#ifndef AS_STRING_FOR_OMX_VIDEOEXT_H
+#define AS_STRING_FOR_OMX_VIDEOEXT_H
+
+inline static const char *asString(OMX_VIDEO_VP8PROFILETYPE i, const char *def = "!!") {
+    switch (i) {
+        case OMX_VIDEO_VP8ProfileMain:    return "Main";
+        case OMX_VIDEO_VP8ProfileUnknown: return "Unknown";  // unused
+        default:                          return def;
+    }
+}
+
+inline static const char *asString(OMX_VIDEO_VP8LEVELTYPE i, const char *def = "!!") {
+    switch (i) {
+        case OMX_VIDEO_VP8Level_Version0: return "_Version0";
+        case OMX_VIDEO_VP8Level_Version1: return "_Version1";
+        case OMX_VIDEO_VP8Level_Version2: return "_Version2";
+        case OMX_VIDEO_VP8Level_Version3: return "_Version3";
+        case OMX_VIDEO_VP8LevelUnknown:   return "Unknown";    // unused
+        default:                          return def;
+    }
+}
+
+inline static const char *asString(
+        OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE i, const char *def = "??") {
+    switch (i) {
+        case OMX_VIDEO_VPXTemporalLayerPatternNone:   return "VPXTemporalLayerPatternNone";
+        case OMX_VIDEO_VPXTemporalLayerPatternWebRTC: return "VPXTemporalLayerPatternWebRTC";
+        default:                                      return def;
+    }
+}
+
+inline static const char *asString(OMX_VIDEO_HEVCPROFILETYPE i, const char *def = "!!") {
+    switch (i) {
+        case OMX_VIDEO_HEVCProfileUnknown: return "Unknown";  // unused
+        case OMX_VIDEO_HEVCProfileMain:    return "Main";
+        case OMX_VIDEO_HEVCProfileMain10:  return "Main10";
+        default:                           return def;
+    }
+}
+
+inline static const char *asString(OMX_VIDEO_HEVCLEVELTYPE i, const char *def = "!!") {
+    switch (i) {
+        case OMX_VIDEO_HEVCLevelUnknown:    return "LevelUnknown";     // unused
+        case OMX_VIDEO_HEVCMainTierLevel1:  return "MainTierLevel1";
+        case OMX_VIDEO_HEVCHighTierLevel1:  return "HighTierLevel1";
+        case OMX_VIDEO_HEVCMainTierLevel2:  return "MainTierLevel2";
+        case OMX_VIDEO_HEVCHighTierLevel2:  return "HighTierLevel2";
+        case OMX_VIDEO_HEVCMainTierLevel21: return "MainTierLevel21";
+        case OMX_VIDEO_HEVCHighTierLevel21: return "HighTierLevel21";
+        case OMX_VIDEO_HEVCMainTierLevel3:  return "MainTierLevel3";
+        case OMX_VIDEO_HEVCHighTierLevel3:  return "HighTierLevel3";
+        case OMX_VIDEO_HEVCMainTierLevel31: return "MainTierLevel31";
+        case OMX_VIDEO_HEVCHighTierLevel31: return "HighTierLevel31";
+        case OMX_VIDEO_HEVCMainTierLevel4:  return "MainTierLevel4";
+        case OMX_VIDEO_HEVCHighTierLevel4:  return "HighTierLevel4";
+        case OMX_VIDEO_HEVCMainTierLevel41: return "MainTierLevel41";
+        case OMX_VIDEO_HEVCHighTierLevel41: return "HighTierLevel41";
+        case OMX_VIDEO_HEVCMainTierLevel5:  return "MainTierLevel5";
+        case OMX_VIDEO_HEVCHighTierLevel5:  return "HighTierLevel5";
+        case OMX_VIDEO_HEVCMainTierLevel51: return "MainTierLevel51";
+        case OMX_VIDEO_HEVCHighTierLevel51: return "HighTierLevel51";
+        case OMX_VIDEO_HEVCMainTierLevel52: return "MainTierLevel52";
+        case OMX_VIDEO_HEVCHighTierLevel52: return "HighTierLevel52";
+        case OMX_VIDEO_HEVCMainTierLevel6:  return "MainTierLevel6";
+        case OMX_VIDEO_HEVCHighTierLevel6:  return "HighTierLevel6";
+        case OMX_VIDEO_HEVCMainTierLevel61: return "MainTierLevel61";
+        case OMX_VIDEO_HEVCHighTierLevel61: return "HighTierLevel61";
+        case OMX_VIDEO_HEVCMainTierLevel62: return "MainTierLevel62";
+        case OMX_VIDEO_HEVCHighTierLevel62: return "HighTierLevel62";
+        default:                            return def;
+    }
+}
+
+#endif // AS_STRING_FOR_OMX_VIDEOEXT_H
+
+#endif // OMX_VideoExt_h
diff --git a/include/media/openmax/OMX_Audio.h b/include/media/openmax/OMX_Audio.h
index f4cb643..a0cbd3b 100644
--- a/include/media/openmax/OMX_Audio.h
+++ b/include/media/openmax/OMX_Audio.h
@@ -16,25 +16,25 @@
  * -------------------------------------------------------------------
  */
 /*
- * Copyright (c) 2008 The Khronos Group Inc. 
- * 
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
  * "Software"), to deal in the Software without restriction, including
  * without limitation the rights to use, copy, modify, merge, publish,
  * distribute, sublicense, and/or sell copies of the Software, and to
  * permit persons to whom the Software is furnished to do so, subject
- * to the following conditions: 
+ * to the following conditions:
  * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software. 
- * 
+ * in all copies or substantial portions of the Software.
+ *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
  */
 
@@ -50,10 +50,9 @@
 extern "C" {
 #endif /* __cplusplus */
 
-
 /* Each OMX header must include all required header files to allow the
  *  header to compile without errors.  The includes below are required
- *  for this header file to compile successfully 
+ *  for this header file to compile successfully
  */
 
 #include <OMX_Core.h>
@@ -61,7 +60,7 @@
 /** @defgroup midi MIDI
  * @ingroup audio
  */
- 
+
 /** @defgroup effects Audio effects
  * @ingroup audio
  */
@@ -71,10 +70,10 @@
  * @{
  */
 
-/** Enumeration used to define the possible audio codings.  
- *  If "OMX_AUDIO_CodingUnused" is selected, the coding selection must 
- *  be done in a vendor specific way.  Since this is for an audio 
- *  processing element this enum is relevant.  However, for another 
+/** Enumeration used to define the possible audio codings.
+ *  If "OMX_AUDIO_CodingUnused" is selected, the coding selection must
+ *  be done in a vendor specific way.  Since this is for an audio
+ *  processing element this enum is relevant.  However, for another
  *  type of component other enums would be in this area.
  */
 typedef enum OMX_AUDIO_CODINGTYPE {
@@ -107,14 +106,14 @@
     OMX_AUDIO_CodingRA,          /**< Any variant of RA encoded data */
     OMX_AUDIO_CodingMIDI,        /**< Any variant of MIDI encoded data */
     OMX_AUDIO_CodingFLAC,        /**< Any variant of FLAC encoded data */
-    OMX_AUDIO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_AUDIO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_AUDIO_CodingMax = 0x7FFFFFFF
 } OMX_AUDIO_CODINGTYPE;
 
 
-/** The PortDefinition structure is used to define all of the parameters 
- *  necessary for the compliant component to setup an input or an output audio 
+/** The PortDefinition structure is used to define all of the parameters
+ *  necessary for the compliant component to setup an input or an output audio
  *  path.  If additional information is needed to define the parameters of the
  *  port (such as frequency), additional structures must be sent such as the
  *  OMX_AUDIO_PARAM_PCMMODETYPE structure to supply the extra parameters for the port.
@@ -122,11 +121,11 @@
 typedef struct OMX_AUDIO_PORTDEFINITIONTYPE {
     OMX_STRING cMIMEType;            /**< MIME type of data for the port */
     OMX_NATIVE_DEVICETYPE pNativeRender; /** < platform specific reference
-                                               for an output device, 
+                                               for an output device,
                                                otherwise this field is 0 */
-    OMX_BOOL bFlagErrorConcealment;  /**< Turns on error concealment if it is 
+    OMX_BOOL bFlagErrorConcealment;  /**< Turns on error concealment if it is
                                           supported by the OMX component */
-    OMX_AUDIO_CODINGTYPE eEncoding;  /**< Type of data expected for this 
+    OMX_AUDIO_CODINGTYPE eEncoding;  /**< Type of data expected for this
                                           port (e.g. PCM, AMR, MP3, etc) */
 } OMX_AUDIO_PORTDEFINITIONTYPE;
 
@@ -143,15 +142,15 @@
 } OMX_AUDIO_PARAM_PORTFORMATTYPE;
 
 
-/** PCM mode type  */ 
-typedef enum OMX_AUDIO_PCMMODETYPE { 
-    OMX_AUDIO_PCMModeLinear = 0,  /**< Linear PCM encoded data */ 
-    OMX_AUDIO_PCMModeALaw,        /**< A law PCM encoded data (G.711) */ 
-    OMX_AUDIO_PCMModeMULaw,       /**< Mu law PCM encoded data (G.711)  */ 
-    OMX_AUDIO_PCMModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+/** PCM mode type  */
+typedef enum OMX_AUDIO_PCMMODETYPE {
+    OMX_AUDIO_PCMModeLinear = 0,  /**< Linear PCM encoded data */
+    OMX_AUDIO_PCMModeALaw,        /**< A law PCM encoded data (G.711) */
+    OMX_AUDIO_PCMModeMULaw,       /**< Mu law PCM encoded data (G.711)  */
+    OMX_AUDIO_PCMModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_AUDIO_PCMModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
-    OMX_AUDIO_PCMModeMax = 0x7FFFFFFF 
-} OMX_AUDIO_PCMMODETYPE; 
+    OMX_AUDIO_PCMModeMax = 0x7FFFFFFF
+} OMX_AUDIO_PCMMODETYPE;
 
 
 typedef enum OMX_AUDIO_CHANNELTYPE {
@@ -165,45 +164,45 @@
     OMX_AUDIO_ChannelCS   = 0x7,    /**< Back surround */
     OMX_AUDIO_ChannelLR   = 0x8,    /**< Left rear. */
     OMX_AUDIO_ChannelRR   = 0x9,    /**< Right rear. */
-    OMX_AUDIO_ChannelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_ChannelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_AUDIO_ChannelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
-    OMX_AUDIO_ChannelMax  = 0x7FFFFFFF 
+    OMX_AUDIO_ChannelMax  = 0x7FFFFFFF
 } OMX_AUDIO_CHANNELTYPE;
 
 #define OMX_AUDIO_MAXCHANNELS 16  /**< maximum number distinct audio channels that a buffer may contain */
 #define OMX_MIN_PCMPAYLOAD_MSEC 5 /**< Minimum audio buffer payload size for uncompressed (PCM) audio */
 
-/** PCM format description */ 
-typedef struct OMX_AUDIO_PARAM_PCMMODETYPE { 
-    OMX_U32 nSize;                    /**< Size of this structure, in Bytes */ 
-    OMX_VERSIONTYPE nVersion;         /**< OMX specification version information */ 
-    OMX_U32 nPortIndex;               /**< port that this structure applies to */ 
-    OMX_U32 nChannels;                /**< Number of channels (e.g. 2 for stereo) */ 
-    OMX_NUMERICALDATATYPE eNumData;   /**< indicates PCM data as signed or unsigned */ 
-    OMX_ENDIANTYPE eEndian;           /**< indicates PCM data as little or big endian */ 
-    OMX_BOOL bInterleaved;            /**< True for normal interleaved data; false for 
-                                           non-interleaved data (e.g. block data) */ 
-    OMX_U32 nBitPerSample;            /**< Bit per sample */ 
-    OMX_U32 nSamplingRate;            /**< Sampling rate of the source data.  Use 0 for 
-                                           variable or unknown sampling rate. */ 
-    OMX_AUDIO_PCMMODETYPE ePCMMode;   /**< PCM mode enumeration */ 
+/** PCM format description */
+typedef struct OMX_AUDIO_PARAM_PCMMODETYPE {
+    OMX_U32 nSize;                    /**< Size of this structure, in Bytes */
+    OMX_VERSIONTYPE nVersion;         /**< OMX specification version information */
+    OMX_U32 nPortIndex;               /**< port that this structure applies to */
+    OMX_U32 nChannels;                /**< Number of channels (e.g. 2 for stereo) */
+    OMX_NUMERICALDATATYPE eNumData;   /**< indicates PCM data as signed or unsigned */
+    OMX_ENDIANTYPE eEndian;           /**< indicates PCM data as little or big endian */
+    OMX_BOOL bInterleaved;            /**< True for normal interleaved data; false for
+                                           non-interleaved data (e.g. block data) */
+    OMX_U32 nBitPerSample;            /**< Bit per sample */
+    OMX_U32 nSamplingRate;            /**< Sampling rate of the source data.  Use 0 for
+                                           variable or unknown sampling rate. */
+    OMX_AUDIO_PCMMODETYPE ePCMMode;   /**< PCM mode enumeration */
     OMX_AUDIO_CHANNELTYPE eChannelMapping[OMX_AUDIO_MAXCHANNELS]; /**< Slot i contains channel defined by eChannelMap[i] */
 
-} OMX_AUDIO_PARAM_PCMMODETYPE; 
+} OMX_AUDIO_PARAM_PCMMODETYPE;
 
 
 /** Audio channel mode.  This is used by both AAC and MP3, although the names are more appropriate
- * for the MP3.  For example, JointStereo for MP3 is CouplingChannels for AAC. 
+ * for the MP3.  For example, JointStereo for MP3 is CouplingChannels for AAC.
  */
 typedef enum OMX_AUDIO_CHANNELMODETYPE {
-    OMX_AUDIO_ChannelModeStereo = 0,  /**< 2 channels, the bitrate allocation between those 
+    OMX_AUDIO_ChannelModeStereo = 0,  /**< 2 channels, the bitrate allocation between those
                                           two channels changes accordingly to each channel information */
-    OMX_AUDIO_ChannelModeJointStereo, /**< mode that takes advantage of what is common between 
+    OMX_AUDIO_ChannelModeJointStereo, /**< mode that takes advantage of what is common between
                                            2 channels for higher compression gain */
-    OMX_AUDIO_ChannelModeDual,        /**< 2 mono-channels, each channel is encoded with half 
+    OMX_AUDIO_ChannelModeDual,        /**< 2 mono-channels, each channel is encoded with half
                                            the bitrate of the overall bitrate */
     OMX_AUDIO_ChannelModeMono,        /**< Mono channel mode */
-    OMX_AUDIO_ChannelModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_ChannelModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_AUDIO_ChannelModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_AUDIO_ChannelModeMax = 0x7FFFFFFF
 } OMX_AUDIO_CHANNELMODETYPE;
@@ -213,7 +212,7 @@
     OMX_AUDIO_MP3StreamFormatMP1Layer3 = 0, /**< MP3 Audio MPEG 1 Layer 3 Stream format */
     OMX_AUDIO_MP3StreamFormatMP2Layer3,     /**< MP3 Audio MPEG 2 Layer 3 Stream format */
     OMX_AUDIO_MP3StreamFormatMP2_5Layer3,   /**< MP3 Audio MPEG2.5 Layer 3 Stream format */
-    OMX_AUDIO_MP3StreamFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_MP3StreamFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_AUDIO_MP3StreamFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_AUDIO_MP3StreamFormatMax = 0x7FFFFFFF
 } OMX_AUDIO_MP3STREAMFORMATTYPE;
@@ -243,7 +242,7 @@
     OMX_AUDIO_AACStreamFormatADIF,        /**< AAC Audio Data Interchange Format */
     OMX_AUDIO_AACStreamFormatMP4FF,       /**< AAC inside MPEG-4/ISO File Format */
     OMX_AUDIO_AACStreamFormatRAW,         /**< AAC Raw Format */
-    OMX_AUDIO_AACStreamFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_AACStreamFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_AUDIO_AACStreamFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_AUDIO_AACStreamFormatMax = 0x7FFFFFFF
 } OMX_AUDIO_AACSTREAMFORMATTYPE;
@@ -329,16 +328,16 @@
                                    variable or unknown sampling rate. */
     OMX_U32 nAudioBandWidth;  /**< Audio band width (in Hz) to which an encoder should
                                    limit the audio signal. Use 0 to let encoder decide */
-    OMX_S32 nQuality;		  /**< Sets encoding quality to n, between -1 (low) and 10 (high).
+    OMX_S32 nQuality;         /**< Sets encoding quality to n, between -1 (low) and 10 (high).
                                    In the default mode of operation, teh quality level is 3.
                                    Normal quality range is 0 - 10. */
-    OMX_BOOL bManaged;		  /**< Set  bitrate  management  mode. This turns off the
+    OMX_BOOL bManaged;        /**< Set  bitrate  management  mode. This turns off the
                                    normal VBR encoding, but allows hard or soft bitrate
                                    constraints to be enforced by the encoder. This mode can
                                    be slower, and may also be lower quality. It is
                                    primarily useful for streaming. */
-    OMX_BOOL bDownmix;		  /**< Downmix input from stereo to mono (has no effect on 
-                                   non-stereo streams). Useful for lower-bitrate encoding. */     
+    OMX_BOOL bDownmix;        /**< Downmix input from stereo to mono (has no effect on
+                                   non-stereo streams). Useful for lower-bitrate encoding. */
 } OMX_AUDIO_PARAM_VORBISTYPE;
 
 
@@ -361,7 +360,7 @@
   OMX_AUDIO_WMAFormat7,          /**< Windows Media Audio format 7 */
   OMX_AUDIO_WMAFormat8,          /**< Windows Media Audio format 8 */
   OMX_AUDIO_WMAFormat9,          /**< Windows Media Audio format 9 */
-  OMX_AUDIO_WMAFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+  OMX_AUDIO_WMAFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
   OMX_AUDIO_WMAFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
   OMX_AUDIO_WMAFormatMax = 0x7FFFFFFF
 } OMX_AUDIO_WMAFORMATTYPE;
@@ -373,7 +372,7 @@
   OMX_AUDIO_WMAProfileL1,          /**< Windows Media audio version 9 profile L1 */
   OMX_AUDIO_WMAProfileL2,          /**< Windows Media audio version 9 profile L2 */
   OMX_AUDIO_WMAProfileL3,          /**< Windows Media audio version 9 profile L3 */
-  OMX_AUDIO_WMAProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+  OMX_AUDIO_WMAProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
   OMX_AUDIO_WMAProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
   OMX_AUDIO_WMAProfileMax = 0x7FFFFFFF
 } OMX_AUDIO_WMAPROFILETYPE;
@@ -388,14 +387,14 @@
     OMX_U32 nBitRate;         /**< Bit rate of the input data.  Use 0 for variable
                                    rate or unknown bit rates */
     OMX_AUDIO_WMAFORMATTYPE eFormat; /**< Version of WMA stream / data */
-	OMX_AUDIO_WMAPROFILETYPE eProfile;  /**< Profile of WMA stream / data */
+    OMX_AUDIO_WMAPROFILETYPE eProfile;  /**< Profile of WMA stream / data */
     OMX_U32 nSamplingRate;    /**< Sampling rate of the source data */
     OMX_U16 nBlockAlign;      /**< is the block alignment, or block size, in bytes of the audio codec */
     OMX_U16 nEncodeOptions;   /**< WMA Type-specific data */
     OMX_U32 nSuperBlockAlign; /**< WMA Type-specific data */
 } OMX_AUDIO_PARAM_WMATYPE;
 
-/** 
+/**
  * RealAudio format
  */
 typedef enum OMX_AUDIO_RAFORMATTYPE {
@@ -407,32 +406,32 @@
     OMX_AUDIO_RA10_LOSSLESS,      /**< RealAudio Lossless */
     OMX_AUDIO_RA10_MULTICHANNEL,  /**< RealAudio Multichannel */
     OMX_AUDIO_RA10_VOICE,         /**< RealAudio Voice for bitrates below 15 kbps */
-    OMX_AUDIO_RAFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_RAFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_AUDIO_RAFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_VIDEO_RAFormatMax = 0x7FFFFFFF
 } OMX_AUDIO_RAFORMATTYPE;
 
-/** RA (Real Audio) params */ 
-typedef struct OMX_AUDIO_PARAM_RATYPE { 
-    OMX_U32 nSize;              /**< Size of this structure, in Bytes */ 
-    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */ 
-    OMX_U32 nPortIndex;         /**< Port that this structure applies to */ 
-    OMX_U32 nChannels;          /**< Number of channels */ 
-    OMX_U32 nSamplingRate;      /**< is the sampling rate of the source data */ 
-    OMX_U32 nBitsPerFrame;      /**< is the value for bits per frame  */ 
-    OMX_U32 nSamplePerFrame;    /**< is the value for samples per frame */ 
-    OMX_U32 nCouplingQuantBits; /**< is the number of coupling quantization bits in the stream */ 
-    OMX_U32 nCouplingStartRegion;   /**< is the coupling start region in the stream  */ 
-    OMX_U32 nNumRegions;        /**< is the number of regions value */ 
+/** RA (Real Audio) params */
+typedef struct OMX_AUDIO_PARAM_RATYPE {
+    OMX_U32 nSize;              /**< Size of this structure, in Bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U32 nPortIndex;         /**< Port that this structure applies to */
+    OMX_U32 nChannels;          /**< Number of channels */
+    OMX_U32 nSamplingRate;      /**< is the sampling rate of the source data */
+    OMX_U32 nBitsPerFrame;      /**< is the value for bits per frame  */
+    OMX_U32 nSamplePerFrame;    /**< is the value for samples per frame */
+    OMX_U32 nCouplingQuantBits; /**< is the number of coupling quantization bits in the stream */
+    OMX_U32 nCouplingStartRegion;   /**< is the coupling start region in the stream  */
+    OMX_U32 nNumRegions;        /**< is the number of regions value */
     OMX_AUDIO_RAFORMATTYPE eFormat; /**< is the RealAudio audio format */
-} OMX_AUDIO_PARAM_RATYPE; 
+} OMX_AUDIO_PARAM_RATYPE;
 
 
 /** SBC Allocation Method Type */
 typedef enum OMX_AUDIO_SBCALLOCMETHODTYPE {
   OMX_AUDIO_SBCAllocMethodLoudness, /**< Loudness allocation method */
   OMX_AUDIO_SBCAllocMethodSNR,      /**< SNR allocation method */
-  OMX_AUDIO_SBCAllocMethodKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+  OMX_AUDIO_SBCAllocMethodKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
   OMX_AUDIO_SBCAllocMethodVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
   OMX_AUDIO_SBCAllocMethodMax = 0x7FFFFFFF
 } OMX_AUDIO_SBCALLOCMETHODTYPE;
@@ -457,18 +456,18 @@
 } OMX_AUDIO_PARAM_SBCTYPE;
 
 
-/** ADPCM stream format parameters */ 
-typedef struct OMX_AUDIO_PARAM_ADPCMTYPE { 
-    OMX_U32 nSize;              /**< size of the structure in bytes */ 
-    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */ 
-    OMX_U32 nPortIndex;         /**< port that this structure applies to */ 
-    OMX_U32 nChannels;          /**< Number of channels in the data stream (not 
-                                     necessarily the same as the number of channels 
-                                     to be rendered. */ 
-    OMX_U32 nBitsPerSample;     /**< Number of bits in each sample */ 
-    OMX_U32 nSampleRate;        /**< Sampling rate of the source data.  Use 0 for 
-                                    variable or unknown sampling rate. */ 
-} OMX_AUDIO_PARAM_ADPCMTYPE; 
+/** ADPCM stream format parameters */
+typedef struct OMX_AUDIO_PARAM_ADPCMTYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U32 nPortIndex;         /**< port that this structure applies to */
+    OMX_U32 nChannels;          /**< Number of channels in the data stream (not
+                                     necessarily the same as the number of channels
+                                     to be rendered. */
+    OMX_U32 nBitsPerSample;     /**< Number of bits in each sample */
+    OMX_U32 nSampleRate;        /**< Sampling rate of the source data.  Use 0 for
+                                    variable or unknown sampling rate. */
+} OMX_AUDIO_PARAM_ADPCMTYPE;
 
 
 /** G723 rate */
@@ -476,25 +475,25 @@
     OMX_AUDIO_G723ModeUnused = 0,  /**< AMRNB Mode unused / unknown */
     OMX_AUDIO_G723ModeLow,         /**< 5300 bps */
     OMX_AUDIO_G723ModeHigh,        /**< 6300 bps */
-    OMX_AUDIO_G723ModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_G723ModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_AUDIO_G723ModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_AUDIO_G723ModeMax = 0x7FFFFFFF
 } OMX_AUDIO_G723RATE;
 
 
 /** G723 - Sample rate must be 8 KHz */
-typedef struct OMX_AUDIO_PARAM_G723TYPE { 
-    OMX_U32 nSize;                /**< size of the structure in bytes */ 
-    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */ 
-    OMX_U32 nPortIndex;           /**< port that this structure applies to */ 
-    OMX_U32 nChannels;            /**< Number of channels in the data stream (not 
-                                       necessarily the same as the number of channels 
-                                       to be rendered. */ 
-    OMX_BOOL bDTX;                /**< Enable Discontinuous Transmisssion */ 
+typedef struct OMX_AUDIO_PARAM_G723TYPE {
+    OMX_U32 nSize;                /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */
+    OMX_U32 nPortIndex;           /**< port that this structure applies to */
+    OMX_U32 nChannels;            /**< Number of channels in the data stream (not
+                                       necessarily the same as the number of channels
+                                       to be rendered. */
+    OMX_BOOL bDTX;                /**< Enable Discontinuous Transmisssion */
     OMX_AUDIO_G723RATE eBitRate;  /**< todo: Should this be moved to a config? */
-    OMX_BOOL bHiPassFilter;       /**< Enable High Pass Filter */ 
-    OMX_BOOL bPostFilter;         /**< Enable Post Filter */ 
-} OMX_AUDIO_PARAM_G723TYPE; 
+    OMX_BOOL bHiPassFilter;       /**< Enable High Pass Filter */
+    OMX_BOOL bPostFilter;         /**< Enable Post Filter */
+} OMX_AUDIO_PARAM_G723TYPE;
 
 
 /** ITU G726 (ADPCM) rate */
@@ -504,22 +503,22 @@
     OMX_AUDIO_G726Mode24,          /**< 24 kbps */
     OMX_AUDIO_G726Mode32,          /**< 32 kbps, most common rate, also G721 */
     OMX_AUDIO_G726Mode40,          /**< 40 kbps */
-    OMX_AUDIO_G726ModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_G726ModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_AUDIO_G726ModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_AUDIO_G726ModeMax = 0x7FFFFFFF
 } OMX_AUDIO_G726MODE;
 
 
-/** G.726 stream format parameters - must be at 8KHz */ 
-typedef struct OMX_AUDIO_PARAM_G726TYPE { 
-    OMX_U32 nSize;              /**< size of the structure in bytes */ 
-    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */ 
-    OMX_U32 nPortIndex;         /**< port that this structure applies to */ 
-    OMX_U32 nChannels;          /**< Number of channels in the data stream (not 
-                                     necessarily the same as the number of channels 
-                                     to be rendered. */ 
+/** G.726 stream format parameters - must be at 8KHz */
+typedef struct OMX_AUDIO_PARAM_G726TYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U32 nPortIndex;         /**< port that this structure applies to */
+    OMX_U32 nChannels;          /**< Number of channels in the data stream (not
+                                     necessarily the same as the number of channels
+                                     to be rendered. */
      OMX_AUDIO_G726MODE eG726Mode;
-} OMX_AUDIO_PARAM_G726TYPE; 
+} OMX_AUDIO_PARAM_G726TYPE;
 
 
 /** G729 coder type */
@@ -528,7 +527,7 @@
     OMX_AUDIO_G729A,              /**< ITU G.729 annex A  encoded data */
     OMX_AUDIO_G729B,              /**< ITU G.729 with annex B encoded data */
     OMX_AUDIO_G729AB,             /**< ITU G.729 annexes A and B encoded data */
-    OMX_AUDIO_G729KhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_G729KhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_AUDIO_G729VendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_AUDIO_G729Max = 0x7FFFFFFF
 } OMX_AUDIO_G729TYPE;
@@ -547,23 +546,23 @@
 } OMX_AUDIO_PARAM_G729TYPE;
 
 
-/** AMR Frame format */ 
-typedef enum OMX_AUDIO_AMRFRAMEFORMATTYPE { 
-    OMX_AUDIO_AMRFrameFormatConformance = 0,  /**< Frame Format is AMR Conformance 
-                                                   (Standard) Format */ 
-    OMX_AUDIO_AMRFrameFormatIF1,              /**< Frame Format is AMR Interface 
-                                                   Format 1 */ 
-    OMX_AUDIO_AMRFrameFormatIF2,              /**< Frame Format is AMR Interface 
-                                                   Format 2*/ 
-    OMX_AUDIO_AMRFrameFormatFSF,              /**< Frame Format is AMR File Storage 
-                                                   Format */ 
-    OMX_AUDIO_AMRFrameFormatRTPPayload,       /**< Frame Format is AMR Real-Time 
-                                                   Transport Protocol Payload Format */ 
-    OMX_AUDIO_AMRFrameFormatITU,              /**< Frame Format is ITU Format (added at Motorola request) */ 
-    OMX_AUDIO_AMRFrameFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+/** AMR Frame format */
+typedef enum OMX_AUDIO_AMRFRAMEFORMATTYPE {
+    OMX_AUDIO_AMRFrameFormatConformance = 0,  /**< Frame Format is AMR Conformance
+                                                   (Standard) Format */
+    OMX_AUDIO_AMRFrameFormatIF1,              /**< Frame Format is AMR Interface
+                                                   Format 1 */
+    OMX_AUDIO_AMRFrameFormatIF2,              /**< Frame Format is AMR Interface
+                                                   Format 2*/
+    OMX_AUDIO_AMRFrameFormatFSF,              /**< Frame Format is AMR File Storage
+                                                   Format */
+    OMX_AUDIO_AMRFrameFormatRTPPayload,       /**< Frame Format is AMR Real-Time
+                                                   Transport Protocol Payload Format */
+    OMX_AUDIO_AMRFrameFormatITU,              /**< Frame Format is ITU Format (added at Motorola request) */
+    OMX_AUDIO_AMRFrameFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_AUDIO_AMRFrameFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
-    OMX_AUDIO_AMRFrameFormatMax = 0x7FFFFFFF 
-} OMX_AUDIO_AMRFRAMEFORMATTYPE; 
+    OMX_AUDIO_AMRFrameFormatMax = 0x7FFFFFFF
+} OMX_AUDIO_AMRFRAMEFORMATTYPE;
 
 
 /** AMR band mode */
@@ -571,7 +570,7 @@
     OMX_AUDIO_AMRBandModeUnused = 0,          /**< AMRNB Mode unused / unknown */
     OMX_AUDIO_AMRBandModeNB0,                 /**< AMRNB Mode 0 =  4750 bps */
     OMX_AUDIO_AMRBandModeNB1,                 /**< AMRNB Mode 1 =  5150 bps */
-    OMX_AUDIO_AMRBandModeNB2,                 /**< AMRNB Mode 2 =  5900 bps */ 
+    OMX_AUDIO_AMRBandModeNB2,                 /**< AMRNB Mode 2 =  5900 bps */
     OMX_AUDIO_AMRBandModeNB3,                 /**< AMRNB Mode 3 =  6700 bps */
     OMX_AUDIO_AMRBandModeNB4,                 /**< AMRNB Mode 4 =  7400 bps */
     OMX_AUDIO_AMRBandModeNB5,                 /**< AMRNB Mode 5 =  7950 bps */
@@ -579,36 +578,36 @@
     OMX_AUDIO_AMRBandModeNB7,                 /**< AMRNB Mode 7 = 12200 bps */
     OMX_AUDIO_AMRBandModeWB0,                 /**< AMRWB Mode 0 =  6600 bps */
     OMX_AUDIO_AMRBandModeWB1,                 /**< AMRWB Mode 1 =  8850 bps */
-    OMX_AUDIO_AMRBandModeWB2,                 /**< AMRWB Mode 2 = 12650 bps */ 
-    OMX_AUDIO_AMRBandModeWB3,                 /**< AMRWB Mode 3 = 14250 bps */ 
+    OMX_AUDIO_AMRBandModeWB2,                 /**< AMRWB Mode 2 = 12650 bps */
+    OMX_AUDIO_AMRBandModeWB3,                 /**< AMRWB Mode 3 = 14250 bps */
     OMX_AUDIO_AMRBandModeWB4,                 /**< AMRWB Mode 4 = 15850 bps */
     OMX_AUDIO_AMRBandModeWB5,                 /**< AMRWB Mode 5 = 18250 bps */
     OMX_AUDIO_AMRBandModeWB6,                 /**< AMRWB Mode 6 = 19850 bps */
     OMX_AUDIO_AMRBandModeWB7,                 /**< AMRWB Mode 7 = 23050 bps */
-    OMX_AUDIO_AMRBandModeWB8,                 /**< AMRWB Mode 8 = 23850 bps */      
-    OMX_AUDIO_AMRBandModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_AMRBandModeWB8,                 /**< AMRWB Mode 8 = 23850 bps */
+    OMX_AUDIO_AMRBandModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_AUDIO_AMRBandModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_AUDIO_AMRBandModeMax = 0x7FFFFFFF
 } OMX_AUDIO_AMRBANDMODETYPE;
-     
 
-/** AMR Discontinuous Transmission mode */ 
-typedef enum OMX_AUDIO_AMRDTXMODETYPE { 
-    OMX_AUDIO_AMRDTXModeOff = 0,        /**< AMR Discontinuous Transmission Mode is disabled */ 
-    OMX_AUDIO_AMRDTXModeOnVAD1,         /**< AMR Discontinuous Transmission Mode using 
-                                             Voice Activity Detector 1 (VAD1) is enabled */ 
-    OMX_AUDIO_AMRDTXModeOnVAD2,         /**< AMR Discontinuous Transmission Mode using 
-                                             Voice Activity Detector 2 (VAD2) is enabled */       
-    OMX_AUDIO_AMRDTXModeOnAuto,         /**< The codec will automatically select between 
-                                             Off, VAD1 or VAD2 modes */ 
+
+/** AMR Discontinuous Transmission mode */
+typedef enum OMX_AUDIO_AMRDTXMODETYPE {
+    OMX_AUDIO_AMRDTXModeOff = 0,        /**< AMR Discontinuous Transmission Mode is disabled */
+    OMX_AUDIO_AMRDTXModeOnVAD1,         /**< AMR Discontinuous Transmission Mode using
+                                             Voice Activity Detector 1 (VAD1) is enabled */
+    OMX_AUDIO_AMRDTXModeOnVAD2,         /**< AMR Discontinuous Transmission Mode using
+                                             Voice Activity Detector 2 (VAD2) is enabled */
+    OMX_AUDIO_AMRDTXModeOnAuto,         /**< The codec will automatically select between
+                                             Off, VAD1 or VAD2 modes */
 
     OMX_AUDIO_AMRDTXasEFR,             /**< DTX as EFR instead of AMR standard (3GPP 26.101, frame type =8,9,10) */
 
-    OMX_AUDIO_AMRDTXModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_AMRDTXModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_AUDIO_AMRDTXModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
-    OMX_AUDIO_AMRDTXModeMax = 0x7FFFFFFF 
-} OMX_AUDIO_AMRDTXMODETYPE; 
- 
+    OMX_AUDIO_AMRDTXModeMax = 0x7FFFFFFF
+} OMX_AUDIO_AMRDTXMODETYPE;
+
 
 /** AMR params */
 typedef struct OMX_AUDIO_PARAM_AMRTYPE {
@@ -617,7 +616,7 @@
     OMX_U32 nPortIndex;                     /**< port that this structure applies to */
     OMX_U32 nChannels;                      /**< Number of channels */
     OMX_U32 nBitRate;                       /**< Bit rate read only field */
-    OMX_AUDIO_AMRBANDMODETYPE eAMRBandMode; /**< AMR Band Mode enumeration */ 
+    OMX_AUDIO_AMRBANDMODETYPE eAMRBandMode; /**< AMR Band Mode enumeration */
     OMX_AUDIO_AMRDTXMODETYPE  eAMRDTXMode;  /**< AMR DTX Mode enumeration */
     OMX_AUDIO_AMRFRAMEFORMATTYPE eAMRFrameFormat; /**< AMR frame format enumeration */
 } OMX_AUDIO_PARAM_AMRTYPE;
@@ -725,7 +724,7 @@
     OMX_AUDIO_CDMARateQuarter,            /**< CDMA encoded frame in quarter rate */
     OMX_AUDIO_CDMARateEighth,             /**< CDMA encoded frame in eighth rate (DTX)*/
     OMX_AUDIO_CDMARateErasure,            /**< CDMA erasure frame */
-    OMX_AUDIO_CDMARateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_CDMARateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_AUDIO_CDMARateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_AUDIO_CDMARateMax = 0x7FFFFFFF
 } OMX_AUDIO_CDMARATETYPE;
@@ -797,7 +796,7 @@
 } OMX_AUDIO_PARAM_SMVTYPE;
 
 
-/** MIDI Format 
+/** MIDI Format
  * @ingroup midi
  */
 typedef enum OMX_AUDIO_MIDIFORMATTYPE
@@ -810,33 +809,33 @@
     OMX_AUDIO_MIDIFormatXMF0,        /**< eXtensible Music Format type 0 */
     OMX_AUDIO_MIDIFormatXMF1,        /**< eXtensible Music Format type 1 */
     OMX_AUDIO_MIDIFormatMobileXMF,   /**< Mobile XMF (eXtensible Music Format type 2) */
-    OMX_AUDIO_MIDIFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_MIDIFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_AUDIO_MIDIFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_AUDIO_MIDIFormatMax = 0x7FFFFFFF
 } OMX_AUDIO_MIDIFORMATTYPE;
 
 
-/** MIDI params 
+/** MIDI params
  * @ingroup midi
  */
 typedef struct OMX_AUDIO_PARAM_MIDITYPE {
     OMX_U32 nSize;                 /**< size of the structure in bytes */
     OMX_VERSIONTYPE nVersion;      /**< OMX specification version information */
     OMX_U32 nPortIndex;            /**< port that this structure applies to */
-    OMX_U32 nFileSize;             /**< size of the MIDI file in bytes, where the entire 
-                                        MIDI file passed in, otherwise if 0x0, the MIDI data 
-                                        is merged and streamed (instead of passed as an 
+    OMX_U32 nFileSize;             /**< size of the MIDI file in bytes, where the entire
+                                        MIDI file passed in, otherwise if 0x0, the MIDI data
+                                        is merged and streamed (instead of passed as an
                                         entire MIDI file) */
-    OMX_BU32 sMaxPolyphony;        /**< Specifies the maximum simultaneous polyphonic 
-                                        voices. A value of zero indicates that the default 
-                                        polyphony of the device is used  */                                    
-    OMX_BOOL bLoadDefaultSound;    /**< Whether to load default sound 
+    OMX_BU32 sMaxPolyphony;        /**< Specifies the maximum simultaneous polyphonic
+                                        voices. A value of zero indicates that the default
+                                        polyphony of the device is used  */
+    OMX_BOOL bLoadDefaultSound;    /**< Whether to load default sound
                                         bank at initialization */
-    OMX_AUDIO_MIDIFORMATTYPE eMidiFormat; /**< Version of the MIDI file */                                                                           
+    OMX_AUDIO_MIDIFORMATTYPE eMidiFormat; /**< Version of the MIDI file */
 } OMX_AUDIO_PARAM_MIDITYPE;
 
 
-/** Type of the MIDI sound bank 
+/** Type of the MIDI sound bank
  * @ingroup midi
  */
 typedef enum OMX_AUDIO_MIDISOUNDBANKTYPE {
@@ -845,13 +844,13 @@
     OMX_AUDIO_MIDISoundBankDLS2,                 /**< DLS version 2 */
     OMX_AUDIO_MIDISoundBankMobileDLSBase,        /**< Mobile DLS, using the base functionality */
     OMX_AUDIO_MIDISoundBankMobileDLSPlusOptions, /**< Mobile DLS, using the specification-defined optional feature set */
-    OMX_AUDIO_MIDISoundBankKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_MIDISoundBankKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_AUDIO_MIDISoundBankVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_AUDIO_MIDISoundBankMax = 0x7FFFFFFF
 } OMX_AUDIO_MIDISOUNDBANKTYPE;
 
 
-/** Bank Layout describes how bank MSB & LSB are used in the DLS instrument definitions sound bank 
+/** Bank Layout describes how bank MSB & LSB are used in the DLS instrument definitions sound bank
  * @ingroup midi
  */
 typedef enum OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE {
@@ -859,13 +858,13 @@
    OMX_AUDIO_MIDISoundBankLayoutGM,           /**< GS layout (based on bank MSB 0x00) */
    OMX_AUDIO_MIDISoundBankLayoutGM2,          /**< General MIDI 2 layout (using MSB 0x78/0x79, LSB 0x00) */
    OMX_AUDIO_MIDISoundBankLayoutUser,         /**< Does not conform to any bank numbering standards */
-   OMX_AUDIO_MIDISoundBankLayoutKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+   OMX_AUDIO_MIDISoundBankLayoutKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
    OMX_AUDIO_MIDISoundBankLayoutVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
    OMX_AUDIO_MIDISoundBankLayoutMax = 0x7FFFFFFF
 } OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE;
 
 
-/** MIDI params to load/unload user soundbank 
+/** MIDI params to load/unload user soundbank
  * @ingroup midi
  */
 typedef struct OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE {
@@ -880,8 +879,8 @@
 } OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE;
 
 
-/** Structure for Live MIDI events and MIP messages. 
- * (MIP = Maximum Instantaneous Polyphony; part of the SP-MIDI standard.) 
+/** Structure for Live MIDI events and MIP messages.
+ * (MIP = Maximum Instantaneous Polyphony; part of the SP-MIDI standard.)
  * @ingroup midi
  */
 typedef struct OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE {
@@ -890,12 +889,12 @@
     OMX_U32 nPortIndex;       /**< Port that this structure applies to */
     OMX_U32 nMidiEventSize;   /**< Size of immediate MIDI events or MIP message in bytes  */
     OMX_U8 nMidiEvents[1];    /**< MIDI event array to be rendered immediately, or an
-                                   array for the MIP message buffer, where the size is 
+                                   array for the MIP message buffer, where the size is
                                    indicated by nMidiEventSize */
 } OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE;
 
 
-/** MIDI sound bank/ program pair in a given channel 
+/** MIDI sound bank/ program pair in a given channel
  * @ingroup midi
  */
 typedef struct OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE {
@@ -905,29 +904,29 @@
     OMX_U32 nChannel;           /**< Valid channel values range from 1 to 16 */
     OMX_U16 nIDProgram;         /**< Valid program ID range is 1 to 128 */
     OMX_U16 nIDSoundBank;       /**< Sound bank ID */
-    OMX_U32 nUserSoundBankIndex;/**< User soundbank index, easier to access soundbanks 
+    OMX_U32 nUserSoundBankIndex;/**< User soundbank index, easier to access soundbanks
                                      by index if multiple banks are present */
 } OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE;
 
 
-/** MIDI control 
+/** MIDI control
  * @ingroup midi
  */
 typedef struct OMX_AUDIO_CONFIG_MIDICONTROLTYPE {
     OMX_U32 nSize;                /**< size of the structure in bytes */
     OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */
     OMX_U32 nPortIndex;           /**< port that this structure applies to */
-    OMX_BS32 sPitchTransposition; /**< Pitch transposition in semitones, stored as Q22.10 
+    OMX_BS32 sPitchTransposition; /**< Pitch transposition in semitones, stored as Q22.10
                                        format based on JAVA MMAPI (JSR-135) requirement */
     OMX_BU32 sPlayBackRate;       /**< Relative playback rate, stored as Q14.17 fixed-point
                                        number based on JSR-135 requirement */
-    OMX_BU32 sTempo ;             /**< Tempo in beats per minute (BPM), stored as Q22.10 
+    OMX_BU32 sTempo ;             /**< Tempo in beats per minute (BPM), stored as Q22.10
                                        fixed-point number based on JSR-135 requirement */
-    OMX_U32 nMaxPolyphony;        /**< Specifies the maximum simultaneous polyphonic 
-                                       voices. A value of zero indicates that the default 
+    OMX_U32 nMaxPolyphony;        /**< Specifies the maximum simultaneous polyphonic
+                                       voices. A value of zero indicates that the default
                                        polyphony of the device is used  */
     OMX_U32 nNumRepeat;           /**< Number of times to repeat playback */
-    OMX_U32 nStopTime;            /**< Time in milliseconds to indicate when playback 
+    OMX_U32 nStopTime;            /**< Time in milliseconds to indicate when playback
                                        will stop automatically.  Set to zero if not used */
     OMX_U16 nChannelMuteMask;     /**< 16 bit mask for channel mute status */
     OMX_U16 nChannelSoloMask;     /**< 16 bit mask for channel solo status */
@@ -939,22 +938,22 @@
 } OMX_AUDIO_CONFIG_MIDICONTROLTYPE;
 
 
-/** MIDI Playback States 
+/** MIDI Playback States
  * @ingroup midi
  */
 typedef enum OMX_AUDIO_MIDIPLAYBACKSTATETYPE {
-  OMX_AUDIO_MIDIPlayBackStateUnknown = 0,      /**< Unknown state or state does not map to 
-  													other defined states */
-  OMX_AUDIO_MIDIPlayBackStateClosedEngaged,    /**< No MIDI resource is currently open. 
-                                                    The MIDI engine is currently processing 
+  OMX_AUDIO_MIDIPlayBackStateUnknown = 0,      /**< Unknown state or state does not map to
+                                                    other defined states */
+  OMX_AUDIO_MIDIPlayBackStateClosedEngaged,    /**< No MIDI resource is currently open.
+                                                    The MIDI engine is currently processing
                                                     MIDI events. */
-  OMX_AUDIO_MIDIPlayBackStateParsing,          /**< A MIDI resource is open and is being 
-                                                    primed. The MIDI engine is currently 
+  OMX_AUDIO_MIDIPlayBackStateParsing,          /**< A MIDI resource is open and is being
+                                                    primed. The MIDI engine is currently
                                                     processing MIDI events. */
-  OMX_AUDIO_MIDIPlayBackStateOpenEngaged,      /**< A MIDI resource is open and primed but 
+  OMX_AUDIO_MIDIPlayBackStateOpenEngaged,      /**< A MIDI resource is open and primed but
                                                     not playing. The MIDI engine is currently
                                                     processing MIDI events. The transition to
-                                                    this state is only possible from the 
+                                                    this state is only possible from the
                                                     OMX_AUDIO_MIDIPlayBackStatePlaying state,
                                                     when the 'playback head' reaches the end
                                                     of media data or the playback stops due
@@ -969,95 +968,95 @@
                                                     no audible MIDI content during playback
                                                     currently. The situation may change if
                                                     resources are freed later.*/
-  OMX_AUDIO_MIDIPlayBackStateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+  OMX_AUDIO_MIDIPlayBackStateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
   OMX_AUDIO_MIDIPlayBackStateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
   OMX_AUDIO_MIDIPlayBackStateMax = 0x7FFFFFFF
 } OMX_AUDIO_MIDIPLAYBACKSTATETYPE;
 
 
-/** MIDI status 
+/** MIDI status
  * @ingroup midi
  */
 typedef struct OMX_AUDIO_CONFIG_MIDISTATUSTYPE {
     OMX_U32 nSize;              /**< size of the structure in bytes */
     OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
     OMX_U32 nPortIndex;         /**< port that this structure applies to */
-    OMX_U16 nNumTracks;         /**< Number of MIDI tracks in the file, read only field. 
-                                     NOTE: May not return a meaningful value until the entire 
+    OMX_U16 nNumTracks;         /**< Number of MIDI tracks in the file, read only field.
+                                     NOTE: May not return a meaningful value until the entire
                                      file is parsed and buffered.  */
-    OMX_U32 nDuration;          /**< The length of the currently open MIDI resource 
-                                     in milliseconds. NOTE: May not return a meaningful value 
-                                     until the entire file is parsed and buffered.  */  
-    OMX_U32 nPosition;          /**< Current Position of the MIDI resource being played 
-                                     in milliseconds */
-    OMX_BOOL bVibra;            /**< Does Vibra track exist? NOTE: May not return a meaningful 
-                                     value until the entire file is parsed and buffered. */
-    OMX_U32 nNumMetaEvents;     /**< Total number of MIDI Meta Events in the currently 
-                                     open MIDI resource. NOTE: May not return a meaningful value 
+    OMX_U32 nDuration;          /**< The length of the currently open MIDI resource
+                                     in milliseconds. NOTE: May not return a meaningful value
                                      until the entire file is parsed and buffered.  */
-    OMX_U32 nNumActiveVoices;   /**< Number of active voices in the currently playing 
-                                     MIDI resource. NOTE: May not return a meaningful value until 
+    OMX_U32 nPosition;          /**< Current Position of the MIDI resource being played
+                                     in milliseconds */
+    OMX_BOOL bVibra;            /**< Does Vibra track exist? NOTE: May not return a meaningful
+                                     value until the entire file is parsed and buffered. */
+    OMX_U32 nNumMetaEvents;     /**< Total number of MIDI Meta Events in the currently
+                                     open MIDI resource. NOTE: May not return a meaningful value
+                                     until the entire file is parsed and buffered.  */
+    OMX_U32 nNumActiveVoices;   /**< Number of active voices in the currently playing
+                                     MIDI resource. NOTE: May not return a meaningful value until
                                      the entire file is parsed and buffered. */
     OMX_AUDIO_MIDIPLAYBACKSTATETYPE eMIDIPlayBackState;  /**< MIDI playback state enumeration, read only field */
 } OMX_AUDIO_CONFIG_MIDISTATUSTYPE;
 
 
 /** MIDI Meta Event structure one per Meta Event.
- *  MIDI Meta Events are like audio metadata, except that they are interspersed 
- *  with the MIDI content throughout the file and are not localized in the header. 
- *  As such, it is necessary to retrieve information about these Meta Events from 
- *  the engine, as it encounters these Meta Events within the MIDI content. 
- *  For example, SMF files can have up to 14 types of MIDI Meta Events (copyright, 
- *  author, default tempo, etc.) scattered throughout the file. 
+ *  MIDI Meta Events are like audio metadata, except that they are interspersed
+ *  with the MIDI content throughout the file and are not localized in the header.
+ *  As such, it is necessary to retrieve information about these Meta Events from
+ *  the engine, as it encounters these Meta Events within the MIDI content.
+ *  For example, SMF files can have up to 14 types of MIDI Meta Events (copyright,
+ *  author, default tempo, etc.) scattered throughout the file.
  *  @ingroup midi
  */
-typedef struct OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE{ 
-    OMX_U32 nSize;            /**< size of the structure in bytes */ 
-    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ 
-    OMX_U32 nPortIndex;       /**< port that this structure applies to */ 
-    OMX_U32 nIndex;           /**< Index of Meta Event */ 
-    OMX_U8 nMetaEventType;    /**< Meta Event Type, 7bits (i.e. 0 - 127) */ 
-    OMX_U32 nMetaEventSize;   /**< size of the Meta Event in bytes */ 
+typedef struct OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE{
+    OMX_U32 nSize;            /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    OMX_U32 nPortIndex;       /**< port that this structure applies to */
+    OMX_U32 nIndex;           /**< Index of Meta Event */
+    OMX_U8 nMetaEventType;    /**< Meta Event Type, 7bits (i.e. 0 - 127) */
+    OMX_U32 nMetaEventSize;   /**< size of the Meta Event in bytes */
     OMX_U32 nTrack;           /**< track number for the meta event */
     OMX_U32 nPosition;        /**< Position of the meta-event in milliseconds */
-} OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE; 
+} OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE;
 
 
-/** MIDI Meta Event Data structure - one per Meta Event. 
+/** MIDI Meta Event Data structure - one per Meta Event.
  * @ingroup midi
- */ 
-typedef struct OMX_AUDIO_CONFIG_MIDIMETAEVENTDATATYPE{ 
-    OMX_U32 nSize;            /**< size of the structure in bytes */ 
-    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ 
-    OMX_U32 nPortIndex;       /**< port that this structure applies to */ 
-    OMX_U32 nIndex;           /**< Index of Meta Event */ 
-    OMX_U32 nMetaEventSize;   /**< size of the Meta Event in bytes */ 
-    OMX_U8 nData[1];          /**< array of one or more bytes of meta data 
-                                   as indicated by the nMetaEventSize field */ 
-} OMX_AUDIO_CONFIG__MIDIMETAEVENTDATATYPE; 
+ */
+typedef struct OMX_AUDIO_CONFIG_MIDIMETAEVENTDATATYPE{
+    OMX_U32 nSize;            /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    OMX_U32 nPortIndex;       /**< port that this structure applies to */
+    OMX_U32 nIndex;           /**< Index of Meta Event */
+    OMX_U32 nMetaEventSize;   /**< size of the Meta Event in bytes */
+    OMX_U8 nData[1];          /**< array of one or more bytes of meta data
+                                   as indicated by the nMetaEventSize field */
+} OMX_AUDIO_CONFIG__MIDIMETAEVENTDATATYPE;
 
 
 /** Audio Volume adjustment for a port */
 typedef struct OMX_AUDIO_CONFIG_VOLUMETYPE {
     OMX_U32 nSize;              /**< size of the structure in bytes */
     OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
-    OMX_U32 nPortIndex;         /**< Port index indicating which port to 
-                                     set.  Select the input port to set 
-                                     just that port's volume.  Select the 
-                                     output port to adjust the master 
+    OMX_U32 nPortIndex;         /**< Port index indicating which port to
+                                     set.  Select the input port to set
+                                     just that port's volume.  Select the
+                                     output port to adjust the master
                                      volume. */
-    OMX_BOOL bLinear;           /**< Is the volume to be set in linear (0.100) 
+    OMX_BOOL bLinear;           /**< Is the volume to be set in linear (0.100)
                                      or logarithmic scale (mB) */
     OMX_BS32 sVolume;           /**< Volume linear setting in the 0..100 range, OR
                                      Volume logarithmic setting for this port.  The values
                                      for volume are in mB (millibels = 1/100 dB) relative
-                                     to a gain of 1 (e.g. the output is the same as the 
-                                     input level).  Values are in mB from nMax 
+                                     to a gain of 1 (e.g. the output is the same as the
+                                     input level).  Values are in mB from nMax
                                      (maximum volume) to nMin mB (typically negative).
                                      Since the volume is "voltage"
                                      and not a "power", it takes a setting of
                                      -600 mB to decrease the volume by 1/2.  If
-                                     a component cannot accurately set the 
+                                     a component cannot accurately set the
                                      volume to the requested value, it must
                                      set the volume to the closest value BELOW
                                      the requested value.  When getting the
@@ -1070,27 +1069,27 @@
 typedef struct OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE {
     OMX_U32 nSize;              /**< size of the structure in bytes */
     OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
-    OMX_U32 nPortIndex;         /**< Port index indicating which port to 
-                                     set.  Select the input port to set 
-                                     just that port's volume.  Select the 
-                                     output port to adjust the master 
+    OMX_U32 nPortIndex;         /**< Port index indicating which port to
+                                     set.  Select the input port to set
+                                     just that port's volume.  Select the
+                                     output port to adjust the master
                                      volume. */
-    OMX_U32 nChannel;           /**< channel to select from 0 to N-1, 
+    OMX_U32 nChannel;           /**< channel to select from 0 to N-1,
                                      using OMX_ALL to apply volume settings
                                      to all channels */
-    OMX_BOOL bLinear;           /**< Is the volume to be set in linear (0.100) or 
+    OMX_BOOL bLinear;           /**< Is the volume to be set in linear (0.100) or
                                      logarithmic scale (mB) */
     OMX_BS32 sVolume;           /**< Volume linear setting in the 0..100 range, OR
-                                     Volume logarithmic setting for this port.  
-                                     The values for volume are in mB 
+                                     Volume logarithmic setting for this port.
+                                     The values for volume are in mB
                                      (millibels = 1/100 dB) relative to a gain
-                                     of 1 (e.g. the output is the same as the 
-                                     input level).  Values are in mB from nMax 
-                                     (maximum volume) to nMin mB (typically negative).  
+                                     of 1 (e.g. the output is the same as the
+                                     input level).  Values are in mB from nMax
+                                     (maximum volume) to nMin mB (typically negative).
                                      Since the volume is "voltage"
                                      and not a "power", it takes a setting of
                                      -600 mB to decrease the volume by 1/2.  If
-                                     a component cannot accurately set the 
+                                     a component cannot accurately set the
                                      volume to the requested value, it must
                                      set the volume to the closest value BELOW
                                      the requested value.  When getting the
@@ -1105,12 +1104,12 @@
 typedef struct OMX_AUDIO_CONFIG_BALANCETYPE {
     OMX_U32 nSize;              /**< size of the structure in bytes */
     OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
-    OMX_U32 nPortIndex;         /**< Port index indicating which port to 
-                                     set.  Select the input port to set 
-                                     just that port's balance.  Select the 
-                                     output port to adjust the master 
+    OMX_U32 nPortIndex;         /**< Port index indicating which port to
+                                     set.  Select the input port to set
+                                     just that port's balance.  Select the
+                                     output port to adjust the master
                                      balance. */
-    OMX_S32 nBalance;           /**< balance setting for this port 
+    OMX_S32 nBalance;           /**< balance setting for this port
                                      (-100 to 100, where -100 indicates
                                      all left, and no right */
 } OMX_AUDIO_CONFIG_BALANCETYPE;
@@ -1120,10 +1119,10 @@
 typedef struct OMX_AUDIO_CONFIG_MUTETYPE {
     OMX_U32 nSize;              /**< size of the structure in bytes */
     OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
-    OMX_U32 nPortIndex;         /**< Port index indicating which port to 
-                                     set.  Select the input port to set 
-                                     just that port's mute.  Select the 
-                                     output port to adjust the master 
+    OMX_U32 nPortIndex;         /**< Port index indicating which port to
+                                     set.  Select the input port to set
+                                     just that port's mute.  Select the
+                                     output port to adjust the master
                                      mute. */
     OMX_BOOL bMute;             /**< Mute setting for this port */
 } OMX_AUDIO_CONFIG_MUTETYPE;
@@ -1134,20 +1133,20 @@
     OMX_U32 nSize;              /**< size of the structure in bytes */
     OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
     OMX_U32 nPortIndex;         /**< port that this structure applies to */
-    OMX_U32 nChannel;           /**< channel to select from 0 to N-1, 
+    OMX_U32 nChannel;           /**< channel to select from 0 to N-1,
                                      using OMX_ALL to apply mute settings
                                      to all channels */
     OMX_BOOL bMute;             /**< Mute setting for this channel */
     OMX_BOOL bIsMIDI;           /**< TRUE if nChannel refers to a MIDI channel,
-                                     FALSE otherwise */ 
+                                     FALSE otherwise */
 } OMX_AUDIO_CONFIG_CHANNELMUTETYPE;
 
 
 
-/** Enable / Disable for loudness control, which boosts bass and to a 
+/** Enable / Disable for loudness control, which boosts bass and to a
  *  smaller extent high end frequencies to compensate for hearing
  *  ability at the extreme ends of the audio spectrum
- */ 
+ */
 typedef struct OMX_AUDIO_CONFIG_LOUDNESSTYPE {
     OMX_U32 nSize;             /**< size of the structure in bytes */
     OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
@@ -1157,33 +1156,33 @@
 
 
 /** Enable / Disable for bass, which controls low frequencies
- */ 
+ */
 typedef struct OMX_AUDIO_CONFIG_BASSTYPE {
     OMX_U32 nSize;             /**< size of the structure in bytes */
     OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
     OMX_U32 nPortIndex;        /**< port that this structure applies to */
     OMX_BOOL bEnable;          /**< Enable/disable for bass control */
-    OMX_S32 nBass;             /**< bass setting for the port, as a 
-                                    continuous value from -100 to 100  
+    OMX_S32 nBass;             /**< bass setting for the port, as a
+                                    continuous value from -100 to 100
                                     (0 means no change in bass level)*/
 } OMX_AUDIO_CONFIG_BASSTYPE;
 
 
 /** Enable / Disable for treble, which controls high frequencies tones
- */ 
+ */
 typedef struct OMX_AUDIO_CONFIG_TREBLETYPE {
     OMX_U32 nSize;             /**< size of the structure in bytes */
     OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
     OMX_U32 nPortIndex;        /**< port that this structure applies to */
     OMX_BOOL bEnable;          /**< Enable/disable for treble control */
     OMX_S32  nTreble;          /**< treble setting for the port, as a
-                                    continuous value from -100 to 100  
+                                    continuous value from -100 to 100
                                     (0 means no change in treble level) */
 } OMX_AUDIO_CONFIG_TREBLETYPE;
 
 
-/** An equalizer is typically used for two reasons: to compensate for an 
- *  sub-optimal frequency response of a system to make it sound more natural 
+/** An equalizer is typically used for two reasons: to compensate for an
+ *  sub-optimal frequency response of a system to make it sound more natural
  *  or to create intentionally some unnatural coloring to the sound to create
  *  an effect.
  *  @ingroup effects
@@ -1193,33 +1192,33 @@
     OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
     OMX_U32 nPortIndex;        /**< port that this structure applies to */
     OMX_BOOL bEnable;          /**< Enable/disable for equalizer */
-    OMX_BU32 sBandIndex;       /**< Band number to be set.  Upper Limit is 
+    OMX_BU32 sBandIndex;       /**< Band number to be set.  Upper Limit is
                                     N-1, where N is the number of bands, lower limit is 0 */
     OMX_BU32 sCenterFreq;      /**< Center frequecies in Hz.  This is a
-                                    read only element and is used to determine 
-                                    the lower, center and upper frequency of 
+                                    read only element and is used to determine
+                                    the lower, center and upper frequency of
                                     this band.  */
     OMX_BS32 sBandLevel;       /**< band level in millibels */
 } OMX_AUDIO_CONFIG_EQUALIZERTYPE;
 
 
-/** Stereo widening mode type 
+/** Stereo widening mode type
  * @ingroup effects
- */ 
+ */
 typedef enum OMX_AUDIO_STEREOWIDENINGTYPE {
     OMX_AUDIO_StereoWideningHeadphones,    /**< Stereo widening for loudspeakers */
     OMX_AUDIO_StereoWideningLoudspeakers,  /**< Stereo widening for closely spaced loudspeakers */
-    OMX_AUDIO_StereoWideningKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_StereoWideningKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_AUDIO_StereoWideningVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_AUDIO_StereoWideningMax = 0x7FFFFFFF
 } OMX_AUDIO_STEREOWIDENINGTYPE;
 
 
 /** Control for stereo widening, which is a special 2-channel
- *  case of the audio virtualizer effect. For example, for 5.1-channel 
- *  output, it translates to virtual surround sound. 
+ *  case of the audio virtualizer effect. For example, for 5.1-channel
+ *  output, it translates to virtual surround sound.
  * @ingroup effects
- */ 
+ */
 typedef struct OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE {
     OMX_U32 nSize;             /**< size of the structure in bytes */
     OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
@@ -1232,10 +1231,10 @@
 
 
 /** The chorus effect (or ``choralizer'') is any signal processor which makes
- *  one sound source (such as a voice) sound like many such sources singing 
- *  (or playing) in unison. Since performance in unison is never exact, chorus 
- *  effects simulate this by making independently modified copies of the input 
- *  signal. Modifications may include (1) delay, (2) frequency shift, and 
+ *  one sound source (such as a voice) sound like many such sources singing
+ *  (or playing) in unison. Since performance in unison is never exact, chorus
+ *  effects simulate this by making independently modified copies of the input
+ *  signal. Modifications may include (1) delay, (2) frequency shift, and
  *  (3) amplitude modulation.
  * @ingroup effects
  */
@@ -1246,16 +1245,16 @@
     OMX_BOOL bEnable;          /**< Enable/disable for chorus */
     OMX_BU32 sDelay;           /**< average delay in milliseconds */
     OMX_BU32 sModulationRate;  /**< rate of modulation in millihertz */
-    OMX_U32 nModulationDepth;  /**< depth of modulation as a percentage of 
+    OMX_U32 nModulationDepth;  /**< depth of modulation as a percentage of
                                     delay (i.e. 0 to 100) */
     OMX_BU32 nFeedback;        /**< Feedback from chorus output to input in percentage */
 } OMX_AUDIO_CONFIG_CHORUSTYPE;
 
 
-/** Reverberation is part of the reflected sound that follows the early 
- *  reflections. In a typical room, this consists of a dense succession of 
- *  echoes whose energy decays exponentially. The reverberation effect structure 
- *  as defined here includes both (early) reflections as well as (late) reverberations. 
+/** Reverberation is part of the reflected sound that follows the early
+ *  reflections. In a typical room, this consists of a dense succession of
+ *  echoes whose energy decays exponentially. The reverberation effect structure
+ *  as defined here includes both (early) reflections as well as (late) reverberations.
  * @ingroup effects
  */
 typedef struct OMX_AUDIO_CONFIG_REVERBERATIONTYPE {
@@ -1263,48 +1262,48 @@
     OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */
     OMX_U32 nPortIndex;           /**< port that this structure applies to */
     OMX_BOOL bEnable;             /**< Enable/disable for reverberation control */
-    OMX_BS32 sRoomLevel;          /**< Intensity level for the whole room effect 
-                                       (i.e. both early reflections and late 
+    OMX_BS32 sRoomLevel;          /**< Intensity level for the whole room effect
+                                       (i.e. both early reflections and late
                                        reverberation) in millibels */
     OMX_BS32 sRoomHighFreqLevel;  /**< Attenuation at high frequencies
                                        relative to the intensity at low
                                        frequencies in millibels */
     OMX_BS32 sReflectionsLevel;   /**< Intensity level of early reflections
                                        (relative to room value), in millibels */
-    OMX_BU32 sReflectionsDelay;   /**< Delay time of the first reflection relative 
+    OMX_BU32 sReflectionsDelay;   /**< Delay time of the first reflection relative
                                        to the direct path, in milliseconds */
     OMX_BS32 sReverbLevel;        /**< Intensity level of late reverberation
                                        relative to room level, in millibels */
-    OMX_BU32 sReverbDelay;        /**< Time delay from the first early reflection 
-                                       to the beginning of the late reverberation 
+    OMX_BU32 sReverbDelay;        /**< Time delay from the first early reflection
+                                       to the beginning of the late reverberation
                                        section, in milliseconds */
     OMX_BU32 sDecayTime;          /**< Late reverberation decay time at low
                                        frequencies, in milliseconds */
-    OMX_BU32 nDecayHighFreqRatio; /**< Ratio of high frequency decay time relative 
+    OMX_BU32 nDecayHighFreqRatio; /**< Ratio of high frequency decay time relative
                                        to low frequency decay time in percent  */
     OMX_U32 nDensity;             /**< Modal density in the late reverberation decay,
                                        in percent (i.e. 0 - 100) */
     OMX_U32 nDiffusion;           /**< Echo density in the late reverberation decay,
                                        in percent (i.e. 0 - 100) */
-    OMX_BU32 sReferenceHighFreq;  /**< Reference high frequency in Hertz. This is 
-                                       the frequency used as the reference for all 
+    OMX_BU32 sReferenceHighFreq;  /**< Reference high frequency in Hertz. This is
+                                       the frequency used as the reference for all
                                        the high-frequency settings above */
 
 } OMX_AUDIO_CONFIG_REVERBERATIONTYPE;
 
 
-/** Possible settings for the Echo Cancelation structure to use 
+/** Possible settings for the Echo Cancelation structure to use
  * @ingroup effects
  */
 typedef enum OMX_AUDIO_ECHOCANTYPE {
    OMX_AUDIO_EchoCanOff = 0,    /**< Echo Cancellation is disabled */
-   OMX_AUDIO_EchoCanNormal,     /**< Echo Cancellation normal operation - 
+   OMX_AUDIO_EchoCanNormal,     /**< Echo Cancellation normal operation -
                                      echo from plastics and face */
-   OMX_AUDIO_EchoCanHFree,      /**< Echo Cancellation optimized for 
+   OMX_AUDIO_EchoCanHFree,      /**< Echo Cancellation optimized for
                                      Hands Free operation */
-   OMX_AUDIO_EchoCanCarKit,    /**< Echo Cancellation optimized for 
+   OMX_AUDIO_EchoCanCarKit,    /**< Echo Cancellation optimized for
                                      Car Kit (longer echo) */
-   OMX_AUDIO_EchoCanKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+   OMX_AUDIO_EchoCanKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
    OMX_AUDIO_EchoCanVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
    OMX_AUDIO_EchoCanMax = 0x7FFFFFFF
 } OMX_AUDIO_ECHOCANTYPE;
@@ -1313,7 +1312,7 @@
 /** Enable / Disable for echo cancelation, which removes undesired echo's
  *  from the audio
  * @ingroup effects
- */ 
+ */
 typedef struct OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE {
     OMX_U32 nSize;             /**< size of the structure in bytes */
     OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
@@ -1325,7 +1324,7 @@
 /** Enable / Disable for noise reduction, which undesired noise from
  * the audio
  * @ingroup effects
- */ 
+ */
 typedef struct OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE {
     OMX_U32 nSize;             /**< size of the structure in bytes */
     OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
diff --git a/include/media/openmax/OMX_AudioExt.h b/include/media/openmax/OMX_AudioExt.h
index 5ac15f7..2a1c3f2 100644
--- a/include/media/openmax/OMX_AudioExt.h
+++ b/include/media/openmax/OMX_AudioExt.h
@@ -47,6 +47,7 @@
     OMX_AUDIO_CodingAndroidUnused = OMX_AUDIO_CodingKhronosExtensions + 0x00100000,
     OMX_AUDIO_CodingAndroidAC3,         /**< AC3 encoded data */
     OMX_AUDIO_CodingAndroidOPUS,        /**< OPUS encoded data */
+    OMX_AUDIO_CodingAndroidEAC3,        /**< EAC3 encoded data */
 } OMX_AUDIO_CODINGEXTTYPE;
 
 typedef struct OMX_AUDIO_PARAM_ANDROID_AC3TYPE {
@@ -58,6 +59,15 @@
                                         variable or unknown sampling rate. */
 } OMX_AUDIO_PARAM_ANDROID_AC3TYPE;
 
+typedef struct OMX_AUDIO_PARAM_ANDROID_EAC3TYPE {
+    OMX_U32 nSize;                 /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;      /**< OMX specification version information */
+    OMX_U32 nPortIndex;            /**< port that this structure applies to */
+    OMX_U32 nChannels;             /**< Number of channels */
+    OMX_U32 nSampleRate;           /**< Sampling rate of the source data.  Use 0 for
+                                        variable or unknown sampling rate. */
+} OMX_AUDIO_PARAM_ANDROID_EAC3TYPE;
+
 typedef struct OMX_AUDIO_PARAM_ANDROID_OPUSTYPE {
     OMX_U32 nSize;            /**< size of the structure in bytes */
     OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
diff --git a/include/media/openmax/OMX_Component.h b/include/media/openmax/OMX_Component.h
index b5b784e..0dc2c76 100644
--- a/include/media/openmax/OMX_Component.h
+++ b/include/media/openmax/OMX_Component.h
@@ -16,25 +16,25 @@
  * -------------------------------------------------------------------
  */
 /*
- * Copyright (c) 2008 The Khronos Group Inc. 
- * 
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
  * "Software"), to deal in the Software without restriction, including
  * without limitation the rights to use, copy, modify, merge, publish,
  * distribute, sublicense, and/or sell copies of the Software, and to
  * permit persons to whom the Software is furnished to do so, subject
- * to the following conditions: 
+ * to the following conditions:
  * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software. 
- * 
+ * in all copies or substantial portions of the Software.
+ *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
  */
 
@@ -55,7 +55,7 @@
 
 /* Each OMX header must include all required header files to allow the
  *  header to compile without errors.  The includes below are required
- *  for this header file to compile successfully 
+ *  for this header file to compile successfully
  */
 
 #include <OMX_Audio.h>
@@ -64,12 +64,12 @@
 #include <OMX_Other.h>
 
 /** @ingroup comp */
-typedef enum OMX_PORTDOMAINTYPE { 
-    OMX_PortDomainAudio, 
-    OMX_PortDomainVideo, 
-    OMX_PortDomainImage, 
+typedef enum OMX_PORTDOMAINTYPE {
+    OMX_PortDomainAudio,
+    OMX_PortDomainVideo,
+    OMX_PortDomainImage,
     OMX_PortDomainOther,
-    OMX_PortDomainKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_PortDomainKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_PortDomainVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_PortDomainMax = 0x7ffffff
 } OMX_PORTDOMAINTYPE;
@@ -88,7 +88,7 @@
                                         When disabled a port is unpopulated. A disabled port
                                         is not populated with buffers on a transition to IDLE. */
     OMX_BOOL bPopulated;           /**< Port is populated with all of its buffers as indicated by
-                                        nBufferCountActual. A disabled port is always unpopulated. 
+                                        nBufferCountActual. A disabled port is always unpopulated.
                                         An enabled port is populated on a transition to OMX_StateIdle
                                         and unpopulated on a transition to loaded. */
     OMX_PORTDOMAINTYPE eDomain;    /**< Domain of the port. Determines the contents of metadata below. */
@@ -103,26 +103,26 @@
 } OMX_PARAM_PORTDEFINITIONTYPE;
 
 /** @ingroup comp */
-typedef struct OMX_PARAM_U32TYPE { 
-    OMX_U32 nSize;                    /**< Size of this structure, in Bytes */ 
-    OMX_VERSIONTYPE nVersion;         /**< OMX specification version information */ 
-    OMX_U32 nPortIndex;               /**< port that this structure applies to */ 
+typedef struct OMX_PARAM_U32TYPE {
+    OMX_U32 nSize;                    /**< Size of this structure, in Bytes */
+    OMX_VERSIONTYPE nVersion;         /**< OMX specification version information */
+    OMX_U32 nPortIndex;               /**< port that this structure applies to */
     OMX_U32 nU32;                     /**< U32 value */
 } OMX_PARAM_U32TYPE;
 
 /** @ingroup rpm */
 typedef enum OMX_SUSPENSIONPOLICYTYPE {
     OMX_SuspensionDisabled, /**< No suspension; v1.0 behavior */
-    OMX_SuspensionEnabled,  /**< Suspension allowed */   
-    OMX_SuspensionPolicyKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_SuspensionEnabled,  /**< Suspension allowed */
+    OMX_SuspensionPolicyKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_SuspensionPolicyStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_SuspensionPolicyMax = 0x7fffffff
 } OMX_SUSPENSIONPOLICYTYPE;
 
 /** @ingroup rpm */
 typedef struct OMX_PARAM_SUSPENSIONPOLICYTYPE {
-    OMX_U32 nSize;                  
-    OMX_VERSIONTYPE nVersion;        
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
     OMX_SUSPENSIONPOLICYTYPE ePolicy;
 } OMX_PARAM_SUSPENSIONPOLICYTYPE;
 
@@ -130,22 +130,22 @@
 typedef enum OMX_SUSPENSIONTYPE {
     OMX_NotSuspended, /**< component is not suspended */
     OMX_Suspended,    /**< component is suspended */
-    OMX_SuspensionKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_SuspensionKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_SuspensionVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_SuspendMax = 0x7FFFFFFF
 } OMX_SUSPENSIONTYPE;
 
 /** @ingroup rpm */
 typedef struct OMX_PARAM_SUSPENSIONTYPE {
-    OMX_U32 nSize;                  
-    OMX_VERSIONTYPE nVersion;       
-    OMX_SUSPENSIONTYPE eType;             
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_SUSPENSIONTYPE eType;
 } OMX_PARAM_SUSPENSIONTYPE ;
 
 typedef struct OMX_CONFIG_BOOLEANTYPE {
     OMX_U32 nSize;
     OMX_VERSIONTYPE nVersion;
-    OMX_BOOL bEnabled;    
+    OMX_BOOL bEnabled;
 } OMX_CONFIG_BOOLEANTYPE;
 
 /* Parameter specifying the content uri to use. */
@@ -171,9 +171,9 @@
 typedef struct OMX_RESOURCECONCEALMENTTYPE {
     OMX_U32 nSize;             /**< size of the structure in bytes */
     OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
-    OMX_BOOL bResourceConcealmentForbidden; /**< disallow the use of resource concealment 
-                                            methods (like degrading algorithm quality to 
-                                            lower resource consumption or functional bypass) 
+    OMX_BOOL bResourceConcealmentForbidden; /**< disallow the use of resource concealment
+                                            methods (like degrading algorithm quality to
+                                            lower resource consumption or functional bypass)
                                             on a component as a resolution to resource conflicts. */
 } OMX_RESOURCECONCEALMENTTYPE;
 
@@ -188,7 +188,7 @@
     OMX_MetadataCharsetJavaConformantUTF8,
     OMX_MetadataCharsetUTF7,
     OMX_MetadataCharsetImapUTF7,
-    OMX_MetadataCharsetUTF16LE, 
+    OMX_MetadataCharsetUTF16LE,
     OMX_MetadataCharsetUTF16BE,
     OMX_MetadataCharsetGB12345,
     OMX_MetadataCharsetHZGB2312,
@@ -214,7 +214,7 @@
     OMX_MetadataCharsetISO2022JP1,
     OMX_MetadataCharsetISOEUCJP,
     OMX_MetadataCharsetSMS7Bit,
-    OMX_MetadataCharsetKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_MetadataCharsetKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_MetadataCharsetVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_MetadataCharsetTypeMax= 0x7FFFFFFF
 } OMX_METADATACHARSETTYPE;
@@ -226,7 +226,7 @@
     OMX_MetadataScopeTopLevel,
     OMX_MetadataScopePortLevel,
     OMX_MetadataScopeNodeLevel,
-    OMX_MetadataScopeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_MetadataScopeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_MetadataScopeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_MetadataScopeTypeMax = 0x7fffffff
 } OMX_METADATASCOPETYPE;
@@ -237,7 +237,7 @@
     OMX_MetadataSearchValueSizeByIndex,
     OMX_MetadataSearchItemByIndex,
     OMX_MetadataSearchNextItemByKey,
-    OMX_MetadataSearchKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_MetadataSearchKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_MetadataSearchVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_MetadataSearchTypeMax = 0x7fffffff
 } OMX_METADATASEARCHMODETYPE;
@@ -258,7 +258,7 @@
     OMX_VERSIONTYPE nVersion;
     OMX_METADATASCOPETYPE eScopeMode;
     OMX_U32 nScopeSpecifier;
-    OMX_U32 nMetadataItemIndex;  
+    OMX_U32 nMetadataItemIndex;
     OMX_METADATASEARCHMODETYPE eSearchMode;
     OMX_METADATACHARSETTYPE eKeyCharset;
     OMX_U8 nKeySizeUsed;
@@ -287,30 +287,30 @@
     OMX_VERSIONTYPE nVersion;
     OMX_BOOL bAllKeys;
     OMX_U32 nParentNodeID;
-    OMX_U32 nNodeIndex; 
-    OMX_U32 nNodeID; 
+    OMX_U32 nNodeIndex;
+    OMX_U32 nNodeID;
     OMX_STRING cNodeName;
     OMX_BOOL bIsLeafType;
 } OMX_CONFIG_CONTAINERNODEIDTYPE;
 
 /** @ingroup metadata */
-typedef struct OMX_PARAM_METADATAFILTERTYPE 
-{ 
-    OMX_U32 nSize; 
-    OMX_VERSIONTYPE nVersion; 
-    OMX_BOOL bAllKeys;	/* if true then this structure refers to all keys and 
+typedef struct OMX_PARAM_METADATAFILTERTYPE
+{
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_BOOL bAllKeys;  /* if true then this structure refers to all keys and
                          * the three key fields below are ignored */
     OMX_METADATACHARSETTYPE eKeyCharset;
-    OMX_U32 nKeySizeUsed; 
-    OMX_U8   nKey [128]; 
+    OMX_U32 nKeySizeUsed;
+    OMX_U8   nKey [128];
     OMX_U32 nLanguageCountrySizeUsed;
     OMX_U8 nLanguageCountry[128];
-    OMX_BOOL bEnabled;	/* if true then key is part of filter (e.g. 
+    OMX_BOOL bEnabled;  /* if true then key is part of filter (e.g.
                          * retained for query later). If false then
                          * key is not part of filter */
-} OMX_PARAM_METADATAFILTERTYPE; 
+} OMX_PARAM_METADATAFILTERTYPE;
 
-/** The OMX_HANDLETYPE structure defines the component handle.  The component 
+/** The OMX_HANDLETYPE structure defines the component handle.  The component
  *  handle is used to access all of the component's public methods and also
  *  contains pointers to the component's private data area.  The component
  *  handle is initialized by the OMX core (with help from the component)
@@ -318,7 +318,7 @@
  *  successfully loaded, the application can safely access any of the
  *  component's public functions (although some may return an error because
  *  the state is inappropriate for the access).
- * 
+ *
  *  @ingroup comp
  */
 typedef struct OMX_COMPONENTTYPE
@@ -329,26 +329,26 @@
         function will fill in this value. */
     OMX_U32 nSize;
 
-    /** nVersion is the version of the OMX specification that the structure 
-        is built against.  It is the responsibility of the creator of this 
-        structure to initialize this value and every user of this structure 
-        should verify that it knows how to use the exact version of 
+    /** nVersion is the version of the OMX specification that the structure
+        is built against.  It is the responsibility of the creator of this
+        structure to initialize this value and every user of this structure
+        should verify that it knows how to use the exact version of
         this structure found herein. */
     OMX_VERSIONTYPE nVersion;
 
-    /** pComponentPrivate is a pointer to the component private data area.  
-        This member is allocated and initialized by the component when the 
-        component is first loaded.  The application should not access this 
+    /** pComponentPrivate is a pointer to the component private data area.
+        This member is allocated and initialized by the component when the
+        component is first loaded.  The application should not access this
         data area. */
     OMX_PTR pComponentPrivate;
 
-    /** pApplicationPrivate is a pointer that is a parameter to the 
-        OMX_GetHandle method, and contains an application private value 
-        provided by the IL client.  This application private data is 
+    /** pApplicationPrivate is a pointer that is a parameter to the
+        OMX_GetHandle method, and contains an application private value
+        provided by the IL client.  This application private data is
         returned to the IL Client by OMX in all callbacks */
     OMX_PTR pApplicationPrivate;
 
-    /** refer to OMX_GetComponentVersion in OMX_core.h or the OMX IL 
+    /** refer to OMX_GetComponentVersion in OMX_core.h or the OMX IL
         specification for details on the GetComponentVersion method.
      */
     OMX_ERRORTYPE (*GetComponentVersion)(
@@ -358,7 +358,7 @@
             OMX_OUT OMX_VERSIONTYPE* pSpecVersion,
             OMX_OUT OMX_UUIDTYPE* pComponentUUID);
 
-    /** refer to OMX_SendCommand in OMX_core.h or the OMX IL 
+    /** refer to OMX_SendCommand in OMX_core.h or the OMX IL
         specification for details on the SendCommand method.
      */
     OMX_ERRORTYPE (*SendCommand)(
@@ -367,43 +367,43 @@
             OMX_IN  OMX_U32 nParam1,
             OMX_IN  OMX_PTR pCmdData);
 
-    /** refer to OMX_GetParameter in OMX_core.h or the OMX IL 
+    /** refer to OMX_GetParameter in OMX_core.h or the OMX IL
         specification for details on the GetParameter method.
      */
     OMX_ERRORTYPE (*GetParameter)(
-            OMX_IN  OMX_HANDLETYPE hComponent, 
-            OMX_IN  OMX_INDEXTYPE nParamIndex,  
+            OMX_IN  OMX_HANDLETYPE hComponent,
+            OMX_IN  OMX_INDEXTYPE nParamIndex,
             OMX_INOUT OMX_PTR pComponentParameterStructure);
 
 
-    /** refer to OMX_SetParameter in OMX_core.h or the OMX IL 
+    /** refer to OMX_SetParameter in OMX_core.h or the OMX IL
         specification for details on the SetParameter method.
      */
     OMX_ERRORTYPE (*SetParameter)(
-            OMX_IN  OMX_HANDLETYPE hComponent, 
+            OMX_IN  OMX_HANDLETYPE hComponent,
             OMX_IN  OMX_INDEXTYPE nIndex,
             OMX_IN  OMX_PTR pComponentParameterStructure);
 
 
-    /** refer to OMX_GetConfig in OMX_core.h or the OMX IL 
+    /** refer to OMX_GetConfig in OMX_core.h or the OMX IL
         specification for details on the GetConfig method.
      */
     OMX_ERRORTYPE (*GetConfig)(
             OMX_IN  OMX_HANDLETYPE hComponent,
-            OMX_IN  OMX_INDEXTYPE nIndex, 
+            OMX_IN  OMX_INDEXTYPE nIndex,
             OMX_INOUT OMX_PTR pComponentConfigStructure);
 
 
-    /** refer to OMX_SetConfig in OMX_core.h or the OMX IL 
+    /** refer to OMX_SetConfig in OMX_core.h or the OMX IL
         specification for details on the SetConfig method.
      */
     OMX_ERRORTYPE (*SetConfig)(
             OMX_IN  OMX_HANDLETYPE hComponent,
-            OMX_IN  OMX_INDEXTYPE nIndex, 
+            OMX_IN  OMX_INDEXTYPE nIndex,
             OMX_IN  OMX_PTR pComponentConfigStructure);
 
 
-    /** refer to OMX_GetExtensionIndex in OMX_core.h or the OMX IL 
+    /** refer to OMX_GetExtensionIndex in OMX_core.h or the OMX IL
         specification for details on the GetExtensionIndex method.
      */
     OMX_ERRORTYPE (*GetExtensionIndex)(
@@ -412,50 +412,50 @@
             OMX_OUT OMX_INDEXTYPE* pIndexType);
 
 
-    /** refer to OMX_GetState in OMX_core.h or the OMX IL 
+    /** refer to OMX_GetState in OMX_core.h or the OMX IL
         specification for details on the GetState method.
      */
     OMX_ERRORTYPE (*GetState)(
             OMX_IN  OMX_HANDLETYPE hComponent,
             OMX_OUT OMX_STATETYPE* pState);
 
-    
+
     /** The ComponentTunnelRequest method will interact with another OMX
         component to determine if tunneling is possible and to setup the
-        tunneling.  The return codes for this method can be used to 
+        tunneling.  The return codes for this method can be used to
         determine if tunneling is not possible, or if tunneling is not
-        supported.  
-        
-        Base profile components (i.e. non-interop) do not support this
-        method and should return OMX_ErrorNotImplemented 
+        supported.
 
-        The interop profile component MUST support tunneling to another 
-        interop profile component with a compatible port parameters.  
+        Base profile components (i.e. non-interop) do not support this
+        method and should return OMX_ErrorNotImplemented
+
+        The interop profile component MUST support tunneling to another
+        interop profile component with a compatible port parameters.
         A component may also support proprietary communication.
-        
-        If proprietary communication is supported the negotiation of 
-        proprietary communication is done outside of OMX in a vendor 
-        specific way. It is only required that the proper result be 
-        returned and the details of how the setup is done is left 
-        to the component implementation.  
-    
+
+        If proprietary communication is supported the negotiation of
+        proprietary communication is done outside of OMX in a vendor
+        specific way. It is only required that the proper result be
+        returned and the details of how the setup is done is left
+        to the component implementation.
+
         When this method is invoked when nPort in an output port, the
         component will:
-        1.  Populate the pTunnelSetup structure with the output port's 
+        1.  Populate the pTunnelSetup structure with the output port's
             requirements and constraints for the tunnel.
 
         When this method is invoked when nPort in an input port, the
         component will:
-        1.  Query the necessary parameters from the output port to 
+        1.  Query the necessary parameters from the output port to
             determine if the ports are compatible for tunneling
         2.  If the ports are compatible, the component should store
             the tunnel step provided by the output port
         3.  Determine which port (either input or output) is the buffer
             supplier, and call OMX_SetParameter on the output port to
             indicate this selection.
-        
+
         The component will return from this call within 5 msec.
-    
+
         @param [in] hComp
             Handle of the component to be accessed.  This is the component
             handle returned by the call to the OMX_GetHandle method.
@@ -463,7 +463,7 @@
             nPort is used to select the port on the component to be used
             for tunneling.
         @param [in] hTunneledComp
-            Handle of the component to tunnel with.  This is the component 
+            Handle of the component to tunnel with.  This is the component
             handle returned by the call to the OMX_GetHandle method.  When
             this parameter is 0x0 the component should setup the port for
             communication with the application / IL Client.
@@ -486,9 +486,9 @@
         OMX_IN  OMX_U32 nPort,
         OMX_IN  OMX_HANDLETYPE hTunneledComp,
         OMX_IN  OMX_U32 nTunneledPort,
-        OMX_INOUT  OMX_TUNNELSETUPTYPE* pTunnelSetup); 
+        OMX_INOUT  OMX_TUNNELSETUPTYPE* pTunnelSetup);
 
-    /** refer to OMX_UseBuffer in OMX_core.h or the OMX IL 
+    /** refer to OMX_UseBuffer in OMX_core.h or the OMX IL
         specification for details on the UseBuffer method.
         @ingroup buf
      */
@@ -500,7 +500,7 @@
             OMX_IN OMX_U32 nSizeBytes,
             OMX_IN OMX_U8* pBuffer);
 
-    /** refer to OMX_AllocateBuffer in OMX_core.h or the OMX IL 
+    /** refer to OMX_AllocateBuffer in OMX_core.h or the OMX IL
         specification for details on the AllocateBuffer method.
         @ingroup buf
      */
@@ -511,7 +511,7 @@
             OMX_IN OMX_PTR pAppPrivate,
             OMX_IN OMX_U32 nSizeBytes);
 
-    /** refer to OMX_FreeBuffer in OMX_core.h or the OMX IL 
+    /** refer to OMX_FreeBuffer in OMX_core.h or the OMX IL
         specification for details on the FreeBuffer method.
         @ingroup buf
      */
@@ -520,7 +520,7 @@
             OMX_IN  OMX_U32 nPortIndex,
             OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer);
 
-    /** refer to OMX_EmptyThisBuffer in OMX_core.h or the OMX IL 
+    /** refer to OMX_EmptyThisBuffer in OMX_core.h or the OMX IL
         specification for details on the EmptyThisBuffer method.
         @ingroup buf
      */
@@ -528,7 +528,7 @@
             OMX_IN  OMX_HANDLETYPE hComponent,
             OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer);
 
-    /** refer to OMX_FillThisBuffer in OMX_core.h or the OMX IL 
+    /** refer to OMX_FillThisBuffer in OMX_core.h or the OMX IL
         specification for details on the FillThisBuffer method.
         @ingroup buf
      */
@@ -543,10 +543,10 @@
             Handle of the component to be accessed.  This is the component
             handle returned by the call to the GetHandle function.
         @param [in] pCallbacks
-            pointer to an OMX_CALLBACKTYPE structure used to provide the 
+            pointer to an OMX_CALLBACKTYPE structure used to provide the
             callback information to the component
         @param [in] pAppData
-            pointer to an application defined value.  It is anticipated that 
+            pointer to an application defined value.  It is anticipated that
             the application will pass a pointer to a data structure or a "this
             pointer" in this area to allow the callback (in the application)
             to determine the context of the call
@@ -556,7 +556,7 @@
      */
     OMX_ERRORTYPE (*SetCallbacks)(
             OMX_IN  OMX_HANDLETYPE hComponent,
-            OMX_IN  OMX_CALLBACKTYPE* pCallbacks, 
+            OMX_IN  OMX_CALLBACKTYPE* pCallbacks,
             OMX_IN  OMX_PTR pAppData);
 
     /** ComponentDeInit method is used to deinitialize the component
@@ -583,8 +583,8 @@
 
     OMX_ERRORTYPE (*ComponentRoleEnum)(
         OMX_IN OMX_HANDLETYPE hComponent,
-		OMX_OUT OMX_U8 *cRole,
-		OMX_IN OMX_U32 nIndex);
+        OMX_OUT OMX_U8 *cRole,
+        OMX_IN OMX_U32 nIndex);
 
 } OMX_COMPONENTTYPE;
 
diff --git a/include/media/openmax/OMX_ContentPipe.h b/include/media/openmax/OMX_ContentPipe.h
index ee9e4db..0224c8a 100644
--- a/include/media/openmax/OMX_ContentPipe.h
+++ b/include/media/openmax/OMX_ContentPipe.h
@@ -16,25 +16,25 @@
  * -------------------------------------------------------------------
  */
 /*
- * Copyright (c) 2008 The Khronos Group Inc. 
- * 
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
  * "Software"), to deal in the Software without restriction, including
  * without limitation the rights to use, copy, modify, merge, publish,
  * distribute, sublicense, and/or sell copies of the Software, and to
  * permit persons to whom the Software is furnished to do so, subject
- * to the following conditions: 
+ * to the following conditions:
  * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software. 
- * 
+ * in all copies or substantial portions of the Software.
+ *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
  */
 
@@ -81,83 +81,83 @@
 
 /** Map types from OMX standard types only here so interface is as generic as possible. */
 typedef OMX_U32    CPresult;
-typedef char *     CPstring;  
+typedef char *     CPstring;
 typedef void *     CPhandle;
 typedef OMX_U32    CPuint;
-typedef OMX_S32    CPint;  
-typedef char       CPbyte;  
+typedef OMX_S32    CPint;
+typedef char       CPbyte;
 typedef OMX_BOOL   CPbool;
 
-/** enumeration of origin types used in the CP_PIPETYPE's Seek function 
+/** enumeration of origin types used in the CP_PIPETYPE's Seek function
  * @ingroup cp
  */
 typedef enum CP_ORIGINTYPE {
-    CP_OriginBegin,      
-    CP_OriginCur,      
-    CP_OriginEnd,      
-    CP_OriginKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    CP_OriginBegin,
+    CP_OriginCur,
+    CP_OriginEnd,
+    CP_OriginKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     CP_OriginVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     CP_OriginMax = 0X7FFFFFFF
 } CP_ORIGINTYPE;
 
-/** enumeration of contact access types used in the CP_PIPETYPE's Open function 
+/** enumeration of contact access types used in the CP_PIPETYPE's Open function
  * @ingroup cp
  */
 typedef enum CP_ACCESSTYPE {
-    CP_AccessRead,      
-    CP_AccessWrite,  
-    CP_AccessReadWrite ,  
-    CP_AccessKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    CP_AccessRead,
+    CP_AccessWrite,
+    CP_AccessReadWrite,
+    CP_AccessKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     CP_AccessVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     CP_AccessMax = 0X7FFFFFFF
 } CP_ACCESSTYPE;
 
-/** enumeration of results returned by the CP_PIPETYPE's CheckAvailableBytes function 
+/** enumeration of results returned by the CP_PIPETYPE's CheckAvailableBytes function
  * @ingroup cp
  */
 typedef enum CP_CHECKBYTESRESULTTYPE
 {
-    CP_CheckBytesOk,                    /**< There are at least the request number 
+    CP_CheckBytesOk,                    /**< There are at least the request number
                                               of bytes available */
-    CP_CheckBytesNotReady,              /**< The pipe is still retrieving bytes 
-                                              and presently lacks sufficient bytes. 
-                                              Client will be called when they are 
+    CP_CheckBytesNotReady,              /**< The pipe is still retrieving bytes
+                                              and presently lacks sufficient bytes.
+                                              Client will be called when they are
                                               sufficient bytes are available. */
-    CP_CheckBytesInsufficientBytes  ,     /**< The pipe has retrieved all bytes 
-                                              but those available are less than those 
+    CP_CheckBytesInsufficientBytes,     /**< The pipe has retrieved all bytes
+                                              but those available are less than those
                                               requested */
     CP_CheckBytesAtEndOfStream,         /**< The pipe has reached the end of stream
                                               and no more bytes are available. */
     CP_CheckBytesOutOfBuffers,          /**< All read/write buffers are currently in use. */
-    CP_CheckBytesKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    CP_CheckBytesKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     CP_CheckBytesVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     CP_CheckBytesMax = 0X7FFFFFFF
 } CP_CHECKBYTESRESULTTYPE;
 
-/** enumeration of content pipe events sent to the client callback. 
+/** enumeration of content pipe events sent to the client callback.
  * @ingroup cp
  */
 typedef enum CP_EVENTTYPE{
-    CP_BytesAvailable,      	    /** bytes requested in a CheckAvailableBytes call are now available*/
-    CP_Overflow,  		           /** enumeration of content pipe events sent to the client callback*/
-    CP_PipeDisconnected  ,  		    /** enumeration of content pipe events sent to the client callback*/
-    CP_EventKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    CP_BytesAvailable,                      /** bytes requested in a CheckAvailableBytes call are now available*/
+    CP_Overflow,                            /** enumeration of content pipe events sent to the client callback*/
+    CP_PipeDisconnected,                    /** enumeration of content pipe events sent to the client callback*/
+    CP_EventKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     CP_EventVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     CP_EventMax = 0X7FFFFFFF
 } CP_EVENTTYPE;
 
-/** content pipe definition 
+/** content pipe definition
  * @ingroup cp
  */
 typedef struct CP_PIPETYPE
 {
-    /** Open a content stream for reading or writing. */ 
+    /** Open a content stream for reading or writing. */
     CPresult (*Open)( CPhandle* hContent, CPstring szURI, CP_ACCESSTYPE eAccess );
 
-    /** Close a content stream. */ 
+    /** Close a content stream. */
     CPresult (*Close)( CPhandle hContent );
 
-    /** Create a content source and open it for writing. */ 
+    /** Create a content source and open it for writing. */
     CPresult (*Create)( CPhandle *hContent, CPstring szURI );
 
     /** Check the that specified number of bytes are available for reading or writing (depending on access type).*/
@@ -171,19 +171,19 @@
 
     /** Retrieve data of the specified size from the content stream (advance content pointer by size of data).
        Note: pipe client provides pointer. This function is appropriate for small high frequency reads. */
-    CPresult (*Read)( CPhandle hContent, CPbyte *pData, CPuint nSize); 
+    CPresult (*Read)( CPhandle hContent, CPbyte *pData, CPuint nSize);
 
-    /** Retrieve a buffer allocated by the pipe that contains the requested number of bytes. 
+    /** Retrieve a buffer allocated by the pipe that contains the requested number of bytes.
        Buffer contains the next block of bytes, as specified by nSize, of the content. nSize also
-       returns the size of the block actually read. Content pointer advances the by the returned size. 
-       Note: pipe provides pointer. This function is appropriate for large reads. The client must call 
-       ReleaseReadBuffer when done with buffer. 
+       returns the size of the block actually read. Content pointer advances the by the returned size.
+       Note: pipe provides pointer. This function is appropriate for large reads. The client must call
+       ReleaseReadBuffer when done with buffer.
 
        In some cases the requested block may not reside in contiguous memory within the
-       pipe implementation. For instance if the pipe leverages a circular buffer then the requested 
-       block may straddle the boundary of the circular buffer. By default a pipe implementation 
+       pipe implementation. For instance if the pipe leverages a circular buffer then the requested
+       block may straddle the boundary of the circular buffer. By default a pipe implementation
        performs a copy in this case to provide the block to the pipe client in one contiguous buffer.
-       If, however, the client sets bForbidCopy, then the pipe returns only those bytes preceding the memory 
+       If, however, the client sets bForbidCopy, then the pipe returns only those bytes preceding the memory
        boundary. Here the client may retrieve the data in segments over successive calls. */
     CPresult (*ReadBuffer)( CPhandle hContent, CPbyte **ppBuffer, CPuint *nSize, CPbool bForbidCopy);
 
@@ -192,14 +192,14 @@
 
     /** Write data of the specified size to the content (advance content pointer by size of data).
        Note: pipe client provides pointer. This function is appropriate for small high frequency writes. */
-    CPresult (*Write)( CPhandle hContent, CPbyte *data, CPuint nSize); 
+    CPresult (*Write)( CPhandle hContent, CPbyte *data, CPuint nSize);
 
-    /** Retrieve a buffer allocated by the pipe used to write data to the content. 
+    /** Retrieve a buffer allocated by the pipe used to write data to the content.
        Client will fill buffer with output data. Note: pipe provides pointer. This function is appropriate
        for large writes. The client must call WriteBuffer when done it has filled the buffer with data.*/
     CPresult (*GetWriteBuffer)( CPhandle hContent, CPbyte **ppBuffer, CPuint nSize);
 
-    /** Deliver a buffer obtained via GetWriteBuffer to the pipe. Pipe will write the 
+    /** Deliver a buffer obtained via GetWriteBuffer to the pipe. Pipe will write the
        the contents of the buffer to content and advance content pointer by the size of the buffer */
     CPresult (*WriteBuffer)( CPhandle hContent, CPbyte *pBuffer, CPuint nFilledSize);
 
diff --git a/include/media/openmax/OMX_Core.h b/include/media/openmax/OMX_Core.h
index 9fb0f6f..12f2b3b 100644
--- a/include/media/openmax/OMX_Core.h
+++ b/include/media/openmax/OMX_Core.h
@@ -16,25 +16,25 @@
  * -------------------------------------------------------------------
  */
 /*
- * Copyright (c) 2008 The Khronos Group Inc. 
- * 
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
  * "Software"), to deal in the Software without restriction, including
  * without limitation the rights to use, copy, modify, merge, publish,
  * distribute, sublicense, and/or sell copies of the Software, and to
  * permit persons to whom the Software is furnished to do so, subject
- * to the following conditions: 
+ * to the following conditions:
  * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software. 
- * 
+ * in all copies or substantial portions of the Software.
+ *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
  */
 
@@ -53,14 +53,14 @@
 
 /* Each OMX header shall include all required header files to allow the
  *  header to compile without errors.  The includes below are required
- *  for this header file to compile successfully 
+ *  for this header file to compile successfully
  */
 
 #include <OMX_Index.h>
 
 
 /** The OMX_COMMANDTYPE enumeration is used to specify the action in the
- *  OMX_SendCommand macro.  
+ *  OMX_SendCommand macro.
  *  @ingroup core
  */
 typedef enum OMX_COMMANDTYPE
@@ -70,7 +70,7 @@
     OMX_CommandPortDisable, /**< Disable a port on a component. */
     OMX_CommandPortEnable,  /**< Enable a port on a component. */
     OMX_CommandMarkBuffer,  /**< Mark a component/buffer for observation */
-    OMX_CommandKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_CommandKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_CommandVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_CommandMax = 0X7FFFFFFF
 } OMX_COMMANDTYPE;
@@ -93,28 +93,28 @@
  *  specified configuration and will transition to the idle state if the
  *  allocation is successful.  If the component cannot successfully
  *  transition to the idle state for any reason, the state of the component
- *  shall be fully rolled back to the Loaded state (e.g. all allocated 
+ *  shall be fully rolled back to the Loaded state (e.g. all allocated
  *  resources shall be released).  When the component receives the command
  *  to go to the Executing state, it shall begin processing buffers by
  *  sending all input buffers it holds to the application.  While
  *  the component is in the Idle state, the application may also send the
  *  Pause command.  If the component receives the pause command while in the
- *  Idle state, the component shall send all input buffers it holds to the 
+ *  Idle state, the component shall send all input buffers it holds to the
  *  application, but shall not begin processing buffers.  This will allow the
  *  application to prefill buffers.
- * 
+ *
  *  @ingroup comp
  */
 
 typedef enum OMX_STATETYPE
 {
-    OMX_StateInvalid,      /**< component has detected that it's internal data 
+    OMX_StateInvalid,      /**< component has detected that it's internal data
                                 structures are corrupted to the point that
                                 it cannot determine it's state properly */
     OMX_StateLoaded,      /**< component has been loaded but has not completed
                                 initialization.  The OMX_SetParameter macro
-                                and the OMX_GetParameter macro are the only 
-                                valid macros allowed to be sent to the 
+                                and the OMX_GetParameter macro are the only
+                                valid macros allowed to be sent to the
                                 component in this state. */
     OMX_StateIdle,        /**< component initialization has been completed
                                 successfully and the component is ready to
@@ -122,17 +122,17 @@
     OMX_StateExecuting,   /**< component has accepted the start command and
                                 is processing data (if data is available) */
     OMX_StatePause,       /**< component has received pause command */
-    OMX_StateWaitForResources, /**< component is waiting for resources, either after 
+    OMX_StateWaitForResources, /**< component is waiting for resources, either after
                                 preemption or before it gets the resources requested.
                                 See specification for complete details. */
-    OMX_StateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_StateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_StateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_StateMax = 0X7FFFFFFF
 } OMX_STATETYPE;
 
-/** The OMX_ERRORTYPE enumeration defines the standard OMX Errors.  These 
- *  errors should cover most of the common failure cases.  However, 
- *  vendors are free to add additional error messages of their own as 
+/** The OMX_ERRORTYPE enumeration defines the standard OMX Errors.  These
+ *  errors should cover most of the common failure cases.  However,
+ *  vendors are free to add additional error messages of their own as
  *  long as they follow these rules:
  *  1.  Vendor error messages shall be in the range of 0x90000000 to
  *      0x9000FFFF.
@@ -203,25 +203,25 @@
   /** This error occurs when trying to transition into the state you are already in */
   OMX_ErrorSameState = (OMX_S32) 0x80001012,
 
-  /** Resources allocated to an executing or paused component have been 
+  /** Resources allocated to an executing or paused component have been
       preempted, causing the component to return to the idle state */
-  OMX_ErrorResourcesPreempted = (OMX_S32) 0x80001013, 
+  OMX_ErrorResourcesPreempted = (OMX_S32) 0x80001013,
 
-  /** A non-supplier port sends this error to the IL client (via the EventHandler callback) 
+  /** A non-supplier port sends this error to the IL client (via the EventHandler callback)
       during the allocation of buffers (on a transition from the LOADED to the IDLE state or
-      on a port restart) when it deems that it has waited an unusually long time for the supplier 
+      on a port restart) when it deems that it has waited an unusually long time for the supplier
       to send it an allocated buffer via a UseBuffer call. */
   OMX_ErrorPortUnresponsiveDuringAllocation = (OMX_S32) 0x80001014,
 
-  /** A non-supplier port sends this error to the IL client (via the EventHandler callback) 
-      during the deallocation of buffers (on a transition from the IDLE to LOADED state or 
-      on a port stop) when it deems that it has waited an unusually long time for the supplier 
+  /** A non-supplier port sends this error to the IL client (via the EventHandler callback)
+      during the deallocation of buffers (on a transition from the IDLE to LOADED state or
+      on a port stop) when it deems that it has waited an unusually long time for the supplier
       to request the deallocation of a buffer header via a FreeBuffer call. */
   OMX_ErrorPortUnresponsiveDuringDeallocation = (OMX_S32) 0x80001015,
 
-  /** A supplier port sends this error to the IL client (via the EventHandler callback) 
-      during the stopping of a port (either on a transition from the IDLE to LOADED 
-      state or a port stop) when it deems that it has waited an unusually long time for 
+  /** A supplier port sends this error to the IL client (via the EventHandler callback)
+      during the stopping of a port (either on a transition from the IDLE to LOADED
+      state or a port stop) when it deems that it has waited an unusually long time for
       the non-supplier to return a buffer via an EmptyThisBuffer or FillThisBuffer call. */
   OMX_ErrorPortUnresponsiveDuringStop = (OMX_S32) 0x80001016,
 
@@ -229,7 +229,7 @@
   OMX_ErrorIncorrectStateTransition = (OMX_S32) 0x80001017,
 
   /* Attempting a command that is not allowed during the present state. */
-  OMX_ErrorIncorrectStateOperation = (OMX_S32) 0x80001018, 
+  OMX_ErrorIncorrectStateOperation = (OMX_S32) 0x80001018,
 
   /** The values encapsulated in the parameter or config structure are not supported. */
   OMX_ErrorUnsupportedSetting = (OMX_S32) 0x80001019,
@@ -249,12 +249,12 @@
   /** Component suspended due to an inability to acquire dynamic resources */
   OMX_ErrorDynamicResourcesUnavailable = (OMX_S32) 0x8000101E,
 
-  /** When the macroblock error reporting is enabled the component returns new error 
+  /** When the macroblock error reporting is enabled the component returns new error
   for every frame that has errors */
   OMX_ErrorMbErrorsInFrame = (OMX_S32) 0x8000101F,
 
   /** A component reports this error when it cannot parse or determine the format of an input stream. */
-  OMX_ErrorFormatNotDetected = (OMX_S32) 0x80001020, 
+  OMX_ErrorFormatNotDetected = (OMX_S32) 0x80001020,
 
   /** The content open operation failed. */
   OMX_ErrorContentPipeOpenFailed = (OMX_S32) 0x80001021,
@@ -268,7 +268,7 @@
   /** Tunneling is unsupported by the component*/
   OMX_ErrorTunnelingUnsupported = (OMX_S32) 0x80001024,
 
-  OMX_ErrorKhronosExtensions = (OMX_S32)0x8F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+  OMX_ErrorKhronosExtensions = (OMX_S32)0x8F000000, /**< Reserved region for introducing Khronos Standard Extensions */
   OMX_ErrorVendorStartUnused = (OMX_S32)0x90000000, /**< Reserved region for introducing Vendor Extensions */
   OMX_ErrorMax = 0x7FFFFFFF
 } OMX_ERRORTYPE;
@@ -304,69 +304,69 @@
     OMX_U8 cRole[OMX_MAX_STRINGNAME_SIZE];  /**< name of standard component which defines component role */
 } OMX_PARAM_COMPONENTROLETYPE;
 
-/** End of Stream Buffer Flag: 
+/** End of Stream Buffer Flag:
   *
-  * A component sets EOS when it has no more data to emit on a particular 
-  * output port. Thus an output port shall set EOS on the last buffer it 
-  * emits. A component's determination of when an output port should 
+  * A component sets EOS when it has no more data to emit on a particular
+  * output port. Thus an output port shall set EOS on the last buffer it
+  * emits. A component's determination of when an output port should
   * cease sending data is implemenation specific.
   * @ingroup buf
   */
 
-#define OMX_BUFFERFLAG_EOS 0x00000001 
+#define OMX_BUFFERFLAG_EOS 0x00000001
 
-/** Start Time Buffer Flag: 
+/** Start Time Buffer Flag:
  *
  * The source of a stream (e.g. a demux component) sets the STARTTIME
  * flag on the buffer that contains the starting timestamp for the
  * stream. The starting timestamp corresponds to the first data that
  * should be displayed at startup or after a seek.
  * The first timestamp of the stream is not necessarily the start time.
- * For instance, in the case of a seek to a particular video frame, 
- * the target frame may be an interframe. Thus the first buffer of 
+ * For instance, in the case of a seek to a particular video frame,
+ * the target frame may be an interframe. Thus the first buffer of
  * the stream will be the intra-frame preceding the target frame and
  * the starttime will occur with the target frame (with any other
  * required frames required to reconstruct the target intervening).
  *
- * The STARTTIME flag is directly associated with the buffer's 
- * timestamp ' thus its association to buffer data and its 
+ * The STARTTIME flag is directly associated with the buffer's
+ * timestamp ' thus its association to buffer data and its
  * propagation is identical to the timestamp's.
  *
- * When a Sync Component client receives a buffer with the 
- * STARTTIME flag it shall perform a SetConfig on its sync port 
+ * When a Sync Component client receives a buffer with the
+ * STARTTIME flag it shall perform a SetConfig on its sync port
  * using OMX_ConfigTimeClientStartTime and passing the buffer's
  * timestamp.
- * 
+ *
  * @ingroup buf
  */
 
 #define OMX_BUFFERFLAG_STARTTIME 0x00000002
 
- 
 
-/** Decode Only Buffer Flag: 
+
+/** Decode Only Buffer Flag:
  *
  * The source of a stream (e.g. a demux component) sets the DECODEONLY
  * flag on any buffer that should shall be decoded but should not be
- * displayed. This flag is used, for instance, when a source seeks to 
- * a target interframe that requires the decode of frames preceding the 
- * target to facilitate the target's reconstruction. In this case the 
- * source would emit the frames preceding the target downstream 
+ * displayed. This flag is used, for instance, when a source seeks to
+ * a target interframe that requires the decode of frames preceding the
+ * target to facilitate the target's reconstruction. In this case the
+ * source would emit the frames preceding the target downstream
  * but mark them as decode only.
  *
- * The DECODEONLY is associated with buffer data and propagated in a 
+ * The DECODEONLY is associated with buffer data and propagated in a
  * manner identical to the buffer timestamp.
  *
- * A component that renders data should ignore all buffers with 
+ * A component that renders data should ignore all buffers with
  * the DECODEONLY flag set.
- * 
+ *
  * @ingroup buf
  */
 
 #define OMX_BUFFERFLAG_DECODEONLY 0x00000004
 
 
-/* Data Corrupt Flag: This flag is set when the IL client believes the data in the associated buffer is corrupt 
+/* Data Corrupt Flag: This flag is set when the IL client believes the data in the associated buffer is corrupt
  * @ingroup buf
  */
 
@@ -374,29 +374,29 @@
 
 /* End of Frame: The buffer contains exactly one end of frame and no data
  *  occurs after the end of frame. This flag is an optional hint. The absence
- *  of this flag does not imply the absence of an end of frame within the buffer. 
+ *  of this flag does not imply the absence of an end of frame within the buffer.
  * @ingroup buf
 */
 #define OMX_BUFFERFLAG_ENDOFFRAME 0x00000010
 
-/* Sync Frame Flag: This flag is set when the buffer content contains a coded sync frame ' 
- *  a frame that has no dependency on any other frame information 
+/* Sync Frame Flag: This flag is set when the buffer content contains a coded sync frame '
+ *  a frame that has no dependency on any other frame information
  *  @ingroup buf
  */
 #define OMX_BUFFERFLAG_SYNCFRAME 0x00000020
 
 /* Extra data present flag: there is extra data appended to the data stream
- * residing in the buffer 
- * @ingroup buf  
+ * residing in the buffer
+ * @ingroup buf
  */
 #define OMX_BUFFERFLAG_EXTRADATA 0x00000040
 
-/** Codec Config Buffer Flag: 
+/** Codec Config Buffer Flag:
 * OMX_BUFFERFLAG_CODECCONFIG is an optional flag that is set by an
 * output port when all bytes in the buffer form part or all of a set of
 * codec specific configuration data.  Examples include SPS/PPS nal units
 * for OMX_VIDEO_CodingAVC or AudioSpecificConfig data for
-* OMX_AUDIO_CodingAAC.  Any component that for a given stream sets 
+* OMX_AUDIO_CodingAAC.  Any component that for a given stream sets
 * OMX_BUFFERFLAG_CODECCONFIG shall not mix codec configuration bytes
 * with frame data in the same buffer, and shall send all buffers
 * containing codec configuration bytes before any buffers containing
@@ -416,50 +416,50 @@
 {
     OMX_U32 nSize;              /**< size of the structure in bytes */
     OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
-    OMX_U8* pBuffer;            /**< Pointer to actual block of memory 
+    OMX_U8* pBuffer;            /**< Pointer to actual block of memory
                                      that is acting as the buffer */
     OMX_U32 nAllocLen;          /**< size of the buffer allocated, in bytes */
-    OMX_U32 nFilledLen;         /**< number of bytes currently in the 
+    OMX_U32 nFilledLen;         /**< number of bytes currently in the
                                      buffer */
     OMX_U32 nOffset;            /**< start offset of valid data in bytes from
                                      the start of the buffer */
     OMX_PTR pAppPrivate;        /**< pointer to any data the application
                                      wants to associate with this buffer */
     OMX_PTR pPlatformPrivate;   /**< pointer to any data the platform
-                                     wants to associate with this buffer */ 
+                                     wants to associate with this buffer */
     OMX_PTR pInputPortPrivate;  /**< pointer to any data the input port
                                      wants to associate with this buffer */
     OMX_PTR pOutputPortPrivate; /**< pointer to any data the output port
                                      wants to associate with this buffer */
-    OMX_HANDLETYPE hMarkTargetComponent; /**< The component that will generate a 
+    OMX_HANDLETYPE hMarkTargetComponent; /**< The component that will generate a
                                               mark event upon processing this buffer. */
-    OMX_PTR pMarkData;          /**< Application specific data associated with 
-                                     the mark sent on a mark event to disambiguate 
+    OMX_PTR pMarkData;          /**< Application specific data associated with
+                                     the mark sent on a mark event to disambiguate
                                      this mark from others. */
     OMX_U32 nTickCount;         /**< Optional entry that the component and
                                      application can update with a tick count
                                      when they access the component.  This
                                      value should be in microseconds.  Since
                                      this is a value relative to an arbitrary
-                                     starting point, this value cannot be used 
+                                     starting point, this value cannot be used
                                      to determine absolute time.  This is an
                                      optional entry and not all components
                                      will update it.*/
- OMX_TICKS nTimeStamp;          /**< Timestamp corresponding to the sample 
-                                     starting at the first logical sample 
-                                     boundary in the buffer. Timestamps of 
+ OMX_TICKS nTimeStamp;          /**< Timestamp corresponding to the sample
+                                     starting at the first logical sample
+                                     boundary in the buffer. Timestamps of
                                      successive samples within the buffer may
-                                     be inferred by adding the duration of the 
+                                     be inferred by adding the duration of the
                                      of the preceding buffer to the timestamp
                                      of the preceding buffer.*/
   OMX_U32     nFlags;           /**< buffer specific flags */
-  OMX_U32 nOutputPortIndex;     /**< The index of the output port (if any) using 
+  OMX_U32 nOutputPortIndex;     /**< The index of the output port (if any) using
                                      this buffer */
   OMX_U32 nInputPortIndex;      /**< The index of the input port (if any) using
                                      this buffer */
 } OMX_BUFFERHEADERTYPE;
 
-/** The OMX_EXTRADATATYPE enumeration is used to define the 
+/** The OMX_EXTRADATATYPE enumeration is used to define the
  * possible extra data payload types.
  * NB: this enum is binary backwards compatible with the previous
  * OMX_EXTRADATA_QUANT define.  This should be replaced with
@@ -467,9 +467,9 @@
  */
 typedef enum OMX_EXTRADATATYPE
 {
-   OMX_ExtraDataNone = 0,                       /**< Indicates that no more extra data sections follow */        
+   OMX_ExtraDataNone = 0,                       /**< Indicates that no more extra data sections follow */
    OMX_ExtraDataQuantization,                   /**< The data payload contains quantization data */
-   OMX_ExtraDataKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+   OMX_ExtraDataKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
    OMX_ExtraDataVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
    OMX_ExtraDataMax = 0x7FFFFFFF
 } OMX_EXTRADATATYPE;
@@ -477,7 +477,7 @@
 
 typedef struct OMX_OTHER_EXTRADATATYPE  {
     OMX_U32 nSize;
-    OMX_VERSIONTYPE nVersion;               
+    OMX_VERSIONTYPE nVersion;
     OMX_U32 nPortIndex;
     OMX_EXTRADATATYPE eType;       /* Extra Data type */
     OMX_U32 nDataSize;   /* Size of the supporting data to follow */
@@ -490,7 +490,7 @@
     OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
     OMX_U32 nPorts;             /**< The number of ports for this component */
     OMX_U32 nStartPortNumber;   /** first port number for this type of port */
-} OMX_PORT_PARAM_TYPE; 
+} OMX_PORT_PARAM_TYPE;
 
 /** @ingroup comp */
 typedef enum OMX_EVENTTYPE
@@ -499,14 +499,14 @@
     OMX_EventError,               /**< component has detected an error condition */
     OMX_EventMark,                /**< component has detected a buffer mark */
     OMX_EventPortSettingsChanged, /**< component is reported a port settings change */
-    OMX_EventBufferFlag,          /**< component has detected an EOS */ 
+    OMX_EventBufferFlag,          /**< component has detected an EOS */
     OMX_EventResourcesAcquired,   /**< component has been granted resources and is
                                        automatically starting the state change from
                                        OMX_StateWaitForResources to OMX_StateIdle. */
    OMX_EventComponentResumed,     /**< Component resumed due to reacquisition of resources */
    OMX_EventDynamicResourcesAvailable, /**< Component has acquired previously unavailable dynamic resources */
    OMX_EventPortFormatDetected,      /**< Component has detected a supported format. */
-   OMX_EventKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+   OMX_EventKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
    OMX_EventVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
    OMX_EventMax = 0x7FFFFFFF
 } OMX_EVENTTYPE;
@@ -517,7 +517,7 @@
         event of interest occurs.  Events are defined in the OMX_EVENTTYPE
         enumeration.  Please see that enumeration for details of what will
         be returned for each type of event. Callbacks should not return
-        an error to the component, so if an error occurs, the application 
+        an error to the component, so if an error occurs, the application
         shall handle it internally.  This is a blocking call.
 
         The application should return from this call within 5 msec to avoid
@@ -527,14 +527,14 @@
             handle of the component to access.  This is the component
             handle returned by the call to the GetHandle function.
         @param pAppData
-            pointer to an application defined value that was provided in the 
+            pointer to an application defined value that was provided in the
             pAppData parameter to the OMX_GetHandle method for the component.
-            This application defined value is provided so that the application 
+            This application defined value is provided so that the application
             can have a component specific context when receiving the callback.
         @param eEvent
             Event that the component wants to notify the application about.
         @param nData1
-            nData will be the OMX_ERRORTYPE for an error event and will be 
+            nData will be the OMX_ERRORTYPE for an error event and will be
             an OMX_COMMANDTYPE for a command complete event and OMX_INDEXTYPE for a OMX_PortSettingsChanged event.
          @param nData2
             nData2 will hold further information related to the event. Can be OMX_STATETYPE for
@@ -553,21 +553,21 @@
         OMX_IN OMX_PTR pEventData);
 
     /** The EmptyBufferDone method is used to return emptied buffers from an
-        input port back to the application for reuse.  This is a blocking call 
+        input port back to the application for reuse.  This is a blocking call
         so the application should not attempt to refill the buffers during this
         call, but should queue them and refill them in another thread.  There
         is no error return, so the application shall handle any errors generated
-        internally.  
-        
+        internally.
+
         The application should return from this call within 5 msec.
-        
+
         @param hComponent
             handle of the component to access.  This is the component
             handle returned by the call to the GetHandle function.
         @param pAppData
-            pointer to an application defined value that was provided in the 
+            pointer to an application defined value that was provided in the
             pAppData parameter to the OMX_GetHandle method for the component.
-            This application defined value is provided so that the application 
+            This application defined value is provided so that the application
             can have a component specific context when receiving the callback.
         @param pBuffer
             pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer
@@ -580,23 +580,23 @@
         OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
 
     /** The FillBufferDone method is used to return filled buffers from an
-        output port back to the application for emptying and then reuse.  
-        This is a blocking call so the application should not attempt to 
-        empty the buffers during this call, but should queue the buffers 
-        and empty them in another thread.  There is no error return, so 
-        the application shall handle any errors generated internally.  The 
+        output port back to the application for emptying and then reuse.
+        This is a blocking call so the application should not attempt to
+        empty the buffers during this call, but should queue the buffers
+        and empty them in another thread.  There is no error return, so
+        the application shall handle any errors generated internally.  The
         application shall also update the buffer header to indicate the
-        number of bytes placed into the buffer.  
+        number of bytes placed into the buffer.
 
         The application should return from this call within 5 msec.
-        
+
         @param hComponent
             handle of the component to access.  This is the component
             handle returned by the call to the GetHandle function.
         @param pAppData
-            pointer to an application defined value that was provided in the 
+            pointer to an application defined value that was provided in the
             pAppData parameter to the OMX_GetHandle method for the component.
-            This application defined value is provided so that the application 
+            This application defined value is provided so that the application
             can have a component specific context when receiving the callback.
         @param pBuffer
             pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer
@@ -620,13 +620,13 @@
                                               or don't care */
     OMX_BufferSupplyInput,             /**< input port supplies the buffers */
     OMX_BufferSupplyOutput,            /**< output port supplies the buffers */
-    OMX_BufferSupplyKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_BufferSupplyKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_BufferSupplyVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_BufferSupplyMax = 0x7FFFFFFF
 } OMX_BUFFERSUPPLIERTYPE;
 
 
-/** buffer supplier parameter 
+/** buffer supplier parameter
  * @ingroup tun
  */
 typedef struct OMX_PARAM_BUFFERSUPPLIERTYPE {
@@ -637,61 +637,61 @@
 } OMX_PARAM_BUFFERSUPPLIERTYPE;
 
 
-/**< indicates that buffers received by an input port of a tunnel 
-     may not modify the data in the buffers 
+/**< indicates that buffers received by an input port of a tunnel
+     may not modify the data in the buffers
      @ingroup tun
  */
-#define OMX_PORTTUNNELFLAG_READONLY 0x00000001 
+#define OMX_PORTTUNNELFLAG_READONLY 0x00000001
 
 
 /** The OMX_TUNNELSETUPTYPE structure is used to pass data from an output
     port to an input port as part the two ComponentTunnelRequest calls
-    resulting from a OMX_SetupTunnel call from the IL Client. 
+    resulting from a OMX_SetupTunnel call from the IL Client.
     @ingroup tun
- */   
+ */
 typedef struct OMX_TUNNELSETUPTYPE
 {
     OMX_U32 nTunnelFlags;             /**< bit flags for tunneling */
     OMX_BUFFERSUPPLIERTYPE eSupplier; /**< supplier preference */
-} OMX_TUNNELSETUPTYPE; 
+} OMX_TUNNELSETUPTYPE;
 
 /* OMX Component headers is included to enable the core to use
-   macros for functions into the component for OMX release 1.0.  
+   macros for functions into the component for OMX release 1.0.
    Developers should not access any structures or data from within
    the component header directly */
 /* TO BE REMOVED - #include <OMX_Component.h> */
 
-/** GetComponentVersion will return information about the component.  
+/** GetComponentVersion will return information about the component.
     This is a blocking call.  This macro will go directly from the
     application to the component (via a core macro).  The
     component will return from this call within 5 msec.
     @param [in] hComponent
         handle of component to execute the command
     @param [out] pComponentName
-        pointer to an empty string of length 128 bytes.  The component 
-        will write its name into this string.  The name will be 
-        terminated by a single zero byte.  The name of a component will 
-        be 127 bytes or less to leave room for the trailing zero byte.  
+        pointer to an empty string of length 128 bytes.  The component
+        will write its name into this string.  The name will be
+        terminated by a single zero byte.  The name of a component will
+        be 127 bytes or less to leave room for the trailing zero byte.
         An example of a valid component name is "OMX.ABC.ChannelMixer\0".
     @param [out] pComponentVersion
-        pointer to an OMX Version structure that the component will fill 
-        in.  The component will fill in a value that indicates the 
-        component version.  NOTE: the component version is NOT the same 
-        as the OMX Specification version (found in all structures).  The 
-        component version is defined by the vendor of the component and 
+        pointer to an OMX Version structure that the component will fill
+        in.  The component will fill in a value that indicates the
+        component version.  NOTE: the component version is NOT the same
+        as the OMX Specification version (found in all structures).  The
+        component version is defined by the vendor of the component and
         its value is entirely up to the component vendor.
     @param [out] pSpecVersion
-        pointer to an OMX Version structure that the component will fill 
-        in.  The SpecVersion is the version of the specification that the 
-        component was built against.  Please note that this value may or 
-        may not match the structure's version.  For example, if the 
-        component was built against the 2.0 specification, but the 
-        application (which creates the structure is built against the 
+        pointer to an OMX Version structure that the component will fill
+        in.  The SpecVersion is the version of the specification that the
+        component was built against.  Please note that this value may or
+        may not match the structure's version.  For example, if the
+        component was built against the 2.0 specification, but the
+        application (which creates the structure is built against the
         1.0 specification the versions would be different.
     @param [out] pComponentUUID
-        pointer to the UUID of the component which will be filled in by 
-        the component.  The UUID is a unique identifier that is set at 
-        RUN time for the component and is unique to each instantion of 
+        pointer to the UUID of the component which will be filled in by
+        the component.  The UUID is a unique identifier that is set at
+        RUN time for the component and is unique to each instantion of
         the component.
     @return OMX_ERRORTYPE
         If the command successfully executes, the return code will be
@@ -714,46 +714,46 @@
 
 /** Send a command to the component.  This call is a non-blocking call.
     The component should check the parameters and then queue the command
-    to the component thread to be executed.  The component thread shall 
-    send the EventHandler() callback at the conclusion of the command. 
+    to the component thread to be executed.  The component thread shall
+    send the EventHandler() callback at the conclusion of the command.
     This macro will go directly from the application to the component (via
     a core macro).  The component will return from this call within 5 msec.
-    
+
     When the command is "OMX_CommandStateSet" the component will queue a
     state transition to the new state idenfied in nParam.
-    
+
     When the command is "OMX_CommandFlush", to flush a port's buffer queues,
-    the command will force the component to return all buffers NOT CURRENTLY 
-    BEING PROCESSED to the application, in the order in which the buffers 
+    the command will force the component to return all buffers NOT CURRENTLY
+    BEING PROCESSED to the application, in the order in which the buffers
     were received.
-    
-    When the command is "OMX_CommandPortDisable" or 
+
+    When the command is "OMX_CommandPortDisable" or
     "OMX_CommandPortEnable", the component's port (given by the value of
-    nParam) will be stopped or restarted. 
-    
+    nParam) will be stopped or restarted.
+
     When the command "OMX_CommandMarkBuffer" is used to mark a buffer, the
     pCmdData will point to a OMX_MARKTYPE structure containing the component
     handle of the component to examine the buffer chain for the mark.  nParam1
     contains the index of the port on which the buffer mark is applied.
 
-    Specification text for more details. 
-    
+    Specification text for more details.
+
     @param [in] hComponent
         handle of component to execute the command
     @param [in] Cmd
         Command for the component to execute
     @param [in] nParam
-        Parameter for the command to be executed.  When Cmd has the value 
-        OMX_CommandStateSet, value is a member of OMX_STATETYPE.  When Cmd has 
-        the value OMX_CommandFlush, value of nParam indicates which port(s) 
-        to flush. -1 is used to flush all ports a single port index will 
+        Parameter for the command to be executed.  When Cmd has the value
+        OMX_CommandStateSet, value is a member of OMX_STATETYPE.  When Cmd has
+        the value OMX_CommandFlush, value of nParam indicates which port(s)
+        to flush. -1 is used to flush all ports a single port index will
         only flush that port.  When Cmd has the value "OMX_CommandPortDisable"
-        or "OMX_CommandPortEnable", the component's port is given by 
+        or "OMX_CommandPortEnable", the component's port is given by
         the value of nParam.  When Cmd has the value "OMX_CommandMarkBuffer"
         the components pot is given by the value of nParam.
     @param [in] pCmdData
         Parameter pointing to the OMX_MARKTYPE structure when Cmd has the value
-        "OMX_CommandMarkBuffer".     
+        "OMX_CommandMarkBuffer".
     @return OMX_ERRORTYPE
         If the command successfully executes, the return code will be
         OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
@@ -771,21 +771,21 @@
          pCmdData)                          /* Macro End */
 
 
-/** The OMX_GetParameter macro will get one of the current parameter 
-    settings from the component.  This macro cannot only be invoked when 
+/** The OMX_GetParameter macro will get one of the current parameter
+    settings from the component.  This macro cannot only be invoked when
     the component is in the OMX_StateInvalid state.  The nParamIndex
     parameter is used to indicate which structure is being requested from
-    the component.  The application shall allocate the correct structure 
-    and shall fill in the structure size and version information before 
+    the component.  The application shall allocate the correct structure
+    and shall fill in the structure size and version information before
     invoking this macro.  When the parameter applies to a port, the
     caller shall fill in the appropriate nPortIndex value indicating the
-    port on which the parameter applies. If the component has not had 
-    any settings changed, then the component should return a set of 
-    valid DEFAULT  parameters for the component.  This is a blocking 
-    call.  
-    
+    port on which the parameter applies. If the component has not had
+    any settings changed, then the component should return a set of
+    valid DEFAULT  parameters for the component.  This is a blocking
+    call.
+
     The component should return from this call within 20 msec.
-    
+
     @param [in] hComponent
         Handle of the component to be accessed.  This is the component
         handle returned by the call to the OMX_GetHandle function.
@@ -793,7 +793,7 @@
         Index of the structure to be filled.  This value is from the
         OMX_INDEXTYPE enumeration.
     @param [in,out] pComponentParameterStructure
-        Pointer to application allocated structure to be filled by the 
+        Pointer to application allocated structure to be filled by the
         component.
     @return OMX_ERRORTYPE
         If the command successfully executes, the return code will be
@@ -814,17 +814,17 @@
     structure to a component.  Each structure shall be sent one at a time,
     in a separate invocation of the macro.  This macro can only be
     invoked when the component is in the OMX_StateLoaded state, or the
-    port is disabled (when the parameter applies to a port). The 
+    port is disabled (when the parameter applies to a port). The
     nParamIndex parameter is used to indicate which structure is being
-    passed to the component.  The application shall allocate the 
-    correct structure and shall fill in the structure size and version 
+    passed to the component.  The application shall allocate the
+    correct structure and shall fill in the structure size and version
     information (as well as the actual data) before invoking this macro.
     The application is free to dispose of this structure after the call
-    as the component is required to copy any data it shall retain.  This 
-    is a blocking call.  
-    
+    as the component is required to copy any data it shall retain.  This
+    is a blocking call.
+
     The component should return from this call within 20 msec.
-    
+
     @param [in] hComponent
         Handle of the component to be accessed.  This is the component
         handle returned by the call to the OMX_GetHandle function.
@@ -849,18 +849,18 @@
         pComponentParameterStructure)    /* Macro End */
 
 
-/** The OMX_GetConfig macro will get one of the configuration structures 
-    from a component.  This macro can be invoked anytime after the 
-    component has been loaded.  The nParamIndex call parameter is used to 
-    indicate which structure is being requested from the component.  The 
-    application shall allocate the correct structure and shall fill in the 
-    structure size and version information before invoking this macro.  
-    If the component has not had this configuration parameter sent before, 
-    then the component should return a set of valid DEFAULT values for the 
-    component.  This is a blocking call.  
-    
+/** The OMX_GetConfig macro will get one of the configuration structures
+    from a component.  This macro can be invoked anytime after the
+    component has been loaded.  The nParamIndex call parameter is used to
+    indicate which structure is being requested from the component.  The
+    application shall allocate the correct structure and shall fill in the
+    structure size and version information before invoking this macro.
+    If the component has not had this configuration parameter sent before,
+    then the component should return a set of valid DEFAULT values for the
+    component.  This is a blocking call.
+
     The component should return from this call within 5 msec.
-    
+
     @param [in] hComponent
         Handle of the component to be accessed.  This is the component
         handle returned by the call to the OMX_GetHandle function.
@@ -868,13 +868,13 @@
         Index of the structure to be filled.  This value is from the
         OMX_INDEXTYPE enumeration.
     @param [in,out] pComponentConfigStructure
-        pointer to application allocated structure to be filled by the 
+        pointer to application allocated structure to be filled by the
         component.
     @return OMX_ERRORTYPE
         If the command successfully executes, the return code will be
         OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
     @ingroup comp
-*/        
+*/
 #define OMX_GetConfig(                                      \
         hComponent,                                         \
         nConfigIndex,                                       \
@@ -885,18 +885,18 @@
         pComponentConfigStructure)       /* Macro End */
 
 
-/** The OMX_SetConfig macro will send one of the configuration 
+/** The OMX_SetConfig macro will send one of the configuration
     structures to a component.  Each structure shall be sent one at a time,
-    each in a separate invocation of the macro.  This macro can be invoked 
-    anytime after the component has been loaded.  The application shall 
-    allocate the correct structure and shall fill in the structure size 
-    and version information (as well as the actual data) before invoking 
-    this macro.  The application is free to dispose of this structure after 
-    the call as the component is required to copy any data it shall retain.  
-    This is a blocking call.  
-    
+    each in a separate invocation of the macro.  This macro can be invoked
+    anytime after the component has been loaded.  The application shall
+    allocate the correct structure and shall fill in the structure size
+    and version information (as well as the actual data) before invoking
+    this macro.  The application is free to dispose of this structure after
+    the call as the component is required to copy any data it shall retain.
+    This is a blocking call.
+
     The component should return from this call within 5 msec.
-    
+
     @param [in] hComponent
         Handle of the component to be accessed.  This is the component
         handle returned by the call to the OMX_GetHandle function.
@@ -921,22 +921,22 @@
         pComponentConfigStructure)       /* Macro End */
 
 
-/** The OMX_GetExtensionIndex macro will invoke a component to translate 
-    a vendor specific configuration or parameter string into an OMX 
-    structure index.  There is no requirement for the vendor to support 
-    this command for the indexes already found in the OMX_INDEXTYPE 
-    enumeration (this is done to save space in small components).  The 
+/** The OMX_GetExtensionIndex macro will invoke a component to translate
+    a vendor specific configuration or parameter string into an OMX
+    structure index.  There is no requirement for the vendor to support
+    this command for the indexes already found in the OMX_INDEXTYPE
+    enumeration (this is done to save space in small components).  The
     component shall support all vendor supplied extension indexes not found
-    in the master OMX_INDEXTYPE enumeration.  This is a blocking call.  
-    
+    in the master OMX_INDEXTYPE enumeration.  This is a blocking call.
+
     The component should return from this call within 5 msec.
-    
+
     @param [in] hComponent
         Handle of the component to be accessed.  This is the component
         handle returned by the call to the GetHandle function.
     @param [in] cParameterName
         OMX_STRING that shall be less than 128 characters long including
-        the trailing null byte.  This is the string that will get 
+        the trailing null byte.  This is the string that will get
         translated by the component into a configuration index.
     @param [out] pIndexType
         a pointer to a OMX_INDEXTYPE to receive the index value.
@@ -955,18 +955,18 @@
         pIndexType)                     /* Macro End */
 
 
-/** The OMX_GetState macro will invoke the component to get the current 
+/** The OMX_GetState macro will invoke the component to get the current
     state of the component and place the state value into the location
-    pointed to by pState.  
-    
+    pointed to by pState.
+
     The component should return from this call within 5 msec.
-    
+
     @param [in] hComponent
         Handle of the component to be accessed.  This is the component
         handle returned by the call to the OMX_GetHandle function.
     @param [out] pState
         pointer to the location to receive the state.  The value returned
-        is one of the OMX_STATETYPE members 
+        is one of the OMX_STATETYPE members
     @return OMX_ERRORTYPE
         If the command successfully executes, the return code will be
         OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
@@ -981,17 +981,17 @@
 
 
 /** The OMX_UseBuffer macro will request that the component use
-    a buffer (and allocate its own buffer header) already allocated 
-    by another component, or by the IL Client. This is a blocking 
+    a buffer (and allocate its own buffer header) already allocated
+    by another component, or by the IL Client. This is a blocking
     call.
-    
+
     The component should return from this call within 20 msec.
-    
+
     @param [in] hComponent
         Handle of the component to be accessed.  This is the component
         handle returned by the call to the OMX_GetHandle function.
     @param [out] ppBuffer
-        pointer to an OMX_BUFFERHEADERTYPE structure used to receive the 
+        pointer to an OMX_BUFFERHEADERTYPE structure used to receive the
         pointer to the buffer header
     @return OMX_ERRORTYPE
         If the command successfully executes, the return code will be
@@ -1015,25 +1015,25 @@
            pBuffer)
 
 
-/** The OMX_AllocateBuffer macro will request that the component allocate 
-    a new buffer and buffer header.  The component will allocate the 
-    buffer and the buffer header and return a pointer to the buffer 
+/** The OMX_AllocateBuffer macro will request that the component allocate
+    a new buffer and buffer header.  The component will allocate the
+    buffer and the buffer header and return a pointer to the buffer
     header.  This is a blocking call.
-    
+
     The component should return from this call within 5 msec.
-    
+
     @param [in] hComponent
         Handle of the component to be accessed.  This is the component
         handle returned by the call to the OMX_GetHandle function.
     @param [out] ppBuffer
-        pointer to an OMX_BUFFERHEADERTYPE structure used to receive 
+        pointer to an OMX_BUFFERHEADERTYPE structure used to receive
         the pointer to the buffer header
     @param [in] nPortIndex
         nPortIndex is used to select the port on the component the buffer will
         be used with.  The port can be found by using the nPortIndex
         value as an index into the Port Definition array of the component.
     @param [in] pAppPrivate
-        pAppPrivate is used to initialize the pAppPrivate member of the 
+        pAppPrivate is used to initialize the pAppPrivate member of the
         buffer header structure.
     @param [in] nSizeBytes
         size of the buffer to allocate.  Used when bAllocateNew is true.
@@ -1041,7 +1041,7 @@
         If the command successfully executes, the return code will be
         OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
     @ingroup comp buf
- */    
+ */
 #define OMX_AllocateBuffer(                                 \
         hComponent,                                         \
         ppBuffer,                                           \
@@ -1057,13 +1057,13 @@
 
 
 /** The OMX_FreeBuffer macro will release a buffer header from the component
-    which was allocated using either OMX_AllocateBuffer or OMX_UseBuffer. If  
-    the component allocated the buffer (see the OMX_UseBuffer macro) then 
-    the component shall free the buffer and buffer header. This is a 
-    blocking call. 
-    
+    which was allocated using either OMX_AllocateBuffer or OMX_UseBuffer. If
+    the component allocated the buffer (see the OMX_UseBuffer macro) then
+    the component shall free the buffer and buffer header. This is a
+    blocking call.
+
     The component should return from this call within 20 msec.
-    
+
     @param [in] hComponent
         Handle of the component to be accessed.  This is the component
         handle returned by the call to the OMX_GetHandle function.
@@ -1088,17 +1088,17 @@
         pBuffer)                        /* Macro End */
 
 
-/** The OMX_EmptyThisBuffer macro will send a buffer full of data to an 
+/** The OMX_EmptyThisBuffer macro will send a buffer full of data to an
     input port of a component.  The buffer will be emptied by the component
     and returned to the application via the EmptyBufferDone call back.
     This is a non-blocking call in that the component will record the buffer
-    and return immediately and then empty the buffer, later, at the proper 
-    time.  As expected, this macro may be invoked only while the component 
+    and return immediately and then empty the buffer, later, at the proper
+    time.  As expected, this macro may be invoked only while the component
     is in the OMX_StateExecuting.  If nPortIndex does not specify an input
-    port, the component shall return an error.  
-    
+    port, the component shall return an error.
+
     The component should return from this call within 5 msec.
-    
+
     @param [in] hComponent
         Handle of the component to be accessed.  This is the component
         handle returned by the call to the OMX_GetHandle function.
@@ -1118,17 +1118,17 @@
         pBuffer)                        /* Macro End */
 
 
-/** The OMX_FillThisBuffer macro will send an empty buffer to an 
+/** The OMX_FillThisBuffer macro will send an empty buffer to an
     output port of a component.  The buffer will be filled by the component
     and returned to the application via the FillBufferDone call back.
     This is a non-blocking call in that the component will record the buffer
-    and return immediately and then fill the buffer, later, at the proper 
-    time.  As expected, this macro may be invoked only while the component 
+    and return immediately and then fill the buffer, later, at the proper
+    time.  As expected, this macro may be invoked only while the component
     is in the OMX_ExecutingState.  If nPortIndex does not specify an output
-    port, the component shall return an error.  
-    
+    port, the component shall return an error.
+
     The component should return from this call within 5 msec.
-    
+
     @param [in] hComponent
         Handle of the component to be accessed.  This is the component
         handle returned by the call to the OMX_GetHandle function.
@@ -1152,14 +1152,14 @@
 /** The OMX_UseEGLImage macro will request that the component use
     a EGLImage provided by EGL (and allocate its own buffer header)
     This is a blocking call.
-    
+
     The component should return from this call within 20 msec.
-    
+
     @param [in] hComponent
         Handle of the component to be accessed.  This is the component
         handle returned by the call to the OMX_GetHandle function.
     @param [out] ppBuffer
-        pointer to an OMX_BUFFERHEADERTYPE structure used to receive the 
+        pointer to an OMX_BUFFERHEADERTYPE structure used to receive the
         pointer to the buffer header.  Note that the memory location used
         for this buffer is NOT visible to the IL Client.
     @param [in] nPortIndex
@@ -1167,13 +1167,13 @@
         be used with.  The port can be found by using the nPortIndex
         value as an index into the Port Definition array of the component.
     @param [in] pAppPrivate
-        pAppPrivate is used to initialize the pAppPrivate member of the 
+        pAppPrivate is used to initialize the pAppPrivate member of the
         buffer header structure.
     @param [in] eglImage
         eglImage contains the handle of the EGLImage to use as a buffer on the
-        specified port.  The component is expected to validate properties of 
+        specified port.  The component is expected to validate properties of
         the EGLImage against the configuration of the port to ensure the component
-        can use the EGLImage as a buffer.          
+        can use the EGLImage as a buffer.
     @return OMX_ERRORTYPE
         If the command successfully executes, the return code will be
         OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
@@ -1194,8 +1194,8 @@
 
 /** The OMX_Init method is used to initialize the OMX core.  It shall be the
     first call made into OMX and it should only be executed one time without
-    an interviening OMX_Deinit call.  
-    
+    an interviening OMX_Deinit call.
+
     The core should return from this call within 20 msec.
 
     @return OMX_ERRORTYPE
@@ -1206,13 +1206,13 @@
 OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Init(void);
 
 
-/** The OMX_Deinit method is used to deinitialize the OMX core.  It shall be 
-    the last call made into OMX. In the event that the core determines that 
-    thare are components loaded when this call is made, the core may return 
+/** The OMX_Deinit method is used to deinitialize the OMX core.  It shall be
+    the last call made into OMX. In the event that the core determines that
+    thare are components loaded when this call is made, the core may return
     with an error rather than try to unload the components.
-        
+
     The core should return from this call within 20 msec.
-    
+
     @return OMX_ERRORTYPE
         If the command successfully executes, the return code will be
         OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
@@ -1229,23 +1229,23 @@
     installation of new components, it is only requried to detect newly
     installed components when the first call to enumerate component names
     is made (i.e. when nIndex is 0x0).
-    
+
     The core should return from this call in 20 msec.
-    
+
     @param [out] cComponentName
         pointer to a null terminated string with the component name.  The
         names of the components are strings less than 127 bytes in length
-        plus the trailing null for a maximum size of 128 bytes.  An example 
-        of a valid component name is "OMX.TI.AUDIO.DSP.MIXER\0".  Names are 
-        assigned by the vendor, but shall start with "OMX." and then have 
+        plus the trailing null for a maximum size of 128 bytes.  An example
+        of a valid component name is "OMX.TI.AUDIO.DSP.MIXER\0".  Names are
+        assigned by the vendor, but shall start with "OMX." and then have
         the Vendor designation next.
     @param [in] nNameLength
-        number of characters in the cComponentName string.  With all 
-        component name strings restricted to less than 128 characters 
+        number of characters in the cComponentName string.  With all
+        component name strings restricted to less than 128 characters
         (including the trailing null) it is recomended that the caller
         provide a input string for the cComponentName of 128 characters.
     @param [in] nIndex
-        number containing the enumeration index for the component. 
+        number containing the enumeration index for the component.
         Multiple calls to OMX_ComponentNameEnum with increasing values
         of nIndex will enumerate through the component names in the
         system until OMX_ErrorNoMore is returned.  The value of nIndex
@@ -1253,7 +1253,7 @@
         in the system.
     @return OMX_ERRORTYPE
         If the command successfully executes, the return code will be
-        OMX_ErrorNone.  When the value of nIndex exceeds the number of 
+        OMX_ErrorNone.  When the value of nIndex exceeds the number of
         components in the system minus 1, OMX_ErrorNoMore will be
         returned. Otherwise the appropriate OMX error will be returned.
     @ingroup core
@@ -1266,18 +1266,18 @@
 
 /** The OMX_GetHandle method will locate the component specified by the
     component name given, load that component into memory and then invoke
-    the component's methods to create an instance of the component.  
-    
+    the component's methods to create an instance of the component.
+
     The core should return from this call within 20 msec.
-    
+
     @param [out] pHandle
         pointer to an OMX_HANDLETYPE pointer to be filled in by this method.
     @param [in] cComponentName
         pointer to a null terminated string with the component name.  The
         names of the components are strings less than 127 bytes in length
-        plus the trailing null for a maximum size of 128 bytes.  An example 
-        of a valid component name is "OMX.TI.AUDIO.DSP.MIXER\0".  Names are 
-        assigned by the vendor, but shall start with "OMX." and then have 
+        plus the trailing null for a maximum size of 128 bytes.  An example
+        of a valid component name is "OMX.TI.AUDIO.DSP.MIXER\0".  Names are
+        assigned by the vendor, but shall start with "OMX." and then have
         the Vendor designation next.
     @param [in] pAppData
         pointer to an application defined value that will be returned
@@ -1285,24 +1285,24 @@
         of the callback.
     @param [in] pCallBacks
         pointer to a OMX_CALLBACKTYPE structure that will be passed to the
-        component to initialize it with.  
+        component to initialize it with.
     @return OMX_ERRORTYPE
         If the command successfully executes, the return code will be
         OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
     @ingroup core
  */
 OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle(
-    OMX_OUT OMX_HANDLETYPE* pHandle, 
+    OMX_OUT OMX_HANDLETYPE* pHandle,
     OMX_IN  OMX_STRING cComponentName,
     OMX_IN  OMX_PTR pAppData,
     OMX_IN  OMX_CALLBACKTYPE* pCallBacks);
 
 
-/** The OMX_FreeHandle method will free a handle allocated by the OMX_GetHandle 
+/** The OMX_FreeHandle method will free a handle allocated by the OMX_GetHandle
     method.  If the component reference count goes to zero, the component will
-    be unloaded from memory.  
-    
-    The core should return from this call within 20 msec when the component is 
+    be unloaded from memory.
+
+    The core should return from this call within 20 msec when the component is
     in the OMX_StateLoaded state.
 
     @param [in] hComponent
@@ -1321,34 +1321,34 @@
 /** The OMX_SetupTunnel method will handle the necessary calls to the components
     to setup the specified tunnel the two components.  NOTE: This is
     an actual method (not a #define macro).  This method will make calls into
-    the component ComponentTunnelRequest method to do the actual tunnel 
-    connection.  
+    the component ComponentTunnelRequest method to do the actual tunnel
+    connection.
 
-    The ComponentTunnelRequest method on both components will be called. 
-    This method shall not be called unless the component is in the 
+    The ComponentTunnelRequest method on both components will be called.
+    This method shall not be called unless the component is in the
     OMX_StateLoaded state except when the ports used for the tunnel are
     disabled. In this case, the component may be in the OMX_StateExecuting,
-    OMX_StatePause, or OMX_StateIdle states. 
+    OMX_StatePause, or OMX_StateIdle states.
 
     The core should return from this call within 20 msec.
-    
+
     @param [in] hOutput
         Handle of the component to be accessed.  Also this is the handle
         of the component whose port, specified in the nPortOutput parameter
         will be used the source for the tunnel. This is the component handle
-        returned by the call to the OMX_GetHandle function.  There is a 
+        returned by the call to the OMX_GetHandle function.  There is a
         requirement that hOutput be the source for the data when
         tunelling (i.e. nPortOutput is an output port).  If 0x0, the component
         specified in hInput will have it's port specified in nPortInput
         setup for communication with the application / IL client.
     @param [in] nPortOutput
         nPortOutput is used to select the source port on component to be
-        used in the tunnel. 
+        used in the tunnel.
     @param [in] hInput
         This is the component to setup the tunnel with. This is the handle
         of the component whose port, specified in the nPortInput parameter
         will be used the destination for the tunnel. This is the component handle
-        returned by the call to the OMX_GetHandle function.  There is a 
+        returned by the call to the OMX_GetHandle function.  There is a
         requirement that hInput be the destination for the data when
         tunelling (i.e. nPortInut is an input port).   If 0x0, the component
         specified in hOutput will have it's port specified in nPortPOutput
@@ -1359,9 +1359,9 @@
     @return OMX_ERRORTYPE
         If the command successfully executes, the return code will be
         OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
-        When OMX_ErrorNotImplemented is returned, one or both components is 
+        When OMX_ErrorNotImplemented is returned, one or both components is
         a non-interop component and does not support tunneling.
-        
+
         On failure, the ports of both components are setup for communication
         with the application / IL Client.
     @ingroup core tun
@@ -1371,50 +1371,50 @@
     OMX_IN  OMX_U32 nPortOutput,
     OMX_IN  OMX_HANDLETYPE hInput,
     OMX_IN  OMX_U32 nPortInput);
-    
+
 /** @ingroup cp */
 OMX_API OMX_ERRORTYPE   OMX_GetContentPipe(
     OMX_OUT OMX_HANDLETYPE *hPipe,
     OMX_IN OMX_STRING szURI);
 
 /** The OMX_GetComponentsOfRole method will return the number of components that support the given
-    role and (if the compNames field is non-NULL) the names of those components. The call will fail if 
+    role and (if the compNames field is non-NULL) the names of those components. The call will fail if
     an insufficiently sized array of names is supplied. To ensure the array is sufficiently sized the
     client should:
         * first call this function with the compNames field NULL to determine the number of component names
-        * second call this function with the compNames field pointing to an array of names allocated 
+        * second call this function with the compNames field pointing to an array of names allocated
           according to the number returned by the first call.
 
     The core should return from this call within 5 msec.
-    
+
     @param [in] role
-        This is generic standard component name consisting only of component class 
+        This is generic standard component name consisting only of component class
         name and the type within that class (e.g. 'audio_decoder.aac').
     @param [inout] pNumComps
-        This is used both as input and output. 
- 
+        This is used both as input and output.
+
         If compNames is NULL, the input is ignored and the output specifies how many components support
         the given role.
-     
-        If compNames is not NULL, on input it bounds the size of the input structure and 
+
+        If compNames is not NULL, on input it bounds the size of the input structure and
         on output, it specifies the number of components string names listed within the compNames parameter.
     @param [inout] compNames
-        If NULL this field is ignored. If non-NULL this points to an array of 128-byte strings which accepts 
-        a list of the names of all physical components that implement the specified standard component name. 
+        If NULL this field is ignored. If non-NULL this points to an array of 128-byte strings which accepts
+        a list of the names of all physical components that implement the specified standard component name.
         Each name is NULL terminated. numComps indicates the number of names.
     @ingroup core
  */
-OMX_API OMX_ERRORTYPE OMX_GetComponentsOfRole ( 
-	OMX_IN      OMX_STRING role,
+OMX_API OMX_ERRORTYPE OMX_GetComponentsOfRole (
+    OMX_IN      OMX_STRING role,
     OMX_INOUT   OMX_U32 *pNumComps,
     OMX_INOUT   OMX_U8  **compNames);
 
 /** The OMX_GetRolesOfComponent method will return the number of roles supported by the given
-    component and (if the roles field is non-NULL) the names of those roles. The call will fail if 
+    component and (if the roles field is non-NULL) the names of those roles. The call will fail if
     an insufficiently sized array of names is supplied. To ensure the array is sufficiently sized the
     client should:
         * first call this function with the roles field NULL to determine the number of role names
-        * second call this function with the roles field pointing to an array of names allocated 
+        * second call this function with the roles field pointing to an array of names allocated
           according to the number returned by the first call.
 
     The core should return from this call within 5 msec.
@@ -1422,20 +1422,20 @@
     @param [in] compName
         This is the name of the component being queried about.
     @param [inout] pNumRoles
-        This is used both as input and output. 
- 
+        This is used both as input and output.
+
         If roles is NULL, the input is ignored and the output specifies how many roles the component supports.
-     
-        If compNames is not NULL, on input it bounds the size of the input structure and 
+
+        If compNames is not NULL, on input it bounds the size of the input structure and
         on output, it specifies the number of roles string names listed within the roles parameter.
     @param [out] roles
-        If NULL this field is ignored. If non-NULL this points to an array of 128-byte strings 
-        which accepts a list of the names of all standard components roles implemented on the 
+        If NULL this field is ignored. If non-NULL this points to an array of 128-byte strings
+        which accepts a list of the names of all standard components roles implemented on the
         specified component name. numComps indicates the number of names.
     @ingroup core
  */
-OMX_API OMX_ERRORTYPE OMX_GetRolesOfComponent ( 
-	OMX_IN      OMX_STRING compName, 
+OMX_API OMX_ERRORTYPE OMX_GetRolesOfComponent (
+    OMX_IN      OMX_STRING compName,
     OMX_INOUT   OMX_U32 *pNumRoles,
     OMX_OUT     OMX_U8 **roles);
 
diff --git a/include/media/openmax/OMX_IVCommon.h b/include/media/openmax/OMX_IVCommon.h
index 5f9e9b6..a5b9d18 100644
--- a/include/media/openmax/OMX_IVCommon.h
+++ b/include/media/openmax/OMX_IVCommon.h
@@ -845,7 +845,7 @@
 typedef enum OMX_METERINGTYPE {
 
     OMX_MeteringModeAverage,     /**< Center-weighted average metering. */
-    OMX_MeteringModeSpot,  	      /**< Spot (partial) metering. */
+    OMX_MeteringModeSpot,        /**< Spot (partial) metering. */
     OMX_MeteringModeMatrix,      /**< Matrix or evaluative metering. */
 
     OMX_MeteringKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
@@ -860,11 +860,11 @@
     OMX_METERINGTYPE eMetering;
     OMX_S32 xEVCompensation;      /**< Fixed point value stored as Q16 */
     OMX_U32 nApertureFNumber;     /**< e.g. nApertureFNumber = 2 implies "f/2" - Q16 format */
-    OMX_BOOL bAutoAperture;		/**< Whether aperture number is defined automatically */
+    OMX_BOOL bAutoAperture;       /**< Whether aperture number is defined automatically */
     OMX_U32 nShutterSpeedMsec;    /**< Shutterspeed in milliseconds */
-    OMX_BOOL bAutoShutterSpeed;	/**< Whether shutter speed is defined automatically */
+    OMX_BOOL bAutoShutterSpeed;   /**< Whether shutter speed is defined automatically */
     OMX_U32 nSensitivity;         /**< e.g. nSensitivity = 100 implies "ISO 100" */
-    OMX_BOOL bAutoSensitivity;	/**< Whether sensitivity is defined automatically */
+    OMX_BOOL bAutoSensitivity;    /**< Whether sensitivity is defined automatically */
 } OMX_CONFIG_EXPOSUREVALUETYPE;
 
 /**
diff --git a/include/media/openmax/OMX_Image.h b/include/media/openmax/OMX_Image.h
index 42e39ec..23a0209 100644
--- a/include/media/openmax/OMX_Image.h
+++ b/include/media/openmax/OMX_Image.h
@@ -16,30 +16,30 @@
  * -------------------------------------------------------------------
  */
 /**
- * Copyright (c) 2008 The Khronos Group Inc. 
- * 
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
  * "Software"), to deal in the Software without restriction, including
  * without limitation the rights to use, copy, modify, merge, publish,
  * distribute, sublicense, and/or sell copies of the Software, and to
  * permit persons to whom the Software is furnished to do so, subject
- * to the following conditions: 
+ * to the following conditions:
  * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software. 
- * 
+ * in all copies or substantial portions of the Software.
+ *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
-/** 
+/**
  * @file OMX_Image.h - OpenMax IL version 1.1.2
- * The structures needed by Image components to exchange parameters and 
+ * The structures needed by Image components to exchange parameters and
  * configuration data with the components.
  */
 #ifndef OMX_Image_h
@@ -51,9 +51,9 @@
 
 
 /**
- * Each OMX header must include all required header files to allow the 
- * header to compile without errors.  The includes below are required  
- * for this header file to compile successfully 
+ * Each OMX header must include all required header files to allow the
+ * header to compile without errors.  The includes below are required
+ * for this header file to compile successfully
  */
 
 #include <OMX_IVCommon.h>
@@ -64,8 +64,8 @@
  * @{
  */
 
-/** 
- * Enumeration used to define the possible image compression coding. 
+/**
+ * Enumeration used to define the possible image compression coding.
  */
 typedef enum OMX_IMAGE_CODINGTYPE {
     OMX_IMAGE_CodingUnused,      /**< Value when format is N/A */
@@ -78,59 +78,59 @@
     OMX_IMAGE_CodingPNG,         /**< PNG image format */
     OMX_IMAGE_CodingLZW,         /**< LZW image format */
     OMX_IMAGE_CodingBMP,         /**< Windows Bitmap format */
-    OMX_IMAGE_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_IMAGE_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_IMAGE_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_IMAGE_CodingMax = 0x7FFFFFFF
 } OMX_IMAGE_CODINGTYPE;
 
 
 /**
- * Data structure used to define an image path. The number of image paths 
- * for input and output will vary by type of the image component.  
- * 
+ * Data structure used to define an image path. The number of image paths
+ * for input and output will vary by type of the image component.
+ *
  *  Input (aka Source) : Zero Inputs, one Output,
  *  Splitter           : One Input, 2 or more Outputs,
  *  Processing Element : One Input, one output,
  *  Mixer              : 2 or more inputs, one output,
  *  Output (aka Sink)  : One Input, zero outputs.
- * 
- * The PortDefinition structure is used to define all of the parameters 
- * necessary for the compliant component to setup an input or an output  
- * image path.  If additional vendor specific data is required, it should  
- * be transmitted to the component using the CustomCommand function.   
- * Compliant components will prepopulate this structure with optimal  
+ *
+ * The PortDefinition structure is used to define all of the parameters
+ * necessary for the compliant component to setup an input or an output
+ * image path.  If additional vendor specific data is required, it should
+ * be transmitted to the component using the CustomCommand function.
+ * Compliant components will prepopulate this structure with optimal
  * values during the OMX_GetParameter() command.
  *
  * STRUCT MEMBERS:
  *  cMIMEType             : MIME type of data for the port
- *  pNativeRender         : Platform specific reference for a display if a 
+ *  pNativeRender         : Platform specific reference for a display if a
  *                          sync, otherwise this field is 0
- *  nFrameWidth           : Width of frame to be used on port if 
- *                          uncompressed format is used.  Use 0 for 
+ *  nFrameWidth           : Width of frame to be used on port if
+ *                          uncompressed format is used.  Use 0 for
  *                          unknown, don't care or variable
- *  nFrameHeight          : Height of frame to be used on port if 
- *                          uncompressed format is used. Use 0 for 
+ *  nFrameHeight          : Height of frame to be used on port if
+ *                          uncompressed format is used. Use 0 for
  *                          unknown, don't care or variable
- *  nStride               : Number of bytes per span of an image (i.e. 
+ *  nStride               : Number of bytes per span of an image (i.e.
  *                          indicates the number of bytes to get from
- *                          span N to span N+1, where negative stride 
+ *                          span N to span N+1, where negative stride
  *                          indicates the image is bottom up
  *  nSliceHeight          : Height used when encoding in slices
- *  bFlagErrorConcealment : Turns on error concealment if it is supported by 
+ *  bFlagErrorConcealment : Turns on error concealment if it is supported by
  *                          the OMX component
- *  eCompressionFormat    : Compression format used in this instance of  
- *                          the component. When OMX_IMAGE_CodingUnused is 
+ *  eCompressionFormat    : Compression format used in this instance of
+ *                          the component. When OMX_IMAGE_CodingUnused is
  *                          specified, eColorFormat is valid
  *  eColorFormat          : Decompressed format used by this component
- *  pNativeWindow         : Platform specific reference for a window object if a 
- *                          display sink , otherwise this field is 0x0. 
+ *  pNativeWindow         : Platform specific reference for a window object if a
+ *                          display sink , otherwise this field is 0x0.
  */
 typedef struct OMX_IMAGE_PORTDEFINITIONTYPE {
     OMX_STRING cMIMEType;
     OMX_NATIVE_DEVICETYPE pNativeRender;
-    OMX_U32 nFrameWidth; 
+    OMX_U32 nFrameWidth;
     OMX_U32 nFrameHeight;
-    OMX_S32 nStride;     
+    OMX_S32 nStride;
     OMX_U32 nSliceHeight;
     OMX_BOOL bFlagErrorConcealment;
     OMX_IMAGE_CODINGTYPE eCompressionFormat;
@@ -139,18 +139,18 @@
 } OMX_IMAGE_PORTDEFINITIONTYPE;
 
 
-/**  
- * Port format parameter.  This structure is used to enumerate the various 
+/**
+ * Port format parameter.  This structure is used to enumerate the various
  * data input/output format supported by the port.
- * 
+ *
  * STRUCT MEMBERS:
  *  nSize              : Size of the structure in bytes
  *  nVersion           : OMX specification version information
  *  nPortIndex         : Indicates which port to set
- *  nIndex             : Indicates the enumeration index for the format from 
+ *  nIndex             : Indicates the enumeration index for the format from
  *                       0x0 to N-1
- *  eCompressionFormat : Compression format used in this instance of the 
- *                       component. When OMX_IMAGE_CodingUnused is specified, 
+ *  eCompressionFormat : Compression format used in this instance of the
+ *                       component. When OMX_IMAGE_CodingUnused is specified,
  *                       eColorFormat is valid
  *  eColorFormat       : Decompressed format used by this component
  */
@@ -164,8 +164,8 @@
 } OMX_IMAGE_PARAM_PORTFORMATTYPE;
 
 
-/** 
- * Flash control type 
+/**
+ * Flash control type
  *
  * ENUMS
  *  Torch : Flash forced constantly on
@@ -177,14 +177,14 @@
     OMX_IMAGE_FlashControlRedEyeReduction,
     OMX_IMAGE_FlashControlFillin,
     OMX_IMAGE_FlashControlTorch,
-    OMX_IMAGE_FlashControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_IMAGE_FlashControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_IMAGE_FlashControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_IMAGE_FlashControlMax = 0x7FFFFFFF
 } OMX_IMAGE_FLASHCONTROLTYPE;
 
 
-/** 
- * Flash control configuration 
+/**
+ * Flash control configuration
  *
  * STRUCT MEMBERS:
  *  nSize         : Size of the structure in bytes
@@ -200,29 +200,29 @@
 } OMX_IMAGE_PARAM_FLASHCONTROLTYPE;
 
 
-/** 
- * Focus control type 
+/**
+ * Focus control type
  */
 typedef enum OMX_IMAGE_FOCUSCONTROLTYPE {
     OMX_IMAGE_FocusControlOn = 0,
     OMX_IMAGE_FocusControlOff,
     OMX_IMAGE_FocusControlAuto,
     OMX_IMAGE_FocusControlAutoLock,
-    OMX_IMAGE_FocusControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_IMAGE_FocusControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_IMAGE_FocusControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_IMAGE_FocusControlMax = 0x7FFFFFFF
 } OMX_IMAGE_FOCUSCONTROLTYPE;
 
- 
-/** 
- * Focus control configuration 
+
+/**
+ * Focus control configuration
  *
  * STRUCT MEMBERS:
  *  nSize           : Size of the structure in bytes
  *  nVersion        : OMX specification version information
  *  nPortIndex      : Port that this structure applies to
  *  eFocusControl   : Focus control
- *  nFocusSteps     : Focus can take on values from 0 mm to infinity. 
+ *  nFocusSteps     : Focus can take on values from 0 mm to infinity.
  *                    Interest is only in number of steps over this range.
  *  nFocusStepIndex : Current focus step index
  */
@@ -236,30 +236,30 @@
 } OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE;
 
 
-/** 
+/**
  * Q Factor for JPEG compression, which controls the tradeoff between image
  * quality and size.  Q Factor provides a more simple means of controlling
  * JPEG compression quality, without directly programming Quantization
- * tables for chroma and luma 
+ * tables for chroma and luma
  *
  * STRUCT MEMBERS:
- *  nSize      : Size of the structure in bytes         
- *  nVersion   : OMX specification version information 
- *  nPortIndex : Port that this structure applies to 
- *  nQFactor   : JPEG Q factor value in the range of 1-100. A factor of 1 
- *               produces the smallest, worst quality images, and a factor 
- *               of 100 produces the largest, best quality images.  A 
- *               typical default is 75 for small good quality images               
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to
+ *  nQFactor   : JPEG Q factor value in the range of 1-100. A factor of 1
+ *               produces the smallest, worst quality images, and a factor
+ *               of 100 produces the largest, best quality images.  A
+ *               typical default is 75 for small good quality images
  */
 typedef struct OMX_IMAGE_PARAM_QFACTORTYPE {
-    OMX_U32 nSize;            
-    OMX_VERSIONTYPE nVersion; 
-    OMX_U32 nPortIndex;       
-    OMX_U32 nQFactor;                                        
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nQFactor;
 } OMX_IMAGE_PARAM_QFACTORTYPE;
 
-/** 
- * Quantization table type 
+/**
+ * Quantization table type
  */
 
 typedef enum OMX_IMAGE_QUANTIZATIONTABLETYPE {
@@ -267,27 +267,27 @@
     OMX_IMAGE_QuantizationTableChroma,
     OMX_IMAGE_QuantizationTableChromaCb,
     OMX_IMAGE_QuantizationTableChromaCr,
-    OMX_IMAGE_QuantizationTableKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_IMAGE_QuantizationTableKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_IMAGE_QuantizationTableVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_IMAGE_QuantizationTableMax = 0x7FFFFFFF
 } OMX_IMAGE_QUANTIZATIONTABLETYPE;
 
-/** 
+/**
  * JPEG quantization tables are used to determine DCT compression for
- * YUV data, as an alternative to specifying Q factor, providing exact 
- * control of compression 
+ * YUV data, as an alternative to specifying Q factor, providing exact
+ * control of compression
  *
  * STRUCT MEMBERS:
  *  nSize                   : Size of the structure in bytes
- *  nVersion                : OMX specification version information 
+ *  nVersion                : OMX specification version information
  *  nPortIndex              : Port that this structure applies to
  *  eQuantizationTable      : Quantization table type
- *  nQuantizationMatrix[64] : JPEG quantization table of coefficients stored 
- *                            in increasing columns then by rows of data (i.e. 
- *                            row 1, ... row 8). Quantization values are in 
+ *  nQuantizationMatrix[64] : JPEG quantization table of coefficients stored
+ *                            in increasing columns then by rows of data (i.e.
+ *                            row 1, ... row 8). Quantization values are in
  *                            the range 0-255 and stored in linear order
- *                            (i.e. the component will zig-zag the 
- *                            quantization table data if required internally) 
+ *                            (i.e. the component will zig-zag the
+ *                            quantization table data if required internally)
  */
 typedef struct OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE {
     OMX_U32 nSize;
@@ -298,9 +298,9 @@
 } OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE;
 
 
-/** 
- * Huffman table type, the same Huffman table is applied for chroma and 
- * luma component 
+/**
+ * Huffman table type, the same Huffman table is applied for chroma and
+ * luma component
  */
 typedef enum OMX_IMAGE_HUFFMANTABLETYPE {
     OMX_IMAGE_HuffmanTableAC = 0,
@@ -309,23 +309,23 @@
     OMX_IMAGE_HuffmanTableACChroma,
     OMX_IMAGE_HuffmanTableDCLuma,
     OMX_IMAGE_HuffmanTableDCChroma,
-    OMX_IMAGE_HuffmanTableKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_IMAGE_HuffmanTableKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_IMAGE_HuffmanTableVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_IMAGE_HuffmanTableMax = 0x7FFFFFFF
 } OMX_IMAGE_HUFFMANTABLETYPE;
 
-/** 
- * JPEG Huffman table 
+/**
+ * JPEG Huffman table
  *
  * STRUCT MEMBERS:
  *  nSize                            : Size of the structure in bytes
  *  nVersion                         : OMX specification version information
  *  nPortIndex                       : Port that this structure applies to
  *  eHuffmanTable                    : Huffman table type
- *  nNumberOfHuffmanCodeOfLength[16] : 0-16, number of Huffman codes of each 
+ *  nNumberOfHuffmanCodeOfLength[16] : 0-16, number of Huffman codes of each
  *                                     possible length
- *  nHuffmanTable[256]               : 0-255, the size used for AC and DC 
- *                                     HuffmanTable are 16 and 162 
+ *  nHuffmanTable[256]               : 0-255, the size used for AC and DC
+ *                                     HuffmanTable are 16 and 162
  */
 typedef struct OMX_IMAGE_PARAM_HUFFMANTTABLETYPE {
     OMX_U32 nSize;
diff --git a/include/media/openmax/OMX_Index.h b/include/media/openmax/OMX_Index.h
index be9a1a6..1a2a548 100644
--- a/include/media/openmax/OMX_Index.h
+++ b/include/media/openmax/OMX_Index.h
@@ -16,25 +16,25 @@
  * -------------------------------------------------------------------
  */
 /*
- * Copyright (c) 2008 The Khronos Group Inc. 
- * 
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
  * "Software"), to deal in the Software without restriction, including
  * without limitation the rights to use, copy, modify, merge, publish,
  * distribute, sublicense, and/or sell copies of the Software, and to
  * permit persons to whom the Software is furnished to do so, subject
- * to the following conditions: 
+ * to the following conditions:
  * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software. 
- * 
+ * in all copies or substantial portions of the Software.
+ *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
  */
 
@@ -51,25 +51,23 @@
 extern "C" {
 #endif /* __cplusplus */
 
-
 /* Each OMX header must include all required header files to allow the
  *  header to compile without errors.  The includes below are required
- *  for this header file to compile successfully 
+ *  for this header file to compile successfully
  */
 #include <OMX_Types.h>
 
-
 /** The OMX_INDEXTYPE enumeration is used to select a structure when either
- *  getting or setting parameters and/or configuration data.  Each entry in 
- *  this enumeration maps to an OMX specified structure.  When the 
+ *  getting or setting parameters and/or configuration data.  Each entry in
+ *  this enumeration maps to an OMX specified structure.  When the
  *  OMX_GetParameter, OMX_SetParameter, OMX_GetConfig or OMX_SetConfig methods
  *  are used, the second parameter will always be an entry from this enumeration
  *  and the third entry will be the structure shown in the comments for the entry.
- *  For example, if the application is initializing a cropping function, the 
- *  OMX_SetConfig command would have OMX_IndexConfigCommonInputCrop as the second parameter 
- *  and would send a pointer to an initialized OMX_RECTTYPE structure as the 
+ *  For example, if the application is initializing a cropping function, the
+ *  OMX_SetConfig command would have OMX_IndexConfigCommonInputCrop as the second parameter
+ *  and would send a pointer to an initialized OMX_RECTTYPE structure as the
  *  third parameter.
- *  
+ *
  *  The enumeration entries named with the OMX_Config prefix are sent using
  *  the OMX_SetConfig command and the enumeration entries named with the
  *  OMX_PARAM_ prefix are sent using the OMX_SetParameter command.
@@ -86,11 +84,11 @@
     OMX_IndexParamActiveStream,             /**< reference: OMX_PARAM_U32TYPE */
     OMX_IndexParamSuspensionPolicy,         /**< reference: OMX_PARAM_SUSPENSIONPOLICYTYPE */
     OMX_IndexParamComponentSuspended,       /**< reference: OMX_PARAM_SUSPENSIONTYPE */
-    OMX_IndexConfigCapturing,               /**< reference: OMX_CONFIG_BOOLEANTYPE */ 
-    OMX_IndexConfigCaptureMode,             /**< reference: OMX_CONFIG_CAPTUREMODETYPE */ 
-    OMX_IndexAutoPauseAfterCapture,         /**< reference: OMX_CONFIG_BOOLEANTYPE */ 
+    OMX_IndexConfigCapturing,               /**< reference: OMX_CONFIG_BOOLEANTYPE */
+    OMX_IndexConfigCaptureMode,             /**< reference: OMX_CONFIG_CAPTUREMODETYPE */
+    OMX_IndexAutoPauseAfterCapture,         /**< reference: OMX_CONFIG_BOOLEANTYPE */
     OMX_IndexParamContentURI,               /**< reference: OMX_PARAM_CONTENTURITYPE */
-    OMX_IndexParamCustomContentPipe,        /**< reference: OMX_PARAM_CONTENTPIPETYPE */ 
+    OMX_IndexParamCustomContentPipe,        /**< reference: OMX_PARAM_CONTENTPIPETYPE */
     OMX_IndexParamDisableResourceConcealment, /**< reference: OMX_RESOURCECONCEALMENTTYPE */
     OMX_IndexConfigMetadataItemCount,       /**< reference: OMX_CONFIG_METADATAITEMCOUNTTYPE */
     OMX_IndexConfigContainerNodeCount,      /**< reference: OMX_CONFIG_CONTAINERNODECOUNTTYPE */
@@ -103,7 +101,7 @@
 
     OMX_IndexPortStartUnused = 0x02000000,
     OMX_IndexParamPortDefinition,           /**< reference: OMX_PARAM_PORTDEFINITIONTYPE */
-    OMX_IndexParamCompBufferSupplier,       /**< reference: OMX_PARAM_BUFFERSUPPLIERTYPE */ 
+    OMX_IndexParamCompBufferSupplier,       /**< reference: OMX_PARAM_BUFFERSUPPLIERTYPE */
     OMX_IndexReservedStartUnused = 0x03000000,
 
     /* Audio parameters and configurations */
@@ -256,10 +254,10 @@
     OMX_IndexConfigTimeSeekMode,            /**< reference: OMX_TIME_CONFIG_SEEKMODETYPE */
 
 
-    OMX_IndexKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_IndexKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     /* Vendor specific area */
     OMX_IndexVendorStartUnused = 0x7F000000,
-    /* Vendor specific structures should be in the range of 0x7F000000 
+    /* Vendor specific structures should be in the range of 0x7F000000
        to 0x7FFFFFFE.  This range is not broken out by vendor, so
        private indexes are not guaranteed unique and therefore should
        only be sent to the appropriate component. */
diff --git a/include/media/openmax/OMX_IndexExt.h b/include/media/openmax/OMX_IndexExt.h
index 6cd774b..ea3d0da 100644
--- a/include/media/openmax/OMX_IndexExt.h
+++ b/include/media/openmax/OMX_IndexExt.h
@@ -60,6 +60,7 @@
     OMX_IndexParamAudioAndroidAc3,                  /**< reference: OMX_AUDIO_PARAM_ANDROID_AC3TYPE */
     OMX_IndexParamAudioAndroidOpus,                 /**< reference: OMX_AUDIO_PARAM_ANDROID_OPUSTYPE */
     OMX_IndexParamAudioAndroidAacPresentation,      /**< reference: OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE */
+    OMX_IndexParamAudioAndroidEac3,                 /**< reference: OMX_AUDIO_PARAM_ANDROID_EAC3TYPE */
 
     /* Image parameters and configurations */
     OMX_IndexExtImageStartUnused = OMX_IndexKhronosExtensions + 0x00500000,
@@ -81,6 +82,7 @@
 
     /* Other configurations */
     OMX_IndexExtOtherStartUnused = OMX_IndexKhronosExtensions + 0x00800000,
+    OMX_IndexConfigAutoFramerateConversion,         /**< reference: OMX_CONFIG_BOOLEANTYPE */
 
     /* Time configurations */
     OMX_IndexExtTimeStartUnused = OMX_IndexKhronosExtensions + 0x00900000,
diff --git a/include/media/openmax/OMX_Other.h b/include/media/openmax/OMX_Other.h
index efbce83..6072ef6 100644
--- a/include/media/openmax/OMX_Other.h
+++ b/include/media/openmax/OMX_Other.h
@@ -16,25 +16,25 @@
  * -------------------------------------------------------------------
  */
 /*
- * Copyright (c) 2008 The Khronos Group Inc. 
- * 
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
  * "Software"), to deal in the Software without restriction, including
  * without limitation the rights to use, copy, modify, merge, publish,
  * distribute, sublicense, and/or sell copies of the Software, and to
  * permit persons to whom the Software is furnished to do so, subject
- * to the following conditions: 
+ * to the following conditions:
  * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software. 
- * 
+ * in all copies or substantial portions of the Software.
+ *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
  */
 
@@ -53,46 +53,46 @@
 
 /* Each OMX header must include all required header files to allow the
  *  header to compile without errors.  The includes below are required
- *  for this header file to compile successfully 
+ *  for this header file to compile successfully
  */
 
 #include <OMX_Core.h>
 
 
-/** 
+/**
  * Enumeration of possible data types which match to multiple domains or no
  * domain at all.  For types which are vendor specific, a value above
  * OMX_OTHER_VENDORTSTART should be used.
  */
 typedef enum OMX_OTHER_FORMATTYPE {
-    OMX_OTHER_FormatTime = 0, /**< Transmission of various timestamps, elapsed time, 
+    OMX_OTHER_FormatTime = 0, /**< Transmission of various timestamps, elapsed time,
                                    time deltas, etc */
-    OMX_OTHER_FormatPower,    /**< Perhaps used for enabling/disabling power 
+    OMX_OTHER_FormatPower,    /**< Perhaps used for enabling/disabling power
                                    management, setting clocks? */
-    OMX_OTHER_FormatStats,    /**< Could be things such as frame rate, frames 
+    OMX_OTHER_FormatStats,    /**< Could be things such as frame rate, frames
                                    dropped, etc */
     OMX_OTHER_FormatBinary,   /**< Arbitrary binary data */
-    OMX_OTHER_FormatVendorReserved = 1000, /**< Starting value for vendor specific 
+    OMX_OTHER_FormatVendorReserved = 1000, /**< Starting value for vendor specific
                                                 formats */
 
-    OMX_OTHER_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_OTHER_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_OTHER_FormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_OTHER_FormatMax = 0x7FFFFFFF
 } OMX_OTHER_FORMATTYPE;
 
-/** 
+/**
  * Enumeration of seek modes.
  */
 typedef enum OMX_TIME_SEEKMODETYPE {
     OMX_TIME_SeekModeFast = 0, /**< Prefer seeking to an approximation
-                                * of the requested seek position over   
+                                * of the requested seek position over
                                 * the actual seek position if it
                                 * results in a faster seek. */
-    OMX_TIME_SeekModeAccurate, /**< Prefer seeking to the actual seek 
+    OMX_TIME_SeekModeAccurate, /**< Prefer seeking to the actual seek
                                 * position over an approximation
                                 * of the requested seek position even
                                 * if it results in a slower seek. */
-    OMX_TIME_SeekModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_TIME_SeekModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_TIME_SeekModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_TIME_SeekModeMax = 0x7FFFFFFF
 } OMX_TIME_SEEKMODETYPE;
@@ -104,42 +104,42 @@
     OMX_TIME_SEEKMODETYPE eType;    /**< The seek mode */
 } OMX_TIME_CONFIG_SEEKMODETYPE;
 
-/** Structure representing a time stamp used with the following configs 
+/** Structure representing a time stamp used with the following configs
  * on the Clock Component (CC):
- * 
- * OMX_IndexConfigTimeCurrentWallTime: query of the CCÂ’s current wall  
+ *
+ * OMX_IndexConfigTimeCurrentWallTime: query of the CC's current wall
  *     time
- * OMX_IndexConfigTimeCurrentMediaTime: query of the CCÂ’s current media
+ * OMX_IndexConfigTimeCurrentMediaTime: query of the CC's current media
  *     time
- * OMX_IndexConfigTimeCurrentAudioReference and  
- * OMX_IndexConfigTimeCurrentVideoReference: audio/video reference 
+ * OMX_IndexConfigTimeCurrentAudioReference and
+ * OMX_IndexConfigTimeCurrentVideoReference: audio/video reference
  *     clock sending SC its reference time
- * OMX_IndexConfigTimeClientStartTime: a Clock Component client sends 
- *     this structure to the Clock Component via a SetConfig on its 
+ * OMX_IndexConfigTimeClientStartTime: a Clock Component client sends
+ *     this structure to the Clock Component via a SetConfig on its
  *     client port when it receives a buffer with
  *     OMX_BUFFERFLAG_STARTTIME set. It must use the timestamp
- *     specified by that buffer for nStartTimestamp. 
+ *     specified by that buffer for nStartTimestamp.
  *
- * ItÂ’s also used with the following config on components in general:
+ * It's also used with the following config on components in general:
  *
- * OMX_IndexConfigTimePosition: IL client querying component position 
+ * OMX_IndexConfigTimePosition: IL client querying component position
  * (GetConfig) or commanding a component to seek to the given location
  * (SetConfig)
- */	
+ */
 typedef struct OMX_TIME_CONFIG_TIMESTAMPTYPE {
     OMX_U32 nSize;               /**< size of the structure in bytes */
     OMX_VERSIONTYPE nVersion;    /**< OMX specification version
                                   *   information */
-    OMX_U32 nPortIndex;     /**< port that this structure applies to */
-    OMX_TICKS nTimestamp;  	     /**< timestamp .*/ 
-} OMX_TIME_CONFIG_TIMESTAMPTYPE;  
+    OMX_U32 nPortIndex;          /**< port that this structure applies to */
+    OMX_TICKS nTimestamp;        /**< timestamp .*/
+} OMX_TIME_CONFIG_TIMESTAMPTYPE;
 
 /** Enumeration of possible reference clocks to the media time. */
 typedef enum OMX_TIME_UPDATETYPE {
       OMX_TIME_UpdateRequestFulfillment,    /**< Update is the fulfillment of a media time request. */
-      OMX_TIME_UpdateScaleChanged,	        /**< Update was generated because the scale chagned. */
+      OMX_TIME_UpdateScaleChanged,          /**< Update was generated because the scale chagned. */
       OMX_TIME_UpdateClockStateChanged,     /**< Update was generated because the clock state changed. */
-      OMX_TIME_UpdateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+      OMX_TIME_UpdateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
       OMX_TIME_UpdateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
       OMX_TIME_UpdateMax = 0x7FFFFFFF
 } OMX_TIME_UPDATETYPE;
@@ -147,9 +147,9 @@
 /** Enumeration of possible reference clocks to the media time. */
 typedef enum OMX_TIME_REFCLOCKTYPE {
       OMX_TIME_RefClockNone,    /**< Use no references. */
-      OMX_TIME_RefClockAudio,	/**< Use references sent through OMX_IndexConfigTimeCurrentAudioReference */
+      OMX_TIME_RefClockAudio,   /**< Use references sent through OMX_IndexConfigTimeCurrentAudioReference */
       OMX_TIME_RefClockVideo,   /**< Use references sent through OMX_IndexConfigTimeCurrentVideoReference */
-      OMX_TIME_RefClockKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+      OMX_TIME_RefClockKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
       OMX_TIME_RefClockVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
       OMX_TIME_RefClockMax = 0x7FFFFFFF
 } OMX_TIME_REFCLOCKTYPE;
@@ -157,11 +157,11 @@
 /** Enumeration of clock states. */
 typedef enum OMX_TIME_CLOCKSTATE {
       OMX_TIME_ClockStateRunning,             /**< Clock running. */
-      OMX_TIME_ClockStateWaitingForStartTime, /**< Clock waiting until the 
+      OMX_TIME_ClockStateWaitingForStartTime, /**< Clock waiting until the
                                                *   prescribed clients emit their
                                                *   start time. */
       OMX_TIME_ClockStateStopped,             /**< Clock stopped. */
-      OMX_TIME_ClockStateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+      OMX_TIME_ClockStateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
       OMX_TIME_ClockStateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
       OMX_TIME_ClockStateMax = 0x7FFFFFFF
 } OMX_TIME_CLOCKSTATE;
@@ -171,18 +171,18 @@
  *  A client component sends this structure to the Clock Component via a SetConfig
  *  on its client port to specify a media timestamp the Clock Component
  *  should emit.  The Clock Component should fulfill the request by sending a
- *  OMX_TIME_MEDIATIMETYPE when its media clock matches the requested 
+ *  OMX_TIME_MEDIATIMETYPE when its media clock matches the requested
  *  timestamp.
  *
  *  The client may require a media time request be fulfilled slightly
- *  earlier than the media time specified. In this case the client specifies 
- *  an offset which is equal to the difference between wall time corresponding 
- *  to the requested media time and the wall time when it will be 
- *  fulfilled. 
+ *  earlier than the media time specified. In this case the client specifies
+ *  an offset which is equal to the difference between wall time corresponding
+ *  to the requested media time and the wall time when it will be
+ *  fulfilled.
  *
  *  A client component may uses these requests and the OMX_TIME_MEDIATIMETYPE to
  *  time events according to timestamps. If a client must perform an operation O at
- *  a time T (e.g. deliver a video frame at its corresponding timestamp), it makes a 
+ *  a time T (e.g. deliver a video frame at its corresponding timestamp), it makes a
  *  media time request at T (perhaps specifying an offset to ensure the request fulfillment
  *  is a little early). When the clock component passes the resulting OMX_TIME_MEDIATIMETYPE
  *  structure back to the client component, the client may perform operation O (perhaps having
@@ -193,52 +193,52 @@
     OMX_U32 nSize;              /**< size of the structure in bytes */
     OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
     OMX_U32 nPortIndex;         /**< port that this structure applies to */
-    OMX_PTR pClientPrivate;     /**< Client private data to disabiguate this media time 
-                                 *   from others (e.g. the number of the frame to deliver). 
-                                 *   Duplicated in the media time structure that fulfills 
-                                 *   this request. A value of zero is reserved for time scale 
+    OMX_PTR pClientPrivate;     /**< Client private data to disabiguate this media time
+                                 *   from others (e.g. the number of the frame to deliver).
+                                 *   Duplicated in the media time structure that fulfills
+                                 *   this request. A value of zero is reserved for time scale
                                  *   updates. */
-    OMX_TICKS nMediaTimestamp;  /**< Media timestamp requested.*/ 
+    OMX_TICKS nMediaTimestamp;  /**< Media timestamp requested.*/
     OMX_TICKS nOffset;          /**< Amount of wall clock time by which this
                                  *   request should be fulfilled early */
 } OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE;
 
-/**< Structure sent from the clock component client either when fulfilling 
- *   a media time request or when the time scale has changed. 
+/**< Structure sent from the clock component client either when fulfilling
+ *   a media time request or when the time scale has changed.
  *
- *   In the former case the Clock Component fills this structure and times its emission 
- *   to a client component (via the client port) according to the corresponding media 
+ *   In the former case the Clock Component fills this structure and times its emission
+ *   to a client component (via the client port) according to the corresponding media
  *   time request sent by the client. The Clock Component should time the emission to occur
- *   when the requested timestamp matches the Clock Component's media time but also the 
- *   prescribed offset early. 
+ *   when the requested timestamp matches the Clock Component's media time but also the
+ *   prescribed offset early.
  *
  *   Upon scale changes the clock component clears the nClientPrivate data, sends the current
- *   media time and sets the nScale to the new scale via the client port. It emits a 
- *   OMX_TIME_MEDIATIMETYPE to all clients independent of any requests. This allows clients to 
- *   alter processing to accomodate scaling. For instance a video component might skip inter-frames 
- *   in the case of extreme fastforward. Likewise an audio component might add or remove samples 
- *   from an audio frame to scale audio data. 
+ *   media time and sets the nScale to the new scale via the client port. It emits a
+ *   OMX_TIME_MEDIATIMETYPE to all clients independent of any requests. This allows clients to
+ *   alter processing to accomodate scaling. For instance a video component might skip inter-frames
+ *   in the case of extreme fastforward. Likewise an audio component might add or remove samples
+ *   from an audio frame to scale audio data.
  *
  *   It is expected that some clock components may not be able to fulfill requests
- *   at exactly the prescribed time. This is acceptable so long as the request is 
- *   fulfilled at least as early as described and not later. This structure provides 
+ *   at exactly the prescribed time. This is acceptable so long as the request is
+ *   fulfilled at least as early as described and not later. This structure provides
  *   fields the client may use to wait for the remaining time.
  *
- *   The client may use either the nOffset or nWallTimeAtMedia fields to determine the 
+ *   The client may use either the nOffset or nWallTimeAtMedia fields to determine the
  *   wall time until the nMediaTimestamp actually occurs. In the latter case the
  *   client can get a more accurate value for offset by getting the current wall
- *   from the cloc component and subtracting it from nWallTimeAtMedia. 
+ *   from the cloc component and subtracting it from nWallTimeAtMedia.
  */
 
 typedef struct OMX_TIME_MEDIATIMETYPE {
     OMX_U32 nSize;                  /**< size of the structure in bytes */
     OMX_VERSIONTYPE nVersion;       /**< OMX specification version information */
-    OMX_U32 nClientPrivate;         /**< Client private data to disabiguate this media time 
-                                     *   from others. Copied from the media time request. 
+    OMX_U32 nClientPrivate;         /**< Client private data to disabiguate this media time
+                                     *   from others. Copied from the media time request.
                                      *   A value of zero is reserved for time scale updates. */
     OMX_TIME_UPDATETYPE eUpdateType; /**< Reason for the update */
-    OMX_TICKS nMediaTimestamp;      /**< Media time requested. If no media time was 
-                                     *   requested then this is the current media time. */ 
+    OMX_TICKS nMediaTimestamp;      /**< Media time requested. If no media time was
+                                     *   requested then this is the current media time. */
     OMX_TICKS nOffset;              /**< Amount of wall clock time by which this
                                      *   request was actually fulfilled early */
 
@@ -250,21 +250,21 @@
     OMX_S32 xScale;                 /**< Current media time scale in Q16 format. */
     OMX_TIME_CLOCKSTATE eState;     /* Seeking Change. Added 7/12.*/
                                     /**< State of the media time. */
-} OMX_TIME_MEDIATIMETYPE;  
+} OMX_TIME_MEDIATIMETYPE;
 
-/** Structure representing the current media time scale factor. Applicable only to clock 
+/** Structure representing the current media time scale factor. Applicable only to clock
  *  component, other components see scale changes via OMX_TIME_MEDIATIMETYPE buffers sent via
- *  the clock component client ports. Upon recieving this config the clock component changes 
- *  the rate by which the media time increases or decreases effectively implementing trick modes. 
- */ 
+ *  the clock component client ports. Upon recieving this config the clock component changes
+ *  the rate by which the media time increases or decreases effectively implementing trick modes.
+ */
 typedef struct OMX_TIME_CONFIG_SCALETYPE {
     OMX_U32 nSize;                  /**< size of the structure in bytes */
     OMX_VERSIONTYPE nVersion;       /**< OMX specification version information */
     OMX_S32 xScale;                 /**< This is a value in Q16 format which is used for
                                      * scaling the media time */
 } OMX_TIME_CONFIG_SCALETYPE;
- 
-/** Bits used to identify a clock port. Used in OMX_TIME_CONFIG_CLOCKSTATETYPEÂ’s nWaitMask field */
+
+/** Bits used to identify a clock port. Used in OMX_TIME_CONFIG_CLOCKSTATETYPE's nWaitMask field */
 #define OMX_CLOCKPORT0 0x00000001
 #define OMX_CLOCKPORT1 0x00000002
 #define OMX_CLOCKPORT2 0x00000004
@@ -274,38 +274,38 @@
 #define OMX_CLOCKPORT6 0x00000040
 #define OMX_CLOCKPORT7 0x00000080
 
-/** Structure representing the current mode of the media clock. 
- *  IL Client uses this config to change or query the mode of the 
+/** Structure representing the current mode of the media clock.
+ *  IL Client uses this config to change or query the mode of the
  *  media clock of the clock component. Applicable only to clock
- *  component. 
- *  
+ *  component.
+ *
  *  On a SetConfig if eState is OMX_TIME_ClockStateRunning media time
  *  starts immediately at the prescribed start time. If
  *  OMX_TIME_ClockStateWaitingForStartTime the Clock Component ignores
- *  the given nStartTime and waits for all clients specified in the 
- *  nWaitMask to send starttimes (via 
- *  OMX_IndexConfigTimeClientStartTime). The Clock Component then starts 
- *  the media clock using the earliest start time supplied. */    
+ *  the given nStartTime and waits for all clients specified in the
+ *  nWaitMask to send starttimes (via
+ *  OMX_IndexConfigTimeClientStartTime). The Clock Component then starts
+ *  the media clock using the earliest start time supplied. */
 typedef struct OMX_TIME_CONFIG_CLOCKSTATETYPE {
     OMX_U32 nSize;              /**< size of the structure in bytes */
-    OMX_VERSIONTYPE nVersion;   /**< OMX specification version 
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version
                                  *   information */
     OMX_TIME_CLOCKSTATE eState; /**< State of the media time. */
     OMX_TICKS nStartTime;       /**< Start time of the media time. */
-    OMX_TICKS nOffset;          /**< Time to offset the media time by 
+    OMX_TICKS nOffset;          /**< Time to offset the media time by
                                  * (e.g. preroll). Media time will be
-                                 * reported to be nOffset ticks earlier.     
+                                 * reported to be nOffset ticks earlier.
                                  */
     OMX_U32 nWaitMask;          /**< Mask of OMX_CLOCKPORT values. */
 } OMX_TIME_CONFIG_CLOCKSTATETYPE;
 
 /** Structure representing the reference clock currently being used to
- *  compute media time. IL client uses this config to change or query the 
+ *  compute media time. IL client uses this config to change or query the
  *  clock component's active reference clock */
 typedef struct OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE {
     OMX_U32 nSize;                  /**< size of the structure in bytes */
     OMX_VERSIONTYPE nVersion;       /**< OMX specification version information */
-    OMX_TIME_REFCLOCKTYPE eClock;   /**< Reference clock used to compute media time */                        
+    OMX_TIME_REFCLOCKTYPE eClock;   /**< Reference clock used to compute media time */
 } OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE;
 
 /** Descriptor for setting specifics of power type.
@@ -327,8 +327,8 @@
 
 
 /**
- * The PortDefinition structure is used to define all of the parameters 
- * necessary for the compliant component to setup an input or an output other 
+ * The PortDefinition structure is used to define all of the parameters
+ * necessary for the compliant component to setup an input or an output other
  * path.
  */
 typedef struct OMX_OTHER_PORTDEFINITIONTYPE {
@@ -344,7 +344,7 @@
     OMX_U32 nPortIndex; /**< Indicates which port to set */
     OMX_U32 nIndex; /**< Indicates the enumeration index for the format from 0x0 to N-1 */
     OMX_OTHER_FORMATTYPE eFormat; /**< Type of data expected for this channel */
-} OMX_OTHER_PARAM_PORTFORMATTYPE; 
+} OMX_OTHER_PARAM_PORTFORMATTYPE;
 
 #ifdef __cplusplus
 }
diff --git a/include/media/openmax/OMX_Types.h b/include/media/openmax/OMX_Types.h
index 71e346a..5afaba0 100644
--- a/include/media/openmax/OMX_Types.h
+++ b/include/media/openmax/OMX_Types.h
@@ -16,32 +16,32 @@
  * -------------------------------------------------------------------
  */
 /*
- * Copyright (c) 2008 The Khronos Group Inc. 
- * 
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
  * "Software"), to deal in the Software without restriction, including
  * without limitation the rights to use, copy, modify, merge, publish,
  * distribute, sublicense, and/or sell copies of the Software, and to
  * permit persons to whom the Software is furnished to do so, subject
- * to the following conditions: 
+ * to the following conditions:
  * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software. 
- * 
+ * in all copies or substantial portions of the Software.
+ *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
  */
 
 /** OMX_Types.h - OpenMax IL version 1.1.2
- *  The OMX_Types header file contains the primitive type definitions used by 
+ *  The OMX_Types header file contains the primitive type definitions used by
  *  the core, the application and the component.  This file may need to be
- *  modified to be used on systems that do not have "char" set to 8 bits, 
+ *  modified to be used on systems that do not have "char" set to 8 bits,
  *  "short" set to 16 bits and "long" set to 32 bits.
  */
 
@@ -57,12 +57,12 @@
 /** The OMX_API and OMX_APIENTRY are platform specific definitions used
  *  to declare OMX function prototypes.  They are modified to meet the
  *  requirements for a particular platform */
-#ifdef __SYMBIAN32__   
+#ifdef __SYMBIAN32__
 #   ifdef __OMX_EXPORTS
 #       define OMX_API __declspec(dllexport)
 #   else
 #       ifdef _WIN32
-#           define OMX_API __declspec(dllexport) 
+#           define OMX_API __declspec(dllexport)
 #       else
 #           define OMX_API __declspec(dllimport)
 #       endif
@@ -85,18 +85,18 @@
 #endif
 
 #ifndef OMX_APIENTRY
-#define OMX_APIENTRY 
-#endif 
+#define OMX_APIENTRY
+#endif
 
-/** OMX_IN is used to identify inputs to an OMX function.  This designation 
-    will also be used in the case of a pointer that points to a parameter 
+/** OMX_IN is used to identify inputs to an OMX function.  This designation
+    will also be used in the case of a pointer that points to a parameter
     that is used as an output. */
 #ifndef OMX_IN
 #define OMX_IN
 #endif
 
-/** OMX_OUT is used to identify outputs from an OMX function.  This 
-    designation will also be used in the case of a pointer that points 
+/** OMX_OUT is used to identify outputs from an OMX function.  This
+    designation will also be used in the case of a pointer that points
     to a parameter that is used as an input. */
 #ifndef OMX_OUT
 #define OMX_OUT
@@ -104,8 +104,8 @@
 
 
 /** OMX_INOUT is used to identify parameters that may be either inputs or
-    outputs from an OMX function at the same time.  This designation will 
-    also be used in the case of a pointer that  points to a parameter that 
+    outputs from an OMX function at the same time.  This designation will
+    also be used in the case of a pointer that  points to a parameter that
     is used both as an input and an output. */
 #ifndef OMX_INOUT
 #define OMX_INOUT
@@ -123,31 +123,31 @@
 /** @defgroup core OpenMAX IL core
  * Functions and structure related to the OMX IL core
  */
- 
+
  /** @defgroup comp OpenMAX IL component
  * Functions and structure related to the OMX IL component
  */
- 
-/** @defgroup rpm Resource and Policy Management 
+
+/** @defgroup rpm Resource and Policy Management
  * Structures for resource and policy management of components
  */
 
 /** @defgroup buf Buffer Management
  * Buffer handling functions and structures
  */
-  
+
 /** @defgroup tun Tunneling
  * @ingroup core comp
  * Structures and functions to manage tunnels among component ports
  */
- 
+
 /** @defgroup cp Content Pipes
  *  @ingroup core
  */
- 
+
  /** @defgroup metadata Metadata handling
-  * 
-  */ 
+  *
+  */
 
 /** OMX_U8 is an 8 bit unsigned quantity that is byte aligned */
 typedef unsigned char OMX_U8;
@@ -169,7 +169,7 @@
 
 
 /* Users with compilers that cannot accept the "long long" designation should
-   define the OMX_SKIP64BIT macro.  It should be noted that this may cause 
+   define the OMX_SKIP64BIT macro.  It should be noted that this may cause
    some components to fail to compile if the component was written to require
    64 bit integral types.  However, these components would NOT compile anyway
    since the compiler does not support the way the component was written.
@@ -184,7 +184,7 @@
 
 #elif defined(WIN32)
 
-/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */   
+/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */
 typedef unsigned __int64  OMX_U64;
 
 /** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */
@@ -202,7 +202,7 @@
 #endif
 
 
-/** The OMX_BOOL type is intended to be used to represent a true or a false 
+/** The OMX_BOOL type is intended to be used to represent a true or a false
     value when passing parameters to and from the OMX core and components.  The
     OMX_BOOL is a 32 bit quantity and is aligned on a 32 bit word boundary.
  */
@@ -210,7 +210,7 @@
     OMX_FALSE = 0,
     OMX_TRUE = !OMX_FALSE,
     OMX_BOOL_MAX = 0x7FFFFFFF
-} OMX_BOOL; 
+} OMX_BOOL;
 
 /*
  * Temporary Android 64 bit modification
@@ -237,14 +237,14 @@
 typedef void* OMX_PTR;
 
 /** The OMX_STRING type is intended to be used to pass "C" type strings between
-    the application and the core and component.  The OMX_STRING type is a 32 
-    bit pointer to a zero terminated string.  The  pointer is word aligned and 
-    the string is byte aligned.  
+    the application and the core and component.  The OMX_STRING type is a 32
+    bit pointer to a zero terminated string.  The  pointer is word aligned and
+    the string is byte aligned.
  */
 typedef char* OMX_STRING;
 
 /** The OMX_BYTE type is intended to be used to pass arrays of bytes such as
-    buffers between the application and the component and core.  The OMX_BYTE 
+    buffers between the application and the component and core.  The OMX_BYTE
     type is a 32 bit pointer to a zero terminated string.  The  pointer is word
     aligned and the string is byte aligned.
  */
@@ -259,7 +259,7 @@
 typedef unsigned char OMX_UUIDTYPE[128];
 
 /** The OMX_DIRTYPE enumeration is used to indicate if a port is an input or
-    an output port.  This enumeration is common across all component types.    
+    an output port.  This enumeration is common across all component types.
  */
 typedef enum OMX_DIRTYPE
 {
@@ -268,8 +268,8 @@
     OMX_DirMax = 0x7FFFFFFF
 } OMX_DIRTYPE;
 
-/** The OMX_ENDIANTYPE enumeration is used to indicate the bit ordering 
-    for numerical data (i.e. big endian, or little endian).    
+/** The OMX_ENDIANTYPE enumeration is used to indicate the bit ordering
+    for numerical data (i.e. big endian, or little endian).
  */
 typedef enum OMX_ENDIANTYPE
 {
@@ -279,7 +279,7 @@
 } OMX_ENDIANTYPE;
 
 
-/** The OMX_NUMERICALDATATYPE enumeration is used to indicate if data 
+/** The OMX_NUMERICALDATATYPE enumeration is used to indicate if data
     is signed or unsigned
  */
 typedef enum OMX_NUMERICALDATATYPE
@@ -307,16 +307,16 @@
 
 
 /** Structure representing some time or duration in microseconds. This structure
-  *  must be interpreted as a signed 64 bit value. The quantity is signed to accommodate 
-  *  negative deltas and preroll scenarios. The quantity is represented in microseconds 
+  *  must be interpreted as a signed 64 bit value. The quantity is signed to accommodate
+  *  negative deltas and preroll scenarios. The quantity is represented in microseconds
   *  to accomodate high resolution timestamps (e.g. DVD presentation timestamps based
-  *  on a 90kHz clock) and to allow more accurate and synchronized delivery (e.g. 
-  *  individual audio samples delivered at 192 kHz). The quantity is 64 bit to 
+  *  on a 90kHz clock) and to allow more accurate and synchronized delivery (e.g.
+  *  individual audio samples delivered at 192 kHz). The quantity is 64 bit to
   *  accommodate a large dynamic range (signed 32 bit values would allow only for plus
   *  or minus 35 minutes).
   *
-  *  Implementations with limited precision may convert the signed 64 bit value to 
-  *  a signed 32 bit value internally but risk loss of precision.  
+  *  Implementations with limited precision may convert the signed 64 bit value to
+  *  a signed 32 bit value internally but risk loss of precision.
   */
 #ifndef OMX_SKIP64BIT
 typedef OMX_S64 OMX_TICKS;
@@ -336,17 +336,17 @@
 
 typedef struct OMX_MARKTYPE
 {
-    OMX_HANDLETYPE hMarkTargetComponent;   /**< The component that will 
-                                                generate a mark event upon 
+    OMX_HANDLETYPE hMarkTargetComponent;   /**< The component that will
+                                                generate a mark event upon
                                                 processing the mark. */
-    OMX_PTR pMarkData;   /**< Application specific data associated with 
-                              the mark sent on a mark event to disambiguate 
+    OMX_PTR pMarkData;   /**< Application specific data associated with
+                              the mark sent on a mark event to disambiguate
                               this mark from others. */
 } OMX_MARKTYPE;
 
 
 /** OMX_NATIVE_DEVICETYPE is used to map a OMX video port to the
- *  platform & operating specific object used to reference the display 
+ *  platform & operating specific object used to reference the display
  *  or can be used by a audio port for native audio rendering */
 typedef OMX_PTR OMX_NATIVE_DEVICETYPE;
 
@@ -357,7 +357,7 @@
 /** The OMX_VERSIONTYPE union is used to specify the version for
     a structure or component.  For a component, the version is entirely
     specified by the component vendor.  Components doing the same function
-    from different vendors may or may not have the same version.  For 
+    from different vendors may or may not have the same version.  For
     structures, the version shall be set by the entity that allocates the
     structure.  For structures specified in the OMX 1.1 specification, the
     value of the version shall be set to 1.1.0.0 in all cases.  Access to the
diff --git a/include/media/openmax/OMX_Video.h b/include/media/openmax/OMX_Video.h
index 89425e0..decc410 100644
--- a/include/media/openmax/OMX_Video.h
+++ b/include/media/openmax/OMX_Video.h
@@ -16,31 +16,31 @@
  * -------------------------------------------------------------------
  */
 /**
- * Copyright (c) 2008 The Khronos Group Inc. 
- * 
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
  * "Software"), to deal in the Software without restriction, including
  * without limitation the rights to use, copy, modify, merge, publish,
  * distribute, sublicense, and/or sell copies of the Software, and to
  * permit persons to whom the Software is furnished to do so, subject
- * to the following conditions: 
+ * to the following conditions:
  * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software. 
- * 
+ * in all copies or substantial portions of the Software.
+ *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
  */
 
-/** 
+/**
  *  @file OMX_Video.h - OpenMax IL version 1.1.2
- *  The structures is needed by Video components to exchange parameters 
+ *  The structures is needed by Video components to exchange parameters
  *  and configuration data with OMX components.
  */
 #ifndef OMX_Video_h
@@ -60,19 +60,19 @@
 /**
  * Each OMX header must include all required header files to allow the
  * header to compile without errors.  The includes below are required
- * for this header file to compile successfully 
+ * for this header file to compile successfully
  */
 
 #include <OMX_IVCommon.h>
 
 
 /**
- * Enumeration used to define the possible video compression codings.  
- * NOTE:  This essentially refers to file extensions. If the coding is 
- *        being used to specify the ENCODE type, then additional work 
- *        must be done to configure the exact flavor of the compression 
- *        to be used.  For decode cases where the user application can 
- *        not differentiate between MPEG-4 and H.264 bit streams, it is 
+ * Enumeration used to define the possible video compression codings.
+ * NOTE:  This essentially refers to file extensions. If the coding is
+ *        being used to specify the ENCODE type, then additional work
+ *        must be done to configure the exact flavor of the compression
+ *        to be used.  For decode cases where the user application can
+ *        not differentiate between MPEG-4 and H.264 bit streams, it is
  *        up to the codec to handle this.
  */
 typedef enum OMX_VIDEO_CODINGTYPE {
@@ -88,58 +88,58 @@
     OMX_VIDEO_CodingVP8,        /**< Google VP8, formerly known as On2 VP8 */
     OMX_VIDEO_CodingVP9,        /**< Google VP9 */
     OMX_VIDEO_CodingHEVC,       /**< ITU H.265/HEVC */
-    OMX_VIDEO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_VIDEO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_VIDEO_CodingMax = 0x7FFFFFFF
 } OMX_VIDEO_CODINGTYPE;
 
 
 /**
- * Data structure used to define a video path.  The number of Video paths for 
- * input and output will vary by type of the Video component.  
- * 
+ * Data structure used to define a video path.  The number of Video paths for
+ * input and output will vary by type of the Video component.
+ *
  *    Input (aka Source) : zero Inputs, one Output,
  *    Splitter           : one Input, 2 or more Outputs,
  *    Processing Element : one Input, one output,
  *    Mixer              : 2 or more inputs, one output,
  *    Output (aka Sink)  : one Input, zero outputs.
- * 
- * The PortDefinition structure is used to define all of the parameters 
- * necessary for the compliant component to setup an input or an output video 
- * path.  If additional vendor specific data is required, it should be 
- * transmitted to the component using the CustomCommand function.  Compliant 
- * components will prepopulate this structure with optimal values during the 
+ *
+ * The PortDefinition structure is used to define all of the parameters
+ * necessary for the compliant component to setup an input or an output video
+ * path.  If additional vendor specific data is required, it should be
+ * transmitted to the component using the CustomCommand function.  Compliant
+ * components will prepopulate this structure with optimal values during the
  * GetDefaultInitParams command.
  *
  * STRUCT MEMBERS:
  *  cMIMEType             : MIME type of data for the port
- *  pNativeRender         : Platform specific reference for a display if a 
+ *  pNativeRender         : Platform specific reference for a display if a
  *                          sync, otherwise this field is 0
- *  nFrameWidth           : Width of frame to be used on channel if 
+ *  nFrameWidth           : Width of frame to be used on channel if
  *                          uncompressed format is used.  Use 0 for unknown,
  *                          don't care or variable
- *  nFrameHeight          : Height of frame to be used on channel if 
+ *  nFrameHeight          : Height of frame to be used on channel if
  *                          uncompressed format is used. Use 0 for unknown,
  *                          don't care or variable
- *  nStride               : Number of bytes per span of an image 
+ *  nStride               : Number of bytes per span of an image
  *                          (i.e. indicates the number of bytes to get
  *                          from span N to span N+1, where negative stride
  *                          indicates the image is bottom up
  *  nSliceHeight          : Height used when encoding in slices
- *  nBitrate              : Bit rate of frame to be used on channel if 
- *                          compressed format is used. Use 0 for unknown, 
+ *  nBitrate              : Bit rate of frame to be used on channel if
+ *                          compressed format is used. Use 0 for unknown,
  *                          don't care or variable
- *  xFramerate            : Frame rate to be used on channel if uncompressed 
- *                          format is used. Use 0 for unknown, don't care or 
+ *  xFramerate            : Frame rate to be used on channel if uncompressed
+ *                          format is used. Use 0 for unknown, don't care or
  *                          variable.  Units are Q16 frames per second.
- *  bFlagErrorConcealment : Turns on error concealment if it is supported by 
+ *  bFlagErrorConcealment : Turns on error concealment if it is supported by
  *                          the OMX component
- *  eCompressionFormat    : Compression format used in this instance of the 
- *                          component. When OMX_VIDEO_CodingUnused is 
+ *  eCompressionFormat    : Compression format used in this instance of the
+ *                          component. When OMX_VIDEO_CodingUnused is
  *                          specified, eColorFormat is used
  *  eColorFormat : Decompressed format used by this component
- *  pNativeWindow : Platform specific reference for a window object if a 
- *                          display sink , otherwise this field is 0x0. 
+ *  pNativeWindow : Platform specific reference for a window object if a
+ *                          display sink , otherwise this field is 0x0.
  */
 typedef struct OMX_VIDEO_PORTDEFINITIONTYPE {
     OMX_STRING cMIMEType;
@@ -156,19 +156,19 @@
     OMX_NATIVE_WINDOWTYPE pNativeWindow;
 } OMX_VIDEO_PORTDEFINITIONTYPE;
 
-/**  
- * Port format parameter.  This structure is used to enumerate the various 
+/**
+ * Port format parameter.  This structure is used to enumerate the various
  * data input/output format supported by the port.
- * 
+ *
  * STRUCT MEMBERS:
  *  nSize              : Size of the structure in bytes
  *  nVersion           : OMX specification version information
  *  nPortIndex         : Indicates which port to set
- *  nIndex             : Indicates the enumeration index for the format from 
+ *  nIndex             : Indicates the enumeration index for the format from
  *                       0x0 to N-1
- *  eCompressionFormat : Compression format used in this instance of the 
- *                       component. When OMX_VIDEO_CodingUnused is specified, 
- *                       eColorFormat is used 
+ *  eCompressionFormat : Compression format used in this instance of the
+ *                       component. When OMX_VIDEO_CodingUnused is specified,
+ *                       eColorFormat is used
  *  eColorFormat       : Decompressed format used by this component
  *  xFrameRate         : Indicates the video frame rate in Q16 format
  */
@@ -177,14 +177,14 @@
     OMX_VERSIONTYPE nVersion;
     OMX_U32 nPortIndex;
     OMX_U32 nIndex;
-    OMX_VIDEO_CODINGTYPE eCompressionFormat; 
+    OMX_VIDEO_CODINGTYPE eCompressionFormat;
     OMX_COLOR_FORMATTYPE eColorFormat;
     OMX_U32 xFramerate;
 } OMX_VIDEO_PARAM_PORTFORMATTYPE;
 
 
 /**
- * This is a structure for configuring video compression quantization 
+ * This is a structure for configuring video compression quantization
  * parameter values.  Codecs may support different QP values for different
  * frame types.
  *
@@ -194,10 +194,10 @@
  *  nPortIndex : Port that this structure applies to
  *  nQpI       : QP value to use for index frames
  *  nQpP       : QP value to use for P frames
- *  nQpB       : QP values to use for bidirectional frames 
+ *  nQpB       : QP values to use for bidirectional frames
  */
 typedef struct OMX_VIDEO_PARAM_QUANTIZATIONTYPE {
-    OMX_U32 nSize;            
+    OMX_U32 nSize;
     OMX_VERSIONTYPE nVersion;
     OMX_U32 nPortIndex;
     OMX_U32 nQpI;
@@ -206,32 +206,32 @@
 } OMX_VIDEO_PARAM_QUANTIZATIONTYPE;
 
 
-/** 
- * Structure for configuration of video fast update parameters. 
- *  
+/**
+ * Structure for configuration of video fast update parameters.
+ *
  * STRUCT MEMBERS:
  *  nSize      : Size of the structure in bytes
- *  nVersion   : OMX specification version info 
+ *  nVersion   : OMX specification version info
  *  nPortIndex : Port that this structure applies to
  *  bEnableVFU : Enable/Disable video fast update
  *  nFirstGOB  : Specifies the number of the first macroblock row
  *  nFirstMB   : specifies the first MB relative to the specified first GOB
- *  nNumMBs    : Specifies the number of MBs to be refreshed from nFirstGOB 
+ *  nNumMBs    : Specifies the number of MBs to be refreshed from nFirstGOB
  *               and nFirstMB
  */
 typedef struct OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE {
-    OMX_U32 nSize;            
-    OMX_VERSIONTYPE nVersion; 
-    OMX_U32 nPortIndex;       
-    OMX_BOOL bEnableVFU;      
-    OMX_U32 nFirstGOB;                            
-    OMX_U32 nFirstMB;                            
-    OMX_U32 nNumMBs;                                  
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_BOOL bEnableVFU;
+    OMX_U32 nFirstGOB;
+    OMX_U32 nFirstMB;
+    OMX_U32 nNumMBs;
 } OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE;
 
 
-/** 
- * Enumeration of possible bitrate control types 
+/**
+ * Enumeration of possible bitrate control types
  */
 typedef enum OMX_VIDEO_CONTROLRATETYPE {
     OMX_Video_ControlRateDisable,
@@ -239,14 +239,14 @@
     OMX_Video_ControlRateConstant,
     OMX_Video_ControlRateVariableSkipFrames,
     OMX_Video_ControlRateConstantSkipFrames,
-    OMX_Video_ControlRateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_Video_ControlRateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_Video_ControlRateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_Video_ControlRateMax = 0x7FFFFFFF
 } OMX_VIDEO_CONTROLRATETYPE;
 
 
-/** 
- * Structure for configuring bitrate mode of a codec. 
+/**
+ * Structure for configuring bitrate mode of a codec.
  *
  * STRUCT MEMBERS:
  *  nSize          : Size of the struct in bytes
@@ -256,23 +256,23 @@
  *  nTargetBitrate : Target bitrate to encode with
  */
 typedef struct OMX_VIDEO_PARAM_BITRATETYPE {
-    OMX_U32 nSize;                          
-    OMX_VERSIONTYPE nVersion;               
-    OMX_U32 nPortIndex;                     
-    OMX_VIDEO_CONTROLRATETYPE eControlRate; 
-    OMX_U32 nTargetBitrate;                 
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_VIDEO_CONTROLRATETYPE eControlRate;
+    OMX_U32 nTargetBitrate;
 } OMX_VIDEO_PARAM_BITRATETYPE;
 
 
-/** 
- * Enumeration of possible motion vector (MV) types 
+/**
+ * Enumeration of possible motion vector (MV) types
  */
 typedef enum OMX_VIDEO_MOTIONVECTORTYPE {
     OMX_Video_MotionVectorPixel,
     OMX_Video_MotionVectorHalfPel,
     OMX_Video_MotionVectorQuarterPel,
     OMX_Video_MotionVectorEighthPel,
-    OMX_Video_MotionVectorKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_Video_MotionVectorKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_Video_MotionVectorVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_Video_MotionVectorMax = 0x7FFFFFFF
 } OMX_VIDEO_MOTIONVECTORTYPE;
@@ -281,7 +281,7 @@
 /**
  * Structure for configuring the number of motion vectors used as well
  * as their accuracy.
- * 
+ *
  * STRUCT MEMBERS:
  *  nSize            : Size of the struct in bytes
  *  nVersion         : OMX spec version info
@@ -304,32 +304,32 @@
 } OMX_VIDEO_PARAM_MOTIONVECTORTYPE;
 
 
-/** 
- * Enumeration of possible methods to use for Intra Refresh 
+/**
+ * Enumeration of possible methods to use for Intra Refresh
  */
 typedef enum OMX_VIDEO_INTRAREFRESHTYPE {
     OMX_VIDEO_IntraRefreshCyclic,
     OMX_VIDEO_IntraRefreshAdaptive,
     OMX_VIDEO_IntraRefreshBoth,
-    OMX_VIDEO_IntraRefreshKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_IntraRefreshKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_VIDEO_IntraRefreshVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_VIDEO_IntraRefreshMax = 0x7FFFFFFF
 } OMX_VIDEO_INTRAREFRESHTYPE;
 
 
 /**
- * Structure for configuring intra refresh mode 
- * 
+ * Structure for configuring intra refresh mode
+ *
  * STRUCT MEMBERS:
  *  nSize        : Size of the structure in bytes
  *  nVersion     : OMX specification version information
  *  nPortIndex   : Port that this structure applies to
  *  eRefreshMode : Cyclic, Adaptive, or Both
- *  nAirMBs      : Number of intra macroblocks to refresh in a frame when 
+ *  nAirMBs      : Number of intra macroblocks to refresh in a frame when
  *                 AIR is enabled
- *  nAirRef      : Number of times a motion marked macroblock has to be  
+ *  nAirRef      : Number of times a motion marked macroblock has to be
  *                 intra coded
- *  nCirMBs      : Number of consecutive macroblocks to be coded as "intra"  
+ *  nCirMBs      : Number of consecutive macroblocks to be coded as "intra"
  *                 when CIR is enabled
  */
 typedef struct OMX_VIDEO_PARAM_INTRAREFRESHTYPE {
@@ -344,19 +344,19 @@
 
 
 /**
- * Structure for enabling various error correction methods for video 
+ * Structure for enabling various error correction methods for video
  * compression.
  *
  * STRUCT MEMBERS:
  *  nSize                   : Size of the structure in bytes
- *  nVersion                : OMX specification version information 
- *  nPortIndex              : Port that this structure applies to 
+ *  nVersion                : OMX specification version information
+ *  nPortIndex              : Port that this structure applies to
  *  bEnableHEC              : Enable/disable header extension codes (HEC)
  *  bEnableResync           : Enable/disable resynchronization markers
- *  nResynchMarkerSpacing   : Resynch markers interval (in bits) to be 
- *                            applied in the stream 
- *  bEnableDataPartitioning : Enable/disable data partitioning 
- *  bEnableRVLC             : Enable/disable reversible variable length 
+ *  nResynchMarkerSpacing   : Resynch markers interval (in bits) to be
+ *                            applied in the stream
+ *  bEnableDataPartitioning : Enable/disable data partitioning
+ *  bEnableRVLC             : Enable/disable reversible variable length
  *                            coding
  */
 typedef struct OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE {
@@ -371,12 +371,12 @@
 } OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE;
 
 
-/** 
- * Configuration of variable block-size motion compensation (VBSMC) 
- * 
+/**
+ * Configuration of variable block-size motion compensation (VBSMC)
+ *
  * STRUCT MEMBERS:
  *  nSize      : Size of the structure in bytes
- *  nVersion   : OMX specification version information 
+ *  nVersion   : OMX specification version information
  *  nPortIndex : Port that this structure applies to
  *  b16x16     : Enable inter block search 16x16
  *  b16x8      : Enable inter block search 16x8
@@ -387,11 +387,11 @@
  *  b4x4       : Enable inter block search 4x4
  */
 typedef struct OMX_VIDEO_PARAM_VBSMCTYPE {
-    OMX_U32 nSize; 
-    OMX_VERSIONTYPE nVersion; 
-    OMX_U32 nPortIndex;       
-    OMX_BOOL b16x16; 
-    OMX_BOOL b16x8; 
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_BOOL b16x16;
+    OMX_BOOL b16x8;
     OMX_BOOL b8x16;
     OMX_BOOL b8x8;
     OMX_BOOL b8x4;
@@ -400,67 +400,67 @@
 } OMX_VIDEO_PARAM_VBSMCTYPE;
 
 
-/** 
- * H.263 profile types, each profile indicates support for various 
+/**
+ * H.263 profile types, each profile indicates support for various
  * performance bounds and different annexes.
  *
  * ENUMS:
- *  Baseline           : Baseline Profile: H.263 (V1), no optional modes                                                    
- *  H320 Coding        : H.320 Coding Efficiency Backward Compatibility 
+ *  Baseline           : Baseline Profile: H.263 (V1), no optional modes
+ *  H320 Coding        : H.320 Coding Efficiency Backward Compatibility
  *                       Profile: H.263+ (V2), includes annexes I, J, L.4
  *                       and T
- *  BackwardCompatible : Backward Compatibility Profile: H.263 (V1), 
- *                       includes annex F                                    
- *  ISWV2              : Interactive Streaming Wireless Profile: H.263+ 
- *                       (V2), includes annexes I, J, K and T                 
- *  ISWV3              : Interactive Streaming Wireless Profile: H.263++  
- *                       (V3), includes profile 3 and annexes V and W.6.3.8   
- *  HighCompression    : Conversational High Compression Profile: H.263++  
- *                       (V3), includes profiles 1 & 2 and annexes D and U   
- *  Internet           : Conversational Internet Profile: H.263++ (V3),  
- *                       includes profile 5 and annex K                       
- *  Interlace          : Conversational Interlace Profile: H.263++ (V3),  
- *                       includes profile 5 and annex W.6.3.11               
- *  HighLatency        : High Latency Profile: H.263++ (V3), includes  
- *                       profile 6 and annexes O.1 and P.5                       
+ *  BackwardCompatible : Backward Compatibility Profile: H.263 (V1),
+ *                       includes annex F
+ *  ISWV2              : Interactive Streaming Wireless Profile: H.263+
+ *                       (V2), includes annexes I, J, K and T
+ *  ISWV3              : Interactive Streaming Wireless Profile: H.263++
+ *                       (V3), includes profile 3 and annexes V and W.6.3.8
+ *  HighCompression    : Conversational High Compression Profile: H.263++
+ *                       (V3), includes profiles 1 & 2 and annexes D and U
+ *  Internet           : Conversational Internet Profile: H.263++ (V3),
+ *                       includes profile 5 and annex K
+ *  Interlace          : Conversational Interlace Profile: H.263++ (V3),
+ *                       includes profile 5 and annex W.6.3.11
+ *  HighLatency        : High Latency Profile: H.263++ (V3), includes
+ *                       profile 6 and annexes O.1 and P.5
  */
 typedef enum OMX_VIDEO_H263PROFILETYPE {
-    OMX_VIDEO_H263ProfileBaseline            = 0x01,        
-    OMX_VIDEO_H263ProfileH320Coding          = 0x02,          
-    OMX_VIDEO_H263ProfileBackwardCompatible  = 0x04,  
-    OMX_VIDEO_H263ProfileISWV2               = 0x08,               
-    OMX_VIDEO_H263ProfileISWV3               = 0x10,               
-    OMX_VIDEO_H263ProfileHighCompression     = 0x20,     
-    OMX_VIDEO_H263ProfileInternet            = 0x40,            
-    OMX_VIDEO_H263ProfileInterlace           = 0x80,           
-    OMX_VIDEO_H263ProfileHighLatency         = 0x100,         
-    OMX_VIDEO_H263ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_H263ProfileBaseline            = 0x01,
+    OMX_VIDEO_H263ProfileH320Coding          = 0x02,
+    OMX_VIDEO_H263ProfileBackwardCompatible  = 0x04,
+    OMX_VIDEO_H263ProfileISWV2               = 0x08,
+    OMX_VIDEO_H263ProfileISWV3               = 0x10,
+    OMX_VIDEO_H263ProfileHighCompression     = 0x20,
+    OMX_VIDEO_H263ProfileInternet            = 0x40,
+    OMX_VIDEO_H263ProfileInterlace           = 0x80,
+    OMX_VIDEO_H263ProfileHighLatency         = 0x100,
+    OMX_VIDEO_H263ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_VIDEO_H263ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
-    OMX_VIDEO_H263ProfileMax                 = 0x7FFFFFFF  
+    OMX_VIDEO_H263ProfileMax                 = 0x7FFFFFFF
 } OMX_VIDEO_H263PROFILETYPE;
 
 
-/** 
- * H.263 level types, each level indicates support for various frame sizes, 
+/**
+ * H.263 level types, each level indicates support for various frame sizes,
  * bit rates, decoder frame rates.
  */
 typedef enum OMX_VIDEO_H263LEVELTYPE {
-    OMX_VIDEO_H263Level10  = 0x01,  
-    OMX_VIDEO_H263Level20  = 0x02,      
-    OMX_VIDEO_H263Level30  = 0x04,      
-    OMX_VIDEO_H263Level40  = 0x08,      
-    OMX_VIDEO_H263Level45  = 0x10,      
-    OMX_VIDEO_H263Level50  = 0x20,      
-    OMX_VIDEO_H263Level60  = 0x40,      
-    OMX_VIDEO_H263Level70  = 0x80, 
-    OMX_VIDEO_H263LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_H263Level10  = 0x01,
+    OMX_VIDEO_H263Level20  = 0x02,
+    OMX_VIDEO_H263Level30  = 0x04,
+    OMX_VIDEO_H263Level40  = 0x08,
+    OMX_VIDEO_H263Level45  = 0x10,
+    OMX_VIDEO_H263Level50  = 0x20,
+    OMX_VIDEO_H263Level60  = 0x40,
+    OMX_VIDEO_H263Level70  = 0x80,
+    OMX_VIDEO_H263LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_VIDEO_H263LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
-    OMX_VIDEO_H263LevelMax = 0x7FFFFFFF  
+    OMX_VIDEO_H263LevelMax = 0x7FFFFFFF
 } OMX_VIDEO_H263LEVELTYPE;
 
 
-/** 
- * Specifies the picture type. These values should be OR'd to signal all 
+/**
+ * Specifies the picture type. These values should be OR'd to signal all
  * pictures types which are allowed.
  *
  * ENUMS:
@@ -478,36 +478,36 @@
     OMX_VIDEO_PictureTypeEI  = 0x11,
     OMX_VIDEO_PictureTypeEP  = 0x12,
     OMX_VIDEO_PictureTypeS   = 0x14,
-    OMX_VIDEO_PictureTypeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_PictureTypeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_VIDEO_PictureTypeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_VIDEO_PictureTypeMax = 0x7FFFFFFF
 } OMX_VIDEO_PICTURETYPE;
 
 
-/** 
- * H.263 Params 
+/**
+ * H.263 Params
  *
  * STRUCT MEMBERS:
  *  nSize                    : Size of the structure in bytes
- *  nVersion                 : OMX specification version information 
+ *  nVersion                 : OMX specification version information
  *  nPortIndex               : Port that this structure applies to
  *  nPFrames                 : Number of P frames between each I frame
  *  nBFrames                 : Number of B frames between each I frame
  *  eProfile                 : H.263 profile(s) to use
  *  eLevel                   : H.263 level(s) to use
- *  bPLUSPTYPEAllowed        : Indicating that it is allowed to use PLUSPTYPE 
- *                             (specified in the 1998 version of H.263) to 
- *                             indicate custom picture sizes or clock 
- *                             frequencies 
- *  nAllowedPictureTypes     : Specifies the picture types allowed in the 
+ *  bPLUSPTYPEAllowed        : Indicating that it is allowed to use PLUSPTYPE
+ *                             (specified in the 1998 version of H.263) to
+ *                             indicate custom picture sizes or clock
+ *                             frequencies
+ *  nAllowedPictureTypes     : Specifies the picture types allowed in the
  *                             bitstream
- *  bForceRoundingTypeToZero : value of the RTYPE bit (bit 6 of MPPTYPE) is 
- *                             not constrained. It is recommended to change 
- *                             the value of the RTYPE bit for each reference 
+ *  bForceRoundingTypeToZero : value of the RTYPE bit (bit 6 of MPPTYPE) is
+ *                             not constrained. It is recommended to change
+ *                             the value of the RTYPE bit for each reference
  *                             picture in error-free communication
- *  nPictureHeaderRepetition : Specifies the frequency of picture header 
+ *  nPictureHeaderRepetition : Specifies the frequency of picture header
  *                             repetition
- *  nGOBHeaderInterval       : Specifies the interval of non-empty GOB  
+ *  nGOBHeaderInterval       : Specifies the interval of non-empty GOB
  *                             headers in units of GOBs
  */
 typedef struct OMX_VIDEO_PARAM_H263TYPE {
@@ -517,7 +517,7 @@
     OMX_U32 nPFrames;
     OMX_U32 nBFrames;
     OMX_VIDEO_H263PROFILETYPE eProfile;
-	OMX_VIDEO_H263LEVELTYPE eLevel;
+    OMX_VIDEO_H263LEVELTYPE eLevel;
     OMX_BOOL bPLUSPTYPEAllowed;
     OMX_U32 nAllowedPictureTypes;
     OMX_BOOL bForceRoundingTypeToZero;
@@ -526,8 +526,8 @@
 } OMX_VIDEO_PARAM_H263TYPE;
 
 
-/** 
- * MPEG-2 profile types, each profile indicates support for various 
+/**
+ * MPEG-2 profile types, each profile indicates support for various
  * performance bounds and different annexes.
  */
 typedef enum OMX_VIDEO_MPEG2PROFILETYPE {
@@ -537,29 +537,29 @@
     OMX_VIDEO_MPEG2ProfileSNR,         /**< SNR Profile */
     OMX_VIDEO_MPEG2ProfileSpatial,     /**< Spatial Profile */
     OMX_VIDEO_MPEG2ProfileHigh,        /**< High Profile */
-    OMX_VIDEO_MPEG2ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_MPEG2ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_VIDEO_MPEG2ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
-    OMX_VIDEO_MPEG2ProfileMax = 0x7FFFFFFF  
+    OMX_VIDEO_MPEG2ProfileMax = 0x7FFFFFFF
 } OMX_VIDEO_MPEG2PROFILETYPE;
 
 
-/** 
- * MPEG-2 level types, each level indicates support for various frame 
- * sizes, bit rates, decoder frame rates.  No need 
+/**
+ * MPEG-2 level types, each level indicates support for various frame
+ * sizes, bit rates, decoder frame rates.  No need
  */
 typedef enum OMX_VIDEO_MPEG2LEVELTYPE {
-    OMX_VIDEO_MPEG2LevelLL = 0,  /**< Low Level */ 
-    OMX_VIDEO_MPEG2LevelML,      /**< Main Level */ 
-    OMX_VIDEO_MPEG2LevelH14,     /**< High 1440 */ 
-    OMX_VIDEO_MPEG2LevelHL,      /**< High Level */   
-    OMX_VIDEO_MPEG2LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_MPEG2LevelLL = 0,  /**< Low Level */
+    OMX_VIDEO_MPEG2LevelML,      /**< Main Level */
+    OMX_VIDEO_MPEG2LevelH14,     /**< High 1440 */
+    OMX_VIDEO_MPEG2LevelHL,      /**< High Level */
+    OMX_VIDEO_MPEG2LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_VIDEO_MPEG2LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
-    OMX_VIDEO_MPEG2LevelMax = 0x7FFFFFFF  
+    OMX_VIDEO_MPEG2LevelMax = 0x7FFFFFFF
 } OMX_VIDEO_MPEG2LEVELTYPE;
 
 
-/** 
- * MPEG-2 params 
+/**
+ * MPEG-2 params
  *
  * STRUCT MEMBERS:
  *  nSize      : Size of the structure in bytes
@@ -571,20 +571,20 @@
  *  eLevel     : MPEG-2 levels(s) to use
  */
 typedef struct OMX_VIDEO_PARAM_MPEG2TYPE {
-    OMX_U32 nSize;           
+    OMX_U32 nSize;
     OMX_VERSIONTYPE nVersion;
-    OMX_U32 nPortIndex;      
-    OMX_U32 nPFrames;        
-    OMX_U32 nBFrames;        
+    OMX_U32 nPortIndex;
+    OMX_U32 nPFrames;
+    OMX_U32 nBFrames;
     OMX_VIDEO_MPEG2PROFILETYPE eProfile;
-	OMX_VIDEO_MPEG2LEVELTYPE eLevel;   
+    OMX_VIDEO_MPEG2LEVELTYPE eLevel;
 } OMX_VIDEO_PARAM_MPEG2TYPE;
 
 
-/** 
- * MPEG-4 profile types, each profile indicates support for various 
+/**
+ * MPEG-4 profile types, each profile indicates support for various
  * performance bounds and different annexes.
- * 
+ *
  * ENUMS:
  *  - Simple Profile, Levels 1-3
  *  - Simple Scalable Profile, Levels 1-2
@@ -603,48 +603,48 @@
  *  - Advanced Scalable Texture, Levels 2-3
  */
 typedef enum OMX_VIDEO_MPEG4PROFILETYPE {
-    OMX_VIDEO_MPEG4ProfileSimple           = 0x01,        
-    OMX_VIDEO_MPEG4ProfileSimpleScalable   = 0x02,    
-    OMX_VIDEO_MPEG4ProfileCore             = 0x04,              
-    OMX_VIDEO_MPEG4ProfileMain             = 0x08,             
-    OMX_VIDEO_MPEG4ProfileNbit             = 0x10,              
-    OMX_VIDEO_MPEG4ProfileScalableTexture  = 0x20,   
-    OMX_VIDEO_MPEG4ProfileSimpleFace       = 0x40,        
-    OMX_VIDEO_MPEG4ProfileSimpleFBA        = 0x80,         
-    OMX_VIDEO_MPEG4ProfileBasicAnimated    = 0x100,     
-    OMX_VIDEO_MPEG4ProfileHybrid           = 0x200,            
-    OMX_VIDEO_MPEG4ProfileAdvancedRealTime = 0x400,  
-    OMX_VIDEO_MPEG4ProfileCoreScalable     = 0x800,      
-    OMX_VIDEO_MPEG4ProfileAdvancedCoding   = 0x1000,    
-    OMX_VIDEO_MPEG4ProfileAdvancedCore     = 0x2000,      
+    OMX_VIDEO_MPEG4ProfileSimple           = 0x01,
+    OMX_VIDEO_MPEG4ProfileSimpleScalable   = 0x02,
+    OMX_VIDEO_MPEG4ProfileCore             = 0x04,
+    OMX_VIDEO_MPEG4ProfileMain             = 0x08,
+    OMX_VIDEO_MPEG4ProfileNbit             = 0x10,
+    OMX_VIDEO_MPEG4ProfileScalableTexture  = 0x20,
+    OMX_VIDEO_MPEG4ProfileSimpleFace       = 0x40,
+    OMX_VIDEO_MPEG4ProfileSimpleFBA        = 0x80,
+    OMX_VIDEO_MPEG4ProfileBasicAnimated    = 0x100,
+    OMX_VIDEO_MPEG4ProfileHybrid           = 0x200,
+    OMX_VIDEO_MPEG4ProfileAdvancedRealTime = 0x400,
+    OMX_VIDEO_MPEG4ProfileCoreScalable     = 0x800,
+    OMX_VIDEO_MPEG4ProfileAdvancedCoding   = 0x1000,
+    OMX_VIDEO_MPEG4ProfileAdvancedCore     = 0x2000,
     OMX_VIDEO_MPEG4ProfileAdvancedScalable = 0x4000,
     OMX_VIDEO_MPEG4ProfileAdvancedSimple   = 0x8000,
-    OMX_VIDEO_MPEG4ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_MPEG4ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_VIDEO_MPEG4ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
-    OMX_VIDEO_MPEG4ProfileMax              = 0x7FFFFFFF  
+    OMX_VIDEO_MPEG4ProfileMax              = 0x7FFFFFFF
 } OMX_VIDEO_MPEG4PROFILETYPE;
 
 
-/** 
- * MPEG-4 level types, each level indicates support for various frame 
- * sizes, bit rates, decoder frame rates.  No need 
+/**
+ * MPEG-4 level types, each level indicates support for various frame
+ * sizes, bit rates, decoder frame rates.  No need
  */
 typedef enum OMX_VIDEO_MPEG4LEVELTYPE {
-    OMX_VIDEO_MPEG4Level0  = 0x01,   /**< Level 0 */   
-    OMX_VIDEO_MPEG4Level0b = 0x02,   /**< Level 0b */   
-    OMX_VIDEO_MPEG4Level1  = 0x04,   /**< Level 1 */ 
-    OMX_VIDEO_MPEG4Level2  = 0x08,   /**< Level 2 */ 
-    OMX_VIDEO_MPEG4Level3  = 0x10,   /**< Level 3 */ 
-    OMX_VIDEO_MPEG4Level4  = 0x20,   /**< Level 4 */  
-    OMX_VIDEO_MPEG4Level4a = 0x40,   /**< Level 4a */  
-    OMX_VIDEO_MPEG4Level5  = 0x80,   /**< Level 5 */  
-    OMX_VIDEO_MPEG4LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_MPEG4Level0  = 0x01,   /**< Level 0 */
+    OMX_VIDEO_MPEG4Level0b = 0x02,   /**< Level 0b */
+    OMX_VIDEO_MPEG4Level1  = 0x04,   /**< Level 1 */
+    OMX_VIDEO_MPEG4Level2  = 0x08,   /**< Level 2 */
+    OMX_VIDEO_MPEG4Level3  = 0x10,   /**< Level 3 */
+    OMX_VIDEO_MPEG4Level4  = 0x20,   /**< Level 4 */
+    OMX_VIDEO_MPEG4Level4a = 0x40,   /**< Level 4a */
+    OMX_VIDEO_MPEG4Level5  = 0x80,   /**< Level 5 */
+    OMX_VIDEO_MPEG4LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_VIDEO_MPEG4LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
-    OMX_VIDEO_MPEG4LevelMax = 0x7FFFFFFF  
+    OMX_VIDEO_MPEG4LevelMax = 0x7FFFFFFF
 } OMX_VIDEO_MPEG4LEVELTYPE;
 
 
-/** 
+/**
  * MPEG-4 configuration.  This structure handles configuration options
  * which are specific to MPEG4 algorithms
  *
@@ -652,24 +652,24 @@
  *  nSize                : Size of the structure in bytes
  *  nVersion             : OMX specification version information
  *  nPortIndex           : Port that this structure applies to
- *  nSliceHeaderSpacing  : Number of macroblocks between slice header (H263+ 
+ *  nSliceHeaderSpacing  : Number of macroblocks between slice header (H263+
  *                         Annex K). Put zero if not used
  *  bSVH                 : Enable Short Video Header mode
  *  bGov                 : Flag to enable GOV
- *  nPFrames             : Number of P frames between each I frame (also called 
+ *  nPFrames             : Number of P frames between each I frame (also called
  *                         GOV period)
  *  nBFrames             : Number of B frames between each I frame
  *  nIDCVLCThreshold     : Value of intra DC VLC threshold
  *  bACPred              : Flag to use ac prediction
  *  nMaxPacketSize       : Maximum size of packet in bytes.
- *  nTimeIncRes          : Used to pass VOP time increment resolution for MPEG4. 
+ *  nTimeIncRes          : Used to pass VOP time increment resolution for MPEG4.
  *                         Interpreted as described in MPEG4 standard.
  *  eProfile             : MPEG-4 profile(s) to use.
  *  eLevel               : MPEG-4 level(s) to use.
  *  nAllowedPictureTypes : Specifies the picture types allowed in the bitstream
  *  nHeaderExtension     : Specifies the number of consecutive video packet
  *                         headers within a VOP
- *  bReversibleVLC       : Specifies whether reversible variable length coding 
+ *  bReversibleVLC       : Specifies whether reversible variable length coding
  *                         is in use
  */
 typedef struct OMX_VIDEO_PARAM_MPEG4TYPE {
@@ -693,22 +693,22 @@
 } OMX_VIDEO_PARAM_MPEG4TYPE;
 
 
-/** 
- * WMV Versions 
+/**
+ * WMV Versions
  */
 typedef enum OMX_VIDEO_WMVFORMATTYPE {
     OMX_VIDEO_WMVFormatUnused = 0x01,   /**< Format unused or unknown */
     OMX_VIDEO_WMVFormat7      = 0x02,   /**< Windows Media Video format 7 */
     OMX_VIDEO_WMVFormat8      = 0x04,   /**< Windows Media Video format 8 */
     OMX_VIDEO_WMVFormat9      = 0x08,   /**< Windows Media Video format 9 */
-    OMX_VIDEO_WMFFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_WMFFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_VIDEO_WMFFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_VIDEO_WMVFormatMax    = 0x7FFFFFFF
 } OMX_VIDEO_WMVFORMATTYPE;
 
 
-/** 
- * WMV Params 
+/**
+ * WMV Params
  *
  * STRUCT MEMBERS:
  *  nSize      : Size of the structure in bytes
@@ -717,33 +717,33 @@
  *  eFormat    : Version of WMV stream / data
  */
 typedef struct OMX_VIDEO_PARAM_WMVTYPE {
-    OMX_U32 nSize; 
+    OMX_U32 nSize;
     OMX_VERSIONTYPE nVersion;
     OMX_U32 nPortIndex;
     OMX_VIDEO_WMVFORMATTYPE eFormat;
 } OMX_VIDEO_PARAM_WMVTYPE;
 
 
-/** 
- * Real Video Version 
+/**
+ * Real Video Version
  */
 typedef enum OMX_VIDEO_RVFORMATTYPE {
     OMX_VIDEO_RVFormatUnused = 0, /**< Format unused or unknown */
     OMX_VIDEO_RVFormat8,          /**< Real Video format 8 */
     OMX_VIDEO_RVFormat9,          /**< Real Video format 9 */
     OMX_VIDEO_RVFormatG2,         /**< Real Video Format G2 */
-    OMX_VIDEO_RVFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_RVFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_VIDEO_RVFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_VIDEO_RVFormatMax = 0x7FFFFFFF
 } OMX_VIDEO_RVFORMATTYPE;
 
 
-/** 
- * Real Video Params 
+/**
+ * Real Video Params
  *
  * STUCT MEMBERS:
  *  nSize              : Size of the structure in bytes
- *  nVersion           : OMX specification version information 
+ *  nVersion           : OMX specification version information
  *  nPortIndex         : Port that this structure applies to
  *  eFormat            : Version of RV stream / data
  *  nBitsPerPixel      : Bits per pixel coded in the frame
@@ -755,11 +755,11 @@
  *  nMaxEncodeFrameSize: Max encoded frame size
  *  bEnablePostFilter  : Turn on/off post filter
  *  bEnableTemporalInterpolation : Turn on/off temporal interpolation
- *  bEnableLatencyMode : When enabled, the decoder does not display a decoded 
- *                       frame until it has detected that no enhancement layer 
- *  					 frames or dependent B frames will be coming. This 
- *  					 detection usually occurs when a subsequent non-B 
- *  					 frame is encountered 
+ *  bEnableLatencyMode : When enabled, the decoder does not display a decoded
+ *                       frame until it has detected that no enhancement layer
+ *                       frames or dependent B frames will be coming. This
+ *                       detection usually occurs when a subsequent non-B
+ *                       frame is encountered
  */
 typedef struct OMX_VIDEO_PARAM_RVTYPE {
     OMX_U32 nSize;
@@ -779,8 +779,8 @@
 } OMX_VIDEO_PARAM_RVTYPE;
 
 
-/** 
- * AVC profile types, each profile indicates support for various 
+/**
+ * AVC profile types, each profile indicates support for various
  * performance bounds and different annexes.
  */
 typedef enum OMX_VIDEO_AVCPROFILETYPE {
@@ -791,15 +791,15 @@
     OMX_VIDEO_AVCProfileHigh10   = 0x10,   /**< High 10 profile */
     OMX_VIDEO_AVCProfileHigh422  = 0x20,   /**< High 4:2:2 profile */
     OMX_VIDEO_AVCProfileHigh444  = 0x40,   /**< High 4:4:4 profile */
-    OMX_VIDEO_AVCProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_AVCProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_VIDEO_AVCProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
-    OMX_VIDEO_AVCProfileMax      = 0x7FFFFFFF  
+    OMX_VIDEO_AVCProfileMax      = 0x7FFFFFFF
 } OMX_VIDEO_AVCPROFILETYPE;
 
 
-/** 
- * AVC level types, each level indicates support for various frame sizes, 
- * bit rates, decoder frame rates.  No need 
+/**
+ * AVC level types, each level indicates support for various frame sizes,
+ * bit rates, decoder frame rates.  No need
  */
 typedef enum OMX_VIDEO_AVCLEVELTYPE {
     OMX_VIDEO_AVCLevel1   = 0x01,     /**< Level 1 */
@@ -819,14 +819,14 @@
     OMX_VIDEO_AVCLevel5   = 0x4000,   /**< Level 5 */
     OMX_VIDEO_AVCLevel51  = 0x8000,   /**< Level 5.1 */
     OMX_VIDEO_AVCLevel52  = 0x10000,  /**< Level 5.2 */
-    OMX_VIDEO_AVCLevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_AVCLevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_VIDEO_AVCLevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
-    OMX_VIDEO_AVCLevelMax = 0x7FFFFFFF  
+    OMX_VIDEO_AVCLevelMax = 0x7FFFFFFF
 } OMX_VIDEO_AVCLEVELTYPE;
 
 
-/** 
- * AVC loop filter modes 
+/**
+ * AVC loop filter modes
  *
  * OMX_VIDEO_AVCLoopFilterEnable               : Enable
  * OMX_VIDEO_AVCLoopFilterDisable              : Disable
@@ -836,20 +836,20 @@
     OMX_VIDEO_AVCLoopFilterEnable = 0,
     OMX_VIDEO_AVCLoopFilterDisable,
     OMX_VIDEO_AVCLoopFilterDisableSliceBoundary,
-    OMX_VIDEO_AVCLoopFilterKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_AVCLoopFilterKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_VIDEO_AVCLoopFilterVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_VIDEO_AVCLoopFilterMax = 0x7FFFFFFF
 } OMX_VIDEO_AVCLOOPFILTERTYPE;
 
 
-/** 
- * AVC params 
+/**
+ * AVC params
  *
  * STRUCT MEMBERS:
  *  nSize                     : Size of the structure in bytes
  *  nVersion                  : OMX specification version information
  *  nPortIndex                : Port that this structure applies to
- *  nSliceHeaderSpacing       : Number of macroblocks between slice header, put  
+ *  nSliceHeaderSpacing       : Number of macroblocks between slice header, put
  *                              zero if not used
  *  nPFrames                  : Number of P frames between each I frame
  *  nBFrames                  : Number of B frames between each I frame
@@ -862,85 +862,85 @@
  *  nRefIdxForward            : Pic param set ref frame index (index into ref
  *                              frame buffer of forward frames list), B frame
  *                              support
- *  bEnableUEP                : Enable/disable unequal error protection. This 
+ *  bEnableUEP                : Enable/disable unequal error protection. This
  *                              is only valid of data partitioning is enabled.
  *  bEnableFMO                : Enable/disable flexible macroblock ordering
  *  bEnableASO                : Enable/disable arbitrary slice ordering
  *  bEnableRS                 : Enable/disable sending of redundant slices
  *  eProfile                  : AVC profile(s) to use
  *  eLevel                    : AVC level(s) to use
- *  nAllowedPictureTypes      : Specifies the picture types allowed in the 
+ *  nAllowedPictureTypes      : Specifies the picture types allowed in the
  *                              bitstream
- *  bFrameMBsOnly             : specifies that every coded picture of the 
- *                              coded video sequence is a coded frame 
+ *  bFrameMBsOnly             : specifies that every coded picture of the
+ *                              coded video sequence is a coded frame
  *                              containing only frame macroblocks
- *  bMBAFF                    : Enable/disable switching between frame and 
+ *  bMBAFF                    : Enable/disable switching between frame and
  *                              field macroblocks within a picture
- *  bEntropyCodingCABAC       : Entropy decoding method to be applied for the 
- *                              syntax elements for which two descriptors appear 
+ *  bEntropyCodingCABAC       : Entropy decoding method to be applied for the
+ *                              syntax elements for which two descriptors appear
  *                              in the syntax tables
- *  bWeightedPPrediction      : Enable/disable weighted prediction shall not 
+ *  bWeightedPPrediction      : Enable/disable weighted prediction shall not
  *                              be applied to P and SP slices
- *  nWeightedBipredicitonMode : Default weighted prediction is applied to B 
- *                              slices 
+ *  nWeightedBipredicitonMode : Default weighted prediction is applied to B
+ *                              slices
  *  bconstIpred               : Enable/disable intra prediction
- *  bDirect8x8Inference       : Specifies the method used in the derivation 
- *                              process for luma motion vectors for B_Skip, 
- *                              B_Direct_16x16 and B_Direct_8x8 as specified 
- *                              in subclause 8.4.1.2 of the AVC spec 
+ *  bDirect8x8Inference       : Specifies the method used in the derivation
+ *                              process for luma motion vectors for B_Skip,
+ *                              B_Direct_16x16 and B_Direct_8x8 as specified
+ *                              in subclause 8.4.1.2 of the AVC spec
  *  bDirectSpatialTemporal    : Flag indicating spatial or temporal direct
- *                              mode used in B slice coding (related to 
- *                              bDirect8x8Inference) . Spatial direct mode is 
+ *                              mode used in B slice coding (related to
+ *                              bDirect8x8Inference) . Spatial direct mode is
  *                              more common and should be the default.
  *  nCabacInitIdx             : Index used to init CABAC contexts
  *  eLoopFilterMode           : Enable/disable loop filter
  */
 typedef struct OMX_VIDEO_PARAM_AVCTYPE {
-    OMX_U32 nSize;                 
-    OMX_VERSIONTYPE nVersion;      
-    OMX_U32 nPortIndex;            
-    OMX_U32 nSliceHeaderSpacing;  
-    OMX_U32 nPFrames;     
-    OMX_U32 nBFrames;     
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nSliceHeaderSpacing;
+    OMX_U32 nPFrames;
+    OMX_U32 nBFrames;
     OMX_BOOL bUseHadamard;
-    OMX_U32 nRefFrames;  
-	OMX_U32 nRefIdx10ActiveMinus1;
-	OMX_U32 nRefIdx11ActiveMinus1;
-    OMX_BOOL bEnableUEP;  
-    OMX_BOOL bEnableFMO;  
-    OMX_BOOL bEnableASO;  
-    OMX_BOOL bEnableRS;   
+    OMX_U32 nRefFrames;
+    OMX_U32 nRefIdx10ActiveMinus1;
+    OMX_U32 nRefIdx11ActiveMinus1;
+    OMX_BOOL bEnableUEP;
+    OMX_BOOL bEnableFMO;
+    OMX_BOOL bEnableASO;
+    OMX_BOOL bEnableRS;
     OMX_VIDEO_AVCPROFILETYPE eProfile;
-	OMX_VIDEO_AVCLEVELTYPE eLevel; 
-    OMX_U32 nAllowedPictureTypes;  
-	OMX_BOOL bFrameMBsOnly;        									
-    OMX_BOOL bMBAFF;               
-    OMX_BOOL bEntropyCodingCABAC;  
-    OMX_BOOL bWeightedPPrediction; 
-    OMX_U32 nWeightedBipredicitonMode; 
+    OMX_VIDEO_AVCLEVELTYPE eLevel;
+    OMX_U32 nAllowedPictureTypes;
+    OMX_BOOL bFrameMBsOnly;
+    OMX_BOOL bMBAFF;
+    OMX_BOOL bEntropyCodingCABAC;
+    OMX_BOOL bWeightedPPrediction;
+    OMX_U32 nWeightedBipredicitonMode;
     OMX_BOOL bconstIpred ;
-    OMX_BOOL bDirect8x8Inference;  
-	OMX_BOOL bDirectSpatialTemporal;
-	OMX_U32 nCabacInitIdc;
-	OMX_VIDEO_AVCLOOPFILTERTYPE eLoopFilterMode;
+    OMX_BOOL bDirect8x8Inference;
+    OMX_BOOL bDirectSpatialTemporal;
+    OMX_U32 nCabacInitIdc;
+    OMX_VIDEO_AVCLOOPFILTERTYPE eLoopFilterMode;
 } OMX_VIDEO_PARAM_AVCTYPE;
 
 typedef struct OMX_VIDEO_PARAM_PROFILELEVELTYPE {
-   OMX_U32 nSize;                 
-   OMX_VERSIONTYPE nVersion;      
-   OMX_U32 nPortIndex;            
-   OMX_U32 eProfile;      /**< type is OMX_VIDEO_AVCPROFILETYPE, OMX_VIDEO_H263PROFILETYPE, 
+   OMX_U32 nSize;
+   OMX_VERSIONTYPE nVersion;
+   OMX_U32 nPortIndex;
+   OMX_U32 eProfile;      /**< type is OMX_VIDEO_AVCPROFILETYPE, OMX_VIDEO_H263PROFILETYPE,
                                  or OMX_VIDEO_MPEG4PROFILETYPE depending on context */
-   OMX_U32 eLevel;        /**< type is OMX_VIDEO_AVCLEVELTYPE, OMX_VIDEO_H263LEVELTYPE, 
+   OMX_U32 eLevel;        /**< type is OMX_VIDEO_AVCLEVELTYPE, OMX_VIDEO_H263LEVELTYPE,
                                  or OMX_VIDEO_MPEG4PROFILETYPE depending on context */
    OMX_U32 nProfileIndex; /**< Used to query for individual profile support information,
-                               This parameter is valid only for 
+                               This parameter is valid only for
                                OMX_IndexParamVideoProfileLevelQuerySupported index,
                                For all other indices this parameter is to be ignored. */
 } OMX_VIDEO_PARAM_PROFILELEVELTYPE;
 
-/** 
- * Structure for dynamically configuring bitrate mode of a codec. 
+/**
+ * Structure for dynamically configuring bitrate mode of a codec.
  *
  * STRUCT MEMBERS:
  *  nSize          : Size of the struct in bytes
@@ -949,18 +949,18 @@
  *  nEncodeBitrate : Target average bitrate to be generated in bps
  */
 typedef struct OMX_VIDEO_CONFIG_BITRATETYPE {
-    OMX_U32 nSize;                          
-    OMX_VERSIONTYPE nVersion;               
-    OMX_U32 nPortIndex;                     
-    OMX_U32 nEncodeBitrate;                 
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nEncodeBitrate;
 } OMX_VIDEO_CONFIG_BITRATETYPE;
 
-/** 
+/**
  * Defines Encoder Frame Rate setting
  *
  * STRUCT MEMBERS:
  *  nSize            : Size of the structure in bytes
- *  nVersion         : OMX specification version information 
+ *  nVersion         : OMX specification version information
  *  nPortIndex       : Port that this structure applies to
  *  xEncodeFramerate : Encoding framerate represented in Q16 format
  */
@@ -1000,8 +1000,8 @@
     OMX_U32 nMacroblocks;
 } OMX_PARAM_MACROBLOCKSTYPE;
 
-/** 
- * AVC Slice Mode modes 
+/**
+ * AVC Slice Mode modes
  *
  * OMX_VIDEO_SLICEMODE_AVCDefault   : Normal frame encoding, one slice per frame
  * OMX_VIDEO_SLICEMODE_AVCMBSlice   : NAL mode, number of MBs per frame
@@ -1011,13 +1011,13 @@
     OMX_VIDEO_SLICEMODE_AVCDefault = 0,
     OMX_VIDEO_SLICEMODE_AVCMBSlice,
     OMX_VIDEO_SLICEMODE_AVCByteSlice,
-    OMX_VIDEO_SLICEMODE_AVCKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_SLICEMODE_AVCKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_VIDEO_SLICEMODE_AVCVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_VIDEO_SLICEMODE_AVCLevelMax = 0x7FFFFFFF
 } OMX_VIDEO_AVCSLICEMODETYPE;
 
-/** 
- * AVC FMO Slice Mode Params 
+/**
+ * AVC FMO Slice Mode Params
  *
  * STRUCT MEMBERS:
  *  nSize      : Size of the structure in bytes
@@ -1028,7 +1028,7 @@
  *  eSliceMode : Specifies the type of slice
  */
 typedef struct OMX_VIDEO_PARAM_AVCSLICEFMO {
-    OMX_U32 nSize; 
+    OMX_U32 nSize;
     OMX_VERSIONTYPE nVersion;
     OMX_U32 nPortIndex;
     OMX_U8 nNumSliceGroups;
@@ -1036,7 +1036,7 @@
     OMX_VIDEO_AVCSLICEMODETYPE eSliceMode;
 } OMX_VIDEO_PARAM_AVCSLICEFMO;
 
-/** 
+/**
  * AVC IDR Period Configs
  *
  * STRUCT MEMBERS:
@@ -1047,14 +1047,14 @@
  *  nPFrames : Specifies internal of coding Intra frames
  */
 typedef struct OMX_VIDEO_CONFIG_AVCINTRAPERIOD {
-    OMX_U32 nSize; 
+    OMX_U32 nSize;
     OMX_VERSIONTYPE nVersion;
     OMX_U32 nPortIndex;
     OMX_U32 nIDRPeriod;
     OMX_U32 nPFrames;
 } OMX_VIDEO_CONFIG_AVCINTRAPERIOD;
 
-/** 
+/**
  * AVC NAL Size Configs
  *
  * STRUCT MEMBERS:
@@ -1064,7 +1064,7 @@
  *  nNaluBytes : Specifies the NAL unit size
  */
 typedef struct OMX_VIDEO_CONFIG_NALSIZE {
-    OMX_U32 nSize; 
+    OMX_U32 nSize;
     OMX_VERSIONTYPE nVersion;
     OMX_U32 nPortIndex;
     OMX_U32 nNaluBytes;
diff --git a/include/private/binder/Static.h b/include/private/binder/Static.h
index 6a03594..d104646 100644
--- a/include/private/binder/Static.h
+++ b/include/private/binder/Static.h
@@ -34,7 +34,7 @@
 extern Mutex gProcessMutex;
 extern sp<ProcessState> gProcess;
 
-// For ServiceManager.cpp
+// For IServiceManager.cpp
 extern Mutex gDefaultServiceManagerLock;
 extern sp<IServiceManager> gDefaultServiceManager;
 extern sp<IPermissionController> gPermissionController;
diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h
index cea94fc..f91d192 100644
--- a/include/ui/GraphicBuffer.h
+++ b/include/ui/GraphicBuffer.h
@@ -97,6 +97,9 @@
     status_t reallocate(uint32_t inWidth, uint32_t inHeight,
             PixelFormat inFormat, uint32_t inUsage);
 
+    bool needsReallocation(uint32_t inWidth, uint32_t inHeight,
+            PixelFormat inFormat, uint32_t inUsage);
+
     status_t lock(uint32_t inUsage, void** vaddr);
     status_t lock(uint32_t inUsage, const Rect& rect, void** vaddr);
     // For HAL_PIXEL_FORMAT_YCbCr_420_888
diff --git a/include/ui/PixelFormat.h b/include/ui/PixelFormat.h
index e7e8ffc..f26fecb 100644
--- a/include/ui/PixelFormat.h
+++ b/include/ui/PixelFormat.h
@@ -60,8 +60,6 @@
     PIXEL_FORMAT_BGRA_8888   = HAL_PIXEL_FORMAT_BGRA_8888,   // 4x8-bit BGRA
     PIXEL_FORMAT_RGBA_5551   = 6,                            // 16-bit ARGB
     PIXEL_FORMAT_RGBA_4444   = 7,                            // 16-bit ARGB
-    PIXEL_FORMAT_sRGB_A_8888 = HAL_PIXEL_FORMAT_sRGB_A_8888, // 4x8-bit sRGB + A
-    PIXEL_FORMAT_sRGB_X_8888 = HAL_PIXEL_FORMAT_sRGB_X_8888, // 4x8-bit sRGB, no A
 };
 
 typedef int32_t PixelFormat;
diff --git a/include/ui/Rect.h b/include/ui/Rect.h
index 40d1166..3886f93 100644
--- a/include/ui/Rect.h
+++ b/include/ui/Rect.h
@@ -31,6 +31,8 @@
 public:
     typedef ARect::value_type value_type;
 
+    static const Rect INVALID_RECT;
+
     // we don't provide copy-ctor and operator= on purpose
     // because we want the compiler generated versions
 
diff --git a/include/ui/Region.h b/include/ui/Region.h
index 49740f7..2a14918 100644
--- a/include/ui/Region.h
+++ b/include/ui/Region.h
@@ -35,6 +35,8 @@
 class Region : public LightFlattenable<Region>
 {
 public:
+    static const Region INVALID_REGION;
+
                         Region();
                         Region(const Region& rhs);
     explicit            Region(const Rect& rhs);
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 80c5d7e..0921186 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -26,7 +26,6 @@
 #include <binder/TextOutput.h>
 
 #include <errno.h>
-#include <utils/CallStack.h>
 #include <utils/Debug.h>
 #include <utils/Log.h>
 #include <utils/String8.h>
@@ -36,8 +35,8 @@
 #include <cutils/ashmem.h>
 
 #include <private/binder/binder_module.h>
+#include <private/binder/Static.h>
 
-#include <fcntl.h>
 #include <inttypes.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -50,6 +49,8 @@
 
 #define LOG_REFS(...)
 //#define LOG_REFS(...) ALOG(LOG_DEBUG, "Parcel", __VA_ARGS__)
+#define LOG_ALLOC(...)
+//#define LOG_ALLOC(...) ALOG(LOG_DEBUG, "Parcel", __VA_ARGS__)
 
 // ---------------------------------------------------------------------------
 
@@ -74,6 +75,10 @@
 
 namespace android {
 
+static pthread_mutex_t gParcelGlobalAllocSizeLock = PTHREAD_MUTEX_INITIALIZER;
+static size_t gParcelGlobalAllocSize = 0;
+static size_t gParcelGlobalAllocCount = 0;
+
 void acquire_object(const sp<ProcessState>& proc,
     const flat_binder_object& obj, const void* who)
 {
@@ -293,12 +298,28 @@
 
 Parcel::Parcel()
 {
+    LOG_ALLOC("Parcel %p: constructing", this);
     initState();
 }
 
 Parcel::~Parcel()
 {
     freeDataNoInit();
+    LOG_ALLOC("Parcel %p: destroyed", this);
+}
+
+size_t Parcel::getGlobalAllocSize() {
+    pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
+    size_t size = gParcelGlobalAllocSize;
+    pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
+    return size;
+}
+
+size_t Parcel::getGlobalAllocCount() {
+    pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
+    size_t count = gParcelGlobalAllocCount;
+    pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
+    return count;
 }
 
 const uint8_t* Parcel::data() const
@@ -774,29 +795,6 @@
 status_t Parcel::writeDupFileDescriptor(int fd)
 {
     int dupFd = dup(fd);
-
-    {   // Temporary extra debug validation for b/17477219: a Parcel recipient is
-        // getting a positive but invalid fd unexpectedly. Trying to track down
-        // where it's coming from.
-        int dupErrno = dupFd < 0 ? errno : 0;
-        int fdFlags = fcntl(fd, F_GETFD);
-        int fdFlagsErrno = fdFlags == -1 ? errno : 0;
-        int dupFlags = fcntl(dupFd, F_GETFD);
-        int dupFlagsErrno = dupFlags == -1 ? errno : 0;
-        if (dupFd < 0 || fdFlags == -1 || dupFlags == -1) {
-            ALOGE("Parcel::writeDupFileDescriptor failed:\n"
-                    "  fd=%d flags=%d err=%d(%s)\n"
-                    "  dupFd=%d dupErr=%d(%s) flags=%d err=%d(%s)",
-                    fd, fdFlags, fdFlagsErrno, strerror(fdFlagsErrno),
-                    dupFd, dupErrno, strerror(dupErrno),
-                    dupFlags, dupFlagsErrno, strerror(dupFlagsErrno));
-            if (fd < 0 || fdFlags == -1) {
-                CallStack(LOG_TAG);
-            }
-            return -errno;
-        }
-    }
-
     if (dupFd < 0) {
         return -errno;
     }
@@ -1320,23 +1318,11 @@
 
     status_t err = NO_ERROR;
     for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
-        int oldfd = this->readFileDescriptor();
-        fds[i] = dup(oldfd);
+        fds[i] = dup(this->readFileDescriptor());
         if (fds[i] < 0) {
-            int dupErrno = errno;
             err = BAD_VALUE;
-            int flags = fcntl(oldfd, F_GETFD);
-            int fcntlErrno = errno;
-            const flat_binder_object* flat = readObject(true);
-            ALOGE("dup failed in Parcel::read, fd %zu of %zu\n"
-                "  dup(%d) = %d [errno: %d (%s)]\n"
-                "  fcntl(%d, F_GETFD) = %d [errno: %d (%s)]\n"
-                "  flat %p type %d",
-                i, fd_count,
-                oldfd, fds[i], dupErrno, strerror(dupErrno),
-                oldfd, flags, fcntlErrno, strerror(fcntlErrno),
-                flat, flat ? flat->type : 0);
-            CallStack(LOG_TAG);
+            ALOGE("dup() failed in Parcel::read, i is %zu, fds[i] is %d, fd_count is %zu, error: %s",
+                i, fds[i], fd_count, strerror(errno));
         }
     }
 
@@ -1540,11 +1526,20 @@
 void Parcel::freeDataNoInit()
 {
     if (mOwner) {
+        LOG_ALLOC("Parcel %p: freeing other owner data", this);
         //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
         mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
     } else {
+        LOG_ALLOC("Parcel %p: freeing allocated data", this);
         releaseObjects();
-        if (mData) free(mData);
+        if (mData) {
+            LOG_ALLOC("Parcel %p: freeing with %zu capacity", this, mDataCapacity);
+            pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
+            gParcelGlobalAllocSize -= mDataCapacity;
+            gParcelGlobalAllocCount--;
+            pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
+            free(mData);
+        }
         if (mObjects) free(mObjects);
     }
 }
@@ -1573,6 +1568,11 @@
     releaseObjects();
 
     if (data) {
+        LOG_ALLOC("Parcel %p: restart from %zu to %zu capacity", this, mDataCapacity, desired);
+        pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
+        gParcelGlobalAllocSize += desired;
+        gParcelGlobalAllocSize -= mDataCapacity;
+        pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
         mData = data;
         mDataCapacity = desired;
     }
@@ -1626,7 +1626,7 @@
         binder_size_t* objects = NULL;
 
         if (objectsSize) {
-            objects = (binder_size_t*)malloc(objectsSize*sizeof(binder_size_t));
+            objects = (binder_size_t*)calloc(objectsSize, sizeof(binder_size_t));
             if (!objects) {
                 free(data);
 
@@ -1652,6 +1652,12 @@
         mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
         mOwner = NULL;
 
+        LOG_ALLOC("Parcel %p: taking ownership of %zu capacity", this, desired);
+        pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
+        gParcelGlobalAllocSize += desired;
+        gParcelGlobalAllocCount++;
+        pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
+
         mData = data;
         mObjects = objects;
         mDataSize = (mDataSize < desired) ? mDataSize : desired;
@@ -1686,6 +1692,12 @@
         if (desired > mDataCapacity) {
             uint8_t* data = (uint8_t*)realloc(mData, desired);
             if (data) {
+                LOG_ALLOC("Parcel %p: continue from %zu to %zu capacity", this, mDataCapacity,
+                        desired);
+                pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
+                gParcelGlobalAllocSize += desired;
+                gParcelGlobalAllocSize -= mDataCapacity;
+                pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
                 mData = data;
                 mDataCapacity = desired;
             } else if (desired > mDataCapacity) {
@@ -1716,6 +1728,12 @@
             ALOGE("continueWrite: %zu/%p/%zu/%zu", mDataCapacity, mObjects, mObjectsCapacity, desired);
         }
 
+        LOG_ALLOC("Parcel %p: allocating with %zu capacity", this, desired);
+        pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
+        gParcelGlobalAllocSize += desired;
+        gParcelGlobalAllocCount++;
+        pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
+
         mData = data;
         mDataSize = mDataPos = 0;
         ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
@@ -1728,6 +1746,7 @@
 
 void Parcel::initState()
 {
+    LOG_ALLOC("Parcel %p: initState", this);
     mError = NO_ERROR;
     mData = 0;
     mDataSize = 0;
diff --git a/libs/binder/Static.cpp b/libs/binder/Static.cpp
index 2062692..cd9509f 100644
--- a/libs/binder/Static.cpp
+++ b/libs/binder/Static.cpp
@@ -90,7 +90,7 @@
 
 static LibBinderIPCtStatics gIPCStatics;
 
-// ------------ ServiceManager.cpp
+// ------------ IServiceManager.cpp
 
 Mutex gDefaultServiceManagerLock;
 sp<IServiceManager> gDefaultServiceManager;
diff --git a/libs/binder/TextOutput.cpp b/libs/binder/TextOutput.cpp
index db3e858..2ed5188 100644
--- a/libs/binder/TextOutput.cpp
+++ b/libs/binder/TextOutput.cpp
@@ -116,8 +116,8 @@
 
 TextOutput& operator<<(TextOutput& to, const void* val)
 {
-    char buf[16];
-    sprintf(buf, "%p", val);
+    char buf[32];
+    snprintf(buf, sizeof(buf), "%p", val);
     to.print(buf, strlen(buf));
     return to;
 }
diff --git a/libs/gui/BufferItem.cpp b/libs/gui/BufferItem.cpp
index d3fa43e..5793d40 100644
--- a/libs/gui/BufferItem.cpp
+++ b/libs/gui/BufferItem.cpp
@@ -28,6 +28,7 @@
     mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
     mTimestamp(0),
     mIsAutoTimestamp(false),
+    mDataSpace(HAL_DATASPACE_UNKNOWN),
     mFrameNumber(0),
     mSlot(INVALID_BUFFER_SLOT),
     mIsDroppable(false),
@@ -36,66 +37,68 @@
     mCrop.makeInvalid();
 }
 
-BufferItem::operator IGraphicBufferConsumer::BufferItem() const {
-    IGraphicBufferConsumer::BufferItem bufferItem;
-    bufferItem.mGraphicBuffer = mGraphicBuffer;
-    bufferItem.mFence = mFence;
-    bufferItem.mCrop = mCrop;
-    bufferItem.mTransform = mTransform;
-    bufferItem.mScalingMode = mScalingMode;
-    bufferItem.mTimestamp = mTimestamp;
-    bufferItem.mIsAutoTimestamp = mIsAutoTimestamp;
-    bufferItem.mFrameNumber = mFrameNumber;
-    bufferItem.mBuf = mSlot;
-    bufferItem.mIsDroppable = mIsDroppable;
-    bufferItem.mAcquireCalled = mAcquireCalled;
-    bufferItem.mTransformToDisplayInverse = mTransformToDisplayInverse;
-    return bufferItem;
+BufferItem::~BufferItem() {}
+
+template <typename T>
+static void addAligned(size_t& size, T /* value */) {
+    size = FlattenableUtils::align<sizeof(T)>(size);
+    size += sizeof(T);
 }
 
 size_t BufferItem::getPodSize() const {
-    size_t c =  sizeof(mCrop) +
-            sizeof(mTransform) +
-            sizeof(mScalingMode) +
-            sizeof(mTimestamp) +
-            sizeof(mIsAutoTimestamp) +
-            sizeof(mFrameNumber) +
-            sizeof(mSlot) +
-            sizeof(mIsDroppable) +
-            sizeof(mAcquireCalled) +
-            sizeof(mTransformToDisplayInverse);
-    return c;
+    // Must align<8> before writing these fields for this to be correct
+    size_t size = 0;
+    addAligned(size, mCrop);
+    addAligned(size, mTransform);
+    addAligned(size, mScalingMode);
+    addAligned(size, mTimestamp);
+    addAligned(size, mIsAutoTimestamp);
+    addAligned(size, mDataSpace);
+    addAligned(size, mFrameNumber);
+    addAligned(size, mSlot);
+    addAligned(size, mIsDroppable);
+    addAligned(size, mAcquireCalled);
+    addAligned(size, mTransformToDisplayInverse);
+    return size;
 }
 
 size_t BufferItem::getFlattenedSize() const {
-    size_t c = 0;
+    size_t size = sizeof(uint32_t); // Flags
     if (mGraphicBuffer != 0) {
-        c += mGraphicBuffer->getFlattenedSize();
-        FlattenableUtils::align<4>(c);
+        size += mGraphicBuffer->getFlattenedSize();
+        FlattenableUtils::align<4>(size);
     }
     if (mFence != 0) {
-        c += mFence->getFlattenedSize();
-        FlattenableUtils::align<4>(c);
+        size += mFence->getFlattenedSize();
+        FlattenableUtils::align<4>(size);
     }
-    return sizeof(int32_t) + c + getPodSize();
+    size += mSurfaceDamage.getFlattenedSize();
+    size = FlattenableUtils::align<8>(size);
+    return size + getPodSize();
 }
 
 size_t BufferItem::getFdCount() const {
-    size_t c = 0;
+    size_t count = 0;
     if (mGraphicBuffer != 0) {
-        c += mGraphicBuffer->getFdCount();
+        count += mGraphicBuffer->getFdCount();
     }
     if (mFence != 0) {
-        c += mFence->getFdCount();
+        count += mFence->getFdCount();
     }
-    return c;
+    return count;
+}
+
+template <typename T>
+static void writeAligned(void*& buffer, size_t& size, T value) {
+    size -= FlattenableUtils::align<alignof(T)>(buffer);
+    FlattenableUtils::write(buffer, size, value);
 }
 
 status_t BufferItem::flatten(
         void*& buffer, size_t& size, int*& fds, size_t& count) const {
 
     // make sure we have enough space
-    if (count < BufferItem::getFlattenedSize()) {
+    if (size < BufferItem::getFlattenedSize()) {
         return NO_MEMORY;
     }
 
@@ -119,30 +122,45 @@
         flags |= 2;
     }
 
-    // check we have enough space (in case flattening the fence/graphicbuffer lied to us)
+    status_t err = mSurfaceDamage.flatten(buffer, size);
+    if (err) return err;
+    FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize());
+
+    // Must align<8> so that getPodSize returns the correct value
+    size -= FlattenableUtils::align<8>(buffer);
+
+    // Check we still have enough space
     if (size < getPodSize()) {
         return NO_MEMORY;
     }
 
-    FlattenableUtils::write(buffer, size, mCrop);
-    FlattenableUtils::write(buffer, size, mTransform);
-    FlattenableUtils::write(buffer, size, mScalingMode);
-    FlattenableUtils::write(buffer, size, mTimestamp);
-    FlattenableUtils::write(buffer, size, mIsAutoTimestamp);
-    FlattenableUtils::write(buffer, size, mFrameNumber);
-    FlattenableUtils::write(buffer, size, mSlot);
-    FlattenableUtils::write(buffer, size, mIsDroppable);
-    FlattenableUtils::write(buffer, size, mAcquireCalled);
-    FlattenableUtils::write(buffer, size, mTransformToDisplayInverse);
+    writeAligned(buffer, size, mCrop);
+    writeAligned(buffer, size, mTransform);
+    writeAligned(buffer, size, mScalingMode);
+    writeAligned(buffer, size, mTimestamp);
+    writeAligned(buffer, size, mIsAutoTimestamp);
+    writeAligned(buffer, size, mDataSpace);
+    writeAligned(buffer, size, mFrameNumber);
+    writeAligned(buffer, size, mSlot);
+    writeAligned(buffer, size, mIsDroppable);
+    writeAligned(buffer, size, mAcquireCalled);
+    writeAligned(buffer, size, mTransformToDisplayInverse);
 
     return NO_ERROR;
 }
 
+template <typename T>
+static void readAligned(const void*& buffer, size_t& size, T& value) {
+    size -= FlattenableUtils::align<alignof(T)>(buffer);
+    FlattenableUtils::read(buffer, size, value);
+}
+
 status_t BufferItem::unflatten(
         void const*& buffer, size_t& size, int const*& fds, size_t& count) {
 
-    if (size < sizeof(uint32_t))
+    if (size < sizeof(uint32_t)) {
         return NO_MEMORY;
+    }
 
     uint32_t flags = 0;
     FlattenableUtils::read(buffer, size, flags);
@@ -161,21 +179,29 @@
         size -= FlattenableUtils::align<4>(buffer);
     }
 
-    // check we have enough space
+    status_t err = mSurfaceDamage.unflatten(buffer, size);
+    if (err) return err;
+    FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize());
+
+    // Must align<8> so that getPodSize returns the correct value
+    size -= FlattenableUtils::align<8>(buffer);
+
+    // Check we still have enough space
     if (size < getPodSize()) {
         return NO_MEMORY;
     }
 
-    FlattenableUtils::read(buffer, size, mCrop);
-    FlattenableUtils::read(buffer, size, mTransform);
-    FlattenableUtils::read(buffer, size, mScalingMode);
-    FlattenableUtils::read(buffer, size, mTimestamp);
-    FlattenableUtils::read(buffer, size, mIsAutoTimestamp);
-    FlattenableUtils::read(buffer, size, mFrameNumber);
-    FlattenableUtils::read(buffer, size, mSlot);
-    FlattenableUtils::read(buffer, size, mIsDroppable);
-    FlattenableUtils::read(buffer, size, mAcquireCalled);
-    FlattenableUtils::read(buffer, size, mTransformToDisplayInverse);
+    readAligned(buffer, size, mCrop);
+    readAligned(buffer, size, mTransform);
+    readAligned(buffer, size, mScalingMode);
+    readAligned(buffer, size, mTimestamp);
+    readAligned(buffer, size, mIsAutoTimestamp);
+    readAligned(buffer, size, mDataSpace);
+    readAligned(buffer, size, mFrameNumber);
+    readAligned(buffer, size, mSlot);
+    readAligned(buffer, size, mIsDroppable);
+    readAligned(buffer, size, mAcquireCalled);
+    readAligned(buffer, size, mTransformToDisplayInverse);
 
     return NO_ERROR;
 }
diff --git a/libs/gui/BufferItemConsumer.cpp b/libs/gui/BufferItemConsumer.cpp
index 61de69a..194121f 100644
--- a/libs/gui/BufferItemConsumer.cpp
+++ b/libs/gui/BufferItemConsumer.cpp
@@ -19,6 +19,7 @@
 //#define ATRACE_TAG ATRACE_TAG_GRAPHICS
 #include <utils/Log.h>
 
+#include <gui/BufferItem.h>
 #include <gui/BufferItemConsumer.h>
 
 //#define BI_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__)
@@ -109,4 +110,10 @@
     return mConsumer->setDefaultBufferFormat(defaultFormat);
 }
 
+status_t BufferItemConsumer::setDefaultBufferDataSpace(
+        android_dataspace defaultDataSpace) {
+    Mutex::Autolock _l(mMutex);
+    return mConsumer->setDefaultBufferDataSpace(defaultDataSpace);
+}
+
 } // namespace android
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index c49a886..2fcbaf2 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -31,10 +31,11 @@
 
 BufferQueue::ProxyConsumerListener::~ProxyConsumerListener() {}
 
-void BufferQueue::ProxyConsumerListener::onFrameAvailable() {
+void BufferQueue::ProxyConsumerListener::onFrameAvailable(
+        const BufferItem& item) {
     sp<ConsumerListener> listener(mConsumerListener.promote());
     if (listener != NULL) {
-        listener->onFrameAvailable();
+        listener->onFrameAvailable(item);
     }
 }
 
diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp
index a798b18..336ddb6 100644
--- a/libs/gui/BufferQueueConsumer.cpp
+++ b/libs/gui/BufferQueueConsumer.cpp
@@ -89,7 +89,20 @@
         // the timestamps are being auto-generated by Surface. If the app isn't
         // generating timestamps explicitly, it probably doesn't want frames to
         // be discarded based on them.
+        //
+        // If the consumer is shadowing our queue, we also make sure that we
+        // don't drop so many buffers that the consumer hasn't received the
+        // onFrameAvailable callback for the buffer it acquires. That is, we
+        // want the buffer we return to be in the consumer's shadow queue.
+        size_t droppableBuffers = mCore->mConsumerShadowQueueSize > 1 ?
+                mCore->mConsumerShadowQueueSize - 1 : 0;
         while (mCore->mQueue.size() > 1 && !mCore->mQueue[0].mIsAutoTimestamp) {
+            if (mCore->mConsumerHasShadowQueue && droppableBuffers == 0) {
+                BQ_LOGV("acquireBuffer: no droppable buffers in consumer's"
+                        " shadow queue, continuing");
+                break;
+            }
+
             // If entry[1] is timely, drop entry[0] (and repeat). We apply an
             // additional criterion here: we only drop the earlier buffer if our
             // desiredPresent falls within +/- 1 second of the expected present.
@@ -120,9 +133,11 @@
             if (mCore->stillTracking(front)) {
                 // Front buffer is still in mSlots, so mark the slot as free
                 mSlots[front->mSlot].mBufferState = BufferSlot::FREE;
+                mCore->mFreeBuffers.push_back(front->mSlot);
             }
             mCore->mQueue.erase(front);
             front = mCore->mQueue.begin();
+            --droppableBuffers;
         }
 
         // See if the front buffer is due
@@ -173,6 +188,8 @@
 
     ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size());
 
+    mCore->validateConsistencyLocked();
+
     return NO_ERROR;
 }
 
@@ -199,6 +216,7 @@
 
     mCore->freeBufferLocked(slot);
     mCore->mDequeueCondition.broadcast();
+    mCore->validateConsistencyLocked();
 
     return NO_ERROR;
 }
@@ -217,18 +235,11 @@
 
     Mutex::Autolock lock(mCore->mMutex);
 
-    // Make sure we don't have too many acquired buffers and find a free slot
-    // to put the buffer into (the oldest if there are multiple).
+    // Make sure we don't have too many acquired buffers
     int numAcquiredBuffers = 0;
-    int found = BufferQueueCore::INVALID_BUFFER_SLOT;
     for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
         if (mSlots[s].mBufferState == BufferSlot::ACQUIRED) {
             ++numAcquiredBuffers;
-        } else if (mSlots[s].mBufferState == BufferSlot::FREE) {
-            if (found == BufferQueueCore::INVALID_BUFFER_SLOT ||
-                    mSlots[s].mFrameNumber < mSlots[found].mFrameNumber) {
-                found = s;
-            }
         }
     }
 
@@ -238,6 +249,17 @@
                 mCore->mMaxAcquiredBufferCount);
         return INVALID_OPERATION;
     }
+
+    // Find a free slot to put the buffer into
+    int found = BufferQueueCore::INVALID_BUFFER_SLOT;
+    if (!mCore->mFreeSlots.empty()) {
+        auto slot = mCore->mFreeSlots.begin();
+        found = *slot;
+        mCore->mFreeSlots.erase(slot);
+    } else if (!mCore->mFreeBuffers.empty()) {
+        found = mCore->mFreeBuffers.front();
+        mCore->mFreeBuffers.remove(found);
+    }
     if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
         BQ_LOGE("attachBuffer(P): could not find free buffer slot");
         return NO_MEMORY;
@@ -271,6 +293,8 @@
     // for attached buffers.
     mSlots[*outSlot].mAcquireCalled = false;
 
+    mCore->validateConsistencyLocked();
+
     return NO_ERROR;
 }
 
@@ -282,6 +306,8 @@
 
     if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS ||
             releaseFence == NULL) {
+        BQ_LOGE("releaseBuffer: slot %d out of range or fence %p NULL", slot,
+                releaseFence.get());
         return BAD_VALUE;
     }
 
@@ -311,6 +337,7 @@
             mSlots[slot].mEglFence = eglFence;
             mSlots[slot].mFence = releaseFence;
             mSlots[slot].mBufferState = BufferSlot::FREE;
+            mCore->mFreeBuffers.push_back(slot);
             listener = mCore->mConnectedProducerListener;
             BQ_LOGV("releaseBuffer: releasing slot %d", slot);
         } else if (mSlots[slot].mNeedsCleanupOnRelease) {
@@ -319,12 +346,13 @@
             mSlots[slot].mNeedsCleanupOnRelease = false;
             return STALE_BUFFER_SLOT;
         } else {
-            BQ_LOGV("releaseBuffer: attempted to release buffer slot %d "
+            BQ_LOGE("releaseBuffer: attempted to release buffer slot %d "
                     "but its state was %d", slot, mSlots[slot].mBufferState);
             return BAD_VALUE;
         }
 
         mCore->mDequeueCondition.broadcast();
+        mCore->validateConsistencyLocked();
     } // Autolock scope
 
     // Call back without lock held
@@ -496,6 +524,15 @@
     return NO_ERROR;
 }
 
+status_t BufferQueueConsumer::setDefaultBufferDataSpace(
+        android_dataspace defaultDataSpace) {
+    ATRACE_CALL();
+    BQ_LOGV("setDefaultBufferDataSpace: %u", defaultDataSpace);
+    Mutex::Autolock lock(mCore->mMutex);
+    mCore->mDefaultBufferDataSpace = defaultDataSpace;
+    return NO_ERROR;
+}
+
 status_t BufferQueueConsumer::setConsumerUsageBits(uint32_t usage) {
     ATRACE_CALL();
     BQ_LOGV("setConsumerUsageBits: %#x", usage);
@@ -516,6 +553,14 @@
     return mCore->mSidebandStream;
 }
 
+void BufferQueueConsumer::setShadowQueueSize(size_t size) {
+    ATRACE_CALL();
+    BQ_LOGV("setShadowQueueSize: %zu", size);
+    Mutex::Autolock lock(mCore->mMutex);
+    mCore->mConsumerHasShadowQueue = true;
+    mCore->mConsumerShadowQueueSize = size;
+}
+
 void BufferQueueConsumer::dump(String8& result, const char* prefix) const {
     mCore->dump(result, prefix);
 }
diff --git a/libs/gui/BufferQueueCore.cpp b/libs/gui/BufferQueueCore.cpp
index ec1e631..37171ed 100644
--- a/libs/gui/BufferQueueCore.cpp
+++ b/libs/gui/BufferQueueCore.cpp
@@ -53,6 +53,8 @@
     mConnectedProducerListener(),
     mSlots(),
     mQueue(),
+    mFreeSlots(),
+    mFreeBuffers(),
     mOverrideMaxBufferCount(0),
     mDequeueCondition(),
     mUseAsyncBuffer(true),
@@ -60,13 +62,18 @@
     mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888),
     mDefaultWidth(1),
     mDefaultHeight(1),
+    mDefaultBufferDataSpace(HAL_DATASPACE_UNKNOWN),
     mDefaultMaxBufferCount(2),
     mMaxAcquiredBufferCount(1),
     mBufferHasBeenQueued(false),
     mFrameCounter(0),
     mTransformHint(0),
     mIsAllocating(false),
-    mIsAllocatingCondition()
+    mIsAllocatingCondition(),
+    mAllowAllocation(true),
+    mBufferAge(0),
+    mConsumerHasShadowQueue(false),
+    mConsumerShadowQueueSize(0)
 {
     if (allocator == NULL) {
         sp<ISurfaceComposer> composer(ComposerService::getComposerService());
@@ -75,6 +82,9 @@
             BQ_LOGE("createGraphicBufferAlloc failed");
         }
     }
+    for (int slot = 0; slot < BufferQueueDefs::NUM_BUFFER_SLOTS; ++slot) {
+        mFreeSlots.insert(slot);
+    }
 }
 
 BufferQueueCore::~BufferQueueCore() {}
@@ -189,13 +199,22 @@
 
 void BufferQueueCore::freeBufferLocked(int slot) {
     BQ_LOGV("freeBufferLocked: slot %d", slot);
+    bool hadBuffer = mSlots[slot].mGraphicBuffer != NULL;
     mSlots[slot].mGraphicBuffer.clear();
     if (mSlots[slot].mBufferState == BufferSlot::ACQUIRED) {
         mSlots[slot].mNeedsCleanupOnRelease = true;
     }
+    if (mSlots[slot].mBufferState != BufferSlot::FREE) {
+        mFreeSlots.insert(slot);
+    } else if (hadBuffer) {
+        // If the slot was FREE, but we had a buffer, we need to move this slot
+        // from the free buffers list to the the free slots list
+        mFreeBuffers.remove(slot);
+        mFreeSlots.insert(slot);
+    }
     mSlots[slot].mBufferState = BufferSlot::FREE;
-    mSlots[slot].mFrameNumber = UINT32_MAX;
     mSlots[slot].mAcquireCalled = false;
+    mSlots[slot].mFrameNumber = 0;
 
     // Destroy fence as BufferQueue now takes ownership
     if (mSlots[slot].mEglFence != EGL_NO_SYNC_KHR) {
@@ -203,6 +222,7 @@
         mSlots[slot].mEglFence = EGL_NO_SYNC_KHR;
     }
     mSlots[slot].mFence = Fence::NO_FENCE;
+    validateConsistencyLocked();
 }
 
 void BufferQueueCore::freeAllBuffersLocked() {
@@ -235,4 +255,48 @@
     }
 }
 
+void BufferQueueCore::validateConsistencyLocked() const {
+    static const useconds_t PAUSE_TIME = 0;
+    for (int slot = 0; slot < BufferQueueDefs::NUM_BUFFER_SLOTS; ++slot) {
+        bool isInFreeSlots = mFreeSlots.count(slot) != 0;
+        bool isInFreeBuffers =
+                std::find(mFreeBuffers.cbegin(), mFreeBuffers.cend(), slot) !=
+                mFreeBuffers.cend();
+        if (mSlots[slot].mBufferState == BufferSlot::FREE) {
+            if (mSlots[slot].mGraphicBuffer == NULL) {
+                if (!isInFreeSlots) {
+                    BQ_LOGE("Slot %d is FREE but is not in mFreeSlots", slot);
+                    usleep(PAUSE_TIME);
+                }
+                if (isInFreeBuffers) {
+                    BQ_LOGE("Slot %d is in mFreeSlots "
+                            "but is also in mFreeBuffers", slot);
+                    usleep(PAUSE_TIME);
+                }
+            } else {
+                if (!isInFreeBuffers) {
+                    BQ_LOGE("Slot %d is FREE but is not in mFreeBuffers", slot);
+                    usleep(PAUSE_TIME);
+                }
+                if (isInFreeSlots) {
+                    BQ_LOGE("Slot %d is in mFreeBuffers "
+                            "but is also in mFreeSlots", slot);
+                    usleep(PAUSE_TIME);
+                }
+            }
+        } else {
+            if (isInFreeSlots) {
+                BQ_LOGE("Slot %d is in mFreeSlots but is not FREE (%d)",
+                        slot, mSlots[slot].mBufferState);
+                usleep(PAUSE_TIME);
+            }
+            if (isInFreeBuffers) {
+                BQ_LOGE("Slot %d is in mFreeBuffers but is not FREE (%d)",
+                        slot, mSlots[slot].mBufferState);
+                usleep(PAUSE_TIME);
+            }
+        }
+    }
+}
+
 } // namespace android
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index ef2a7e8..7251d36 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -38,7 +38,12 @@
     mCore(core),
     mSlots(core->mSlots),
     mConsumerName(),
-    mStickyTransform(0) {}
+    mStickyTransform(0),
+    mLastQueueBufferFence(Fence::NO_FENCE),
+    mCallbackMutex(),
+    mNextCallbackTicket(0),
+    mCurrentCallbackTicket(0),
+    mCallbackCondition() {}
 
 BufferQueueProducer::~BufferQueueProducer() {}
 
@@ -156,8 +161,6 @@
             }
         }
 
-        // Look for a free buffer to give to the client
-        *found = BufferQueueCore::INVALID_BUFFER_SLOT;
         int dequeuedCount = 0;
         int acquiredCount = 0;
         for (int s = 0; s < maxBufferCount; ++s) {
@@ -168,15 +171,6 @@
                 case BufferSlot::ACQUIRED:
                     ++acquiredCount;
                     break;
-                case BufferSlot::FREE:
-                    // We return the oldest of the free buffers to avoid
-                    // stalling the producer if possible, since the consumer
-                    // may still have pending reads of in-flight buffers
-                    if (*found == BufferQueueCore::INVALID_BUFFER_SLOT ||
-                            mSlots[s].mFrameNumber < mSlots[*found].mFrameNumber) {
-                        *found = s;
-                    }
-                    break;
                 default:
                     break;
             }
@@ -209,6 +203,8 @@
             }
         }
 
+        *found = BufferQueueCore::INVALID_BUFFER_SLOT;
+
         // If we disconnect and reconnect quickly, we can be in a state where
         // our slots are empty but we have many buffers in the queue. This can
         // cause us to run out of memory if we outrun the consumer. Wait here if
@@ -218,6 +214,19 @@
         if (tooManyBuffers) {
             BQ_LOGV("%s: queue size is %zu, waiting", caller,
                     mCore->mQueue.size());
+        } else {
+            if (!mCore->mFreeBuffers.empty()) {
+                auto slot = mCore->mFreeBuffers.begin();
+                *found = *slot;
+                mCore->mFreeBuffers.erase(slot);
+            } else if (mCore->mAllowAllocation && !mCore->mFreeSlots.empty()) {
+                auto slot = mCore->mFreeSlots.begin();
+                // Only return free slots up to the max buffer count
+                if (*slot < maxBufferCount) {
+                    *found = *slot;
+                    mCore->mFreeSlots.erase(slot);
+                }
+            }
         }
 
         // If no buffer is found, or if the queue has too many buffers
@@ -276,17 +285,39 @@
         // Enable the usage bits the consumer requested
         usage |= mCore->mConsumerUsageBits;
 
-        int found;
-        status_t status = waitForFreeSlotThenRelock("dequeueBuffer", async,
-                &found, &returnFlags);
-        if (status != NO_ERROR) {
-            return status;
+        const bool useDefaultSize = !width && !height;
+        if (useDefaultSize) {
+            width = mCore->mDefaultWidth;
+            height = mCore->mDefaultHeight;
         }
 
-        // This should not happen
-        if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
-            BQ_LOGE("dequeueBuffer: no available buffer slots");
-            return -EBUSY;
+        int found = BufferItem::INVALID_BUFFER_SLOT;
+        while (found == BufferItem::INVALID_BUFFER_SLOT) {
+            status_t status = waitForFreeSlotThenRelock("dequeueBuffer", async,
+                    &found, &returnFlags);
+            if (status != NO_ERROR) {
+                return status;
+            }
+
+            // This should not happen
+            if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
+                BQ_LOGE("dequeueBuffer: no available buffer slots");
+                return -EBUSY;
+            }
+
+            const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer);
+
+            // If we are not allowed to allocate new buffers,
+            // waitForFreeSlotThenRelock must have returned a slot containing a
+            // buffer. If this buffer would require reallocation to meet the
+            // requested attributes, we free it and attempt to get another one.
+            if (!mCore->mAllowAllocation) {
+                if (buffer->needsReallocation(width, height, format, usage)) {
+                    mCore->freeBufferLocked(found);
+                    found = BufferItem::INVALID_BUFFER_SLOT;
+                    continue;
+                }
+            }
         }
 
         *outSlot = found;
@@ -294,20 +325,11 @@
 
         attachedByConsumer = mSlots[found].mAttachedByConsumer;
 
-        const bool useDefaultSize = !width && !height;
-        if (useDefaultSize) {
-            width = mCore->mDefaultWidth;
-            height = mCore->mDefaultHeight;
-        }
-
         mSlots[found].mBufferState = BufferSlot::DEQUEUED;
 
         const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer);
         if ((buffer == NULL) ||
-                (static_cast<uint32_t>(buffer->width) != width) ||
-                (static_cast<uint32_t>(buffer->height) != height) ||
-                (buffer->format != format) ||
-                ((static_cast<uint32_t>(buffer->usage) & usage) != usage))
+                buffer->needsReallocation(width, height, format, usage))
         {
             mSlots[found].mAcquireCalled = false;
             mSlots[found].mGraphicBuffer = NULL;
@@ -315,10 +337,19 @@
             mSlots[found].mEglDisplay = EGL_NO_DISPLAY;
             mSlots[found].mEglFence = EGL_NO_SYNC_KHR;
             mSlots[found].mFence = Fence::NO_FENCE;
+            mCore->mBufferAge = 0;
 
             returnFlags |= BUFFER_NEEDS_REALLOCATION;
+        } else {
+            // We add 1 because that will be the frame number when this buffer
+            // is queued
+            mCore->mBufferAge =
+                    mCore->mFrameCounter + 1 - mSlots[found].mFrameNumber;
         }
 
+        BQ_LOGV("dequeueBuffer: setting buffer age to %" PRIu64,
+                mCore->mBufferAge);
+
         if (CC_UNLIKELY(mSlots[found].mFence == NULL)) {
             BQ_LOGE("dequeueBuffer: about to return a NULL fence - "
                     "slot=%d w=%d h=%d format=%u",
@@ -330,6 +361,8 @@
         *outFence = mSlots[found].mFence;
         mSlots[found].mEglFence = EGL_NO_SYNC_KHR;
         mSlots[found].mFence = Fence::NO_FENCE;
+
+        mCore->validateConsistencyLocked();
     } // Autolock scope
 
     if (returnFlags & BUFFER_NEEDS_REALLOCATION) {
@@ -350,7 +383,6 @@
                 return NO_INIT;
             }
 
-            mSlots[*outSlot].mFrameNumber = UINT32_MAX;
             mSlots[*outSlot].mGraphicBuffer = graphicBuffer;
         } // Autolock scope
     }
@@ -409,6 +441,7 @@
 
     mCore->freeBufferLocked(slot);
     mCore->mDequeueCondition.broadcast();
+    mCore->validateConsistencyLocked();
 
     return NO_ERROR;
 }
@@ -433,27 +466,19 @@
         return NO_INIT;
     }
 
-    // Find the oldest valid slot
-    int found = BufferQueueCore::INVALID_BUFFER_SLOT;
-    for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
-        if (mSlots[s].mBufferState == BufferSlot::FREE &&
-                mSlots[s].mGraphicBuffer != NULL) {
-            if (found == BufferQueueCore::INVALID_BUFFER_SLOT ||
-                    mSlots[s].mFrameNumber < mSlots[found].mFrameNumber) {
-                found = s;
-            }
-        }
-    }
-
-    if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
+    if (mCore->mFreeBuffers.empty()) {
         return NO_MEMORY;
     }
 
+    int found = mCore->mFreeBuffers.front();
+    mCore->mFreeBuffers.remove(found);
+
     BQ_LOGV("detachNextBuffer detached slot %d", found);
 
     *outBuffer = mSlots[found].mGraphicBuffer;
     *outFence = mSlots[found].mFence;
     mCore->freeBufferLocked(found);
+    mCore->validateConsistencyLocked();
 
     return NO_ERROR;
 }
@@ -501,6 +526,8 @@
     mSlots[*outSlot].mFence = Fence::NO_FENCE;
     mSlots[*outSlot].mRequestBufferCalled = true;
 
+    mCore->validateConsistencyLocked();
+
     return returnFlags;
 }
 
@@ -511,23 +538,20 @@
 
     int64_t timestamp;
     bool isAutoTimestamp;
+    android_dataspace dataSpace;
     Rect crop;
     int scalingMode;
     uint32_t transform;
     uint32_t stickyTransform;
     bool async;
     sp<Fence> fence;
-    input.deflate(&timestamp, &isAutoTimestamp, &crop, &scalingMode, &transform,
-            &async, &fence, &stickyTransform);
+    input.deflate(&timestamp, &isAutoTimestamp, &dataSpace, &crop, &scalingMode,
+            &transform, &async, &fence, &stickyTransform);
+    Region surfaceDamage = input.getSurfaceDamage();
 
     if (fence == NULL) {
         BQ_LOGE("queueBuffer: fence is NULL");
-        // Temporary workaround for b/17946343: soldier-on instead of returning an error. This
-        // prevents the client from dying, at the risk of visible corruption due to hwcomposer
-        // reading the buffer before the producer is done rendering it. Unless the buffer is the
-        // last frame of an animation, the corruption will be transient.
-        fence = Fence::NO_FENCE;
-        // return BAD_VALUE;
+        return BAD_VALUE;
     }
 
     switch (scalingMode) {
@@ -541,7 +565,10 @@
             return BAD_VALUE;
     }
 
-    sp<IConsumerListener> listener;
+    sp<IConsumerListener> frameAvailableListener;
+    sp<IConsumerListener> frameReplacedListener;
+    int callbackTicket = 0;
+    BufferItem item;
     { // Autolock scope
         Mutex::Autolock lock(mCore->mMutex);
 
@@ -576,9 +603,9 @@
             return BAD_VALUE;
         }
 
-        BQ_LOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64
+        BQ_LOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64 " dataSpace=%d"
                 " crop=[%d,%d,%d,%d] transform=%#x scale=%s",
-                slot, mCore->mFrameCounter + 1, timestamp,
+                slot, mCore->mFrameCounter + 1, timestamp, dataSpace,
                 crop.left, crop.top, crop.right, crop.bottom, transform,
                 BufferItem::scalingModeName(static_cast<uint32_t>(scalingMode)));
 
@@ -592,12 +619,16 @@
             return BAD_VALUE;
         }
 
+        // Override UNKNOWN dataspace with consumer default
+        if (dataSpace == HAL_DATASPACE_UNKNOWN) {
+            dataSpace = mCore->mDefaultBufferDataSpace;
+        }
+
         mSlots[slot].mFence = fence;
         mSlots[slot].mBufferState = BufferSlot::QUEUED;
         ++mCore->mFrameCounter;
         mSlots[slot].mFrameNumber = mCore->mFrameCounter;
 
-        BufferItem item;
         item.mAcquireCalled = mSlots[slot].mAcquireCalled;
         item.mGraphicBuffer = mSlots[slot].mGraphicBuffer;
         item.mCrop = crop;
@@ -608,10 +639,12 @@
         item.mScalingMode = static_cast<uint32_t>(scalingMode);
         item.mTimestamp = timestamp;
         item.mIsAutoTimestamp = isAutoTimestamp;
+        item.mDataSpace = dataSpace;
         item.mFrameNumber = mCore->mFrameCounter;
         item.mSlot = slot;
         item.mFence = fence;
         item.mIsDroppable = mCore->mDequeueBufferCannotBlock || async;
+        item.mSurfaceDamage = surfaceDamage;
 
         mStickyTransform = stickyTransform;
 
@@ -619,7 +652,7 @@
             // When the queue is empty, we can ignore mDequeueBufferCannotBlock
             // and simply queue this buffer
             mCore->mQueue.push_back(item);
-            listener = mCore->mConsumerListener;
+            frameAvailableListener = mCore->mConsumerListener;
         } else {
             // When the queue is not empty, we need to look at the front buffer
             // state to see if we need to replace it
@@ -629,15 +662,14 @@
                 // mark it as freed
                 if (mCore->stillTracking(front)) {
                     mSlots[front->mSlot].mBufferState = BufferSlot::FREE;
-                    // Reset the frame number of the freed buffer so that it is
-                    // the first in line to be dequeued again
-                    mSlots[front->mSlot].mFrameNumber = 0;
+                    mCore->mFreeBuffers.push_front(front->mSlot);
                 }
                 // Overwrite the droppable buffer with the incoming one
                 *front = item;
+                frameReplacedListener = mCore->mConsumerListener;
             } else {
                 mCore->mQueue.push_back(item);
-                listener = mCore->mConsumerListener;
+                frameAvailableListener = mCore->mConsumerListener;
             }
         }
 
@@ -649,11 +681,43 @@
                 static_cast<uint32_t>(mCore->mQueue.size()));
 
         ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size());
+
+        // Take a ticket for the callback functions
+        callbackTicket = mNextCallbackTicket++;
+
+        mCore->validateConsistencyLocked();
     } // Autolock scope
 
-    // Call back without lock held
-    if (listener != NULL) {
-        listener->onFrameAvailable();
+    // Wait without lock held
+    if (mCore->mConnectedApi == NATIVE_WINDOW_API_EGL) {
+        // Waiting here allows for two full buffers to be queued but not a
+        // third. In the event that frames take varying time, this makes a
+        // small trade-off in favor of latency rather than throughput.
+        mLastQueueBufferFence->waitForever("Throttling EGL Production");
+        mLastQueueBufferFence = fence;
+    }
+
+    // Don't send the GraphicBuffer through the callback, and don't send
+    // the slot number, since the consumer shouldn't need it
+    item.mGraphicBuffer.clear();
+    item.mSlot = BufferItem::INVALID_BUFFER_SLOT;
+
+    // Call back without the main BufferQueue lock held, but with the callback
+    // lock held so we can ensure that callbacks occur in order
+    {
+        Mutex::Autolock lock(mCallbackMutex);
+        while (callbackTicket != mCurrentCallbackTicket) {
+            mCallbackCondition.wait(mCallbackMutex);
+        }
+
+        if (frameAvailableListener != NULL) {
+            frameAvailableListener->onFrameAvailable(item);
+        } else if (frameReplacedListener != NULL) {
+            frameReplacedListener->onFrameReplaced(item);
+        }
+
+        ++mCurrentCallbackTicket;
+        mCallbackCondition.broadcast();
     }
 
     return NO_ERROR;
@@ -682,10 +746,11 @@
         return;
     }
 
+    mCore->mFreeBuffers.push_front(slot);
     mSlots[slot].mBufferState = BufferSlot::FREE;
-    mSlots[slot].mFrameNumber = 0;
     mSlots[slot].mFence = fence;
     mCore->mDequeueCondition.broadcast();
+    mCore->validateConsistencyLocked();
 }
 
 int BufferQueueProducer::query(int what, int *outValue) {
@@ -725,6 +790,16 @@
         case NATIVE_WINDOW_CONSUMER_USAGE_BITS:
             value = static_cast<int32_t>(mCore->mConsumerUsageBits);
             break;
+        case NATIVE_WINDOW_DEFAULT_DATASPACE:
+            value = static_cast<int32_t>(mCore->mDefaultBufferDataSpace);
+            break;
+        case NATIVE_WINDOW_BUFFER_AGE:
+            if (mCore->mBufferAge > INT32_MAX) {
+                value = 0;
+            } else {
+                value = static_cast<int32_t>(mCore->mBufferAge);
+            }
+            break;
         default:
             return BAD_VALUE;
     }
@@ -887,6 +962,12 @@
             Mutex::Autolock lock(mCore->mMutex);
             mCore->waitWhileAllocatingLocked();
 
+            if (!mCore->mAllowAllocation) {
+                BQ_LOGE("allocateBuffers: allocation is not allowed for this "
+                        "BufferQueue");
+                return;
+            }
+
             int currentBufferCount = 0;
             for (int slot = 0; slot < BufferQueueDefs::NUM_BUFFER_SLOTS; ++slot) {
                 if (mSlots[slot].mGraphicBuffer != NULL) {
@@ -964,17 +1045,32 @@
                 }
                 mCore->freeBufferLocked(slot); // Clean up the slot first
                 mSlots[slot].mGraphicBuffer = buffers[i];
-                mSlots[slot].mFrameNumber = 0;
                 mSlots[slot].mFence = Fence::NO_FENCE;
+
+                // freeBufferLocked puts this slot on the free slots list. Since
+                // we then attached a buffer, move the slot to free buffer list.
+                mCore->mFreeSlots.erase(slot);
+                mCore->mFreeBuffers.push_front(slot);
+
                 BQ_LOGV("allocateBuffers: allocated a new buffer in slot %d", slot);
             }
 
             mCore->mIsAllocating = false;
             mCore->mIsAllocatingCondition.broadcast();
+            mCore->validateConsistencyLocked();
         } // Autolock scope
     }
 }
 
+status_t BufferQueueProducer::allowAllocation(bool allow) {
+    ATRACE_CALL();
+    BQ_LOGV("allowAllocation: %s", allow ? "true" : "false");
+
+    Mutex::Autolock lock(mCore->mMutex);
+    mCore->mAllowAllocation = allow;
+    return NO_ERROR;
+}
+
 void BufferQueueProducer::binderDied(const wp<android::IBinder>& /* who */) {
     // If we're here, it means that a producer we were connected to died.
     // We're guaranteed that we are still connected to it because we remove
diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp
index 580e0e7..e576018 100644
--- a/libs/gui/ConsumerBase.cpp
+++ b/libs/gui/ConsumerBase.cpp
@@ -27,6 +27,7 @@
 
 #include <hardware/hardware.h>
 
+#include <gui/BufferItem.h>
 #include <gui/IGraphicBufferAlloc.h>
 #include <gui/ISurfaceComposer.h>
 #include <gui/SurfaceComposerClient.h>
@@ -98,7 +99,7 @@
     mSlots[slotIndex].mFrameNumber = 0;
 }
 
-void ConsumerBase::onFrameAvailable() {
+void ConsumerBase::onFrameAvailable(const BufferItem& item) {
     CB_LOGV("onFrameAvailable");
 
     sp<FrameAvailableListener> listener;
@@ -109,7 +110,7 @@
 
     if (listener != NULL) {
         CB_LOGV("actually calling onFrameAvailable");
-        listener->onFrameAvailable();
+        listener->onFrameAvailable(item);
     }
 }
 
@@ -162,6 +163,21 @@
     mFrameAvailableListener = listener;
 }
 
+status_t ConsumerBase::detachBuffer(int slot) {
+    CB_LOGV("detachBuffer");
+    Mutex::Autolock lock(mMutex);
+
+    status_t result = mConsumer->detachBuffer(slot);
+    if (result != NO_ERROR) {
+        CB_LOGE("Failed to detach buffer: %d", result);
+        return result;
+    }
+
+    freeBufferLocked(slot);
+
+    return result;
+}
+
 void ConsumerBase::dump(String8& result) const {
     dump(result, "");
 }
@@ -179,7 +195,7 @@
     }
 }
 
-status_t ConsumerBase::acquireBufferLocked(BufferQueue::BufferItem *item,
+status_t ConsumerBase::acquireBufferLocked(BufferItem *item,
         nsecs_t presentWhen) {
     status_t err = mConsumer->acquireBuffer(item, presentWhen);
     if (err != NO_ERROR) {
diff --git a/libs/gui/CpuConsumer.cpp b/libs/gui/CpuConsumer.cpp
index d74d06c..eb39469 100644
--- a/libs/gui/CpuConsumer.cpp
+++ b/libs/gui/CpuConsumer.cpp
@@ -20,9 +20,10 @@
 
 #include <cutils/compiler.h>
 #include <utils/Log.h>
+#include <gui/BufferItem.h>
 #include <gui/CpuConsumer.h>
 
-//#define CC_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__)
+#define CC_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__)
 //#define CC_LOGD(x, ...) ALOGD("[%s] " x, mName.string(), ##__VA_ARGS__)
 //#define CC_LOGI(x, ...) ALOGI("[%s] " x, mName.string(), ##__VA_ARGS__)
 #define CC_LOGW(x, ...) ALOGW("[%s] " x, mName.string(), ##__VA_ARGS__)
@@ -67,6 +68,39 @@
     return mConsumer->setDefaultBufferFormat(defaultFormat);
 }
 
+status_t CpuConsumer::setDefaultBufferDataSpace(
+        android_dataspace defaultDataSpace)
+{
+    Mutex::Autolock _l(mMutex);
+    return mConsumer->setDefaultBufferDataSpace(defaultDataSpace);
+}
+
+static bool isPossiblyYUV(PixelFormat format) {
+    switch (static_cast<int>(format)) {
+        case HAL_PIXEL_FORMAT_RGBA_8888:
+        case HAL_PIXEL_FORMAT_RGBX_8888:
+        case HAL_PIXEL_FORMAT_RGB_888:
+        case HAL_PIXEL_FORMAT_RGB_565:
+        case HAL_PIXEL_FORMAT_BGRA_8888:
+        case HAL_PIXEL_FORMAT_Y8:
+        case HAL_PIXEL_FORMAT_Y16:
+        case HAL_PIXEL_FORMAT_RAW16:
+        case HAL_PIXEL_FORMAT_RAW10:
+        case HAL_PIXEL_FORMAT_RAW_OPAQUE:
+        case HAL_PIXEL_FORMAT_BLOB:
+        case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
+            return false;
+
+        case HAL_PIXEL_FORMAT_YV12:
+        case HAL_PIXEL_FORMAT_YCbCr_420_888:
+        case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+        case HAL_PIXEL_FORMAT_YCbCr_422_I:
+        default:
+            return true;
+    }
+}
+
 status_t CpuConsumer::lockNextBuffer(LockedBuffer *nativeBuffer) {
     status_t err;
 
@@ -77,7 +111,7 @@
         return NOT_ENOUGH_DATA;
     }
 
-    BufferQueue::BufferItem b;
+    BufferItem b;
 
     Mutex::Autolock _l(mMutex);
 
@@ -96,59 +130,51 @@
     void *bufferPointer = NULL;
     android_ycbcr ycbcr = android_ycbcr();
 
-    if (b.mFence.get()) {
-        if (mSlots[buf].mGraphicBuffer->getPixelFormat() ==
-                HAL_PIXEL_FORMAT_YCbCr_420_888) {
+    PixelFormat format = mSlots[buf].mGraphicBuffer->getPixelFormat();
+    PixelFormat flexFormat = format;
+    if (isPossiblyYUV(format)) {
+        if (b.mFence.get()) {
             err = mSlots[buf].mGraphicBuffer->lockAsyncYCbCr(
                 GraphicBuffer::USAGE_SW_READ_OFTEN,
                 b.mCrop,
                 &ycbcr,
                 b.mFence->dup());
-
-            if (err != OK) {
-                CC_LOGE("Unable to lock YCbCr buffer for CPU reading: %s (%d)",
-                        strerror(-err), err);
-                return err;
-            }
-            bufferPointer = ycbcr.y;
         } else {
+            err = mSlots[buf].mGraphicBuffer->lockYCbCr(
+                GraphicBuffer::USAGE_SW_READ_OFTEN,
+                b.mCrop,
+                &ycbcr);
+        }
+        if (err == OK) {
+            bufferPointer = ycbcr.y;
+            flexFormat = HAL_PIXEL_FORMAT_YCbCr_420_888;
+            if (format != HAL_PIXEL_FORMAT_YCbCr_420_888) {
+                CC_LOGV("locking buffer of format %#x as flex YUV", format);
+            }
+        } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+            CC_LOGE("Unable to lock YCbCr buffer for CPU reading: %s (%d)",
+                    strerror(-err), err);
+            return err;
+        }
+    }
+
+    if (bufferPointer == NULL) { // not flexible YUV
+        if (b.mFence.get()) {
             err = mSlots[buf].mGraphicBuffer->lockAsync(
                 GraphicBuffer::USAGE_SW_READ_OFTEN,
                 b.mCrop,
                 &bufferPointer,
                 b.mFence->dup());
-
-            if (err != OK) {
-                CC_LOGE("Unable to lock buffer for CPU reading: %s (%d)",
-                        strerror(-err), err);
-                return err;
-            }
-        }
-    } else {
-        if (mSlots[buf].mGraphicBuffer->getPixelFormat() ==
-                HAL_PIXEL_FORMAT_YCbCr_420_888) {
-            err = mSlots[buf].mGraphicBuffer->lockYCbCr(
-                GraphicBuffer::USAGE_SW_READ_OFTEN,
-                b.mCrop,
-                &ycbcr);
-
-            if (err != OK) {
-                CC_LOGE("Unable to lock YCbCr buffer for CPU reading: %s (%d)",
-                        strerror(-err), err);
-                return err;
-            }
-            bufferPointer = ycbcr.y;
         } else {
             err = mSlots[buf].mGraphicBuffer->lock(
                 GraphicBuffer::USAGE_SW_READ_OFTEN,
                 b.mCrop,
                 &bufferPointer);
-
-            if (err != OK) {
-                CC_LOGE("Unable to lock buffer for CPU reading: %s (%d)",
-                        strerror(-err), err);
-                return err;
-            }
+        }
+        if (err != OK) {
+            CC_LOGE("Unable to lock buffer for CPU reading: %s (%d)",
+                    strerror(-err), err);
+            return err;
         }
     }
 
@@ -170,7 +196,8 @@
             reinterpret_cast<uint8_t*>(bufferPointer);
     nativeBuffer->width  = mSlots[buf].mGraphicBuffer->getWidth();
     nativeBuffer->height = mSlots[buf].mGraphicBuffer->getHeight();
-    nativeBuffer->format = mSlots[buf].mGraphicBuffer->getPixelFormat();
+    nativeBuffer->format = format;
+    nativeBuffer->flexFormat = flexFormat;
     nativeBuffer->stride = (ycbcr.y != NULL) ?
             static_cast<uint32_t>(ycbcr.ystride) :
             mSlots[buf].mGraphicBuffer->getStride();
@@ -179,6 +206,7 @@
     nativeBuffer->transform   = b.mTransform;
     nativeBuffer->scalingMode = b.mScalingMode;
     nativeBuffer->timestamp   = b.mTimestamp;
+    nativeBuffer->dataSpace   = b.mDataSpace;
     nativeBuffer->frameNumber = b.mFrameNumber;
 
     nativeBuffer->dataCb       = reinterpret_cast<uint8_t*>(ycbcr.cb);
diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp
index 936ad53..96c0841 100644
--- a/libs/gui/GLConsumer.cpp
+++ b/libs/gui/GLConsumer.cpp
@@ -29,6 +29,7 @@
 
 #include <hardware/hardware.h>
 
+#include <gui/BufferItem.h>
 #include <gui/GLConsumer.h>
 #include <gui/IGraphicBufferAlloc.h>
 #include <gui/ISurfaceComposer.h>
@@ -210,7 +211,7 @@
         return err;
     }
 
-    BufferQueue::BufferItem item;
+    BufferItem item;
 
     // Acquire the next buffer.
     // In asynchronous mode the list is guaranteed to be one buffer
@@ -342,7 +343,7 @@
     return sReleasedTexImageBuffer;
 }
 
-status_t GLConsumer::acquireBufferLocked(BufferQueue::BufferItem *item,
+status_t GLConsumer::acquireBufferLocked(BufferItem *item,
         nsecs_t presentWhen) {
     status_t err = ConsumerBase::acquireBufferLocked(item, presentWhen);
     if (err != NO_ERROR) {
@@ -373,7 +374,7 @@
     return err;
 }
 
-status_t GLConsumer::updateAndReleaseLocked(const BufferQueue::BufferItem& item)
+status_t GLConsumer::updateAndReleaseLocked(const BufferItem& item)
 {
     status_t err = NO_ERROR;
 
@@ -516,7 +517,7 @@
         if (mEglDisplay == EGL_NO_DISPLAY) {
             mEglDisplay = dpy;
         }
-        if (mEglContext == EGL_NO_DISPLAY) {
+        if (mEglContext == EGL_NO_CONTEXT) {
             mEglContext = ctx;
         }
     }
@@ -899,14 +900,14 @@
 
         // The crop is too wide
         if (newWidth < currentWidth) {
-            uint32_t dw = (newWidth - currentWidth) / 2;
-            outCrop.left -=dw;
-            outCrop.right += dw;
+            uint32_t dw = (currentWidth - newWidth) / 2;
+            outCrop.left += dw;
+            outCrop.right -= dw;
         // The crop is too tall
         } else if (newHeight < currentHeight) {
-            uint32_t dh = (newHeight - currentHeight) / 2;
-            outCrop.top -= dh;
-            outCrop.bottom += dh;
+            uint32_t dh = (currentHeight - newHeight) / 2;
+            outCrop.top += dh;
+            outCrop.bottom -= dh;
         }
 
         GLC_LOGV("getCurrentCrop final crop [%d,%d,%d,%d]",
@@ -1023,6 +1024,12 @@
     return mConsumer->setDefaultBufferFormat(defaultFormat);
 }
 
+status_t GLConsumer::setDefaultBufferDataSpace(
+        android_dataspace defaultDataSpace) {
+    Mutex::Autolock lock(mMutex);
+    return mConsumer->setDefaultBufferDataSpace(defaultDataSpace);
+}
+
 status_t GLConsumer::setConsumerUsageBits(uint32_t usage) {
     Mutex::Autolock lock(mMutex);
     usage |= DEFAULT_USAGE_FLAGS;
@@ -1079,6 +1086,7 @@
         if (!eglDestroyImageKHR(mEglDisplay, mEglImage)) {
            ALOGE("~EglImage: eglDestroyImageKHR failed");
         }
+        eglTerminate(mEglDisplay);
     }
 }
 
@@ -1093,6 +1101,7 @@
         if (!eglDestroyImageKHR(mEglDisplay, mEglImage)) {
            ALOGE("createIfNeeded: eglDestroyImageKHR failed");
         }
+        eglTerminate(mEglDisplay);
         mEglImage = EGL_NO_IMAGE_KHR;
         mEglDisplay = EGL_NO_DISPLAY;
     }
@@ -1145,11 +1154,13 @@
         // removes this restriction if there is hardware that can support it.
         attrs[2] = EGL_NONE;
     }
+    eglInitialize(dpy, 0, 0);
     EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT,
             EGL_NATIVE_BUFFER_ANDROID, cbuf, attrs);
     if (image == EGL_NO_IMAGE_KHR) {
         EGLint error = eglGetError();
         ALOGE("error creating EGLImage: %#x", error);
+        eglTerminate(dpy);
     }
     return image;
 }
diff --git a/libs/gui/IConsumerListener.cpp b/libs/gui/IConsumerListener.cpp
index 32d7920..cab7dc3 100644
--- a/libs/gui/IConsumerListener.cpp
+++ b/libs/gui/IConsumerListener.cpp
@@ -21,6 +21,7 @@
 #include <binder/Parcel.h>
 
 #include <gui/IConsumerListener.h>
+#include <gui/BufferItem.h>
 
 // ---------------------------------------------------------------------------
 namespace android {
@@ -41,9 +42,10 @@
 
     virtual ~BpConsumerListener();
 
-    virtual void onFrameAvailable() {
+    virtual void onFrameAvailable(const BufferItem& item) {
         Parcel data, reply;
         data.writeInterfaceToken(IConsumerListener::getInterfaceDescriptor());
+        data.write(item);
         remote()->transact(ON_FRAME_AVAILABLE, data, &reply, IBinder::FLAG_ONEWAY);
     }
 
@@ -72,18 +74,20 @@
     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
 {
     switch(code) {
-        case ON_FRAME_AVAILABLE:
+        case ON_FRAME_AVAILABLE: {
             CHECK_INTERFACE(IConsumerListener, data, reply);
-            onFrameAvailable();
-            return NO_ERROR;
-        case ON_BUFFER_RELEASED:
+            BufferItem item;
+            data.read(item);
+            onFrameAvailable(item);
+            return NO_ERROR; }
+        case ON_BUFFER_RELEASED: {
             CHECK_INTERFACE(IConsumerListener, data, reply);
             onBuffersReleased();
-            return NO_ERROR;
-        case ON_SIDEBAND_STREAM_CHANGED:
+            return NO_ERROR; }
+        case ON_SIDEBAND_STREAM_CHANGED: {
             CHECK_INTERFACE(IConsumerListener, data, reply);
             onSidebandStreamChanged();
-            return NO_ERROR;
+            return NO_ERROR; }
     }
     return BBinder::onTransact(code, data, reply, flags);
 }
diff --git a/libs/gui/IGraphicBufferConsumer.cpp b/libs/gui/IGraphicBufferConsumer.cpp
index 2602884..480dfb6 100644
--- a/libs/gui/IGraphicBufferConsumer.cpp
+++ b/libs/gui/IGraphicBufferConsumer.cpp
@@ -23,6 +23,7 @@
 #include <binder/Parcel.h>
 #include <binder/IInterface.h>
 
+#include <gui/BufferItem.h>
 #include <gui/IConsumerListener.h>
 #include <gui/IGraphicBufferConsumer.h>
 
@@ -32,159 +33,6 @@
 #include <system/window.h>
 
 namespace android {
-// ---------------------------------------------------------------------------
-
-IGraphicBufferConsumer::BufferItem::BufferItem() :
-    mTransform(0),
-    mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
-    mTimestamp(0),
-    mIsAutoTimestamp(false),
-    mFrameNumber(0),
-    mBuf(INVALID_BUFFER_SLOT),
-    mIsDroppable(false),
-    mAcquireCalled(false),
-    mTransformToDisplayInverse(false) {
-    mCrop.makeInvalid();
-}
-
-size_t IGraphicBufferConsumer::BufferItem::getPodSize() const {
-    size_t c =  sizeof(mCrop) +
-            sizeof(mTransform) +
-            sizeof(mScalingMode) +
-            sizeof(mTimestamp) +
-            sizeof(mIsAutoTimestamp) +
-            sizeof(mFrameNumber) +
-            sizeof(mBuf) +
-            sizeof(mIsDroppable) +
-            sizeof(mAcquireCalled) +
-            sizeof(mTransformToDisplayInverse);
-    return c;
-}
-
-size_t IGraphicBufferConsumer::BufferItem::getFlattenedSize() const {
-    size_t c = 0;
-    if (mGraphicBuffer != 0) {
-        c += mGraphicBuffer->getFlattenedSize();
-        c = FlattenableUtils::align<4>(c);
-    }
-    if (mFence != 0) {
-        c += mFence->getFlattenedSize();
-        c = FlattenableUtils::align<4>(c);
-    }
-    return sizeof(int32_t) + c + getPodSize();
-}
-
-size_t IGraphicBufferConsumer::BufferItem::getFdCount() const {
-    size_t c = 0;
-    if (mGraphicBuffer != 0) {
-        c += mGraphicBuffer->getFdCount();
-    }
-    if (mFence != 0) {
-        c += mFence->getFdCount();
-    }
-    return c;
-}
-
-static void writeBoolAsInt(void*& buffer, size_t& size, bool b) {
-    FlattenableUtils::write(buffer, size, static_cast<int32_t>(b));
-}
-
-static bool readBoolFromInt(void const*& buffer, size_t& size) {
-    int32_t i;
-    FlattenableUtils::read(buffer, size, i);
-    return static_cast<bool>(i);
-}
-
-status_t IGraphicBufferConsumer::BufferItem::flatten(
-        void*& buffer, size_t& size, int*& fds, size_t& count) const {
-
-    // make sure we have enough space
-    if (size < BufferItem::getFlattenedSize()) {
-        return NO_MEMORY;
-    }
-
-    // content flags are stored first
-    uint32_t& flags = *static_cast<uint32_t*>(buffer);
-
-    // advance the pointer
-    FlattenableUtils::advance(buffer, size, sizeof(uint32_t));
-
-    flags = 0;
-    if (mGraphicBuffer != 0) {
-        status_t err = mGraphicBuffer->flatten(buffer, size, fds, count);
-        if (err) return err;
-        size -= FlattenableUtils::align<4>(buffer);
-        flags |= 1;
-    }
-    if (mFence != 0) {
-        status_t err = mFence->flatten(buffer, size, fds, count);
-        if (err) return err;
-        size -= FlattenableUtils::align<4>(buffer);
-        flags |= 2;
-    }
-
-    // check we have enough space (in case flattening the fence/graphicbuffer lied to us)
-    if (size < getPodSize()) {
-        return NO_MEMORY;
-    }
-
-    FlattenableUtils::write(buffer, size, mCrop);
-    FlattenableUtils::write(buffer, size, mTransform);
-    FlattenableUtils::write(buffer, size, mScalingMode);
-    FlattenableUtils::write(buffer, size, mTimestamp);
-    writeBoolAsInt(buffer, size, mIsAutoTimestamp);
-    FlattenableUtils::write(buffer, size, mFrameNumber);
-    FlattenableUtils::write(buffer, size, mBuf);
-    writeBoolAsInt(buffer, size, mIsDroppable);
-    writeBoolAsInt(buffer, size, mAcquireCalled);
-    writeBoolAsInt(buffer, size, mTransformToDisplayInverse);
-
-    return NO_ERROR;
-}
-
-status_t IGraphicBufferConsumer::BufferItem::unflatten(
-        void const*& buffer, size_t& size, int const*& fds, size_t& count) {
-
-    if (size < sizeof(uint32_t))
-        return NO_MEMORY;
-
-    uint32_t flags = 0;
-    FlattenableUtils::read(buffer, size, flags);
-
-    if (flags & 1) {
-        mGraphicBuffer = new GraphicBuffer();
-        status_t err = mGraphicBuffer->unflatten(buffer, size, fds, count);
-        if (err) return err;
-        size -= FlattenableUtils::align<4>(buffer);
-    }
-
-    if (flags & 2) {
-        mFence = new Fence();
-        status_t err = mFence->unflatten(buffer, size, fds, count);
-        if (err) return err;
-        size -= FlattenableUtils::align<4>(buffer);
-    }
-
-    // check we have enough space
-    if (size < getPodSize()) {
-        return NO_MEMORY;
-    }
-
-    FlattenableUtils::read(buffer, size, mCrop);
-    FlattenableUtils::read(buffer, size, mTransform);
-    FlattenableUtils::read(buffer, size, mScalingMode);
-    FlattenableUtils::read(buffer, size, mTimestamp);
-    mIsAutoTimestamp = readBoolFromInt(buffer, size);
-    FlattenableUtils::read(buffer, size, mFrameNumber);
-    FlattenableUtils::read(buffer, size, mBuf);
-    mIsDroppable = readBoolFromInt(buffer, size);
-    mAcquireCalled = readBoolFromInt(buffer, size);
-    mTransformToDisplayInverse = readBoolFromInt(buffer, size);
-
-    return NO_ERROR;
-}
-
-// ---------------------------------------------------------------------------
 
 enum {
     ACQUIRE_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
@@ -200,9 +48,11 @@
     SET_MAX_ACQUIRED_BUFFER_COUNT,
     SET_CONSUMER_NAME,
     SET_DEFAULT_BUFFER_FORMAT,
+    SET_DEFAULT_BUFFER_DATA_SPACE,
     SET_CONSUMER_USAGE_BITS,
     SET_TRANSFORM_HINT,
     GET_SIDEBAND_STREAM,
+    SET_SHADOW_QUEUE_SIZE,
     DUMP,
 };
 
@@ -371,6 +221,19 @@
         return reply.readInt32();
     }
 
+    virtual status_t setDefaultBufferDataSpace(
+            android_dataspace defaultDataSpace) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
+        data.writeInt32(static_cast<int32_t>(defaultDataSpace));
+        status_t result = remote()->transact(SET_DEFAULT_BUFFER_DATA_SPACE,
+                data, &reply);
+        if (result != NO_ERROR) {
+            return result;
+        }
+        return reply.readInt32();
+    }
+
     virtual status_t setConsumerUsageBits(uint32_t usage) {
         Parcel data, reply;
         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
@@ -407,6 +270,17 @@
         return stream;
     }
 
+    virtual void setShadowQueueSize(size_t size) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
+        data.writeInt64(static_cast<int64_t>(size));
+        status_t result = remote()->transact(SET_SHADOW_QUEUE_SIZE, data, &reply);
+        if (result != NO_ERROR) {
+            ALOGE("setShadowQueueSize failed (%d)", result);
+            return;
+        }
+    }
+
     virtual void dump(String8& result, const char* prefix) const {
         Parcel data, reply;
         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
@@ -530,6 +404,14 @@
             reply->writeInt32(result);
             return NO_ERROR;
         }
+        case SET_DEFAULT_BUFFER_DATA_SPACE: {
+            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
+            android_dataspace defaultDataSpace =
+                    static_cast<android_dataspace>(data.readInt32());
+            status_t result = setDefaultBufferDataSpace(defaultDataSpace);
+            reply->writeInt32(result);
+            return NO_ERROR;
+        }
         case SET_CONSUMER_USAGE_BITS: {
             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
             uint32_t usage = data.readUint32();
@@ -544,6 +426,21 @@
             reply->writeInt32(result);
             return NO_ERROR;
         }
+        case GET_SIDEBAND_STREAM: {
+            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
+            sp<NativeHandle> stream = getSidebandStream();
+            reply->writeInt32(static_cast<int32_t>(stream != NULL));
+            if (stream != NULL) {
+                reply->writeNativeHandle(stream->handle());
+            }
+            return NO_ERROR;
+        }
+        case SET_SHADOW_QUEUE_SIZE: {
+            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
+            size_t size = static_cast<size_t>(data.readInt64());
+            setShadowQueueSize(size);
+            return NO_ERROR;
+        }
         case DUMP: {
             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
             String8 result = data.readString8();
diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp
index 63d881e..7093ffa 100644
--- a/libs/gui/IGraphicBufferProducer.cpp
+++ b/libs/gui/IGraphicBufferProducer.cpp
@@ -46,6 +46,7 @@
     DISCONNECT,
     SET_SIDEBAND_STREAM,
     ALLOCATE_BUFFERS,
+    ALLOW_ALLOCATION,
 };
 
 class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer>
@@ -271,6 +272,18 @@
             ALOGE("allocateBuffers failed to transact: %d", result);
         }
     }
+
+    virtual status_t allowAllocation(bool allow) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
+        data.writeInt32(static_cast<int32_t>(allow));
+        status_t result = remote()->transact(ALLOW_ALLOCATION, data, &reply);
+        if (result != NO_ERROR) {
+            return result;
+        }
+        result = reply.readInt32();
+        return result;
+    }
 };
 
 // Out-of-line virtual method definition to trigger vtable emission in this
@@ -418,7 +431,7 @@
             reply->writeInt32(result);
             return NO_ERROR;
         }
-        case ALLOCATE_BUFFERS:
+        case ALLOCATE_BUFFERS: {
             CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
             bool async = static_cast<bool>(data.readInt32());
             uint32_t width = data.readUint32();
@@ -427,6 +440,14 @@
             uint32_t usage = data.readUint32();
             allocateBuffers(async, width, height, format, usage);
             return NO_ERROR;
+        }
+        case ALLOW_ALLOCATION: {
+            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
+            bool allow = static_cast<bool>(data.readInt32());
+            status_t result = allowAllocation(allow);
+            reply->writeInt32(result);
+            return NO_ERROR;
+        }
     }
     return BBinder::onTransact(code, data, reply, flags);
 }
@@ -440,12 +461,14 @@
 size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const {
     return sizeof(timestamp)
          + sizeof(isAutoTimestamp)
+         + sizeof(dataSpace)
          + sizeof(crop)
          + sizeof(scalingMode)
          + sizeof(transform)
          + sizeof(stickyTransform)
          + sizeof(async)
-         + fence->getFlattenedSize();
+         + fence->getFlattenedSize()
+         + surfaceDamage.getFlattenedSize();
 }
 
 size_t IGraphicBufferProducer::QueueBufferInput::getFdCount() const {
@@ -460,12 +483,17 @@
     }
     FlattenableUtils::write(buffer, size, timestamp);
     FlattenableUtils::write(buffer, size, isAutoTimestamp);
+    FlattenableUtils::write(buffer, size, dataSpace);
     FlattenableUtils::write(buffer, size, crop);
     FlattenableUtils::write(buffer, size, scalingMode);
     FlattenableUtils::write(buffer, size, transform);
     FlattenableUtils::write(buffer, size, stickyTransform);
     FlattenableUtils::write(buffer, size, async);
-    return fence->flatten(buffer, size, fds, count);
+    status_t result = fence->flatten(buffer, size, fds, count);
+    if (result != NO_ERROR) {
+        return result;
+    }
+    return surfaceDamage.flatten(buffer, size);
 }
 
 status_t IGraphicBufferProducer::QueueBufferInput::unflatten(
@@ -474,6 +502,7 @@
     size_t minNeeded =
               sizeof(timestamp)
             + sizeof(isAutoTimestamp)
+            + sizeof(dataSpace)
             + sizeof(crop)
             + sizeof(scalingMode)
             + sizeof(transform)
@@ -486,6 +515,7 @@
 
     FlattenableUtils::read(buffer, size, timestamp);
     FlattenableUtils::read(buffer, size, isAutoTimestamp);
+    FlattenableUtils::read(buffer, size, dataSpace);
     FlattenableUtils::read(buffer, size, crop);
     FlattenableUtils::read(buffer, size, scalingMode);
     FlattenableUtils::read(buffer, size, transform);
@@ -493,7 +523,11 @@
     FlattenableUtils::read(buffer, size, async);
 
     fence = new Fence();
-    return fence->unflatten(buffer, size, fds, count);
+    status_t result = fence->unflatten(buffer, size, fds, count);
+    if (result != NO_ERROR) {
+        return result;
+    }
+    return surfaceDamage.unflatten(buffer, size);
 }
 
 }; // namespace android
diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp
index 8d38eef..35661f2 100644
--- a/libs/gui/Sensor.cpp
+++ b/libs/gui/Sensor.cpp
@@ -204,6 +204,13 @@
             mFlags |= SENSOR_FLAG_WAKE_UP;
         }
         break;
+    case SENSOR_TYPE_WRIST_TILT_GESTURE:
+        mStringType = SENSOR_STRING_TYPE_WRIST_TILT_GESTURE;
+        mFlags |= SENSOR_FLAG_SPECIAL_REPORTING_MODE;
+        if (halVersion < SENSORS_DEVICE_API_VERSION_1_3) {
+            mFlags |= SENSOR_FLAG_WAKE_UP;
+        }
+        break;
     default:
         // Only pipe the stringType, requiredPermission and flags for custom sensors.
         if (halVersion > SENSORS_DEVICE_API_VERSION_1_0 && hwSensor->stringType) {
diff --git a/libs/gui/StreamSplitter.cpp b/libs/gui/StreamSplitter.cpp
index 4a1f9e0..43f9214 100644
--- a/libs/gui/StreamSplitter.cpp
+++ b/libs/gui/StreamSplitter.cpp
@@ -20,6 +20,7 @@
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 //#define LOG_NDEBUG 0
 
+#include <gui/BufferItem.h>
 #include <gui/IGraphicBufferConsumer.h>
 #include <gui/IGraphicBufferProducer.h>
 #include <gui/StreamSplitter.h>
@@ -98,7 +99,7 @@
     mInput->setConsumerName(name);
 }
 
-void StreamSplitter::onFrameAvailable() {
+void StreamSplitter::onFrameAvailable(const BufferItem& /* item */) {
     ATRACE_CALL();
     Mutex::Autolock lock(mMutex);
 
@@ -123,7 +124,7 @@
     ++mOutstandingBuffers;
 
     // Acquire and detach the buffer from the input
-    IGraphicBufferConsumer::BufferItem bufferItem;
+    BufferItem bufferItem;
     status_t status = mInput->acquireBuffer(&bufferItem, /* presentWhen */ 0);
     LOG_ALWAYS_FATAL_IF(status != NO_ERROR,
             "acquiring buffer from input failed (%d)", status);
@@ -141,7 +142,8 @@
 
     IGraphicBufferProducer::QueueBufferInput queueInput(
             bufferItem.mTimestamp, bufferItem.mIsAutoTimestamp,
-            bufferItem.mCrop, static_cast<int32_t>(bufferItem.mScalingMode),
+            bufferItem.mDataSpace, bufferItem.mCrop,
+            static_cast<int32_t>(bufferItem.mScalingMode),
             bufferItem.mTransform, bufferItem.mIsDroppable,
             bufferItem.mFence);
 
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index aa4aee4..35aa7c7 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -27,6 +27,7 @@
 #include <utils/NativeHandle.h>
 
 #include <ui/Fence.h>
+#include <ui/Region.h>
 
 #include <gui/IProducerListener.h>
 #include <gui/ISurfaceComposer.h>
@@ -64,6 +65,7 @@
     mReqFormat = 0;
     mReqUsage = 0;
     mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
+    mDataSpace = HAL_DATASPACE_UNKNOWN;
     mCrop.clear();
     mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
     mTransform = 0;
@@ -265,6 +267,9 @@
     Mutex::Autolock lock(mMutex);
     int i = getSlotFromBufferLocked(buffer);
     if (i < 0) {
+        if (fenceFd >= 0) {
+            close(fenceFd);
+        }
         return i;
     }
     sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
@@ -306,6 +311,9 @@
     }
     int i = getSlotFromBufferLocked(buffer);
     if (i < 0) {
+        if (fenceFd >= 0) {
+            close(fenceFd);
+        }
         return i;
     }
 
@@ -317,8 +325,27 @@
     sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
     IGraphicBufferProducer::QueueBufferOutput output;
     IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp,
-            crop, mScalingMode, mTransform ^ mStickyTransform, mSwapIntervalZero,
-            fence, mStickyTransform);
+            mDataSpace, crop, mScalingMode, mTransform ^ mStickyTransform,
+            mSwapIntervalZero, fence, mStickyTransform);
+
+    if (mConnectedToCpu || mDirtyRegion.bounds() == Rect::INVALID_RECT) {
+        input.setSurfaceDamage(Region::INVALID_REGION);
+    } else {
+        // The surface damage was specified using the OpenGL ES convention of
+        // the origin being in the bottom-left corner. Here we flip to the
+        // convention that the rest of the system uses (top-left corner) by
+        // subtracting all top/bottom coordinates from the buffer height.
+        Region flippedRegion;
+        for (auto rect : mDirtyRegion) {
+            auto top = buffer->height - rect.bottom;
+            auto bottom = buffer->height - rect.top;
+            Rect flippedRect{rect.left, top, rect.right, bottom};
+            flippedRegion.orSelf(flippedRect);
+        }
+
+        input.setSurfaceDamage(flippedRegion);
+    }
+
     status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
     if (err != OK)  {
         ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);
@@ -335,6 +362,11 @@
 
     mConsumerRunningBehind = (numPendingBuffers >= 2);
 
+    if (!mConnectedToCpu) {
+        // Clear surface damage back to full-buffer
+        mDirtyRegion = Region::INVALID_REGION;
+    }
+
     return err;
 }
 
@@ -449,6 +481,12 @@
     case NATIVE_WINDOW_SET_SIDEBAND_STREAM:
         res = dispatchSetSidebandStream(args);
         break;
+    case NATIVE_WINDOW_SET_BUFFERS_DATASPACE:
+        res = dispatchSetBuffersDataSpace(args);
+        break;
+    case NATIVE_WINDOW_SET_SURFACE_DAMAGE:
+        res = dispatchSetSurfaceDamage(args);
+        break;
     default:
         res = NAME_NOT_FOUND;
         break;
@@ -546,10 +584,27 @@
     return OK;
 }
 
+int Surface::dispatchSetBuffersDataSpace(va_list args) {
+    android_dataspace dataspace =
+            static_cast<android_dataspace>(va_arg(args, int));
+    return setBuffersDataSpace(dataspace);
+}
+
+int Surface::dispatchSetSurfaceDamage(va_list args) {
+    android_native_rect_t* rects = va_arg(args, android_native_rect_t*);
+    size_t numRects = va_arg(args, size_t);
+    setSurfaceDamage(rects, numRects);
+    return NO_ERROR;
+}
+
 int Surface::connect(int api) {
+    static sp<IProducerListener> listener = new DummyProducerListener();
+    return connect(api, listener);
+}
+
+int Surface::connect(int api, const sp<IProducerListener>& listener) {
     ATRACE_CALL();
     ALOGV("Surface::connect");
-    static sp<IProducerListener> listener = new DummyProducerListener();
     Mutex::Autolock lock(mMutex);
     IGraphicBufferProducer::QueueBufferOutput output;
     int err = mGraphicBufferProducer->connect(listener, api, mProducerControlledByApp, &output);
@@ -568,7 +623,13 @@
     }
     if (!err && api == NATIVE_WINDOW_API_CPU) {
         mConnectedToCpu = true;
+        // Clear the dirty region in case we're switching from a non-CPU API
+        mDirtyRegion.clear();
+    } else if (!err) {
+        // Initialize the dirty region for tracking surface damage
+        mDirtyRegion = Region::INVALID_REGION;
     }
+
     return err;
 }
 
@@ -596,6 +657,55 @@
     return err;
 }
 
+int Surface::detachNextBuffer(sp<GraphicBuffer>* outBuffer,
+        sp<Fence>* outFence) {
+    ATRACE_CALL();
+    ALOGV("Surface::detachNextBuffer");
+
+    if (outBuffer == NULL || outFence == NULL) {
+        return BAD_VALUE;
+    }
+
+    Mutex::Autolock lock(mMutex);
+
+    sp<GraphicBuffer> buffer(NULL);
+    sp<Fence> fence(NULL);
+    status_t result = mGraphicBufferProducer->detachNextBuffer(
+            &buffer, &fence);
+    if (result != NO_ERROR) {
+        return result;
+    }
+
+    *outBuffer = buffer;
+    if (fence != NULL && fence->isValid()) {
+        *outFence = fence;
+    } else {
+        *outFence = Fence::NO_FENCE;
+    }
+
+    return NO_ERROR;
+}
+
+int Surface::attachBuffer(ANativeWindowBuffer* buffer)
+{
+    ATRACE_CALL();
+    ALOGV("Surface::attachBuffer");
+
+    Mutex::Autolock lock(mMutex);
+
+    sp<GraphicBuffer> graphicBuffer(static_cast<GraphicBuffer*>(buffer));
+    int32_t attachedSlot = -1;
+    status_t result = mGraphicBufferProducer->attachBuffer(
+            &attachedSlot, graphicBuffer);
+    if (result != NO_ERROR) {
+        ALOGE("attachBuffer: IGraphicBufferProducer call failed (%d)", result);
+        return result;
+    }
+    mSlots[attachedSlot].buffer = graphicBuffer;
+
+    return NO_ERROR;
+}
+
 int Surface::setUsage(uint32_t reqUsage)
 {
     ALOGV("Surface::setUsage");
@@ -723,12 +833,41 @@
     return NO_ERROR;
 }
 
+int Surface::setBuffersDataSpace(android_dataspace dataSpace)
+{
+    ALOGV("Surface::setBuffersDataSpace");
+    Mutex::Autolock lock(mMutex);
+    mDataSpace = dataSpace;
+    return NO_ERROR;
+}
+
 void Surface::freeAllBuffers() {
     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
         mSlots[i].buffer = 0;
     }
 }
 
+void Surface::setSurfaceDamage(android_native_rect_t* rects, size_t numRects) {
+    ATRACE_CALL();
+    ALOGV("Surface::setSurfaceDamage");
+    Mutex::Autolock lock(mMutex);
+
+    if (mConnectedToCpu || numRects == 0) {
+        mDirtyRegion = Region::INVALID_REGION;
+        return;
+    }
+
+    mDirtyRegion.clear();
+    for (size_t r = 0; r < numRects; ++r) {
+        // We intentionally flip top and bottom here, since because they're
+        // specified with a bottom-left origin, top > bottom, which fails
+        // validation in the Region class. We will fix this up when we flip to a
+        // top-left origin in queueBuffer.
+        Rect rect(rects[r].left, rects[r].bottom, rects[r].right, rects[r].top);
+        mDirtyRegion.orSelf(rect);
+    }
+}
+
 // ----------------------------------------------------------------------
 // the lock/unlock APIs must be used from the same thread
 
diff --git a/libs/gui/tests/Android.mk b/libs/gui/tests/Android.mk
index 128a32a..6ad9986 100644
--- a/libs/gui/tests/Android.mk
+++ b/libs/gui/tests/Android.mk
@@ -3,6 +3,8 @@
 include $(CLEAR_VARS)
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 
+LOCAL_CLANG := true
+
 LOCAL_MODULE := libgui_test
 
 LOCAL_MODULE_TAGS := tests
diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp
index 5cccc9b..1584fef 100644
--- a/libs/gui/tests/BufferQueue_test.cpp
+++ b/libs/gui/tests/BufferQueue_test.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "BufferQueue_test"
 //#define LOG_NDEBUG 0
 
+#include <gui/BufferItem.h>
 #include <gui/BufferQueue.h>
 #include <gui/IProducerListener.h>
 
@@ -67,11 +68,13 @@
 };
 
 struct DummyConsumer : public BnConsumerListener {
-    virtual void onFrameAvailable() {}
+    virtual void onFrameAvailable(const BufferItem& /* item */) {}
     virtual void onBuffersReleased() {}
     virtual void onSidebandStreamChanged() {}
 };
 
+static const uint32_t TEST_DATA = 0x12345678u;
+
 // XXX: Tests that fork a process to hold the BufferQueue must run before tests
 // that use a local BufferQueue, or else Binder will get unhappy
 TEST_F(BufferQueueTest, BufferQueueInAnotherProcess) {
@@ -121,20 +124,21 @@
     uint32_t* dataIn;
     ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
             reinterpret_cast<void**>(&dataIn)));
-    *dataIn = 0x12345678;
+    *dataIn = TEST_DATA;
     ASSERT_EQ(OK, buffer->unlock());
 
-    IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1),
+    IGraphicBufferProducer::QueueBufferInput input(0, false,
+            HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
 
-    IGraphicBufferConsumer::BufferItem item;
+    BufferItem item;
     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
 
     uint32_t* dataOut;
     ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
             reinterpret_cast<void**>(&dataOut)));
-    ASSERT_EQ(*dataOut, 0x12345678);
+    ASSERT_EQ(*dataOut, TEST_DATA);
     ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
 }
 
@@ -150,9 +154,10 @@
     int slot;
     sp<Fence> fence;
     sp<GraphicBuffer> buf;
-    IGraphicBufferProducer::QueueBufferInput qbi(0, false, Rect(0, 0, 1, 1),
+    IGraphicBufferProducer::QueueBufferInput qbi(0, false,
+            HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
-    BufferQueue::BufferItem item;
+    BufferItem item;
 
     for (int i = 0; i < 2; i++) {
         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
@@ -236,7 +241,7 @@
     uint32_t* dataIn;
     ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
             reinterpret_cast<void**>(&dataIn)));
-    *dataIn = 0x12345678;
+    *dataIn = TEST_DATA;
     ASSERT_EQ(OK, buffer->unlock());
 
     int newSlot;
@@ -244,17 +249,18 @@
     ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(&newSlot, NULL));
 
     ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, buffer));
-    IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1),
+    IGraphicBufferProducer::QueueBufferInput input(0, false,
+            HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
     ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output));
 
-    IGraphicBufferConsumer::BufferItem item;
+    BufferItem item;
     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
 
     uint32_t* dataOut;
     ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
             reinterpret_cast<void**>(&dataOut)));
-    ASSERT_EQ(*dataOut, 0x12345678);
+    ASSERT_EQ(*dataOut, TEST_DATA);
     ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
 }
 
@@ -273,7 +279,8 @@
             mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
                     GRALLOC_USAGE_SW_WRITE_OFTEN));
     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
-    IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1),
+    IGraphicBufferProducer::QueueBufferInput input(0, false,
+            HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
 
@@ -282,7 +289,7 @@
             BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high
     ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(0)); // Not acquired
 
-    IGraphicBufferConsumer::BufferItem item;
+    BufferItem item;
     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
 
     ASSERT_EQ(OK, mConsumer->detachBuffer(item.mBuf));
@@ -292,7 +299,7 @@
     ASSERT_EQ(OK, item.mGraphicBuffer->lock(
             GraphicBuffer::USAGE_SW_WRITE_OFTEN,
             reinterpret_cast<void**>(&dataIn)));
-    *dataIn = 0x12345678;
+    *dataIn = TEST_DATA;
     ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
 
     int newSlot;
@@ -312,7 +319,7 @@
     uint32_t* dataOut;
     ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
             reinterpret_cast<void**>(&dataOut)));
-    ASSERT_EQ(*dataOut, 0x12345678);
+    ASSERT_EQ(*dataOut, TEST_DATA);
     ASSERT_EQ(OK, buffer->unlock());
 }
 
@@ -335,14 +342,15 @@
     uint32_t* dataIn;
     ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
             reinterpret_cast<void**>(&dataIn)));
-    *dataIn = 0x12345678;
+    *dataIn = TEST_DATA;
     ASSERT_EQ(OK, buffer->unlock());
 
-    IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1),
+    IGraphicBufferProducer::QueueBufferInput input(0, false,
+            HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
 
-    IGraphicBufferConsumer::BufferItem item;
+    BufferItem item;
     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
     ASSERT_EQ(OK, mConsumer->detachBuffer(item.mBuf));
 
@@ -354,8 +362,44 @@
     uint32_t* dataOut;
     ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
             reinterpret_cast<void**>(&dataOut)));
-    ASSERT_EQ(*dataOut, 0x12345678);
+    ASSERT_EQ(*dataOut, TEST_DATA);
     ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
 }
 
+TEST_F(BufferQueueTest, TestDisallowingAllocation) {
+    createBufferQueue();
+    sp<DummyConsumer> dc(new DummyConsumer);
+    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
+    IGraphicBufferProducer::QueueBufferOutput output;
+    ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
+            NATIVE_WINDOW_API_CPU, true, &output));
+
+    static const uint32_t WIDTH = 320;
+    static const uint32_t HEIGHT = 240;
+
+    ASSERT_EQ(OK, mConsumer->setDefaultBufferSize(WIDTH, HEIGHT));
+
+    int slot;
+    sp<Fence> fence;
+    sp<GraphicBuffer> buffer;
+    // This should return an error since it would require an allocation
+    ASSERT_EQ(OK, mProducer->allowAllocation(false));
+    ASSERT_EQ(WOULD_BLOCK, mProducer->dequeueBuffer(&slot, &fence, false, 0, 0,
+            0, GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+    // This should succeed, now that we've lifted the prohibition
+    ASSERT_EQ(OK, mProducer->allowAllocation(true));
+    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
+            mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
+            GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+    // Release the previous buffer back to the BufferQueue
+    mProducer->cancelBuffer(slot, fence);
+
+    // This should fail since we're requesting a different size
+    ASSERT_EQ(OK, mProducer->allowAllocation(false));
+    ASSERT_EQ(WOULD_BLOCK, mProducer->dequeueBuffer(&slot, &fence, false,
+            WIDTH * 2, HEIGHT * 2, 0, GRALLOC_USAGE_SW_WRITE_OFTEN));
+}
+
 } // namespace android
diff --git a/libs/gui/tests/CpuConsumer_test.cpp b/libs/gui/tests/CpuConsumer_test.cpp
index abd3724..2dc9ccc 100644
--- a/libs/gui/tests/CpuConsumer_test.cpp
+++ b/libs/gui/tests/CpuConsumer_test.cpp
@@ -94,7 +94,7 @@
             mPendingFrames--;
         }
 
-        virtual void onFrameAvailable() {
+        virtual void onFrameAvailable(const BufferItem&) {
             Mutex::Autolock lock(mMutex);
             mPendingFrames++;
             mCondition.signal();
@@ -125,7 +125,7 @@
             mPendingFrames--;
         }
 
-        virtual void onFrameAvailable() {
+        virtual void onFrameAvailable(const BufferItem&) {
             Mutex::Autolock lock(mMutex);
             mPendingFrames++;
             mFrameCondition.signal();
@@ -166,7 +166,7 @@
         uint32_t x, uint32_t y, uint32_t r, uint32_t g=0, uint32_t b=0) {
     // Ignores components that don't exist for given pixel
     switch(buf.format) {
-        case HAL_PIXEL_FORMAT_RAW_SENSOR: {
+        case HAL_PIXEL_FORMAT_RAW16: {
             String8 msg;
             uint16_t *bPtr = (uint16_t*)buf.data;
             bPtr += y * buf.stride + x;
@@ -429,7 +429,7 @@
 
 void checkAnyBuffer(const CpuConsumer::LockedBuffer &buf, int format) {
     switch (format) {
-        case HAL_PIXEL_FORMAT_RAW_SENSOR:
+        case HAL_PIXEL_FORMAT_RAW16:
             checkBayerRawBuffer(buf);
             break;
         case HAL_PIXEL_FORMAT_Y8:
@@ -457,9 +457,12 @@
         const CpuConsumerTestParams& params,
         int maxBufferSlack) {
     status_t err;
-    err = native_window_set_buffers_geometry(anw.get(),
-            params.width, params.height, params.format);
-    ASSERT_NO_ERROR(err, "set_buffers_geometry error: ");
+    err = native_window_set_buffers_dimensions(anw.get(),
+            params.width, params.height);
+    ASSERT_NO_ERROR(err, "set_buffers_dimensions error: ");
+
+    err = native_window_set_buffers_format(anw.get(), params.format);
+    ASSERT_NO_ERROR(err, "set_buffers_format error: ");
 
     err = native_window_set_usage(anw.get(),
             GRALLOC_USAGE_SW_WRITE_OFTEN);
@@ -505,7 +508,7 @@
         case HAL_PIXEL_FORMAT_YV12:
             fillYV12Buffer(img, params.width, params.height, *stride);
             break;
-        case HAL_PIXEL_FORMAT_RAW_SENSOR:
+        case HAL_PIXEL_FORMAT_RAW16:
             fillBayerRawBuffer(img, params.width, params.height, buf->getStride());
             break;
         case HAL_PIXEL_FORMAT_Y8:
@@ -537,7 +540,7 @@
     ASSERT_NO_ERROR(err, "queueBuffer error:");
 };
 
-// This test is disabled because the HAL_PIXEL_FORMAT_RAW_SENSOR format is not
+// This test is disabled because the HAL_PIXEL_FORMAT_RAW16 format is not
 // supported on all devices.
 TEST_P(CpuConsumerTest, FromCpuSingle) {
     status_t err;
@@ -571,7 +574,7 @@
     mCC->unlockBuffer(b);
 }
 
-// This test is disabled because the HAL_PIXEL_FORMAT_RAW_SENSOR format is not
+// This test is disabled because the HAL_PIXEL_FORMAT_RAW16 format is not
 // supported on all devices.
 TEST_P(CpuConsumerTest, FromCpuManyInQueue) {
     status_t err;
@@ -614,7 +617,7 @@
     }
 }
 
-// This test is disabled because the HAL_PIXEL_FORMAT_RAW_SENSOR format is not
+// This test is disabled because the HAL_PIXEL_FORMAT_RAW16 format is not
 // supported on all devices.
 TEST_P(CpuConsumerTest, FromCpuLockMax) {
     status_t err;
@@ -710,12 +713,12 @@
 };
 
 CpuConsumerTestParams rawTestSets[] = {
-    { 512,   512, 1, HAL_PIXEL_FORMAT_RAW_SENSOR},
-    { 512,   512, 3, HAL_PIXEL_FORMAT_RAW_SENSOR},
-    { 2608, 1960, 1, HAL_PIXEL_FORMAT_RAW_SENSOR},
-    { 2608, 1960, 3, HAL_PIXEL_FORMAT_RAW_SENSOR},
-    { 100,   100, 1, HAL_PIXEL_FORMAT_RAW_SENSOR},
-    { 100,   100, 3, HAL_PIXEL_FORMAT_RAW_SENSOR},
+    { 512,   512, 1, HAL_PIXEL_FORMAT_RAW16},
+    { 512,   512, 3, HAL_PIXEL_FORMAT_RAW16},
+    { 2608, 1960, 1, HAL_PIXEL_FORMAT_RAW16},
+    { 2608, 1960, 3, HAL_PIXEL_FORMAT_RAW16},
+    { 100,   100, 1, HAL_PIXEL_FORMAT_RAW16},
+    { 100,   100, 3, HAL_PIXEL_FORMAT_RAW16},
 };
 
 CpuConsumerTestParams rgba8888TestSets[] = {
diff --git a/libs/gui/tests/DisconnectWaiter.h b/libs/gui/tests/DisconnectWaiter.h
index 56e96c2..6e6915b 100644
--- a/libs/gui/tests/DisconnectWaiter.h
+++ b/libs/gui/tests/DisconnectWaiter.h
@@ -44,7 +44,7 @@
         mPendingFrames--;
     }
 
-    virtual void onFrameAvailable() {
+    virtual void onFrameAvailable(const BufferItem& /* item */) {
         Mutex::Autolock lock(mMutex);
         mPendingFrames++;
         mFrameCondition.signal();
diff --git a/libs/gui/tests/FrameWaiter.h b/libs/gui/tests/FrameWaiter.h
index bdedba6..f78fa00 100644
--- a/libs/gui/tests/FrameWaiter.h
+++ b/libs/gui/tests/FrameWaiter.h
@@ -35,7 +35,7 @@
         mPendingFrames--;
     }
 
-    virtual void onFrameAvailable() {
+    virtual void onFrameAvailable(const BufferItem& /* item */) {
         Mutex::Autolock lock(mMutex);
         mPendingFrames++;
         mCondition.signal();
diff --git a/libs/gui/tests/IGraphicBufferProducer_test.cpp b/libs/gui/tests/IGraphicBufferProducer_test.cpp
index aadfe61..ff58420 100644
--- a/libs/gui/tests/IGraphicBufferProducer_test.cpp
+++ b/libs/gui/tests/IGraphicBufferProducer_test.cpp
@@ -38,34 +38,35 @@
 #define TEST_CONTROLLED_BY_APP false
 #define TEST_PRODUCER_USAGE_BITS (0)
 
-// TODO: Make these public constants in a header
-enum {
-    // Default dimensions before setDefaultBufferSize is called
-    DEFAULT_WIDTH = 1,
-    DEFAULT_HEIGHT = 1,
-
-    // Default format before setDefaultBufferFormat is called
-    DEFAULT_FORMAT = HAL_PIXEL_FORMAT_RGBA_8888,
-
-    // Default transform hint before setTransformHint is called
-    DEFAULT_TRANSFORM_HINT = 0,
-};
-
 namespace android {
 
 namespace {
-// Parameters for a generic "valid" input for queueBuffer.
-const int64_t QUEUE_BUFFER_INPUT_TIMESTAMP = 1384888611;
-const bool QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP = false;
-const Rect QUEUE_BUFFER_INPUT_RECT = Rect(DEFAULT_WIDTH, DEFAULT_HEIGHT);
-const int QUEUE_BUFFER_INPUT_SCALING_MODE = 0;
-const int QUEUE_BUFFER_INPUT_TRANSFORM = 0;
-const bool QUEUE_BUFFER_INPUT_ASYNC = false;
-const sp<Fence> QUEUE_BUFFER_INPUT_FENCE = Fence::NO_FENCE;
+    // Default dimensions before setDefaultBufferSize is called
+    const uint32_t DEFAULT_WIDTH = 1;
+    const uint32_t DEFAULT_HEIGHT = 1;
+
+    // Default format before setDefaultBufferFormat is called
+    const PixelFormat DEFAULT_FORMAT = HAL_PIXEL_FORMAT_RGBA_8888;
+
+    // Default transform hint before setTransformHint is called
+    const uint32_t DEFAULT_TRANSFORM_HINT = 0;
+
+    // TODO: Make these constants in header
+    const int DEFAULT_CONSUMER_USAGE_BITS = 0;
+
+    // Parameters for a generic "valid" input for queueBuffer.
+    const int64_t QUEUE_BUFFER_INPUT_TIMESTAMP = 1384888611;
+    const bool QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP = false;
+    const android_dataspace QUEUE_BUFFER_INPUT_DATASPACE = HAL_DATASPACE_UNKNOWN;
+    const Rect QUEUE_BUFFER_INPUT_RECT = Rect(DEFAULT_WIDTH, DEFAULT_HEIGHT);
+    const int QUEUE_BUFFER_INPUT_SCALING_MODE = 0;
+    const int QUEUE_BUFFER_INPUT_TRANSFORM = 0;
+    const bool QUEUE_BUFFER_INPUT_ASYNC = false;
+    const sp<Fence> QUEUE_BUFFER_INPUT_FENCE = Fence::NO_FENCE;
 }; // namespace anonymous
 
 struct DummyConsumer : public BnConsumerListener {
-    virtual void onFrameAvailable() {}
+    virtual void onFrameAvailable(const BufferItem& /* item */) {}
     virtual void onBuffersReleased() {}
     virtual void onSidebandStreamChanged() {}
 };
@@ -126,6 +127,7 @@
         QueueBufferInputBuilder() {
            timestamp = QUEUE_BUFFER_INPUT_TIMESTAMP;
            isAutoTimestamp = QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP;
+           dataSpace = QUEUE_BUFFER_INPUT_DATASPACE;
            crop = QUEUE_BUFFER_INPUT_RECT;
            scalingMode = QUEUE_BUFFER_INPUT_SCALING_MODE;
            transform = QUEUE_BUFFER_INPUT_TRANSFORM;
@@ -137,6 +139,7 @@
             return IGraphicBufferProducer::QueueBufferInput(
                     timestamp,
                     isAutoTimestamp,
+                    dataSpace,
                     crop,
                     scalingMode,
                     transform,
@@ -154,6 +157,11 @@
             return *this;
         }
 
+        QueueBufferInputBuilder& setDataSpace(android_dataspace dataSpace) {
+            this->dataSpace = dataSpace;
+            return *this;
+        }
+
         QueueBufferInputBuilder& setCrop(Rect crop) {
             this->crop = crop;
             return *this;
@@ -182,6 +190,7 @@
     private:
         int64_t timestamp;
         bool isAutoTimestamp;
+        android_dataspace dataSpace;
         Rect crop;
         int scalingMode;
         uint32_t transform;
@@ -264,15 +273,12 @@
 TEST_F(IGraphicBufferProducerTest, Query_Succeeds) {
     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
 
-    // TODO: Make these constants in header
-    const int DEFAULT_CONSUMER_USAGE_BITS = 0;
-
-    int value = -1;
+    int32_t value = -1;
     EXPECT_OK(mProducer->query(NATIVE_WINDOW_WIDTH, &value));
-    EXPECT_EQ(DEFAULT_WIDTH, value);
+    EXPECT_EQ(DEFAULT_WIDTH, static_cast<uint32_t>(value));
 
     EXPECT_OK(mProducer->query(NATIVE_WINDOW_HEIGHT, &value));
-    EXPECT_EQ(DEFAULT_HEIGHT, value);
+    EXPECT_EQ(DEFAULT_HEIGHT, static_cast<uint32_t>(value));
 
     EXPECT_OK(mProducer->query(NATIVE_WINDOW_FORMAT, &value));
     EXPECT_EQ(DEFAULT_FORMAT, value);
@@ -293,7 +299,7 @@
     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
 
     // One past the end of the last 'query' enum value. Update this if we add more enums.
-    const int NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE = NATIVE_WINDOW_CONSUMER_USAGE_BITS + 1;
+    const int NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE = NATIVE_WINDOW_DEFAULT_DATASPACE + 1;
 
     int value;
     // What was out of range
@@ -360,7 +366,7 @@
         EXPECT_EQ(DEFAULT_WIDTH, width);
         EXPECT_EQ(DEFAULT_HEIGHT, height);
         EXPECT_EQ(DEFAULT_TRANSFORM_HINT, transformHint);
-        EXPECT_EQ(1, numPendingBuffers); // since queueBuffer was called exactly once
+        EXPECT_EQ(1u, numPendingBuffers); // since queueBuffer was called exactly once
     }
 
     // Buffer was not in the dequeued state
diff --git a/libs/gui/tests/SRGB_test.cpp b/libs/gui/tests/SRGB_test.cpp
index da2add7..3b11b97 100644
--- a/libs/gui/tests/SRGB_test.cpp
+++ b/libs/gui/tests/SRGB_test.cpp
@@ -17,6 +17,10 @@
 #define LOG_TAG "SRGB_test"
 //#define LOG_NDEBUG 0
 
+// Ignore for this file because it flags every instance of
+// ASSERT_EQ(GL_NO_ERROR, glGetError());
+#pragma clang diagnostic ignored "-Wsign-compare"
+
 #include "GLTest.h"
 
 #include <math.h>
@@ -214,10 +218,11 @@
         ASSERT_EQ(GL_NO_ERROR, glGetError());
     }
 
-    void checkLockedBuffer(PixelFormat format) {
+    void checkLockedBuffer(PixelFormat format, android_dataspace dataSpace) {
         ASSERT_EQ(mLockedBuffer.format, format);
         ASSERT_EQ(mLockedBuffer.width, DISPLAY_WIDTH);
         ASSERT_EQ(mLockedBuffer.height, DISPLAY_HEIGHT);
+        ASSERT_EQ(mLockedBuffer.dataSpace, dataSpace);
     }
 
     static bool withinTolerance(int a, int b) {
@@ -328,14 +333,15 @@
         ANativeWindow_Buffer outBuffer;
         ARect outBufferBounds;
         mOutputSurface->lock(&outBuffer, &outBufferBounds);
-        ASSERT_EQ(mLockedBuffer.width, outBuffer.width);
-        ASSERT_EQ(mLockedBuffer.height, outBuffer.height);
-        ASSERT_EQ(mLockedBuffer.stride, outBuffer.stride);
+        ASSERT_EQ(mLockedBuffer.width, static_cast<uint32_t>(outBuffer.width));
+        ASSERT_EQ(mLockedBuffer.height, static_cast<uint32_t>(outBuffer.height));
+        ASSERT_EQ(mLockedBuffer.stride, static_cast<uint32_t>(outBuffer.stride));
 
         if (mLockedBuffer.format == outBuffer.format) {
             memcpy(outBuffer.bits, mLockedBuffer.data, bufferSize);
         } else {
-            ASSERT_EQ(mLockedBuffer.format, PIXEL_FORMAT_sRGB_A_8888);
+            ASSERT_EQ(mLockedBuffer.format, PIXEL_FORMAT_RGBA_8888);
+            ASSERT_EQ(mLockedBuffer.dataSpace, HAL_DATASPACE_SRGB);
             ASSERT_EQ(outBuffer.format, PIXEL_FORMAT_RGBA_8888);
             uint8_t* outPointer = reinterpret_cast<uint8_t*>(outBuffer.bits);
             for (int y = 0; y < outBuffer.height; ++y) {
@@ -380,7 +386,8 @@
 
     // Lock
     ASSERT_EQ(NO_ERROR, mCpuConsumer->lockNextBuffer(&mLockedBuffer));
-    ASSERT_NO_FATAL_FAILURE(checkLockedBuffer(PIXEL_FORMAT_RGBA_8888));
+    ASSERT_NO_FATAL_FAILURE(
+        checkLockedBuffer(PIXEL_FORMAT_RGBA_8888, HAL_DATASPACE_UNKNOWN));
 
     // Compare a pixel in the middle of each texture
     int midSRGBOffset = (DISPLAY_HEIGHT / 4) * mLockedBuffer.stride *
@@ -398,7 +405,8 @@
     // the debug surface if necessary
 }
 
-TEST_F(SRGBTest, RenderToSRGBSurface) {
+// XXX: Disabled since we don't currently expect this to work
+TEST_F(SRGBTest, DISABLED_RenderToSRGBSurface) {
     ASSERT_NO_FATAL_FAILURE(initShaders());
 
     // By default, the first buffer we write into will be RGB
@@ -411,7 +419,8 @@
 
     // Lock
     ASSERT_EQ(NO_ERROR, mCpuConsumer->lockNextBuffer(&mLockedBuffer));
-    ASSERT_NO_FATAL_FAILURE(checkLockedBuffer(PIXEL_FORMAT_RGBA_8888));
+    ASSERT_NO_FATAL_FAILURE(
+        checkLockedBuffer(PIXEL_FORMAT_RGBA_8888, HAL_DATASPACE_UNKNOWN));
 
     // Save the values of the middle pixel for later comparison against SRGB
     uint8_t values[PIXEL_SIZE] = {};
@@ -460,7 +469,8 @@
     ASSERT_EQ(NO_ERROR, mCpuConsumer->lockNextBuffer(&mLockedBuffer));
 
     // Make sure we actually got the SRGB buffer on the consumer side
-    ASSERT_NO_FATAL_FAILURE(checkLockedBuffer(PIXEL_FORMAT_sRGB_A_8888));
+    ASSERT_NO_FATAL_FAILURE(
+        checkLockedBuffer(PIXEL_FORMAT_RGBA_8888, HAL_DATASPACE_SRGB));
 
     // Verify that the stored value is the same, accounting for RGB/SRGB
     for (int c = 0; c < PIXEL_SIZE; ++c) {
diff --git a/libs/gui/tests/StreamSplitter_test.cpp b/libs/gui/tests/StreamSplitter_test.cpp
index 32ec90d..00cc39d 100644
--- a/libs/gui/tests/StreamSplitter_test.cpp
+++ b/libs/gui/tests/StreamSplitter_test.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "StreamSplitter_test"
 //#define LOG_NDEBUG 0
 
+#include <gui/BufferItem.h>
 #include <gui/BufferQueue.h>
 #include <gui/IConsumerListener.h>
 #include <gui/ISurfaceComposer.h>
@@ -46,7 +47,7 @@
 };
 
 struct DummyListener : public BnConsumerListener {
-    virtual void onFrameAvailable() {}
+    virtual void onFrameAvailable(const BufferItem& /* item */) {}
     virtual void onBuffersReleased() {}
     virtual void onSidebandStreamChanged() {}
 };
@@ -75,6 +76,8 @@
     int mAllocCount;
 };
 
+static const uint32_t TEST_DATA = 0x12345678u;
+
 TEST_F(StreamSplitterTest, OneInputOneOutput) {
     sp<CountedAllocator> allocator(new CountedAllocator);
 
@@ -107,21 +110,22 @@
     uint32_t* dataIn;
     ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
             reinterpret_cast<void**>(&dataIn)));
-    *dataIn = 0x12345678;
+    *dataIn = TEST_DATA;
     ASSERT_EQ(OK, buffer->unlock());
 
     IGraphicBufferProducer::QueueBufferInput qbInput(0, false,
+            HAL_DATASPACE_UNKNOWN,
             Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false,
             Fence::NO_FENCE);
     ASSERT_EQ(OK, inputProducer->queueBuffer(slot, qbInput, &qbOutput));
 
-    IGraphicBufferConsumer::BufferItem item;
+    BufferItem item;
     ASSERT_EQ(OK, outputConsumer->acquireBuffer(&item, 0));
 
     uint32_t* dataOut;
     ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
             reinterpret_cast<void**>(&dataOut)));
-    ASSERT_EQ(*dataOut, 0x12345678);
+    ASSERT_EQ(*dataOut, TEST_DATA);
     ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
 
     ASSERT_EQ(OK, outputConsumer->releaseBuffer(item.mBuf, item.mFrameNumber,
@@ -173,22 +177,23 @@
     uint32_t* dataIn;
     ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
             reinterpret_cast<void**>(&dataIn)));
-    *dataIn = 0x12345678;
+    *dataIn = TEST_DATA;
     ASSERT_EQ(OK, buffer->unlock());
 
     IGraphicBufferProducer::QueueBufferInput qbInput(0, false,
+            HAL_DATASPACE_UNKNOWN,
             Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false,
             Fence::NO_FENCE);
     ASSERT_EQ(OK, inputProducer->queueBuffer(slot, qbInput, &qbOutput));
 
     for (int output = 0; output < NUM_OUTPUTS; ++output) {
-        IGraphicBufferConsumer::BufferItem item;
+        BufferItem item;
         ASSERT_EQ(OK, outputConsumers[output]->acquireBuffer(&item, 0));
 
         uint32_t* dataOut;
         ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
                     reinterpret_cast<void**>(&dataOut)));
-        ASSERT_EQ(*dataOut, 0x12345678);
+        ASSERT_EQ(*dataOut, TEST_DATA);
         ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
 
         ASSERT_EQ(OK, outputConsumers[output]->releaseBuffer(item.mBuf,
@@ -234,6 +239,7 @@
     outputConsumer->consumerDisconnect();
 
     IGraphicBufferProducer::QueueBufferInput qbInput(0, false,
+            HAL_DATASPACE_UNKNOWN,
             Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false,
             Fence::NO_FENCE);
     ASSERT_EQ(OK, inputProducer->queueBuffer(slot, qbInput, &qbOutput));
diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp
index 8cdf3bc..d750cd0 100644
--- a/libs/gui/tests/SurfaceTextureClient_test.cpp
+++ b/libs/gui/tests/SurfaceTextureClient_test.cpp
@@ -207,12 +207,8 @@
 }
 
 TEST_F(SurfaceTextureClientTest, BufferGeometryInvalidSizesFail) {
-    EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), -1,  0,  0));
-    EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(),  0, -1,  0));
-    EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(),  0,  0, -1));
-    EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), -1, -1,  0));
-    EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(),  0,  8,  0));
-    EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(),  8,  0,  0));
+    EXPECT_GT(OK, native_window_set_buffers_dimensions(mANW.get(),  0,  8));
+    EXPECT_GT(OK, native_window_set_buffers_dimensions(mANW.get(),  8,  0));
 }
 
 TEST_F(SurfaceTextureClientTest, DefaultGeometryValues) {
@@ -226,7 +222,8 @@
 
 TEST_F(SurfaceTextureClientTest, BufferGeometryCanBeSet) {
     ANativeWindowBuffer* buf;
-    EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, PIXEL_FORMAT_RGB_565));
+    EXPECT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 16, 8));
+    EXPECT_EQ(OK, native_window_set_buffers_format(mANW.get(), PIXEL_FORMAT_RGB_565));
     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf));
     EXPECT_EQ(16, buf->width);
     EXPECT_EQ(8, buf->height);
@@ -236,7 +233,8 @@
 
 TEST_F(SurfaceTextureClientTest, BufferGeometryDefaultSizeSetFormat) {
     ANativeWindowBuffer* buf;
-    EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, PIXEL_FORMAT_RGB_565));
+    EXPECT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 0, 0));
+    EXPECT_EQ(OK, native_window_set_buffers_format(mANW.get(), PIXEL_FORMAT_RGB_565));
     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf));
     EXPECT_EQ(1, buf->width);
     EXPECT_EQ(1, buf->height);
@@ -246,7 +244,8 @@
 
 TEST_F(SurfaceTextureClientTest, BufferGeometrySetSizeDefaultFormat) {
     ANativeWindowBuffer* buf;
-    EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, 0));
+    EXPECT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 16, 8));
+    EXPECT_EQ(OK, native_window_set_buffers_format(mANW.get(), 0));
     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf));
     EXPECT_EQ(16, buf->width);
     EXPECT_EQ(8, buf->height);
@@ -256,13 +255,15 @@
 
 TEST_F(SurfaceTextureClientTest, BufferGeometrySizeCanBeUnset) {
     ANativeWindowBuffer* buf;
-    EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, 0));
+    EXPECT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 16, 8));
+    EXPECT_EQ(OK, native_window_set_buffers_format(mANW.get(), 0));
     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf));
     EXPECT_EQ(16, buf->width);
     EXPECT_EQ(8, buf->height);
     EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format);
     ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf, -1));
-    EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, 0));
+    EXPECT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 0, 0));
+    EXPECT_EQ(OK, native_window_set_buffers_format(mANW.get(), 0));
     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf));
     EXPECT_EQ(1, buf->width);
     EXPECT_EQ(1, buf->height);
@@ -272,7 +273,8 @@
 
 TEST_F(SurfaceTextureClientTest, BufferGeometrySizeCanBeChangedWithoutFormat) {
     ANativeWindowBuffer* buf;
-    EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, PIXEL_FORMAT_RGB_565));
+    EXPECT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 0, 0));
+    EXPECT_EQ(OK, native_window_set_buffers_format(mANW.get(), PIXEL_FORMAT_RGB_565));
     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf));
     EXPECT_EQ(1, buf->width);
     EXPECT_EQ(1, buf->height);
@@ -330,7 +332,8 @@
     EXPECT_EQ(8, buf[1]->height);
     ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0], -1));
     ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[1], -1));
-    EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 12, 24, 0));
+    EXPECT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 12, 24));
+    EXPECT_EQ(OK, native_window_set_buffers_format(mANW.get(), 0));
     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
     EXPECT_NE(buf[0], buf[1]);
@@ -468,7 +471,8 @@
 
     // Once we've queued a buffer, however we should not be able to dequeue more
     // than (buffer-count - MIN_UNDEQUEUED_BUFFERS), which is 2 in this case.
-    EXPECT_EQ(-EBUSY, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
+    EXPECT_EQ(INVALID_OPERATION,
+            native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
 
     ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0], -1));
     ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[2], -1));
@@ -620,7 +624,8 @@
     crop.bottom = 5;
 
     ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
-    ASSERT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 8, 8, 0));
+    ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 8, 8));
+    ASSERT_EQ(OK, native_window_set_buffers_format(mANW.get(), 0));
     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
     ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &crop));
     ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0], -1));
@@ -668,7 +673,8 @@
     const int numFmts = (sizeof(fmts) / sizeof(fmts[0]));
     for (int i = 0; i < numFmts; i++) {
       int fmt = -1;
-      ASSERT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 0, 0, fmts[i]));
+      ASSERT_EQ(OK, native_window_set_buffers_dimensions(anw.get(), 0, 0));
+      ASSERT_EQ(OK, native_window_set_buffers_format(anw.get(), fmts[i]));
       ASSERT_EQ(OK, anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &fmt));
       EXPECT_EQ(fmts[i], fmt);
     }
diff --git a/libs/gui/tests/SurfaceTextureFBO_test.cpp b/libs/gui/tests/SurfaceTextureFBO_test.cpp
index b165ae6..c243fc0 100644
--- a/libs/gui/tests/SurfaceTextureFBO_test.cpp
+++ b/libs/gui/tests/SurfaceTextureFBO_test.cpp
@@ -27,8 +27,10 @@
     const int texWidth = 64;
     const int texHeight = 64;
 
-    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
-            texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
+            texWidth, texHeight));
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
+            HAL_PIXEL_FORMAT_RGBA_8888));
     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
 
diff --git a/libs/gui/tests/SurfaceTextureGLThreadToGL.h b/libs/gui/tests/SurfaceTextureGLThreadToGL.h
index 6410516..14e42ac 100644
--- a/libs/gui/tests/SurfaceTextureGLThreadToGL.h
+++ b/libs/gui/tests/SurfaceTextureGLThreadToGL.h
@@ -130,7 +130,7 @@
         }
 
         // This should be called by GLConsumer on the producer thread.
-        virtual void onFrameAvailable() {
+        virtual void onFrameAvailable(const BufferItem& /* item */) {
             Mutex::Autolock lock(mMutex);
             ALOGV("+onFrameAvailable");
             mFrameAvailable = true;
diff --git a/libs/gui/tests/SurfaceTextureGL_test.cpp b/libs/gui/tests/SurfaceTextureGL_test.cpp
index fa1e1b7..fad133f 100644
--- a/libs/gui/tests/SurfaceTextureGL_test.cpp
+++ b/libs/gui/tests/SurfaceTextureGL_test.cpp
@@ -28,8 +28,10 @@
     const int texWidth = 64;
     const int texHeight = 66;
 
-    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
-            texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
+            texWidth, texHeight));
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
+            HAL_PIXEL_FORMAT_YV12));
     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
 
@@ -74,8 +76,10 @@
     const int texWidth = 64;
     const int texHeight = 64;
 
-    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
-            texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
+            texWidth, texHeight));
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
+            HAL_PIXEL_FORMAT_YV12));
     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
 
@@ -120,8 +124,10 @@
     const int texWidth = 64;
     const int texHeight = 66;
 
-    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
-            texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
+            texWidth, texHeight));
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
+            HAL_PIXEL_FORMAT_YV12));
     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
 
@@ -185,8 +191,10 @@
     enum { numFrames = 1024 };
 
     ASSERT_EQ(NO_ERROR, mST->setDefaultMaxBufferCount(2));
-    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
-            texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
+            texWidth, texHeight));
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
+            HAL_PIXEL_FORMAT_YV12));
     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
             GRALLOC_USAGE_SW_WRITE_OFTEN));
 
@@ -326,8 +334,10 @@
     const int texWidth = 64;
     const int texHeight = 66;
 
-    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
-            texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
+            texWidth, texHeight));
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
+            HAL_PIXEL_FORMAT_RGBA_8888));
     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
 
@@ -368,8 +378,10 @@
     const int texWidth = 64;
     const int texHeight = 64;
 
-    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
-            texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
+            texWidth, texHeight));
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
+            HAL_PIXEL_FORMAT_RGBA_8888));
     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
 
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 5e6aeef..4f87824 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -155,4 +155,26 @@
     ASSERT_EQ(TEST_USAGE_FLAGS, flags);
 }
 
+TEST_F(SurfaceTest, QueryDefaultBuffersDataSpace) {
+    const android_dataspace TEST_DATASPACE = HAL_DATASPACE_SRGB;
+    sp<IGraphicBufferProducer> producer;
+    sp<IGraphicBufferConsumer> consumer;
+    BufferQueue::createBufferQueue(&producer, &consumer);
+    sp<CpuConsumer> cpuConsumer = new CpuConsumer(consumer, 1);
+
+    cpuConsumer->setDefaultBufferDataSpace(TEST_DATASPACE);
+
+    sp<Surface> s = new Surface(producer);
+
+    sp<ANativeWindow> anw(s);
+
+    android_dataspace dataSpace;
+
+    int err = anw->query(anw.get(), NATIVE_WINDOW_DEFAULT_DATASPACE,
+            reinterpret_cast<int*>(&dataSpace));
+
+    ASSERT_EQ(NO_ERROR, err);
+    ASSERT_EQ(TEST_DATASPACE, dataSpace);
+}
+
 }
diff --git a/libs/ui/Fence.cpp b/libs/ui/Fence.cpp
index 9cf2881..bf24ffb 100644
--- a/libs/ui/Fence.cpp
+++ b/libs/ui/Fence.cpp
@@ -130,7 +130,7 @@
 }
 
 size_t Fence::getFlattenedSize() const {
-    return 1;
+    return 4;
 }
 
 size_t Fence::getFdCount() const {
@@ -141,7 +141,9 @@
     if (size < getFlattenedSize() || count < getFdCount()) {
         return NO_MEMORY;
     }
-    FlattenableUtils::write(buffer, size, getFdCount());
+    // Cast to uint32_t since the size of a size_t can vary between 32- and
+    // 64-bit processes
+    FlattenableUtils::write(buffer, size, static_cast<uint32_t>(getFdCount()));
     if (isValid()) {
         *fds++ = mFenceFd;
         count--;
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 425df38..6a42a22 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -152,6 +152,16 @@
     return initSize(inWidth, inHeight, inFormat, inUsage);
 }
 
+bool GraphicBuffer::needsReallocation(uint32_t inWidth, uint32_t inHeight,
+        PixelFormat inFormat, uint32_t inUsage)
+{
+    if (static_cast<int>(inWidth) != width) return true;
+    if (static_cast<int>(inHeight) != height) return true;
+    if (inFormat != format) return true;
+    if ((static_cast<uint32_t>(usage) & inUsage) != inUsage) return true;
+    return false;
+}
+
 status_t GraphicBuffer::initSize(uint32_t inWidth, uint32_t inHeight,
         PixelFormat inFormat, uint32_t inUsage)
 {
@@ -303,7 +313,7 @@
                 static_cast<size_t>(handle->numInts) * sizeof(int));
     }
 
-    buffer = reinterpret_cast<void*>(static_cast<int*>(buffer) + sizeNeeded);
+    buffer = static_cast<void*>(static_cast<uint8_t*>(buffer) + sizeNeeded);
     size -= sizeNeeded;
     if (handle) {
         fds += handle->numFds;
@@ -323,7 +333,11 @@
     const size_t numFds  = static_cast<size_t>(buf[8]);
     const size_t numInts = static_cast<size_t>(buf[9]);
 
-    const size_t maxNumber = UINT_MAX / sizeof(int);
+    // Limit the maxNumber to be relatively small. The number of fds or ints
+    // should not come close to this number, and the number itself was simply
+    // chosen to be high enough to not cause issues and low enough to prevent
+    // overflow problems.
+    const size_t maxNumber = 4096;
     if (numFds >= maxNumber || numInts >= (maxNumber - 10)) {
         width = height = stride = format = usage = 0;
         handle = NULL;
@@ -381,7 +395,7 @@
         }
     }
 
-    buffer = reinterpret_cast<void const*>(static_cast<int const*>(buffer) + sizeNeeded);
+    buffer = static_cast<void const*>(static_cast<uint8_t const*>(buffer) + sizeNeeded);
     size -= sizeNeeded;
     fds += numFds;
     count -= numFds;
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index 01acdc8..90a1c11 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -97,6 +97,10 @@
     ATRACE_CALL();
     status_t err;
 
+    if (mAllocMod->lock_ycbcr == NULL) {
+        return -EINVAL; // do not log failure
+    }
+
     err = mAllocMod->lock_ycbcr(mAllocMod, handle, static_cast<int>(usage),
             bounds.left, bounds.top, bounds.width(), bounds.height(),
             ycbcr);
@@ -127,8 +131,10 @@
                 bounds.left, bounds.top, bounds.width(), bounds.height(),
                 vaddr, fenceFd);
     } else {
-        sync_wait(fenceFd, -1);
-        close(fenceFd);
+        if (fenceFd >= 0) {
+            sync_wait(fenceFd, -1);
+            close(fenceFd);
+        }
         err = mAllocMod->lock(mAllocMod, handle, static_cast<int>(usage),
                 bounds.left, bounds.top, bounds.width(), bounds.height(),
                 vaddr);
@@ -144,16 +150,24 @@
     ATRACE_CALL();
     status_t err;
 
-    if (mAllocMod->common.module_api_version >= GRALLOC_MODULE_API_VERSION_0_3) {
+    if (mAllocMod->common.module_api_version >= GRALLOC_MODULE_API_VERSION_0_3
+            && mAllocMod->lockAsync_ycbcr != NULL) {
         err = mAllocMod->lockAsync_ycbcr(mAllocMod, handle,
                 static_cast<int>(usage), bounds.left, bounds.top,
                 bounds.width(), bounds.height(), ycbcr, fenceFd);
-    } else {
-        sync_wait(fenceFd, -1);
-        close(fenceFd);
+    } else if (mAllocMod->lock_ycbcr != NULL) {
+        if (fenceFd >= 0) {
+            sync_wait(fenceFd, -1);
+            close(fenceFd);
+        }
         err = mAllocMod->lock_ycbcr(mAllocMod, handle, static_cast<int>(usage),
                 bounds.left, bounds.top, bounds.width(), bounds.height(),
                 ycbcr);
+    } else {
+        if (fenceFd >= 0) {
+            close(fenceFd);
+        }
+        return -EINVAL; // do not log failure
     }
 
     ALOGW_IF(err, "lock(...) failed %d (%s)", err, strerror(-err));
diff --git a/libs/ui/PixelFormat.cpp b/libs/ui/PixelFormat.cpp
index 99ed6f7..cab1dde 100644
--- a/libs/ui/PixelFormat.cpp
+++ b/libs/ui/PixelFormat.cpp
@@ -25,8 +25,6 @@
         case PIXEL_FORMAT_RGBA_8888:
         case PIXEL_FORMAT_RGBX_8888:
         case PIXEL_FORMAT_BGRA_8888:
-        case PIXEL_FORMAT_sRGB_A_8888:
-        case PIXEL_FORMAT_sRGB_X_8888:
             return 4;
         case PIXEL_FORMAT_RGB_888:
             return 3;
@@ -57,4 +55,3 @@
 // ----------------------------------------------------------------------------
 }; // namespace android
 // ----------------------------------------------------------------------------
-
diff --git a/libs/ui/Rect.cpp b/libs/ui/Rect.cpp
index b480f3a..dcce21f 100644
--- a/libs/ui/Rect.cpp
+++ b/libs/ui/Rect.cpp
@@ -19,6 +19,8 @@
 
 namespace android {
 
+const Rect Rect::INVALID_RECT{0, 0, -1, -1};
+
 static inline int32_t min(int32_t a, int32_t b) {
     return (a < b) ? a : b;
 }
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index 91fa216..3810da4 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -53,6 +53,8 @@
     direction_RTL
 };
 
+const Region Region::INVALID_REGION(Rect::INVALID_RECT);
+
 // ----------------------------------------------------------------------------
 
 Region::Region() {
@@ -130,43 +132,42 @@
             // prevIndex can't be -1 here because if endLastSpan is set to a
             // value greater than -1 (allowing the loop to execute),
             // beginLastSpan (and therefore prevIndex) will also be increased
-            const Rect* prev = &dst[static_cast<size_t>(prevIndex)];
-
+            const Rect prev = dst[static_cast<size_t>(prevIndex)];
             if (spanDirection == direction_RTL) {
                 // iterating over previous span RTL, quit if it's too far left
-                if (prev->right <= left) break;
+                if (prev.right <= left) break;
 
-                if (prev->right > left && prev->right < right) {
-                    dst.add(Rect(prev->right, top, right, bottom));
-                    right = prev->right;
+                if (prev.right > left && prev.right < right) {
+                    dst.add(Rect(prev.right, top, right, bottom));
+                    right = prev.right;
                 }
 
-                if (prev->left > left && prev->left < right) {
-                    dst.add(Rect(prev->left, top, right, bottom));
-                    right = prev->left;
+                if (prev.left > left && prev.left < right) {
+                    dst.add(Rect(prev.left, top, right, bottom));
+                    right = prev.left;
                 }
 
                 // if an entry in the previous span is too far right, nothing further left in the
                 // current span will need it
-                if (prev->left >= right) {
+                if (prev.left >= right) {
                     beginLastSpan = prevIndex;
                 }
             } else {
                 // iterating over previous span LTR, quit if it's too far right
-                if (prev->left >= right) break;
+                if (prev.left >= right) break;
 
-                if (prev->left > left && prev->left < right) {
-                    dst.add(Rect(left, top, prev->left, bottom));
-                    left = prev->left;
+                if (prev.left > left && prev.left < right) {
+                    dst.add(Rect(left, top, prev.left, bottom));
+                    left = prev.left;
                 }
 
-                if (prev->right > left && prev->right < right) {
-                    dst.add(Rect(left, top, prev->right, bottom));
-                    left = prev->right;
+                if (prev.right > left && prev.right < right) {
+                    dst.add(Rect(left, top, prev.right, bottom));
+                    left = prev.right;
                 }
                 // if an entry in the previous span is too far left, nothing further right in the
                 // current span will need it
-                if (prev->right <= left) {
+                if (prev.right <= left) {
                     beginLastSpan = prevIndex;
                 }
             }
@@ -518,8 +519,12 @@
     Rect b(*prev);
     while (cur != tail) {
         if (cur->isValid() == false) {
-            ALOGE_IF(!silent, "%s: region contains an invalid Rect", name);
-            result = false;
+            // We allow this particular flavor of invalid Rect, since it is used
+            // as a signal value in various parts of the system
+            if (*cur != Rect::INVALID_RECT) {
+                ALOGE_IF(!silent, "%s: region contains an invalid Rect", name);
+                result = false;
+            }
         }
         if (cur->right > region_operator<Rect>::max_value) {
             ALOGE_IF(!silent, "%s: rect->right > max_value", name);
@@ -691,7 +696,9 @@
         const Region& lhs,
         const Rect& rhs, int dx, int dy)
 {
-    if (!rhs.isValid()) {
+    // We allow this particular flavor of invalid Rect, since it is used as a
+    // signal value in various parts of the system
+    if (!rhs.isValid() && rhs != Rect::INVALID_RECT) {
         ALOGE("Region::boolean_operation(op=%d) invalid Rect={%d,%d,%d,%d}",
                 op, rhs.left, rhs.top, rhs.right, rhs.bottom);
         return;
@@ -754,35 +761,52 @@
 // ----------------------------------------------------------------------------
 
 size_t Region::getFlattenedSize() const {
-    return mStorage.size() * sizeof(Rect);
+    return sizeof(uint32_t) + mStorage.size() * sizeof(Rect);
 }
 
 status_t Region::flatten(void* buffer, size_t size) const {
 #if VALIDATE_REGIONS
     validate(*this, "Region::flatten");
 #endif
-    if (size < mStorage.size() * sizeof(Rect)) {
+    if (size < getFlattenedSize()) {
         return NO_MEMORY;
     }
-    Rect* rects = reinterpret_cast<Rect*>(buffer);
-    memcpy(rects, mStorage.array(), mStorage.size() * sizeof(Rect));
+    // Cast to uint32_t since the size of a size_t can vary between 32- and
+    // 64-bit processes
+    FlattenableUtils::write(buffer, size, static_cast<uint32_t>(mStorage.size()));
+    for (auto rect : mStorage) {
+        status_t result = rect.flatten(buffer, size);
+        if (result != NO_ERROR) {
+            return result;
+        }
+        FlattenableUtils::advance(buffer, size, sizeof(rect));
+    }
     return NO_ERROR;
 }
 
 status_t Region::unflatten(void const* buffer, size_t size) {
-    Region result;
-    if (size >= sizeof(Rect)) {
-        Rect const* rects = reinterpret_cast<Rect const*>(buffer);
-        size_t count = size / sizeof(Rect);
-        if (count > 0) {
-            result.mStorage.clear();
-            ssize_t err = result.mStorage.insertAt(0, count);
-            if (err < 0) {
-                return status_t(err);
-            }
-            memcpy(result.mStorage.editArray(), rects, count*sizeof(Rect));
-        }
+    if (size < sizeof(uint32_t)) {
+        return NO_MEMORY;
     }
+
+    uint32_t numRects = 0;
+    FlattenableUtils::read(buffer, size, numRects);
+    if (size < numRects * sizeof(Rect)) {
+        return NO_MEMORY;
+    }
+
+    Region result;
+    result.mStorage.clear();
+    for (size_t r = 0; r < numRects; ++r) {
+        Rect rect;
+        status_t status = rect.unflatten(buffer, size);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        FlattenableUtils::advance(buffer, size, sizeof(rect));
+        result.mStorage.push_back(rect);
+    }
+
 #if VALIDATE_REGIONS
     validate(result, "Region::unflatten");
 #endif
diff --git a/opengl/include/EGL/eglext.h b/opengl/include/EGL/eglext.h
index 3b2984a..25f7607 100644
--- a/opengl/include/EGL/eglext.h
+++ b/opengl/include/EGL/eglext.h
@@ -176,6 +176,15 @@
 #define EGL_BITMAP_PIXEL_SIZE_KHR		0x3110
 #endif
 
+#ifndef EGL_KHR_partial_update
+#define EGL_KHR_partial_update 1
+#define EGL_BUFFER_AGE_KHR                0x313D
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETDAMAGEREGIONKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSetDamageRegionKHR (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
+#endif
+#endif /* EGL_KHR_partial_update */
+
 #ifndef EGL_NV_coverage_sample
 #define EGL_NV_coverage_sample 1
 #define EGL_COVERAGE_BUFFERS_NV			0x30E0
@@ -440,6 +449,14 @@
 /* No tokens/entry points, just relaxes an error condition */
 #endif
 
+#ifndef EGL_KHR_swap_buffers_with_damage
+#define EGL_KHR_swap_buffers_with_damage 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageKHR (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
+#endif
+#endif /* EGL_KHR_swap_buffers_with_damage */
+
 #ifdef EGL_KHR_stream /* Requires KHR_stream extension */
 #ifndef EGL_KHR_stream_cross_process_fd
 #define EGL_KHR_stream_cross_process_fd 1
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index ff08a6b..f5b90dd 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -80,6 +80,7 @@
 extern char const * const gBuiltinExtensionString =
         "EGL_KHR_get_all_proc_addresses "
         "EGL_ANDROID_presentation_time "
+        "EGL_KHR_swap_buffers_with_damage "
         ;
 extern char const * const gExtensionString  =
         "EGL_KHR_image "                        // mandatory
@@ -100,6 +101,8 @@
         "EGL_ANDROID_image_native_buffer "      // mandatory
         "EGL_KHR_wait_sync "                    // strongly recommended
         "EGL_ANDROID_recordable "               // mandatory
+        "EGL_KHR_partial_update "               // strongly recommended
+        "EGL_EXT_buffer_age "                   // strongly recommended with partial_update
         ;
 
 // extensions not exposed to applications but used by the ANDROID system
@@ -152,6 +155,14 @@
     // EGL_ANDROID_presentation_time
     { "eglPresentationTimeANDROID",
             (__eglMustCastToProperFunctionPointerType)&eglPresentationTimeANDROID },
+
+    // EGL_KHR_swap_buffers_with_damage
+    { "eglSwapBuffersWithDamageKHR",
+            (__eglMustCastToProperFunctionPointerType)&eglSwapBuffersWithDamageKHR },
+
+    // EGL_KHR_partial_update
+    { "eglSetDamageRegionKHR",
+            (__eglMustCastToProperFunctionPointerType)&eglSetDamageRegionKHR },
 };
 
 /*
@@ -381,20 +392,15 @@
 // Turn linear formats into corresponding sRGB formats when colorspace is
 // EGL_GL_COLORSPACE_SRGB_KHR, or turn sRGB formats into corresponding linear
 // formats when colorspace is EGL_GL_COLORSPACE_LINEAR_KHR. In any cases where
-// the modification isn't possible, the original format is returned.
-static int modifyFormatColorspace(int fmt, EGLint colorspace) {
+// the modification isn't possible, the original dataSpace is returned.
+static android_dataspace modifyBufferDataspace( android_dataspace dataSpace,
+                                                EGLint colorspace) {
     if (colorspace == EGL_GL_COLORSPACE_LINEAR_KHR) {
-        switch (fmt) {
-            case HAL_PIXEL_FORMAT_sRGB_A_8888: return HAL_PIXEL_FORMAT_RGBA_8888;
-            case HAL_PIXEL_FORMAT_sRGB_X_8888: return HAL_PIXEL_FORMAT_RGBX_8888;
-        }
+        return HAL_DATASPACE_SRGB_LINEAR;
     } else if (colorspace == EGL_GL_COLORSPACE_SRGB_KHR) {
-        switch (fmt) {
-            case HAL_PIXEL_FORMAT_RGBA_8888: return HAL_PIXEL_FORMAT_sRGB_A_8888;
-            case HAL_PIXEL_FORMAT_RGBX_8888: return HAL_PIXEL_FORMAT_sRGB_X_8888;
-        }
+        return HAL_DATASPACE_SRGB;
     }
-    return fmt;
+    return dataSpace;
 }
 
 EGLSurface eglCreateWindowSurface(  EGLDisplay dpy, EGLConfig config,
@@ -424,6 +430,7 @@
 
         // by default, just pick RGBA_8888
         EGLint format = HAL_PIXEL_FORMAT_RGBA_8888;
+        android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
 
         EGLint a = 0;
         cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_ALPHA_SIZE, &a);
@@ -449,7 +456,7 @@
             for (const EGLint* attr = attrib_list; *attr != EGL_NONE; attr += 2) {
                 if (*attr == EGL_GL_COLORSPACE_KHR) {
                     if (ENABLE_EGL_KHR_GL_COLORSPACE) {
-                        format = modifyFormatColorspace(format, *(attr+1));
+                        dataSpace = modifyBufferDataspace(dataSpace, *(attr+1));
                     } else {
                         // Normally we'd pass through unhandled attributes to
                         // the driver. But in case the driver implements this
@@ -473,6 +480,16 @@
             }
         }
 
+        if (dataSpace != 0) {
+            int err = native_window_set_buffers_data_space(window, dataSpace);
+            if (err != 0) {
+                ALOGE("error setting native window pixel dataSpace: %s (%d)",
+                        strerror(-err), err);
+                native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
+                return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+            }
+        }
+
         // the EGL spec requires that a new EGLSurface default to swap interval
         // 1, so explicitly set that on the window here.
         ANativeWindow* anw = reinterpret_cast<ANativeWindow*>(window);
@@ -1015,7 +1032,8 @@
     Mutex mMutex;
 };
 
-EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
+EGLBoolean eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface draw,
+        EGLint *rects, EGLint n_rects)
 {
     ATRACE_CALL();
     clearError();
@@ -1074,7 +1092,38 @@
         }
     }
 
-    return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface);
+    if (n_rects == 0) {
+        return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface);
+    }
+
+    Vector<android_native_rect_t> androidRects;
+    for (int r = 0; r < n_rects; ++r) {
+        int offset = r * 4;
+        int x = rects[offset];
+        int y = rects[offset + 1];
+        int width = rects[offset + 2];
+        int height = rects[offset + 3];
+        android_native_rect_t androidRect;
+        androidRect.left = x;
+        androidRect.top = y + height;
+        androidRect.right = x + width;
+        androidRect.bottom = y;
+        androidRects.push_back(androidRect);
+    }
+    native_window_set_surface_damage(s->win.get(), androidRects.array(),
+            androidRects.size());
+
+    if (s->cnx->egl.eglSwapBuffersWithDamageKHR) {
+        return s->cnx->egl.eglSwapBuffersWithDamageKHR(dp->disp.dpy, s->surface,
+                rects, n_rects);
+    } else {
+        return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface);
+    }
+}
+
+EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
+{
+    return eglSwapBuffersWithDamageKHR(dpy, surface, NULL, 0);
 }
 
 EGLBoolean eglCopyBuffers(  EGLDisplay dpy, EGLSurface surface,
@@ -1563,3 +1612,32 @@
 
     return setErrorQuiet(EGL_BAD_DISPLAY, 0);
 }
+
+// ----------------------------------------------------------------------------
+// Partial update extension
+// ----------------------------------------------------------------------------
+EGLBoolean eglSetDamageRegionKHR(EGLDisplay dpy, EGLSurface surface,
+        EGLint *rects, EGLint n_rects)
+{
+    clearError();
+
+    const egl_display_ptr dp = validate_display(dpy);
+    if (!dp) {
+        setError(EGL_BAD_DISPLAY, EGL_FALSE);
+        return EGL_FALSE;
+    }
+
+    SurfaceRef _s(dp.get(), surface);
+    if (!_s.get()) {
+        setError(EGL_BAD_SURFACE, EGL_FALSE);
+        return EGL_FALSE;
+    }
+
+    egl_surface_t const * const s = get_surface(surface);
+    if (s->cnx->egl.eglSetDamageRegionKHR) {
+        return s->cnx->egl.eglSetDamageRegionKHR(dp->disp.dpy, s->surface,
+                rects, n_rects);
+    }
+
+    return EGL_FALSE;
+}
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index 7784ca6..ec59235 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -57,7 +57,7 @@
 egl_display_t egl_display_t::sDisplay[NUM_DISPLAYS];
 
 egl_display_t::egl_display_t() :
-    magic('_dpy'), finishOnSwap(false), traceGpuCompletion(false), refs(0) {
+    magic('_dpy'), finishOnSwap(false), traceGpuCompletion(false), refs(0), eglIsInitialized(false) {
 }
 
 egl_display_t::~egl_display_t() {
@@ -120,163 +120,188 @@
 
 EGLBoolean egl_display_t::initialize(EGLint *major, EGLint *minor) {
 
-    Mutex::Autolock _l(lock);
+    {
+        Mutex::Autolock _rf(refLock);
 
-    if (refs > 0) {
+        refs++;
+        if (refs > 1) {
+            if (major != NULL)
+                *major = VERSION_MAJOR;
+            if (minor != NULL)
+                *minor = VERSION_MINOR;
+            while(!eglIsInitialized) refCond.wait(refLock);
+            return EGL_TRUE;
+        }
+
+        while(eglIsInitialized) refCond.wait(refLock);
+    }
+
+    {
+        Mutex::Autolock _l(lock);
+
+#if EGL_TRACE
+
+        // Called both at early_init time and at this time. (Early_init is pre-zygote, so
+        // the information from that call may be stale.)
+        initEglTraceLevel();
+        initEglDebugLevel();
+
+#endif
+
+        setGLHooksThreadSpecific(&gHooksNoContext);
+
+        // initialize each EGL and
+        // build our own extension string first, based on the extension we know
+        // and the extension supported by our client implementation
+
+        egl_connection_t* const cnx = &gEGLImpl;
+        cnx->major = -1;
+        cnx->minor = -1;
+        if (cnx->dso) {
+            EGLDisplay idpy = disp.dpy;
+            if (cnx->egl.eglInitialize(idpy, &cnx->major, &cnx->minor)) {
+                //ALOGD("initialized dpy=%p, ver=%d.%d, cnx=%p",
+                //        idpy, cnx->major, cnx->minor, cnx);
+
+                // display is now initialized
+                disp.state = egl_display_t::INITIALIZED;
+
+                // get the query-strings for this display for each implementation
+                disp.queryString.vendor = cnx->egl.eglQueryString(idpy,
+                        EGL_VENDOR);
+                disp.queryString.version = cnx->egl.eglQueryString(idpy,
+                        EGL_VERSION);
+                disp.queryString.extensions = cnx->egl.eglQueryString(idpy,
+                        EGL_EXTENSIONS);
+                disp.queryString.clientApi = cnx->egl.eglQueryString(idpy,
+                        EGL_CLIENT_APIS);
+
+            } else {
+                ALOGW("eglInitialize(%p) failed (%s)", idpy,
+                        egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
+            }
+        }
+
+        // the query strings are per-display
+        mVendorString.setTo(sVendorString);
+        mVersionString.setTo(sVersionString);
+        mClientApiString.setTo(sClientApiString);
+
+        mExtensionString.setTo(gBuiltinExtensionString);
+        char const* start = gExtensionString;
+        char const* end;
+        do {
+            // find the space separating this extension for the next one
+            end = strchr(start, ' ');
+            if (end) {
+                // length of the extension string
+                const size_t len = end - start;
+                if (len) {
+                    // NOTE: we could avoid the copy if we had strnstr.
+                    const String8 ext(start, len);
+                    if (findExtension(disp.queryString.extensions, ext.string(),
+                            len)) {
+                        mExtensionString.append(start, len+1);
+                    }
+                }
+                // process the next extension string, and skip the space.
+                start = end + 1;
+            }
+        } while (end);
+
+        egl_cache_t::get()->initialize(this);
+
+        char value[PROPERTY_VALUE_MAX];
+        property_get("debug.egl.finish", value, "0");
+        if (atoi(value)) {
+            finishOnSwap = true;
+        }
+
+        property_get("debug.egl.traceGpuCompletion", value, "0");
+        if (atoi(value)) {
+            traceGpuCompletion = true;
+        }
+
         if (major != NULL)
             *major = VERSION_MAJOR;
         if (minor != NULL)
             *minor = VERSION_MINOR;
-        refs++;
-        return EGL_TRUE;
+
+        mHibernation.setDisplayValid(true);
     }
 
-#if EGL_TRACE
-
-    // Called both at early_init time and at this time. (Early_init is pre-zygote, so
-    // the information from that call may be stale.)
-    initEglTraceLevel();
-    initEglDebugLevel();
-
-#endif
-
-    setGLHooksThreadSpecific(&gHooksNoContext);
-
-    // initialize each EGL and
-    // build our own extension string first, based on the extension we know
-    // and the extension supported by our client implementation
-
-    egl_connection_t* const cnx = &gEGLImpl;
-    cnx->major = -1;
-    cnx->minor = -1;
-    if (cnx->dso) {
-        EGLDisplay idpy = disp.dpy;
-        if (cnx->egl.eglInitialize(idpy, &cnx->major, &cnx->minor)) {
-            //ALOGD("initialized dpy=%p, ver=%d.%d, cnx=%p",
-            //        idpy, cnx->major, cnx->minor, cnx);
-
-            // display is now initialized
-            disp.state = egl_display_t::INITIALIZED;
-
-            // get the query-strings for this display for each implementation
-            disp.queryString.vendor = cnx->egl.eglQueryString(idpy,
-                    EGL_VENDOR);
-            disp.queryString.version = cnx->egl.eglQueryString(idpy,
-                    EGL_VERSION);
-            disp.queryString.extensions = cnx->egl.eglQueryString(idpy,
-                    EGL_EXTENSIONS);
-            disp.queryString.clientApi = cnx->egl.eglQueryString(idpy,
-                    EGL_CLIENT_APIS);
-
-        } else {
-            ALOGW("eglInitialize(%p) failed (%s)", idpy,
-                    egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
-        }
+    {
+        Mutex::Autolock _rf(refLock);
+        eglIsInitialized = true;
+        refCond.broadcast();
     }
 
-    // the query strings are per-display
-    mVendorString.setTo(sVendorString);
-    mVersionString.setTo(sVersionString);
-    mClientApiString.setTo(sClientApiString);
-
-    mExtensionString.setTo(gBuiltinExtensionString);
-    char const* start = gExtensionString;
-    char const* end;
-    do {
-        // find the space separating this extension for the next one
-        end = strchr(start, ' ');
-        if (end) {
-            // length of the extension string
-            const size_t len = end - start;
-            if (len) {
-                // NOTE: we could avoid the copy if we had strnstr.
-                const String8 ext(start, len);
-                if (findExtension(disp.queryString.extensions, ext.string(),
-                        len)) {
-                    mExtensionString.append(start, len+1);
-                }
-            }
-            // process the next extension string, and skip the space.
-            start = end + 1;
-        }
-    } while (end);
-
-    egl_cache_t::get()->initialize(this);
-
-    char value[PROPERTY_VALUE_MAX];
-    property_get("debug.egl.finish", value, "0");
-    if (atoi(value)) {
-        finishOnSwap = true;
-    }
-
-    property_get("debug.egl.traceGpuCompletion", value, "0");
-    if (atoi(value)) {
-        traceGpuCompletion = true;
-    }
-
-    refs++;
-    if (major != NULL)
-        *major = VERSION_MAJOR;
-    if (minor != NULL)
-        *minor = VERSION_MINOR;
-
-    mHibernation.setDisplayValid(true);
-
     return EGL_TRUE;
 }
 
 EGLBoolean egl_display_t::terminate() {
 
-    Mutex::Autolock _l(lock);
+    {
+        Mutex::Autolock _rl(refLock);
+        if (refs == 0) {
+            /*
+             * From the EGL spec (3.2):
+             * "Termination of a display that has already been terminated,
+             *  (...), is allowed, but the only effect of such a call is
+             *  to return EGL_TRUE (...)
+             */
+            return EGL_TRUE;
+        }
 
-    if (refs == 0) {
-        /*
-         * From the EGL spec (3.2):
-         * "Termination of a display that has already been terminated,
-         *  (...), is allowed, but the only effect of such a call is
-         *  to return EGL_TRUE (...)
-         */
-        return EGL_TRUE;
-    }
-
-    // this is specific to Android, display termination is ref-counted.
-    if (refs > 1) {
+        // this is specific to Android, display termination is ref-counted.
         refs--;
-        return EGL_TRUE;
+        if (refs > 0) {
+            return EGL_TRUE;
+        }
     }
 
     EGLBoolean res = EGL_FALSE;
-    egl_connection_t* const cnx = &gEGLImpl;
-    if (cnx->dso && disp.state == egl_display_t::INITIALIZED) {
-        if (cnx->egl.eglTerminate(disp.dpy) == EGL_FALSE) {
-            ALOGW("eglTerminate(%p) failed (%s)", disp.dpy,
-                    egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
+
+    {
+        Mutex::Autolock _l(lock);
+
+        egl_connection_t* const cnx = &gEGLImpl;
+        if (cnx->dso && disp.state == egl_display_t::INITIALIZED) {
+            if (cnx->egl.eglTerminate(disp.dpy) == EGL_FALSE) {
+                ALOGW("eglTerminate(%p) failed (%s)", disp.dpy,
+                        egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
+            }
+            // REVISIT: it's unclear what to do if eglTerminate() fails
+            disp.state = egl_display_t::TERMINATED;
+            res = EGL_TRUE;
         }
-        // REVISIT: it's unclear what to do if eglTerminate() fails
-        disp.state = egl_display_t::TERMINATED;
-        res = EGL_TRUE;
+
+        mHibernation.setDisplayValid(false);
+
+        // Reset the extension string since it will be regenerated if we get
+        // reinitialized.
+        mExtensionString.setTo("");
+
+        // Mark all objects remaining in the list as terminated, unless
+        // there are no reference to them, it which case, we're free to
+        // delete them.
+        size_t count = objects.size();
+        ALOGW_IF(count, "eglTerminate() called w/ %d objects remaining", count);
+        for (size_t i=0 ; i<count ; i++) {
+            egl_object_t* o = objects.itemAt(i);
+            o->destroy();
+        }
+
+        // this marks all object handles are "terminated"
+        objects.clear();
     }
 
-    mHibernation.setDisplayValid(false);
-
-    // Reset the extension string since it will be regenerated if we get
-    // reinitialized.
-    mExtensionString.setTo("");
-
-    // Mark all objects remaining in the list as terminated, unless
-    // there are no reference to them, it which case, we're free to
-    // delete them.
-    size_t count = objects.size();
-    ALOGW_IF(count, "eglTerminate() called w/ %d objects remaining", count);
-    for (size_t i=0 ; i<count ; i++) {
-        egl_object_t* o = objects.itemAt(i);
-        o->destroy();
+    {
+        Mutex::Autolock _rl(refLock);
+        eglIsInitialized = false;
+        refCond.broadcast();
     }
 
-    // this marks all object handles are "terminated"
-    objects.clear();
-
-    refs--;
     return res;
 }
 
diff --git a/opengl/libs/EGL/egl_display.h b/opengl/libs/EGL/egl_display.h
index 0a6e425..2d86295 100644
--- a/opengl/libs/EGL/egl_display.h
+++ b/opengl/libs/EGL/egl_display.h
@@ -131,7 +131,9 @@
     void leave() { return mHibernation.decWakeCount(HibernationMachine::WEAK); }
 
             uint32_t                    refs;
-    mutable Mutex                       lock;
+            bool                        eglIsInitialized;
+    mutable Mutex                       lock, refLock;
+    mutable Condition                   refCond;
             SortedVector<egl_object_t*> objects;
             String8 mVendorString;
             String8 mVersionString;
diff --git a/opengl/libs/EGL/egl_entries.in b/opengl/libs/EGL/egl_entries.in
index 70d0e52..1e27cb6 100644
--- a/opengl/libs/EGL/egl_entries.in
+++ b/opengl/libs/EGL/egl_entries.in
@@ -89,4 +89,9 @@
 /* IMG extensions */
 
 EGL_ENTRY(EGLBoolean, eglHibernateProcessIMG, void)
-EGL_ENTRY(EGLBoolean, eglAwakenProcessIMG, void)
\ No newline at end of file
+EGL_ENTRY(EGLBoolean, eglAwakenProcessIMG, void)
+
+/* Partial update extensions */
+
+EGL_ENTRY(EGLBoolean, eglSwapBuffersWithDamageKHR, EGLDisplay, EGLSurface, EGLint *, EGLint)
+EGL_ENTRY(EGLBoolean, eglSetDamageRegionKHR, EGLDisplay, EGLSurface, EGLint *, EGLint)
diff --git a/opengl/libs/EGL/getProcAddress.cpp b/opengl/libs/EGL/getProcAddress.cpp
index 2b2b227..660af33 100644
--- a/opengl/libs/EGL/getProcAddress.cpp
+++ b/opengl/libs/EGL/getProcAddress.cpp
@@ -163,6 +163,7 @@
             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"                               \
diff --git a/opengl/libs/GLES2/gl2.cpp b/opengl/libs/GLES2/gl2.cpp
index 40555d7..d5dc012 100644
--- a/opengl/libs/GLES2/gl2.cpp
+++ b/opengl/libs/GLES2/gl2.cpp
@@ -163,6 +163,7 @@
         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"                                \
diff --git a/opengl/libs/GLES_CM/gl.cpp b/opengl/libs/GLES_CM/gl.cpp
index 0b30956..b1b31f8 100644
--- a/opengl/libs/GLES_CM/gl.cpp
+++ b/opengl/libs/GLES_CM/gl.cpp
@@ -219,6 +219,7 @@
         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"                                \
diff --git a/opengl/tests/EGLTest/EGL_test.cpp b/opengl/tests/EGLTest/EGL_test.cpp
index a4364c6..d69a275 100644
--- a/opengl/tests/EGLTest/EGL_test.cpp
+++ b/opengl/tests/EGLTest/EGL_test.cpp
@@ -101,7 +101,7 @@
     EXPECT_TRUE(eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs));
 
     struct DummyConsumer : public BnConsumerListener {
-        virtual void onFrameAvailable() {}
+        virtual void onFrameAvailable(const BufferItem& /* item */) {}
         virtual void onBuffersReleased() {}
         virtual void onSidebandStreamChanged() {}
     };
diff --git a/opengl/tools/glgen/stubs/egl/eglGetDisplay.cpp b/opengl/tools/glgen/stubs/egl/eglGetDisplay.cpp
index 003efd3..2abc916 100755
--- a/opengl/tools/glgen/stubs/egl/eglGetDisplay.cpp
+++ b/opengl/tools/glgen/stubs/egl/eglGetDisplay.cpp
@@ -14,7 +14,8 @@
 android_eglGetDisplayInt
   (JNIEnv *_env, jobject _this, jint display_id) {
 
-    if ((EGLNativeDisplayType)display_id != EGL_DEFAULT_DISPLAY) {
+    if (static_cast<uintptr_t>(display_id) !=
+        reinterpret_cast<uintptr_t>(EGL_DEFAULT_DISPLAY)) {
         jniThrowException(_env, "java/lang/UnsupportedOperationException", "eglGetDisplay");
         return 0;
     }
diff --git a/opengl/tools/glgen/stubs/gles11/glDrawElementsInstanced.cpp b/opengl/tools/glgen/stubs/gles11/glDrawElementsInstanced.cpp
index 41df486..d844152 100644
--- a/opengl/tools/glgen/stubs/gles11/glDrawElementsInstanced.cpp
+++ b/opengl/tools/glgen/stubs/gles11/glDrawElementsInstanced.cpp
@@ -32,7 +32,7 @@
         (GLenum)mode,
         (GLsizei)count,
         (GLenum)type,
-        (GLvoid *)indicesOffset,
+        (GLvoid *)static_cast<uintptr_t>(indicesOffset),
         (GLsizei)instanceCount
     );
 }
diff --git a/opengl/tools/glgen/stubs/gles11/glGetTransformFeedbackVarying.cpp b/opengl/tools/glgen/stubs/gles11/glGetTransformFeedbackVarying.cpp
index 0514fe9..a977693 100644
--- a/opengl/tools/glgen/stubs/gles11/glGetTransformFeedbackVarying.cpp
+++ b/opengl/tools/glgen/stubs/gles11/glGetTransformFeedbackVarying.cpp
@@ -157,7 +157,11 @@
         (GLsizei *)length,
         (GLint *)size,
         (GLenum *)type,
-        (char *)name
+        // The cast below is incorrect. The driver will end up writing to the
+        // address specified by name, which will always crash the process since
+        // it is guaranteed to be in low memory. The additional static_cast
+        // suppresses the warning for now. http://b/19478262
+        (char *)static_cast<uintptr_t>(name)
     );
     if (_typeArray) {
         releasePointer(_env, _typeArray, type, JNI_TRUE);
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index 1a6ff33..9157bc1 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -477,7 +477,6 @@
         const InputWindowInfo* windowInfo = windowHandle->getInfo();
         if (windowInfo->displayId == displayId) {
             int32_t flags = windowInfo->layoutParamsFlags;
-            int32_t privateFlags = windowInfo->layoutParamsPrivateFlags;
 
             if (windowInfo->visible) {
                 if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
@@ -489,11 +488,6 @@
                     }
                 }
             }
-
-            if (privateFlags & InputWindowInfo::PRIVATE_FLAG_SYSTEM_ERROR) {
-                // Error window is on top but not visible, so touch is dropped.
-                return NULL;
-            }
         }
     }
     return NULL;
@@ -1190,7 +1184,6 @@
         int32_t y = int32_t(entry->pointerCoords[pointerIndex].
                 getAxisValue(AMOTION_EVENT_AXIS_Y));
         sp<InputWindowHandle> newTouchedWindowHandle;
-        sp<InputWindowHandle> topErrorWindowHandle;
         bool isTouchModal = false;
 
         // Traverse windows from front to back to find touched window and outside targets.
@@ -1202,13 +1195,6 @@
                 continue; // wrong display
             }
 
-            int32_t privateFlags = windowInfo->layoutParamsPrivateFlags;
-            if (privateFlags & InputWindowInfo::PRIVATE_FLAG_SYSTEM_ERROR) {
-                if (topErrorWindowHandle == NULL) {
-                    topErrorWindowHandle = windowHandle;
-                }
-            }
-
             int32_t flags = windowInfo->layoutParamsFlags;
             if (windowInfo->visible) {
                 if (! (flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
@@ -1233,17 +1219,6 @@
             }
         }
 
-        // If there is an error window but it is not taking focus (typically because
-        // it is invisible) then wait for it.  Any other focused window may in
-        // fact be in ANR state.
-        if (topErrorWindowHandle != NULL && newTouchedWindowHandle != topErrorWindowHandle) {
-            injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
-                    NULL, NULL, nextWakeupTime,
-                    "Waiting because a system error window is about to be displayed.");
-            injectionPermission = INJECTION_PERMISSION_UNKNOWN;
-            goto Unresponsive;
-        }
-
         // Figure out whether splitting will be allowed for this window.
         if (newTouchedWindowHandle != NULL
                 && newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index 8634e42..318c85f 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -4315,7 +4315,7 @@
             bottom = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale + mXTranslate;
             top = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale + mXTranslate;
             orientation -= M_PI_2;
-            if (orientation < mOrientedRanges.orientation.min) {
+            if (mOrientedRanges.haveOrientation && orientation < mOrientedRanges.orientation.min) {
                 orientation += (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
             }
             break;
@@ -4327,7 +4327,7 @@
             bottom = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
             top = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale + mYTranslate;
             orientation -= M_PI;
-            if (orientation < mOrientedRanges.orientation.min) {
+            if (mOrientedRanges.haveOrientation && orientation < mOrientedRanges.orientation.min) {
                 orientation += (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
             }
             break;
@@ -4339,7 +4339,7 @@
             bottom = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
             top = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
             orientation += M_PI_2;
-            if (orientation > mOrientedRanges.orientation.max) {
+            if (mOrientedRanges.haveOrientation && orientation > mOrientedRanges.orientation.max) {
                 orientation -= (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
             }
             break;
diff --git a/services/inputflinger/InputWindow.h b/services/inputflinger/InputWindow.h
index 5879c84..42457ce 100644
--- a/services/inputflinger/InputWindow.h
+++ b/services/inputflinger/InputWindow.h
@@ -64,11 +64,6 @@
         FLAG_NEEDS_MENU_KEY = 0x40000000,
     };
 
-    // Private Window flags from WindowManager.LayoutParams
-    enum {
-        PRIVATE_FLAG_SYSTEM_ERROR = 0x00000100,
-    };
-
     // Window types from WindowManager.LayoutParams
     enum {
         FIRST_APPLICATION_WINDOW = 1,
@@ -119,7 +114,6 @@
     sp<InputChannel> inputChannel;
     String8 name;
     int32_t layoutParamsFlags;
-    int32_t layoutParamsPrivateFlags;
     int32_t layoutParamsType;
     nsecs_t dispatchingTimeout;
     int32_t frameLeft;
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 9b2acea..a857366 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -191,6 +191,8 @@
             mSensorEventScratch = new sensors_event_t[minBufferSize];
             mMapFlushEventsToConnections = new SensorEventConnection const * [minBufferSize];
 
+            mAckReceiver = new SensorEventAckReceiver(this);
+            mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
             mInitCheck = NO_ERROR;
             run("SensorService", PRIORITY_URGENT_DISPLAY);
         }
@@ -386,8 +388,6 @@
     SensorDevice& device(SensorDevice::getInstance());
     const size_t vcount = mVirtualSensorList.size();
 
-    SensorEventAckReceiver sender(this);
-    sender.run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
     const int halVersion = device.getHalDeviceVersion();
     do {
         ssize_t count = device.poll(mSensorEventBuffer, numEventMax);
@@ -408,16 +408,7 @@
         // result in a deadlock as ~SensorEventConnection() needs to acquire mLock again for
         // cleanup. So copy all the strongPointers to a vector before the lock is acquired.
         SortedVector< sp<SensorEventConnection> > activeConnections;
-        {
-            Mutex::Autolock _l(mLock);
-            for (size_t i=0 ; i < mActiveConnections.size(); ++i) {
-                sp<SensorEventConnection> connection(mActiveConnections[i].promote());
-                if (connection != 0) {
-                    activeConnections.add(connection);
-                }
-            }
-        }
-
+        populateActiveConnections(&activeConnections);
         Mutex::Autolock _l(mLock);
         // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The
         // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock,
@@ -433,8 +424,7 @@
         }
 
         if (bufferHasWakeUpEvent && !mWakeLockAcquired) {
-            acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
-            mWakeLockAcquired = true;
+            setWakeLockAcquiredLocked(true);
         }
         recordLastValueLocked(mSensorEventBuffer, count);
 
@@ -522,8 +512,7 @@
         }
 
         if (mWakeLockAcquired && !needsWakeLock) {
-            release_wake_lock(WAKE_LOCK_NAME);
-            mWakeLockAcquired = false;
+            setWakeLockAcquiredLocked(false);
         }
     } while (!Thread::exitPending());
 
@@ -536,11 +525,52 @@
     return mLooper;
 }
 
+void SensorService::resetAllWakeLockRefCounts() {
+    SortedVector< sp<SensorEventConnection> > activeConnections;
+    populateActiveConnections(&activeConnections);
+    {
+        Mutex::Autolock _l(mLock);
+        for (size_t i=0 ; i < activeConnections.size(); ++i) {
+            if (activeConnections[i] != 0) {
+                activeConnections[i]->resetWakeLockRefCount();
+            }
+        }
+        setWakeLockAcquiredLocked(false);
+    }
+}
+
+void SensorService::setWakeLockAcquiredLocked(bool acquire) {
+    if (acquire) {
+        if (!mWakeLockAcquired) {
+            acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
+            mWakeLockAcquired = true;
+        }
+        mLooper->wake();
+    } else {
+        if (mWakeLockAcquired) {
+            release_wake_lock(WAKE_LOCK_NAME);
+            mWakeLockAcquired = false;
+        }
+    }
+}
+
+
+bool SensorService::isWakeLockAcquired() {
+    Mutex::Autolock _l(mLock);
+    return mWakeLockAcquired;
+}
+
 bool SensorService::SensorEventAckReceiver::threadLoop() {
     ALOGD("new thread SensorEventAckReceiver");
+    sp<Looper> looper = mService->getLooper();
     do {
-        sp<Looper> looper = mService->getLooper();
-        looper->pollOnce(-1);
+        bool wakeLockAcquired = mService->isWakeLockAcquired();
+        int timeout = -1;
+        if (wakeLockAcquired) timeout = 5000;
+        int ret = looper->pollOnce(timeout);
+        if (ret == ALOOPER_POLL_TIMEOUT) {
+           mService->resetAllWakeLockRefCounts();
+        }
     } while(!Thread::exitPending());
     return false;
 }
@@ -711,10 +741,7 @@
                 sensors_event_t& event(mLastEventSeen.editValueFor(handle));
                 if (event.version == sizeof(sensors_event_t)) {
                     if (isWakeUpSensorEvent(event) && !mWakeLockAcquired) {
-                        acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
-                        mWakeLockAcquired = true;
-                        ALOGD_IF(DEBUG_CONNECTIONS, "acquired wakelock for on_change sensor %s",
-                                                        WAKE_LOCK_NAME);
+                        setWakeLockAcquiredLocked(true);
                     }
                     connection->sendEvents(&event, 1, NULL);
                     if (!connection->needsWakeLock() && mWakeLockAcquired) {
@@ -919,8 +946,26 @@
         }
     }
     if (releaseLock) {
-        release_wake_lock(WAKE_LOCK_NAME);
-        mWakeLockAcquired = false;
+        setWakeLockAcquiredLocked(false);
+    }
+}
+
+void SensorService::sendEventsFromCache(const sp<SensorEventConnection>& connection) {
+    Mutex::Autolock _l(mLock);
+    connection->writeToSocketFromCache();
+    if (connection->needsWakeLock()) {
+        setWakeLockAcquiredLocked(true);
+    }
+}
+
+void SensorService::populateActiveConnections(
+        SortedVector< sp<SensorEventConnection> >* activeConnections) {
+    Mutex::Autolock _l(mLock);
+    for (size_t i=0 ; i < mActiveConnections.size(); ++i) {
+        sp<SensorEventConnection> connection(mActiveConnections[i].promote());
+        if (connection != 0) {
+            activeConnections->add(connection);
+        }
     }
 }
 
@@ -1010,6 +1055,11 @@
     return !mDead && mWakeLockRefCount > 0;
 }
 
+void SensorService::SensorEventConnection::resetWakeLockRefCount() {
+    Mutex::Autolock _l(mConnectionLock);
+    mWakeLockRefCount = 0;
+}
+
 void SensorService::SensorEventConnection::dump(String8& result) {
     Mutex::Autolock _l(mConnectionLock);
     result.appendFormat("\t WakeLockRefCount %d | uid %d | cache size %d | max cache size %d\n",
@@ -1331,11 +1381,14 @@
         while (flushInfo.mPendingFlushEventsToSend > 0) {
             const int sensor_handle = mSensorInfo.keyAt(i);
             flushCompleteEvent.meta_data.sensor = sensor_handle;
-            if (mService->getSensorFromHandle(sensor_handle).isWakeUpSensor()) {
+            bool wakeUpSensor = mService->getSensorFromHandle(sensor_handle).isWakeUpSensor();
+            if (wakeUpSensor) {
+               ++mWakeLockRefCount;
                flushCompleteEvent.flags |= WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
             }
             ssize_t size = SensorEventQueue::write(mChannel, &flushCompleteEvent, 1);
             if (size < 0) {
+                if (wakeUpSensor) --mWakeLockRefCount;
                 return;
             }
             ALOGD_IF(DEBUG_CONNECTIONS, "sent dropped flush complete event==%d ",
@@ -1345,11 +1398,12 @@
     }
 }
 
-void SensorService::SensorEventConnection::writeToSocketFromCacheLocked() {
+void SensorService::SensorEventConnection::writeToSocketFromCache() {
     // At a time write at most half the size of the receiver buffer in SensorEventQueue OR
     // half the size of the socket buffer allocated in BitTube whichever is smaller.
     const int maxWriteSize = helpers::min(SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT/2,
             int(mService->mSocketBufferSize/(sizeof(sensors_event_t)*2)));
+    Mutex::Autolock _l(mConnectionLock);
     // Send pending flush complete events (if any)
     sendPendingFlushEventsLocked();
     for (int numEventsSent = 0; numEventsSent < mCacheSize;) {
@@ -1500,9 +1554,8 @@
     }
 
     if (events & ALOOPER_EVENT_OUTPUT) {
-        // send sensor data that is stored in mEventCache.
-        Mutex::Autolock _l(mConnectionLock);
-        writeToSocketFromCacheLocked();
+        // send sensor data that is stored in mEventCache for this connection.
+        mService->sendEventsFromCache(this);
     }
     return 1;
 }
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 2e16677..e9ca3a5 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -108,7 +108,7 @@
         void sendPendingFlushEventsLocked();
 
         // Writes events from mEventCache to the socket.
-        void writeToSocketFromCacheLocked();
+        void writeToSocketFromCache();
 
         // Compute the approximate cache size from the FIFO sizes of various sensors registered for
         // this connection. Wake up and non-wake up sensors have separate FIFOs but FIFO may be
@@ -189,6 +189,7 @@
         void setFirstFlushPending(int32_t handle, bool value);
         void dump(String8& result);
         bool needsWakeLock();
+        void resetWakeLockRefCount();
 
         uid_t getUid() const { return mUid; }
     };
@@ -237,12 +238,29 @@
     // corresponding applications, if yes the wakelock is released.
     void checkWakeLockState();
     void checkWakeLockStateLocked();
+    bool isWakeLockAcquired();
     bool isWakeUpSensorEvent(const sensors_event_t& event) const;
 
     SensorRecord * getSensorRecord(int handle);
 
     sp<Looper> getLooper() const;
 
+    // Reset mWakeLockRefCounts for all SensorEventConnections to zero. This may happen if
+    // SensorService did not receive any acknowledgements from apps which have registered for
+    // wake_up sensors.
+    void resetAllWakeLockRefCounts();
+
+    // Acquire or release wake_lock. If wake_lock is acquired, set the timeout in the looper to
+    // 5 seconds and wake the looper.
+    void setWakeLockAcquiredLocked(bool acquire);
+
+    // Send events from the event cache for this particular connection.
+    void sendEventsFromCache(const sp<SensorEventConnection>& connection);
+
+    // Promote all weak referecences in mActiveConnections vector to strong references and add them
+    // to the output vector.
+    void populateActiveConnections(SortedVector< sp<SensorEventConnection> >* activeConnections);
+
     // constants
     Vector<Sensor> mSensorList;
     Vector<Sensor> mUserSensorListDebug;
@@ -254,6 +272,7 @@
     // supported or not.
     uint32_t mSocketBufferSize;
     sp<Looper> mLooper;
+    sp<SensorEventAckReceiver> mAckReceiver;
 
     // protected by mLock
     mutable Mutex mLock;
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 342d685..1eb2361 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -83,8 +83,14 @@
     LOCAL_CFLAGS += -DPRESENT_TIME_OFFSET_FROM_VSYNC_NS=0
 endif
 
+ifneq ($(MAX_VIRTUAL_DISPLAY_DIMENSION),)
+    LOCAL_CFLAGS += -DMAX_VIRTUAL_DISPLAY_DIMENSION=$(MAX_VIRTUAL_DISPLAY_DIMENSION)
+else
+    LOCAL_CFLAGS += -DMAX_VIRTUAL_DISPLAY_DIMENSION=0
+endif
+
 LOCAL_CFLAGS += -fvisibility=hidden -Werror=format
-LOCAL_CPPFLAGS := -std=c++11
+LOCAL_CFLAGS += -std=c++11
 
 LOCAL_SHARED_LIBRARIES := \
     libcutils \
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index f9d76d1..6ef3295 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -29,8 +29,9 @@
 #include <EGL/egl.h>
 
 #include <hardware/hardware.h>
-#include <gui/Surface.h>
+#include <gui/BufferItem.h>
 #include <gui/GraphicBufferAlloc.h>
+#include <gui/Surface.h>
 #include <ui/GraphicBuffer.h>
 
 #include "FramebufferSurface.h"
@@ -68,7 +69,7 @@
     mConsumer->setDefaultMaxBufferCount(NUM_FRAMEBUFFER_SURFACE_BUFFERS);
 }
 
-status_t FramebufferSurface::beginFrame(bool /* mustRecompose */) {
+status_t FramebufferSurface::beginFrame(bool /*mustRecompose*/) {
     return NO_ERROR;
 }
 
@@ -86,7 +87,7 @@
 status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence) {
     Mutex::Autolock lock(mMutex);
 
-    BufferQueue::BufferItem item;
+    BufferItem item;
     status_t err = acquireBufferLocked(&item, 0);
     if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
         outBuffer = mCurrentBuffer;
@@ -122,7 +123,7 @@
 }
 
 // Overrides ConsumerBase::onFrameAvailable(), does not call base class impl.
-void FramebufferSurface::onFrameAvailable() {
+void FramebufferSurface::onFrameAvailable(const BufferItem& /* item */) {
     sp<GraphicBuffer> buf;
     sp<Fence> acquireFence;
     status_t err = nextBuffer(buf, acquireFence);
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
index 6ffc52d..3d17840 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
@@ -53,7 +53,7 @@
 private:
     virtual ~FramebufferSurface() { }; // this class cannot be overloaded
 
-    virtual void onFrameAvailable();
+    virtual void onFrameAvailable(const BufferItem& item);
     virtual void freeBufferLocked(int slotIndex);
 
     virtual void dumpLocked(String8& result, const char* prefix) const;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index edfed49..c8b36ec 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -1020,6 +1020,21 @@
         SharedBuffer const* sb = reg.getSharedBuffer(&visibleRegion.numRects);
         visibleRegion.rects = reinterpret_cast<hwc_rect_t const *>(sb->data());
     }
+    virtual void setSurfaceDamage(const Region& reg) {
+        if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_5)) {
+            return;
+        }
+        hwc_region_t& surfaceDamage = getLayer()->surfaceDamage;
+        // We encode default full-screen damage as INVALID_RECT upstream, but as
+        // 0 rects for HWComposer
+        if (reg.isRect() && reg.getBounds() == Rect::INVALID_RECT) {
+            surfaceDamage.numRects = 0;
+            surfaceDamage.rects = NULL;
+            return;
+        }
+        SharedBuffer const* sb = reg.getSharedBuffer(&surfaceDamage.numRects);
+        surfaceDamage.rects = reinterpret_cast<hwc_rect_t const *>(sb->data());
+    }
     virtual void setSidebandStream(const sp<NativeHandle>& stream) {
         ALOG_ASSERT(stream->handle() != NULL);
         getLayer()->compositionType = HWC_SIDEBAND;
@@ -1050,6 +1065,18 @@
         }
 
         getLayer()->acquireFenceFd = -1;
+
+        if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_5)) {
+            return;
+        }
+
+        hwc_region_t& surfaceDamage = getLayer()->surfaceDamage;
+        sb = SharedBuffer::bufferFromData(surfaceDamage.rects);
+        if (sb) {
+            sb->release();
+            surfaceDamage.numRects = 0;
+            surfaceDamage.rects = NULL;
+        }
     }
 };
 
@@ -1105,8 +1132,6 @@
     case PIXEL_FORMAT_RGB_888:      return String8("RGB_888");
     case PIXEL_FORMAT_RGB_565:      return String8("RGB_565");
     case PIXEL_FORMAT_BGRA_8888:    return String8("BGRA_8888");
-    case PIXEL_FORMAT_sRGB_A_8888:  return String8("sRGB_A_8888");
-    case PIXEL_FORMAT_sRGB_X_8888:  return String8("sRGB_x_8888");
     case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
                                     return String8("ImplDef");
     default:
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index a62ac5c..28d8c65 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -168,6 +168,7 @@
         virtual void setFrame(const Rect& frame) = 0;
         virtual void setCrop(const FloatRect& crop) = 0;
         virtual void setVisibleRegionScreen(const Region& reg) = 0;
+        virtual void setSurfaceDamage(const Region& reg) = 0;
         virtual void setSidebandStream(const sp<NativeHandle>& stream) = 0;
         virtual void setBuffer(const sp<GraphicBuffer>& buffer) = 0;
         virtual void setAcquireFenceFd(int fenceFd) = 0;
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index ef10fa7..11cbdc6 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -18,6 +18,8 @@
 #include "VirtualDisplaySurface.h"
 #include "HWComposer.h"
 
+#include <gui/BufferItem.h>
+
 // ---------------------------------------------------------------------------
 namespace android {
 // ---------------------------------------------------------------------------
@@ -234,6 +236,7 @@
             status_t result = mSource[SOURCE_SINK]->queueBuffer(sslot,
                     QueueBufferInput(
                         systemTime(), false /* isAutoTimestamp */,
+                        HAL_DATASPACE_UNKNOWN,
                         Rect(mSinkBufferWidth, mSinkBufferHeight),
                         NATIVE_WINDOW_SCALING_MODE_FREEZE, 0 /* transform */,
                         true /* async*/,
@@ -435,7 +438,7 @@
         // Now acquire the buffer from the scratch pool -- should be the same
         // slot and fence as we just queued.
         Mutex::Autolock lock(mMutex);
-        BufferQueue::BufferItem item;
+        BufferItem item;
         result = acquireBufferLocked(&item, 0);
         if (result != NO_ERROR)
             return result;
@@ -453,12 +456,13 @@
         // Extract the GLES release fence for HWC to acquire
         int64_t timestamp;
         bool isAutoTimestamp;
+        android_dataspace dataSpace;
         Rect crop;
         int scalingMode;
         uint32_t transform;
         bool async;
-        input.deflate(&timestamp, &isAutoTimestamp, &crop, &scalingMode,
-                &transform, &async, &mFbFence);
+        input.deflate(&timestamp, &isAutoTimestamp, &dataSpace, &crop,
+                &scalingMode, &transform, &async, &mFbFence);
 
         mFbProducerSlot = pslot;
         mOutputFence = mFbFence;
@@ -522,6 +526,10 @@
     // TODO: Should we actually allocate buffers for a virtual display?
 }
 
+status_t VirtualDisplaySurface::allowAllocation(bool /* allow */) {
+    return INVALID_OPERATION;
+}
+
 void VirtualDisplaySurface::updateQueueBufferOutput(
         const QueueBufferOutput& qbo) {
     uint32_t w, h, transformHint, numPendingBuffers;
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
index 0a3f4a1..97af980 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
@@ -115,6 +115,7 @@
     virtual status_t setSidebandStream(const sp<NativeHandle>& stream);
     virtual void allocateBuffers(bool async, uint32_t width, uint32_t height,
             PixelFormat format, uint32_t usage);
+    virtual status_t allowAllocation(bool allow);
 
     //
     // Utility methods
diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp
index 9b6360e..f760200 100644
--- a/services/surfaceflinger/EventThread.cpp
+++ b/services/surfaceflinger/EventThread.cpp
@@ -71,6 +71,11 @@
     mVsyncHintSent = false;
 }
 
+void EventThread::setPhaseOffset(nsecs_t phaseOffset) {
+    Mutex::Autolock _l(mLock);
+    mVSyncSource->setPhaseOffset(phaseOffset);
+}
+
 void EventThread::sendVsyncHintOnLocked() {
     struct itimerspec ts;
     if(!mVsyncHintSent) {
diff --git a/services/surfaceflinger/EventThread.h b/services/surfaceflinger/EventThread.h
index d1c4fcd..9ba179a 100644
--- a/services/surfaceflinger/EventThread.h
+++ b/services/surfaceflinger/EventThread.h
@@ -51,6 +51,7 @@
     virtual ~VSyncSource() {}
     virtual void setVSyncEnabled(bool enable) = 0;
     virtual void setCallback(const sp<Callback>& callback) = 0;
+    virtual void setPhaseOffset(nsecs_t phaseOffset) = 0;
 };
 
 class EventThread : public Thread, private VSyncSource::Callback {
@@ -99,6 +100,8 @@
     void dump(String8& result) const;
     void sendVsyncHintOff();
 
+    void setPhaseOffset(nsecs_t phaseOffset);
+
 private:
     virtual bool        threadLoop();
     virtual void        onFirstRef();
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 91e9a02..7b104c3 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -34,6 +34,7 @@
 #include <ui/GraphicBuffer.h>
 #include <ui/PixelFormat.h>
 
+#include <gui/BufferItem.h>
 #include <gui/Surface.h>
 
 #include "clz.h"
@@ -126,6 +127,10 @@
     mSurfaceFlingerConsumer->setContentsChangedListener(this);
     mSurfaceFlingerConsumer->setName(mName);
 
+    // Set the shadow queue size to 0 to notify the BufferQueue that we are
+    // shadowing it
+    mSurfaceFlingerConsumer->setShadowQueueSize(0);
+
 #ifdef TARGET_DISABLE_TRIPLE_BUFFERING
 #warning "disabling triple buffering"
     mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
@@ -158,11 +163,27 @@
     }
 }
 
-void Layer::onFrameAvailable() {
-    android_atomic_inc(&mQueuedFrames);
+void Layer::onFrameAvailable(const BufferItem& item) {
+    // Add this buffer from our internal queue tracker
+    { // Autolock scope
+        Mutex::Autolock lock(mQueueItemLock);
+        mQueueItems.push_back(item);
+        mSurfaceFlingerConsumer->setShadowQueueSize(mQueueItems.size());
+        android_atomic_inc(&mQueuedFrames);
+    }
+
     mFlinger->signalLayerUpdate();
 }
 
+void Layer::onFrameReplaced(const BufferItem& item) {
+    Mutex::Autolock lock(mQueueItemLock);
+    if (mQueueItems.empty()) {
+        ALOGE("Can't replace a frame on an empty queue");
+        return;
+    }
+    mQueueItems.editItemAt(0) = item;
+}
+
 void Layer::onSidebandStreamChanged() {
     if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
         // mSidebandStreamChanged was false
@@ -277,12 +298,17 @@
 
 Rect Layer::computeBounds() const {
     const Layer::State& s(getDrawingState());
+    return computeBounds(s.activeTransparentRegion);
+}
+
+Rect Layer::computeBounds(const Region& activeTransparentRegion) const {
+    const Layer::State& s(getDrawingState());
     Rect win(s.active.w, s.active.h);
     if (!s.active.crop.isEmpty()) {
         win.intersect(s.active.crop, &win);
     }
     // subtract the transparent region and snap to the bounds
-    return reduce(win, s.activeTransparentRegion);
+    return reduce(win, activeTransparentRegion);
 }
 
 FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
@@ -310,8 +336,12 @@
     activeCrop.intersect(hw->getViewport(), &activeCrop);
     activeCrop = s.transform.inverse().transform(activeCrop);
 
-    // paranoia: make sure the window-crop is constrained in the
-    // window's bounds
+    // This needs to be here as transform.transform(Rect) computes the
+    // transformed rect and then takes the bounding box of the result before
+    // returning. This means
+    // transform.inverse().transform(transform.transform(Rect)) != Rect
+    // in which case we need to make sure the final rect is clipped to the
+    // display bounds.
     activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
 
     // subtract the transparent region and snap to the bounds
@@ -404,7 +434,29 @@
 
     // apply the layer's transform, followed by the display's global transform
     // here we're guaranteed that the layer's transform preserves rects
-    Rect frame(s.transform.transform(computeBounds()));
+    Region activeTransparentRegion(s.activeTransparentRegion);
+    if (!s.active.crop.isEmpty()) {
+        Rect activeCrop(s.active.crop);
+        activeCrop = s.transform.transform(activeCrop);
+        activeCrop.intersect(hw->getViewport(), &activeCrop);
+        activeCrop = s.transform.inverse().transform(activeCrop);
+        // This needs to be here as transform.transform(Rect) computes the
+        // transformed rect and then takes the bounding box of the result before
+        // returning. This means
+        // transform.inverse().transform(transform.transform(Rect)) != Rect
+        // in which case we need to make sure the final rect is clipped to the
+        // display bounds.
+        activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
+        // mark regions outside the crop as transparent
+        activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
+        activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
+                s.active.w, s.active.h));
+        activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
+                activeCrop.left, activeCrop.bottom));
+        activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
+                s.active.w, activeCrop.bottom));
+    }
+    Rect frame(s.transform.transform(computeBounds(activeTransparentRegion)));
     frame.intersect(hw->getViewport(), &frame);
     const Transform& tr(hw->getTransform());
     layer.setFrame(tr.transform(frame));
@@ -466,6 +518,16 @@
     Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
     layer.setVisibleRegionScreen(visible);
 
+    // Pass full-surface damage down untouched
+    if (surfaceDamageRegion.isRect() &&
+            surfaceDamageRegion.getBounds() == Rect::INVALID_RECT) {
+        layer.setSurfaceDamage(surfaceDamageRegion);
+    } else {
+        Region surfaceDamage =
+            tr.transform(surfaceDamageRegion.intersect(hw->getViewport()));
+        layer.setSurfaceDamage(surfaceDamage);
+    }
+
     if (mSidebandStream.get()) {
         layer.setSidebandStream(mSidebandStream);
     } else {
@@ -717,7 +779,6 @@
     switch (format) {
         case HAL_PIXEL_FORMAT_RGBA_8888:
         case HAL_PIXEL_FORMAT_BGRA_8888:
-        case HAL_PIXEL_FORMAT_sRGB_A_8888:
             return false;
     }
     // in all other case, we have no blending (also for unknown formats)
@@ -862,7 +923,7 @@
         const bool resizePending = (c.requested.w != c.active.w) ||
                                    (c.requested.h != c.active.h);
 
-        if (resizePending) {
+        if (resizePending && mSidebandStream == NULL) {
             // don't let Layer::doTransaction update the drawing state
             // if we have a pending resize, unless we are in fixed-size mode.
             // the drawing state will be updated only once we receive a buffer
@@ -871,6 +932,10 @@
             // in particular, we want to make sure the clip (which is part
             // of the geometry state) is latched together with the size but is
             // latched immediately when no resizing is involved.
+            //
+            // If a sideband stream is attached, however, we want to skip this
+            // optimization so that transactions aren't missed when a buffer
+            // never arrives
 
             flags |= eDontUpdateGeometryState;
         }
@@ -988,10 +1053,30 @@
     return true;
 }
 
+void Layer::useSurfaceDamage() {
+    if (mFlinger->mForceFullDamage) {
+        surfaceDamageRegion = Region::INVALID_REGION;
+    } else {
+        surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
+    }
+}
+
+void Layer::useEmptyDamage() {
+    surfaceDamageRegion.clear();
+}
+
 // ----------------------------------------------------------------------------
 // pageflip handling...
 // ----------------------------------------------------------------------------
 
+bool Layer::shouldPresentNow(const DispSync& dispSync) const {
+    Mutex::Autolock lock(mQueueItemLock);
+    nsecs_t expectedPresent =
+            mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
+    return mQueueItems.empty() ?
+            false : mQueueItems[0].mTimestamp < expectedPresent;
+}
+
 bool Layer::onPreComposition() {
     mRefreshPending = false;
     return mQueuedFrames > 0 || mSidebandStreamChanged;
@@ -1040,6 +1125,10 @@
     if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
         // mSidebandStreamChanged was true
         mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
+        if (mSidebandStream != NULL) {
+            setTransactionFlags(eTransactionNeeded);
+            mFlinger->setTransactionFlags(eTraversalNeeded);
+        }
         recomputeVisibleRegions = true;
 
         const State& s(getDrawingState());
@@ -1076,7 +1165,7 @@
             }
 
             virtual bool reject(const sp<GraphicBuffer>& buf,
-                    const IGraphicBufferConsumer::BufferItem& item) {
+                    const BufferItem& item) {
                 if (buf == NULL) {
                     return false;
                 }
@@ -1179,8 +1268,39 @@
             // layer update so we check again at the next opportunity.
             mFlinger->signalLayerUpdate();
             return outDirtyRegion;
+        } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
+            // If the buffer has been rejected, remove it from the shadow queue
+            // and return early
+            Mutex::Autolock lock(mQueueItemLock);
+
+            // Update the BufferQueue with the new shadow queue size after
+            // dropping this item
+            mQueueItems.removeAt(0);
+            mSurfaceFlingerConsumer->setShadowQueueSize(mQueueItems.size());
+
+            android_atomic_dec(&mQueuedFrames);
+            return outDirtyRegion;
         }
 
+        { // Autolock scope
+            auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
+
+            Mutex::Autolock lock(mQueueItemLock);
+
+            // Remove any stale buffers that have been dropped during
+            // updateTexImage
+            while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
+                mQueueItems.removeAt(0);
+                android_atomic_dec(&mQueuedFrames);
+            }
+
+            // Update the BufferQueue with our new shadow queue size, since we
+            // have removed at least one item
+            mQueueItems.removeAt(0);
+            mSurfaceFlingerConsumer->setShadowQueueSize(mQueueItems.size());
+        }
+
+
         // Decrement the queued-frames count.  Signal another event if we
         // have more frames pending.
         if (android_atomic_dec(&mQueuedFrames) > 1) {
@@ -1289,6 +1409,7 @@
 
     s.activeTransparentRegion.dump(result, "transparentRegion");
     visibleRegion.dump(result, "visibleRegion");
+    surfaceDamageRegion.dump(result, "surfaceDamageRegion");
     sp<Client> client(mClientRef.promote());
 
     result.appendFormat(            "      "
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 2ef39e8..46c17e5 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -76,6 +76,7 @@
     Region visibleRegion;
     Region coveredRegion;
     Region visibleNonTransparentRegion;
+    Region surfaceDamageRegion;
 
     // Layer serial number.  This gives layers an explicit ordering, so we
     // have a stable sort order when their layer stack and Z-order are
@@ -137,11 +138,18 @@
     bool setCrop(const Rect& crop);
     bool setLayerStack(uint32_t layerStack);
 
+    // If we have received a new buffer this frame, we will pass its surface
+    // damage down to hardware composer. Otherwise, we must send a region with
+    // one empty rect.
+    void useSurfaceDamage();
+    void useEmptyDamage();
+
     uint32_t getTransactionFlags(uint32_t flags);
     uint32_t setTransactionFlags(uint32_t flags);
 
     void computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
             bool useIdentityTransform) const;
+    Rect computeBounds(const Region& activeTransparentRegion) const;
     Rect computeBounds() const;
 
     sp<IBinder> getHandle();
@@ -209,6 +217,8 @@
     void onLayerDisplayed(const sp<const DisplayDevice>& hw,
             HWComposer::HWCLayerInterface* layer);
 
+    bool shouldPresentNow(const DispSync& dispSync) const;
+
     /*
      * called before composition.
      * returns true if the layer has pending updates.
@@ -329,7 +339,8 @@
 
 private:
     // Interface implementation for SurfaceFlingerConsumer::ContentsChangedListener
-    virtual void onFrameAvailable();
+    virtual void onFrameAvailable(const BufferItem& item);
+    virtual void onFrameReplaced(const BufferItem& item);
     virtual void onSidebandStreamChanged();
 
     void commitTransaction();
@@ -402,6 +413,10 @@
 
     // This layer can be a cursor on some displays.
     bool mPotentialCursor;
+
+    // Local copy of the queued contents of the incoming BufferQueue
+    mutable Mutex mQueueItemLock;
+    Vector<BufferItem> mQueueItems;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/LayerDim.h b/services/surfaceflinger/LayerDim.h
index 60edd91..a0cfca9 100644
--- a/services/surfaceflinger/LayerDim.h
+++ b/services/surfaceflinger/LayerDim.h
@@ -28,7 +28,7 @@
 
 class LayerDim : public Layer
 {
-public:    
+public:
                 LayerDim(SurfaceFlinger* flinger, const sp<Client>& client,
                         const String8& name, uint32_t w, uint32_t h, uint32_t flags);
         virtual ~LayerDim();
@@ -36,8 +36,7 @@
     virtual const char* getTypeId() const { return "LayerDim"; }
     virtual void onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
             bool useIdentityTransform) const;
-    using Layer::isOpaque;
-    virtual bool isOpaque() const         { return false; }
+    virtual bool isOpaque(const Layer::State&) const { return false; }
     virtual bool isSecure() const         { return false; }
     virtual bool isFixedSize() const      { return true; }
     virtual bool isVisible() const;
diff --git a/services/surfaceflinger/MonitoredProducer.cpp b/services/surfaceflinger/MonitoredProducer.cpp
index e4e7d42..9fb555b 100644
--- a/services/surfaceflinger/MonitoredProducer.cpp
+++ b/services/surfaceflinger/MonitoredProducer.cpp
@@ -110,6 +110,10 @@
     mProducer->allocateBuffers(async, width, height, format, usage);
 }
 
+status_t MonitoredProducer::allowAllocation(bool allow) {
+    return mProducer->allowAllocation(allow);
+}
+
 IBinder* MonitoredProducer::onAsBinder() {
     return IInterface::asBinder(mProducer).get();
 }
diff --git a/services/surfaceflinger/MonitoredProducer.h b/services/surfaceflinger/MonitoredProducer.h
index aec3e85..b2f8293 100644
--- a/services/surfaceflinger/MonitoredProducer.h
+++ b/services/surfaceflinger/MonitoredProducer.h
@@ -53,6 +53,7 @@
     virtual status_t setSidebandStream(const sp<NativeHandle>& stream);
     virtual void allocateBuffers(bool async, uint32_t width, uint32_t height,
             PixelFormat format, uint32_t usage);
+    virtual status_t allowAllocation(bool allow);
     virtual IBinder* onAsBinder();
 
 private:
diff --git a/services/surfaceflinger/RenderEngine/Mesh.cpp b/services/surfaceflinger/RenderEngine/Mesh.cpp
index 3f50cb0..ffd9be2 100644
--- a/services/surfaceflinger/RenderEngine/Mesh.cpp
+++ b/services/surfaceflinger/RenderEngine/Mesh.cpp
@@ -16,14 +16,40 @@
 
 #include "Mesh.h"
 
+#include <utils/Log.h>
+
 namespace android {
 
 Mesh::Mesh(Primitive primitive, size_t vertexCount, size_t vertexSize, size_t texCoordSize)
     : mVertexCount(vertexCount), mVertexSize(vertexSize), mTexCoordsSize(texCoordSize),
       mPrimitive(primitive)
 {
-    mVertices = new float[(vertexSize + texCoordSize) * vertexCount];
-    mStride = mVertexSize + mTexCoordsSize;
+    if (vertexCount == 0) {
+        mVertices = new float[1];
+        mVertices[0] = 0.0f;
+        mStride = 0;
+        return;
+    }
+
+    size_t stride = vertexSize + texCoordSize;
+    size_t remainder = (stride * vertexCount) / vertexCount;
+    // Since all of the input parameters are unsigned, if stride is less than
+    // either vertexSize or texCoordSize, it must have overflowed. remainder
+    // will be equal to stride as long as stride * vertexCount doesn't overflow.
+    if ((stride < vertexSize) || (remainder != stride)) {
+        ALOGE("Overflow in Mesh(..., %zu, %zu, %zu)", vertexCount, vertexSize,
+                texCoordSize);
+        mVertices = new float[1];
+        mVertices[0] = 0.0f;
+        mVertexCount = 0;
+        mVertexSize = 0;
+        mTexCoordsSize = 0;
+        mStride = 0;
+        return;
+    }
+
+    mVertices = new float[stride * vertexCount];
+    mStride = stride;
 }
 
 Mesh::~Mesh() {
diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.cpp b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
index 0de5cca..ba11259 100644
--- a/services/surfaceflinger/RenderEngine/ProgramCache.cpp
+++ b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
@@ -199,10 +199,8 @@
             // un-premultiply if needed before linearization
             fs << "gl_FragColor.rgb = gl_FragColor.rgb/gl_FragColor.a;";
         }
-        fs << "gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(2.2));";
         fs << "vec4 transformed = colorMatrix * vec4(gl_FragColor.rgb, 1);";
         fs << "gl_FragColor.rgb = transformed.rgb/transformed.a;";
-        fs << "gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(1.0 / 2.2));";
         if (!needs.isOpaque() && needs.isPremultiplied()) {
             // and re-premultiply if needed after gamma correction
             fs << "gl_FragColor.rgb = gl_FragColor.rgb*gl_FragColor.a;";
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
index 767b714..7cd42e4 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
@@ -219,6 +219,10 @@
     drawMesh(mesh);
 }
 
+void RenderEngine::flush() {
+    glFlush();
+}
+
 void RenderEngine::clearWithColor(float red, float green, float blue, float alpha) {
     glClearColor(red, green, blue, alpha);
     glClear(GL_COLOR_BUFFER_BIT);
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h
index acbff9b..8d7529c 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.h
@@ -67,6 +67,7 @@
     virtual void dump(String8& result);
 
     // helpers
+    void flush();
     void clearWithColor(float red, float green, float blue, float alpha);
     void fillRegionWithColor(const Region& region, uint32_t height,
             float red, float green, float blue, float alpha);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 6a5a39e..715b92f 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -145,6 +145,7 @@
         mDebugInTransaction(0),
         mLastTransactionTime(0),
         mBootFinished(false),
+        mForceFullDamage(false),
         mPrimaryHWVsyncEnabled(false),
         mHWVsyncAvailable(false),
         mDaltonize(false),
@@ -319,17 +320,20 @@
     DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync,
         const char* label) :
             mValue(0),
-            mPhaseOffset(phaseOffset),
             mTraceVsync(traceVsync),
             mVsyncOnLabel(String8::format("VsyncOn-%s", label)),
             mVsyncEventLabel(String8::format("VSYNC-%s", label)),
-            mDispSync(dispSync) {}
+            mDispSync(dispSync),
+            mCallbackMutex(),
+            mCallback(),
+            mVsyncMutex(),
+            mPhaseOffset(phaseOffset),
+            mEnabled(false) {}
 
     virtual ~DispSyncSource() {}
 
     virtual void setVSyncEnabled(bool enable) {
-        // Do NOT lock the mutex here so as to avoid any mutex ordering issues
-        // with locking it in the onDispSyncEvent callback.
+        Mutex::Autolock lock(mVsyncMutex);
         if (enable) {
             status_t err = mDispSync->addEventListener(mPhaseOffset,
                     static_cast<DispSync::Callback*>(this));
@@ -347,18 +351,54 @@
             }
             //ATRACE_INT(mVsyncOnLabel.string(), 0);
         }
+        mEnabled = enable;
     }
 
     virtual void setCallback(const sp<VSyncSource::Callback>& callback) {
-        Mutex::Autolock lock(mMutex);
+        Mutex::Autolock lock(mCallbackMutex);
         mCallback = callback;
     }
 
+    virtual void setPhaseOffset(nsecs_t phaseOffset) {
+        Mutex::Autolock lock(mVsyncMutex);
+
+        // Normalize phaseOffset to [0, period)
+        auto period = mDispSync->getPeriod();
+        phaseOffset %= period;
+        if (phaseOffset < 0) {
+            // If we're here, then phaseOffset is in (-period, 0). After this
+            // operation, it will be in (0, period)
+            phaseOffset += period;
+        }
+        mPhaseOffset = phaseOffset;
+
+        // If we're not enabled, we don't need to mess with the listeners
+        if (!mEnabled) {
+            return;
+        }
+
+        // Remove the listener with the old offset
+        status_t err = mDispSync->removeEventListener(
+                static_cast<DispSync::Callback*>(this));
+        if (err != NO_ERROR) {
+            ALOGE("error unregistering vsync callback: %s (%d)",
+                    strerror(-err), err);
+        }
+
+        // Add a listener with the new offset
+        err = mDispSync->addEventListener(mPhaseOffset,
+                static_cast<DispSync::Callback*>(this));
+        if (err != NO_ERROR) {
+            ALOGE("error registering vsync callback: %s (%d)",
+                    strerror(-err), err);
+        }
+    }
+
 private:
     virtual void onDispSyncEvent(nsecs_t when) {
         sp<VSyncSource::Callback> callback;
         {
-            Mutex::Autolock lock(mMutex);
+            Mutex::Autolock lock(mCallbackMutex);
             callback = mCallback;
 
             if (mTraceVsync) {
@@ -374,14 +414,18 @@
 
     int mValue;
 
-    const nsecs_t mPhaseOffset;
     const bool mTraceVsync;
     const String8 mVsyncOnLabel;
     const String8 mVsyncEventLabel;
 
     DispSync* mDispSync;
+
+    Mutex mCallbackMutex; // Protects the following
     sp<VSyncSource::Callback> mCallback;
-    Mutex mMutex;
+
+    Mutex mVsyncMutex; // Protects the following
+    nsecs_t mPhaseOffset;
+    bool mEnabled;
 };
 
 void SurfaceFlinger::init() {
@@ -506,6 +550,9 @@
         return BAD_VALUE;
     }
 
+    if (!display.get())
+        return NAME_NOT_FOUND;
+
     int32_t type = NAME_NOT_FOUND;
     for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
         if (display == mBuiltinDisplays[i]) {
@@ -617,7 +664,11 @@
 }
 
 int SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) {
-    return getDisplayDevice(display)->getActiveConfig();
+    sp<DisplayDevice> device(getDisplayDevice(display));
+    if (device != NULL) {
+        return device->getActiveConfig();
+    }
+    return BAD_VALUE;
 }
 
 void SurfaceFlinger::setActiveConfigInternal(const sp<DisplayDevice>& hw, int mode) {
@@ -652,7 +703,7 @@
         virtual bool handler() {
             Vector<DisplayInfo> configs;
             mFlinger.getDisplayConfigs(mDisplay, &configs);
-            if(mMode < 0 || static_cast<size_t>(mMode) >= configs.size()) {
+            if (mMode < 0 || mMode >= static_cast<int>(configs.size())) {
                 ALOGE("Attempt to set active config = %d for display with %zu configs",
                         mMode, configs.size());
             }
@@ -825,30 +876,41 @@
 void SurfaceFlinger::onMessageReceived(int32_t what) {
     ATRACE_CALL();
     switch (what) {
-    case MessageQueue::TRANSACTION:
-        handleMessageTransaction();
-        break;
-    case MessageQueue::INVALIDATE:
-        handleMessageTransaction();
-        handleMessageInvalidate();
-        signalRefresh();
-        break;
-    case MessageQueue::REFRESH:
-        handleMessageRefresh();
-        break;
+        case MessageQueue::TRANSACTION: {
+            handleMessageTransaction();
+            break;
+        }
+        case MessageQueue::INVALIDATE: {
+            bool refreshNeeded = handleMessageTransaction();
+            refreshNeeded |= handleMessageInvalidate();
+            refreshNeeded |= mRepaintEverything;
+            if (refreshNeeded) {
+                // Signal a refresh if a transaction modified the window state,
+                // a new buffer was latched, or if HWC has requested a full
+                // repaint
+                signalRefresh();
+            }
+            break;
+        }
+        case MessageQueue::REFRESH: {
+            handleMessageRefresh();
+            break;
+        }
     }
 }
 
-void SurfaceFlinger::handleMessageTransaction() {
+bool SurfaceFlinger::handleMessageTransaction() {
     uint32_t transactionFlags = peekTransactionFlags(eTransactionMask);
     if (transactionFlags) {
         handleTransaction(transactionFlags);
+        return true;
     }
+    return false;
 }
 
-void SurfaceFlinger::handleMessageInvalidate() {
+bool SurfaceFlinger::handleMessageInvalidate() {
     ATRACE_CALL();
-    handlePageFlip();
+    return handlePageFlip();
 }
 
 void SurfaceFlinger::handleMessageRefresh() {
@@ -1329,7 +1391,22 @@
                         // etc.) but no internal state (i.e. a DisplayDevice).
                         if (state.surface != NULL) {
 
-                            hwcDisplayId = allocateHwcDisplayId(state.type);
+                            int width = 0;
+                            int status = state.surface->query(
+                                    NATIVE_WINDOW_WIDTH, &width);
+                            ALOGE_IF(status != NO_ERROR,
+                                    "Unable to query width (%d)", status);
+                            int height = 0;
+                            status = state.surface->query(
+                                    NATIVE_WINDOW_HEIGHT, &height);
+                            ALOGE_IF(status != NO_ERROR,
+                                    "Unable to query height (%d)", status);
+                            if (MAX_VIRTUAL_DISPLAY_DIMENSION == 0 ||
+                                    (width <= MAX_VIRTUAL_DISPLAY_DIMENSION &&
+                                     height <= MAX_VIRTUAL_DISPLAY_DIMENSION)) {
+                                hwcDisplayId = allocateHwcDisplayId(state.type);
+                            }
+
                             sp<VirtualDisplaySurface> vds = new VirtualDisplaySurface(
                                     *mHwc, hwcDisplayId, state.surface,
                                     bqProducer, bqConsumer, state.displayName);
@@ -1668,12 +1745,13 @@
     }
 }
 
-void SurfaceFlinger::handlePageFlip()
+bool SurfaceFlinger::handlePageFlip()
 {
     Region dirtyRegion;
 
     bool visibleRegions = false;
     const LayerVector& layers(mDrawingState.layersSortedByZ);
+    bool frameQueued = false;
 
     // Store the set of layers that need updates. This set must not change as
     // buffers are being latched, as this could result in a deadlock.
@@ -1687,17 +1765,36 @@
     Vector<Layer*> layersWithQueuedFrames;
     for (size_t i = 0, count = layers.size(); i<count ; i++) {
         const sp<Layer>& layer(layers[i]);
-        if (layer->hasQueuedFrame())
-            layersWithQueuedFrames.push_back(layer.get());
+        if (layer->hasQueuedFrame()) {
+            frameQueued = true;
+            if (layer->shouldPresentNow(mPrimaryDispSync)) {
+                layersWithQueuedFrames.push_back(layer.get());
+            } else {
+                layer->useEmptyDamage();
+            }
+        } else {
+            layer->useEmptyDamage();
+        }
     }
     for (size_t i = 0, count = layersWithQueuedFrames.size() ; i<count ; i++) {
         Layer* layer = layersWithQueuedFrames[i];
         const Region dirty(layer->latchBuffer(visibleRegions));
+        layer->useSurfaceDamage();
         const Layer::State& s(layer->getDrawingState());
         invalidateLayerStack(s.layerStack, dirty);
     }
 
     mVisibleRegionsDirty |= visibleRegions;
+
+    // If we will need to wake up at some time in the future to deal with a
+    // queued frame that shouldn't be displayed during this vsync period, wake
+    // up during the next vsync period to check again.
+    if (frameQueued && layersWithQueuedFrames.empty()) {
+        signalLayerUpdate();
+    }
+
+    // Only continue with the refresh if there is actually new work to do
+    return !layersWithQueuedFrames.empty();
 }
 
 void SurfaceFlinger::invalidateHwcGeometry()
@@ -1897,18 +1994,25 @@
     engine.fillRegionWithColor(region, height, 0, 0, 0, 0);
 }
 
-void SurfaceFlinger::addClientLayer(const sp<Client>& client,
+status_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
         const sp<IBinder>& handle,
         const sp<IGraphicBufferProducer>& gbc,
         const sp<Layer>& lbc)
 {
+    // add this layer to the current state list
+    {
+        Mutex::Autolock _l(mStateLock);
+        if (mCurrentState.layersSortedByZ.size() >= MAX_LAYERS) {
+            return NO_MEMORY;
+        }
+        mCurrentState.layersSortedByZ.add(lbc);
+        mGraphicBufferProducerList.add(IInterface::asBinder(gbc));
+    }
+
     // attach this layer to the client
     client->attachLayer(handle, lbc);
 
-    // add this layer to the current state list
-    Mutex::Autolock _l(mStateLock);
-    mCurrentState.layersSortedByZ.add(lbc);
-    mGraphicBufferProducerList.add(IInterface::asBinder(gbc));
+    return NO_ERROR;
 }
 
 status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
@@ -2165,10 +2269,16 @@
             break;
     }
 
-    if (result == NO_ERROR) {
-        addClientLayer(client, *handle, *gbp, layer);
-        setTransactionFlags(eTransactionNeeded);
+    if (result != NO_ERROR) {
+        return result;
     }
+
+    result = addClientLayer(client, *handle, *gbp, layer);
+    if (result != NO_ERROR) {
+        return result;
+    }
+
+    setTransactionFlags(eTransactionNeeded);
     return result;
 }
 
@@ -2828,6 +2938,21 @@
                 mPrimaryDispSync.setRefreshSkipCount(n);
                 return NO_ERROR;
             }
+            case 1017: {
+                n = data.readInt32();
+                mForceFullDamage = static_cast<bool>(n);
+                return NO_ERROR;
+            }
+            case 1018: { // Modify Choreographer's phase offset
+                n = data.readInt32();
+                mEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
+                return NO_ERROR;
+            }
+            case 1019: { // Modify SurfaceFlinger's phase offset
+                n = data.readInt32();
+                mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
+                return NO_ERROR;
+            }
         }
     }
     return err;
@@ -3075,7 +3200,7 @@
     const int32_t hw_w = hw->getWidth();
     const int32_t hw_h = hw->getHeight();
     const bool filtering = static_cast<int32_t>(reqWidth) != hw_w ||
-                           static_cast<int32_t>(reqWidth) != hw_h;
+                           static_cast<int32_t>(reqHeight) != hw_h;
 
     // if a default or invalid sourceCrop is passed in, set reasonable values
     if (sourceCrop.width() == 0 || sourceCrop.height() == 0 ||
@@ -3200,6 +3325,8 @@
                         EGLSyncKHR sync;
                         if (!DEBUG_SCREENSHOTS) {
                            sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
+                           // native fence fd will not be populated until flush() is done.
+                           getRenderEngine().flush();
                         } else {
                             sync = EGL_NO_SYNC_KHR;
                         }
@@ -3246,10 +3373,8 @@
                 } else {
                     result = BAD_VALUE;
                 }
+                // queueBuffer takes ownership of syncFd
                 window->queueBuffer(window, buffer, syncFd);
-                if (syncFd != -1) {
-                    close(syncFd);
-                }
             }
         } else {
             result = BAD_VALUE;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 710dac7..74f9031 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -144,6 +144,8 @@
     // every half hour.
     enum { LOG_FRAME_STATS_PERIOD =  30*60*60 };
 
+    static const size_t MAX_LAYERS = 4096;
+
     // We're reference counted, never destroy SurfaceFlinger directly
     virtual ~SurfaceFlinger();
 
@@ -247,8 +249,12 @@
     // called on the main thread in response to setPowerMode()
     void setPowerModeInternal(const sp<DisplayDevice>& hw, int mode);
 
-    void handleMessageTransaction();
-    void handleMessageInvalidate();
+    // Returns whether the transaction actually modified any state
+    bool handleMessageTransaction();
+
+    // Returns whether a new buffer has been latched (see handlePageFlip())
+    bool handleMessageInvalidate();
+
     void handleMessageRefresh();
 
     void handleTransaction(uint32_t transactionFlags);
@@ -256,10 +262,11 @@
 
     void updateCursorAsync();
 
-    /* handlePageFilp: this is were we latch a new buffer
-     * if available and compute the dirty region.
+    /* handlePageFlip - latch a new buffer if available and compute the dirty
+     * region. Returns whether a new buffer has been latched, i.e., whether it
+     * is necessary to perform a refresh during this vsync.
      */
-    void handlePageFlip();
+    bool handlePageFlip();
 
     /* ------------------------------------------------------------------------
      * Transactions
@@ -300,7 +307,7 @@
     status_t removeLayer(const sp<Layer>& layer);
 
     // add a layer to SurfaceFlinger
-    void addClientLayer(const sp<Client>& client,
+    status_t addClientLayer(const sp<Client>& client,
             const sp<IBinder>& handle,
             const sp<IGraphicBufferProducer>& gbc,
             const sp<Layer>& lbc);
@@ -464,6 +471,7 @@
     volatile nsecs_t mDebugInTransaction;
     nsecs_t mLastTransactionTime;
     bool mBootFinished;
+    bool mForceFullDamage;
 
     // these are thread safe
     mutable MessageQueue mEventQueue;
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.cpp b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
index 7de6ac4..a9a2958 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.cpp
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
@@ -21,6 +21,8 @@
 
 #include <private/gui/SyncFeatures.h>
 
+#include <gui/BufferItem.h>
+
 #include <utils/Errors.h>
 #include <utils/NativeHandle.h>
 #include <utils/Trace.h>
@@ -47,7 +49,7 @@
         return err;
     }
 
-    BufferQueue::BufferItem item;
+    BufferItem item;
 
     // Acquire the next buffer.
     // In asynchronous mode the list is guaranteed to be one buffer
@@ -72,7 +74,7 @@
     int buf = item.mBuf;
     if (rejecter && rejecter->reject(mSlots[buf].mGraphicBuffer, item)) {
         releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, EGL_NO_SYNC_KHR);
-        return NO_ERROR;
+        return BUFFER_REJECTED;
     }
 
     // Release the previous buffer.
@@ -101,11 +103,12 @@
     return bindTextureImageLocked();
 }
 
-status_t SurfaceFlingerConsumer::acquireBufferLocked(
-        BufferQueue::BufferItem *item, nsecs_t presentWhen) {
+status_t SurfaceFlingerConsumer::acquireBufferLocked(BufferItem* item,
+        nsecs_t presentWhen) {
     status_t result = GLConsumer::acquireBufferLocked(item, presentWhen);
     if (result == NO_ERROR) {
         mTransformToDisplayInverse = item->mTransformToDisplayInverse;
+        mSurfaceDamage = item->mSurfaceDamage;
     }
     return result;
 }
@@ -114,10 +117,18 @@
     return mTransformToDisplayInverse;
 }
 
+const Region& SurfaceFlingerConsumer::getSurfaceDamage() const {
+    return mSurfaceDamage;
+}
+
 sp<NativeHandle> SurfaceFlingerConsumer::getSidebandStream() const {
     return mConsumer->getSidebandStream();
 }
 
+void SurfaceFlingerConsumer::setShadowQueueSize(size_t size) {
+    mConsumer->setShadowQueueSize(size);
+}
+
 // We need to determine the time when a buffer acquired now will be
 // displayed.  This can be calculated:
 //   time when previous buffer's actual-present fence was signaled
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.h b/services/surfaceflinger/SurfaceFlingerConsumer.h
index 5633980..a90a8b9 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.h
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.h
@@ -28,6 +28,8 @@
  */
 class SurfaceFlingerConsumer : public GLConsumer {
 public:
+    static const status_t BUFFER_REJECTED = UNKNOWN_ERROR + 8;
+
     struct ContentsChangedListener: public FrameAvailableListener {
         virtual void onSidebandStreamChanged() = 0;
     };
@@ -35,19 +37,19 @@
     SurfaceFlingerConsumer(const sp<IGraphicBufferConsumer>& consumer,
             uint32_t tex)
         : GLConsumer(consumer, tex, GLConsumer::TEXTURE_EXTERNAL, false, false),
-          mTransformToDisplayInverse(false)
+          mTransformToDisplayInverse(false), mSurfaceDamage()
     {}
 
     class BufferRejecter {
         friend class SurfaceFlingerConsumer;
         virtual bool reject(const sp<GraphicBuffer>& buf,
-                const IGraphicBufferConsumer::BufferItem& item) = 0;
+                const BufferItem& item) = 0;
 
     protected:
         virtual ~BufferRejecter() { }
     };
 
-    virtual status_t acquireBufferLocked(BufferQueue::BufferItem *item, nsecs_t presentWhen);
+    virtual status_t acquireBufferLocked(BufferItem *item, nsecs_t presentWhen);
 
     // This version of updateTexImage() takes a functor that may be used to
     // reject the newly acquired buffer.  Unlike the GLConsumer version,
@@ -60,6 +62,7 @@
 
     // must be called from SF main thread
     bool getTransformToDisplayInverse() const;
+    const Region& getSurfaceDamage() const;
 
     // Sets the contents changed listener. This should be used instead of
     // ConsumerBase::setFrameAvailableListener().
@@ -67,9 +70,12 @@
 
     sp<NativeHandle> getSidebandStream() const;
 
-private:
+    // See IGraphicBufferConsumer::setShadowQueueSize
+    void setShadowQueueSize(size_t size);
+
     nsecs_t computeExpectedPresent(const DispSync& dispSync);
 
+private:
     virtual void onSidebandStreamChanged();
 
     wp<ContentsChangedListener> mContentsChangedListener;
@@ -78,6 +84,9 @@
     // it is displayed onto. This is applied after GLConsumer::mCurrentTransform.
     // This must be set/read from SurfaceFlinger's main thread.
     bool mTransformToDisplayInverse;
+
+    // The portion of this surface that has changed since the previous frame
+    Region mSurfaceDamage;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/services/surfaceflinger/Transform.cpp b/services/surfaceflinger/Transform.cpp
index 3456abf..35e7e7d 100644
--- a/services/surfaceflinger/Transform.cpp
+++ b/services/surfaceflinger/Transform.cpp
@@ -301,16 +301,16 @@
     // (T*M)^-1 = M^-1 * T^-1
     Transform result;
     if (mType <= TRANSLATE) {
-        // 1 0 x
-        // 0 1 y
-        // 0 0 1
+        // 1 0 0
+        // 0 1 0
+        // x y 1
         result = *this;
         result.mMatrix[2][0] = -result.mMatrix[2][0];
         result.mMatrix[2][1] = -result.mMatrix[2][1];
     } else {
-        // a c x
-        // b d y
-        // 0 0 1
+        // a c 0
+        // b d 0
+        // x y 1
         const mat33& M(mMatrix);
         const float a = M[0][0];
         const float b = M[1][0];
@@ -319,16 +319,17 @@
         const float x = M[2][0];
         const float y = M[2][1];
 
-        Transform R, T;
         const float idet = 1.0 / (a*d - b*c);
-        R.mMatrix[0][0] =  d*idet;    R.mMatrix[0][1] = -c*idet;
-        R.mMatrix[1][0] = -b*idet;    R.mMatrix[1][1] =  a*idet;
-        R.mType = mType &= ~TRANSLATE;
+        result.mMatrix[0][0] =  d*idet;
+        result.mMatrix[0][1] = -c*idet;
+        result.mMatrix[1][0] = -b*idet;
+        result.mMatrix[1][1] =  a*idet;
+        result.mType = mType;
 
-        T.mMatrix[2][0] = -x;
-        T.mMatrix[2][1] = -y;
-        T.mType = TRANSLATE;
-        result =  R * T;
+        vec2 T(-x, -y);
+        T = result.transform(T);
+        result.mMatrix[2][0] = T[0];
+        result.mMatrix[2][1] = T[1];
     }
     return result;
 }
diff --git a/services/surfaceflinger/tests/waitforvsync/waitforvsync.cpp b/services/surfaceflinger/tests/waitforvsync/waitforvsync.cpp
index 279b88b..b88b04a 100644
--- a/services/surfaceflinger/tests/waitforvsync/waitforvsync.cpp
+++ b/services/surfaceflinger/tests/waitforvsync/waitforvsync.cpp
@@ -23,6 +23,7 @@
 #include <errno.h>
 #include <string.h>
 #include <stdio.h>
+#include <unistd.h>
 
 #ifndef FBIO_WAITFORVSYNC
 #define FBIO_WAITFORVSYNC   _IOW('F', 0x20, __u32)