Roll NDK to pick std::deque patch.
[android_tools.git] / sdk / tools / apps / SdkController / src / com / android / tools / sdkcontroller / lib / Socket.java
blob08e6b2813ed71042f259bc2b08105b6c77c92ff0
1 /*
2 * Copyright (C) 2012 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
6 * the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations under
14 * the License.
17 package com.android.tools.sdkcontroller.lib;
19 import android.net.LocalSocket;
20 import android.util.Log;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.nio.ByteOrder;
25 import java.nio.channels.ClosedChannelException;
27 /**
28 * Encapsulates a connection with the emulator over a UNIX-domain socket.
30 public class Socket {
31 /** UNIX-domain socket connected with the emulator. */
32 private LocalSocket mSocket = null;
33 /** Channel name for the connection established via this socket. */
34 private String mChannelName;
35 /** Endianness of data transferred in this connection. */
36 private ByteOrder mEndian;
38 /** Tag for message logging. */
39 private static final String TAG = "SdkControllerSocket";
40 /** Controls debug log. */
41 private static boolean DEBUG = false;
43 /**
44 * Constructs Socket instance.
46 * @param socket Socket connection with the emulator.
47 * @param name Channel port name for this connection.
48 * @param endian Endianness of data transferred in this connection.
50 public Socket(LocalSocket socket, String name, ByteOrder endian) {
51 mSocket = socket;
52 mChannelName = name;
53 mEndian = endian;
54 if (DEBUG) Log.d(TAG, "Socket is constructed for " + mChannelName);
57 /**
58 * Gets connection status of this socket.
60 * @return true if socket is connected, or false if socket is not connected.
62 public boolean isConnected() {
63 return mSocket != null;
66 /**
67 * Gets channel name for this socket.
69 * @return Channel name for this socket.
71 public String getChannelName() {
72 return mChannelName;
75 /**
76 * Gets endianness of data transferred via this socket.
78 * @return Endianness of data transferred via this socket.
80 public ByteOrder getEndian() {
81 return mEndian;
84 /**
85 * Sends data to the socket.
87 * @param data Data to send. Data size is defined by the length of the
88 * array.
89 * @throws IOException
91 public void send(byte[] data) throws IOException {
92 // Use local copy of the socket, ensuring it's not going to NULL while
93 // we're working with it. If it gets closed, while we're in the middle
94 // of data transfer - it's OK, since it will produce an exception, and
95 // the caller will gracefully handle it.
97 // Same technique is used everywhere in this class where mSocket member
98 // is touched.
99 LocalSocket socket = mSocket;
100 if (socket == null) {
101 Logw("'send' request on closed Socket " + mChannelName);
102 throw new ClosedChannelException();
104 socket.getOutputStream().write(data);
108 * Sends data to the socket.
110 * @param data Data to send.
111 * @param offset The start position in data from where to get bytes.
112 * @param len The number of bytes from data to write to this socket.
113 * @throws IOException
115 public void send(byte[] data, int offset, int len) throws IOException {
116 LocalSocket socket = mSocket;
117 if (socket == null) {
118 Logw("'send' request on closed Socket " + mChannelName);
119 throw new ClosedChannelException();
121 socket.getOutputStream().write(data, offset, len);
125 * Receives data from the socket.
127 * @param socket Socket from where to receive data.
128 * @param data Array where to save received data.
129 * @param len Number of bytes to receive.
130 * @throws IOException
132 public static void receive(LocalSocket socket, byte[] data, int len) throws IOException {
133 final InputStream is = socket.getInputStream();
134 int received = 0;
135 while (received != len) {
136 final int chunk = is.read(data, received, len - received);
137 if (chunk < 0) {
138 throw new IOException(
139 "I/O failure while receiving SDK controller data from socket.");
141 received += chunk;
146 * Receives data from the socket.
148 * @param data Array where to save received data.
149 * @param len Number of bytes to receive.
150 * @throws IOException
152 public void receive(byte[] data, int len) throws IOException {
153 LocalSocket socket = mSocket;
154 if (socket == null) {
155 Logw("'receive' request on closed Socket " + mChannelName);
156 throw new ClosedChannelException();
158 receive(socket, data, len);
162 * Receives data from the socket.
164 * @param data Array where to save received data. Data size is defined by
165 * the size of the array.
166 * @throws IOException
168 public void receive(byte[] data) throws IOException {
169 receive(data, data.length);
173 * Closes the socket.
175 * @return true if socket has been closed in this call, or false if it had
176 * been already closed when this method has been called.
178 public boolean close() {
179 // This is the only place in this class where we will null the socket
180 // object. Since this method can be called concurrently from different
181 // threads, lets do this under the lock.
182 LocalSocket socket;
183 synchronized (this) {
184 socket = mSocket;
185 mSocket = null;
187 if (socket != null) {
188 try {
189 // Force all I/O to stop before closing the socket.
190 socket.shutdownInput();
191 socket.shutdownOutput();
192 socket.close();
193 if (DEBUG) Log.d(TAG, "Socket is closed for " + mChannelName);
194 return true;
195 } catch (IOException e) {
196 Loge("Exception " + e + " while closing Socket for " + mChannelName);
199 return false;
202 /***************************************************************************
203 * Logging wrappers
204 **************************************************************************/
206 private void Loge(String log) {
207 Log.e(TAG, log);
210 private void Logw(String log) {
211 Log.w(TAG, log);