Merge "rename uevent_checked_recv to uevent_kernel_multicast_recv"
diff --git a/adb/Android.mk b/adb/Android.mk
index e893ca9..2ac9335 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -165,7 +165,6 @@
 
 LOCAL_SRC_FILES := \
 	adb.c \
-	backup_service.c \
 	console.c \
 	transport.c \
 	transport_local.c \
diff --git a/adb/adb.h b/adb/adb.h
index 318a2d8..92dc62e 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -304,7 +304,11 @@
 #endif
 
 #if !ADB_HOST
-int backup_service(char* args);
+typedef enum {
+    BACKUP,
+    RESTORE
+} BackupOperation;
+int backup_service(BackupOperation operation, char* args);
 void framebuffer_service(int fd, void *cookie);
 void log_service(int fd, void *cookie);
 void remount_service(int fd, void *cookie);
diff --git a/adb/backup_service.c b/adb/backup_service.c
index f5dc0b2..2e6e754 100644
--- a/adb/backup_service.c
+++ b/adb/backup_service.c
@@ -23,17 +23,28 @@
 #include "adb.h"
 
 /* returns the data socket passing the backup data here for forwarding */
-int backup_service(char* args) {
+int backup_service(BackupOperation op, char* args) {
     pid_t pid;
     int s[2];
+    char* operation;
+    int socketnum;
 
-    D("backup_service(%s)\n", args);
+    // Command string and choice of stdin/stdout for the pipe depend on our invocation
+    if (op == BACKUP) {
+        operation = "backup";
+        socketnum = STDOUT_FILENO;
+    } else {
+        operation = "restore";
+        socketnum = STDIN_FILENO;
+    }
+
+    D("backup_service(%s, %s)\n", operation, args);
 
     // set up the pipe from the subprocess to here
     // parent will read s[0]; child will write s[1]
     if (adb_socketpair(s)) {
-        D("can't create backup socketpair\n");
-        fprintf(stderr, "unable to create backup socketpair\n");
+        D("can't create backup/restore socketpair\n");
+        fprintf(stderr, "unable to create backup/restore socketpair\n");
         return -1;
     }
 
@@ -41,8 +52,8 @@
     pid = fork();
     if (pid < 0) {
         // failure
-        D("can't fork for backup\n");
-        fprintf(stderr, "unable to fork for backup\n");
+        D("can't fork for %s\n", operation);
+        fprintf(stderr, "unable to fork for %s\n", operation);
         adb_close(s[0]);
         adb_close(s[1]);
         return -1;
@@ -52,36 +63,37 @@
     if (pid == 0) {
         char* p;
         int argc;
-        char** backup_args;
+        char** bu_args;
 
         // child -- actually run the backup here
-        argc = 1; // room for the basic 'bu' argv[0]
+        argc = 2; // room for the basic 'bu' argv[0] and '[operation]' argv[1]
         for (p = (char*)args; p && *p; ) {
             argc++;
             while (*p && *p != ':') p++;
             if (*p == ':') p++;
         }
 
-        backup_args = (char**) alloca(argc*sizeof(char*) + 1);
-        backup_args[0] = "bu";
-        argc = 1;   // run through again to build the argv array
-        for (p = (char*)args; *p; ) {
-            backup_args[argc++] = p;
+        bu_args = (char**) alloca(argc*sizeof(char*) + 1);
+        bu_args[0] = "bu";
+        bu_args[1] = operation;
+        argc = 2;   // run through again to build the argv array
+        for (p = (char*)args; p && *p; ) {
+            bu_args[argc++] = p;
             while (*p && *p != ':') p++;
             if (*p == ':') {
                 *p = 0;
                 p++;
             }
         }
-        backup_args[argc] = NULL;
+        bu_args[argc] = NULL;
 
         // Close the half of the socket that we don't care about, route 'bu's console
         // to the output socket, and off we go
         adb_close(s[0]);
-        dup2(s[1], STDOUT_FILENO);
+        dup2(s[1], socketnum);
 
         // off we go
-        execvp("/system/bin/bu", (char * const *)backup_args);
+        execvp("/system/bin/bu", (char * const *)bu_args);
         // oops error - close up shop and go home
         fprintf(stderr, "Unable to exec 'bu', bailing\n");
         exit(-1);
diff --git a/adb/commandline.c b/adb/commandline.c
index 733cbff..460120e 100644
--- a/adb/commandline.c
+++ b/adb/commandline.c
@@ -142,6 +142,8 @@
         "                                    the -all or -shared flags are passed, then the package\n"
         "                                    list is optional.)\n"
         "\n"
+        "  adb restore <file>           - restore device contents from the <file> backup tarfile\n"
+        "\n"
         "  adb help                     - show this help message\n"
         "  adb version                  - show version num\n"
         "\n"
@@ -601,6 +603,33 @@
     return 0;
 }
 
+static int restore(int argc, char** argv) {
+    const char* filename;
+    int fd, tarFd;
+
+    if (argc != 2) return usage();
+
+    filename = argv[1];
+    tarFd = adb_open(filename, O_RDONLY);
+    if (tarFd < 0) {
+        fprintf(stderr, "adb: unable to open file %s\n", filename);
+        return -1;
+    }
+
+    fd = adb_connect("restore:");
+    if (fd < 0) {
+        fprintf(stderr, "adb: unable to connect for backup\n");
+        adb_close(tarFd);
+        return -1;
+    }
+
+    copy_to_file(tarFd, fd);
+
+    adb_close(fd);
+    adb_close(tarFd);
+    return 0;
+}
+
 #define SENTINEL_FILE "config" OS_PATH_SEPARATOR_STR "envsetup.make"
 static int top_works(const char *top)
 {
@@ -1164,6 +1193,10 @@
         return backup(argc, argv);
     }
 
+    if (!strcmp(argv[0], "restore")) {
+        return restore(argc, argv);
+    }
+
     if (!strcmp(argv[0], "jdwp")) {
         int  fd = adb_connect("jdwp");
         if (fd >= 0) {
diff --git a/adb/services.c b/adb/services.c
index ec0b0ba..6bbd6f8 100644
--- a/adb/services.c
+++ b/adb/services.c
@@ -482,7 +482,9 @@
     } else if(!strncmp(name, "backup:", 7)) {
         char* arg = strdup(name+7);
         if (arg == NULL) return -1;
-        ret = backup_service(arg);
+        ret = backup_service(BACKUP, arg);
+    } else if(!strncmp(name, "restore:", 8)) {
+        ret = backup_service(RESTORE, NULL);
     } else if(!strncmp(name, "tcpip:", 6)) {
         int port;
         if (sscanf(name + 6, "%d", &port) == 0) {
diff --git a/adb/usb_linux.c b/adb/usb_linux.c
index b7ee4ec..4d55b74 100644
--- a/adb/usb_linux.c
+++ b/adb/usb_linux.c
@@ -605,6 +605,7 @@
         ctrl.wIndex = 0;
         ctrl.wLength = sizeof(languages);
         ctrl.data = languages;
+        ctrl.timeout = 1000;
 
         result = ioctl(usb->desc, USBDEVFS_CONTROL, &ctrl);
         if (result > 0)
@@ -620,6 +621,7 @@
             ctrl.wIndex = __le16_to_cpu(languages[i]);
             ctrl.wLength = sizeof(buffer);
             ctrl.data = buffer;
+            ctrl.timeout = 1000;
 
             result = ioctl(usb->desc, USBDEVFS_CONTROL, &ctrl);
             if (result > 0) {
diff --git a/adb/usb_vendors.c b/adb/usb_vendors.c
index d642566..1ab5100 100644
--- a/adb/usb_vendors.c
+++ b/adb/usb_vendors.c
@@ -87,6 +87,10 @@
 #define VENDOR_ID_PHILIPS       0x0471
 // Texas Instruments's USB Vendor ID
 #define VENDOR_ID_TI            0x0451
+// Funai's USB Vendor ID
+#define VENDOR_ID_FUNAI         0x0F1C
+// Gigabyte's USB Vendor ID
+#define VENDOR_ID_GIGABYTE      0x0414
 
 
 /** built-in vendor list */
@@ -117,6 +121,8 @@
     VENDOR_ID_ASUS,
     VENDOR_ID_PHILIPS,
     VENDOR_ID_TI,
+    VENDOR_ID_FUNAI,
+    VENDOR_ID_GIGABYTE,
 };
 
 #define BUILT_IN_VENDOR_COUNT    (sizeof(builtInVendorIds)/sizeof(builtInVendorIds[0]))
diff --git a/include/system/audio.h b/include/system/audio.h
new file mode 100644
index 0000000..8f2ac0c
--- /dev/null
+++ b/include/system/audio.h
@@ -0,0 +1,393 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+
+#ifndef ANDROID_AUDIO_CORE_H
+#define ANDROID_AUDIO_CORE_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+#include <cutils/bitops.h>
+
+__BEGIN_DECLS
+
+/* The enums were moved here mostly from
+ * frameworks/base/include/media/AudioSystem.h
+ */
+
+typedef int audio_io_handle_t;
+
+/* Audio stream types */
+typedef enum {
+    AUDIO_STREAM_DEFAULT          = -1,
+    AUDIO_STREAM_VOICE_CALL       = 0,
+    AUDIO_STREAM_SYSTEM           = 1,
+    AUDIO_STREAM_RING             = 2,
+    AUDIO_STREAM_MUSIC            = 3,
+    AUDIO_STREAM_ALARM            = 4,
+    AUDIO_STREAM_NOTIFICATION     = 5,
+    AUDIO_STREAM_BLUETOOTH_SCO    = 6,
+    AUDIO_STREAM_ENFORCED_AUDIBLE = 7, /* Sounds that cannot be muted by user and must be routed to speaker */
+    AUDIO_STREAM_DTMF             = 8,
+    AUDIO_STREAM_TTS              = 9,
+
+    AUDIO_STREAM_CNT,
+    AUDIO_STREAM_MAX              = AUDIO_STREAM_CNT - 1,
+} audio_stream_type_t;
+
+/* Do not change these values without updating their counterparts
+ * in media/java/android/media/MediaRecorder.java!
+ */
+typedef enum {
+    AUDIO_SOURCE_DEFAULT             = 0,
+    AUDIO_SOURCE_MIC                 = 1,
+    AUDIO_SOURCE_VOICE_UPLINK        = 2,
+    AUDIO_SOURCE_VOICE_DOWNLINK      = 3,
+    AUDIO_SOURCE_VOICE_CALL          = 4,
+    AUDIO_SOURCE_CAMCORDER           = 5,
+    AUDIO_SOURCE_VOICE_RECOGNITION   = 6,
+    AUDIO_SOURCE_VOICE_COMMUNICATION = 7,
+
+    AUDIO_SOURCE_CNT,
+    AUDIO_SOURCE_MAX                 = AUDIO_SOURCE_CNT - 1,
+} audio_source_t;
+
+/* special audio session values
+ * (XXX: should this be living in the audio effects land?)
+ */
+typedef enum {
+    /* session for effects attached to a particular output stream
+     * (value must be less than 0)
+     */
+    AUDIO_SESSION_OUTPUT_STAGE = -1,
+
+    /* session for effects applied to output mix. These effects can
+     * be moved by audio policy manager to another output stream
+     * (value must be 0)
+     */
+    AUDIO_SESSION_OUTPUT_MIX = 0,
+} audio_session_t;
+
+/* Audio sub formats (see enum audio_format). */
+
+/* PCM sub formats */
+typedef enum {
+    AUDIO_FORMAT_PCM_SUB_16_BIT          = 0x1, /* DO NOT CHANGE */
+    AUDIO_FORMAT_PCM_SUB_8_BIT           = 0x2, /* DO NOT CHANGE */
+} audio_format_pcm_sub_fmt_t;
+
+/* MP3 sub format field definition : can use 11 LSBs in the same way as MP3
+ * frame header to specify bit rate, stereo mode, version...
+ */
+typedef enum {
+    AUDIO_FORMAT_MP3_SUB_NONE            = 0x0,
+} audio_format_mp3_sub_fmt_t;
+
+/* AMR NB/WB sub format field definition: specify frame block interleaving,
+ * bandwidth efficient or octet aligned, encoding mode for recording...
+ */
+typedef enum {
+    AUDIO_FORMAT_AMR_SUB_NONE            = 0x0,
+} audio_format_amr_sub_fmt_t;
+
+/* AAC sub format field definition: specify profile or bitrate for recording... */
+typedef enum {
+    AUDIO_FORMAT_AAC_SUB_NONE            = 0x0,
+} audio_format_aac_sub_fmt_t;
+
+/* VORBIS sub format field definition: specify quality for recording... */
+typedef enum {
+    AUDIO_FORMAT_VORBIS_SUB_NONE         = 0x0,
+} audio_format_vorbis_sub_fmt_t;
+
+/* Audio format consists in a main format field (upper 8 bits) and a sub format
+ * field (lower 24 bits).
+ *
+ * The main format indicates the main codec type. The sub format field
+ * indicates options and parameters for each format. The sub format is mainly
+ * used for record to indicate for instance the requested bitrate or profile.
+ * It can also be used for certain formats to give informations not present in
+ * the encoded audio stream (e.g. octet alignement for AMR).
+ */
+typedef enum {
+    AUDIO_FORMAT_INVALID             = 0xFFFFFFFFUL,
+    AUDIO_FORMAT_DEFAULT             = 0,
+    AUDIO_FORMAT_PCM                 = 0x00000000UL, /* DO NOT CHANGE */
+    AUDIO_FORMAT_MP3                 = 0x01000000UL,
+    AUDIO_FORMAT_AMR_NB              = 0x02000000UL,
+    AUDIO_FORMAT_AMR_WB              = 0x03000000UL,
+    AUDIO_FORMAT_AAC                 = 0x04000000UL,
+    AUDIO_FORMAT_HE_AAC_V1           = 0x05000000UL,
+    AUDIO_FORMAT_HE_AAC_V2           = 0x06000000UL,
+    AUDIO_FORMAT_VORBIS              = 0x07000000UL,
+    AUDIO_FORMAT_MAIN_MASK           = 0xFF000000UL,
+    AUDIO_FORMAT_SUB_MASK            = 0x00FFFFFFUL,
+
+    /* Aliases */
+    AUDIO_FORMAT_PCM_16_BIT          = (AUDIO_FORMAT_PCM |
+                                        AUDIO_FORMAT_PCM_SUB_16_BIT),
+    AUDIO_FORMAT_PCM_8_BIT           = (AUDIO_FORMAT_PCM |
+                                        AUDIO_FORMAT_PCM_SUB_8_BIT),
+} audio_format_t;
+
+/* Channel mask definitions must be kept in sync with JAVA values in
+ * frameworks/base/media/java/android/media/AudioFormat.java */
+typedef enum {
+    /* output channels */
+    AUDIO_CHANNEL_OUT_FRONT_LEFT            = 0x4,
+    AUDIO_CHANNEL_OUT_FRONT_RIGHT           = 0x8,
+    AUDIO_CHANNEL_OUT_FRONT_CENTER          = 0x10,
+    AUDIO_CHANNEL_OUT_LOW_FREQUENCY         = 0x20,
+    AUDIO_CHANNEL_OUT_BACK_LEFT             = 0x40,
+    AUDIO_CHANNEL_OUT_BACK_RIGHT            = 0x80,
+    AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER  = 0x100,
+    AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER = 0x200,
+    AUDIO_CHANNEL_OUT_BACK_CENTER           = 0x400,
+
+    AUDIO_CHANNEL_OUT_MONO     = AUDIO_CHANNEL_OUT_FRONT_LEFT,
+    AUDIO_CHANNEL_OUT_STEREO   = (AUDIO_CHANNEL_OUT_FRONT_LEFT |
+                                  AUDIO_CHANNEL_OUT_FRONT_RIGHT),
+    AUDIO_CHANNEL_OUT_QUAD     = (AUDIO_CHANNEL_OUT_FRONT_LEFT |
+                                  AUDIO_CHANNEL_OUT_FRONT_RIGHT |
+                                  AUDIO_CHANNEL_OUT_BACK_LEFT |
+                                  AUDIO_CHANNEL_OUT_BACK_RIGHT),
+    AUDIO_CHANNEL_OUT_SURROUND = (AUDIO_CHANNEL_OUT_FRONT_LEFT |
+                                  AUDIO_CHANNEL_OUT_FRONT_RIGHT |
+                                  AUDIO_CHANNEL_OUT_FRONT_CENTER |
+                                  AUDIO_CHANNEL_OUT_BACK_CENTER),
+    AUDIO_CHANNEL_OUT_5POINT1  = (AUDIO_CHANNEL_OUT_FRONT_LEFT |
+                                  AUDIO_CHANNEL_OUT_FRONT_RIGHT |
+                                  AUDIO_CHANNEL_OUT_FRONT_CENTER |
+                                  AUDIO_CHANNEL_OUT_LOW_FREQUENCY |
+                                  AUDIO_CHANNEL_OUT_BACK_LEFT |
+                                  AUDIO_CHANNEL_OUT_BACK_RIGHT),
+    AUDIO_CHANNEL_OUT_7POINT1  = (AUDIO_CHANNEL_OUT_FRONT_LEFT |
+                                  AUDIO_CHANNEL_OUT_FRONT_RIGHT |
+                                  AUDIO_CHANNEL_OUT_FRONT_CENTER |
+                                  AUDIO_CHANNEL_OUT_LOW_FREQUENCY |
+                                  AUDIO_CHANNEL_OUT_BACK_LEFT |
+                                  AUDIO_CHANNEL_OUT_BACK_RIGHT |
+                                  AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER |
+                                  AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER),
+    AUDIO_CHANNEL_OUT_ALL      = (AUDIO_CHANNEL_OUT_FRONT_LEFT |
+                                  AUDIO_CHANNEL_OUT_FRONT_RIGHT |
+                                  AUDIO_CHANNEL_OUT_FRONT_CENTER |
+                                  AUDIO_CHANNEL_OUT_LOW_FREQUENCY |
+                                  AUDIO_CHANNEL_OUT_BACK_LEFT |
+                                  AUDIO_CHANNEL_OUT_BACK_RIGHT |
+                                  AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER |
+                                  AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER |
+                                  AUDIO_CHANNEL_OUT_BACK_CENTER),
+
+    /* input channels */
+    AUDIO_CHANNEL_IN_LEFT            = 0x4,
+    AUDIO_CHANNEL_IN_RIGHT           = 0x8,
+    AUDIO_CHANNEL_IN_FRONT           = 0x10,
+    AUDIO_CHANNEL_IN_BACK            = 0x20,
+    AUDIO_CHANNEL_IN_LEFT_PROCESSED  = 0x40,
+    AUDIO_CHANNEL_IN_RIGHT_PROCESSED = 0x80,
+    AUDIO_CHANNEL_IN_FRONT_PROCESSED = 0x100,
+    AUDIO_CHANNEL_IN_BACK_PROCESSED  = 0x200,
+    AUDIO_CHANNEL_IN_PRESSURE        = 0x400,
+    AUDIO_CHANNEL_IN_X_AXIS          = 0x800,
+    AUDIO_CHANNEL_IN_Y_AXIS          = 0x1000,
+    AUDIO_CHANNEL_IN_Z_AXIS          = 0x2000,
+    AUDIO_CHANNEL_IN_VOICE_UPLINK    = 0x4000,
+    AUDIO_CHANNEL_IN_VOICE_DNLINK    = 0x8000,
+
+    AUDIO_CHANNEL_IN_MONO   = AUDIO_CHANNEL_IN_FRONT,
+    AUDIO_CHANNEL_IN_STEREO = (AUDIO_CHANNEL_IN_LEFT | AUDIO_CHANNEL_IN_RIGHT),
+    AUDIO_CHANNEL_IN_ALL    = (AUDIO_CHANNEL_IN_LEFT |
+                               AUDIO_CHANNEL_IN_RIGHT |
+                               AUDIO_CHANNEL_IN_FRONT |
+                               AUDIO_CHANNEL_IN_BACK|
+                               AUDIO_CHANNEL_IN_LEFT_PROCESSED |
+                               AUDIO_CHANNEL_IN_RIGHT_PROCESSED |
+                               AUDIO_CHANNEL_IN_FRONT_PROCESSED |
+                               AUDIO_CHANNEL_IN_BACK_PROCESSED|
+                               AUDIO_CHANNEL_IN_PRESSURE |
+                               AUDIO_CHANNEL_IN_X_AXIS |
+                               AUDIO_CHANNEL_IN_Y_AXIS |
+                               AUDIO_CHANNEL_IN_Z_AXIS |
+                               AUDIO_CHANNEL_IN_VOICE_UPLINK |
+                               AUDIO_CHANNEL_IN_VOICE_DNLINK),
+} audio_channels_t;
+
+typedef enum {
+    AUDIO_MODE_INVALID          = -2,
+    AUDIO_MODE_CURRENT          = -1,
+    AUDIO_MODE_NORMAL           = 0,
+    AUDIO_MODE_RINGTONE         = 1,
+    AUDIO_MODE_IN_CALL          = 2,
+    AUDIO_MODE_IN_COMMUNICATION = 3,
+
+    AUDIO_MODE_CNT,
+    AUDIO_MODE_MAX              = AUDIO_MODE_CNT - 1,
+} audio_mode_t;
+
+typedef enum {
+    AUDIO_IN_ACOUSTICS_AGC_ENABLE    = 0x0001,
+    AUDIO_IN_ACOUSTICS_AGC_DISABLE   = 0,
+    AUDIO_IN_ACOUSTICS_NS_ENABLE     = 0x0002,
+    AUDIO_IN_ACOUSTICS_NS_DISABLE    = 0,
+    AUDIO_IN_ACOUSTICS_TX_IIR_ENABLE = 0x0004,
+    AUDIO_IN_ACOUSTICS_TX_DISABLE    = 0,
+} audio_in_acoustics_t;
+
+typedef enum {
+    /* output devices */
+    AUDIO_DEVICE_OUT_EARPIECE                  = 0x1,
+    AUDIO_DEVICE_OUT_SPEAKER                   = 0x2,
+    AUDIO_DEVICE_OUT_WIRED_HEADSET             = 0x4,
+    AUDIO_DEVICE_OUT_WIRED_HEADPHONE           = 0x8,
+    AUDIO_DEVICE_OUT_BLUETOOTH_SCO             = 0x10,
+    AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET     = 0x20,
+    AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT      = 0x40,
+    AUDIO_DEVICE_OUT_BLUETOOTH_A2DP            = 0x80,
+    AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100,
+    AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER    = 0x200,
+    AUDIO_DEVICE_OUT_AUX_DIGITAL               = 0x400,
+    AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET         = 0x800,
+    AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET         = 0x1000,
+    AUDIO_DEVICE_OUT_DEFAULT                   = 0x8000,
+    AUDIO_DEVICE_OUT_ALL      = (AUDIO_DEVICE_OUT_EARPIECE |
+                                 AUDIO_DEVICE_OUT_SPEAKER |
+                                 AUDIO_DEVICE_OUT_WIRED_HEADSET |
+                                 AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
+                                 AUDIO_DEVICE_OUT_BLUETOOTH_SCO |
+                                 AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET |
+                                 AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT |
+                                 AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
+                                 AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
+                                 AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER |
+                                 AUDIO_DEVICE_OUT_AUX_DIGITAL |
+                                 AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET |
+                                 AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET |
+                                 AUDIO_DEVICE_OUT_DEFAULT),
+    AUDIO_DEVICE_OUT_ALL_A2DP = (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
+                                 AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
+                                 AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER),
+    AUDIO_DEVICE_OUT_ALL_SCO  = (AUDIO_DEVICE_OUT_BLUETOOTH_SCO |
+                                 AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET |
+                                 AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT),
+
+    /* input devices */
+    AUDIO_DEVICE_IN_COMMUNICATION         = 0x10000,
+    AUDIO_DEVICE_IN_AMBIENT               = 0x20000,
+    AUDIO_DEVICE_IN_BUILTIN_MIC           = 0x40000,
+    AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET = 0x80000,
+    AUDIO_DEVICE_IN_WIRED_HEADSET         = 0x100000,
+    AUDIO_DEVICE_IN_AUX_DIGITAL           = 0x200000,
+    AUDIO_DEVICE_IN_VOICE_CALL            = 0x400000,
+    AUDIO_DEVICE_IN_BACK_MIC              = 0x800000,
+    AUDIO_DEVICE_IN_DEFAULT               = 0x80000000,
+
+    AUDIO_DEVICE_IN_ALL     = (AUDIO_DEVICE_IN_COMMUNICATION |
+                               AUDIO_DEVICE_IN_AMBIENT |
+                               AUDIO_DEVICE_IN_BUILTIN_MIC |
+                               AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET |
+                               AUDIO_DEVICE_IN_WIRED_HEADSET |
+                               AUDIO_DEVICE_IN_AUX_DIGITAL |
+                               AUDIO_DEVICE_IN_VOICE_CALL |
+                               AUDIO_DEVICE_IN_BACK_MIC |
+                               AUDIO_DEVICE_IN_DEFAULT),
+    AUDIO_DEVICE_IN_ALL_SCO = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
+} audio_devices_t;
+
+static inline bool audio_is_output_device(audio_devices_t device)
+{
+    if ((popcount(device) == 1) && ((device & ~AUDIO_DEVICE_OUT_ALL) == 0))
+        return true;
+    else
+        return false;
+}
+
+static inline bool audio_is_input_device(audio_devices_t device)
+{
+    if ((popcount(device) == 1) && ((device & ~AUDIO_DEVICE_IN_ALL) == 0))
+        return true;
+    else
+        return false;
+}
+
+static inline bool audio_is_a2dp_device(audio_devices_t device)
+{
+    if ((popcount(device) == 1) && (device & AUDIO_DEVICE_OUT_ALL_A2DP))
+        return true;
+    else
+        return false;
+}
+
+static inline bool audio_is_bluetooth_sco_device(audio_devices_t device)
+{
+    if ((popcount(device) == 1) && (device & (AUDIO_DEVICE_OUT_ALL_SCO |
+                   AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET)))
+        return true;
+    else
+        return false;
+}
+
+static inline bool audio_is_input_channel(uint32_t channel)
+{
+    if ((channel & ~AUDIO_CHANNEL_IN_ALL) == 0)
+        return true;
+    else
+        return false;
+}
+
+static inline bool audio_is_output_channel(uint32_t channel)
+{
+    if ((channel & ~AUDIO_CHANNEL_OUT_ALL) == 0)
+        return true;
+    else
+        return false;
+}
+
+static inline bool audio_is_valid_format(uint32_t format)
+{
+    switch (format & AUDIO_FORMAT_MAIN_MASK) {
+    case AUDIO_FORMAT_PCM:
+    case AUDIO_FORMAT_MP3:
+    case AUDIO_FORMAT_AMR_NB:
+    case AUDIO_FORMAT_AMR_WB:
+    case AUDIO_FORMAT_AAC:
+    case AUDIO_FORMAT_HE_AAC_V1:
+    case AUDIO_FORMAT_HE_AAC_V2:
+    case AUDIO_FORMAT_VORBIS:
+        return true;
+    default:
+        return false;
+    }
+}
+
+static inline bool audio_is_linear_pcm(uint32_t format)
+{
+    switch (format) {
+    case AUDIO_FORMAT_PCM_16_BIT:
+    case AUDIO_FORMAT_PCM_8_BIT:
+        return true;
+    default:
+        return false;
+    }
+}
+
+
+__END_DECLS
+
+#endif  // ANDROID_AUDIO_CORE_H
diff --git a/include/system/graphics.h b/include/system/graphics.h
index fab6ec9..d39bd4e 100644
--- a/include/system/graphics.h
+++ b/include/system/graphics.h
@@ -48,12 +48,11 @@
     /*
      * Android YUV format:
      *
-     * This format is exposed outside of the HAL to software
-     * decoders and applications.
-     * EGLImageKHR must support it in conjunction with the
+     * This format is exposed outside of the HAL to software decoders and
+     * applications.  EGLImageKHR must support it in conjunction with the
      * OES_EGL_image_external extension.
      *
-     * YV12 is 4:2:0 YCrCb planar format comprised of a WxH Y plane followed
+     * YV12 is a 4:2:0 YCrCb planar format comprised of a WxH Y plane followed
      * by (W/2) x (H/2) Cr and Cb planes.
      *
      * This format assumes
diff --git a/include/system/window.h b/include/system/window.h
index 4b0381b..5762a50 100644
--- a/include/system/window.h
+++ b/include/system/window.h
@@ -454,4 +454,4 @@
 
 __END_DECLS
 
-#endif SYSTEM_CORE_INCLUDE_ANDROID_WINDOW_H
+#endif /* SYSTEM_CORE_INCLUDE_ANDROID_WINDOW_H */
diff --git a/libnetutils/ifc_utils.c b/libnetutils/ifc_utils.c
index 92b9681..208402c 100644
--- a/libnetutils/ifc_utils.c
+++ b/libnetutils/ifc_utils.c
@@ -51,6 +51,8 @@
 static int ifc_ctl_sock6 = -1;
 void printerr(char *fmt, ...);
 
+#define DBG 0
+
 in_addr_t prefixLengthToIpv4Netmask(int prefix_length)
 {
     in_addr_t mask = 0;
@@ -88,13 +90,17 @@
 
 int ifc_init(void)
 {
+    int ret;
     if (ifc_ctl_sock == -1) {
-        ifc_ctl_sock = socket(AF_INET, SOCK_DGRAM, 0);    
+        ifc_ctl_sock = socket(AF_INET, SOCK_DGRAM, 0);
         if (ifc_ctl_sock < 0) {
             printerr("socket() failed: %s\n", strerror(errno));
         }
     }
-    return ifc_ctl_sock < 0 ? -1 : 0;
+
+    ret = ifc_ctl_sock < 0 ? -1 : 0;
+    if (DBG) printerr("ifc_init_returning %d", ret);
+    return ret;
 }
 
 int ifc_init6(void)
@@ -110,6 +116,7 @@
 
 void ifc_close(void)
 {
+    if (DBG) printerr("ifc_close");
     if (ifc_ctl_sock != -1) {
         (void)close(ifc_ctl_sock);
         ifc_ctl_sock = -1;
@@ -141,7 +148,7 @@
     if(r < 0) return -1;
 
     memcpy(ptr, &ifr.ifr_hwaddr.sa_data, ETH_ALEN);
-    return 0;    
+    return 0;
 }
 
 int ifc_get_ifindex(const char *name, int *if_indexp)
@@ -169,12 +176,16 @@
 
 int ifc_up(const char *name)
 {
-    return ifc_set_flags(name, IFF_UP, 0);
+    int ret = ifc_set_flags(name, IFF_UP, 0);
+    if (DBG) printerr("ifc_up(%s) = %d", name, ret);
+    return ret;
 }
 
 int ifc_down(const char *name)
 {
-    return ifc_set_flags(name, 0, IFF_UP);
+    int ret = ifc_set_flags(name, 0, IFF_UP);
+    if (DBG) printerr("ifc_down(%s) = %d", name, ret);
+    return ret;
 }
 
 static void init_sockaddr_in(struct sockaddr *sa, in_addr_t addr)
@@ -188,11 +199,14 @@
 int ifc_set_addr(const char *name, in_addr_t addr)
 {
     struct ifreq ifr;
+    int ret;
 
     ifc_init_ifr(name, &ifr);
     init_sockaddr_in(&ifr.ifr_addr, addr);
 
-    return ioctl(ifc_ctl_sock, SIOCSIFADDR, &ifr);
+    ret = ioctl(ifc_ctl_sock, SIOCSIFADDR, &ifr);
+    if (DBG) printerr("ifc_set_addr(%s, xx) = %d", name, ret);
+    return ret;
 }
 
 int ifc_set_hwaddr(const char *name, const void *ptr)
@@ -209,11 +223,14 @@
 int ifc_set_mask(const char *name, in_addr_t mask)
 {
     struct ifreq ifr;
+    int ret;
 
     ifc_init_ifr(name, &ifr);
     init_sockaddr_in(&ifr.ifr_addr, mask);
 
-    return ioctl(ifc_ctl_sock, SIOCSIFNETMASK, &ifr);
+    ret = ioctl(ifc_ctl_sock, SIOCSIFNETMASK, &ifr);
+    if (DBG) printerr("ifc_set_mask(%s, xx) = %d", name, ret);
+    return ret;
 }
 
 int ifc_set_prefixLength(const char *name, int prefixLength)
@@ -279,7 +296,7 @@
     return 0;
 }
 
-int ifc_add_ipv4_route(const char *ifname, struct in_addr dst, int prefix_length,
+int ifc_act_on_ipv4_route(int action, const char *ifname, struct in_addr dst, int prefix_length,
       struct in_addr gw)
 {
     struct rtentry rt;
@@ -311,7 +328,7 @@
         return -errno;
     }
 
-    result = ioctl(ifc_ctl_sock, SIOCADDRT, &rt);
+    result = ioctl(ifc_ctl_sock, action, &rt);
     if (result < 0) {
         if (errno == EEXIST) {
             result = 0;
@@ -323,6 +340,7 @@
     return result;
 }
 
+/* deprecated - v4 only */
 int ifc_create_default_route(const char *name, in_addr_t gw)
 {
     struct in_addr in_dst, in_gw;
@@ -330,9 +348,12 @@
     in_dst.s_addr = 0;
     in_gw.s_addr = gw;
 
-    return ifc_add_ipv4_route(name, in_dst, 0, in_gw);
+    int ret = ifc_act_on_ipv4_route(SIOCADDRT, name, in_dst, 0, in_gw);
+    if (DBG) printerr("ifc_create_default_route(%s, %d) = %d", name, gw, ret);
+    return ret;
 }
 
+/* deprecated v4-only */
 int ifc_add_host_route(const char *name, in_addr_t dst)
 {
     struct in_addr in_dst, in_gw;
@@ -340,7 +361,7 @@
     in_dst.s_addr = dst;
     in_gw.s_addr = 0;
 
-    return ifc_add_ipv4_route(name, in_dst, 32, in_gw);
+    return ifc_act_on_ipv4_route(SIOCADDRT, name, in_dst, 32, in_gw);
 }
 
 int ifc_enable(const char *ifname)
@@ -463,6 +484,8 @@
  *
  * TODO: factor out common code from this and remove_host_routes()
  * so that we only scan /proc/net/route in one place.
+ *
+ * DEPRECATED
  */
 int ifc_get_default_route(const char *ifname)
 {
@@ -503,6 +526,7 @@
 
 /*
  * Sets the specified gateway as the default route for the named interface.
+ * DEPRECATED
  */
 int ifc_set_default_route(const char *ifname, in_addr_t gateway)
 {
@@ -582,7 +606,7 @@
     return 0;
 }
 
-int ifc_add_ipv6_route(const char *ifname, struct in6_addr dst, int prefix_length,
+int ifc_act_on_ipv6_route(int action, const char *ifname, struct in6_addr dst, int prefix_length,
       struct in6_addr gw)
 {
     struct in6_rtmsg rtmsg;
@@ -617,7 +641,7 @@
         return -errno;
     }
 
-    result = ioctl(ifc_ctl_sock6, SIOCADDRT, &rtmsg);
+    result = ioctl(ifc_ctl_sock6, action, &rtmsg);
     if (result < 0) {
         if (errno == EEXIST) {
             result = 0;
@@ -629,8 +653,8 @@
     return result;
 }
 
-int ifc_add_route(const char *ifname, const char *dst, int prefix_length,
-      const char *gw)
+int ifc_act_on_route(int action, const char *ifname, const char *dst, int prefix_length,
+        const char *gw)
 {
     int ret = 0;
     struct sockaddr_in ipv4_dst, ipv4_gw;
@@ -648,7 +672,7 @@
         return -EINVAL;
     }
 
-    if (gw == NULL) {
+    if (gw == NULL || (strlen(gw) == 0)) {
         if (addr_ai->ai_family == AF_INET6) {
             gw = "::";
         } else if (addr_ai->ai_family == AF_INET) {
@@ -656,6 +680,13 @@
         }
     }
 
+    if (((addr_ai->ai_family == AF_INET6) && (prefix_length < 0 || prefix_length > 128)) ||
+            ((addr_ai->ai_family == AF_INET) && (prefix_length < 0 || prefix_length > 32))) {
+        printerr("ifc_add_route: invalid prefix length");
+        freeaddrinfo(addr_ai);
+        return -EINVAL;
+    }
+
     ret = getaddrinfo(gw, NULL, &hints, &gw_ai);
     if (ret != 0) {
         printerr("getaddrinfo failed: invalid gateway %s\n", gw);
@@ -673,13 +704,13 @@
     if (addr_ai->ai_family == AF_INET6) {
         memcpy(&ipv6_dst, addr_ai->ai_addr, sizeof(struct sockaddr_in6));
         memcpy(&ipv6_gw, gw_ai->ai_addr, sizeof(struct sockaddr_in6));
-        ret = ifc_add_ipv6_route(ifname, ipv6_dst.sin6_addr, prefix_length,
-              ipv6_gw.sin6_addr);
+        ret = ifc_act_on_ipv6_route(action, ifname, ipv6_dst.sin6_addr,
+                prefix_length, ipv6_gw.sin6_addr);
     } else if (addr_ai->ai_family == AF_INET) {
         memcpy(&ipv4_dst, addr_ai->ai_addr, sizeof(struct sockaddr_in));
         memcpy(&ipv4_gw, gw_ai->ai_addr, sizeof(struct sockaddr_in));
-        ret = ifc_add_ipv4_route(ifname, ipv4_dst.sin_addr, prefix_length,
-              ipv4_gw.sin_addr);
+        ret = ifc_act_on_ipv4_route(action, ifname, ipv4_dst.sin_addr,
+                prefix_length, ipv4_gw.sin_addr);
     } else {
         printerr("ifc_add_route: getaddrinfo returned un supported address family %d\n",
                   addr_ai->ai_family);
@@ -690,3 +721,35 @@
     freeaddrinfo(gw_ai);
     return ret;
 }
+
+/*
+ * DEPRECATED
+ */
+int ifc_add_ipv4_route(const char *ifname, struct in_addr dst, int prefix_length,
+      struct in_addr gw)
+{
+    int i =ifc_act_on_ipv4_route(SIOCADDRT, ifname, dst, prefix_length, gw);
+    printerr("ifc_add_ipv4_route(%s, xx, %d, xx) = %d", ifname, prefix_length, i);
+    return i;
+}
+
+/*
+ * DEPRECATED
+ */
+int ifc_add_ipv6_route(const char *ifname, struct in6_addr dst, int prefix_length,
+      struct in6_addr gw)
+{
+    return ifc_act_on_ipv6_route(SIOCADDRT, ifname, dst, prefix_length, gw);
+}
+
+int ifc_add_route(const char *ifname, const char *dst, int prefix_length, const char *gw)
+{
+    int i = ifc_act_on_route(SIOCADDRT, ifname, dst, prefix_length, gw);
+    printerr("ifc_add_route(%s, %s, %d, %s) = %d", ifname, dst, prefix_length, gw, i);
+    return i;
+}
+
+int ifc_remove_route(const char *ifname, const char*dst, int prefix_length, const char *gw)
+{
+    return ifc_act_on_route(SIOCDELRT, ifname, dst, prefix_length, gw);
+}
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 657797e..54873e0 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -150,6 +150,7 @@
     mkdir /data/misc/bluetoothd 0770 bluetooth bluetooth
     mkdir /data/misc/bluetooth 0770 system system
     mkdir /data/misc/keystore 0700 keystore keystore
+    mkdir /data/misc/keychain 0771 keychain keychain
     mkdir /data/misc/vpn 0770 system system
     mkdir /data/misc/systemkeys 0700 system system
     mkdir /data/misc/vpn/profiles 0770 system system
diff --git a/rootdir/ueventd.rc b/rootdir/ueventd.rc
index 51a4337..438cf0a 100644
--- a/rootdir/ueventd.rc
+++ b/rootdir/ueventd.rc
@@ -70,11 +70,11 @@
 /dev/bus/usb/*            0660   root       usb
 /dev/mtp_usb              0660   root       mtp
 /dev/usb_accessory        0660   root       usb
+/dev/tun                  0660   system     vpn
 
 # CDMA radio interface MUX
 /dev/ts0710mux*           0640   radio      radio
 /dev/ppp                  0660   radio      vpn
-/dev/tun                  0640   vpn        vpn
 
 # sysfs properties
 /sys/devices/virtual/input/input*   enable      0660  root   input