1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.net;
18
19import android.net.LinkCapabilities;
20import android.net.LinkProperties;
21import android.net.LinkSocketNotifier;
22
23import android.util.Log;
24
25import java.io.IOException;
26import java.net.Socket;
27import java.net.SocketAddress;
28import java.net.SocketTimeoutException;
29import java.net.UnknownHostException;
30import java.util.HashSet;
31import java.util.Set;
32
33/** @hide */
34public class LinkSocket extends Socket {
35    private final static String TAG = "LinkSocket";
36    private final static boolean DBG = true;
37
38    /**
39     * Default constructor
40     */
41    public LinkSocket() {
42        if (DBG) log("LinkSocket() EX");
43    }
44
45    /**
46     * Creates a new unconnected socket.
47     * @param notifier a reference to a class that implements {@code LinkSocketNotifier}
48     */
49    public LinkSocket(LinkSocketNotifier notifier) {
50        if (DBG) log("LinkSocket(notifier) EX");
51    }
52
53    /**
54     * Creates a new unconnected socket usign the given proxy type.
55     * @param notifier a reference to a class that implements {@code LinkSocketNotifier}
56     * @param proxy the specified proxy for this socket
57     * @throws IllegalArgumentException if the argument proxy is null or of an invalid type.
58     * @throws SecurityException if a security manager exists and it denies the permission
59     *                           to connect to the given proxy.
60     */
61    public LinkSocket(LinkSocketNotifier notifier, Proxy proxy) {
62        if (DBG) log("LinkSocket(notifier, proxy) EX");
63    }
64
65    /**
66     * @return the {@code LinkProperties} for the socket
67     */
68    public LinkProperties getLinkProperties() {
69        if (DBG) log("LinkProperties() EX");
70        return new LinkProperties();
71    }
72
73    /**
74     * Set the {@code LinkCapabilies} needed for this socket.  If the socket is already connected
75     * or is a duplicate socket the request is ignored and {@code false} will
76     * be returned. A needs map can be created via the {@code createNeedsMap} static
77     * method.
78     * @param needs the needs of the socket
79     * @return {@code true} if needs are successfully set, {@code false} otherwise
80     */
81    public boolean setNeededCapabilities(LinkCapabilities needs) {
82        if (DBG) log("setNeeds() EX");
83        return false;
84    }
85
86    /**
87     * @return the LinkCapabilites set by setNeededCapabilities, empty if none has been set
88     */
89    public LinkCapabilities getNeededCapabilities() {
90        if (DBG) log("getNeeds() EX");
91        return null;
92    }
93
94    /**
95     * @return all of the {@code LinkCapabilities} of the link used by this socket
96     */
97    public LinkCapabilities getCapabilities() {
98        if (DBG) log("getCapabilities() EX");
99        return null;
100    }
101
102    /**
103     * Returns this LinkSockets set of capabilities, filtered according to
104     * the given {@code Set}.  Capabilities in the Set but not available from
105     * the link will not be reported in the results.  Capabilities of the link
106     * but not listed in the Set will also not be reported in the results.
107     * @param capabilities {@code Set} of capabilities requested
108     * @return the filtered {@code LinkCapabilities} of this LinkSocket, may be empty
109     */
110    public LinkCapabilities getCapabilities(Set<Integer> capabilities) {
111        if (DBG) log("getCapabilities(capabilities) EX");
112        return new LinkCapabilities();
113    }
114
115    /**
116     * Provide the set of capabilities the application is interested in tracking
117     * for this LinkSocket.
118     * @param capabilities a {@code Set} of capabilities to track
119     */
120    public void setTrackedCapabilities(Set<Integer> capabilities) {
121        if (DBG) log("setTrackedCapabilities(capabilities) EX");
122    }
123
124    /**
125     * @return the {@code LinkCapabilities} that are tracked, empty if none has been set.
126     */
127    public Set<Integer> getTrackedCapabilities() {
128        if (DBG) log("getTrackedCapabilities(capabilities) EX");
129        return new HashSet<Integer>();
130    }
131
132    /**
133     * Connects this socket to the given remote host address and port specified
134     * by dstName and dstPort.
135     * @param dstName the address of the remote host to connect to
136     * @param dstPort the port to connect to on the remote host
137     * @param timeout the timeout value in milliseconds or 0 for infinite timeout
138     * @throws UnknownHostException if the given dstName is invalid
139     * @throws IOException if the socket is already connected or an error occurs
140     *                     while connecting
141     * @throws SocketTimeoutException if the timeout fires
142     */
143    public void connect(String dstName, int dstPort, int timeout)
144            throws UnknownHostException, IOException, SocketTimeoutException {
145        if (DBG) log("connect(dstName, dstPort, timeout) EX");
146    }
147
148    /**
149     * Connects this socket to the given remote host address and port specified
150     * by dstName and dstPort.
151     * @param dstName the address of the remote host to connect to
152     * @param dstPort the port to connect to on the remote host
153     * @throws UnknownHostException if the given dstName is invalid
154     * @throws IOException if the socket is already connected or an error occurs
155     *                     while connecting
156     */
157    public void connect(String dstName, int dstPort)
158            throws UnknownHostException, IOException {
159        if (DBG) log("connect(dstName, dstPort, timeout) EX");
160    }
161
162    /**
163     * Connects this socket to the given remote host address and port specified
164     * by the SocketAddress with the specified timeout.
165     * @deprecated Use {@code connect(String dstName, int dstPort, int timeout)}
166     *             instead.  Using this method may result in reduced functionality.
167     * @param remoteAddr the address and port of the remote host to connect to
168     * @throws IllegalArgumentException if the given SocketAddress is invalid
169     * @throws IOException if the socket is already connected or an error occurs
170     *                     while connecting
171     * @throws SocketTimeoutException if the timeout expires
172     */
173    @Override
174    @Deprecated
175    public void connect(SocketAddress remoteAddr, int timeout)
176            throws IOException, SocketTimeoutException {
177        if (DBG) log("connect(remoteAddr, timeout) EX DEPRECATED");
178    }
179
180    /**
181     * Connects this socket to the given remote host address and port specified
182     * by the SocketAddress.
183     * TODO add comment on all these that the network selection happens during connect
184     * and may take 30 seconds
185     * @deprecated Use {@code connect(String dstName, int dstPort)}
186     *             Using this method may result in reduced functionality.
187     * @param remoteAddr the address and port of the remote host to connect to.
188     * @throws IllegalArgumentException if the SocketAddress is invalid or not supported.
189     * @throws IOException if the socket is already connected or an error occurs
190     *                     while connecting
191     */
192    @Override
193    @Deprecated
194    public void connect(SocketAddress remoteAddr) throws IOException {
195        if (DBG) log("connect(remoteAddr) EX DEPRECATED");
196    }
197
198    /**
199     * Connect a duplicate socket socket to the same remote host address and port
200     * as the original with a timeout parameter.
201     * @param timeout the timeout value in milliseconds or 0 for infinite timeout
202     * @throws IOException if the socket is already connected or an error occurs
203     *                     while connecting
204     */
205    public void connect(int timeout) throws IOException {
206        if (DBG) log("connect(timeout) EX");
207    }
208
209    /**
210     * Connect a duplicate socket socket to the same remote host address and port
211     * as the original.
212     * @throws IOException if the socket is already connected or an error occurs
213     *                     while connecting
214     */
215    public void connect() throws IOException {
216        if (DBG) log("connect() EX");
217    }
218
219    /**
220     * Closes the socket.  It is not possible to reconnect or rebind to this
221     * socket thereafter which means a new socket instance has to be created.
222     * @throws IOException if an error occurs while closing the socket
223     */
224    @Override
225    public synchronized void close() throws IOException {
226        if (DBG) log("close() EX");
227    }
228
229    /**
230     * Request that a new LinkSocket be created using a different radio
231     * (such as WiFi or 3G) than the current LinkSocket.  If a different
232     * radio is available a call back will be made via {@code onBetterLinkAvail}.
233     * If unable to find a better radio, application will be notified via
234     * {@code onNewLinkUnavailable}
235     * @see LinkSocketNotifier#onBetterLinkAvailable(LinkSocket, LinkSocket)
236     * @param linkRequestReason reason for requesting a new link.
237     */
238    public void requestNewLink(LinkRequestReason linkRequestReason) {
239        if (DBG) log("requestNewLink(linkRequestReason) EX");
240    }
241
242    /**
243     * @deprecated LinkSocket will automatically pick the optimum interface
244     *             to bind to
245     * @param localAddr the specific address and port on the local machine
246     *                  to bind to
247     * @throws IOException always as this method is deprecated for LinkSocket
248     */
249    @Override
250    @Deprecated
251    public void bind(SocketAddress localAddr) throws UnsupportedOperationException {
252        if (DBG) log("bind(localAddr) EX throws IOException");
253        throw new UnsupportedOperationException("bind is deprecated for LinkSocket");
254    }
255
256    /**
257     * Reason codes an application can specify when requesting for a new link.
258     * TODO: need better documentation
259     */
260    public static final class LinkRequestReason {
261        /** No constructor */
262        private LinkRequestReason() {}
263
264        /** This link is working properly */
265        public static final int LINK_PROBLEM_NONE = 0;
266        /** This link has an unknown issue */
267        public static final int LINK_PROBLEM_UNKNOWN = 1;
268    }
269
270    /**
271     * Debug logging
272     */
273    protected static void log(String s) {
274        Log.d(TAG, s);
275    }
276}
277