2 * Copyright (C) 2010 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
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.
19 import android.content.Context;
20 import android.net.ConnectivityManager;
21 import android.net.DhcpInfoInternal;
22 import android.net.LinkAddress;
23 import android.net.LinkCapabilities;
24 import android.net.LinkProperties;
25 import android.net.NetworkInfo;
26 import android.net.NetworkInfo.DetailedState;
27 import android.net.NetworkStateTracker;
28 import android.net.NetworkUtils;
29 import android.os.Handler;
30 import android.os.IBinder;
31 import android.os.INetworkManagementService;
32 import android.os.Message;
33 import android.os.RemoteException;
34 import android.os.ServiceManager;
35 import android.util.Log;
37 import java.net.InetAddress;
38 import java.util.concurrent.atomic.AtomicBoolean;
39 import java.util.concurrent.atomic.AtomicInteger;
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.
47 public class EthernetDataTracker implements NetworkStateTracker {
48 private static final String NETWORKTYPE = "ETHERNET";
49 private static final String TAG = "Ethernet";
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);
56 private LinkProperties mLinkProperties;
57 private LinkCapabilities mLinkCapabilities;
58 private NetworkInfo mNetworkInfo;
59 private InterfaceObserver mInterfaceObserver;
61 /* For sending events to connectivity service handler */
62 private Handler mCsHandler;
63 private Context mContext;
65 private static EthernetDataTracker sInstance;
66 private static String mIface = "";
68 private static class InterfaceObserver extends INetworkManagementEventObserver.Stub {
69 private EthernetDataTracker mTracker;
71 InterfaceObserver(EthernetDataTracker tracker) {
76 public void interfaceLinkStatusChanged(String iface, boolean up) {
77 Log.d(TAG, "Interface " + iface + " link " + (up ? "up" : "down"));
80 public void interfaceAdded(String iface) {
81 mTracker.interfaceAdded(iface);
84 public void interfaceRemoved(String iface) {
85 mTracker.interfaceRemoved(iface);
89 private EthernetDataTracker() {
90 mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_ETHERNET, 0, NETWORKTYPE, "");
91 mLinkProperties = new LinkProperties();
92 mLinkCapabilities = new LinkCapabilities();
94 mNetworkInfo.setIsAvailable(false);
95 setTeardownRequested(false);
98 private void interfaceAdded(String iface) {
99 if (!iface.matches("eth\\d"))
102 Log.d(TAG, "Adding " + iface);
104 synchronized(mIface) {
105 if(!mIface.isEmpty())
110 mNetworkInfo.setIsAvailable(true);
111 Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo);
117 private void interfaceRemoved(String iface) {
118 if (!iface.equals(mIface))
121 Log.d(TAG, "Removing " + iface);
123 NetworkUtils.stopDhcp(mIface);
125 mLinkProperties.clear();
126 mNetworkInfo.setIsAvailable(false);
127 mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);
129 Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo);
132 msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
138 private void runDhcp() {
139 Thread dhcpThread = new Thread(new Runnable() {
141 DhcpInfoInternal dhcpInfoInternal = new DhcpInfoInternal();
142 if (!NetworkUtils.runDhcp(mIface, dhcpInfoInternal)) {
143 Log.e(TAG, "DHCP request error:" + NetworkUtils.getDhcpError());
146 mLinkProperties = dhcpInfoInternal.makeLinkProperties();
147 mLinkProperties.setInterfaceName(mIface);
149 mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, null);
150 Message msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
157 public static synchronized EthernetDataTracker getInstance() {
158 if (sInstance == null) sInstance = new EthernetDataTracker();
162 public Object Clone() throws CloneNotSupportedException {
163 throw new CloneNotSupportedException();
166 public void setTeardownRequested(boolean isRequested) {
167 mTeardownRequested.set(isRequested);
170 public boolean isTeardownRequested() {
171 return mTeardownRequested.get();
175 * Begin monitoring connectivity
177 public void startMonitoring(Context context, Handler target) {
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);
186 service.registerObserver(mInterfaceObserver);
187 } catch (RemoteException e) {
188 Log.e(TAG, "Could not register InterfaceObserver " + e);
193 * Disable connectivity to a network
194 * TODO: do away with return value after making MobileDataStateTracker async
196 public boolean teardown() {
197 mTeardownRequested.set(true);
198 NetworkUtils.stopDhcp(mIface);
203 * Re-enable connectivity to a network after a {@link #teardown()}.
205 public boolean reconnect() {
206 mTeardownRequested.set(false);
212 * Turn the wireless radio off for a network.
213 * @param turnOn {@code true} to turn the radio on, {@code false}
215 public boolean setRadio(boolean turnOn) {
220 * @return true - If are we currently tethered with another device.
222 public synchronized boolean isAvailable() {
223 return mNetworkInfo.isAvailable();
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
239 public int startUsingNetworkFeature(String feature, int callingPid, int callingUid) {
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
256 public int stopUsingNetworkFeature(String feature, int callingPid, int callingUid) {
263 public void setDataEnable(boolean enabled) {
264 Log.d(TAG, "setDataEnabled: IGNORING enabled=" + enabled);
268 * Check if private DNS route is set for the network
270 public boolean isPrivateDnsRouteSet() {
271 return mPrivateDnsRouteSet.get();
275 * Set a flag indicating private DNS route is set
277 public void privateDnsRouteSet(boolean enabled) {
278 mPrivateDnsRouteSet.set(enabled);
282 * Fetch NetworkInfo for the network
284 public synchronized NetworkInfo getNetworkInfo() {
289 * Fetch LinkProperties for the network
291 public synchronized LinkProperties getLinkProperties() {
292 return new LinkProperties(mLinkProperties);
296 * A capability is an Integer/String pair, the capabilities
297 * are defined in the class LinkSocket#Key.
299 * @return a copy of this connections capabilities, may be empty but never null.
301 public LinkCapabilities getLinkCapabilities() {
302 return new LinkCapabilities(mLinkCapabilities);
306 * Fetch default gateway address for the network
308 public int getDefaultGatewayAddr() {
309 return mDefaultGatewayAddr.get();
313 * Check if default route is set
315 public boolean isDefaultRouteSet() {
316 return mDefaultRouteSet.get();
320 * Set a flag indicating default route is set for the network
322 public void defaultRouteSet(boolean enabled) {
323 mDefaultRouteSet.set(enabled);
327 * Return the system properties name associated with the tcp buffer sizes
330 public String getTcpBufferSizesPropName() {
331 return "net.tcp.buffersize.wifi";
334 public void setDependencyMet(boolean met) {
335 // not supported on this network