Merge change 2329

* changes:
  Fix bug where ECONNABORTED would have always occured on asocket_write.
diff --git a/adb/Android.mk b/adb/Android.mk
index 6cbaf82..9725478 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -53,6 +53,7 @@
 	$(USB_SRCS) \
 	shlist.c \
 	utils.c \
+	usb_vendors.c \
 
 
 ifneq ($(USE_SYSDEPS_WIN32),)
diff --git a/adb/adb.c b/adb/adb.c
index 12a36f5..0b5ebac 100644
--- a/adb/adb.c
+++ b/adb/adb.c
@@ -29,6 +29,8 @@
 
 #if !ADB_HOST
 #include <private/android_filesystem_config.h>
+#else
+#include "usb_vendors.h"
 #endif
 
 
@@ -818,19 +820,6 @@
 #if !ADB_HOST
     int secure = 0;
     char value[PROPERTY_VALUE_MAX];
-
-    // prevent the OOM killer from killing us
-    char text[64];
-    snprintf(text, sizeof text, "/proc/%d/oom_adj", (int)getpid());
-    int fd = adb_open(text, O_WRONLY);
-    if (fd >= 0) {
-        // -17 should make us immune to OOM
-        snprintf(text, sizeof text, "%d", -17);
-        adb_write(fd, text, strlen(text));
-        adb_close(fd);
-    } else {
-       D("adb: unable to open %s\n", text);
-    }
 #endif
 
     atexit(adb_cleanup);
@@ -846,6 +835,7 @@
 
 #if ADB_HOST
     HOST = 1;
+    usb_vendors_init();
     usb_init();
     local_init();
 
@@ -929,6 +919,9 @@
     fdevent_loop();
 
     usb_cleanup();
+#if ADB_HOST
+    usb_vendors_cleanup();
+#endif
 
     return 0;
 }
diff --git a/adb/adb.h b/adb/adb.h
index aebb81a..7762e00 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -375,7 +375,9 @@
 void usb_kick(usb_handle *h);
 
 /* used for USB device detection */
+#if ADB_HOST
 int is_adb_interface(int vid, int pid, int usb_class, int usb_subclass, int usb_protocol);
+#endif
 
 unsigned host_to_le32(unsigned n);
 int adb_commandline(int argc, char **argv);
diff --git a/adb/services.c b/adb/services.c
index 1de55e6..0a5edcf 100644
--- a/adb/services.c
+++ b/adb/services.c
@@ -244,6 +244,18 @@
                 cmd, strerror(errno), errno);
         exit(-1);
     } else {
+#if !ADB_HOST
+        // set child's OOM adjustment to zero
+        char text[64];
+        snprintf(text, sizeof text, "/proc/%d/oom_adj", pid);
+        int fd = adb_open(text, O_WRONLY);
+        if (fd >= 0) {
+            adb_write(fd, "0", 1);
+            adb_close(fd);
+        } else {
+           D("adb: unable to open %s\n", text);
+        }
+#endif
         return ptm;
     }
 #endif /* !HAVE_WIN32_PROC */
diff --git a/adb/transport_usb.c b/adb/transport_usb.c
index 01c4a7e..50ebff7 100644
--- a/adb/transport_usb.c
+++ b/adb/transport_usb.c
@@ -23,6 +23,10 @@
 #define  TRACE_TAG  TRACE_TRANSPORT
 #include "adb.h"
 
+#if ADB_HOST
+#include "usb_vendors.h"
+#endif
+
 /* XXX better define? */
 #ifdef __ppc__
 #define H4(x)	(((x) & 0xFF000000) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | (((x) & 0x000000FF) << 24)
@@ -125,23 +129,23 @@
 #endif
 }
 
+#if ADB_HOST
 int is_adb_interface(int vid, int pid, int usb_class, int usb_subclass, int usb_protocol)
 {
-    if (vid == VENDOR_ID_GOOGLE) {
-            /* might support adb */
-    } else if (vid == VENDOR_ID_HTC) {
-            /* might support adb */
-    } else {
-            /* not supported */
-        return 0;
-    }
+    unsigned i;
+    for (i = 0; i < vendorIdCount; i++) {
+        if (vid == vendorIds[i]) {
+            /* class:vendor (0xff) subclass:android (0x42) proto:adb (0x01) */
+            if(usb_class == 0xff) {
+                if((usb_subclass == 0x42) && (usb_protocol == 0x01)) {
+                    return 1;
+                }
+            }
 
-        /* class:vendor (0xff) subclass:android (0x42) proto:adb (0x01) */
-    if(usb_class == 0xff) {
-        if((usb_subclass == 0x42) && (usb_protocol == 0x01)) {
-            return 1;
+            return 0;
         }
     }
 
     return 0;
 }
+#endif
diff --git a/adb/usb_osx.c b/adb/usb_osx.c
index 2d4c1a9..171a9fc 100644
--- a/adb/usb_osx.c
+++ b/adb/usb_osx.c
@@ -28,20 +28,15 @@
 
 #define TRACE_TAG   TRACE_USB
 #include "adb.h"
+#include "usb_vendors.h"
 
 #define  DBG   D
 
 #define ADB_SUBCLASS           0x42
 #define ADB_PROTOCOL           0x1
 
-int vendorIds[] = {
-    VENDOR_ID_GOOGLE,
-    VENDOR_ID_HTC,
-};
-#define NUM_VENDORS             (sizeof(vendorIds)/sizeof(vendorIds[0]))
-
 static IONotificationPortRef    notificationPort = 0;
-static io_iterator_t            notificationIterators[NUM_VENDORS];
+static io_iterator_t*           notificationIterators;
 
 struct usb_handle
 {
@@ -81,7 +76,7 @@
     memset(notificationIterators, 0, sizeof(notificationIterators));
 
     //* loop through all supported vendors
-    for (i = 0; i < NUM_VENDORS; i++) {
+    for (i = 0; i < vendorIdCount; i++) {
         //* Create our matching dictionary to find the Android device's
         //* adb interface
         //* IOServiceAddMatchingNotification consumes the reference, so we do
@@ -374,7 +369,7 @@
     CFRunLoopRun();
     currentRunLoop = 0;
 
-    for (i = 0; i < NUM_VENDORS; i++) {
+    for (i = 0; i < vendorIdCount; i++) {
         IOObjectRelease(notificationIterators[i]);
     }
     IONotificationPortDestroy(notificationPort);
@@ -391,6 +386,9 @@
     {
         adb_thread_t    tid;
 
+        notificationIterators = (io_iterator_t*)malloc(
+            vendorIdCount * sizeof(io_iterator_t));
+
         adb_mutex_init(&start_lock, NULL);
         adb_cond_init(&start_cond, NULL);
 
@@ -415,6 +413,11 @@
     close_usb_devices();
     if (currentRunLoop)
         CFRunLoopStop(currentRunLoop);
+
+    if (notificationIterators != NULL) {
+        free(notificationIterators);
+        notificationIterators = NULL;
+    }
 }
 
 int usb_write(usb_handle *handle, const void *buf, int len)
diff --git a/adb/usb_vendors.c b/adb/usb_vendors.c
new file mode 100644
index 0000000..f949249
--- /dev/null
+++ b/adb/usb_vendors.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2009 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 "usb_vendors.h"
+
+#include "sysdeps.h"
+#include <stdio.h>
+#include "adb.h"
+
+int* vendorIds = NULL;
+unsigned vendorIdCount = 0;
+
+void usb_vendors_init(void) {
+    /* for now, only put the built-in VENDOR_ID_* */
+    vendorIdCount = 2;
+    vendorIds = (int*)malloc(vendorIdCount * sizeof(int));
+    vendorIds[0] = VENDOR_ID_GOOGLE;
+    vendorIds[1] = VENDOR_ID_HTC;
+}
+
+void usb_vendors_cleanup(void) {
+    if (vendorIds != NULL) {
+        free(vendorIds);
+        vendorIds = NULL;
+        vendorIdCount = 0;
+    }
+}
diff --git a/adb/usb_vendors.h b/adb/usb_vendors.h
new file mode 100644
index 0000000..43e5f99
--- /dev/null
+++ b/adb/usb_vendors.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2009 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 __USB_VENDORS_H
+#define __USB_VENDORS_H
+
+extern int* vendorIds;
+extern unsigned  vendorIdCount;
+
+void usb_vendors_init(void);
+void usb_vendors_cleanup(void);
+
+#endif
\ No newline at end of file
diff --git a/include/cutils/native_handle.h b/include/cutils/native_handle.h
index 2b64893..89d6b65 100644
--- a/include/cutils/native_handle.h
+++ b/include/cutils/native_handle.h
@@ -17,12 +17,57 @@
 #ifndef NATIVE_HANDLE_H_
 #define NATIVE_HANDLE_H_
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 typedef struct
 {
-    int version;        /* sizeof(native_handle) */
+    int version;        /* sizeof(native_handle_t) */
     int numFds;         /* number of file-descriptors at &data[0] */
     int numInts;        /* number of ints at &data[numFds] */
     int data[0];        /* numFds + numInts ints */
-} native_handle;
+} native_handle_t;
+
+
+/* keep the old definition for backward source-compatibility */
+typedef native_handle_t native_handle;
+
+/*
+ * native_handle_close
+ * 
+ * closes the file descriptors contained in this native_handle_t
+ * 
+ * return 0 on success, or a negative error code on failure
+ * 
+ */
+int native_handle_close(const native_handle_t* h);
+
+
+/*
+ * native_handle_create
+ * 
+ * creates a native_handle_t and initializes it. must be destroyed with
+ * native_handle_delete().
+ * 
+ */
+native_handle_t* native_handle_create(int numFds, int numInts);
+
+/*
+ * native_handle_delete
+ * 
+ * frees a native_handle_t allocated with native_handle_create().
+ * This ONLY frees the memory allocated for the native_handle_t, but doesn't
+ * close the file descriptors; which can be achieved with native_handle_close().
+ * 
+ * return 0 on success, or a negative error code on failure
+ * 
+ */
+int native_handle_delete(native_handle_t* h);
+
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* NATIVE_HANDLE_H_ */
diff --git a/include/sysutils/FrameworkClient.h b/include/sysutils/FrameworkClient.h
index 1eb112a..0ef0753 100644
--- a/include/sysutils/FrameworkClient.h
+++ b/include/sysutils/FrameworkClient.h
@@ -13,8 +13,8 @@
     FrameworkClient(int sock);
     virtual ~FrameworkClient() {}
 
-    int sendMsg(char *msg);
-    int sendMsg(char *msg, char *data);
+    int sendMsg(const char *msg);
+    int sendMsg(const char *msg, const char *data);
 };
 
 typedef android::List<FrameworkClient *> FrameworkClientCollection;
diff --git a/include/sysutils/SocketClient.h b/include/sysutils/SocketClient.h
index cde64a5..469dd9d 100644
--- a/include/sysutils/SocketClient.h
+++ b/include/sysutils/SocketClient.h
@@ -15,8 +15,8 @@
 
     int getSocket() { return mSocket; }
 
-    int sendMsg(int code, char *msg, bool addErrno);
-    int sendMsg(char *msg);
+    int sendMsg(int code, const char *msg, bool addErrno);
+    int sendMsg(const char *msg);
 };
 
 typedef android::List<SocketClient *> SocketClientCollection;
diff --git a/include/sysutils/SocketListener.h b/include/sysutils/SocketListener.h
index 30d050d..68dcb8f 100644
--- a/include/sysutils/SocketListener.h
+++ b/include/sysutils/SocketListener.h
@@ -37,8 +37,8 @@
     int startListener();
     int stopListener();
 
-    void sendBroadcast(int code, char *msg, bool addErrno);
-    void sendBroadcast(char *msg);
+    void sendBroadcast(int code, const char *msg, bool addErrno);
+    void sendBroadcast(const char *msg);
 
 protected:
     virtual bool onDataAvailable(SocketClient *c) = 0;
diff --git a/libcutils/Android.mk b/libcutils/Android.mk
index 7cb1ae4..285e195 100644
--- a/libcutils/Android.mk
+++ b/libcutils/Android.mk
@@ -21,6 +21,7 @@
 	array.c \
 	hashmap.c \
 	atomic.c \
+        native_handle.c \
 	buffer.c \
 	socket_inaddr_any_server.c \
 	socket_local_client.c \
diff --git a/libcutils/native_handle.c b/libcutils/native_handle.c
new file mode 100644
index 0000000..4089968
--- /dev/null
+++ b/libcutils/native_handle.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "NativeHandle"
+
+#include <stdint.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <cutils/log.h>
+#include <cutils/native_handle.h>
+
+native_handle_t* native_handle_create(int numFds, int numInts)
+{
+    native_handle_t* h = malloc(
+            sizeof(native_handle_t) + sizeof(int)*(numFds+numInts));
+
+    h->version = sizeof(native_handle_t);
+    h->numFds = numFds;
+    h->numInts = numInts;
+    return h;
+}
+
+int native_handle_delete(native_handle_t* h)
+{
+    if (h) {
+        if (h->version != sizeof(native_handle_t))
+            return -EINVAL;
+        free(h);
+    }
+    return 0;
+}
+
+int native_handle_close(const native_handle_t* h)
+{
+    if (h->version != sizeof(native_handle_t))
+        return -EINVAL;
+
+    const int numFds = h->numFds;
+    int i;
+    for (i=0 ; i<numFds ; i++) {
+        close(h->data[i]);
+    }
+    return 0;
+}
diff --git a/libsysutils/src/FrameworkClient.cpp b/libsysutils/src/FrameworkClient.cpp
index 237bb60..1686996 100644
--- a/libsysutils/src/FrameworkClient.cpp
+++ b/libsysutils/src/FrameworkClient.cpp
@@ -13,8 +13,7 @@
     pthread_mutex_init(&mWriteMutex, NULL);
 }
 
-int FrameworkClient::sendMsg(char *msg) {
-    LOGD("FrameworkClient::sendMsg(%s)", msg);
+int FrameworkClient::sendMsg(const char *msg) {
     if (mSocket < 0) {
         errno = EHOSTUNREACH;
         return -1;
@@ -28,7 +27,7 @@
     return 0;
 }
 
-int FrameworkClient::sendMsg(char *msg, char *data) {
+int FrameworkClient::sendMsg(const char *msg, const char *data) {
     char *buffer = (char *) alloca(strlen(msg) + strlen(data) + 1);
     if (!buffer) {
         errno = -ENOMEM;
diff --git a/libsysutils/src/SocketClient.cpp b/libsysutils/src/SocketClient.cpp
index ab020ca..b229627 100644
--- a/libsysutils/src/SocketClient.cpp
+++ b/libsysutils/src/SocketClient.cpp
@@ -14,7 +14,7 @@
     pthread_mutex_init(&mWriteMutex, NULL);
 }
 
-int SocketClient::sendMsg(int code, char *msg, bool addErrno) {
+int SocketClient::sendMsg(int code, const char *msg, bool addErrno) {
     char *buf;
     
     if (addErrno) {
@@ -27,23 +27,24 @@
     return sendMsg(buf);
 }
 
-int SocketClient::sendMsg(char *msg) {
+int SocketClient::sendMsg(const char *msg) {
     if (mSocket < 0) {
         errno = EHOSTUNREACH;
         return -1;
     }
 
-    char *bp;
-  
+    char *tmp;
+    const char *bp = msg;
+
     if (msg[strlen(msg)] != '\n') {
-        bp = (char *) alloca(strlen(msg) + 1);
-        strcpy(bp, msg);
-        strcat(bp, "\n");
-    } else
-        bp = msg;
+        tmp = (char *) alloca(strlen(msg) + 1);
+        strcpy(tmp, msg);
+        strcat(tmp, "\n");
+        bp = tmp;
+    }
        
     int rc = 0;
-    char *p = bp;
+    const char *p = bp;
     int brtw = strlen(bp);
 
     pthread_mutex_lock(&mWriteMutex);
diff --git a/libsysutils/src/SocketListener.cpp b/libsysutils/src/SocketListener.cpp
index acc4a67..cb7dd80 100644
--- a/libsysutils/src/SocketListener.cpp
+++ b/libsysutils/src/SocketListener.cpp
@@ -173,7 +173,7 @@
     }
 }
 
-void SocketListener::sendBroadcast(int code, char *msg, bool addErrno) {
+void SocketListener::sendBroadcast(int code, const char *msg, bool addErrno) {
     pthread_mutex_lock(&mClientsLock);
     SocketClientCollection::iterator i;
 
@@ -185,7 +185,7 @@
     pthread_mutex_unlock(&mClientsLock);
 }
 
-void SocketListener::sendBroadcast(char *msg) {
+void SocketListener::sendBroadcast(const char *msg) {
     pthread_mutex_lock(&mClientsLock);
     SocketClientCollection::iterator i;
 
diff --git a/nexus/OpenVpnController.cpp b/nexus/OpenVpnController.cpp
index d326ad5..411a0c7 100644
--- a/nexus/OpenVpnController.cpp
+++ b/nexus/OpenVpnController.cpp
@@ -26,6 +26,7 @@
 #include "OpenVpnController.h"
 
 #define DAEMON_PROP_NAME "vpn.openvpn.status"
+
 #define DAEMON_CONFIG_FILE "/data/misc/openvpn/openvpn.conf"
 
 OpenVpnController::OpenVpnController() :
@@ -46,13 +47,16 @@
 }
 
 int OpenVpnController::enable() {
-
-    if (validateConfig()) {
-        LOGE("Error validating configuration file");
+    char svc[PROPERTY_VALUE_MAX];
+    char tmp[64];
+    
+    if (!getProperty("vpn.gateway", tmp, sizeof(tmp))) {
+        LOGE("Error reading property 'vpn.gateway' (%s)", strerror(errno));
         return -1;
     }
+    snprintf(svc, sizeof(svc), "openvpn:--remote %s 1194", tmp);
 
-    if (mServiceManager->start("openvpn"))
+    if (mServiceManager->start(svc))
         return -1;
 
     return 0;
@@ -64,15 +68,3 @@
         return -1;
     return 0;
 }
-
-int OpenVpnController::validateConfig() {
-    unlink(DAEMON_CONFIG_FILE);
-
-    FILE *fp = fopen(DAEMON_CONFIG_FILE, "w");
-    if (!fp)
-        return -1;
-
-    fprintf(fp, "remote %s 1194\n", inet_ntoa(getVpnGateway()));
-    fclose(fp);
-    return 0;
-}
diff --git a/nexus/OpenVpnController.h b/nexus/OpenVpnController.h
index 7bcc098..b321029 100644
--- a/nexus/OpenVpnController.h
+++ b/nexus/OpenVpnController.h
@@ -33,11 +33,6 @@
     int stop();
     int enable();
     int disable();
-
-protected:
-
-private:
-    int validateConfig();
 };
 
 #endif
diff --git a/rootdir/init.rc b/rootdir/init.rc
index c20eeaa..9853cc6 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -246,6 +246,12 @@
     group audio
     oneshot
 
+service bootanim /system/bin/bootanimation
+    user graphics
+    group graphics
+    disabled
+    oneshot
+
 service dbus /system/bin/dbus-daemon --system --nofork
     socket dbus stream 660 bluetooth bluetooth
     user bluetooth
diff --git a/vold/volmgr_vfat.c b/vold/volmgr_vfat.c
index 2b0e1fa..4013df8 100644
--- a/vold/volmgr_vfat.c
+++ b/vold/volmgr_vfat.c
@@ -110,7 +110,7 @@
     LOG_VOL("vfat_mount(%d:%d, %s, %d):", dev->major, dev->minor, vol->mount_point, safe_mode);
 #endif
 
-    flags = MS_NODEV | MS_NOEXEC | MS_NOSUID | MS_DIRSYNC;
+    flags = MS_NODEV | MS_NOEXEC | MS_NOSUID | MS_DIRSYNC | MS_SYNCHRONOUS;
 
     if (vol->state == volstate_mounted) {
         LOG_VOL("Remounting %d:%d on %s, safe mode %d", dev->major,