gltrace_transport.cpp revision 93a826f78f6313db791e6fc880439189897651b3
1/* 2 * Copyright 2011, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <stdlib.h> 18#include <unistd.h> 19 20#include <sys/socket.h> 21#include <netinet/in.h> 22#include <arpa/inet.h> 23 24#include <cutils/log.h> 25 26#include "gltrace_transport.h" 27 28namespace android { 29namespace gltrace { 30 31int acceptClientConnection(int serverPort) { 32 int serverSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); 33 if (serverSocket < 0) { 34 LOGE("Error (%d) while creating socket. Check if app has network permissions.", 35 serverSocket); 36 return -1; 37 } 38 39 struct sockaddr_in server, client; 40 41 server.sin_family = AF_INET; 42 server.sin_addr.s_addr = htonl(INADDR_ANY); 43 server.sin_port = htons(serverPort); 44 45 socklen_t sockaddr_len = sizeof(sockaddr_in); 46 if (bind(serverSocket, (struct sockaddr *) &server, sizeof(server)) < 0) { 47 close(serverSocket); 48 LOGE("Failed to bind the server socket"); 49 return -1; 50 } 51 52 if (listen(serverSocket, 1) < 0) { 53 close(serverSocket); 54 LOGE("Failed to listen on server socket"); 55 return -1; 56 } 57 58 ALOGD("gltrace::waitForClientConnection: server listening @ port %d", serverPort); 59 60 int clientSocket = accept(serverSocket, (struct sockaddr *)&client, &sockaddr_len); 61 if (clientSocket < 0) { 62 close(serverSocket); 63 LOGE("Failed to accept client connection"); 64 return -1; 65 } 66 67 ALOGD("gltrace::waitForClientConnection: client connected: %s", inet_ntoa(client.sin_addr)); 68 69 // do not accept any more incoming connections 70 close(serverSocket); 71 72 return clientSocket; 73} 74 75TCPStream::TCPStream(int socket) { 76 mSocket = socket; 77 pthread_mutex_init(&mSocketWriteMutex, NULL); 78} 79 80TCPStream::~TCPStream() { 81 pthread_mutex_destroy(&mSocketWriteMutex); 82} 83 84void TCPStream::closeStream() { 85 if (mSocket > 0) { 86 close(mSocket); 87 mSocket = 0; 88 } 89} 90 91int TCPStream::send(void *buf, size_t len) { 92 if (mSocket <= 0) { 93 return -1; 94 } 95 96 pthread_mutex_lock(&mSocketWriteMutex); 97 int n = write(mSocket, buf, len); 98 pthread_mutex_unlock(&mSocketWriteMutex); 99 100 return n; 101} 102 103int TCPStream::receive(void *data, size_t len) { 104 if (mSocket <= 0) { 105 return -1; 106 } 107 108 return read(mSocket, data, len); 109} 110 111BufferedOutputStream::BufferedOutputStream(TCPStream *stream, size_t bufferSize) { 112 mStream = stream; 113 114 mBufferSize = bufferSize; 115 mStringBuffer = ""; 116 mStringBuffer.reserve(bufferSize); 117} 118 119int BufferedOutputStream::flush() { 120 if (mStringBuffer.size() == 0) { 121 return 0; 122 } 123 124 int n = mStream->send((void *)mStringBuffer.data(), mStringBuffer.size()); 125 mStringBuffer.clear(); 126 return n; 127} 128 129void BufferedOutputStream::enqueueMessage(GLMessage *msg) { 130 const uint32_t len = msg->ByteSize(); 131 132 mStringBuffer.append((const char *)&len, sizeof(len)); // append header 133 msg->AppendToString(&mStringBuffer); // append message 134} 135 136int BufferedOutputStream::send(GLMessage *msg) { 137 enqueueMessage(msg); 138 139 if (mStringBuffer.size() > mBufferSize) { 140 return flush(); 141 } 142 143 return 0; 144} 145 146}; // namespace gltrace 147}; // namespace android 148