Merge "emulator: opengl: Add support for unix sockets."
diff --git a/tools/emulator/opengl/host/include/libOpenglRender/render_api.h b/tools/emulator/opengl/host/include/libOpenglRender/render_api.h
index 97a2292..bb33192 100644
--- a/tools/emulator/opengl/host/include/libOpenglRender/render_api.h
+++ b/tools/emulator/opengl/host/include/libOpenglRender/render_api.h
@@ -32,6 +32,16 @@
 //
 bool initLibrary(void);
 
+// list of constants to be passed to setStreamMode, which determines
+// which
+#define STREAM_MODE_DEFAULT   0
+#define STREAM_MODE_TCP       1
+#define STREAM_MODE_UNIX      2
+#define STREAM_MODE_PIPE      3
+
+// Change the stream mode. This must be called before initOpenGLRenderer
+int setStreamMode(int mode);
+
 //
 // initOpenGLRenderer - initialize the OpenGL renderer process.
 //     portNum is the tcp port number the renderer is listening to.
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/RenderServer.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/RenderServer.cpp
index 31f59c1..fb5948b 100644
--- a/tools/emulator/opengl/host/libs/libOpenglRender/RenderServer.cpp
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/RenderServer.cpp
@@ -15,6 +15,9 @@
 */
 #include "RenderServer.h"
 #include "TcpStream.h"
+#ifndef _WIN32
+#include "UnixStream.h"
+#endif
 #include "RenderThread.h"
 #include "FrameBuffer.h"
 #include <set>
@@ -27,6 +30,8 @@
 {
 }
 
+extern "C" int gRendererStreamMode;
+
 RenderServer *RenderServer::create(int port)
 {
     RenderServer *server = new RenderServer();
@@ -34,7 +39,16 @@
         return NULL;
     }
 
+    if (gRendererStreamMode == STREAM_MODE_TCP) {
+        server->m_listenSock = new TcpStream();
+    } else {
+#ifdef _WIN32
     server->m_listenSock = new TcpStream();
+#else
+    server->m_listenSock = new UnixStream();
+#endif
+    }
+
     if (server->m_listenSock->listen(port) < 0) {
         ERR("RenderServer::create failed to listen on port %d\n", port);
         delete server;
@@ -49,7 +63,7 @@
     RenderThreadsSet threads;
 
     while(1) {
-        TcpStream *stream = m_listenSock->accept();
+        SocketStream *stream = m_listenSock->accept();
         if (!stream) {
             fprintf(stderr,"Error accepting connection, aborting\n");
             break;
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/RenderServer.h b/tools/emulator/opengl/host/libs/libOpenglRender/RenderServer.h
index 1de4053..98e9890 100644
--- a/tools/emulator/opengl/host/libs/libOpenglRender/RenderServer.h
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/RenderServer.h
@@ -16,7 +16,7 @@
 #ifndef _LIB_OPENGL_RENDER_RENDER_SERVER_H
 #define _LIB_OPENGL_RENDER_RENDER_SERVER_H
 
-#include "TcpStream.h"
+#include "SocketStream.h"
 #include "osThread.h"
 
 class RenderServer : public osUtils::Thread
@@ -31,7 +31,7 @@
     RenderServer();
 
 private:
-    TcpStream *m_listenSock;
+    SocketStream *m_listenSock;
     bool m_exiting;
 };
 
diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/render_api.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/render_api.cpp
index eeaa631..7381b7d 100644
--- a/tools/emulator/opengl/host/libs/libOpenglRender/render_api.cpp
+++ b/tools/emulator/opengl/host/libs/libOpenglRender/render_api.cpp
@@ -20,6 +20,11 @@
 #include "osProcess.h"
 #include "TimeUtils.h"
 
+#include "TcpStream.h"
+#ifndef _WIN32
+#include "UnixStream.h"
+#endif
+
 #include "EGLDispatch.h"
 #include "GLDispatch.h"
 #include "GL2Dispatch.h"
@@ -270,15 +275,35 @@
     }
 }
 
+
+/* NOTE: For now, always use TCP mode by default, until the emulator
+ *        has been updated to support Unix and Win32 pipes
+ */
+#define  DEFAULT_STREAM_MODE  STREAM_MODE_TCP
+
+int gRendererStreamMode = DEFAULT_STREAM_MODE;
+
 IOStream *createRenderThread(int p_stream_buffer_size, unsigned int clientFlags)
 {
-    TcpStream *stream = new TcpStream(p_stream_buffer_size);
+    SocketStream*  stream = NULL;
+
+    if (gRendererStreamMode == STREAM_MODE_TCP) {
+        stream = new TcpStream(p_stream_buffer_size);
+#ifdef _WIN32
+    } else {
+        /* XXX: Need Win32 named pipe stream here */
+        stream = new TcpStream(p_stream_buffer_size);
+#else
+    } else if (gRendererStreamMode == STREAM_MODE_UNIX) {
+        stream = new UnixStream(p_stream_buffer_size);
+#endif
+    }
+
     if (!stream) {
         ERR("createRenderThread failed to create stream\n");
         return NULL;
     }
-
-    if (stream->connect("localhost", s_renderPort) < 0) {
+    if (stream->connect(s_renderPort) < 0) {
         ERR("createRenderThread failed to connect\n");
         delete stream;
         return NULL;
@@ -287,10 +312,36 @@
     //
     // send clientFlags to the renderer
     //
-    unsigned int *pClientFlags = 
+    unsigned int *pClientFlags =
                 (unsigned int *)stream->allocBuffer(sizeof(unsigned int));
     *pClientFlags = clientFlags;
     stream->commitBuffer(sizeof(unsigned int));
 
     return stream;
 }
+
+int
+setStreamMode(int mode)
+{
+    switch (mode) {
+        case STREAM_MODE_DEFAULT:
+            mode = DEFAULT_STREAM_MODE;
+            break;
+
+        case STREAM_MODE_TCP:
+            break;
+
+#ifndef _WIN32
+        case STREAM_MODE_UNIX:
+            break;
+#else /* _WIN32 */
+        case STREAM_MODE_PIPE:
+            break;
+#endif /* _WIN32 */
+        default:
+            // Invalid stream mode
+            return -1;
+    }
+    gRendererStreamMode = mode;
+    return 0;
+}
diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/Android.mk b/tools/emulator/opengl/shared/OpenglCodecCommon/Android.mk
index fa1b248..fb9c2c9 100644
--- a/tools/emulator/opengl/shared/OpenglCodecCommon/Android.mk
+++ b/tools/emulator/opengl/shared/OpenglCodecCommon/Android.mk
@@ -3,16 +3,23 @@
 #
 LOCAL_PATH := $(call my-dir)
 
-### CodecCommon  guest ##############################################
-$(call emugl-begin-static-library,libOpenglCodecCommon)
-
-LOCAL_SRC_FILES := \
+commonSources := \
         GLClientState.cpp \
         GLSharedGroup.cpp \
         glUtils.cpp \
+        SocketStream.cpp \
         TcpStream.cpp \
         TimeUtils.cpp
 
+ifneq ($(HOST_OS),windows)
+    commonSources += UnixStream.cpp
+endif
+
+### CodecCommon  guest ##############################################
+$(call emugl-begin-static-library,libOpenglCodecCommon)
+
+LOCAL_SRC_FILES := $(commonSources)
+
 LOCAL_CFLAGS += -DLOG_TAG=\"eglCodecCommon\"
 
 $(call emugl-export,SHARED_LIBRARIES,libcutils libutils)
@@ -22,11 +29,7 @@
 ### OpenglCodecCommon  host ##############################################
 $(call emugl-begin-host-static-library,libOpenglCodecCommon)
 
-LOCAL_SRC_FILES := \
-        GLClientState.cpp \
-        glUtils.cpp \
-        TcpStream.cpp \
-        TimeUtils.cpp
+LOCAL_SRC_FILES := $(commonSources)
 
 $(call emugl-export,STATIC_LIBRARIES,libcutils)
 $(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/SocketStream.cpp b/tools/emulator/opengl/shared/OpenglCodecCommon/SocketStream.cpp
new file mode 100644
index 0000000..244cfbb
--- /dev/null
+++ b/tools/emulator/opengl/shared/OpenglCodecCommon/SocketStream.cpp
@@ -0,0 +1,163 @@
+/*
+* 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.
+*/
+#include "SocketStream.h"
+#include <cutils/sockets.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#ifndef _WIN32
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <sys/un.h>
+#else
+#include <ws2tcpip.h>
+#endif
+
+SocketStream::SocketStream(size_t bufSize) :
+    IOStream(bufSize),
+    m_sock(-1),
+    m_bufsize(bufSize),
+    m_buf(NULL)
+{
+}
+
+SocketStream::SocketStream(int sock, size_t bufSize) :
+    IOStream(bufSize),
+    m_sock(sock),
+    m_bufsize(bufSize),
+    m_buf(NULL)
+{
+}
+
+SocketStream::~SocketStream()
+{
+    if (m_sock >= 0) {
+#ifdef _WIN32
+        closesocket(m_sock);
+#else
+        ::close(m_sock);
+#endif
+    }
+    if (m_buf != NULL) {
+        free(m_buf);
+        m_buf = NULL;
+    }
+}
+
+
+void *SocketStream::allocBuffer(size_t minSize)
+{
+    size_t allocSize = (m_bufsize < minSize ? minSize : m_bufsize);
+    if (!m_buf) {
+        m_buf = (unsigned char *)malloc(allocSize);
+    }
+    else if (m_bufsize < allocSize) {
+        unsigned char *p = (unsigned char *)realloc(m_buf, allocSize);
+        if (p != NULL) {
+            m_buf = p;
+            m_bufsize = allocSize;
+        } else {
+            ERR("%s: realloc (%d) failed\n", __FUNCTION__, allocSize);
+            free(m_buf);
+            m_buf = NULL;
+            m_bufsize = 0;
+        }
+    }
+
+    return m_buf;
+};
+
+int SocketStream::commitBuffer(size_t size)
+{
+    if (!valid()) return -1;
+
+    size_t res = size;
+    int retval = 0;
+
+    while (res > 0) {
+        ssize_t stat = ::send(m_sock, (const char *)(m_buf) + (size - res), res, 0);
+        if (stat < 0) {
+            if (errno != EINTR) {
+                retval =  stat;
+                ERR("%s: failed: %s\n", __FUNCTION__, strerror(errno));
+                break;
+            }
+        } else {
+            res -= stat;
+        }
+    }
+    return retval;
+}
+
+const unsigned char *SocketStream::readFully(void *buf, size_t len)
+{
+    const unsigned char* ret = NULL;
+    if (!valid()) return NULL;
+    if (!buf) {
+      return NULL;  // do not allow NULL buf in that implementation
+    }
+    size_t res = len;
+    while (res > 0) {
+        ssize_t stat = ::recv(m_sock, (char *)(buf) + len - res, res, 0);
+        if (stat > 0) {
+            res -= stat;
+            continue;
+        }
+        if (stat == 0 || errno != EINTR) { // client shutdown or error
+            return NULL;
+        }
+    }
+    return (const unsigned char *)buf;
+}
+
+const unsigned char *SocketStream::read( void *buf, size_t *inout_len)
+{
+    if (!valid()) return NULL;
+    if (!buf) {
+      return NULL;  // do not allow NULL buf in that implementation
+    }
+
+    int n;
+    do {
+        n = recv(buf, *inout_len);
+    } while( n < 0 && errno == EINTR );
+
+    if (n > 0) {
+        *inout_len = n;
+        return (const unsigned char *)buf;
+    }
+
+    return NULL;
+}
+
+int SocketStream::recv(void *buf, size_t len)
+{
+    if (!valid()) return int(ERR_INVALID_SOCKET);
+    int res = 0;
+    while(true) {
+        res = ::recv(m_sock, (char *)buf, len, 0);
+        if (res < 0) {
+            if (errno == EINTR) {
+                continue;
+            }
+        }
+        break;
+    }
+    return res;
+}
diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/SocketStream.h b/tools/emulator/opengl/shared/OpenglCodecCommon/SocketStream.h
new file mode 100644
index 0000000..c54dea7
--- /dev/null
+++ b/tools/emulator/opengl/shared/OpenglCodecCommon/SocketStream.h
@@ -0,0 +1,50 @@
+/*
+* 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 __SOCKET_STREAM_H
+#define __SOCKET_STREAM_H
+
+#include <stdlib.h>
+#include "IOStream.h"
+
+class SocketStream : public IOStream {
+public:
+    typedef enum { ERR_INVALID_SOCKET = -1000 } SocketStreamError;
+
+    explicit SocketStream(size_t bufsize = 10000);
+    virtual ~SocketStream();
+
+    virtual int listen(unsigned short port) = 0;
+    virtual SocketStream *accept() = 0;
+    virtual int connect(unsigned short port) = 0;
+
+    virtual void *allocBuffer(size_t minSize);
+    virtual int commitBuffer(size_t size);
+    virtual const unsigned char *readFully(void *buf, size_t len);
+    virtual const unsigned char *read(void *buf, size_t *inout_len);
+
+    bool valid() { return m_sock >= 0; }
+    virtual int recv(void *buf, size_t len);
+
+protected:
+    int            m_sock;
+    size_t         m_bufsize;
+    unsigned char *m_buf;
+
+    SocketStream(int sock, size_t bufSize);
+    int writeFully(const void *buf, size_t len);
+};
+
+#endif /* __SOCKET_STREAM_H */
diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/TcpStream.cpp b/tools/emulator/opengl/shared/OpenglCodecCommon/TcpStream.cpp
index c057ff9..4da2cec 100644
--- a/tools/emulator/opengl/shared/OpenglCodecCommon/TcpStream.cpp
+++ b/tools/emulator/opengl/shared/OpenglCodecCommon/TcpStream.cpp
@@ -29,18 +29,12 @@
 #endif
 
 TcpStream::TcpStream(size_t bufSize) :
-    IOStream(bufSize),
-    m_sock(-1),
-    m_bufsize(bufSize),
-    m_buf(NULL)
+    SocketStream(bufSize)
 {
 }
 
 TcpStream::TcpStream(int sock, size_t bufSize) :
-    IOStream(bufSize),
-    m_sock(sock),
-    m_bufsize(bufSize),
-    m_buf(NULL)
+    SocketStream(sock, bufSize)
 {
     // disable Nagle algorithm to improve bandwidth of small
     // packets which are quite common in our implementation.
@@ -53,34 +47,15 @@
     setsockopt( sock, IPPROTO_TCP, TCP_NODELAY, (const char*)&flag, sizeof(flag) );
 }
 
-TcpStream::~TcpStream()
+int TcpStream::listen(unsigned short port)
 {
-    if (m_sock >= 0) {
-#ifdef _WIN32
-        closesocket(m_sock);
-#else
-        ::close(m_sock);
-#endif
-    }
-    if (m_buf != NULL) {
-        free(m_buf);
-    }
-}
-
-
-int TcpStream::listen(unsigned short port, bool localhost_only)
-{
-    if (localhost_only) {
-        m_sock = socket_loopback_server(port, SOCK_STREAM);
-    } else {
-        m_sock = socket_inaddr_any_server(port, SOCK_STREAM);
-    }
+    m_sock = socket_loopback_server(port, SOCK_STREAM);
     if (!valid()) return int(ERR_INVALID_SOCKET);
 
     return 0;
 }
 
-TcpStream * TcpStream::accept()
+SocketStream * TcpStream::accept()
 {
     int clientSock = -1;
 
@@ -103,120 +78,14 @@
     return clientStream;
 }
 
+int TcpStream::connect(unsigned short port)
+{
+    return connect("127.0.0.1",port);
+}
 
-int TcpStream::connect(const char *hostname, unsigned short port)
+int TcpStream::connect(const char* hostname, unsigned short port)
 {
     m_sock = socket_network_client(hostname, port, SOCK_STREAM);
     if (!valid()) return -1;
     return 0;
 }
-
-void *TcpStream::allocBuffer(size_t minSize)
-{
-    size_t allocSize = (m_bufsize < minSize ? minSize : m_bufsize);
-    if (!m_buf) {
-        m_buf = (unsigned char *)malloc(allocSize);
-    }
-    else if (m_bufsize < allocSize) {
-        unsigned char *p = (unsigned char *)realloc(m_buf, allocSize);
-        if (p != NULL) {
-            m_buf = p;
-            m_bufsize = allocSize;
-        } else {
-            ERR("realloc (%d) failed\n", allocSize);
-            free(m_buf);
-            m_buf = NULL;
-            m_bufsize = 0;
-        }
-    }
-
-    return m_buf;
-};
-
-int TcpStream::commitBuffer(size_t size)
-{
-    return writeFully(m_buf, size);
-}
-
-int TcpStream::writeFully(const void *buf, size_t len)
-{
-    if (!valid()) return -1;
-
-    size_t res = len;
-    int retval = 0;
-
-    while (res > 0) {
-        ssize_t stat = ::send(m_sock, (const char *)(buf) + (len - res), res, 0);
-        if (stat < 0) {
-            if (errno != EINTR) {
-                retval =  stat;
-                ERR("TcpStream::writeFully failed: %s\n", strerror(errno));
-                break;
-            }
-        } else {
-            res -= stat;
-        }
-    }
-    return retval;
-}
-
-const unsigned char *TcpStream::readFully(void *buf, size_t len)
-{
-    if (!valid()) return NULL;
-    if (!buf) {
-      return NULL;  // do not allow NULL buf in that implementation
-    }
-    size_t res = len;
-    while (res > 0) {
-        ssize_t stat = ::recv(m_sock, (char *)(buf) + len - res, res, 0);
-        if (stat == 0) {
-            // client shutdown;
-            return NULL;
-        } else if (stat < 0) {
-            if (errno == EINTR) {
-                continue;
-            } else {
-                return NULL;
-            }
-        } else {
-            res -= stat;
-        }
-    }
-    return (const unsigned char *)buf;
-}
-
-const unsigned char *TcpStream::read( void *buf, size_t *inout_len)
-{
-    if (!valid()) return NULL;
-    if (!buf) {
-      return NULL;  // do not allow NULL buf in that implementation
-    }
-
-    int n;
-    do {
-        n = recv(buf, *inout_len);
-    } while( n < 0 && errno == EINTR );
-
-    if (n > 0) {
-        *inout_len = n;
-        return (const unsigned char *)buf;
-    }
-
-    return NULL;
-}
-
-int TcpStream::recv(void *buf, size_t len)
-{
-    if (!valid()) return int(ERR_INVALID_SOCKET);
-    int res = 0;
-    while(true) {
-        res = ::recv(m_sock, (char *)buf, len, 0);
-        if (res < 0) {
-            if (errno == EINTR) {
-                continue;
-            }
-        }
-        break;
-    }
-    return res;
-}
diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/TcpStream.h b/tools/emulator/opengl/shared/OpenglCodecCommon/TcpStream.h
index 7521843..811a871 100644
--- a/tools/emulator/opengl/shared/OpenglCodecCommon/TcpStream.h
+++ b/tools/emulator/opengl/shared/OpenglCodecCommon/TcpStream.h
@@ -16,35 +16,16 @@
 #ifndef __TCP_STREAM_H
 #define __TCP_STREAM_H
 
-#include <stdlib.h>
-#include "IOStream.h"
+#include "SocketStream.h"
 
-
-class TcpStream : public IOStream {
+class TcpStream : public SocketStream {
 public:
-    typedef enum { ERR_INVALID_SOCKET = -1000 } TcpStreamError;
-
     explicit TcpStream(size_t bufsize = 10000);
-    ~TcpStream();
-    int listen(unsigned short port, bool localhost_only = true);
-    TcpStream *accept();
-    int connect(const char *hostname, unsigned short port);
-
-    virtual void *allocBuffer(size_t minSize);
-    virtual int commitBuffer(size_t size);
-    virtual const unsigned char *readFully( void *buf, size_t len);
-    virtual const unsigned char *read( void *buf, size_t *inout_len);
-
-    bool valid() { return m_sock >= 0; }
-    int recv(void *buf, size_t len);
-
+    virtual int listen(unsigned short port);
+    virtual SocketStream *accept();
+    virtual int connect(unsigned short port);
+    int connect(const char* hostname, unsigned short port);
 private:
-    int writeFully(const void *buf, size_t len);
-
-private:
-    int m_sock;
-    size_t m_bufsize;
-    unsigned char *m_buf;
     TcpStream(int sock, size_t bufSize);
 };
 
diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/UnixStream.cpp b/tools/emulator/opengl/shared/OpenglCodecCommon/UnixStream.cpp
new file mode 100644
index 0000000..8e463a3
--- /dev/null
+++ b/tools/emulator/opengl/shared/OpenglCodecCommon/UnixStream.cpp
@@ -0,0 +1,137 @@
+/*
+* 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.
+*/
+#include "UnixStream.h"
+#include <cutils/sockets.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <sys/un.h>
+#include <sys/stat.h>
+
+/* Not all systems define PATH_MAX, those who don't generally don't
+ * have a limit on the maximum path size, so use a value that is
+ * large enough for our very limited needs.
+ */
+#ifndef PATH_MAX
+#define PATH_MAX   128
+#endif
+
+UnixStream::UnixStream(size_t bufSize) :
+    SocketStream(bufSize)
+{
+}
+
+UnixStream::UnixStream(int sock, size_t bufSize) :
+    SocketStream(sock, bufSize)
+{
+}
+
+/* Initialize a sockaddr_un with the appropriate values corresponding
+ * to a given 'virtual port'. Returns 0 on success, -1 on error.
+ */
+static int
+make_unix_path(char *path, size_t  pathlen, int port_number)
+{
+    char  tmp[PATH_MAX];  // temp directory
+    int   ret = 0;
+
+    // First, create user-specific temp directory if needed
+    const char* user = getenv("USER");
+    if (user != NULL) {
+        struct stat  st;
+        snprintf(tmp, sizeof(tmp), "/tmp/android-%s", user);
+        do {
+            ret = ::lstat(tmp, &st);
+        } while (ret < 0 && errno == EINTR);
+
+        if (ret < 0 && errno == ENOENT) {
+            do {
+                ret = ::mkdir(tmp, 0766);
+            } while (ret < 0 && errno == EINTR);
+            if (ret < 0) {
+                ERR("Could not create temp directory: %s", tmp);
+                user = NULL;  // will fall-back to /tmp
+            }
+        }
+        else if (ret < 0) {
+            user = NULL;  // will fallback to /tmp
+        }
+    }
+
+    if (user == NULL) {  // fallback to /tmp in case of error
+        snprintf(tmp, sizeof(tmp), "/tmp");
+    }
+
+    // Now, initialize it properly
+    snprintf(path, pathlen, "%s/qemu-gles-%d", tmp, port_number);
+    return 0;
+}
+
+
+int UnixStream::listen(unsigned short port)
+{
+    char  path[PATH_MAX];
+
+    if (make_unix_path(path, sizeof(path), port) < 0) {
+        return -1;
+    }
+
+    m_sock = socket_local_server(path, ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
+    if (!valid()) return int(ERR_INVALID_SOCKET);
+
+    return 0;
+}
+
+SocketStream * UnixStream::accept()
+{
+    int clientSock = -1;
+
+    while (true) {
+        struct sockaddr_un addr;
+        socklen_t len = sizeof(addr);
+        clientSock = ::accept(m_sock, (sockaddr *)&addr, &len);
+
+        if (clientSock < 0 && errno == EINTR) {
+            continue;
+        }
+        break;
+    }
+
+    UnixStream *clientStream = NULL;
+
+    if (clientSock >= 0) {
+        clientStream =  new UnixStream(clientSock, m_bufsize);
+    }
+    return clientStream;
+}
+
+int UnixStream::connect(unsigned short port)
+{
+    char  path[PATH_MAX];
+
+    if (make_unix_path(path, sizeof(path), port) < 0)
+        return -1;
+
+    m_sock = socket_local_client(path, ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
+    if (!valid()) return -1;
+
+    return 0;
+}
diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/UnixStream.h b/tools/emulator/opengl/shared/OpenglCodecCommon/UnixStream.h
new file mode 100644
index 0000000..c184b19
--- /dev/null
+++ b/tools/emulator/opengl/shared/OpenglCodecCommon/UnixStream.h
@@ -0,0 +1,31 @@
+/*
+* 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 __UNIX_STREAM_H
+#define __UNIX_STREAM_H
+
+#include "SocketStream.h"
+
+class UnixStream : public SocketStream {
+public:
+    explicit UnixStream(size_t bufsize = 10000);
+    virtual int listen(unsigned short port);
+    virtual SocketStream *accept();
+    virtual int connect(unsigned short port);
+private:
+    UnixStream(int sock, size_t bufSize);
+};
+
+#endif
diff --git a/tools/emulator/opengl/system/OpenglSystemCommon/HostConnection.cpp b/tools/emulator/opengl/system/OpenglSystemCommon/HostConnection.cpp
index c967b4f..2927341 100644
--- a/tools/emulator/opengl/system/OpenglSystemCommon/HostConnection.cpp
+++ b/tools/emulator/opengl/system/OpenglSystemCommon/HostConnection.cpp
@@ -60,22 +60,6 @@
             return NULL;
         }
 
-#if 0
-            TcpStream *stream = new TcpStream(STREAM_BUFFER_SIZE);
-            if (stream) {
-                if (stream->connect("10.0.2.2", STREAM_PORT_NUM) < 0) {
-                    LOGE("Failed to connect to host (TcpStream)!!!\n");
-                    delete stream;
-                    stream = NULL;
-                }
-                else {
-                    con->m_stream = stream;
-                    LOGE("Established TCP connection with HOST\n");
-                }
-            }
-            if (!stream)
-#endif
-
         if (useQemuPipe) {
             QemuPipeStream *stream = new QemuPipeStream(STREAM_BUFFER_SIZE);
             if (!stream) {
@@ -108,11 +92,11 @@
         }
 
         // send zero 'clientFlags' to the host.
-        unsigned int *pClientFlags = 
+        unsigned int *pClientFlags =
                 (unsigned int *)con->m_stream->allocBuffer(sizeof(unsigned int));
         *pClientFlags = 0;
         con->m_stream->commitBuffer(sizeof(unsigned int));
-        
+
         LOGD("HostConnection::get() New Host Connection established %p, tid %d\n", con, gettid());
         tinfo->hostConn = con;
     }
diff --git a/tools/emulator/opengl/tests/ut_renderer/ReadBuffer.cpp b/tools/emulator/opengl/tests/ut_renderer/ReadBuffer.cpp
index 661b4cc..e0073c0 100644
--- a/tools/emulator/opengl/tests/ut_renderer/ReadBuffer.cpp
+++ b/tools/emulator/opengl/tests/ut_renderer/ReadBuffer.cpp
@@ -17,7 +17,7 @@
 #include <string.h>
 #include <assert.h>
 
-ReadBuffer::ReadBuffer(TcpStream *stream, size_t bufsize)
+ReadBuffer::ReadBuffer(SocketStream *stream, size_t bufsize)
 {
     m_size = bufsize;
     m_stream = stream;
diff --git a/tools/emulator/opengl/tests/ut_renderer/ReadBuffer.h b/tools/emulator/opengl/tests/ut_renderer/ReadBuffer.h
index 1b8f6fd..b039b19 100644
--- a/tools/emulator/opengl/tests/ut_renderer/ReadBuffer.h
+++ b/tools/emulator/opengl/tests/ut_renderer/ReadBuffer.h
@@ -16,11 +16,11 @@
 #ifndef _READ_BUFFER_H
 #define _READ_BUFFER_H
 
-#include "TcpStream.h"
+#include "SocketStream.h"
 
 class ReadBuffer {
 public:
-    ReadBuffer(TcpStream *stream, size_t bufSize);
+    ReadBuffer(SocketStream *stream, size_t bufSize);
     ~ReadBuffer();
     int getData(); // get fresh data from the stream
     unsigned char *buf() { return m_readPtr; } // return the next read location
@@ -31,6 +31,6 @@
     unsigned char *m_readPtr;
     size_t m_size;
     size_t m_validData;
-    TcpStream *m_stream;
+    SocketStream *m_stream;
 };
 #endif
diff --git a/tools/emulator/opengl/tests/ut_renderer/RenderingThread.cpp b/tools/emulator/opengl/tests/ut_renderer/RenderingThread.cpp
index ddd8405..70eee20 100644
--- a/tools/emulator/opengl/tests/ut_renderer/RenderingThread.cpp
+++ b/tools/emulator/opengl/tests/ut_renderer/RenderingThread.cpp
@@ -255,7 +255,7 @@
 }
 
 
-RenderingThread::RenderingThread(TcpStream *stream) :
+RenderingThread::RenderingThread(SocketStream *stream) :
     m_stream(stream),
     m_currentContext(NULL)
 {
diff --git a/tools/emulator/opengl/tests/ut_renderer/RenderingThread.h b/tools/emulator/opengl/tests/ut_renderer/RenderingThread.h
index 549d4af..0b4ebe6 100644
--- a/tools/emulator/opengl/tests/ut_renderer/RenderingThread.h
+++ b/tools/emulator/opengl/tests/ut_renderer/RenderingThread.h
@@ -16,7 +16,7 @@
 #ifndef _RENDERING_THREAD_H_
 #define _RENDERING_THREAD_H_
 
-#include "TcpStream.h"
+#include "SocketStream.h"
 #include "GLDecoder.h"
 #include "GL2Decoder.h"
 #include "ut_rendercontrol_dec.h"
@@ -38,7 +38,7 @@
 
 class RenderingThread {
 public:
-    RenderingThread(TcpStream *stream);
+    RenderingThread(SocketStream *stream);
     int start();
     void *thread();
     RendererContext *currentContext() { return m_currentContext; }
@@ -54,7 +54,7 @@
     ut_rendercontrol_decoder_context_t m_utDec;
     GL2Decoder m_gl2Dec;
 
-    TcpStream   *m_stream;
+    SocketStream   *m_stream;
     pthread_t m_thread;
     RendererContext * m_currentContext;
 
diff --git a/tools/emulator/opengl/tests/ut_renderer/ut_renderer.cpp b/tools/emulator/opengl/tests/ut_renderer/ut_renderer.cpp
index 2137a82..f2b2bc3 100644
--- a/tools/emulator/opengl/tests/ut_renderer/ut_renderer.cpp
+++ b/tools/emulator/opengl/tests/ut_renderer/ut_renderer.cpp
@@ -20,22 +20,33 @@
 #include "codec_defs.h"
 #include "RenderingThread.h"
 #include "TcpStream.h"
+#ifndef _WIN32
+#include "UnixStream.h"
+#endif
 
 
 int main(int argc, char **argv)
 {
-
-    TcpStream *socket = new TcpStream;
+#ifdef _WIN32
+    TcpStream *socket = new TcpStream();
 
     if (socket->listen(CODEC_SERVER_PORT) < 0) {
         perror("listen");
         exit(1);
     }
+#else
+    UnixStream *socket = new UnixStream();
+
+    if (socket->listen(CODEC_SERVER_PORT) < 0) {
+        perror("listen");
+        exit(1);
+    }
+#endif
 
     printf("waiting for client connection on port: %d\n", CODEC_SERVER_PORT);
     while (1) {
         // wait for client connection
-        TcpStream  *glStream = socket->accept();
+        SocketStream  *glStream = socket->accept();
         if (glStream == NULL) {
             printf("failed to get client.. aborting\n");
             exit(3);