Merge "Remove code to handle non-default file encryption"
diff --git a/debuggerd/debuggerd.rc b/debuggerd/debuggerd.rc
index e43fe96..1c6b9ff 100644
--- a/debuggerd/debuggerd.rc
+++ b/debuggerd/debuggerd.rc
@@ -1,4 +1,3 @@
 service debuggerd /system/bin/debuggerd
-    class main
     group root readproc
     writepid /dev/cpuset/system-background/tasks
diff --git a/debuggerd/debuggerd64.rc b/debuggerd/debuggerd64.rc
index 35b5af3..3e8847a 100644
--- a/debuggerd/debuggerd64.rc
+++ b/debuggerd/debuggerd64.rc
@@ -1,4 +1,3 @@
 service debuggerd64 /system/bin/debuggerd64
-    class main
     group root readproc
     writepid /dev/cpuset/system-background/tasks
diff --git a/fastboot/Android.mk b/fastboot/Android.mk
index fcec5b1..65f4e01 100644
--- a/fastboot/Android.mk
+++ b/fastboot/Android.mk
@@ -106,7 +106,11 @@
 LOCAL_MODULE := fastboot_test
 LOCAL_MODULE_HOST_OS := darwin linux windows
 
-LOCAL_SRC_FILES := socket.cpp socket_test.cpp
+LOCAL_SRC_FILES := \
+    socket.cpp \
+    socket_mock.cpp \
+    socket_test.cpp \
+
 LOCAL_STATIC_LIBRARIES := libbase libcutils
 
 LOCAL_CFLAGS += -Wall -Wextra -Werror -Wunreachable-code
diff --git a/fastboot/socket.cpp b/fastboot/socket.cpp
index d41f1fe..0a3ddfa 100644
--- a/fastboot/socket.cpp
+++ b/fastboot/socket.cpp
@@ -28,6 +28,7 @@
 
 #include "socket.h"
 
+#include <android-base/errors.h>
 #include <android-base/stringprintf.h>
 
 Socket::Socket(cutils_socket_t sock) : sock_(sock) {}
@@ -77,6 +78,10 @@
     return total;
 }
 
+int Socket::GetLocalPort() {
+    return socket_get_local_port(sock_);
+}
+
 // Implements the Socket interface for UDP.
 class UdpSocket : public Socket {
   public:
@@ -210,3 +215,12 @@
 
     return nullptr;
 }
+
+std::string Socket::GetErrorMessage() {
+#if defined(_WIN32)
+    DWORD error_code = WSAGetLastError();
+#else
+    int error_code = errno;
+#endif
+    return android::base::SystemErrorCodeToString(error_code);
+}
diff --git a/fastboot/socket.h b/fastboot/socket.h
index 3e66c27..a7481db 100644
--- a/fastboot/socket.h
+++ b/fastboot/socket.h
@@ -44,6 +44,10 @@
   public:
     enum class Protocol { kTcp, kUdp };
 
+    // Returns the socket error message. This must be called immediately after a socket failure
+    // before any other system calls are made.
+    static std::string GetErrorMessage();
+
     // Creates a new client connection. Clients are connected to a specific hostname/port and can
     // only send to that destination.
     // On failure, |error| is filled (if non-null) and nullptr is returned.
@@ -78,6 +82,9 @@
     // connected to the client on success, nullptr on failure.
     virtual std::unique_ptr<Socket> Accept() { return nullptr; }
 
+    // Returns the local port the Socket is bound to or -1 on error.
+    int GetLocalPort();
+
   protected:
     // Protected constructor to force factory function use.
     Socket(cutils_socket_t sock);
diff --git a/fastboot/socket_mock.cpp b/fastboot/socket_mock.cpp
new file mode 100644
index 0000000..8fea554
--- /dev/null
+++ b/fastboot/socket_mock.cpp
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "socket_mock.h"
+
+#include <gtest/gtest.h>
+
+SocketMock::SocketMock() : Socket(INVALID_SOCKET) {}
+
+SocketMock::~SocketMock() {
+    if (!events_.empty()) {
+        ADD_FAILURE() << events_.size() << " event(s) were not handled";
+    }
+}
+
+ssize_t SocketMock::Send(const void* data, size_t length) {
+    if (events_.empty()) {
+        ADD_FAILURE() << "Send() was called when no message was expected";
+        return -1;
+    }
+
+    if (events_.front().type != EventType::kSend) {
+        ADD_FAILURE() << "Send() was called out-of-order";
+        return -1;
+    }
+
+    std::string message(reinterpret_cast<const char*>(data), length);
+    if (events_.front().message != message) {
+        ADD_FAILURE() << "Send() expected " << events_.front().message << ", but got " << message;
+        return -1;
+    }
+
+    ssize_t return_value = events_.front().return_value;
+    events_.pop();
+    return return_value;
+}
+
+ssize_t SocketMock::Receive(void* data, size_t length, int /*timeout_ms*/) {
+    if (events_.empty()) {
+        ADD_FAILURE() << "Receive() was called when no message was ready";
+        return -1;
+    }
+
+    if (events_.front().type != EventType::kReceive) {
+        ADD_FAILURE() << "Receive() was called out-of-order";
+        return -1;
+    }
+
+    if (events_.front().return_value > static_cast<ssize_t>(length)) {
+        ADD_FAILURE() << "Receive(): not enough bytes (" << length << ") for "
+                      << events_.front().message;
+        return -1;
+    }
+
+    ssize_t return_value = events_.front().return_value;
+    if (return_value > 0) {
+        memcpy(data, events_.front().message.data(), return_value);
+    }
+    events_.pop();
+    return return_value;
+}
+
+int SocketMock::Close() {
+    return 0;
+}
+
+std::unique_ptr<Socket> SocketMock::Accept() {
+    if (events_.empty()) {
+        ADD_FAILURE() << "Accept() was called when no socket was ready";
+        return nullptr;
+    }
+
+    if (events_.front().type != EventType::kAccept) {
+        ADD_FAILURE() << "Accept() was called out-of-order";
+        return nullptr;
+    }
+
+    std::unique_ptr<Socket> sock = std::move(events_.front().sock);
+    events_.pop();
+    return sock;
+}
+
+void SocketMock::ExpectSend(std::string message) {
+    ssize_t return_value = message.length();
+    events_.push(Event(EventType::kSend, std::move(message), return_value, nullptr));
+}
+
+void SocketMock::ExpectSendFailure(std::string message) {
+    events_.push(Event(EventType::kSend, std::move(message), -1, nullptr));
+}
+
+void SocketMock::AddReceive(std::string message) {
+    ssize_t return_value = message.length();
+    events_.push(Event(EventType::kReceive, std::move(message), return_value, nullptr));
+}
+
+void SocketMock::AddReceiveFailure() {
+    events_.push(Event(EventType::kReceive, "", -1, nullptr));
+}
+
+void SocketMock::AddAccept(std::unique_ptr<Socket> sock) {
+    events_.push(Event(EventType::kAccept, "", 0, std::move(sock)));
+}
+
+SocketMock::Event::Event(EventType _type, std::string _message, ssize_t _return_value,
+                         std::unique_ptr<Socket> _sock)
+        : type(_type), message(_message), return_value(_return_value), sock(std::move(_sock)) {}
diff --git a/fastboot/socket_mock.h b/fastboot/socket_mock.h
new file mode 100644
index 0000000..3e62b33
--- /dev/null
+++ b/fastboot/socket_mock.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef SOCKET_MOCK_H_
+#define SOCKET_MOCK_H_
+
+#include <memory>
+#include <queue>
+#include <string>
+
+#include <android-base/macros.h>
+
+#include "socket.h"
+
+// A mock Socket implementation to be used for testing. Tests can set expectations for messages
+// to be sent and provide messages to be received in order to verify protocol behavior.
+//
+// Example: testing sending "foo" and receiving "bar".
+//   SocketMock mock;
+//   mock.ExpectSend("foo");
+//   mock.AddReceive("bar");
+//   EXPECT_TRUE(DoFooBar(&mock));
+//
+// Example: testing sending "foo" and expecting "bar", but receiving "baz" instead.
+//   SocketMock mock;
+//   mock.ExpectSend("foo");
+//   mock.AddReceive("baz");
+//   EXPECT_FALSE(DoFooBar(&mock));
+class SocketMock : public Socket {
+  public:
+    SocketMock();
+    ~SocketMock() override;
+
+    ssize_t Send(const void* data, size_t length) override;
+    ssize_t Receive(void* data, size_t length, int timeout_ms) override;
+    int Close() override;
+    virtual std::unique_ptr<Socket> Accept();
+
+    // Adds an expectation for Send().
+    void ExpectSend(std::string message);
+
+    // Adds an expectation for Send() that returns -1.
+    void ExpectSendFailure(std::string message);
+
+    // Adds data to provide for Receive().
+    void AddReceive(std::string message);
+
+    // Adds a Receive() failure.
+    void AddReceiveFailure();
+
+    // Adds a Socket to return from Accept().
+    void AddAccept(std::unique_ptr<Socket> sock);
+
+  private:
+    enum class EventType { kSend, kReceive, kAccept };
+
+    struct Event {
+        Event(EventType _type, std::string _message, ssize_t _return_value,
+              std::unique_ptr<Socket> _sock);
+
+        EventType type;
+        std::string message;
+        ssize_t return_value;
+        std::unique_ptr<Socket> sock;
+    };
+
+    std::queue<Event> events_;
+
+    DISALLOW_COPY_AND_ASSIGN(SocketMock);
+};
+
+#endif  // SOCKET_MOCK_H_
diff --git a/fastboot/socket_test.cpp b/fastboot/socket_test.cpp
index 1fd9d7c..7bfe967 100644
--- a/fastboot/socket_test.cpp
+++ b/fastboot/socket_test.cpp
@@ -14,33 +14,31 @@
  * limitations under the License.
  */
 
-// Tests UDP functionality using loopback connections. Requires that kTestPort is available
-// for loopback communication on the host. These tests also assume that no UDP packets are lost,
-// which should be the case for loopback communication, but is not guaranteed.
+// Tests socket functionality using loopback connections. The UDP tests assume that no packets are
+// lost, which should be the case for loopback communication, but is not guaranteed.
+//
+// Also tests our SocketMock class to make sure it works as expected and reports errors properly
+// if the mock expectations aren't met during a test.
 
 #include "socket.h"
+#include "socket_mock.h"
 
 #include <gtest/gtest.h>
+#include <gtest/gtest-spi.h>
 
-enum {
-    // This port must be available for loopback communication.
-    kTestPort = 54321,
-
-    // Don't wait forever in a unit test.
-    kTestTimeoutMs = 3000,
-};
+enum { kTestTimeoutMs = 3000 };
 
 // Creates connected sockets |server| and |client|. Returns true on success.
 bool MakeConnectedSockets(Socket::Protocol protocol, std::unique_ptr<Socket>* server,
-                          std::unique_ptr<Socket>* client, const std::string hostname = "localhost",
-                          int port = kTestPort) {
-    *server = Socket::NewServer(protocol, port);
+                          std::unique_ptr<Socket>* client,
+                          const std::string hostname = "localhost") {
+    *server = Socket::NewServer(protocol, 0);
     if (*server == nullptr) {
         ADD_FAILURE() << "Failed to create server.";
         return false;
     }
 
-    *client = Socket::NewClient(protocol, hostname, port, nullptr);
+    *client = Socket::NewClient(protocol, hostname, (*server)->GetLocalPort(), nullptr);
     if (*client == nullptr) {
         ADD_FAILURE() << "Failed to create client.";
         return false;
@@ -124,3 +122,86 @@
         EXPECT_EQ(-1, bytes);
     }
 }
+
+TEST(SocketMockTest, TestSendSuccess) {
+    SocketMock mock;
+
+    mock.ExpectSend("foo");
+    EXPECT_TRUE(SendString(&mock, "foo"));
+
+    mock.ExpectSend("abc");
+    mock.ExpectSend("123");
+    EXPECT_TRUE(SendString(&mock, "abc"));
+    EXPECT_TRUE(SendString(&mock, "123"));
+}
+
+TEST(SocketMockTest, TestSendFailure) {
+    SocketMock* mock = new SocketMock;
+
+    EXPECT_NONFATAL_FAILURE(SendString(mock, "foo"), "no message was expected");
+
+    mock->ExpectSend("foo");
+    EXPECT_NONFATAL_FAILURE(SendString(mock, "bar"), "expected foo, but got bar");
+    EXPECT_TRUE(SendString(mock, "foo"));
+
+    mock->AddReceive("foo");
+    EXPECT_NONFATAL_FAILURE(SendString(mock, "foo"), "called out-of-order");
+    EXPECT_TRUE(ReceiveString(mock, "foo"));
+
+    mock->ExpectSend("foo");
+    EXPECT_NONFATAL_FAILURE(delete mock, "1 event(s) were not handled");
+}
+
+TEST(SocketMockTest, TestReceiveSuccess) {
+    SocketMock mock;
+
+    mock.AddReceive("foo");
+    EXPECT_TRUE(ReceiveString(&mock, "foo"));
+
+    mock.AddReceive("abc");
+    mock.AddReceive("123");
+    EXPECT_TRUE(ReceiveString(&mock, "abc"));
+    EXPECT_TRUE(ReceiveString(&mock, "123"));
+}
+
+TEST(SocketMockTest, TestReceiveFailure) {
+    SocketMock* mock = new SocketMock;
+
+    EXPECT_NONFATAL_FAILURE(ReceiveString(mock, "foo"), "no message was ready");
+
+    mock->ExpectSend("foo");
+    EXPECT_NONFATAL_FAILURE(ReceiveString(mock, "foo"), "called out-of-order");
+    EXPECT_TRUE(SendString(mock, "foo"));
+
+    char c;
+    mock->AddReceive("foo");
+    EXPECT_NONFATAL_FAILURE(mock->Receive(&c, 1, 0), "not enough bytes (1) for foo");
+    EXPECT_TRUE(ReceiveString(mock, "foo"));
+
+    mock->AddReceive("foo");
+    EXPECT_NONFATAL_FAILURE(delete mock, "1 event(s) were not handled");
+}
+
+TEST(SocketMockTest, TestAcceptSuccess) {
+    SocketMock mock;
+
+    SocketMock* mock_handler = new SocketMock;
+    mock.AddAccept(std::unique_ptr<SocketMock>(mock_handler));
+    EXPECT_EQ(mock_handler, mock.Accept().get());
+
+    mock.AddAccept(nullptr);
+    EXPECT_EQ(nullptr, mock.Accept().get());
+}
+
+TEST(SocketMockTest, TestAcceptFailure) {
+    SocketMock* mock = new SocketMock;
+
+    EXPECT_NONFATAL_FAILURE(mock->Accept(), "no socket was ready");
+
+    mock->ExpectSend("foo");
+    EXPECT_NONFATAL_FAILURE(mock->Accept(), "called out-of-order");
+    EXPECT_TRUE(SendString(mock, "foo"));
+
+    mock->AddAccept(nullptr);
+    EXPECT_NONFATAL_FAILURE(delete mock, "1 event(s) were not handled");
+}
diff --git a/include/cutils/sockets.h b/include/cutils/sockets.h
index e25c555..cb9b3ff 100644
--- a/include/cutils/sockets.h
+++ b/include/cutils/sockets.h
@@ -30,12 +30,15 @@
 
 typedef int  socklen_t;
 typedef SOCKET cutils_socket_t;
+typedef WSABUF cutils_socket_buffer_t;
 
 #else
 
 #include <sys/socket.h>
+#include <sys/uio.h>
 
 typedef int cutils_socket_t;
+typedef struct iovec cutils_socket_buffer_t;
 #define INVALID_SOCKET (-1)
 
 #endif
@@ -132,6 +135,33 @@
 int socket_set_receive_timeout(cutils_socket_t sock, int timeout_ms);
 
 /*
+ * Returns the local port the socket is bound to or -1 on error.
+ */
+int socket_get_local_port(cutils_socket_t sock);
+
+/*
+ * Sends to a socket from multiple buffers; wraps writev() on Unix or WSASend()
+ * on Windows. This can give significant speedup compared to calling send()
+ * multiple times.
+ *
+ * Because Unix and Windows use different structs to hold buffers, we also
+ * need a generic function to set up the buffers.
+ *
+ * Example usage:
+ *   cutils_socket_buffer_t buffers[2] = {
+ *       make_cutils_socket_buffer(data0, len0),
+ *       make_cutils_socket_buffer(data1, len1)
+ *   };
+ *   socket_send_buffers(sock, buffers, 2);
+ *
+ * Returns the number of bytes written or -1 on error.
+ */
+cutils_socket_buffer_t make_cutils_socket_buffer(void* data, size_t length);
+ssize_t socket_send_buffers(cutils_socket_t sock,
+                            cutils_socket_buffer_t* buffers,
+                            size_t num_buffers);
+
+/*
  * socket_peer_is_trusted - Takes a socket which is presumed to be a
  * connected local socket (e.g. AF_LOCAL) and returns whether the peer
  * (the userid that owns the process on the other end of that socket)
diff --git a/init/devices.cpp b/init/devices.cpp
index d556e30..39cd706 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -40,6 +40,7 @@
 #include <sys/time.h>
 #include <sys/wait.h>
 
+#include <android-base/file.h>
 #include <cutils/list.h>
 #include <cutils/uevent.h>
 
@@ -769,21 +770,13 @@
             ret = -1;
             break;
         }
-
-        len_to_copy -= nr;
-        while (nr > 0) {
-            ssize_t nw = 0;
-
-            nw = write(data_fd, buf + nw, nr);
-            if(nw <= 0) {
-                ret = -1;
-                goto out;
-            }
-            nr -= nw;
+        if (!android::base::WriteFully(data_fd, buf, nr)) {
+            ret = -1;
+            break;
         }
+        len_to_copy -= nr;
     }
 
-out:
     if(!ret)
         write(loading_fd, "0", 1);  /* successful end of transfer */
     else
diff --git a/libcutils/Android.mk b/libcutils/Android.mk
index f5f341a..af15cff 100644
--- a/libcutils/Android.mk
+++ b/libcutils/Android.mk
@@ -17,21 +17,22 @@
 include $(CLEAR_VARS)
 
 libcutils_common_sources := \
-        hashmap.c \
         atomic.c.arm \
-        native_handle.c \
         config_utils.c \
+        fs_config.c \
+        hashmap.c \
+        iosched_policy.c \
         load_file.c \
-        strlcpy.c \
+        native_handle.c \
         open_memstream.c \
+        process_name.c \
+        record_stream.c \
+        sched_policy.c \
+        sockets.cpp \
         strdup16to8.c \
         strdup8to16.c \
-        record_stream.c \
-        process_name.c \
+        strlcpy.c \
         threads.c \
-        sched_policy.c \
-        iosched_policy.c \
-        fs_config.c
 
 # some files must not be compiled when building against Mingw
 # they correspond to features not used by our host development tools
diff --git a/libcutils/ashmem-dev.c b/libcutils/ashmem-dev.c
index 3089a94..a5203e1 100644
--- a/libcutils/ashmem-dev.c
+++ b/libcutils/ashmem-dev.c
@@ -20,17 +20,19 @@
  * used by the simulator.
  */
 
-#include <unistd.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
+#include <errno.h>
 #include <fcntl.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
 
 #include <linux/ashmem.h>
+
 #include <cutils/ashmem.h>
 
-#define ASHMEM_DEVICE	"/dev/ashmem"
+#define ASHMEM_DEVICE "/dev/ashmem"
 
 /*
  * ashmem_create_region - creates a new ashmem region and returns the file
@@ -41,50 +43,55 @@
  */
 int ashmem_create_region(const char *name, size_t size)
 {
-	int fd, ret;
+    int ret, save_errno;
 
-	fd = open(ASHMEM_DEVICE, O_RDWR);
-	if (fd < 0)
-		return fd;
+    int fd = TEMP_FAILURE_RETRY(open(ASHMEM_DEVICE, O_RDWR));
+    if (fd < 0) {
+        return fd;
+    }
 
-	if (name) {
-		char buf[ASHMEM_NAME_LEN] = {0};
+    if (name) {
+        char buf[ASHMEM_NAME_LEN] = {0};
 
-		strlcpy(buf, name, sizeof(buf));
-		ret = ioctl(fd, ASHMEM_SET_NAME, buf);
-		if (ret < 0)
-			goto error;
-	}
+        strlcpy(buf, name, sizeof(buf));
+        ret = TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_SET_NAME, buf));
+        if (ret < 0) {
+            goto error;
+        }
+    }
 
-	ret = ioctl(fd, ASHMEM_SET_SIZE, size);
-	if (ret < 0)
-		goto error;
+    ret = TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_SET_SIZE, size));
+    if (ret < 0) {
+        goto error;
+    }
 
-	return fd;
+    return fd;
 
 error:
-	close(fd);
-	return ret;
+    save_errno = errno;
+    close(fd);
+    errno = save_errno;
+    return ret;
 }
 
 int ashmem_set_prot_region(int fd, int prot)
 {
-	return ioctl(fd, ASHMEM_SET_PROT_MASK, prot);
+    return TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_SET_PROT_MASK, prot));
 }
 
 int ashmem_pin_region(int fd, size_t offset, size_t len)
 {
-	struct ashmem_pin pin = { offset, len };
-	return ioctl(fd, ASHMEM_PIN, &pin);
+    struct ashmem_pin pin = { offset, len };
+    return TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_PIN, &pin));
 }
 
 int ashmem_unpin_region(int fd, size_t offset, size_t len)
 {
-	struct ashmem_pin pin = { offset, len };
-	return ioctl(fd, ASHMEM_UNPIN, &pin);
+    struct ashmem_pin pin = { offset, len };
+    return TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_UNPIN, &pin));
 }
 
 int ashmem_get_size_region(int fd)
 {
-  return ioctl(fd, ASHMEM_GET_SIZE, NULL);
+    return TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_GET_SIZE, NULL));
 }
diff --git a/libcutils/ashmem-host.c b/libcutils/ashmem-host.c
index 15dd43e..c85f06b 100644
--- a/libcutils/ashmem-host.c
+++ b/libcutils/ashmem-host.c
@@ -78,8 +78,11 @@
         return -1;
     }
 
-    // Check if this is an "ashmem" region.
-    // TODO: This is very hacky, and can easily break. We need some reliable indicator.
+    /*
+     * Check if this is an "ashmem" region.
+     * TODO: This is very hacky, and can easily break.
+     * We need some reliable indicator.
+     */
     if (!(buf.st_nlink == 0 && S_ISREG(buf.st_mode))) {
         errno = ENOTTY;
         return -1;
diff --git a/libcutils/sockets.cpp b/libcutils/sockets.cpp
new file mode 100644
index 0000000..d9ab146
--- /dev/null
+++ b/libcutils/sockets.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+// This file contains socket implementation that can be shared between
+// platforms as long as the correct headers are included.
+
+#include <cutils/sockets.h>
+
+#if !defined(_WIN32)
+#include <netinet/in.h>
+#endif
+
+int socket_get_local_port(cutils_socket_t sock) {
+    sockaddr_storage addr;
+    socklen_t addr_size = sizeof(addr);
+
+    if (getsockname(sock, reinterpret_cast<sockaddr*>(&addr), &addr_size) == 0) {
+        // sockaddr_in and sockaddr_in6 always overlap the port field.
+        return ntohs(reinterpret_cast<sockaddr_in*>(&addr)->sin_port);
+    }
+    return -1;
+}
diff --git a/libcutils/sockets_unix.c b/libcutils/sockets_unix.c
index 5eddc4b..3e7cea0 100644
--- a/libcutils/sockets_unix.c
+++ b/libcutils/sockets_unix.c
@@ -47,12 +47,25 @@
 }
 
 int socket_close(int sock) {
-  return close(sock);
+    return close(sock);
 }
 
 int socket_set_receive_timeout(cutils_socket_t sock, int timeout_ms) {
-  struct timeval tv;
-  tv.tv_sec = timeout_ms / 1000;
-  tv.tv_usec = (timeout_ms % 1000) * 1000;
-  return setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
+    struct timeval tv;
+    tv.tv_sec = timeout_ms / 1000;
+    tv.tv_usec = (timeout_ms % 1000) * 1000;
+    return setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
+}
+
+cutils_socket_buffer_t make_cutils_socket_buffer(void* data, size_t length) {
+    cutils_socket_buffer_t buffer;
+    buffer.iov_base = data;
+    buffer.iov_len = length;
+    return buffer;
+}
+
+ssize_t socket_send_buffers(cutils_socket_t sock,
+                            cutils_socket_buffer_t* buffers,
+                            size_t num_buffers) {
+    return writev(sock, buffers, num_buffers);
 }
diff --git a/libcutils/sockets_windows.c b/libcutils/sockets_windows.c
index 1bf2933..8153688 100644
--- a/libcutils/sockets_windows.c
+++ b/libcutils/sockets_windows.c
@@ -58,3 +58,22 @@
     return setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout_ms,
                       sizeof(timeout_ms));
 }
+
+cutils_socket_buffer_t make_cutils_socket_buffer(void* data, size_t length) {
+    cutils_socket_buffer_t buffer;
+    buffer.buf = data;
+    buffer.len = length;
+    return buffer;
+}
+
+ssize_t socket_send_buffers(cutils_socket_t sock,
+                            cutils_socket_buffer_t* buffers,
+                            size_t num_buffers) {
+    DWORD bytes_sent = 0;
+
+    if (WSASend(sock, buffers, num_buffers, &bytes_sent, 0, NULL, NULL) !=
+            SOCKET_ERROR) {
+        return bytes_sent;
+    }
+    return -1;
+}
diff --git a/libcutils/tests/sockets_test.cpp b/libcutils/tests/sockets_test.cpp
index 966dfe7..40fa9b1 100644
--- a/libcutils/tests/sockets_test.cpp
+++ b/libcutils/tests/sockets_test.cpp
@@ -15,9 +15,8 @@
  */
 
 // Tests socket functionality using loopback connections. Requires IPv4 and
-// IPv6 capabilities, and that kTestPort is available for loopback
-// communication. These tests also assume that no UDP packets are lost,
-// which should be the case for loopback communication, but is not guaranteed.
+// IPv6 capabilities. These tests assume that no UDP packets are lost, which
+// should be the case for loopback communication, but is not guaranteed.
 
 #include <cutils/sockets.h>
 
@@ -25,11 +24,6 @@
 
 #include <gtest/gtest.h>
 
-enum {
-    // This port must be available for loopback communication.
-    kTestPort = 54321
-};
-
 // Makes sure the passed sockets are valid, sends data between them, and closes
 // them. Any failures are logged with gtest.
 //
@@ -40,30 +34,41 @@
     ASSERT_NE(INVALID_SOCKET, server);
     ASSERT_NE(INVALID_SOCKET, client);
 
-    char buffer[3];
+    char buffer[128];
     sockaddr_storage addr;
     socklen_t addr_size = sizeof(addr);
 
     // Send client -> server first to get the UDP client's address.
     ASSERT_EQ(3, send(client, "foo", 3, 0));
     if (type == SOCK_DGRAM) {
-      EXPECT_EQ(3, recvfrom(server, buffer, 3, 0,
-                            reinterpret_cast<sockaddr*>(&addr), &addr_size));
+        EXPECT_EQ(3, recvfrom(server, buffer, sizeof(buffer), 0,
+                              reinterpret_cast<sockaddr*>(&addr), &addr_size));
     } else {
-      EXPECT_EQ(3, recv(server, buffer, 3, 0));
+        EXPECT_EQ(3, recv(server, buffer, sizeof(buffer), 0));
     }
     EXPECT_EQ(0, memcmp(buffer, "foo", 3));
 
     // Now send server -> client.
     if (type == SOCK_DGRAM) {
-      ASSERT_EQ(3, sendto(server, "bar", 3, 0,
-                          reinterpret_cast<sockaddr*>(&addr), addr_size));
+        ASSERT_EQ(3, sendto(server, "bar", 3, 0,
+                            reinterpret_cast<sockaddr*>(&addr), addr_size));
     } else {
-      ASSERT_EQ(3, send(server, "bar", 3, 0));
+        ASSERT_EQ(3, send(server, "bar", 3, 0));
     }
-    EXPECT_EQ(3, recv(client, buffer, 3, 0));
+    EXPECT_EQ(3, recv(client, buffer, sizeof(buffer), 0));
     EXPECT_EQ(0, memcmp(buffer, "bar", 3));
 
+    // Send multiple buffers using socket_send_buffers().
+    std::string data[] = {"foo", "bar", "12345"};
+    cutils_socket_buffer_t socket_buffers[3];
+    for (int i = 0; i < 3; ++i) {
+        socket_buffers[i] = make_cutils_socket_buffer(&data[i][0],
+                                                      data[i].length());
+    }
+    EXPECT_EQ(11, socket_send_buffers(client, socket_buffers, 3));
+    EXPECT_EQ(11, recv(server, buffer, sizeof(buffer), 0));
+    EXPECT_EQ(0, memcmp(buffer, "foobar12345", 11));
+
     EXPECT_EQ(0, socket_close(server));
     EXPECT_EQ(0, socket_close(client));
 }
@@ -87,22 +92,43 @@
     EXPECT_LE(1.0, difftime(time(nullptr), start_time));
 }
 
+// Tests socket_get_local_port().
+TEST(SocketsTest, TestGetLocalPort) {
+    cutils_socket_t server;
+
+    // Check a bunch of ports so that we can ignore any conflicts in case
+    // of ports already being taken, but if a server is able to start up we
+    // should always be able to read its port.
+    for (int port : {10000, 12345, 15999, 20202, 25000}) {
+        for (int type : {SOCK_DGRAM, SOCK_STREAM}) {
+            server = socket_inaddr_any_server(port, SOCK_DGRAM);
+            if (server != INVALID_SOCKET) {
+                EXPECT_EQ(port, socket_get_local_port(server));
+            }
+            socket_close(server);
+        }
+    }
+
+    // Check expected failure for an invalid socket.
+    EXPECT_EQ(-1, socket_get_local_port(INVALID_SOCKET));
+}
+
 // Tests socket_inaddr_any_server() and socket_network_client() for IPv4 UDP.
 TEST(SocketsTest, TestIpv4UdpLoopback) {
-    cutils_socket_t server = socket_inaddr_any_server(kTestPort, SOCK_DGRAM);
-    cutils_socket_t client = socket_network_client("127.0.0.1", kTestPort,
-                                                   SOCK_DGRAM);
+    cutils_socket_t server = socket_inaddr_any_server(0, SOCK_DGRAM);
+    cutils_socket_t client = socket_network_client(
+            "127.0.0.1", socket_get_local_port(server), SOCK_DGRAM);
 
     TestConnectedSockets(server, client, SOCK_DGRAM);
 }
 
 // Tests socket_inaddr_any_server() and socket_network_client() for IPv4 TCP.
 TEST(SocketsTest, TestIpv4TcpLoopback) {
-    cutils_socket_t server = socket_inaddr_any_server(kTestPort, SOCK_STREAM);
+    cutils_socket_t server = socket_inaddr_any_server(0, SOCK_STREAM);
     ASSERT_NE(INVALID_SOCKET, server);
 
-    cutils_socket_t client = socket_network_client("127.0.0.1", kTestPort,
-                                                   SOCK_STREAM);
+    cutils_socket_t client = socket_network_client(
+            "127.0.0.1", socket_get_local_port(server), SOCK_STREAM);
     cutils_socket_t handler = accept(server, nullptr, nullptr);
     EXPECT_EQ(0, socket_close(server));
 
@@ -111,20 +137,20 @@
 
 // Tests socket_inaddr_any_server() and socket_network_client() for IPv6 UDP.
 TEST(SocketsTest, TestIpv6UdpLoopback) {
-    cutils_socket_t server = socket_inaddr_any_server(kTestPort, SOCK_DGRAM);
-    cutils_socket_t client = socket_network_client("::1", kTestPort,
-                                                   SOCK_DGRAM);
+    cutils_socket_t server = socket_inaddr_any_server(0, SOCK_DGRAM);
+    cutils_socket_t client = socket_network_client(
+            "::1", socket_get_local_port(server), SOCK_DGRAM);
 
     TestConnectedSockets(server, client, SOCK_DGRAM);
 }
 
 // Tests socket_inaddr_any_server() and socket_network_client() for IPv6 TCP.
 TEST(SocketsTest, TestIpv6TcpLoopback) {
-    cutils_socket_t server = socket_inaddr_any_server(kTestPort, SOCK_STREAM);
+    cutils_socket_t server = socket_inaddr_any_server(0, SOCK_STREAM);
     ASSERT_NE(INVALID_SOCKET, server);
 
-    cutils_socket_t client = socket_network_client("::1", kTestPort,
-                                                   SOCK_STREAM);
+    cutils_socket_t client = socket_network_client(
+            "::1", socket_get_local_port(server), SOCK_STREAM);
     cutils_socket_t handler = accept(server, nullptr, nullptr);
     EXPECT_EQ(0, socket_close(server));
 
@@ -133,7 +159,7 @@
 
 // Tests setting a receive timeout for UDP sockets.
 TEST(SocketsTest, TestUdpReceiveTimeout) {
-    cutils_socket_t sock = socket_inaddr_any_server(kTestPort, SOCK_DGRAM);
+    cutils_socket_t sock = socket_inaddr_any_server(0, SOCK_DGRAM);
     ASSERT_NE(INVALID_SOCKET, sock);
 
     TestReceiveTimeout(sock);
@@ -143,11 +169,11 @@
 
 // Tests setting a receive timeout for TCP sockets.
 TEST(SocketsTest, TestTcpReceiveTimeout) {
-    cutils_socket_t server = socket_inaddr_any_server(kTestPort, SOCK_STREAM);
+    cutils_socket_t server = socket_inaddr_any_server(0, SOCK_STREAM);
     ASSERT_NE(INVALID_SOCKET, server);
 
-    cutils_socket_t client = socket_network_client("localhost", kTestPort,
-                                                   SOCK_STREAM);
+    cutils_socket_t client = socket_network_client(
+            "localhost", socket_get_local_port(server), SOCK_STREAM);
     cutils_socket_t handler = accept(server, nullptr, nullptr);
     EXPECT_EQ(0, socket_close(server));
 
@@ -156,3 +182,8 @@
     EXPECT_EQ(0, socket_close(client));
     EXPECT_EQ(0, socket_close(handler));
 }
+
+// Tests socket_send_buffers() failure.
+TEST(SocketsTest, TestSocketSendBuffersFailure) {
+    EXPECT_EQ(-1, socket_send_buffers(INVALID_SOCKET, nullptr, 0));
+}
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
index 7f3082c..75d2a2d 100644
--- a/libnativeloader/native_loader.cpp
+++ b/libnativeloader/native_loader.cpp
@@ -47,6 +47,8 @@
                                             "libGLESv1_CM.so:"
                                             "libGLESv2.so:"
                                             "libGLESv3.so:"
+                                            "libicui18n.so:"
+                                            "libicuuc.so:"
                                             "libjnigraphics.so:"
                                             "liblog.so:"
                                             "libmediandk.so:"
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 21ecb5a..dda7338 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -315,8 +315,12 @@
     # We restorecon /data in case the userdata partition has been reset.
     restorecon /data
 
-    # Make sure we have the device encryption key
+    # Start logd, then start debuggerd to make debugging early-boot crashes easier.
     start logd
+    start debuggerd
+    start debuggerd64
+
+    # Make sure we have the device encryption key.
     start vold
     installkey /data