Socket.java revision 8cc54e9f098c4f299d2b88bb2b9110ce44354ed7
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.net;
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException;
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.InputStream;
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.OutputStream;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.SocketChannel;
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.AccessController;
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.net.NetUtil;
26f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilsonimport org.apache.harmony.luni.net.PlainSocketImpl;
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.platform.Platform;
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.util.Msg;
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.util.PriviAction;
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Provides a client-side TCP socket.
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class Socket {
358cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    private static SocketImplFactory factory;
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
378cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    final SocketImpl impl;
388cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    private final Proxy proxy;
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private volatile boolean isCreated = false;
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean isBound = false;
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean isConnected = false;
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean isClosed = false;
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean isInputShutdown = false;
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean isOutputShutdown = false;
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
478cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    private InetAddress localAddress = Inet4Address.ANY;
488cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static class ConnectLock {
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
528cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    private final Object connectLock = new ConnectLock();
531f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new unconnected socket. When a SocketImplFactory is defined it
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * creates the internal socket implementation, otherwise the default socket
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * implementation will be used for this socket.
58f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketImplFactory
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketImpl
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Socket() {
638cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        this.impl = factory != null ? factory.createSocketImpl() : new PlainSocketImpl();
648cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        this.proxy = null;
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new unconnected socket using the given proxy type. When a
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code SocketImplFactory} is defined it creates the internal socket
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * implementation, otherwise the default socket implementation will be used
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * for this socket.
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Example that will create a socket connection through a {@code SOCKS}
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * proxy server: <br>
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code Socket sock = new Socket(new Proxy(Proxy.Type.SOCKS, new
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * InetSocketAddress("test.domain.org", 2130)));}
77f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param proxy
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the specified proxy for this socket.
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the argument {@code proxy} is {@code null} or of an
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             invalid type.
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SecurityException
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a security manager exists and it denies the permission to
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             connect to the given proxy.
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketImplFactory
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketImpl
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Socket(Proxy proxy) {
908cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        this.proxy = proxy;
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (null == proxy || Proxy.Type.HTTP == proxy.type()) {
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // KA023=Proxy is null or invalid type
93f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            throw new IllegalArgumentException(Msg.getString("KA023"));
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        InetSocketAddress address = (InetSocketAddress) proxy.address();
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (null != address) {
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            InetAddress addr = address.getAddress();
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            String host;
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (null != addr) {
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                host = addr.getHostAddress();
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                host = address.getHostName();
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int port = address.getPort();
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            checkConnectPermission(host, port);
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1078cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        this.impl = factory != null ? factory.createSocketImpl() : new PlainSocketImpl(proxy);
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1101f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti    // BEGIN android-added
1111f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti    /**
1121f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * Tries to connect a socket to all IP addresses of the given hostname.
1131f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *
1141f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * @param dstName
1151f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *            the target host name or IP address to connect to.
1161f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * @param dstPort
1171f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *            the port on the target host to connect to.
1181f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * @param localAddress
1191f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *            the address on the local host to bind to.
1201f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * @param localPort
1211f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *            the port on the local host to bind to.
1221f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * @param streaming
1231f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *            if {@code true} a streaming socket is returned, a datagram
1241f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *            socket otherwise.
1251f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * @throws UnknownHostException
1261f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *             if the host name could not be resolved into an IP address.
1271f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * @throws IOException
1281f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *             if an error occurs while creating the socket.
1291f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * @throws SecurityException
1301f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *             if a security manager exists and it denies the permission to
1311f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *             connect to the given address and port.
1321f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     */
1331f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti    private void tryAllAddresses(String dstName, int dstPort, InetAddress
1341f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti            localAddress, int localPort, boolean streaming) throws IOException {
1351f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        InetAddress[] dstAddresses = InetAddress.getAllByName(dstName);
1361f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        // Loop through all the destination addresses except the last, trying to
1371f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        // connect to each one and ignoring errors. There must be at least one
1381f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        // address, or getAllByName would have thrown UnknownHostException.
1391f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        InetAddress dstAddress;
1401f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        for (int i = 0; i < dstAddresses.length - 1; i++) {
1411f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti            dstAddress = dstAddresses[i];
1421f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti            try {
1431f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti                checkDestination(dstAddress, dstPort);
1448cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes                startupSocket(dstAddress, dstPort, localAddress, localPort, streaming);
1451f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti                return;
1468cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes            } catch (SecurityException e1) {
1478cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes            } catch (IOException e2) {
1481f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti            }
1491f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        }
1501f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti
1511f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        // Now try to connect to the last address in the array, handing back to
1521f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        // the caller any exceptions that are thrown.
1531f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        dstAddress = dstAddresses[dstAddresses.length - 1];
1541f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        checkDestination(dstAddress, dstPort);
1551f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        startupSocket(dstAddress, dstPort, localAddress, localPort, streaming);
1561f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti    }
1571f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti    // END android-added
1581f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new streaming socket connected to the target host specified by
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the parameters {@code dstName} and {@code dstPort}. The socket is bound
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * to any available port on the local host.
1631f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * <p><strong>Implementation note:</strong> this implementation tries each
1641f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * IP address for the given hostname until it either connects successfully
1651f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * or it exhausts the set. It will try both IPv4 and IPv6 addresses in the
1664c5cbf2953ada194c4dc9d7b387615b1c6fe3e63Elliott Hughes     * order specified by the system property {@code "java.net.preferIPv6Addresses"}.
167f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstName
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the target host name or IP address to connect to.
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstPort
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the target host to connect to.
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws UnknownHostException
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the host name could not be resolved into an IP address.
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the socket.
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SecurityException
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a security manager exists and it denies the permission to
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             connect to the given address and port.
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1808cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    public Socket(String dstName, int dstPort) throws UnknownHostException, IOException {
1811f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        this(dstName, dstPort, null, 0);
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new streaming socket connected to the target host specified by
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the parameters {@code dstName} and {@code dstPort}. On the local endpoint
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the socket is bound to the given address {@code localAddress} on port
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code localPort}.
189f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * If {@code host} is {@code null} a loopback address is used to connect to.
1911f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * <p><strong>Implementation note:</strong> this implementation tries each
1921f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * IP address for the given hostname until it either connects successfully
1931f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * or it exhausts the set. It will try both IPv4 and IPv6 addresses in the
1944c5cbf2953ada194c4dc9d7b387615b1c6fe3e63Elliott Hughes     * order specified by the system property {@code "java.net.preferIPv6Addresses"}.
195f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstName
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the target host name or IP address to connect to.
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstPort
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the target host to connect to.
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param localAddress
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the address on the local host to bind to.
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param localPort
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the local host to bind to.
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws UnknownHostException
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the host name could not be resolved into an IP address.
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the socket.
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SecurityException
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a security manager exists and it denies the permission to
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             connect to the given address and port.
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2128cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    public Socket(String dstName, int dstPort, InetAddress localAddress, int localPort) throws IOException {
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this();
2141f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        tryAllAddresses(dstName, dstPort, localAddress, localPort, true);
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new streaming or datagram socket connected to the target host
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * specified by the parameters {@code hostName} and {@code port}. The socket
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * is bound to any available port on the local host.
2211f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * <p><strong>Implementation note:</strong> this implementation tries each
2221f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * IP address for the given hostname until it either connects successfully
2231f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * or it exhausts the set. It will try both IPv4 and IPv6 addresses in the
2244c5cbf2953ada194c4dc9d7b387615b1c6fe3e63Elliott Hughes     * order specified by the system property {@code "java.net.preferIPv6Addresses"}.
225f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param hostName
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the target host name or IP address to connect to.
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param port
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the target host to connect to.
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param streaming
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            if {@code true} a streaming socket is returned, a datagram
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            socket otherwise.
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws UnknownHostException
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the host name could not be resolved into an IP address.
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the socket.
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SecurityException
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a security manager exists and it denies the permission to
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             connect to the given address and port.
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @deprecated Use {@code Socket(String, int)} instead of this for streaming
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             sockets or an appropriate constructor of {@code
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             DatagramSocket} for UDP transport.
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Deprecated
2458cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    public Socket(String hostName, int port, boolean streaming) throws IOException {
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this();
2471f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        tryAllAddresses(hostName, port, null, 0, streaming);
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new streaming socket connected to the target host specified by
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the parameters {@code dstAddress} and {@code dstPort}. The socket is
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * bound to any available port on the local host.
254f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstAddress
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the target host address to connect to.
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstPort
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the target host to connect to.
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the socket.
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SecurityException
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a security manager exists and it denies the permission to
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             connect to the given address and port.
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Socket(InetAddress dstAddress, int dstPort) throws IOException {
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this();
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkDestination(dstAddress, dstPort);
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        startupSocket(dstAddress, dstPort, null, 0, true);
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new streaming socket connected to the target host specified by
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the parameters {@code dstAddress} and {@code dstPort}. On the local
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * endpoint the socket is bound to the given address {@code localAddress} on
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * port {@code localPort}.
276f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstAddress
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the target host address to connect to.
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstPort
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the target host to connect to.
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param localAddress
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the address on the local host to bind to.
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param localPort
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the local host to bind to.
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the socket.
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SecurityException
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a security manager exists and it denies the permission to
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             connect to the given address and port.
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Socket(InetAddress dstAddress, int dstPort,
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            InetAddress localAddress, int localPort) throws IOException {
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this();
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkDestination(dstAddress, dstPort);
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        startupSocket(dstAddress, dstPort, localAddress, localPort, true);
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new streaming or datagram socket connected to the target host
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * specified by the parameters {@code addr} and {@code port}. The socket is
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * bound to any available port on the local host.
302f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param addr
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the Internet address to connect to.
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param port
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the target host to connect to.
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param streaming
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            if {@code true} a streaming socket is returned, a datagram
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            socket otherwise.
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the socket.
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SecurityException
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a security manager exists and it denies the permission to
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             connect to the given address and port.
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @deprecated Use {@code Socket(InetAddress, int)} instead of this for
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             streaming sockets or an appropriate constructor of {@code
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             DatagramSocket} for UDP transport.
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Deprecated
3208cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    public Socket(InetAddress addr, int port, boolean streaming) throws IOException {
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this();
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkDestination(addr, port);
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        startupSocket(addr, port, null, 0, streaming);
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates an unconnected socket with the given socket implementation.
328f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
3298cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes     * @param impl
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the socket implementation to be used.
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the socket.
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3348cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    protected Socket(SocketImpl impl) throws SocketException {
3358cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        this.impl = impl;
3368cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        this.proxy = null;
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Checks whether the connection destination satisfies the security policy
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * and the validity of the port range.
342f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param destAddr
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the destination host address.
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstPort
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the destination host.
347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3488cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    private void checkDestination(InetAddress destAddr, int dstPort) {
349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (dstPort < 0 || dstPort > 65535) {
350f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            throw new IllegalArgumentException(Msg.getString("K0032"));
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkConnectPermission(destAddr.getHostAddress(), dstPort);
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Checks whether the connection destination satisfies the security policy.
357f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param hostname
359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the destination hostname.
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstPort
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the destination host.
362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void checkConnectPermission(String hostname, int dstPort) {
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        SecurityManager security = System.getSecurityManager();
365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (security != null) {
366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            security.checkConnect(hostname, dstPort);
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Closes the socket. It is not possible to reconnect or rebind to this
372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * socket thereafter which means a new socket instance has to be created.
373f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while closing the socket.
376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized void close() throws IOException {
378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        isClosed = true;
3798cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        // RI compatibility: the RI returns the any address (but the original local port) after close.
3808cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        localAddress = Inet4Address.ANY;
381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.close();
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the IP address of the target host this socket is connected to.
386f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the IP address of the connected target host or {@code null} if
388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         this socket is not yet connected.
389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public InetAddress getInetAddress() {
391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isConnected()) {
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return impl.getInetAddress();
395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets an input stream to read data from this socket.
399f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the byte-oriented input stream.
401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the input stream or the
403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             socket is in an invalid state.
404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public InputStream getInputStream() throws IOException {
406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(false);
407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isInputShutdown()) {
408f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            throw new SocketException(Msg.getString("K0321"));
409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return impl.getInputStream();
411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the setting of the socket option {@code SocketOptions.SO_KEEPALIVE}.
415f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the {@code SocketOptions.SO_KEEPALIVE} is
417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         enabled, {@code false} otherwise.
418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading the socket option.
420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_KEEPALIVE
421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean getKeepAlive() throws SocketException {
423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(true);
4248cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        return (Boolean) impl.getOption(SocketOptions.SO_KEEPALIVE);
425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
4288cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes     * Returns the local IP address this socket is bound to, or {@code InetAddress.ANY} if
4298cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes     * the socket is unbound.
430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public InetAddress getLocalAddress() {
4328cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        return localAddress;
433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
4368cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes     * Returns the local port this socket is bound to, or -1 if the socket is unbound.
437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getLocalPort() {
439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isBound()) {
440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return -1;
441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return impl.getLocalPort();
443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets an output stream to write data into this socket.
447f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the byte-oriented output stream.
449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the output stream or the
451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             socket is in an invalid state.
452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public OutputStream getOutputStream() throws IOException {
454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(false);
455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isOutputShutdown()) {
456f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            throw new SocketException(Msg.getString("KA00f"));
457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return impl.getOutputStream();
459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the port number of the target host this socket is connected to.
463f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the port number of the connected target host or {@code 0} if this
465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         socket is not yet connected.
466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getPort() {
468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isConnected()) {
469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return 0;
470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return impl.getPort();
472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the value of the socket option {@code SocketOptions.SO_LINGER}.
476f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the current value of the option {@code SocketOptions.SO_LINGER}
478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         or {@code -1} if this option is disabled.
479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading the socket option.
481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_LINGER
482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getSoLinger() throws SocketException {
484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(true);
485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return ((Integer) impl.getOption(SocketOptions.SO_LINGER)).intValue();
486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the receive buffer size of this socket.
490f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the current value of the option {@code SocketOptions.SO_RCVBUF}.
492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading the socket option.
494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_RCVBUF
495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized int getReceiveBufferSize() throws SocketException {
497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(true);
498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return ((Integer) impl.getOption(SocketOptions.SO_RCVBUF)).intValue();
499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the send buffer size of this socket.
503f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the current value of the option {@code SocketOptions.SO_SNDBUF}.
505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading the socket option.
507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_SNDBUF
508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized int getSendBufferSize() throws SocketException {
510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(true);
511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return ((Integer) impl.getOption(SocketOptions.SO_SNDBUF)).intValue();
512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the timeout for this socket during which a reading operation shall
516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * block while waiting for data.
517f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the current value of the option {@code SocketOptions.SO_TIMEOUT}
519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         or {@code 0} which represents an infinite timeout.
520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading the socket option.
522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_TIMEOUT
523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized int getSoTimeout() throws SocketException {
525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(true);
526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return ((Integer) impl.getOption(SocketOptions.SO_TIMEOUT)).intValue();
527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the setting of the socket option {@code SocketOptions.TCP_NODELAY}.
531f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the {@code SocketOptions.TCP_NODELAY} is enabled,
533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading the socket option.
536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#TCP_NODELAY
537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean getTcpNoDelay() throws SocketException {
539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(true);
5408cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        return ((Boolean) impl.getOption(SocketOptions.TCP_NODELAY)).booleanValue();
541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the state of the {@code SocketOptions.SO_KEEPALIVE} for this socket.
545f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param value
547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the state whether this option is enabled or not.
548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the option.
550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_KEEPALIVE
551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setKeepAlive(boolean value) throws SocketException {
553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (impl != null) {
554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            checkClosedAndCreate(true);
555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            impl.setOption(SocketOptions.SO_KEEPALIVE, value ? Boolean.TRUE
556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    : Boolean.FALSE);
557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the internal factory for creating socket implementations. This may
562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * only be executed once during the lifetime of the application.
563f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param fac
565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the socket implementation factory to be set.
566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the factory has been already set.
568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static synchronized void setSocketImplFactory(SocketImplFactory fac)
570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws IOException {
571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        SecurityManager security = System.getSecurityManager();
572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (security != null) {
573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            security.checkSetFactory();
574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (factory != null) {
576f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            throw new SocketException(Msg.getString("K0044"));
577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        factory = fac;
579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the send buffer size of this socket.
583f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param size
585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the buffer size in bytes. This value must be a positive number
586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            greater than {@code 0}.
587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the size or the given value
589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             is an invalid size.
590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_SNDBUF
591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized void setSendBufferSize(int size) throws SocketException {
593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(true);
594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (size < 1) {
595f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            throw new IllegalArgumentException(Msg.getString("K0035"));
596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.setOption(SocketOptions.SO_SNDBUF, Integer.valueOf(size));
598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the receive buffer size of this socket.
602f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param size
604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the buffer size in bytes. This value must be a positive number
605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            greater than {@code 0}.
606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the size or the given value
608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             is an invalid size.
609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_RCVBUF
610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized void setReceiveBufferSize(int size)
612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws SocketException {
613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(true);
614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (size < 1) {
615f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            throw new IllegalArgumentException(Msg.getString("K0035"));
616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.setOption(SocketOptions.SO_RCVBUF, Integer.valueOf(size));
618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the state of the {@code SocketOptions.SO_LINGER} with the given
622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * timeout in seconds. The timeout value for this option is silently limited
623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * to the maximum of {@code 65535}.
624f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param on
626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the state whether this option is enabled or not.
627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param timeout
628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the linger timeout value in seconds.
629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the option.
631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_LINGER
632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setSoLinger(boolean on, int timeout) throws SocketException {
634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(true);
635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (on && timeout < 0) {
636f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            throw new IllegalArgumentException(Msg.getString("K0045"));
637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // BEGIN android-changed
639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /*
640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * The spec indicates that the right way to turn off an option
641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * is to pass Boolean.FALSE, so that's what we do here.
642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (on) {
644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (timeout > 65535) {
645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                timeout = 65535;
646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            impl.setOption(SocketOptions.SO_LINGER, Integer.valueOf(timeout));
648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            impl.setOption(SocketOptions.SO_LINGER, Boolean.FALSE);
650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // END android-changed
652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the reading timeout in milliseconds for this socket. The read
656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * operation will block indefinitely if this option value is set to {@code
657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * 0}. The timeout must be set before calling the read operation. A
658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code SocketTimeoutException} is thrown when this timeout expires.
659f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param timeout
661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the reading timeout value as number greater than {@code 0} or
662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            {@code 0} for an infinite timeout.
663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the option.
665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_TIMEOUT
666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized void setSoTimeout(int timeout) throws SocketException {
668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(true);
669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (timeout < 0) {
670f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            throw new IllegalArgumentException(Msg.getString("K0036"));
671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.setOption(SocketOptions.SO_TIMEOUT, Integer.valueOf(timeout));
673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the state of the {@code SocketOptions.TCP_NODELAY} for this socket.
677f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param on
679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the state whether this option is enabled or not.
680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the option.
682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#TCP_NODELAY
683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setTcpNoDelay(boolean on) throws SocketException {
685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(true);
686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.setOption(SocketOptions.TCP_NODELAY, Boolean.valueOf(on));
687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a stream socket, binds it to the nominated local address/port,
691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * then connects it to the nominated destination address/port.
692f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstAddress
694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the destination host address.
695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstPort
696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the destination host.
697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param localAddress
698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the address on the local machine to bind.
699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param localPort
700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the local machine to bind.
701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             thrown if an error occurs during the bind or connect
703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             operations.
704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    void startupSocket(InetAddress dstAddress, int dstPort,
706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            InetAddress localAddress, int localPort, boolean streaming)
707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws IOException {
708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (localPort < 0 || localPort > 65535) {
710f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            throw new IllegalArgumentException(Msg.getString("K0046"));
711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
7138cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        InetAddress addr = localAddress == null ? Inet4Address.ANY : localAddress;
714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        synchronized (this) {
715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            impl.create(streaming);
716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            isCreated = true;
717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (!streaming || !NetUtil.usingSocks(proxy)) {
719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    impl.bind(addr, localPort);
720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                isBound = true;
722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                impl.connect(dstAddress, dstPort);
723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                isConnected = true;
7248cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes                cacheLocalAddress();
725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (IOException e) {
726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                impl.close();
727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw e;
728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a {@code String} containing a concise, human-readable description of the
734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * socket.
735f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the textual representation of this socket.
737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toString() {
740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isConnected()) {
741f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            return "Socket[unconnected]";
742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return impl.toString();
744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Closes the input stream of this socket. Any further data sent to this
748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * socket will be discarded. Reading from this socket after this method has
749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * been called will return the value {@code EOF}.
750f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while closing the socket input stream.
753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the input stream is already closed.
755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void shutdownInput() throws IOException {
757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isInputShutdown()) {
758f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            throw new SocketException(Msg.getString("K0321"));
759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(false);
761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.shutdownInput();
762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        isInputShutdown = true;
763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Closes the output stream of this socket. All buffered data will be sent
767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * followed by the termination sequence. Writing to the closed output stream
768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * will cause an {@code IOException}.
769f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while closing the socket output stream.
772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the output stream is already closed.
774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void shutdownOutput() throws IOException {
776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isOutputShutdown()) {
777f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            throw new SocketException(Msg.getString("KA00f"));
778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(false);
780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.shutdownOutput();
781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        isOutputShutdown = true;
782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Checks whether the socket is closed, and throws an exception. Otherwise
786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * creates the underlying SocketImpl.
787f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the socket is closed.
790adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
791adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void checkClosedAndCreate(boolean create) throws SocketException {
792adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isClosed()) {
793f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            throw new SocketException(Msg.getString("K003d"));
794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!create) {
796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!isConnected()) {
797f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                throw new SocketException(Msg.getString("K0320"));
798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // a connected socket must be created
799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            /*
802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project             * return directly to fix a possible bug, if !create, should return
803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project             * here
804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project             */
805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isCreated) {
808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        synchronized (this) {
811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (isCreated) {
812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return;
813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                impl.create(true);
816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (SocketException e) {
817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw e;
818adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (IOException e) {
819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new SocketException(e.toString());
820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            isCreated = true;
822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the local address and port of this socket as a SocketAddress or
827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code null} if the socket is unbound. This is useful on multihomed
828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * hosts.
829f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the bound local socket address and port.
831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
832adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public SocketAddress getLocalSocketAddress() {
833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isBound()) {
834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return new InetSocketAddress(getLocalAddress(), getLocalPort());
837adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
838adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the remote address and port of this socket as a {@code
841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * SocketAddress} or {@code null} if the socket is not connected.
842f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the remote socket address and port.
844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public SocketAddress getRemoteSocketAddress() {
846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isConnected()) {
847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
848adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return new InetSocketAddress(getInetAddress(), getPort());
850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this socket is bound to a local address and port.
854f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
855adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the socket is bound to a local address, {@code
856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         false} otherwise.
857adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
858adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isBound() {
859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return isBound;
860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
863adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this socket is connected to a remote host.
864f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the socket is connected, {@code false} otherwise.
866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isConnected() {
868adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return isConnected;
869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
870adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this socket is closed.
873f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the socket is closed, {@code false} otherwise.
875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isClosed() {
877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return isClosed;
878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
879adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Binds this socket to the given local host address and port specified by
882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the SocketAddress {@code localAddr}. If {@code localAddr} is set to
883adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code null}, this socket will be bound to an available local address on
884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * any free port.
885f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param localAddr
887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the specific address and port on the local machine to bind to.
888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the given SocketAddress is invalid or not supported.
890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the socket is already bound or an error occurs while
892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             binding.
893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void bind(SocketAddress localAddr) throws IOException {
895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(true);
896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isBound()) {
897f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            throw new BindException(Msg.getString("K0315"));
898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
899adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int port = 0;
901051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti        InetAddress addr = Inet4Address.ANY;
902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (localAddr != null) {
903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!(localAddr instanceof InetSocketAddress)) {
904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new IllegalArgumentException(Msg.getString(
905f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                        "K0316", localAddr.getClass()));
906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            InetSocketAddress inetAddr = (InetSocketAddress) localAddr;
908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if ((addr = inetAddr.getAddress()) == null) {
909adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new SocketException(Msg.getString(
910f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                        "K0317", inetAddr.getHostName()));
911adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            port = inetAddr.getPort();
913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
915adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        synchronized (this) {
916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                impl.bind(addr, port);
918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                isBound = true;
9198cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes                cacheLocalAddress();
920adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (IOException e) {
921adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                impl.close();
922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw e;
923adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
927adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
928adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Connects this socket to the given remote host address and port specified
929adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * by the SocketAddress {@code remoteAddr}.
930f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param remoteAddr
932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the address and port of the remote host to connect to.
933adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the given SocketAddress is invalid or not supported.
935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the socket is already connected or an error occurs while
937adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             connecting.
938adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
939adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void connect(SocketAddress remoteAddr) throws IOException {
940adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        connect(remoteAddr, 0);
941adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
942adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
943adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
944adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Connects this socket to the given remote host address and port specified
945adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * by the SocketAddress {@code remoteAddr} with the specified timeout. The
946adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * connecting method will block until the connection is established or an
947adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * error occurred.
948f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
949adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param remoteAddr
950adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the address and port of the remote host to connect to.
951adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param timeout
952adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the timeout value in milliseconds or {@code 0} for an infinite
953adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            timeout.
954adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
955adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the given SocketAddress is invalid or not supported or the
956adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             timeout value is negative.
957adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
958adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the socket is already connected or an error occurs while
959adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             connecting.
960adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
9618cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    public void connect(SocketAddress remoteAddr, int timeout) throws IOException {
962adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(true);
963adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (timeout < 0) {
964f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            throw new IllegalArgumentException(Msg.getString("K0036"));
965adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
966adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isConnected()) {
967f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            throw new SocketException(Msg.getString("K0079"));
968adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
969adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (remoteAddr == null) {
970f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            throw new IllegalArgumentException(Msg.getString("K0318"));
971adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
972adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
973adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!(remoteAddr instanceof InetSocketAddress)) {
974adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IllegalArgumentException(Msg.getString(
975f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                    "K0316", remoteAddr.getClass()));
976adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
977adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        InetSocketAddress inetAddr = (InetSocketAddress) remoteAddr;
978adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        InetAddress addr;
979adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((addr = inetAddr.getAddress()) == null) {
980fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes            throw new UnknownHostException(Msg.getString("K0317", remoteAddr));
981adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
982adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int port = inetAddr.getPort();
983adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
984adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkDestination(addr, port);
985adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        synchronized (connectLock) {
986adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
987adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (!isBound()) {
9888cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes                    // socket already created at this point by earlier call or
989adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // checkClosedAndCreate this caused us to lose socket
990adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // options on create
991adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // impl.create(true);
992adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (!NetUtil.usingSocks(proxy)) {
993051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti                        impl.bind(Inet4Address.ANY, 0);
994adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
995adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    isBound = true;
996adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
997adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                impl.connect(remoteAddr, timeout);
998adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                isConnected = true;
9998cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes                cacheLocalAddress();
1000adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (IOException e) {
1001adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                impl.close();
1002adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw e;
1003adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1004adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1005adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1006adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1007adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1008adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether the incoming channel of the socket has already been
1009adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * closed.
1010f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1011adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if reading from this socket is not possible anymore,
1012adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
1013adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1014adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isInputShutdown() {
1015adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return isInputShutdown;
1016adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1017adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1018adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1019f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * Returns whether the outgoing channel of the socket has already been
1020adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * closed.
1021f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1022adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if writing to this socket is not possible anymore,
1023adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
1024adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1025adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isOutputShutdown() {
1026adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return isOutputShutdown;
1027adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1028adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1029adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1030adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the state of the {@code SocketOptions.SO_REUSEADDR} for this socket.
1031f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1032adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param reuse
1033adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the state whether this option is enabled or not.
1034adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
1035adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the option.
1036adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_REUSEADDR
1037adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1038adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setReuseAddress(boolean reuse) throws SocketException {
1039adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(true);
1040adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.setOption(SocketOptions.SO_REUSEADDR, reuse ? Boolean.TRUE
1041adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                : Boolean.FALSE);
1042adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1043adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1044adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1045adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the setting of the socket option {@code SocketOptions.SO_REUSEADDR}.
1046f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1047adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the {@code SocketOptions.SO_REUSEADDR} is
1048adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         enabled, {@code false} otherwise.
1049adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
1050adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading the socket option.
1051adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_REUSEADDR
1052adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1053adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean getReuseAddress() throws SocketException {
1054adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(true);
1055adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return ((Boolean) impl.getOption(SocketOptions.SO_REUSEADDR))
1056adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                .booleanValue();
1057adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1058adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1059adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1060adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the state of the {@code SocketOptions.SO_OOBINLINE} for this socket.
1061adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * When this option is enabled urgent data can be received in-line with
1062adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * normal data.
1063f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1064adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param oobinline
1065adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            whether this option is enabled or not.
1066adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
1067adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the option.
1068adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_OOBINLINE
1069adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1070adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setOOBInline(boolean oobinline) throws SocketException {
1071adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(true);
1072adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.setOption(SocketOptions.SO_OOBINLINE, oobinline ? Boolean.TRUE
1073adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                : Boolean.FALSE);
1074adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1075adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1076adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1077adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the setting of the socket option {@code SocketOptions.SO_OOBINLINE}.
1078f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1079adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the {@code SocketOptions.SO_OOBINLINE} is
1080adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         enabled, {@code false} otherwise.
1081adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
1082adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading the socket option.
1083adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_OOBINLINE
1084adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1085adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean getOOBInline() throws SocketException {
1086adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(true);
1087adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return ((Boolean) impl.getOption(SocketOptions.SO_OOBINLINE))
1088adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                .booleanValue();
1089adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1090adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1091adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1092adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the value of the {@code SocketOptions.IP_TOS} for this socket. See
1093adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the specification RFC 1349 for more information about the type of service
1094adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * field.
1095f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1096adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param value
1097adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the value to be set for this option with a valid range of
1098adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            {@code 0-255}.
1099adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
1100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the option.
1101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#IP_TOS
1102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setTrafficClass(int value) throws SocketException {
1104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(true);
1105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (value < 0 || value > 255) {
1106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IllegalArgumentException();
1107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.setOption(SocketOptions.IP_TOS, Integer.valueOf(value));
1109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the value of the socket option {@code SocketOptions.IP_TOS}.
1113f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the value which represents the type of service.
1115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
1116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading the socket option.
1117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#IP_TOS
1118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getTrafficClass() throws SocketException {
1120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(true);
1121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return ((Number) impl.getOption(SocketOptions.IP_TOS)).intValue();
1122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sends the given single byte data which is represented by the lowest octet
1126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * of {@code value} as "TCP urgent data".
1127f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param value
1129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the byte of urgent data to be sent.
1130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
1131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while sending urgent data.
1132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void sendUrgentData(int value) throws IOException {
1134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!impl.supportsUrgentData()) {
1135f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            throw new SocketException(Msg.getString("K0333"));
1136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.sendUrgentData(value);
1138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Set the appropriate flags for a socket created by {@code
1142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * ServerSocket.accept()}.
1143f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see ServerSocket#implAccept
1145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    void accepted() {
1147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        isCreated = isBound = isConnected = true;
11488cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        cacheLocalAddress();
11498cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    }
11508cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes
11518cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    private void cacheLocalAddress() {
11528cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        this.localAddress = Platform.getNetworkSystem().getSocketLocalAddress(impl.fd);
1153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static boolean preferIPv4Stack() {
1156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String result = AccessController.doPrivileged(new PriviAction<String>(
1157f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                "java.net.preferIPv4Stack"));
1158f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        return "true".equals(result);
1159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the SocketChannel of this socket, if one is available. The current
1163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * implementation of this method returns always {@code null}.
1164f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the related SocketChannel or {@code null} if no channel exists.
1166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public SocketChannel getChannel() {
1168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return null;
1169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets performance preferences for connectionTime, latency and bandwidth.
1173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
1174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This method does currently nothing.
1175f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param connectionTime
1177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the value representing the importance of a short connecting
1178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            time.
1179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param latency
1180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the value representing the importance of low latency.
1181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param bandwidth
1182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the value representing the importance of high bandwidth.
1183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setPerformancePreferences(int connectionTime, int latency,
1185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int bandwidth) {
1186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Our socket implementation only provide one protocol: TCP/IP, so
1187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // we do nothing for this method
1188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
1190