blob: 55850c90ca32f99cc8ce06f983b17508d0f2b1ba [file] [log] [blame]
Benoit Goby19970692010-12-22 14:29:40 -08001/*
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.content.Context;
20import android.net.ConnectivityManager;
21import android.net.DhcpInfoInternal;
22import android.net.LinkAddress;
23import android.net.LinkCapabilities;
24import android.net.LinkProperties;
25import android.net.NetworkInfo;
26import android.net.NetworkInfo.DetailedState;
27import android.net.NetworkStateTracker;
28import android.net.NetworkUtils;
29import android.os.Handler;
30import android.os.IBinder;
31import android.os.INetworkManagementService;
32import android.os.Message;
33import android.os.RemoteException;
34import android.os.ServiceManager;
35import android.util.Log;
36
37import java.net.InetAddress;
38import java.util.concurrent.atomic.AtomicBoolean;
39import java.util.concurrent.atomic.AtomicInteger;
40
41/**
42 * This class tracks the data connection associated with Ethernet
43 * This is a singleton class and an instance will be created by
44 * ConnectivityService.
45 * @hide
46 */
47public class EthernetDataTracker implements NetworkStateTracker {
48 private static final String NETWORKTYPE = "ETHERNET";
49 private static final String TAG = "Ethernet";
50
51 private AtomicBoolean mTeardownRequested = new AtomicBoolean(false);
52 private AtomicBoolean mPrivateDnsRouteSet = new AtomicBoolean(false);
53 private AtomicInteger mDefaultGatewayAddr = new AtomicInteger(0);
54 private AtomicBoolean mDefaultRouteSet = new AtomicBoolean(false);
55
56 private LinkProperties mLinkProperties;
57 private LinkCapabilities mLinkCapabilities;
58 private NetworkInfo mNetworkInfo;
59 private InterfaceObserver mInterfaceObserver;
60
61 /* For sending events to connectivity service handler */
62 private Handler mCsHandler;
63 private Context mContext;
64
65 private static EthernetDataTracker sInstance;
66 private static String mIface = "";
67
68 private static class InterfaceObserver extends INetworkManagementEventObserver.Stub {
69 private EthernetDataTracker mTracker;
70
71 InterfaceObserver(EthernetDataTracker tracker) {
72 super();
73 mTracker = tracker;
74 }
75
76 public void interfaceLinkStatusChanged(String iface, boolean up) {
77 Log.d(TAG, "Interface " + iface + " link " + (up ? "up" : "down"));
78 }
79
80 public void interfaceAdded(String iface) {
81 mTracker.interfaceAdded(iface);
82 }
83
84 public void interfaceRemoved(String iface) {
85 mTracker.interfaceRemoved(iface);
86 }
87 }
88
89 private EthernetDataTracker() {
90 mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_ETHERNET, 0, NETWORKTYPE, "");
91 mLinkProperties = new LinkProperties();
92 mLinkCapabilities = new LinkCapabilities();
93
94 mNetworkInfo.setIsAvailable(false);
95 setTeardownRequested(false);
96 }
97
98 private void interfaceAdded(String iface) {
99 if (!iface.matches("eth\\d"))
100 return;
101
102 Log.d(TAG, "Adding " + iface);
103
104 synchronized(mIface) {
105 if(!mIface.isEmpty())
106 return;
107 mIface = iface;
108 }
109
110 mNetworkInfo.setIsAvailable(true);
111 Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo);
112 msg.sendToTarget();
113
114 runDhcp();
115 }
116
117 private void interfaceRemoved(String iface) {
118 if (!iface.equals(mIface))
119 return;
120
121 Log.d(TAG, "Removing " + iface);
122
123 NetworkUtils.stopDhcp(mIface);
124
125 mLinkProperties.clear();
126 mNetworkInfo.setIsAvailable(false);
127 mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);
128
129 Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo);
130 msg.sendToTarget();
131
132 msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
133 msg.sendToTarget();
134
135 mIface = "";
136 }
137
138 private void runDhcp() {
139 Thread dhcpThread = new Thread(new Runnable() {
140 public void run() {
141 DhcpInfoInternal dhcpInfoInternal = new DhcpInfoInternal();
142 if (!NetworkUtils.runDhcp(mIface, dhcpInfoInternal)) {
143 Log.e(TAG, "DHCP request error:" + NetworkUtils.getDhcpError());
144 return;
145 }
146 mLinkProperties = dhcpInfoInternal.makeLinkProperties();
147 mLinkProperties.setInterfaceName(mIface);
148
149 mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, null);
150 Message msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
151 msg.sendToTarget();
152 }
153 });
154 dhcpThread.start();
155 }
156
157 public static synchronized EthernetDataTracker getInstance() {
158 if (sInstance == null) sInstance = new EthernetDataTracker();
159 return sInstance;
160 }
161
162 public Object Clone() throws CloneNotSupportedException {
163 throw new CloneNotSupportedException();
164 }
165
166 public void setTeardownRequested(boolean isRequested) {
167 mTeardownRequested.set(isRequested);
168 }
169
170 public boolean isTeardownRequested() {
171 return mTeardownRequested.get();
172 }
173
174 /**
175 * Begin monitoring connectivity
176 */
177 public void startMonitoring(Context context, Handler target) {
178 mContext = context;
179 mCsHandler = target;
180
181 // register for notifications from NetworkManagement Service
182 IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
183 INetworkManagementService service = INetworkManagementService.Stub.asInterface(b);
184 mInterfaceObserver = new InterfaceObserver(this);
185 try {
186 service.registerObserver(mInterfaceObserver);
187 } catch (RemoteException e) {
188 Log.e(TAG, "Could not register InterfaceObserver " + e);
189 }
190 }
191
192 /**
193 * Disable connectivity to a network
194 * TODO: do away with return value after making MobileDataStateTracker async
195 */
196 public boolean teardown() {
197 mTeardownRequested.set(true);
198 NetworkUtils.stopDhcp(mIface);
199 return true;
200 }
201
202 /**
203 * Re-enable connectivity to a network after a {@link #teardown()}.
204 */
205 public boolean reconnect() {
206 mTeardownRequested.set(false);
207 runDhcp();
208 return true;
209 }
210
211 /**
212 * Turn the wireless radio off for a network.
213 * @param turnOn {@code true} to turn the radio on, {@code false}
214 */
215 public boolean setRadio(boolean turnOn) {
216 return true;
217 }
218
219 /**
220 * @return true - If are we currently tethered with another device.
221 */
222 public synchronized boolean isAvailable() {
223 return mNetworkInfo.isAvailable();
224 }
225
226 /**
227 * Tells the underlying networking system that the caller wants to
228 * begin using the named feature. The interpretation of {@code feature}
229 * is completely up to each networking implementation.
230 * @param feature the name of the feature to be used
231 * @param callingPid the process ID of the process that is issuing this request
232 * @param callingUid the user ID of the process that is issuing this request
233 * @return an integer value representing the outcome of the request.
234 * The interpretation of this value is specific to each networking
235 * implementation+feature combination, except that the value {@code -1}
236 * always indicates failure.
237 * TODO: needs to go away
238 */
239 public int startUsingNetworkFeature(String feature, int callingPid, int callingUid) {
240 return -1;
241 }
242
243 /**
244 * Tells the underlying networking system that the caller is finished
245 * using the named feature. The interpretation of {@code feature}
246 * is completely up to each networking implementation.
247 * @param feature the name of the feature that is no longer needed.
248 * @param callingPid the process ID of the process that is issuing this request
249 * @param callingUid the user ID of the process that is issuing this request
250 * @return an integer value representing the outcome of the request.
251 * The interpretation of this value is specific to each networking
252 * implementation+feature combination, except that the value {@code -1}
253 * always indicates failure.
254 * TODO: needs to go away
255 */
256 public int stopUsingNetworkFeature(String feature, int callingPid, int callingUid) {
257 return -1;
258 }
259
260 /**
261 * @param enabled
262 */
263 public void setDataEnable(boolean enabled) {
264 Log.d(TAG, "setDataEnabled: IGNORING enabled=" + enabled);
265 }
266
267 /**
268 * Check if private DNS route is set for the network
269 */
270 public boolean isPrivateDnsRouteSet() {
271 return mPrivateDnsRouteSet.get();
272 }
273
274 /**
275 * Set a flag indicating private DNS route is set
276 */
277 public void privateDnsRouteSet(boolean enabled) {
278 mPrivateDnsRouteSet.set(enabled);
279 }
280
281 /**
282 * Fetch NetworkInfo for the network
283 */
284 public synchronized NetworkInfo getNetworkInfo() {
285 return mNetworkInfo;
286 }
287
288 /**
289 * Fetch LinkProperties for the network
290 */
291 public synchronized LinkProperties getLinkProperties() {
292 return new LinkProperties(mLinkProperties);
293 }
294
295 /**
296 * A capability is an Integer/String pair, the capabilities
297 * are defined in the class LinkSocket#Key.
298 *
299 * @return a copy of this connections capabilities, may be empty but never null.
300 */
301 public LinkCapabilities getLinkCapabilities() {
302 return new LinkCapabilities(mLinkCapabilities);
303 }
304
305 /**
306 * Fetch default gateway address for the network
307 */
308 public int getDefaultGatewayAddr() {
309 return mDefaultGatewayAddr.get();
310 }
311
312 /**
313 * Check if default route is set
314 */
315 public boolean isDefaultRouteSet() {
316 return mDefaultRouteSet.get();
317 }
318
319 /**
320 * Set a flag indicating default route is set for the network
321 */
322 public void defaultRouteSet(boolean enabled) {
323 mDefaultRouteSet.set(enabled);
324 }
325
326 /**
327 * Return the system properties name associated with the tcp buffer sizes
328 * for this network.
329 */
330 public String getTcpBufferSizesPropName() {
331 return "net.tcp.buffersize.wifi";
332 }
Robert Greenwaltaf6eddb2011-04-07 15:44:10 -0700333
334 public void setDependencyMet(boolean met) {
335 // not supported on this network
336 }
Benoit Goby19970692010-12-22 14:29:40 -0800337}