11997069436f0d47583a0b700c12ed63132cf3312Benoit Goby/* 21997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * Copyright (C) 2010 The Android Open Source Project 31997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * 41997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * Licensed under the Apache License, Version 2.0 (the "License"); 51997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * you may not use this file except in compliance with the License. 61997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * You may obtain a copy of the License at 71997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * 81997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * http://www.apache.org/licenses/LICENSE-2.0 91997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * 101997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * Unless required by applicable law or agreed to in writing, software 111997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * distributed under the License is distributed on an "AS IS" BASIS, 121997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * See the License for the specific language governing permissions and 141997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * limitations under the License. 151997069436f0d47583a0b700c12ed63132cf3312Benoit Goby */ 161997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 171997069436f0d47583a0b700c12ed63132cf3312Benoit Gobypackage android.net; 181997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 191997069436f0d47583a0b700c12ed63132cf3312Benoit Gobyimport android.content.Context; 201997069436f0d47583a0b700c12ed63132cf3312Benoit Gobyimport android.net.NetworkInfo.DetailedState; 211997069436f0d47583a0b700c12ed63132cf3312Benoit Gobyimport android.os.Handler; 221997069436f0d47583a0b700c12ed63132cf3312Benoit Gobyimport android.os.IBinder; 231997069436f0d47583a0b700c12ed63132cf3312Benoit Gobyimport android.os.INetworkManagementService; 241997069436f0d47583a0b700c12ed63132cf3312Benoit Gobyimport android.os.Message; 251997069436f0d47583a0b700c12ed63132cf3312Benoit Gobyimport android.os.RemoteException; 261997069436f0d47583a0b700c12ed63132cf3312Benoit Gobyimport android.os.ServiceManager; 271997069436f0d47583a0b700c12ed63132cf3312Benoit Gobyimport android.util.Log; 281997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 291997069436f0d47583a0b700c12ed63132cf3312Benoit Gobyimport java.util.concurrent.atomic.AtomicBoolean; 301997069436f0d47583a0b700c12ed63132cf3312Benoit Gobyimport java.util.concurrent.atomic.AtomicInteger; 311997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 321997069436f0d47583a0b700c12ed63132cf3312Benoit Goby/** 331997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * This class tracks the data connection associated with Ethernet 341997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * This is a singleton class and an instance will be created by 351997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * ConnectivityService. 361997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * @hide 371997069436f0d47583a0b700c12ed63132cf3312Benoit Goby */ 381997069436f0d47583a0b700c12ed63132cf3312Benoit Gobypublic class EthernetDataTracker implements NetworkStateTracker { 391997069436f0d47583a0b700c12ed63132cf3312Benoit Goby private static final String NETWORKTYPE = "ETHERNET"; 401997069436f0d47583a0b700c12ed63132cf3312Benoit Goby private static final String TAG = "Ethernet"; 411997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 421997069436f0d47583a0b700c12ed63132cf3312Benoit Goby private AtomicBoolean mTeardownRequested = new AtomicBoolean(false); 431997069436f0d47583a0b700c12ed63132cf3312Benoit Goby private AtomicBoolean mPrivateDnsRouteSet = new AtomicBoolean(false); 441997069436f0d47583a0b700c12ed63132cf3312Benoit Goby private AtomicInteger mDefaultGatewayAddr = new AtomicInteger(0); 451997069436f0d47583a0b700c12ed63132cf3312Benoit Goby private AtomicBoolean mDefaultRouteSet = new AtomicBoolean(false); 461997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 47f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen private static boolean mLinkUp; 481997069436f0d47583a0b700c12ed63132cf3312Benoit Goby private LinkProperties mLinkProperties; 491997069436f0d47583a0b700c12ed63132cf3312Benoit Goby private LinkCapabilities mLinkCapabilities; 501997069436f0d47583a0b700c12ed63132cf3312Benoit Goby private NetworkInfo mNetworkInfo; 511997069436f0d47583a0b700c12ed63132cf3312Benoit Goby private InterfaceObserver mInterfaceObserver; 52d60ae7f6688ea83df536c2eb1101a74ae1914ac6Doug Zongker private String mHwAddr; 531997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 541997069436f0d47583a0b700c12ed63132cf3312Benoit Goby /* For sending events to connectivity service handler */ 551997069436f0d47583a0b700c12ed63132cf3312Benoit Goby private Handler mCsHandler; 561997069436f0d47583a0b700c12ed63132cf3312Benoit Goby private Context mContext; 571997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 581997069436f0d47583a0b700c12ed63132cf3312Benoit Goby private static EthernetDataTracker sInstance; 59c96a667162fab44a250503caccb770109a9cb69aMike J. Chen private static String sIfaceMatch = ""; 601997069436f0d47583a0b700c12ed63132cf3312Benoit Goby private static String mIface = ""; 611997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 62198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt private INetworkManagementService mNMService; 63198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt 641997069436f0d47583a0b700c12ed63132cf3312Benoit Goby private static class InterfaceObserver extends INetworkManagementEventObserver.Stub { 651997069436f0d47583a0b700c12ed63132cf3312Benoit Goby private EthernetDataTracker mTracker; 661997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 671997069436f0d47583a0b700c12ed63132cf3312Benoit Goby InterfaceObserver(EthernetDataTracker tracker) { 681997069436f0d47583a0b700c12ed63132cf3312Benoit Goby super(); 691997069436f0d47583a0b700c12ed63132cf3312Benoit Goby mTracker = tracker; 701997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 711997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 72f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen public void interfaceStatusChanged(String iface, boolean up) { 73f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen Log.d(TAG, "Interface status changed: " + iface + (up ? "up" : "down")); 74f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen } 75f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen 76f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen public void interfaceLinkStateChanged(String iface, boolean up) { 77f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen if (mIface.equals(iface) && mLinkUp != up) { 78f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen Log.d(TAG, "Interface " + iface + " link " + (up ? "up" : "down")); 79f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen mLinkUp = up; 80efeba018bde81e02e1255714e3d4eeeb43c055e7Mike Lockwood mTracker.mNetworkInfo.setIsAvailable(up); 81f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen 82f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen // use DHCP 83f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen if (up) { 84f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen mTracker.reconnect(); 85f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen } else { 864bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen mTracker.disconnect(); 87f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen } 88f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen } 891997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 901997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 911997069436f0d47583a0b700c12ed63132cf3312Benoit Goby public void interfaceAdded(String iface) { 921997069436f0d47583a0b700c12ed63132cf3312Benoit Goby mTracker.interfaceAdded(iface); 931997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 941997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 951997069436f0d47583a0b700c12ed63132cf3312Benoit Goby public void interfaceRemoved(String iface) { 961997069436f0d47583a0b700c12ed63132cf3312Benoit Goby mTracker.interfaceRemoved(iface); 971997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 9812b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall 9912b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall public void limitReached(String limitName, String iface) { 10012b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall // Ignored. 10112b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall } 1021997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 1031997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 1041997069436f0d47583a0b700c12ed63132cf3312Benoit Goby private EthernetDataTracker() { 1051997069436f0d47583a0b700c12ed63132cf3312Benoit Goby mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_ETHERNET, 0, NETWORKTYPE, ""); 1061997069436f0d47583a0b700c12ed63132cf3312Benoit Goby mLinkProperties = new LinkProperties(); 1071997069436f0d47583a0b700c12ed63132cf3312Benoit Goby mLinkCapabilities = new LinkCapabilities(); 1081997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 1091997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 1101997069436f0d47583a0b700c12ed63132cf3312Benoit Goby private void interfaceAdded(String iface) { 111c96a667162fab44a250503caccb770109a9cb69aMike J. Chen if (!iface.matches(sIfaceMatch)) 1121997069436f0d47583a0b700c12ed63132cf3312Benoit Goby return; 1131997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 1141997069436f0d47583a0b700c12ed63132cf3312Benoit Goby Log.d(TAG, "Adding " + iface); 1151997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 116efeba018bde81e02e1255714e3d4eeeb43c055e7Mike Lockwood synchronized(this) { 1171997069436f0d47583a0b700c12ed63132cf3312Benoit Goby if(!mIface.isEmpty()) 1181997069436f0d47583a0b700c12ed63132cf3312Benoit Goby return; 1191997069436f0d47583a0b700c12ed63132cf3312Benoit Goby mIface = iface; 1201997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 1211997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 122198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt // we don't get link status indications unless the iface is up - bring it up 123198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt try { 124198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt mNMService.setInterfaceUp(iface); 125198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt } catch (Exception e) { 126198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt Log.e(TAG, "Error upping interface " + iface + ": " + e); 127198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt } 128198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt 1291997069436f0d47583a0b700c12ed63132cf3312Benoit Goby mNetworkInfo.setIsAvailable(true); 1301997069436f0d47583a0b700c12ed63132cf3312Benoit Goby Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo); 1311997069436f0d47583a0b700c12ed63132cf3312Benoit Goby msg.sendToTarget(); 1321997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 1331997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 1344bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen public void disconnect() { 1351997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 1361997069436f0d47583a0b700c12ed63132cf3312Benoit Goby NetworkUtils.stopDhcp(mIface); 1371997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 1381997069436f0d47583a0b700c12ed63132cf3312Benoit Goby mLinkProperties.clear(); 1391997069436f0d47583a0b700c12ed63132cf3312Benoit Goby mNetworkInfo.setIsAvailable(false); 140d60ae7f6688ea83df536c2eb1101a74ae1914ac6Doug Zongker mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, mHwAddr); 1411997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 1421997069436f0d47583a0b700c12ed63132cf3312Benoit Goby Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo); 1431997069436f0d47583a0b700c12ed63132cf3312Benoit Goby msg.sendToTarget(); 1441997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 1451997069436f0d47583a0b700c12ed63132cf3312Benoit Goby msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo); 1461997069436f0d47583a0b700c12ed63132cf3312Benoit Goby msg.sendToTarget(); 1471997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 1484bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 1494bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen INetworkManagementService service = INetworkManagementService.Stub.asInterface(b); 1504bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen try { 1514bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen service.clearInterfaceAddresses(mIface); 1524bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen } catch (Exception e) { 1534bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen Log.e(TAG, "Failed to clear addresses or disable ipv6" + e); 1544bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen } 1554bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen } 1564bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen 1574bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen private void interfaceRemoved(String iface) { 1584bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen if (!iface.equals(mIface)) 1594bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen return; 1604bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen 1614bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen Log.d(TAG, "Removing " + iface); 162efeba018bde81e02e1255714e3d4eeeb43c055e7Mike Lockwood disconnect(); 1631997069436f0d47583a0b700c12ed63132cf3312Benoit Goby mIface = ""; 1641997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 1651997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 1661997069436f0d47583a0b700c12ed63132cf3312Benoit Goby private void runDhcp() { 1671997069436f0d47583a0b700c12ed63132cf3312Benoit Goby Thread dhcpThread = new Thread(new Runnable() { 1681997069436f0d47583a0b700c12ed63132cf3312Benoit Goby public void run() { 1691997069436f0d47583a0b700c12ed63132cf3312Benoit Goby DhcpInfoInternal dhcpInfoInternal = new DhcpInfoInternal(); 1701997069436f0d47583a0b700c12ed63132cf3312Benoit Goby if (!NetworkUtils.runDhcp(mIface, dhcpInfoInternal)) { 1711997069436f0d47583a0b700c12ed63132cf3312Benoit Goby Log.e(TAG, "DHCP request error:" + NetworkUtils.getDhcpError()); 1721997069436f0d47583a0b700c12ed63132cf3312Benoit Goby return; 1731997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 1741997069436f0d47583a0b700c12ed63132cf3312Benoit Goby mLinkProperties = dhcpInfoInternal.makeLinkProperties(); 1751997069436f0d47583a0b700c12ed63132cf3312Benoit Goby mLinkProperties.setInterfaceName(mIface); 1761997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 177d60ae7f6688ea83df536c2eb1101a74ae1914ac6Doug Zongker mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, mHwAddr); 1781997069436f0d47583a0b700c12ed63132cf3312Benoit Goby Message msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo); 1791997069436f0d47583a0b700c12ed63132cf3312Benoit Goby msg.sendToTarget(); 1801997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 1811997069436f0d47583a0b700c12ed63132cf3312Benoit Goby }); 1821997069436f0d47583a0b700c12ed63132cf3312Benoit Goby dhcpThread.start(); 1831997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 1841997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 1851997069436f0d47583a0b700c12ed63132cf3312Benoit Goby public static synchronized EthernetDataTracker getInstance() { 1861997069436f0d47583a0b700c12ed63132cf3312Benoit Goby if (sInstance == null) sInstance = new EthernetDataTracker(); 1871997069436f0d47583a0b700c12ed63132cf3312Benoit Goby return sInstance; 1881997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 1891997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 1901997069436f0d47583a0b700c12ed63132cf3312Benoit Goby public Object Clone() throws CloneNotSupportedException { 1911997069436f0d47583a0b700c12ed63132cf3312Benoit Goby throw new CloneNotSupportedException(); 1921997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 1931997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 1941997069436f0d47583a0b700c12ed63132cf3312Benoit Goby public void setTeardownRequested(boolean isRequested) { 1951997069436f0d47583a0b700c12ed63132cf3312Benoit Goby mTeardownRequested.set(isRequested); 1961997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 1971997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 1981997069436f0d47583a0b700c12ed63132cf3312Benoit Goby public boolean isTeardownRequested() { 1991997069436f0d47583a0b700c12ed63132cf3312Benoit Goby return mTeardownRequested.get(); 2001997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 2011997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 2021997069436f0d47583a0b700c12ed63132cf3312Benoit Goby /** 2031997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * Begin monitoring connectivity 2041997069436f0d47583a0b700c12ed63132cf3312Benoit Goby */ 2051997069436f0d47583a0b700c12ed63132cf3312Benoit Goby public void startMonitoring(Context context, Handler target) { 2061997069436f0d47583a0b700c12ed63132cf3312Benoit Goby mContext = context; 2071997069436f0d47583a0b700c12ed63132cf3312Benoit Goby mCsHandler = target; 2081997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 2091997069436f0d47583a0b700c12ed63132cf3312Benoit Goby // register for notifications from NetworkManagement Service 2101997069436f0d47583a0b700c12ed63132cf3312Benoit Goby IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 211198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt mNMService = INetworkManagementService.Stub.asInterface(b); 212f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen 2131997069436f0d47583a0b700c12ed63132cf3312Benoit Goby mInterfaceObserver = new InterfaceObserver(this); 214c96a667162fab44a250503caccb770109a9cb69aMike J. Chen 215f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen // enable and try to connect to an ethernet interface that 216f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen // already exists 217c96a667162fab44a250503caccb770109a9cb69aMike J. Chen sIfaceMatch = context.getResources().getString( 218c96a667162fab44a250503caccb770109a9cb69aMike J. Chen com.android.internal.R.string.config_ethernet_iface_regex); 219c96a667162fab44a250503caccb770109a9cb69aMike J. Chen try { 220198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt final String[] ifaces = mNMService.listInterfaces(); 221c96a667162fab44a250503caccb770109a9cb69aMike J. Chen for (String iface : ifaces) { 222c96a667162fab44a250503caccb770109a9cb69aMike J. Chen if (iface.matches(sIfaceMatch)) { 223c96a667162fab44a250503caccb770109a9cb69aMike J. Chen mIface = iface; 224198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt mNMService.setInterfaceUp(iface); 225198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt InterfaceConfiguration config = mNMService.getInterfaceConfig(iface); 226f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen mLinkUp = config.isActive(); 227d60ae7f6688ea83df536c2eb1101a74ae1914ac6Doug Zongker if (config != null && mHwAddr == null) { 228efeba018bde81e02e1255714e3d4eeeb43c055e7Mike Lockwood mHwAddr = config.getHardwareAddress(); 229d60ae7f6688ea83df536c2eb1101a74ae1914ac6Doug Zongker if (mHwAddr != null) { 230d60ae7f6688ea83df536c2eb1101a74ae1914ac6Doug Zongker mNetworkInfo.setExtraInfo(mHwAddr); 231d60ae7f6688ea83df536c2eb1101a74ae1914ac6Doug Zongker } 232d60ae7f6688ea83df536c2eb1101a74ae1914ac6Doug Zongker } 233c96a667162fab44a250503caccb770109a9cb69aMike J. Chen reconnect(); 234c96a667162fab44a250503caccb770109a9cb69aMike J. Chen break; 235c96a667162fab44a250503caccb770109a9cb69aMike J. Chen } 236c96a667162fab44a250503caccb770109a9cb69aMike J. Chen } 237c96a667162fab44a250503caccb770109a9cb69aMike J. Chen } catch (RemoteException e) { 238c96a667162fab44a250503caccb770109a9cb69aMike J. Chen Log.e(TAG, "Could not get list of interfaces " + e); 239c96a667162fab44a250503caccb770109a9cb69aMike J. Chen } 240f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen 241f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen try { 242198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt mNMService.registerObserver(mInterfaceObserver); 243f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen } catch (RemoteException e) { 244f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen Log.e(TAG, "Could not register InterfaceObserver " + e); 245f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen } 2461997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 2471997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 2481997069436f0d47583a0b700c12ed63132cf3312Benoit Goby /** 2491997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * Disable connectivity to a network 2501997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * TODO: do away with return value after making MobileDataStateTracker async 2511997069436f0d47583a0b700c12ed63132cf3312Benoit Goby */ 2521997069436f0d47583a0b700c12ed63132cf3312Benoit Goby public boolean teardown() { 2531997069436f0d47583a0b700c12ed63132cf3312Benoit Goby mTeardownRequested.set(true); 2541997069436f0d47583a0b700c12ed63132cf3312Benoit Goby NetworkUtils.stopDhcp(mIface); 2551997069436f0d47583a0b700c12ed63132cf3312Benoit Goby return true; 2561997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 2571997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 2581997069436f0d47583a0b700c12ed63132cf3312Benoit Goby /** 2591997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * Re-enable connectivity to a network after a {@link #teardown()}. 2601997069436f0d47583a0b700c12ed63132cf3312Benoit Goby */ 2611997069436f0d47583a0b700c12ed63132cf3312Benoit Goby public boolean reconnect() { 262efeba018bde81e02e1255714e3d4eeeb43c055e7Mike Lockwood if (mLinkUp) { 263efeba018bde81e02e1255714e3d4eeeb43c055e7Mike Lockwood mTeardownRequested.set(false); 264efeba018bde81e02e1255714e3d4eeeb43c055e7Mike Lockwood runDhcp(); 265efeba018bde81e02e1255714e3d4eeeb43c055e7Mike Lockwood } 266efeba018bde81e02e1255714e3d4eeeb43c055e7Mike Lockwood return mLinkUp; 2671997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 2681997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 2691997069436f0d47583a0b700c12ed63132cf3312Benoit Goby /** 2701997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * Turn the wireless radio off for a network. 2711997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * @param turnOn {@code true} to turn the radio on, {@code false} 2721997069436f0d47583a0b700c12ed63132cf3312Benoit Goby */ 2731997069436f0d47583a0b700c12ed63132cf3312Benoit Goby public boolean setRadio(boolean turnOn) { 2741997069436f0d47583a0b700c12ed63132cf3312Benoit Goby return true; 2751997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 2761997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 2771997069436f0d47583a0b700c12ed63132cf3312Benoit Goby /** 2781997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * @return true - If are we currently tethered with another device. 2791997069436f0d47583a0b700c12ed63132cf3312Benoit Goby */ 2801997069436f0d47583a0b700c12ed63132cf3312Benoit Goby public synchronized boolean isAvailable() { 2811997069436f0d47583a0b700c12ed63132cf3312Benoit Goby return mNetworkInfo.isAvailable(); 2821997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 2831997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 2841997069436f0d47583a0b700c12ed63132cf3312Benoit Goby /** 2851997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * Tells the underlying networking system that the caller wants to 2861997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * begin using the named feature. The interpretation of {@code feature} 2871997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * is completely up to each networking implementation. 2881997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * @param feature the name of the feature to be used 2891997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * @param callingPid the process ID of the process that is issuing this request 2901997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * @param callingUid the user ID of the process that is issuing this request 2911997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * @return an integer value representing the outcome of the request. 2921997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * The interpretation of this value is specific to each networking 2931997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * implementation+feature combination, except that the value {@code -1} 2941997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * always indicates failure. 2951997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * TODO: needs to go away 2961997069436f0d47583a0b700c12ed63132cf3312Benoit Goby */ 2971997069436f0d47583a0b700c12ed63132cf3312Benoit Goby public int startUsingNetworkFeature(String feature, int callingPid, int callingUid) { 2981997069436f0d47583a0b700c12ed63132cf3312Benoit Goby return -1; 2991997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 3001997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 3011997069436f0d47583a0b700c12ed63132cf3312Benoit Goby /** 3021997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * Tells the underlying networking system that the caller is finished 3031997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * using the named feature. The interpretation of {@code feature} 3041997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * is completely up to each networking implementation. 3051997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * @param feature the name of the feature that is no longer needed. 3061997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * @param callingPid the process ID of the process that is issuing this request 3071997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * @param callingUid the user ID of the process that is issuing this request 3081997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * @return an integer value representing the outcome of the request. 3091997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * The interpretation of this value is specific to each networking 3101997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * implementation+feature combination, except that the value {@code -1} 3111997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * always indicates failure. 3121997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * TODO: needs to go away 3131997069436f0d47583a0b700c12ed63132cf3312Benoit Goby */ 3141997069436f0d47583a0b700c12ed63132cf3312Benoit Goby public int stopUsingNetworkFeature(String feature, int callingPid, int callingUid) { 3151997069436f0d47583a0b700c12ed63132cf3312Benoit Goby return -1; 3161997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 3171997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 3188e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey @Override 3198e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey public void setUserDataEnable(boolean enabled) { 3208e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey Log.w(TAG, "ignoring setUserDataEnable(" + enabled + ")"); 3218e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey } 3228e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey 3238e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey @Override 3248e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey public void setPolicyDataEnable(boolean enabled) { 3258e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey Log.w(TAG, "ignoring setPolicyDataEnable(" + enabled + ")"); 3261997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 3271997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 3281997069436f0d47583a0b700c12ed63132cf3312Benoit Goby /** 3291997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * Check if private DNS route is set for the network 3301997069436f0d47583a0b700c12ed63132cf3312Benoit Goby */ 3311997069436f0d47583a0b700c12ed63132cf3312Benoit Goby public boolean isPrivateDnsRouteSet() { 3321997069436f0d47583a0b700c12ed63132cf3312Benoit Goby return mPrivateDnsRouteSet.get(); 3331997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 3341997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 3351997069436f0d47583a0b700c12ed63132cf3312Benoit Goby /** 3361997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * Set a flag indicating private DNS route is set 3371997069436f0d47583a0b700c12ed63132cf3312Benoit Goby */ 3381997069436f0d47583a0b700c12ed63132cf3312Benoit Goby public void privateDnsRouteSet(boolean enabled) { 3391997069436f0d47583a0b700c12ed63132cf3312Benoit Goby mPrivateDnsRouteSet.set(enabled); 3401997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 3411997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 3421997069436f0d47583a0b700c12ed63132cf3312Benoit Goby /** 3431997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * Fetch NetworkInfo for the network 3441997069436f0d47583a0b700c12ed63132cf3312Benoit Goby */ 3451997069436f0d47583a0b700c12ed63132cf3312Benoit Goby public synchronized NetworkInfo getNetworkInfo() { 3461997069436f0d47583a0b700c12ed63132cf3312Benoit Goby return mNetworkInfo; 3471997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 3481997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 3491997069436f0d47583a0b700c12ed63132cf3312Benoit Goby /** 3501997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * Fetch LinkProperties for the network 3511997069436f0d47583a0b700c12ed63132cf3312Benoit Goby */ 3521997069436f0d47583a0b700c12ed63132cf3312Benoit Goby public synchronized LinkProperties getLinkProperties() { 3531997069436f0d47583a0b700c12ed63132cf3312Benoit Goby return new LinkProperties(mLinkProperties); 3541997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 3551997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 3561997069436f0d47583a0b700c12ed63132cf3312Benoit Goby /** 3571997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * A capability is an Integer/String pair, the capabilities 3581997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * are defined in the class LinkSocket#Key. 3591997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * 3601997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * @return a copy of this connections capabilities, may be empty but never null. 3611997069436f0d47583a0b700c12ed63132cf3312Benoit Goby */ 3621997069436f0d47583a0b700c12ed63132cf3312Benoit Goby public LinkCapabilities getLinkCapabilities() { 3631997069436f0d47583a0b700c12ed63132cf3312Benoit Goby return new LinkCapabilities(mLinkCapabilities); 3641997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 3651997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 3661997069436f0d47583a0b700c12ed63132cf3312Benoit Goby /** 3671997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * Fetch default gateway address for the network 3681997069436f0d47583a0b700c12ed63132cf3312Benoit Goby */ 3691997069436f0d47583a0b700c12ed63132cf3312Benoit Goby public int getDefaultGatewayAddr() { 3701997069436f0d47583a0b700c12ed63132cf3312Benoit Goby return mDefaultGatewayAddr.get(); 3711997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 3721997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 3731997069436f0d47583a0b700c12ed63132cf3312Benoit Goby /** 3741997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * Check if default route is set 3751997069436f0d47583a0b700c12ed63132cf3312Benoit Goby */ 3761997069436f0d47583a0b700c12ed63132cf3312Benoit Goby public boolean isDefaultRouteSet() { 3771997069436f0d47583a0b700c12ed63132cf3312Benoit Goby return mDefaultRouteSet.get(); 3781997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 3791997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 3801997069436f0d47583a0b700c12ed63132cf3312Benoit Goby /** 3811997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * Set a flag indicating default route is set for the network 3821997069436f0d47583a0b700c12ed63132cf3312Benoit Goby */ 3831997069436f0d47583a0b700c12ed63132cf3312Benoit Goby public void defaultRouteSet(boolean enabled) { 3841997069436f0d47583a0b700c12ed63132cf3312Benoit Goby mDefaultRouteSet.set(enabled); 3851997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 3861997069436f0d47583a0b700c12ed63132cf3312Benoit Goby 3871997069436f0d47583a0b700c12ed63132cf3312Benoit Goby /** 3881997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * Return the system properties name associated with the tcp buffer sizes 3891997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * for this network. 3901997069436f0d47583a0b700c12ed63132cf3312Benoit Goby */ 3911997069436f0d47583a0b700c12ed63132cf3312Benoit Goby public String getTcpBufferSizesPropName() { 3921997069436f0d47583a0b700c12ed63132cf3312Benoit Goby return "net.tcp.buffersize.wifi"; 3931997069436f0d47583a0b700c12ed63132cf3312Benoit Goby } 394af6eddb1c285a11841a2e1e0e3a41636f6bfd63dRobert Greenwalt 395af6eddb1c285a11841a2e1e0e3a41636f6bfd63dRobert Greenwalt public void setDependencyMet(boolean met) { 396af6eddb1c285a11841a2e1e0e3a41636f6bfd63dRobert Greenwalt // not supported on this network 397af6eddb1c285a11841a2e1e0e3a41636f6bfd63dRobert Greenwalt } 3981997069436f0d47583a0b700c12ed63132cf3312Benoit Goby} 399