Merge "gltrace: Allow receiving commands of length > 4" into jb-dev
diff --git a/opengl/libs/GLES_trace/src/gltrace_eglapi.cpp b/opengl/libs/GLES_trace/src/gltrace_eglapi.cpp
index c442153..9698bf9 100644
--- a/opengl/libs/GLES_trace/src/gltrace_eglapi.cpp
+++ b/opengl/libs/GLES_trace/src/gltrace_eglapi.cpp
@@ -44,9 +44,14 @@
     GLTraceState *state = (GLTraceState *)arg;
     TCPStream *stream = state->getStream();
 
-    // Currently, there are very few user configurable settings.
-    // As a result, they can be encoded in a single integer.
-    int cmd;
+    // The control stream always receives an integer size of the
+    // command buffer, followed by the actual command buffer.
+    uint32_t cmdSize;
+
+    // Command Buffer
+    void *cmdBuf = NULL;
+    uint32_t cmdBufSize = 0;
+
     enum TraceSettingsMasks {
         READ_FB_ON_EGLSWAP_MASK = 1 << 0,
         READ_FB_ON_GLDRAW_MASK = 1 << 1,
@@ -54,12 +59,33 @@
     };
 
     while (true) {
-        int n = stream->receive(&cmd, 4);
-        if (n != 4) {
+        // read command size
+        if (stream->receive(&cmdSize, sizeof(uint32_t)) < 0) {
+            break;
+        }
+        cmdSize = ntohl(cmdSize);
+
+        // ensure command buffer is of required size
+        if (cmdBufSize < cmdSize) {
+            free(cmdBuf);
+            cmdBufSize = cmdSize;
+            cmdBuf = malloc(cmdSize);
+            if (cmdBuf == NULL)
+                break;
+        }
+
+        // receive the command
+        if (stream->receive(cmdBuf, cmdSize) < 0) {
             break;
         }
 
-        cmd = ntohl(cmd);
+        if (cmdSize != sizeof(uint32_t)) {
+            // Currently, we only support commands that are a single integer,
+            // so we skip all other commands
+            continue;
+        }
+
+        uint32_t cmd = ntohl(*(uint32_t*)cmdBuf);
 
         bool collectFbOnEglSwap = (cmd & READ_FB_ON_EGLSWAP_MASK) != 0;
         bool collectFbOnGlDraw = (cmd & READ_FB_ON_GLDRAW_MASK) != 0;
@@ -73,6 +99,9 @@
             collectFbOnEglSwap, collectFbOnGlDraw, collectTextureData);
     }
 
+    ALOGE("Stopping OpenGL Trace Command Receiver\n");
+
+    free(cmdBuf);
     return NULL;
 }
 
diff --git a/opengl/libs/GLES_trace/src/gltrace_transport.cpp b/opengl/libs/GLES_trace/src/gltrace_transport.cpp
index 157bd24..2996d32 100644
--- a/opengl/libs/GLES_trace/src/gltrace_transport.cpp
+++ b/opengl/libs/GLES_trace/src/gltrace_transport.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <errno.h>
 #include <stdlib.h>
 #include <unistd.h>
 
@@ -123,7 +124,18 @@
         return -1;
     }
 
-    return read(mSocket, data, len);
+    size_t totalRead = 0;
+    while (totalRead < len) {
+        int n = read(mSocket, (uint8_t*)data + totalRead, len - totalRead);
+        if (n < 0) {
+            ALOGE("Error receiving data from stream: %d", errno);
+            return -1;
+        }
+
+        totalRead += n;
+    }
+
+    return 0;
 }
 
 BufferedOutputStream::BufferedOutputStream(TCPStream *stream, size_t bufferSize) {
diff --git a/opengl/libs/GLES_trace/src/gltrace_transport.h b/opengl/libs/GLES_trace/src/gltrace_transport.h
index 3665035..9cf5b45 100644
--- a/opengl/libs/GLES_trace/src/gltrace_transport.h
+++ b/opengl/libs/GLES_trace/src/gltrace_transport.h
@@ -42,8 +42,11 @@
     /** Send @data of size @len to host. . Returns -1 on error, 0 on success. */
     int send(void *data, size_t len);
 
-    /** Receive data into @buf from the remote end. This is a blocking call. */
-    int receive(void *buf, size_t size);
+    /**
+     * Receive @len bytes of data into @buf from the remote end. This is a blocking call.
+     * Returns -1 on failure, 0 on success.
+     */
+    int receive(void *buf, size_t len);
 };
 
 /**