blob: 31bc20b03501b12d82c92666823c83a6cea85616 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 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
17package android.net;
18
Jeff Sharkey065b2992012-08-05 14:16:48 -070019import java.io.Closeable;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import java.io.FileDescriptor;
21import java.io.IOException;
22import java.io.InputStream;
23import java.io.OutputStream;
24import java.net.SocketOptions;
25
26/**
27 * Creates a (non-server) socket in the UNIX-domain namespace. The interface
28 * here is not entirely unlike that of java.net.Socket
29 */
Jeff Sharkey065b2992012-08-05 14:16:48 -070030public class LocalSocket implements Closeable {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031
32 private LocalSocketImpl impl;
33 private volatile boolean implCreated;
34 private LocalSocketAddress localAddress;
35 private boolean isBound;
36 private boolean isConnected;
Mike Lockwoode7d309a2013-07-16 11:36:22 -070037 private final int sockType;
38
39 /** unknown socket type (used for constructor with existing file descriptor) */
40 /* package */ static final int SOCKET_UNKNOWN = 0;
41 /** Datagram socket type */
42 public static final int SOCKET_DGRAM = 1;
43 /** Stream socket type */
44 public static final int SOCKET_STREAM = 2;
45 /** Sequential packet socket type */
46 public static final int SOCKET_SEQPACKET = 3;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047
48 /**
49 * Creates a AF_LOCAL/UNIX domain stream socket.
50 */
51 public LocalSocket() {
Mike Lockwoode7d309a2013-07-16 11:36:22 -070052 this(SOCKET_STREAM);
53 }
54
55 /**
56 * Creates a AF_LOCAL/UNIX domain stream socket with given socket type
57 *
58 * @param sockType either {@link #SOCKET_DGRAM}, {@link #SOCKET_STREAM}
59 * or {@link #SOCKET_SEQPACKET}
60 */
61 public LocalSocket(int sockType) {
62 this(new LocalSocketImpl(), sockType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063 isBound = false;
64 isConnected = false;
65 }
Mike Lockwoode7d309a2013-07-16 11:36:22 -070066
zzy3b147b72012-04-03 19:48:32 -070067 /**
68 * Creates a AF_LOCAL/UNIX domain stream socket with FileDescriptor.
69 * @hide
70 */
71 public LocalSocket(FileDescriptor fd) throws IOException {
Mike Lockwoode7d309a2013-07-16 11:36:22 -070072 this(new LocalSocketImpl(fd), SOCKET_UNKNOWN);
zzy3b147b72012-04-03 19:48:32 -070073 isBound = true;
74 isConnected = true;
75 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076
77 /**
78 * for use with AndroidServerSocket
79 * @param impl a SocketImpl
80 */
Mike Lockwoode7d309a2013-07-16 11:36:22 -070081 /*package*/ LocalSocket(LocalSocketImpl impl, int sockType) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082 this.impl = impl;
Mike Lockwoode7d309a2013-07-16 11:36:22 -070083 this.sockType = sockType;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084 this.isConnected = false;
85 this.isBound = false;
86 }
87
88 /** {@inheritDoc} */
89 @Override
90 public String toString() {
91 return super.toString() + " impl:" + impl;
92 }
93
94 /**
95 * It's difficult to discern from the spec when impl.create() should be
96 * called, but it seems like a reasonable rule is "as soon as possible,
97 * but not in a context where IOException cannot be thrown"
98 *
99 * @throws IOException from SocketImpl.create()
100 */
101 private void implCreateIfNeeded() throws IOException {
102 if (!implCreated) {
103 synchronized (this) {
104 if (!implCreated) {
Jesse Wilsonc59a6622010-09-21 10:26:57 -0700105 try {
Mike Lockwoode7d309a2013-07-16 11:36:22 -0700106 impl.create(sockType);
Jesse Wilsonc59a6622010-09-21 10:26:57 -0700107 } finally {
108 implCreated = true;
109 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110 }
111 }
112 }
113 }
114
115 /**
116 * Connects this socket to an endpoint. May only be called on an instance
117 * that has not yet been connected.
118 *
119 * @param endpoint endpoint address
120 * @throws IOException if socket is in invalid state or the address does
121 * not exist.
122 */
123 public void connect(LocalSocketAddress endpoint) throws IOException {
124 synchronized (this) {
125 if (isConnected) {
126 throw new IOException("already connected");
127 }
128
129 implCreateIfNeeded();
130 impl.connect(endpoint, 0);
131 isConnected = true;
132 isBound = true;
133 }
134 }
135
136 /**
137 * Binds this socket to an endpoint name. May only be called on an instance
138 * that has not yet been bound.
139 *
140 * @param bindpoint endpoint address
141 * @throws IOException
142 */
143 public void bind(LocalSocketAddress bindpoint) throws IOException {
144 implCreateIfNeeded();
145
146 synchronized (this) {
147 if (isBound) {
148 throw new IOException("already bound");
149 }
150
151 localAddress = bindpoint;
152 impl.bind(localAddress);
153 isBound = true;
154 }
155 }
156
157 /**
158 * Retrieves the name that this socket is bound to, if any.
159 *
160 * @return Local address or null if anonymous
161 */
162 public LocalSocketAddress getLocalSocketAddress() {
163 return localAddress;
164 }
165
166 /**
167 * Retrieves the input stream for this instance.
168 *
169 * @return input stream
170 * @throws IOException if socket has been closed or cannot be created.
171 */
172 public InputStream getInputStream() throws IOException {
173 implCreateIfNeeded();
174 return impl.getInputStream();
175 }
176
177 /**
178 * Retrieves the output stream for this instance.
179 *
180 * @return output stream
181 * @throws IOException if socket has been closed or cannot be created.
182 */
183 public OutputStream getOutputStream() throws IOException {
184 implCreateIfNeeded();
185 return impl.getOutputStream();
186 }
187
188 /**
189 * Closes the socket.
190 *
191 * @throws IOException
192 */
Jeff Sharkey065b2992012-08-05 14:16:48 -0700193 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800194 public void close() throws IOException {
195 implCreateIfNeeded();
196 impl.close();
197 }
198
199 /**
200 * Shuts down the input side of the socket.
201 *
202 * @throws IOException
203 */
204 public void shutdownInput() throws IOException {
205 implCreateIfNeeded();
206 impl.shutdownInput();
207 }
208
209 /**
210 * Shuts down the output side of the socket.
211 *
212 * @throws IOException
213 */
214 public void shutdownOutput() throws IOException {
215 implCreateIfNeeded();
216 impl.shutdownOutput();
217 }
218
219 public void setReceiveBufferSize(int size) throws IOException {
220 impl.setOption(SocketOptions.SO_RCVBUF, Integer.valueOf(size));
221 }
222
223 public int getReceiveBufferSize() throws IOException {
224 return ((Integer) impl.getOption(SocketOptions.SO_RCVBUF)).intValue();
225 }
226
227 public void setSoTimeout(int n) throws IOException {
228 impl.setOption(SocketOptions.SO_TIMEOUT, Integer.valueOf(n));
229 }
230
231 public int getSoTimeout() throws IOException {
232 return ((Integer) impl.getOption(SocketOptions.SO_TIMEOUT)).intValue();
233 }
234
235 public void setSendBufferSize(int n) throws IOException {
236 impl.setOption(SocketOptions.SO_SNDBUF, Integer.valueOf(n));
237 }
238
239 public int getSendBufferSize() throws IOException {
240 return ((Integer) impl.getOption(SocketOptions.SO_SNDBUF)).intValue();
241 }
242
243 //???SEC
244 public LocalSocketAddress getRemoteSocketAddress() {
245 throw new UnsupportedOperationException();
246 }
247
248 //???SEC
249 public synchronized boolean isConnected() {
250 return isConnected;
251 }
252
253 //???SEC
254 public boolean isClosed() {
255 throw new UnsupportedOperationException();
256 }
257
258 //???SEC
259 public synchronized boolean isBound() {
260 return isBound;
261 }
262
263 //???SEC
264 public boolean isOutputShutdown() {
265 throw new UnsupportedOperationException();
266 }
267
268 //???SEC
269 public boolean isInputShutdown() {
270 throw new UnsupportedOperationException();
271 }
272
273 //???SEC
274 public void connect(LocalSocketAddress endpoint, int timeout)
275 throws IOException {
276 throw new UnsupportedOperationException();
277 }
278
279 /**
280 * Enqueues a set of file descriptors to send to the peer. The queue
281 * is one deep. The file descriptors will be sent with the next write
282 * of normal data, and will be delivered in a single ancillary message.
283 * See "man 7 unix" SCM_RIGHTS on a desktop Linux machine.
284 *
285 * @param fds non-null; file descriptors to send.
286 */
287 public void setFileDescriptorsForSend(FileDescriptor[] fds) {
288 impl.setFileDescriptorsForSend(fds);
289 }
290
291 /**
292 * Retrieves a set of file descriptors that a peer has sent through
293 * an ancillary message. This method retrieves the most recent set sent,
294 * and then returns null until a new set arrives.
295 * File descriptors may only be passed along with regular data, so this
296 * method can only return a non-null after a read operation.
297 *
298 * @return null or file descriptor array
299 * @throws IOException
300 */
301 public FileDescriptor[] getAncillaryFileDescriptors() throws IOException {
302 return impl.getAncillaryFileDescriptors();
303 }
304
305 /**
306 * Retrieves the credentials of this socket's peer. Only valid on
307 * connected sockets.
308 *
309 * @return non-null; peer credentials
310 * @throws IOException
311 */
312 public Credentials getPeerCredentials() throws IOException {
313 return impl.getPeerCredentials();
314 }
315
316 /**
317 * Returns file descriptor or null if not yet open/already closed
318 *
319 * @return fd or null
320 */
321 public FileDescriptor getFileDescriptor() {
322 return impl.getFileDescriptor();
323 }
324}