120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti/* 220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * Copyright (C) 2014 The Android Open Source Project 320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * 420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * Licensed under the Apache License, Version 2.0 (the "License"); 520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * you may not use this file except in compliance with the License. 620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * You may obtain a copy of the License at 720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * 820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * http://www.apache.org/licenses/LICENSE-2.0 920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * 1020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * Unless required by applicable law or agreed to in writing, software 1120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * distributed under the License is distributed on an "AS IS" BASIS, 1220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * See the License for the specific language governing permissions and 1420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * limitations under the License. 1520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti */ 1620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 1720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittipackage com.android.server.ethernet; 1820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 1920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.content.Context; 2020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.net.ConnectivityManager; 2120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.net.DhcpResults; 22a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kimimport android.net.EthernetManager; 23a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kimimport android.net.IEthernetServiceListener; 2420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.net.InterfaceConfiguration; 2520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.net.IpConfiguration; 2620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.net.IpConfiguration.IpAssignment; 2720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.net.IpConfiguration.ProxySettings; 2820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.net.LinkProperties; 2920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.net.NetworkAgent; 3020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.net.NetworkCapabilities; 310d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwaltimport android.net.NetworkFactory; 3220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.net.NetworkInfo; 3320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.net.NetworkInfo.DetailedState; 34a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kimimport android.net.NetworkUtils; 3541a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colittiimport android.net.StaticIpConfiguration; 3620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.os.Handler; 3720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.os.IBinder; 3820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.os.INetworkManagementService; 3920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.os.Looper; 40a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kimimport android.os.RemoteCallbackList; 4120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.os.RemoteException; 4220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.os.ServiceManager; 4320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.text.TextUtils; 4420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport android.util.Log; 4520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 46aea43f5901e6591c390b83b10d3dd9b515a6442aLorenzo Colittiimport com.android.internal.util.IndentingPrintWriter; 4720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colittiimport com.android.server.net.BaseNetworkObserver; 4820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 49aea43f5901e6591c390b83b10d3dd9b515a6442aLorenzo Colittiimport java.io.FileDescriptor; 50aea43f5901e6591c390b83b10d3dd9b515a6442aLorenzo Colittiimport java.io.PrintWriter; 5120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 5220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 5320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti/** 54044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti * Manages connectivity for an Ethernet interface. 55044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti * 56044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti * Ethernet Interfaces may be present at boot time or appear after boot (e.g., 57044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti * for Ethernet adapters connected over USB). This class currently supports 58044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti * only one interface. When an interface appears on the system (or is present 59044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti * at boot time) this class will start tracking it and bring it up, and will 60044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti * attempt to connect when requested. Any other interfaces that subsequently 61044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti * appear will be ignored until the tracked interface disappears. Only 62044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti * interfaces whose names match the <code>config_ethernet_iface_regex</code> 63044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti * regular expression are tracked. 64044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti * 65044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti * This class reports a static network score of 70 when it is tracking an 66044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti * interface and that interface's link is up, and a score of 0 otherwise. 67044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti * 6820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * @hide 6920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti */ 700d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwaltclass EthernetNetworkFactory { 710d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt private static final String NETWORK_TYPE = "Ethernet"; 7220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti private static final String TAG = "EthernetNetworkFactory"; 7320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti private static final int NETWORK_SCORE = 70; 7420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti private static final boolean DBG = true; 7520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 76044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti /** Tracks interface changes. Called from NetworkManagementService. */ 7720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti private InterfaceObserver mInterfaceObserver; 7820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 7920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti /** For static IP configuration */ 8020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti private EthernetManager mEthernetManager; 8120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 8220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti /** To set link state and configure IP addresses. */ 8320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti private INetworkManagementService mNMService; 8420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 8520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti /* To communicate with ConnectivityManager */ 8620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti private NetworkCapabilities mNetworkCapabilities; 8720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti private NetworkAgent mNetworkAgent; 880d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt private LocalNetworkFactory mFactory; 890d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt private Context mContext; 9020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 91044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti /** Product-dependent regular expression of interface names we track. */ 9220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti private static String mIfaceMatch = ""; 9320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 94a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim /** To notify Ethernet status. */ 95a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim private final RemoteCallbackList<IEthernetServiceListener> mListeners; 96a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim 97044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti /** Data members. All accesses to these must be synchronized(this). */ 9820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti private static String mIface = ""; 9920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti private String mHwAddr; 10020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti private static boolean mLinkUp; 10120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti private NetworkInfo mNetworkInfo; 10220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti private LinkProperties mLinkProperties; 10320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 104a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim EthernetNetworkFactory(RemoteCallbackList<IEthernetServiceListener> listeners) { 10520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_ETHERNET, 0, NETWORK_TYPE, ""); 10620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti mLinkProperties = new LinkProperties(); 10720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti initNetworkCapabilities(); 108a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim mListeners = listeners; 10920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 11020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 1110d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt private class LocalNetworkFactory extends NetworkFactory { 1120d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt LocalNetworkFactory(String name, Context context, Looper looper) { 1130d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt super(looper, context, name, new NetworkCapabilities()); 1140d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt } 1150d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt 1160d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt protected void startNetwork() { 1170d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt onRequestNetwork(); 1180d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt } 1190d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt protected void stopNetwork() { 1200d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt } 1210d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt } 1220d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt 1230d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt 124044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti /** 125044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti * Updates interface state variables. 126044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti * Called on link state changes or on startup. 127044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti */ 12820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti private void updateInterfaceState(String iface, boolean up) { 12920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti if (!mIface.equals(iface)) { 13020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti return; 13120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 13220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti Log.d(TAG, "updateInterface: " + iface + " link " + (up ? "up" : "down")); 13320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 13420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti synchronized(this) { 13520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti mLinkUp = up; 13620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti mNetworkInfo.setIsAvailable(up); 137044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti if (!up) { 138044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti // Tell the agent we're disconnected. It will call disconnect(). 139044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, mHwAddr); 140044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti } 14120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti updateAgent(); 142e3cbf2e7349dd366f33905784595e2e3a1cec245Robert Greenwalt // set our score lower than any network could go 143e3cbf2e7349dd366f33905784595e2e3a1cec245Robert Greenwalt // so we get dropped. TODO - just unregister the factory 144e3cbf2e7349dd366f33905784595e2e3a1cec245Robert Greenwalt // when link goes down. 1450d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt mFactory.setScoreFilter(up ? NETWORK_SCORE : -1); 14620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 14720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 14820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 14920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti private class InterfaceObserver extends BaseNetworkObserver { 15020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti @Override 15120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti public void interfaceLinkStateChanged(String iface, boolean up) { 15220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti updateInterfaceState(iface, up); 15320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 15420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 15520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti @Override 15620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti public void interfaceAdded(String iface) { 15720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti maybeTrackInterface(iface); 15820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 15920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 16020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti @Override 16120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti public void interfaceRemoved(String iface) { 16220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti stopTrackingInterface(iface); 16320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 16420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 16520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 16620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti private void setInterfaceUp(String iface) { 16720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti // Bring up the interface so we get link status indications. 16820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti try { 16920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti mNMService.setInterfaceUp(iface); 17020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti String hwAddr = null; 17120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti InterfaceConfiguration config = mNMService.getInterfaceConfig(iface); 17220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 17320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti if (config == null) { 17420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti Log.e(TAG, "Null iterface config for " + iface + ". Bailing out."); 17520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti return; 17620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 17720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 17820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti synchronized (this) { 179a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim if (!isTrackingInterface()) { 180a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim setInterfaceInfoLocked(iface, config.getHardwareAddress()); 18120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti mNetworkInfo.setIsAvailable(true); 18220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti mNetworkInfo.setExtraInfo(mHwAddr); 18320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } else { 18420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti Log.e(TAG, "Interface unexpectedly changed from " + iface + " to " + mIface); 18520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti mNMService.setInterfaceDown(iface); 18620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 18720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 18820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } catch (RemoteException e) { 18920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti Log.e(TAG, "Error upping interface " + mIface + ": " + e); 19020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 19120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 19220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 19320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti private boolean maybeTrackInterface(String iface) { 19420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti // If we don't already have an interface, and if this interface matches 19520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti // our regex, start tracking it. 196a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim if (!iface.matches(mIfaceMatch) || isTrackingInterface()) 19720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti return false; 19820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 19920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti Log.d(TAG, "Started tracking interface " + iface); 20020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti setInterfaceUp(iface); 20120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti return true; 20220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 20320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 20420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti private void stopTrackingInterface(String iface) { 20520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti if (!iface.equals(mIface)) 20620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti return; 20720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 20820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti Log.d(TAG, "Stopped tracking interface " + iface); 20974d270d167ed6c3a6fa28e426da80d51a44a2af0Lorenzo Colitti // TODO: Unify this codepath with stop(). 21020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti synchronized (this) { 21174d270d167ed6c3a6fa28e426da80d51a44a2af0Lorenzo Colitti NetworkUtils.stopDhcp(mIface); 212a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim setInterfaceInfoLocked("", null); 21320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti mNetworkInfo.setExtraInfo(null); 21474d270d167ed6c3a6fa28e426da80d51a44a2af0Lorenzo Colitti mLinkUp = false; 21574d270d167ed6c3a6fa28e426da80d51a44a2af0Lorenzo Colitti mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, mHwAddr); 21674d270d167ed6c3a6fa28e426da80d51a44a2af0Lorenzo Colitti updateAgent(); 21774d270d167ed6c3a6fa28e426da80d51a44a2af0Lorenzo Colitti mNetworkAgent = null; 218044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_ETHERNET, 0, NETWORK_TYPE, ""); 219044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti mLinkProperties = new LinkProperties(); 22020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 22120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 22220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 22341a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti private boolean setStaticIpAddress(StaticIpConfiguration staticConfig) { 22441a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti if (staticConfig.ipAddress != null && 22541a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti staticConfig.gateway != null && 22641a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti staticConfig.dnsServers.size() > 0) { 22741a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti try { 22841a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti Log.i(TAG, "Applying static IPv4 configuration to " + mIface + ": " + staticConfig); 22941a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti InterfaceConfiguration config = mNMService.getInterfaceConfig(mIface); 23041a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti config.setLinkAddress(staticConfig.ipAddress); 23141a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti mNMService.setInterfaceConfig(mIface, config); 23241a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti return true; 23341a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti } catch(RemoteException|IllegalStateException e) { 23441a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti Log.e(TAG, "Setting static IP address failed: " + e.getMessage()); 23520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 23641a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti } else { 23741a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti Log.e(TAG, "Invalid static IP configuration."); 23820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 23941a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti return false; 24020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 24120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 2420d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt public void updateAgent() { 2430d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt synchronized (EthernetNetworkFactory.this) { 2440d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt if (mNetworkAgent == null) return; 2450d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt if (DBG) { 2460d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt Log.i(TAG, "Updating mNetworkAgent with: " + 2470d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt mNetworkCapabilities + ", " + 2480d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt mNetworkInfo + ", " + 2490d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt mLinkProperties); 2500d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt } 2510d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities); 2520d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt mNetworkAgent.sendNetworkInfo(mNetworkInfo); 2530d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt mNetworkAgent.sendLinkProperties(mLinkProperties); 254e3cbf2e7349dd366f33905784595e2e3a1cec245Robert Greenwalt // never set the network score below 0. 255e3cbf2e7349dd366f33905784595e2e3a1cec245Robert Greenwalt mNetworkAgent.sendNetworkScore(mLinkUp? NETWORK_SCORE : 0); 25620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 25720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 25820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 2590d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt /* Called by the NetworkFactory on the handler thread. */ 2600d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt public void onRequestNetwork() { 2610d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt // TODO: Handle DHCP renew. 26220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti Thread dhcpThread = new Thread(new Runnable() { 26320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti public void run() { 2640d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt if (DBG) Log.i(TAG, "dhcpThread(+" + mIface + "): mNetworkInfo=" + mNetworkInfo); 26520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti LinkProperties linkProperties; 26620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 26720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti IpConfiguration config = mEthernetManager.getConfiguration(); 26820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 26941a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti if (config.getIpAssignment() == IpAssignment.STATIC) { 27041a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti if (!setStaticIpAddress(config.getStaticIpConfiguration())) { 27141a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti // We've already logged an error. 27241a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti return; 27341a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti } 27441a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti linkProperties = config.getStaticIpConfiguration().toLinkProperties(mIface); 27520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } else { 2760d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt mNetworkInfo.setDetailedState(DetailedState.OBTAINING_IPADDR, null, mHwAddr); 2770d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt 27820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti DhcpResults dhcpResults = new DhcpResults(); 279044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti // TODO: Handle DHCP renewals better. 280044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti // In general runDhcp handles DHCP renewals for us, because 281044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti // the dhcp client stays running, but if the renewal fails, 282044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti // we will lose our IP address and connectivity without 283044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti // noticing. 28420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti if (!NetworkUtils.runDhcp(mIface, dhcpResults)) { 28520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti Log.e(TAG, "DHCP request error:" + NetworkUtils.getDhcpError()); 286e3cbf2e7349dd366f33905784595e2e3a1cec245Robert Greenwalt // set our score lower than any network could go 287e3cbf2e7349dd366f33905784595e2e3a1cec245Robert Greenwalt // so we get dropped. 2880d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt mFactory.setScoreFilter(-1); 28920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti return; 29020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 29141a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti linkProperties = dhcpResults.toLinkProperties(mIface); 29220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 29341a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti if (config.getProxySettings() == ProxySettings.STATIC || 29441a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti config.getProxySettings() == ProxySettings.PAC) { 29541a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti linkProperties.setHttpProxy(config.getHttpProxy()); 29620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 29720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 29869b9c6a7d6453c1c76857c5edfeb1d89a1315674Robert Greenwalt String tcpBufferSizes = mContext.getResources().getString( 29969b9c6a7d6453c1c76857c5edfeb1d89a1315674Robert Greenwalt com.android.internal.R.string.config_ethernet_tcp_buffers); 30069b9c6a7d6453c1c76857c5edfeb1d89a1315674Robert Greenwalt if (TextUtils.isEmpty(tcpBufferSizes) == false) { 30169b9c6a7d6453c1c76857c5edfeb1d89a1315674Robert Greenwalt linkProperties.setTcpBufferSizes(tcpBufferSizes); 30269b9c6a7d6453c1c76857c5edfeb1d89a1315674Robert Greenwalt } 303dcbf3b908024d9ce1d3bf9216f8af11503459afcRobert Greenwalt 30420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti synchronized(EthernetNetworkFactory.this) { 3053191f909a20216646f1652537eba6804b5435c74Robert Greenwalt if (mNetworkAgent != null) { 3063191f909a20216646f1652537eba6804b5435c74Robert Greenwalt Log.e(TAG, "Already have a NetworkAgent - aborting new request"); 3073191f909a20216646f1652537eba6804b5435c74Robert Greenwalt return; 3083191f909a20216646f1652537eba6804b5435c74Robert Greenwalt } 30920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti mLinkProperties = linkProperties; 31020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti mNetworkInfo.setIsAvailable(true); 31120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, mHwAddr); 3120d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt 3130d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt // Create our NetworkAgent. 3140d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt mNetworkAgent = new NetworkAgent(mFactory.getLooper(), mContext, 3150d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt NETWORK_TYPE, mNetworkInfo, mNetworkCapabilities, mLinkProperties, 3160d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt NETWORK_SCORE) { 3170d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt public void unwanted() { 3183191f909a20216646f1652537eba6804b5435c74Robert Greenwalt synchronized(EthernetNetworkFactory.this) { 3193191f909a20216646f1652537eba6804b5435c74Robert Greenwalt if (this == mNetworkAgent) { 3203191f909a20216646f1652537eba6804b5435c74Robert Greenwalt NetworkUtils.stopDhcp(mIface); 3213191f909a20216646f1652537eba6804b5435c74Robert Greenwalt 3223191f909a20216646f1652537eba6804b5435c74Robert Greenwalt mLinkProperties.clear(); 3233191f909a20216646f1652537eba6804b5435c74Robert Greenwalt mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, 3243191f909a20216646f1652537eba6804b5435c74Robert Greenwalt mHwAddr); 3253191f909a20216646f1652537eba6804b5435c74Robert Greenwalt updateAgent(); 3263191f909a20216646f1652537eba6804b5435c74Robert Greenwalt mNetworkAgent = null; 3273191f909a20216646f1652537eba6804b5435c74Robert Greenwalt try { 3283191f909a20216646f1652537eba6804b5435c74Robert Greenwalt mNMService.clearInterfaceAddresses(mIface); 3293191f909a20216646f1652537eba6804b5435c74Robert Greenwalt } catch (Exception e) { 3303191f909a20216646f1652537eba6804b5435c74Robert Greenwalt Log.e(TAG, "Failed to clear addresses or disable ipv6" + e); 3313191f909a20216646f1652537eba6804b5435c74Robert Greenwalt } 3323191f909a20216646f1652537eba6804b5435c74Robert Greenwalt } else { 3333191f909a20216646f1652537eba6804b5435c74Robert Greenwalt Log.d(TAG, "Ignoring unwanted as we have a more modern " + 3343191f909a20216646f1652537eba6804b5435c74Robert Greenwalt "instance"); 3353191f909a20216646f1652537eba6804b5435c74Robert Greenwalt } 3363191f909a20216646f1652537eba6804b5435c74Robert Greenwalt } 3370d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt }; 3380d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt }; 33920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 34020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 34120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti }); 34220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti dhcpThread.start(); 34320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 34420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 345044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti /** 34620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti * Begin monitoring connectivity 34720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti */ 34820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti public synchronized void start(Context context, Handler target) { 34920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti // The services we use. 35020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 35120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti mNMService = INetworkManagementService.Stub.asInterface(b); 35220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti mEthernetManager = (EthernetManager) context.getSystemService(Context.ETHERNET_SERVICE); 35320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 35420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti // Interface match regex. 35520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti mIfaceMatch = context.getResources().getString( 35620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti com.android.internal.R.string.config_ethernet_iface_regex); 35720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 35820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti // Create and register our NetworkFactory. 3590d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt mFactory = new LocalNetworkFactory(NETWORK_TYPE, context, target.getLooper()); 3600d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt mFactory.setCapabilityFilter(mNetworkCapabilities); 3610d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt mFactory.setScoreFilter(-1); // this set high when we have an iface 36220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti mFactory.register(); 36320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 3640d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt mContext = context; 3650d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt 36620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti // Start tracking interface change events. 36720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti mInterfaceObserver = new InterfaceObserver(); 36820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti try { 36920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti mNMService.registerObserver(mInterfaceObserver); 37020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } catch (RemoteException e) { 37120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti Log.e(TAG, "Could not register InterfaceObserver " + e); 37220c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 37320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 37420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti // If an Ethernet interface is already connected, start tracking that. 37520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti // Otherwise, the first Ethernet interface to appear will be tracked. 37620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti try { 37720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti final String[] ifaces = mNMService.listInterfaces(); 37820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti for (String iface : ifaces) { 379044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti synchronized(this) { 380044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti if (maybeTrackInterface(iface)) { 381044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti // We have our interface. Track it. 382044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti // Note: if the interface already has link (e.g., if we 383044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti // crashed and got restarted while it was running), 384044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti // we need to fake a link up notification so we start 385044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti // configuring it. Since we're already holding the lock, 386044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti // any real link up/down notification will only arrive 387044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti // after we've done this. 388044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti if (mNMService.getInterfaceConfig(iface).hasFlag("running")) { 389044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti updateInterfaceState(iface, true); 390044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti } 391044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti break; 392044a758ebb1e38df875a45e9cfe84f4a53352abaLorenzo Colitti } 39320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 39420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 39520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } catch (RemoteException e) { 39620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti Log.e(TAG, "Could not get list of interfaces " + e); 39720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 39820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 39920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 40020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti public synchronized void stop() { 40141a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti NetworkUtils.stopDhcp(mIface); 40241a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti // ConnectivityService will only forget our NetworkAgent if we send it a NetworkInfo object 40341a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti // with a state of DISCONNECTED or SUSPENDED. So we can't simply clear our NetworkInfo here: 40441a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti // that sets the state to IDLE, and ConnectivityService will still think we're connected. 40541a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti // 40641a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti // TODO: stop using explicit comparisons to DISCONNECTED / SUSPENDED in ConnectivityService, 40741a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti // and instead use isConnectedOrConnecting(). 40841a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, mHwAddr); 40941a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti mLinkUp = false; 41041a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti updateAgent(); 41141a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti mLinkProperties = new LinkProperties(); 41241a372f13a7d19807d91e09f2e955b8a61f02d5cLorenzo Colitti mNetworkAgent = null; 413a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim setInterfaceInfoLocked("", null); 4140d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_ETHERNET, 0, NETWORK_TYPE, ""); 4150d1b1749dad71372d9baeb0f852d3d91fccac73dRobert Greenwalt mFactory.unregister(); 41620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 41720c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti 41820c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti private void initNetworkCapabilities() { 41920c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti mNetworkCapabilities = new NetworkCapabilities(); 42020c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti mNetworkCapabilities.addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET); 4214b1ec3fc8e4e4b432328297c45519fa4f6baa3cdRobert Greenwalt mNetworkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); 4224b1ec3fc8e4e4b432328297c45519fa4f6baa3cdRobert Greenwalt mNetworkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED); 42320c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti // We have no useful data on bandwidth. Say 100M up and 100M down. :-( 42420c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti mNetworkCapabilities.setLinkUpstreamBandwidthKbps(100 * 1000); 42520c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti mNetworkCapabilities.setLinkDownstreamBandwidthKbps(100 * 1000); 42620c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti } 427aea43f5901e6591c390b83b10d3dd9b515a6442aLorenzo Colitti 428a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim public synchronized boolean isTrackingInterface() { 429a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim return !TextUtils.isEmpty(mIface); 430a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim } 431a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim 432a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim /** 433a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim * Set interface information and notify listeners if availability is changed. 434a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim * This should be called with the lock held. 435a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim */ 436a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim private void setInterfaceInfoLocked(String iface, String hwAddr) { 437a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim boolean oldAvailable = isTrackingInterface(); 438a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim mIface = iface; 439a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim mHwAddr = hwAddr; 440a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim boolean available = isTrackingInterface(); 441a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim 442a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim if (oldAvailable != available) { 443a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim int n = mListeners.beginBroadcast(); 444a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim for (int i = 0; i < n; i++) { 445a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim try { 446a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim mListeners.getBroadcastItem(i).onAvailabilityChanged(available); 447a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim } catch (RemoteException e) { 448a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim // Do nothing here. 449a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim } 450a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim } 451a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim mListeners.finishBroadcast(); 452a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim } 453a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim } 454a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim 455aea43f5901e6591c390b83b10d3dd9b515a6442aLorenzo Colitti synchronized void dump(FileDescriptor fd, IndentingPrintWriter pw, String[] args) { 456a3d7e61812f8d68ca109280c4e7589e4f968723aJaewan Kim if (isTrackingInterface()) { 457aea43f5901e6591c390b83b10d3dd9b515a6442aLorenzo Colitti pw.println("Tracking interface: " + mIface); 458aea43f5901e6591c390b83b10d3dd9b515a6442aLorenzo Colitti pw.increaseIndent(); 459aea43f5901e6591c390b83b10d3dd9b515a6442aLorenzo Colitti pw.println("MAC address: " + mHwAddr); 460aea43f5901e6591c390b83b10d3dd9b515a6442aLorenzo Colitti pw.println("Link state: " + (mLinkUp ? "up" : "down")); 461aea43f5901e6591c390b83b10d3dd9b515a6442aLorenzo Colitti pw.decreaseIndent(); 462aea43f5901e6591c390b83b10d3dd9b515a6442aLorenzo Colitti } else { 463aea43f5901e6591c390b83b10d3dd9b515a6442aLorenzo Colitti pw.println("Not tracking any interface"); 464aea43f5901e6591c390b83b10d3dd9b515a6442aLorenzo Colitti } 465aea43f5901e6591c390b83b10d3dd9b515a6442aLorenzo Colitti 466aea43f5901e6591c390b83b10d3dd9b515a6442aLorenzo Colitti pw.println(); 467aea43f5901e6591c390b83b10d3dd9b515a6442aLorenzo Colitti pw.println("NetworkInfo: " + mNetworkInfo); 468aea43f5901e6591c390b83b10d3dd9b515a6442aLorenzo Colitti pw.println("LinkProperties: " + mLinkProperties); 469aea43f5901e6591c390b83b10d3dd9b515a6442aLorenzo Colitti pw.println("NetworkAgent: " + mNetworkAgent); 470aea43f5901e6591c390b83b10d3dd9b515a6442aLorenzo Colitti } 47120c1c99c4351abd8bb3d6e8f966fcf3b6de0e5b0Lorenzo Colitti} 472