Merge "Add ability to quote responses as needed."
diff --git a/fastboot/usb_linux.c b/fastboot/usb_linux.c
index 85187de..83c6de9 100644
--- a/fastboot/usb_linux.c
+++ b/fastboot/usb_linux.c
@@ -131,7 +131,9 @@
     info.serial_number[0] = 0;
     if (dev->iSerialNumber) {
         struct usbdevfs_ctrltransfer  ctrl;
-        __u16 buffer[128];
+        // Keep it short enough because some bootloaders are borked if the URB len is > 255
+        // 128 is too big by 1.
+        __u16 buffer[127];
         int result;
 
         memset(buffer, 0, sizeof(buffer));
diff --git a/include/cutils/sched_policy.h b/include/cutils/sched_policy.h
index 753a08c..ba84ce3 100644
--- a/include/cutils/sched_policy.h
+++ b/include/cutils/sched_policy.h
@@ -21,21 +21,29 @@
 extern "C" {
 #endif
 
+/* Keep in sync with THREAD_GROUP_* in frameworks/base/core/java/android/os/Process.java */
 typedef enum {
+    SP_DEFAULT    = -1,
     SP_BACKGROUND = 0,
     SP_FOREGROUND = 1,
+    SP_SYSTEM     = 2,  // can't be used with set_sched_policy()
+    SP_AUDIO_APP  = 3,
+    SP_AUDIO_SYS  = 4,
     SP_CNT,
     SP_MAX        = SP_CNT - 1,
+    SP_SYSTEM_DEFAULT = SP_FOREGROUND,
 } SchedPolicy;
 
 /* Assign thread tid to the cgroup associated with the specified policy.
  * If the thread is a thread group leader, that is it's gettid() == getpid(),
  * then the other threads in the same thread group are _not_ affected.
+ * On platforms which support gettid(), zero tid means current thread.
  * Return value: 0 for success, or -errno for error.
  */
 extern int set_sched_policy(int tid, SchedPolicy policy);
 
 /* Return the policy associated with the cgroup of thread tid via policy pointer.
+ * On platforms which support gettid(), zero tid means current thread.
  * Return value: 0 for success, or -1 for error and set errno.
  */
 extern int get_sched_policy(int tid, SchedPolicy *policy);
diff --git a/include/netutils/dhcp.h b/include/netutils/dhcp.h
index bd16240..d25e58f 100644
--- a/include/netutils/dhcp.h
+++ b/include/netutils/dhcp.h
@@ -30,7 +30,8 @@
                           char *dns1,
                           char *dns2,
                           char *server,
-                          uint32_t  *lease);
+                          uint32_t *lease,
+                          char *vendorInfo);
 extern int dhcp_stop(const char *ifname);
 extern int dhcp_release_lease(const char *ifname);
 extern char *dhcp_get_errmsg();
diff --git a/include/sync/sync.h b/include/sync/sync.h
new file mode 100644
index 0000000..6aa5f2d
--- /dev/null
+++ b/include/sync/sync.h
@@ -0,0 +1,45 @@
+/*
+ *  sync.h
+ *
+ *   Copyright 2012 Google, Inc
+ *
+ *  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.
+ */
+
+#ifndef __SYS_CORE_SYNC_H
+#define __SYS_CORE_SYNC_H
+
+#include <linux/sync.h>
+#include <linux/sw_sync.h>
+
+__BEGIN_DECLS
+
+/* timeout in msecs */
+int sync_wait(int fd, unsigned int timeout);
+int sync_merge(const char *name, int fd1, int fd2);
+struct sync_fence_info_data *sync_fence_info(int fd);
+struct sync_pt_info *sync_pt_info(struct sync_fence_info_data *info,
+                                  struct sync_pt_info *itr);
+void sync_fence_info_free(struct sync_fence_info_data *info);
+
+/* sw_sync is mainly inteded for testing and should not be complied into
+ * production kernels
+ */
+
+int sw_sync_timeline_create(void);
+int sw_sync_timeline_inc(int fd, unsigned count);
+int sw_sync_fence_create(int fd, const char *name, unsigned value);
+
+__END_DECLS
+
+#endif /* __SYS_CORE_SYNC_H */
diff --git a/include/system/audio.h b/include/system/audio.h
index 382fc36..3807317 100644
--- a/include/system/audio.h
+++ b/include/system/audio.h
@@ -351,16 +351,17 @@
  * (when getOuput() is called) to an available output stream.
  */
 typedef enum {
-    AUDIO_OUTPUT_FLAG_NONE = 0x0,    // no attributes
-    AUDIO_OUTPUT_FLAG_DIRECT = 0x1,  // this output directly connects a track
-                                     // to one output stream: no software mixer
-    AUDIO_OUTPUT_FLAG_PRIMARY = 0x2, // this output is the primary output of
-                                     // the device. It is unique and must be
-                                     // present. It is opened by default and
-                                     // receives routing, audio mode and volume
-                                     // controls related to voice calls.
-    AUDIO_OUTPUT_FLAG_FAST = 0x4,    // output supports "fast tracks",
-                                     // defined elsewhere
+    AUDIO_OUTPUT_FLAG_NONE = 0x0,       // no attributes
+    AUDIO_OUTPUT_FLAG_DIRECT = 0x1,     // this output directly connects a track
+                                        // to one output stream: no software mixer
+    AUDIO_OUTPUT_FLAG_PRIMARY = 0x2,    // this output is the primary output of
+                                        // the device. It is unique and must be
+                                        // present. It is opened by default and
+                                        // receives routing, audio mode and volume
+                                        // controls related to voice calls.
+    AUDIO_OUTPUT_FLAG_FAST = 0x4,       // output supports "fast tracks",
+                                        // defined elsewhere
+    AUDIO_OUTPUT_FLAG_DEEP_BUFFER = 0x8 // use deep audio buffers
 } audio_output_flags_t;
 
 static inline bool audio_is_output_device(audio_devices_t device)
diff --git a/include/system/audio_policy.h b/include/system/audio_policy.h
index 701c86a..57f7110 100644
--- a/include/system/audio_policy.h
+++ b/include/system/audio_policy.h
@@ -30,15 +30,6 @@
  * frameworks/base/include/media/AudioSystem.h
  */
 
-/* FIXME: temporary definitions to be removed once all projects have been changed
- * to use audio_output_flags_t */
-typedef enum {
-    AUDIO_POLICY_OUTPUT_FLAG_NONE = AUDIO_OUTPUT_FLAG_NONE,
-    AUDIO_POLICY_OUTPUT_FLAG_DIRECT = AUDIO_OUTPUT_FLAG_DIRECT,
-    AUDIO_POLICY_OUTPUT_FLAG_PRIMARY = AUDIO_OUTPUT_FLAG_PRIMARY,
-    AUDIO_POLICY_OUTPUT_FLAG_FAST = AUDIO_OUTPUT_FLAG_FAST,
-} audio_policy_output_flags_t;
-
 /* device categories used for audio_policy->set_force_use() */
 typedef enum {
     AUDIO_POLICY_FORCE_NONE,
diff --git a/include/system/graphics.h b/include/system/graphics.h
index 729e92c..e206e3e 100644
--- a/include/system/graphics.h
+++ b/include/system/graphics.h
@@ -86,7 +86,27 @@
      */
     HAL_PIXEL_FORMAT_YV12   = 0x32315659, // YCrCb 4:2:0 Planar
 
-
+    /*
+     * Android RAW sensor format:
+     *
+     * This format is exposed outside of the HAL to applications.
+     *
+     * RAW_SENSOR is a single-channel 16-bit format, typically representing raw
+     * Bayer-pattern images from an image sensor, with minimal processing.
+     *
+     * The exact pixel layout of the data in the buffer is sensor-dependent, and
+     * needs to be queried from the camera device.
+     *
+     * Generally, not all 16 bits are used; more common values are 10 or 12
+     * bits. All parameters to interpret the raw data (black and white points,
+     * color space, etc) must be queried from the camera device.
+     *
+     * This format assumes
+     * - an even width
+     * - an even height
+     * - a horizontal stride multiple of 16 pixels (32 bytes).
+     */
+    HAL_PIXEL_FORMAT_RAW_SENSOR = 0x20,
 
     /* Legacy formats (deprecated), used by ImageFormat.java */
     HAL_PIXEL_FORMAT_YCbCr_422_SP       = 0x10, // NV16
diff --git a/libcutils/sched_policy.c b/libcutils/sched_policy.c
index 35d362a..20771c0 100644
--- a/libcutils/sched_policy.c
+++ b/libcutils/sched_policy.c
@@ -44,28 +44,51 @@
 
 #define POLICY_DEBUG 0
 
+#define CAN_SET_SP_SYSTEM 0 // non-zero means to implement set_sched_policy(tid, SP_SYSTEM)
+
 static pthread_once_t the_once = PTHREAD_ONCE_INIT;
 
 static int __sys_supports_schedgroups = -1;
 
 // File descriptors open to /dev/cpuctl/../tasks, setup by initialize, or -1 on error.
-static int normal_cgroup_fd = -1;
 static int bg_cgroup_fd = -1;
+static int fg_cgroup_fd = -1;
+#if CAN_SET_SP_SYSTEM
+static int system_cgroup_fd = -1;
+#endif
+static int audio_app_cgroup_fd = -1;
+static int audio_sys_cgroup_fd = -1;
 
 /* Add tid to the scheduling group defined by the policy */
 static int add_tid_to_cgroup(int tid, SchedPolicy policy)
 {
     int fd;
 
-    if (policy == SP_BACKGROUND) {
+    switch (policy) {
+    case SP_BACKGROUND:
         fd = bg_cgroup_fd;
-    } else {
-        fd = normal_cgroup_fd;
+        break;
+    case SP_FOREGROUND:
+        fd = fg_cgroup_fd;
+        break;
+#if CAN_SET_SP_SYSTEM
+    case SP_SYSTEM:
+        fd = system_cgroup_fd;
+        break;
+#endif
+    case SP_AUDIO_APP:
+        fd = audio_app_cgroup_fd;
+        break;
+    case SP_AUDIO_SYS:
+        fd = audio_sys_cgroup_fd;
+        break;
+    default:
+        fd = -1;
+        break;
     }
 
     if (fd < 0) {
-        SLOGE("add_tid_to_cgroup failed; background=%d\n",
-              policy == SP_BACKGROUND ? 1 : 0);
+        SLOGE("add_tid_to_cgroup failed; policy=%d\n", policy);
         return -1;
     }
 
@@ -86,8 +109,8 @@
          */
         if (errno == ESRCH)
                 return 0;
-        SLOGW("add_tid_to_cgroup failed to write '%s' (%s); background=%d\n",
-              ptr, strerror(errno), policy == SP_BACKGROUND ? 1 : 0);
+        SLOGW("add_tid_to_cgroup failed to write '%s' (%s); policy=%d\n",
+              ptr, strerror(errno), policy);
         return -1;
     }
 
@@ -99,9 +122,17 @@
     if (!access("/dev/cpuctl/tasks", F_OK)) {
         __sys_supports_schedgroups = 1;
 
+#if CAN_SET_SP_SYSTEM
         filename = "/dev/cpuctl/tasks";
-        normal_cgroup_fd = open(filename, O_WRONLY);
-        if (normal_cgroup_fd < 0) {
+        system_cgroup_fd = open(filename, O_WRONLY);
+        if (system_cgroup_fd < 0) {
+            SLOGV("open of %s failed: %s\n", filename, strerror(errno));
+        }
+#endif
+
+        filename = "/dev/cpuctl/foreground/tasks";
+        fg_cgroup_fd = open(filename, O_WRONLY);
+        if (fg_cgroup_fd < 0) {
             SLOGE("open of %s failed: %s\n", filename, strerror(errno));
         }
 
@@ -110,6 +141,19 @@
         if (bg_cgroup_fd < 0) {
             SLOGE("open of %s failed: %s\n", filename, strerror(errno));
         }
+
+        filename = "/dev/cpuctl/audio_app/tasks";
+        audio_app_cgroup_fd = open(filename, O_WRONLY);
+        if (audio_app_cgroup_fd < 0) {
+            SLOGV("open of %s failed: %s\n", filename, strerror(errno));
+        }
+
+        filename = "/dev/cpuctl/audio_sys/tasks";
+        audio_sys_cgroup_fd = open(filename, O_WRONLY);
+        if (audio_sys_cgroup_fd < 0) {
+            SLOGV("open of %s failed: %s\n", filename, strerror(errno));
+        }
+
     } else {
         __sys_supports_schedgroups = 0;
     }
@@ -189,6 +233,11 @@
 
 int get_sched_policy(int tid, SchedPolicy *policy)
 {
+#ifdef HAVE_GETTID
+    if (tid == 0) {
+        tid = gettid();
+    }
+#endif
     pthread_once(&the_once, __initialize);
 
     if (__sys_supports_schedgroups) {
@@ -196,9 +245,15 @@
         if (getSchedulerGroup(tid, grpBuf, sizeof(grpBuf)) < 0)
             return -1;
         if (grpBuf[0] == '\0') {
-            *policy = SP_FOREGROUND;
+            *policy = SP_SYSTEM;
         } else if (!strcmp(grpBuf, "bg_non_interactive")) {
             *policy = SP_BACKGROUND;
+        } else if (!strcmp(grpBuf, "foreground")) {
+            *policy = SP_FOREGROUND;
+        } else if (!strcmp(grpBuf, "audio_app")) {
+            *policy = SP_AUDIO_APP;
+        } else if (!strcmp(grpBuf, "audio_sys")) {
+            *policy = SP_AUDIO_SYS;
         } else {
             errno = ERANGE;
             return -1;
@@ -219,8 +274,23 @@
     return 0;
 }
 
+/* Re-map SP_DEFAULT to the system default policy, and leave other values unchanged.
+ * Call this any place a SchedPolicy is used as an input parameter.
+ * Returns the possibly re-mapped policy.
+ */
+static inline SchedPolicy _policy(SchedPolicy p)
+{
+   return p == SP_DEFAULT ? SP_SYSTEM_DEFAULT : p;
+}
+
 int set_sched_policy(int tid, SchedPolicy policy)
 {
+#ifdef HAVE_GETTID
+    if (tid == 0) {
+        tid = gettid();
+    }
+#endif
+    policy = _policy(policy);
     pthread_once(&the_once, __initialize);
 
 #if POLICY_DEBUG
@@ -246,12 +316,25 @@
 
         strncpy(thread_name, p, (q-p));
     }
-    if (policy == SP_BACKGROUND) {
+    switch (policy) {
+    case SP_BACKGROUND:
         SLOGD("vvv tid %d (%s)", tid, thread_name);
-    } else if (policy == SP_FOREGROUND) {
+        break;
+    case SP_FOREGROUND:
         SLOGD("^^^ tid %d (%s)", tid, thread_name);
-    } else {
+        break;
+    case SP_SYSTEM:
+        SLOGD("/// tid %d (%s)", tid, thread_name);
+        break;
+    case SP_AUDIO_APP:
+        SLOGD("aaa tid %d (%s)", tid, thread_name);
+        break;
+    case SP_AUDIO_SYS:
+        SLOGD("sss tid %d (%s)", tid, thread_name);
+        break;
+    default:
         SLOGD("??? tid %d (%s)", tid, thread_name);
+        break;
     }
 #endif
 
@@ -275,9 +358,13 @@
 
 const char *get_sched_policy_name(SchedPolicy policy)
 {
+    policy = _policy(policy);
     static const char * const strings[SP_CNT] = {
        [SP_BACKGROUND] = "bg",
        [SP_FOREGROUND] = "fg",
+       [SP_SYSTEM]     = "  ",
+       [SP_AUDIO_APP]  = "aa",
+       [SP_AUDIO_SYS]  = "as",
     };
     if ((policy < SP_CNT) && (strings[policy] != NULL))
         return strings[policy];
diff --git a/libnetutils/dhcp_utils.c b/libnetutils/dhcp_utils.c
index d18931b..398d9c4 100644
--- a/libnetutils/dhcp_utils.c
+++ b/libnetutils/dhcp_utils.c
@@ -70,7 +70,8 @@
                      char *dns1,
                      char *dns2,
                      char *server,
-                     uint32_t  *lease)
+                     uint32_t *lease,
+                     char *vendorInfo)
 {
     char prop_name[PROPERTY_KEY_MAX];
     char prop_value[PROPERTY_VALUE_MAX];
@@ -122,6 +123,10 @@
     if (property_get(prop_name, prop_value, NULL)) {
         *lease = atol(prop_value);
     }
+
+    snprintf(prop_name, sizeof(prop_name), "%s.%s.vendorInfo", DHCP_PROP_NAME_PREFIX, interface);
+    property_get(prop_name, vendorInfo, NULL);
+
     return 0;
 }
 
@@ -158,7 +163,8 @@
                     char *dns1,
                     char *dns2,
                     char *server,
-                    uint32_t  *lease)
+                    uint32_t *lease,
+                    char *vendorInfo)
 {
     char result_prop_name[PROPERTY_KEY_MAX];
     char daemon_prop_name[PROPERTY_KEY_MAX];
@@ -207,8 +213,8 @@
     }
     if (strcmp(prop_value, "ok") == 0) {
         char dns_prop_name[PROPERTY_KEY_MAX];
-        if (fill_ip_info(interface, ipaddr, gateway, prefixLength, dns1, dns2, server, lease)
-                == -1) {
+        if (fill_ip_info(interface, ipaddr, gateway, prefixLength,
+                dns1, dns2, server, lease, vendorInfo) == -1) {
             return -1;
         }
 
@@ -305,7 +311,8 @@
                     in_addr_t *dns1,
                     in_addr_t *dns2,
                     in_addr_t *server,
-                    uint32_t  *lease)
+                    uint32_t *lease,
+                    char *vendorInfo)
 {
     char result_prop_name[PROPERTY_KEY_MAX];
     char prop_value[PROPERTY_VALUE_MAX] = {'\0'};
@@ -341,7 +348,8 @@
         return -1;
     }
     if (strcmp(prop_value, "ok") == 0) {
-        fill_ip_info(interface, ipaddr, gateway, prefixLength, dns1, dns2, server, lease);
+        fill_ip_info(interface, ipaddr, gateway, prefixLength,
+                dns1, dns2, server, lease, vendorInfo);
         return 0;
     } else {
         snprintf(errmsg, sizeof(errmsg), "DHCP Renew result was %s", prop_value);
diff --git a/libsync/Android.mk b/libsync/Android.mk
new file mode 100644
index 0000000..73de069
--- /dev/null
+++ b/libsync/Android.mk
@@ -0,0 +1,15 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := sync.c
+LOCAL_MODULE := libsync
+LOCAL_MODULE_TAGS := optional
+LOCAL_SHARED_LIBRARIES := liblog
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := sync.c sync_test.c
+LOCAL_MODULE := sync_test
+LOCAL_MODULE_TAGS := optional tests
+LOCAL_SHARED_LIBRARIES := liblog
+include $(BUILD_EXECUTABLE)
diff --git a/libsync/sync.c b/libsync/sync.c
new file mode 100644
index 0000000..311da14
--- /dev/null
+++ b/libsync/sync.c
@@ -0,0 +1,115 @@
+/*
+ *  sync.c
+ *
+ *   Copyright 2012 Google, Inc
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#include <fcntl.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <sync/sync.h>
+
+int sync_wait(int fd, unsigned int timeout)
+{
+    __u32 to = timeout;
+
+    return ioctl(fd, SYNC_IOC_WAIT, &to);
+}
+
+int sync_merge(const char *name, int fd1, int fd2)
+{
+    struct sync_merge_data data;
+    int err;
+
+    data.fd2 = fd2;
+    strlcpy(data.name, name, sizeof(data.name));
+
+    err = ioctl(fd1, SYNC_IOC_MERGE, &data);
+    if (err < 0)
+        return err;
+
+    return data.fence;
+}
+
+struct sync_fence_info_data *sync_fence_info(int fd)
+{
+    struct sync_fence_info_data *info;
+    int err;
+
+    info = malloc(4096);
+    if (info == NULL)
+        return NULL;
+
+    info->len = 4096;
+    err = ioctl(fd, SYNC_IOC_FENCE_INFO, info);
+    if (err < 0) {
+        free(info);
+        return NULL;
+    }
+
+    return info;
+}
+
+struct sync_pt_info *sync_pt_info(struct sync_fence_info_data *info,
+                                  struct sync_pt_info *itr)
+{
+    if (itr == NULL)
+        itr = (struct sync_pt_info *) info->pt_info;
+    else
+        itr = (struct sync_pt_info *) ((__u8 *)itr + itr->len);
+
+    if ((__u8 *)itr - (__u8 *)info >= (int)info->len)
+        return NULL;
+
+    return itr;
+}
+
+void sync_fence_info_free(struct sync_fence_info_data *info)
+{
+    free(info);
+}
+
+
+int sw_sync_timeline_create(void)
+{
+    return open("/dev/sw_sync", O_RDWR);
+}
+
+int sw_sync_timeline_inc(int fd, unsigned count)
+{
+    __u32 arg = count;
+
+    return ioctl(fd, SW_SYNC_IOC_INC, &arg);
+}
+
+int sw_sync_fence_create(int fd, const char *name, unsigned value)
+{
+    struct sw_sync_create_fence_data data;
+    int err;
+
+    data.value = value;
+    strlcpy(data.name, name, sizeof(data.name));
+
+    err = ioctl(fd, SW_SYNC_IOC_CREATE_FENCE, &data);
+    if (err < 0)
+        return err;
+
+    return data.fence;
+}
diff --git a/libsync/sync_test.c b/libsync/sync_test.c
new file mode 100644
index 0000000..a75f671
--- /dev/null
+++ b/libsync/sync_test.c
@@ -0,0 +1,146 @@
+/*
+ *  sync_test.c
+ *
+ *   Copyright 2012 Google, Inc
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sync/sync.h>
+
+pthread_mutex_t printf_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+struct sync_thread_data {
+    int thread_no;
+    int fd[2];
+};
+
+void *sync_thread(void *data)
+{
+    struct sync_thread_data *sync_data = data;
+    struct sync_fence_info_data *info;
+    int err;
+    int i;
+
+    for (i = 0; i < 2; i++) {
+        err = sync_wait(sync_data->fd[i], 10000);
+
+        pthread_mutex_lock(&printf_mutex);
+        if (err < 0) {
+            printf("thread %d wait %d failed: %s\n", sync_data->thread_no,
+                   i, strerror(errno));
+        } else {
+            printf("thread %d wait %d done\n", sync_data->thread_no, i);
+        }
+        info = sync_fence_info(sync_data->fd[i]);
+        if (info) {
+            struct sync_pt_info *pt_info = NULL;
+            printf("  fence %s %d\n", info->name, info->status);
+
+            while ((pt_info = sync_pt_info(info, pt_info))) {
+                int ts_sec = pt_info->timestamp_ns / 1000000000LL;
+                int ts_usec = (pt_info->timestamp_ns % 1000000000LL) / 1000LL;
+                printf("    pt %s %s %d %d.%06d", pt_info->obj_name,
+                       pt_info->driver_name, pt_info->status,
+                       ts_sec, ts_usec);
+                if (!strcmp(pt_info->driver_name, "sw_sync"))
+                    printf(" val=%d\n", *(uint32_t *)pt_info->driver_data);
+                else
+                    printf("\n");
+            }
+            sync_fence_info_free(info);
+        }
+        pthread_mutex_unlock(&printf_mutex);
+    }
+
+    return NULL;
+}
+
+int main(int argc, char *argv[])
+{
+    struct sync_thread_data sync_data[4];
+    pthread_t threads[4];
+    int sync_timeline_fd;
+    int i, j;
+    char str[256];
+
+    sync_timeline_fd = sw_sync_timeline_create();
+    if (sync_timeline_fd < 0) {
+        perror("can't create sw_sync_timeline:");
+        return 1;
+    }
+
+    for (i = 0; i < 3; i++) {
+        sync_data[i].thread_no = i;
+
+        for (j = 0; j < 2; j++) {
+            unsigned val = i + j * 3 + 1;
+            sprintf(str, "test_fence%d-%d", i, j);
+            int fd = sw_sync_fence_create(sync_timeline_fd, str, val);
+            if (fd < 0) {
+                printf("can't create sync pt %d: %s", val, strerror(errno));
+                return 1;
+            }
+            sync_data[i].fd[j] = fd;
+            printf("sync_data[%d].fd[%d] = %d;\n", i, j, fd);
+
+        }
+    }
+
+    sync_data[3].thread_no = 3;
+    for (j = 0; j < 2; j++) {
+        sprintf(str, "merged_fence%d", j);
+        sync_data[3].fd[j] = sync_merge(str, sync_data[0].fd[j], sync_data[1].fd[j]);
+        if (sync_data[3].fd[j] < 0) {
+            printf("can't merge sync pts %d and %d: %s\n",
+                   sync_data[0].fd[j], sync_data[1].fd[j], strerror(errno));
+            return 1;
+        }
+    }
+
+    for (i = 0; i < 4; i++)
+        pthread_create(&threads[i], NULL, sync_thread, &sync_data[i]);
+
+
+    for (i = 0; i < 3; i++) {
+        int err;
+        printf("press enter to inc to %d\n", i+1);
+        fgets(str, sizeof(str), stdin);
+        err = sw_sync_timeline_inc(sync_timeline_fd, 1);
+        if (err < 0) {
+            perror("can't increment sync obj:");
+            return 1;
+        }
+    }
+
+    printf("press enter to close sync_timeline\n");
+    fgets(str, sizeof(str), stdin);
+
+    close(sync_timeline_fd);
+
+    printf("press enter to end test\n");
+    fgets(str, sizeof(str), stdin);
+
+    for (i = 0; i < 3; i++) {
+        void *val;
+        pthread_join(threads[i], &val);
+    }
+
+    return 0;
+}
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 8f93b49..212edf4 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -80,25 +80,47 @@
     write /proc/sys/kernel/kptr_restrict 2
     write /proc/sys/kernel/dmesg_restrict 1
     write /proc/sys/vm/mmap_min_addr 32768
+    write /proc/sys/kernel/sched_rt_runtime_us 950000
+    write /proc/sys/kernel/sched_rt_period_us 1000000
 
 # Create cgroup mount points for process groups
     mkdir /dev/cpuctl
     mount cgroup none /dev/cpuctl cpu
     chown system system /dev/cpuctl
     chown system system /dev/cpuctl/tasks
-    chmod 0777 /dev/cpuctl/tasks
+    chmod 0660 /dev/cpuctl/tasks
     write /dev/cpuctl/cpu.shares 1024
+    write /dev/cpuctl/cpu.rt_runtime_us 950000
+    write /dev/cpuctl/cpu.rt_period_us 1000000
 
-    mkdir /dev/cpuctl/fg_boost
-    chown system system /dev/cpuctl/fg_boost/tasks
-    chmod 0777 /dev/cpuctl/fg_boost/tasks
-    write /dev/cpuctl/fg_boost/cpu.shares 1024
+    mkdir /dev/cpuctl/foreground
+    chown system system /dev/cpuctl/foreground/tasks
+    chmod 0666 /dev/cpuctl/foreground/tasks
+    write /dev/cpuctl/foreground/cpu.shares 1024
+    write /dev/cpuctl/foreground/cpu.rt_runtime_us 0
+    write /dev/cpuctl/foreground/cpu.rt_period_us 1000000
 
     mkdir /dev/cpuctl/bg_non_interactive
     chown system system /dev/cpuctl/bg_non_interactive/tasks
-    chmod 0777 /dev/cpuctl/bg_non_interactive/tasks
+    chmod 0666 /dev/cpuctl/bg_non_interactive/tasks
     # 5.0 %
     write /dev/cpuctl/bg_non_interactive/cpu.shares 52
+    write /dev/cpuctl/bg_non_interactive/cpu.rt_runtime_us 0
+    write /dev/cpuctl/bg_non_interactive/cpu.rt_period_us 1000000
+
+    mkdir /dev/cpuctl/audio_app
+    chown system system /dev/cpuctl/audio_app/tasks
+    chmod 0660 /dev/cpuctl/audio_app/tasks
+    write /dev/cpuctl/audio_app/cpu.shares 10
+    write /dev/cpuctl/audio_app/cpu.rt_runtime_us  50000
+    write /dev/cpuctl/audio_app/cpu.rt_period_us 1000000
+
+    mkdir /dev/cpuctl/audio_sys
+    chown system system /dev/cpuctl/audio_sys/tasks
+    chmod 0660 /dev/cpuctl/audio_sys/tasks
+    write /dev/cpuctl/audio_sys/cpu.shares 10
+    write /dev/cpuctl/audio_sys/cpu.rt_runtime_us  50000
+    write /dev/cpuctl/audio_sys/cpu.rt_period_us 1000000
 
 # Allow everybody to read the xt_qtaguid resource tracking misc dev.
 # This is needed by any process that uses socket tagging.
@@ -213,7 +235,7 @@
 
 # Memory management.  Basic kernel parameters, and allow the high
 # level system server to be able to adjust the kernel OOM driver
-# paramters to match how it is managing things.
+# parameters to match how it is managing things.
     write /proc/sys/vm/overcommit_memory 1
     write /proc/sys/vm/min_free_order_shift 4
     chown root system /sys/module/lowmemorykiller/parameters/adj
@@ -247,6 +269,8 @@
     chmod 0660 /sys/devices/system/cpu/cpufreq/interactive/hispeed_freq
     chown system system /sys/devices/system/cpu/cpufreq/interactive/go_hispeed_load
     chmod 0660 /sys/devices/system/cpu/cpufreq/interactive/go_hispeed_load
+    chown system system /sys/devices/system/cpu/cpufreq/interactive/above_hispeed_delay
+    chmod 0660 /sys/devices/system/cpu/cpufreq/interactive/above_hispeed_delay
 
     # Assume SMP uses shared cpufreq policy for all CPUs
     chown system system /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq