Use new SdkController communication protocol for emulation ports

android/sdk-control-socket.* has replaced android/android-device.* as the back-bone
of communicating with SDK controller on the device. The major differences are:

- New communication protocol uses just one (async) socket connection to communicate
  with the device (the old one used two sockets: one sync, and another - async).
- New communication protocol connects to one TCP port (1970 in this CL) for all emulation
  ports. Channel multiplexing is done by using port names, and assigning a separate socket
  for communication inside each separate port. The old protocol had separate TCP ports for
  each emulation ports (1968 for sensors, and 1969 for multi-touch)

Change-Id: I779fcbdfba2f9b4c433a9d76a567975708b00469
diff --git a/android/async-socket.c b/android/async-socket.c
index 5e2ae29..ab4e4b6 100644
--- a/android/async-socket.c
+++ b/android/async-socket.c
@@ -20,8 +20,6 @@
  * a TCP port forwarding, enabled by ADB.
  */
 
-#include "qemu-common.h"
-#include "android/async-utils.h"
 #include "android/utils/debug.h"
 #include "android/async-socket-connector.h"
 #include "android/async-socket.h"
@@ -683,10 +681,10 @@
 _async_socket_close_socket(AsyncSocket* as)
 {
     if (as->fd >= 0) {
-        loopIo_done(as->io);
-        socket_close(as->fd);
         T("ASocket %s: Socket handle %d is closed.",
           _async_socket_string(as), as->fd);
+        loopIo_done(as->io);
+        socket_close(as->fd);
         as->fd = -1;
     }
 }
@@ -1217,15 +1215,22 @@
     AsyncSocketIO* const asr =
         _async_socket_reader_new(as, buffer, len, reader_cb, reader_opaque,
                                  deadline);
-    /* Add new reader to the list. Note that we use initial reference from I/O
-     * 'new' routine as "in the list" reference counter. */
-    if (as->readers_head == NULL) {
-        as->readers_head = as->readers_tail = asr;
+    if (async_socket_is_connected(as)) {
+        /* Add new reader to the list. Note that we use initial reference from I/O
+         * 'new' routine as "in the list" reference counter. */
+        if (as->readers_head == NULL) {
+            as->readers_head = as->readers_tail = asr;
+        } else {
+            as->readers_tail->next = asr;
+            as->readers_tail = asr;
+        }
+        loopIo_wantRead(as->io);
     } else {
-        as->readers_tail->next = asr;
-        as->readers_tail = asr;
+        D("ASocket %s: Read on a disconnected socket.", _async_socket_string(as));
+        errno = ECONNRESET;
+        reader_cb(reader_opaque, asr, ASIO_STATE_FAILED);
+        async_socket_io_release(asr);
     }
-    loopIo_wantRead(as->io);
 }
 
 void
@@ -1253,15 +1258,22 @@
     AsyncSocketIO* const asw =
         _async_socket_writer_new(as, buffer, len, writer_cb, writer_opaque,
                                  deadline);
-    /* Add new writer to the list. Note that we use initial reference from I/O
-     * 'new' routine as "in the list" reference counter. */
-    if (as->writers_head == NULL) {
-        as->writers_head = as->writers_tail = asw;
+    if (async_socket_is_connected(as)) {
+        /* Add new writer to the list. Note that we use initial reference from I/O
+         * 'new' routine as "in the list" reference counter. */
+        if (as->writers_head == NULL) {
+            as->writers_head = as->writers_tail = asw;
+        } else {
+            as->writers_tail->next = asw;
+            as->writers_tail = asw;
+        }
+        loopIo_wantWrite(as->io);
     } else {
-        as->writers_tail->next = asw;
-        as->writers_tail = asw;
+        D("ASocket %s: Write on a disconnected socket.", _async_socket_string(as));
+        errno = ECONNRESET;
+        writer_cb(writer_opaque, asw, ASIO_STATE_FAILED);
+        async_socket_io_release(asw);
     }
-    loopIo_wantWrite(as->io);
 }
 
 void
@@ -1294,3 +1306,9 @@
 {
     return sock_address_get_port(&as->address);
 }
+
+int
+async_socket_is_connected(const AsyncSocket* as)
+{
+    return as->fd >= 0;
+}