Merge "Revert "add IP checking for adb over TCP""
diff --git a/adb/Android.mk b/adb/Android.mk
index 248208a..1a25106 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -95,16 +95,6 @@
 # adbd device daemon
 # =========================================================
 
-BUILD_ADBD := true
-
-# build adbd for the Linux simulator build
-# so we can use it to test the adb USB gadget driver on x86
-#ifeq ($(HOST_OS),linux)
-#    BUILD_ADBD := true
-#endif
-
-
-ifeq ($(BUILD_ADBD),true)
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := \
@@ -127,12 +117,6 @@
 LOCAL_CFLAGS := -O2 -g -DADB_HOST=0 -Wall -Wno-unused-parameter
 LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE
 
-# TODO: This should probably be board specific, whether or not the kernel has
-# the gadget driver; rather than relying on the architecture type.
-ifeq ($(TARGET_ARCH),arm)
-LOCAL_CFLAGS += -DANDROID_GADGET=1
-endif
-
 ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
 LOCAL_CFLAGS += -DALLOW_ADBD_ROOT=1
 endif
@@ -146,8 +130,6 @@
 LOCAL_STATIC_LIBRARIES := libcutils libc
 include $(BUILD_EXECUTABLE)
 
-endif
-
 
 # adb host tool for device-as-host
 # =========================================================
diff --git a/adb/adb.h b/adb/adb.h
index 85922bf..03a7393 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -86,6 +86,11 @@
         */
     int    closing;
 
+        /* flag: quit adbd when both ends close the
+        ** local service socket
+        */
+    int    exit_on_close;
+
         /* the asocket we are connected to
         */
 
diff --git a/adb/commandline.c b/adb/commandline.c
index 5b2aa88..7af8163 100644
--- a/adb/commandline.c
+++ b/adb/commandline.c
@@ -1575,7 +1575,7 @@
 
     err = do_sync_push(apk_file, apk_dest, 1 /* verify APK */);
     if (err) {
-        return err;
+        goto cleanup_apk;
     } else {
         argv[file_arg] = apk_dest; /* destination name, not source location */
     }
@@ -1591,11 +1591,11 @@
 
     pm_command(transport, serial, argc, argv);
 
+cleanup_apk:
     if (verification_file != NULL) {
         delete_file(transport, serial, verification_dest);
     }
 
-cleanup_apk:
     delete_file(transport, serial, apk_dest);
 
     return err;
diff --git a/adb/services.c b/adb/services.c
index 6940be8..495a083 100644
--- a/adb/services.c
+++ b/adb/services.c
@@ -125,12 +125,10 @@
             return;
         }
 
+        property_set("service.adb.root", "1");
         snprintf(buf, sizeof(buf), "restarting adbd as root\n");
         writex(fd, buf, strlen(buf));
         adb_close(fd);
-
-        // This will cause a property trigger in init.rc to restart us
-        property_set("service.adb.root", "1");
     }
 }
 
@@ -152,10 +150,6 @@
     snprintf(buf, sizeof(buf), "restarting in TCP mode port: %d\n", port);
     writex(fd, buf, strlen(buf));
     adb_close(fd);
-
-    // quit, and init will restart us in TCP mode
-    sleep(1);
-    exit(1);
 }
 
 void restart_usb_service(int fd, void *cookie)
@@ -166,10 +160,6 @@
     snprintf(buf, sizeof(buf), "restarting in USB mode\n");
     writex(fd, buf, strlen(buf));
     adb_close(fd);
-
-    // quit, and init will restart us in USB mode
-    sleep(1);
-    exit(1);
 }
 
 void reboot_service(int fd, void *arg)
@@ -369,7 +359,6 @@
                 break;
             }
          }
-        usleep(100000);  // poll every 0.1 sec
     }
     D("shell exited fd=%d of pid=%d err=%d\n", fd, pid, errno);
     if (SHELL_EXIT_NOTIFY_FD >=0) {
diff --git a/adb/sockets.c b/adb/sockets.c
index df223b1..ce3c65e 100644
--- a/adb/sockets.c
+++ b/adb/sockets.c
@@ -199,6 +199,8 @@
 static void local_socket_destroy(asocket  *s)
 {
     apacket *p, *n;
+    int exit_on_close = s->exit_on_close;
+
     D("LS(%d): destroying fde.fd=%d\n", s->id, s->fde.fd);
 
         /* IMPORTANT: the remove closes the fd
@@ -214,6 +216,11 @@
     }
     remove_socket(s);
     free(s);
+
+    if (exit_on_close) {
+        D("local_socket_destroy: exiting\n");
+        exit(1);
+    }
 }
 
 
@@ -418,6 +425,13 @@
 
     s = create_local_socket(fd);
     D("LS(%d): bound to '%s' via %d\n", s->id, name, fd);
+
+    if (!strcmp(name, "root:") || !strcmp(name, "usb:") ||
+                                  !strcmp(name, "tcpip:")) {
+        D("LS(%d): enabling exit_on_close\n", s->id);
+        s->exit_on_close = 1;
+    }
+
     return s;
 }
 
diff --git a/adb/usb_vendors.c b/adb/usb_vendors.c
index 5d8a831..a477e4e 100644
--- a/adb/usb_vendors.c
+++ b/adb/usb_vendors.c
@@ -117,8 +117,6 @@
 #define VENDOR_ID_FUJITSU       0x04C5
 // Lumigon's USB Vendor ID
 #define VENDOR_ID_LUMIGON       0x25E3
-//Intel's USB Vendor ID
-#define VENDOR_ID_INTEL         0x8087
 // Quanta's USB Vendor ID
 #define VENDOR_ID_QUANTA        0x0408
 // INQ Mobile's USB Vendor ID
@@ -169,7 +167,6 @@
     VENDOR_ID_POSITIVO,
     VENDOR_ID_FUJITSU,
     VENDOR_ID_LUMIGON,
-    VENDOR_ID_INTEL,
     VENDOR_ID_QUANTA,
     VENDOR_ID_INQ_MOBILE,
     VENDOR_ID_SONY,
diff --git a/include/arch/darwin-x86/AndroidConfig.h b/include/arch/darwin-x86/AndroidConfig.h
index f79f364..48f8d9a 100644
--- a/include/arch/darwin-x86/AndroidConfig.h
+++ b/include/arch/darwin-x86/AndroidConfig.h
@@ -305,4 +305,14 @@
  */
 #define HAVE_PRINTF_ZD 1
 
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a BSD style function prototype.
+ */
+#define HAVE_BSD_QSORT_R 1
+
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a GNU style function prototype.
+ */
+#define HAVE_GNU_QSORT_R 0
+
 #endif /*_ANDROID_CONFIG_H*/
diff --git a/include/arch/freebsd-x86/AndroidConfig.h b/include/arch/freebsd-x86/AndroidConfig.h
index a8176f4..4bc5559 100644
--- a/include/arch/freebsd-x86/AndroidConfig.h
+++ b/include/arch/freebsd-x86/AndroidConfig.h
@@ -363,4 +363,14 @@
  */
 #define HAVE_PRINTF_ZD 1
 
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a BSD style function prototype.
+ */
+#define HAVE_BSD_QSORT_R 1
+
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a GNU style function prototype.
+ */
+#define HAVE_GNU_QSORT_R 0
+
 #endif /*_ANDROID_CONFIG_H*/
diff --git a/include/arch/linux-arm/AndroidConfig.h b/include/arch/linux-arm/AndroidConfig.h
index b8e8713..233752b 100644
--- a/include/arch/linux-arm/AndroidConfig.h
+++ b/include/arch/linux-arm/AndroidConfig.h
@@ -361,4 +361,14 @@
  */
 #define HAVE_PRINTF_ZD 1
 
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a BSD style function prototype.
+ */
+#define HAVE_BSD_QSORT_R 0
+
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a GNU style function prototype.
+ */
+#define HAVE_GNU_QSORT_R 0
+
 #endif /* _ANDROID_CONFIG_H */
diff --git a/include/arch/linux-ppc/AndroidConfig.h b/include/arch/linux-ppc/AndroidConfig.h
index 774c458..ae2569b 100644
--- a/include/arch/linux-ppc/AndroidConfig.h
+++ b/include/arch/linux-ppc/AndroidConfig.h
@@ -323,4 +323,14 @@
  */
 #define HAVE_PREAD 1
 
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a BSD style function prototype.
+ */
+#define HAVE_BSD_QSORT_R 0
+
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a GNU style function prototype.
+ */
+#define HAVE_GNU_QSORT_R 1
+
 #endif /*_ANDROID_CONFIG_H*/
diff --git a/include/arch/linux-sh/AndroidConfig.h b/include/arch/linux-sh/AndroidConfig.h
index cdfa2ac..818b628 100644
--- a/include/arch/linux-sh/AndroidConfig.h
+++ b/include/arch/linux-sh/AndroidConfig.h
@@ -366,4 +366,14 @@
  */
 #define HAVE_PRINTF_ZD 1
 
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a BSD style function prototype.
+ */
+#define HAVE_BSD_QSORT_R 0
+
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a GNU style function prototype.
+ */
+#define HAVE_GNU_QSORT_R 0
+
 #endif /* _ANDROID_CONFIG_H */
diff --git a/include/arch/linux-x86/AndroidConfig.h b/include/arch/linux-x86/AndroidConfig.h
index 6521699..431a54b 100644
--- a/include/arch/linux-x86/AndroidConfig.h
+++ b/include/arch/linux-x86/AndroidConfig.h
@@ -333,4 +333,18 @@
  */
 #define HAVE_PRINTF_ZD 1
 
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a BSD style function prototype.
+ */
+#define HAVE_BSD_QSORT_R 0
+
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a GNU style function prototype.
+ */
+#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8)
+#define HAVE_GNU_QSORT_R 1
+#else
+#define HAVE_GNU_QSORT_R 0
+#endif
+
 #endif /*_ANDROID_CONFIG_H*/
diff --git a/include/arch/target_linux-x86/AndroidConfig.h b/include/arch/target_linux-x86/AndroidConfig.h
index 9efb81a..ab53892 100644
--- a/include/arch/target_linux-x86/AndroidConfig.h
+++ b/include/arch/target_linux-x86/AndroidConfig.h
@@ -350,4 +350,14 @@
  */
 #define HAVE_PRINTF_ZD 1
 
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a BSD style function prototype.
+ */
+#define HAVE_BSD_QSORT_R 0
+
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a GNU style function prototype.
+ */
+#define HAVE_GNU_QSORT_R 0
+
 #endif /* _ANDROID_CONFIG_H */
diff --git a/include/arch/windows/AndroidConfig.h b/include/arch/windows/AndroidConfig.h
index 445e754..0274da5 100644
--- a/include/arch/windows/AndroidConfig.h
+++ b/include/arch/windows/AndroidConfig.h
@@ -338,4 +338,14 @@
  */
 /* #define HAVE_PRINTF_ZD 1 */
 
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a BSD style function prototype.
+ */
+#define HAVE_BSD_QSORT_R 0
+
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a GNU style function prototype.
+ */
+#define HAVE_GNU_QSORT_R 0
+
 #endif /*_ANDROID_CONFIG_H*/
diff --git a/include/cutils/list.h b/include/cutils/list.h
index eb5a3c8..3881fc9 100644
--- a/include/cutils/list.h
+++ b/include/cutils/list.h
@@ -19,6 +19,10 @@
 
 #include <stddef.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
 struct listnode
 {
     struct listnode *next;
@@ -48,4 +52,8 @@
 #define list_head(list) ((list)->next)
 #define list_tail(list) ((list)->prev)
 
+#ifdef __cplusplus
+};
+#endif /* __cplusplus */
+
 #endif
diff --git a/include/cutils/logger.h b/include/cutils/logger.h
index b60f7ad..04f3fb0 100644
--- a/include/cutils/logger.h
+++ b/include/cutils/logger.h
@@ -12,6 +12,11 @@
 
 #include <stdint.h>
 
+/*
+ * The userspace structure for version 1 of the logger_entry ABI.
+ * This structure is returned to userspace by the kernel logger
+ * driver unless an upgrade to a newer ABI version is requested.
+ */
 struct logger_entry {
     uint16_t    len;    /* length of the payload */
     uint16_t    __pad;  /* no matter what, we get 2 bytes of padding */
@@ -22,14 +27,41 @@
     char        msg[0]; /* the entry's payload */
 };
 
+/*
+ * The userspace structure for version 2 of the logger_entry ABI.
+ * This structure is returned to userspace if ioctl(LOGGER_SET_VERSION)
+ * is called with version==2
+ */
+struct logger_entry_v2 {
+    uint16_t    len;       /* length of the payload */
+    uint16_t    hdr_size;  /* sizeof(struct logger_entry_v2) */
+    int32_t     pid;       /* generating process's pid */
+    int32_t     tid;       /* generating process's tid */
+    int32_t     sec;       /* seconds since Epoch */
+    int32_t     nsec;      /* nanoseconds */
+    uint32_t    euid;      /* effective UID of logger */
+    char        msg[0];    /* the entry's payload */
+};
+
 #define LOGGER_LOG_MAIN		"log/main"
 #define LOGGER_LOG_RADIO	"log/radio"
 #define LOGGER_LOG_EVENTS	"log/events"
 #define LOGGER_LOG_SYSTEM	"log/system"
 
-#define LOGGER_ENTRY_MAX_LEN		(4*1024)
-#define LOGGER_ENTRY_MAX_PAYLOAD	\
-	(LOGGER_ENTRY_MAX_LEN - sizeof(struct logger_entry))
+/*
+ * The maximum size of the log entry payload that can be
+ * written to the kernel logger driver. An attempt to write
+ * more than this amount to /dev/log/* will result in a
+ * truncated log entry.
+ */
+#define LOGGER_ENTRY_MAX_PAYLOAD	4076
+
+/*
+ * The maximum size of a log entry which can be read from the
+ * kernel logger driver. An attempt to read less than this amount
+ * may result in read() returning EINVAL.
+ */
+#define LOGGER_ENTRY_MAX_LEN		(5*1024)
 
 #ifdef HAVE_IOCTL
 
@@ -41,6 +73,8 @@
 #define LOGGER_GET_LOG_LEN		_IO(__LOGGERIO, 2) /* used log len */
 #define LOGGER_GET_NEXT_ENTRY_LEN	_IO(__LOGGERIO, 3) /* next entry len */
 #define LOGGER_FLUSH_LOG		_IO(__LOGGERIO, 4) /* flush log */
+#define LOGGER_GET_VERSION		_IO(__LOGGERIO, 5) /* abi version */
+#define LOGGER_SET_VERSION		_IO(__LOGGERIO, 6) /* abi version */
 
 #endif // HAVE_IOCTL
 
diff --git a/include/cutils/qsort_r_compat.h b/include/cutils/qsort_r_compat.h
new file mode 100644
index 0000000..479a1ab
--- /dev/null
+++ b/include/cutils/qsort_r_compat.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+/*
+ * Provides a portable version of qsort_r, called qsort_r_compat, which is a
+ * reentrant variant of qsort that passes a user data pointer to its comparator.
+ * This implementation follows the BSD parameter convention.
+ */
+
+#ifndef _LIBS_CUTILS_QSORT_R_COMPAT_H
+#define _LIBS_CUTILS_QSORT_R_COMPAT_H
+
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void qsort_r_compat(void* base, size_t nel, size_t width, void* thunk,
+        int (*compar)(void*, const void* , const void* ));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _LIBS_CUTILS_QSORT_R_COMPAT_H
diff --git a/include/cutils/sched_policy.h b/include/cutils/sched_policy.h
index eaf3993..753a08c 100644
--- a/include/cutils/sched_policy.h
+++ b/include/cutils/sched_policy.h
@@ -24,11 +24,28 @@
 typedef enum {
     SP_BACKGROUND = 0,
     SP_FOREGROUND = 1,
+    SP_CNT,
+    SP_MAX        = SP_CNT - 1,
 } 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.
+ * 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.
+ * Return value: 0 for success, or -1 for error and set errno.
+ */
 extern int get_sched_policy(int tid, SchedPolicy *policy);
 
+/* Return a displayable string corresponding to policy.
+ * Return value: non-NULL NUL-terminated name of unspecified length;
+ * the caller is responsible for displaying the useful part of the string.
+ */
+extern const char *get_sched_policy_name(SchedPolicy policy);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/system/audio.h b/include/system/audio.h
index 0980319..0276231 100644
--- a/include/system/audio.h
+++ b/include/system/audio.h
@@ -384,7 +384,7 @@
         return false;
 }
 
-/* Derive a channel mask from a channel count.
+/* Derive an output channel mask from a channel count.
  * This is to be used when the content channel mask is unknown. The 1, 2, 4, 5, 6, 7 and 8 channel
  * cases are mapped to the standard game/home-theater layouts, but note that 4 is mapped to quad,
  * and not stereo + FC + mono surround. A channel count of 3 is arbitrarily mapped to stereo + FC
@@ -392,7 +392,7 @@
  * Returns the matching channel mask, or 0 if the number of channels exceeds that of the
  * configurations for which a default channel mask is defined.
  */
-static inline audio_channel_mask_t audio_channel_mask_from_count(uint32_t channel_count)
+static inline audio_channel_mask_t audio_channel_out_mask_from_count(uint32_t channel_count)
 {
     switch(channel_count) {
     case 1:
@@ -416,6 +416,19 @@
     }
 }
 
+/* Similar to above, but for input.  Currently handles only mono and stereo. */
+static inline audio_channel_mask_t audio_channel_in_mask_from_count(uint32_t channel_count)
+{
+    switch (channel_count) {
+    case 1:
+        return AUDIO_CHANNEL_IN_MONO;
+    case 2:
+        return AUDIO_CHANNEL_IN_STEREO;
+    default:
+        return 0;
+    }
+}
+
 static inline bool audio_is_valid_format(audio_format_t format)
 {
     switch (format & AUDIO_FORMAT_MAIN_MASK) {
@@ -447,18 +460,18 @@
     size_t size = 0;
 
     switch (format) {
-        case AUDIO_FORMAT_PCM_32_BIT:
-        case AUDIO_FORMAT_PCM_8_24_BIT:
-            size = sizeof(int32_t);
-            break;
-        case AUDIO_FORMAT_PCM_16_BIT:
-            size = sizeof(int16_t);
-            break;
-        case AUDIO_FORMAT_PCM_8_BIT:
-            size = sizeof(uint8_t);
-            break;
-        default:
-            break;
+    case AUDIO_FORMAT_PCM_32_BIT:
+    case AUDIO_FORMAT_PCM_8_24_BIT:
+        size = sizeof(int32_t);
+        break;
+    case AUDIO_FORMAT_PCM_16_BIT:
+        size = sizeof(int16_t);
+        break;
+    case AUDIO_FORMAT_PCM_8_BIT:
+        size = sizeof(uint8_t);
+        break;
+    default:
+        break;
     }
     return size;
 }
diff --git a/include/system/audio_policy.h b/include/system/audio_policy.h
index 70fc534..641b177 100644
--- a/include/system/audio_policy.h
+++ b/include/system/audio_policy.h
@@ -43,10 +43,11 @@
     AUDIO_POLICY_OUTPUT_FLAG_NONE = 0x0,    // no attributes
     AUDIO_POLICY_OUTPUT_FLAG_DIRECT = 0x1,  // this output directly connects a track to one output
                                             // stream (no software mixer)
-    AUDIO_POLICY_OUTPUT_FLAG_PRIMARY = 0x2  // this output is the primary output of the device.
+    AUDIO_POLICY_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_POLICY_OUTPUT_FLAG_FAST = 0x4,    // output supports "fast tracks", defined elsewhere
 } audio_policy_output_flags_t;
 
 /* device categories used for audio_policy->set_force_use() */
diff --git a/include/system/camera.h b/include/system/camera.h
index 62167cf..b8389b1 100644
--- a/include/system/camera.h
+++ b/include/system/camera.h
@@ -151,11 +151,30 @@
      * arg1 = 0 will disable, while passing arg1 = 1 will enable the callback.
      */
     CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG = 8,
+
+    /**
+     * Ping camera service to see if camera hardware is released.
+     *
+     * When any camera method returns error, the client can use ping command
+     * to see if the camera has been taken away by other clients. If the result
+     * is NO_ERROR, it means the camera hardware is not released. If the result
+     * is not NO_ERROR, the camera has been released and the existing client
+     * can silently finish itself or show a dialog.
+     */
+    CAMERA_CMD_PING = 9,
 };
 
 /** camera fatal errors */
 enum {
     CAMERA_ERROR_UNKNOWN = 1,
+    /**
+     * Camera was released because another client has connected to the camera.
+     * The original client should call Camera::disconnect immediately after
+     * getting this notification. Otherwise, the camera will be released by
+     * camera service in a short time. The client should not call any method
+     * (except disconnect and sending CAMERA_CMD_PING) after getting this.
+     */
+    CAMERA_ERROR_RELEASED = 2,
     CAMERA_ERROR_SERVER_DIED = 100
 };
 
diff --git a/init/builtins.c b/init/builtins.c
index 9aa2345..adad353 100644
--- a/init/builtins.c
+++ b/init/builtins.c
@@ -75,6 +75,52 @@
     }
 }
 
+static int _chown(const char *path, unsigned int uid, unsigned int gid)
+{
+    int fd;
+    int ret;
+
+    fd = open(path, O_RDONLY | O_NOFOLLOW);
+    if (fd < 0) {
+        return -1;
+    }
+
+    ret = fchown(fd, uid, gid);
+    if (ret < 0) {
+        int errno_copy = errno;
+        close(fd);
+        errno = errno_copy;
+        return -1;
+    }
+
+    close(fd);
+
+    return 0;
+}
+
+static int _chmod(const char *path, mode_t mode)
+{
+    int fd;
+    int ret;
+
+    fd = open(path, O_RDONLY | O_NOFOLLOW);
+    if (fd < 0) {
+        return -1;
+    }
+
+    ret = fchmod(fd, mode);
+    if (ret < 0) {
+        int errno_copy = errno;
+        close(fd);
+        errno = errno_copy;
+        return -1;
+    }
+
+    close(fd);
+
+    return 0;
+}
+
 static int insmod(const char *filename, char *options)
 {
     void *module;
@@ -246,7 +292,7 @@
     ret = mkdir(args[1], mode);
     /* chmod in case the directory already exists */
     if (ret == -1 && errno == EEXIST) {
-        ret = chmod(args[1], mode);
+        ret = _chmod(args[1], mode);
     }
     if (ret == -1) {
         return -errno;
@@ -260,7 +306,7 @@
             gid = decode_uid(args[4]);
         }
 
-        if (chown(args[1], uid, gid)) {
+        if (_chown(args[1], uid, gid) < 0) {
             return -errno;
         }
     }
@@ -644,10 +690,10 @@
 int do_chown(int nargs, char **args) {
     /* GID is optional. */
     if (nargs == 3) {
-        if (chown(args[2], decode_uid(args[1]), -1) < 0)
+        if (_chown(args[2], decode_uid(args[1]), -1) < 0)
             return -errno;
     } else if (nargs == 4) {
-        if (chown(args[3], decode_uid(args[1]), decode_uid(args[2])))
+        if (_chown(args[3], decode_uid(args[1]), decode_uid(args[2])) < 0)
             return -errno;
     } else {
         return -1;
@@ -670,7 +716,7 @@
 
 int do_chmod(int nargs, char **args) {
     mode_t mode = get_mode(args[1]);
-    if (chmod(args[2], mode) < 0) {
+    if (_chmod(args[2], mode) < 0) {
         return -errno;
     }
     return 0;
diff --git a/init/devices.c b/init/devices.c
index 3b4d369..125f981 100644
--- a/init/devices.c
+++ b/init/devices.c
@@ -63,6 +63,7 @@
     const char *subsystem;
     const char *firmware;
     const char *partition_name;
+    const char *device_name;
     int partition_num;
     int major;
     int minor;
@@ -335,6 +336,7 @@
     uevent->minor = -1;
     uevent->partition_name = NULL;
     uevent->partition_num = -1;
+    uevent->device_name = NULL;
 
         /* currently ignoring SEQNUM */
     while(*msg) {
@@ -362,9 +364,12 @@
         } else if(!strncmp(msg, "PARTNAME=", 9)) {
             msg += 9;
             uevent->partition_name = msg;
+        } else if(!strncmp(msg, "DEVNAME=", 8)) {
+            msg += 8;
+            uevent->device_name = msg;
         }
 
-            /* advance to after the next \0 */
+        /* advance to after the next \0 */
         while(*msg++)
             ;
     }
@@ -579,18 +584,39 @@
 
     if (!strncmp(uevent->subsystem, "usb", 3)) {
          if (!strcmp(uevent->subsystem, "usb")) {
-             /* This imitates the file system that would be created
-              * if we were using devfs instead.
-              * Minors are broken up into groups of 128, starting at "001"
-              */
-             int bus_id = uevent->minor / 128 + 1;
-             int device_id = uevent->minor % 128 + 1;
-             /* build directories */
-             make_dir("/dev/bus", 0755);
-             make_dir("/dev/bus/usb", 0755);
-             snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d", bus_id);
-             make_dir(devpath, 0755);
-             snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d/%03d", bus_id, device_id);
+            if (uevent->device_name) {
+                /*
+                 * create device node provided by kernel if present
+                 * see drivers/base/core.c
+                 */
+                char *p = devpath;
+                snprintf(devpath, sizeof(devpath), "/dev/%s", uevent->device_name);
+                /* skip leading /dev/ */
+                p += 5;
+                /* build directories */
+                while (*p) {
+                    if (*p == '/') {
+                        *p = 0;
+                        make_dir(devpath, 0755);
+                        *p = '/';
+                    }
+                    p++;
+                }
+             }
+             else {
+                 /* This imitates the file system that would be created
+                  * if we were using devfs instead.
+                  * Minors are broken up into groups of 128, starting at "001"
+                  */
+                 int bus_id = uevent->minor / 128 + 1;
+                 int device_id = uevent->minor % 128 + 1;
+                 /* build directories */
+                 make_dir("/dev/bus", 0755);
+                 make_dir("/dev/bus/usb", 0755);
+                 snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d", bus_id);
+                 make_dir(devpath, 0755);
+                 snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d/%03d", bus_id, device_id);
+             }
          } else {
              /* ignore other USB events */
              return;
diff --git a/init/init.c b/init/init.c
index 1ee88a7..5458e34 100755
--- a/init/init.c
+++ b/init/init.c
@@ -134,6 +134,7 @@
     if ((fd = open(console_name, O_RDWR)) < 0) {
         fd = open("/dev/null", O_RDWR);
     }
+    ioctl(fd, TIOCSCTTY, 0);
     dup2(fd, 0);
     dup2(fd, 1);
     dup2(fd, 2);
diff --git a/libcutils/Android.mk b/libcutils/Android.mk
index 3809733..0d49165 100644
--- a/libcutils/Android.mk
+++ b/libcutils/Android.mk
@@ -46,6 +46,7 @@
 	record_stream.c \
 	process_name.c \
 	properties.c \
+	qsort_r_compat.c \
 	threads.c \
 	sched_policy.c \
 	iosched_policy.c \
diff --git a/libcutils/process_name.c b/libcutils/process_name.c
index b235429..bda9d08 100644
--- a/libcutils/process_name.c
+++ b/libcutils/process_name.c
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <stdlib.h>
 #include <string.h>
 #include <cutils/process_name.h>
 #include <cutils/properties.h>
diff --git a/libcutils/qsort_r_compat.c b/libcutils/qsort_r_compat.c
new file mode 100644
index 0000000..8971cb5
--- /dev/null
+++ b/libcutils/qsort_r_compat.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <cutils/qsort_r_compat.h>
+
+#if HAVE_BSD_QSORT_R
+
+/*
+ * BSD qsort_r parameter order is as we have defined here.
+ */
+
+void qsort_r_compat(void* base, size_t nel, size_t width, void* thunk,
+        int (*compar)(void*, const void* , const void*)) {
+    qsort_r(base, nel, width, thunk, compar);
+}
+
+#elif HAVE_GNU_QSORT_R
+
+/*
+ * GNU qsort_r parameter order places the thunk parameter last.
+ */
+
+struct compar_data {
+    void* thunk;
+    int (*compar)(void*, const void* , const void*);
+};
+
+static int compar_wrapper(const void* a, const void* b, void* data) {
+    struct compar_data* compar_data = (struct compar_data*)data;
+    return compar_data->compar(compar_data->thunk, a, b);
+}
+
+void qsort_r_compat(void* base, size_t nel, size_t width, void* thunk,
+        int (*compar)(void*, const void* , const void*)) {
+    struct compar_data compar_data;
+    compar_data.thunk = thunk;
+    compar_data.compar = compar;
+    qsort_r(base, nel, width, compar_wrapper, &compar_data);
+}
+
+#else
+
+/*
+ * Emulate qsort_r using thread local storage to access the thunk data.
+ */
+
+#include <cutils/threads.h>
+
+static thread_store_t compar_data_key = THREAD_STORE_INITIALIZER;
+
+struct compar_data {
+    void* thunk;
+    int (*compar)(void*, const void* , const void*);
+};
+
+static int compar_wrapper(const void* a, const void* b) {
+    struct compar_data* compar_data = (struct compar_data*)thread_store_get(&compar_data_key);
+    return compar_data->compar(compar_data->thunk, a, b);
+}
+
+void qsort_r_compat(void* base, size_t nel, size_t width, void* thunk,
+        int (*compar)(void*, const void* , const void*)) {
+    struct compar_data compar_data;
+    compar_data.thunk = thunk;
+    compar_data.compar = compar;
+    thread_store_set(&compar_data_key, &compar_data, NULL);
+    qsort(base, nel, width, compar_wrapper);
+}
+
+#endif
diff --git a/libcutils/sched_policy.c b/libcutils/sched_policy.c
index f9c111e..35d362a 100644
--- a/libcutils/sched_policy.c
+++ b/libcutils/sched_policy.c
@@ -273,5 +273,17 @@
     return 0;
 }
 
+const char *get_sched_policy_name(SchedPolicy policy)
+{
+    static const char * const strings[SP_CNT] = {
+       [SP_BACKGROUND] = "bg",
+       [SP_FOREGROUND] = "fg",
+    };
+    if ((policy < SP_CNT) && (strings[policy] != NULL))
+        return strings[policy];
+    else
+        return "error";
+}
+
 #endif /* HAVE_PTHREADS */
 #endif /* HAVE_SCHED_H */
diff --git a/libcutils/str_parms.c b/libcutils/str_parms.c
index 16138f6..9e1d2dc 100644
--- a/libcutils/str_parms.c
+++ b/libcutils/str_parms.c
@@ -70,19 +70,57 @@
     return NULL;
 }
 
+struct remove_ctxt {
+    struct str_parms *str_parms;
+    const char *key;
+};
+
 static bool remove_pair(void *key, void *value, void *context)
 {
-    struct str_parms *str_parms = context;
+    struct remove_ctxt *ctxt = context;
+    bool should_continue;
 
-    hashmapRemove(str_parms->map, key);
+    /*
+     * - if key is not supplied, then we are removing all entries,
+     *   so remove key and continue (i.e. return true)
+     * - if key is supplied and matches, then remove it and don't
+     *   continue (return false). Otherwise, return true and keep searching
+     *   for key.
+     *
+     */
+    if (!ctxt->key) {
+        should_continue = true;
+        goto do_remove;
+    } else if (!strcmp(ctxt->key, key)) {
+        should_continue = false;
+        goto do_remove;
+    }
+
+    return true;
+
+do_remove:
+    hashmapRemove(ctxt->str_parms->map, key);
     free(key);
     free(value);
-    return true;
+    return should_continue;
+}
+
+void str_parms_del(struct str_parms *str_parms, const char *key)
+{
+    struct remove_ctxt ctxt = {
+        .str_parms = str_parms,
+        .key = key,
+    };
+    hashmapForEach(str_parms->map, remove_pair, &ctxt);
 }
 
 void str_parms_destroy(struct str_parms *str_parms)
 {
-    hashmapForEach(str_parms->map, remove_pair, str_parms);
+    struct remove_ctxt ctxt = {
+        .str_parms = str_parms,
+    };
+
+    hashmapForEach(str_parms->map, remove_pair, &ctxt);
     hashmapFree(str_parms->map);
     free(str_parms);
 }
@@ -128,8 +166,10 @@
 
         /* if we replaced a value, free it */
         old_val = hashmapPut(str_parms->map, key, value);
-        if (old_val)
+        if (old_val) {
             free(old_val);
+            free(key);
+        }
 
         items++;
 next_pair:
@@ -149,11 +189,6 @@
     return NULL;
 }
 
-void str_parms_del(struct str_parms *str_parms, const char *key)
-{
-    hashmapRemove(str_parms->map, (void *)key);
-}
-
 int str_parms_add_str(struct str_parms *str_parms, const char *key,
                       const char *value)
 {
@@ -167,6 +202,7 @@
 
     if (old_val) {
         free(old_val);
+        free(tmp_key);
     } else if (errno == ENOMEM) {
         free(tmp_key);
         free(tmp_val);
@@ -302,6 +338,8 @@
 
     str_parms = str_parms_create_str(str);
     str_parms_add_str(str_parms, "dude", "woah");
+    str_parms_add_str(str_parms, "dude", "woah");
+    str_parms_del(str_parms, "dude");
     str_parms_dump(str_parms);
     out_str = str_parms_to_str(str_parms);
     str_parms_destroy(str_parms);
@@ -327,6 +365,7 @@
     test_str_parms_str("foo=bar;baz=");
     test_str_parms_str("foo=bar;baz=bat");
     test_str_parms_str("foo=bar;baz=bat;");
+    test_str_parms_str("foo=bar;baz=bat;foo=bar");
 
     return 0;
 }
diff --git a/libcutils/tzstrftime.c b/libcutils/tzstrftime.c
index e37d79a..e4f54df 100644
--- a/libcutils/tzstrftime.c
+++ b/libcutils/tzstrftime.c
@@ -8,6 +8,7 @@
 #endif /* !defined NOID */
 #endif /* !defined lint */
 
+#include <stdio.h>
 #include <time.h>
 #include <tzfile.h>
 #include <limits.h>
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 2e8f7d2..71ec3fa 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -1,3 +1,9 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# IMPORTANT: Do not create world writable files or directories.
+# This is a common source of Android security bugs.
+#
+
 import /init.${ro.hardware}.rc
 
 on early-init
@@ -24,7 +30,7 @@
     export ANDROID_DATA /data
     export ASEC_MOUNTPOINT /mnt/asec
     export LOOP_MOUNTPOINT /mnt/obb
-    export BOOTCLASSPATH /system/framework/core.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/apache-xml.jar:/system/framework/filterfw.jar
+    export BOOTCLASSPATH /system/framework/core.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/apache-xml.jar
 
 # Backward compatibility
     symlink /system/etc /etc
@@ -163,11 +169,16 @@
     mkdir /data/misc/wifi 0770 wifi wifi
     chmod 0660 /data/misc/wifi/wpa_supplicant.conf
     mkdir /data/local 0751 root root
+
+    # For security reasons, /data/local/tmp should always be empty.
+    # Do not place files or directories in /data/local/tmp
     mkdir /data/local/tmp 0771 shell shell
     mkdir /data/data 0771 system system
     mkdir /data/app-private 0771 system system
     mkdir /data/app 0771 system system
     mkdir /data/property 0700 root root
+    mkdir /data/ssh 0750 root shell
+    mkdir /data/ssh/empty 0700 root root
 
     # create dalvik-cache, so as to enforce our permissions
     mkdir /data/dalvik-cache 0771 system system
@@ -224,7 +235,8 @@
     chown radio system /sys/android_power/acquire_full_wake_lock
     chown radio system /sys/android_power/acquire_partial_wake_lock
     chown radio system /sys/android_power/release_wake_lock
-    chown radio system /sys/power/state
+    chown system system /sys/power/state
+    chown system system /sys/power/wakeup_count
     chown radio system /sys/power/wake_lock
     chown radio system /sys/power/wake_unlock
     chmod 0660 /sys/power/state
@@ -367,18 +379,6 @@
 on property:ro.kernel.qemu=1
     start adbd
 
-# This property trigger has added to imitiate the previous behavior of "adb root".
-# The adb gadget driver used to reset the USB bus when the adbd daemon exited,
-# and the host side adb relied on this behavior to force it to reconnect with the
-# new adbd instance after init relaunches it. So now we force the USB bus to reset
-# here when adbd sets the service.adb.root property to 1.  We also restart adbd here
-# rather than waiting for init to notice its death and restarting it so the timing
-# of USB resetting and adb restarting more closely matches the previous behavior.
-on property:service.adb.root=1
-    write /sys/class/android_usb/android0/enable 0
-    restart adbd
-    write /sys/class/android_usb/android0/enable 1
-
 service servicemanager /system/bin/servicemanager
     class core
     user system
@@ -426,7 +426,7 @@
 service drm /system/bin/drmserver
     class main
     user drm
-    group system inet drmrpc
+    group drm system inet drmrpc
 
 service media /system/bin/mediaserver
     class main
@@ -483,7 +483,7 @@
 service keystore /system/bin/keystore /data/misc/keystore
     class main
     user keystore
-    group keystore
+    group keystore drmrpc
     socket keystore stream 666
 
 service dumpstate /system/bin/dumpstate -s
@@ -491,3 +491,7 @@
     socket dumpstate stream 0660 shell log
     disabled
     oneshot
+
+service sshd /system/bin/start-ssh
+    class main
+    disabled
diff --git a/toolbox/ps.c b/toolbox/ps.c
index 7c3de4a..7c35ccb 100644
--- a/toolbox/ps.c
+++ b/toolbox/ps.c
@@ -167,14 +167,8 @@
             SchedPolicy p;
             if (get_sched_policy(pid, &p) < 0)
                 printf(" un ");
-            else {
-                if (p == SP_BACKGROUND)
-                    printf(" bg ");
-                else if (p == SP_FOREGROUND)
-                    printf(" fg ");
-                else
-                    printf(" er ");
-            }
+            else
+                printf(" %.2s ", get_sched_policy_name(p));
         }
         printf(" %08x %08x %s %s", wchan, eip, state, cmdline[0] ? cmdline : name);
         if(display_flags&SHOW_TIME)
diff --git a/toolbox/top.c b/toolbox/top.c
index 999c8e1..7642522 100644
--- a/toolbox/top.c
+++ b/toolbox/top.c
@@ -48,6 +48,7 @@
 
 #define PROC_NAME_LEN 64
 #define THREAD_NAME_LEN 32
+#define POLICY_NAME_LEN 4
 
 struct proc_info {
     struct proc_info *next;
@@ -67,7 +68,7 @@
     long rss;
     int prs;
     int num_threads;
-    char policy[32];
+    char policy[POLICY_NAME_LEN];
 };
 
 struct proc_list {
@@ -381,14 +382,10 @@
 static void read_policy(int pid, struct proc_info *proc) {
     SchedPolicy p;
     if (get_sched_policy(pid, &p) < 0)
-        strcpy(proc->policy, "unk");
+        strlcpy(proc->policy, "unk", POLICY_NAME_LEN);
     else {
-        if (p == SP_BACKGROUND)
-            strcpy(proc->policy, "bg");
-        else if (p == SP_FOREGROUND)
-            strcpy(proc->policy, "fg");
-        else
-            strcpy(proc->policy, "er");
+        strlcpy(proc->policy, get_sched_policy_name(p), POLICY_NAME_LEN);
+        proc->policy[2] = '\0';
     }
 }