Tethering.java revision 3c2a2f6789ee257e3838ffb0f3f117e08825ad5f
1d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt/* 2d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt * Copyright (C) 2010 The Android Open Source Project 3d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt * 4d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt * Licensed under the Apache License, Version 2.0 (the "License"); 5d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt * you may not use this file except in compliance with the License. 6d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt * You may obtain a copy of the License at 7d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt * 8d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt * http://www.apache.org/licenses/LICENSE-2.0 9d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt * 10d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt * Unless required by applicable law or agreed to in writing, software 11d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt * distributed under the License is distributed on an "AS IS" BASIS, 12d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt * See the License for the specific language governing permissions and 14d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt * limitations under the License. 15d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt */ 16d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 17d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltpackage com.android.server.connectivity; 18d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 19d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.app.Notification; 20d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.app.NotificationManager; 21d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.app.PendingIntent; 226fdd0c6274c81b337ad35b70480f881daf7354c3Danica Changimport android.bluetooth.BluetoothPan; 23d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.content.BroadcastReceiver; 24d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.content.Context; 25d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.content.Intent; 26d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.content.IntentFilter; 272a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport android.content.pm.PackageManager; 28d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.content.res.Resources; 29c4308f01c965571dc2354107c3574df113e397eeMike Lockwoodimport android.hardware.usb.UsbManager; 30d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.net.ConnectivityManager; 3165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwaltimport android.net.InterfaceConfiguration; 322a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport android.net.IConnectivityManager; 33d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.net.INetworkManagementEventObserver; 34ed1264093234b1f1354cd5f669eb82a50bb56869Robert Greenwaltimport android.net.LinkAddress; 3505d8936f275762bab0d66c6337e352388c8eeee0Robert Greenwaltimport android.net.LinkProperties; 362a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport android.net.NetworkInfo; 37e590373ea71251cfffc8f22f011e2e6335dce716Robert Greenwaltimport android.net.NetworkUtils; 382a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport android.os.Binder; 39030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwaltimport android.os.Environment; 406eef5c687677b5965f769c62f50edda25abb431eMike Lockwoodimport android.os.Handler; 417eae25021d3aa71c7616ea766f9a4d5af3b1772bRobert Greenwaltimport android.os.HandlerThread; 42d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.os.IBinder; 43d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.os.INetworkManagementService; 44dfadaeac088cabce854d8f476405cd412f82593aRobert Greenwaltimport android.os.Looper; 452a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport android.os.Message; 46d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.os.RemoteException; 47d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.os.ServiceManager; 48d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.provider.Settings; 49d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.util.Log; 50d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 512a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport com.android.internal.telephony.Phone; 5264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Savilleimport com.android.internal.util.IState; 5364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Savilleimport com.android.internal.util.State; 5464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Savilleimport com.android.internal.util.StateMachine; 552a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 562a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport java.io.FileDescriptor; 572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport java.io.PrintWriter; 5804808c294027f8bc318643a94c85a999257d7f52Robert Greenwaltimport java.net.InetAddress; 59d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport java.util.ArrayList; 602a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport java.util.HashMap; 616fdd0c6274c81b337ad35b70480f881daf7354c3Danica Changimport java.util.LinkedList; 622a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport java.util.Set; 63d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt/** 64d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt * @hide 652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt * 662a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt * Timeout 672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt * 682a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt * TODO - look for parent classes and code sharing 69d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt */ 7065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 71d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltpublic class Tethering extends INetworkManagementEventObserver.Stub { 72d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 73d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt private Context mContext; 74924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt private final static String TAG = "Tethering"; 751039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt private final static boolean DEBUG = true; 76d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 77c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt private boolean mBooted = false; 78c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt //used to remember if we got connected before boot finished 79c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt private boolean mDeferedUsbConnection = false; 80d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 812a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // TODO - remove both of these - should be part of interface inspection/selection stuff 822a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private String[] mTetherableUsbRegexs; 832a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private String[] mTetherableWifiRegexs; 846fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang private String[] mTetherableBluetoothRegexs; 85c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt private String[] mUpstreamIfaceRegexs; 862a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 87c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh private INetworkManagementService mNMService; 887eae25021d3aa71c7616ea766f9a4d5af3b1772bRobert Greenwalt private Looper mLooper; 897eae25021d3aa71c7616ea766f9a4d5af3b1772bRobert Greenwalt private HandlerThread mThread; 90dfadaeac088cabce854d8f476405cd412f82593aRobert Greenwalt 91030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt private HashMap<String, TetherInterfaceSM> mIfaces; // all tethered/tetherable ifaces 92d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 93d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt private BroadcastReceiver mStateReceiver; 94d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 95bfb7bfa53847832db2a3eb05e5eff7cb974c3c7aRobert Greenwalt private static final String USB_NEAR_IFACE_ADDR = "192.168.42.129"; 96b979f79158f9c470fa09ff3b96d72db274262201Robert Greenwalt private static final int USB_PREFIX_LENGTH = 24; 97bfb7bfa53847832db2a3eb05e5eff7cb974c3c7aRobert Greenwalt 98707952ecd4b6cae25aabcf51f94d702a65847e9eJaikumar Ganesh // USB is 192.168.42.1 and 255.255.255.0 99707952ecd4b6cae25aabcf51f94d702a65847e9eJaikumar Ganesh // Wifi is 192.168.43.1 and 255.255.255.0 100707952ecd4b6cae25aabcf51f94d702a65847e9eJaikumar Ganesh // BT is limited to max default of 5 connections. 192.168.44.1 to 192.168.48.1 101707952ecd4b6cae25aabcf51f94d702a65847e9eJaikumar Ganesh // with 255.255.255.0 102d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt 1032a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private String[] mDhcpRange; 104c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh private static final String[] DHCP_DEFAULT_RANGE = { 105c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh "192.168.42.2", "192.168.42.254", "192.168.43.2", "192.168.43.254", 106c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh "192.168.44.2", "192.168.44.254", "192.168.45.2", "192.168.45.254", 107c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh "192.168.46.2", "192.168.46.254", "192.168.47.2", "192.168.47.254", 108c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh "192.168.48.2", "192.168.48.254", 109c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh }; 1102a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 1112a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private String[] mDnsServers; 112d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt private static final String DNS_DEFAULT_SERVER1 = "8.8.8.8"; 113df255c2283b2bcf2d5e70d095a4d2333c1cb80a3Robert Greenwalt private static final String DNS_DEFAULT_SERVER2 = "8.8.4.4"; 1142a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 11577b32ddbbeeb13a07b16f23af705567c75a8e3dfRobert Greenwalt // resampled each time we turn on tethering - used as cache for settings/config-val 116030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt private boolean mDunRequired; // configuration info - must use DUN apn on 3g 117030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt 11864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville private StateMachine mTetherMasterSM; 119a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt 120a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt private Notification mTetheredNotification; 1212a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 122030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt // whether we can tether is the && of these two - they come in as separate 123030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt // broadcasts so track them so we can decide what to do when either changes 124030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt private boolean mUsbMassStorageOff; // track the status of USB Mass Storage 125030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt private boolean mUsbConnected; // track the status of USB connection 126030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt 127c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh public Tethering(Context context, INetworkManagementService nmService, Looper looper) { 128d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt mContext = context; 129c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh mNMService = nmService; 130dfadaeac088cabce854d8f476405cd412f82593aRobert Greenwalt mLooper = looper; 131d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 1322a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mIfaces = new HashMap<String, TetherInterfaceSM>(); 133d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 1347eae25021d3aa71c7616ea766f9a4d5af3b1772bRobert Greenwalt // make our own thread so we don't anr the system 1357eae25021d3aa71c7616ea766f9a4d5af3b1772bRobert Greenwalt mThread = new HandlerThread("Tethering"); 1367eae25021d3aa71c7616ea766f9a4d5af3b1772bRobert Greenwalt mThread.start(); 1377eae25021d3aa71c7616ea766f9a4d5af3b1772bRobert Greenwalt mLooper = mThread.getLooper(); 138dfadaeac088cabce854d8f476405cd412f82593aRobert Greenwalt mTetherMasterSM = new TetherMasterSM("TetherMaster", mLooper); 1392a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTetherMasterSM.start(); 1402a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 141bb51d9feea260e1527628b878319c0cf76adadebRobert Greenwalt mStateReceiver = new StateReceiver(); 142d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt IntentFilter filter = new IntentFilter(); 143770126a678ccc9328a89407ffc82f4d998b25427Mike Lockwood filter.addAction(UsbManager.ACTION_USB_STATE); 1442a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); 145c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt filter.addAction(Intent.ACTION_BOOT_COMPLETED); 146bb51d9feea260e1527628b878319c0cf76adadebRobert Greenwalt mContext.registerReceiver(mStateReceiver, filter); 147bb51d9feea260e1527628b878319c0cf76adadebRobert Greenwalt 148bb51d9feea260e1527628b878319c0cf76adadebRobert Greenwalt filter = new IntentFilter(); 149030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt filter.addAction(Intent.ACTION_MEDIA_SHARED); 150030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt filter.addAction(Intent.ACTION_MEDIA_UNSHARED); 151bb51d9feea260e1527628b878319c0cf76adadebRobert Greenwalt filter.addDataScheme("file"); 152bb51d9feea260e1527628b878319c0cf76adadebRobert Greenwalt mContext.registerReceiver(mStateReceiver, filter); 153bb51d9feea260e1527628b878319c0cf76adadebRobert Greenwalt 154030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt mUsbMassStorageOff = !Environment.MEDIA_SHARED.equals( 155030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt Environment.getExternalStorageState()); 1562a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 1572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mDhcpRange = context.getResources().getStringArray( 1582a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt com.android.internal.R.array.config_tether_dhcp_range); 159bfb7bfa53847832db2a3eb05e5eff7cb974c3c7aRobert Greenwalt if ((mDhcpRange.length == 0) || (mDhcpRange.length % 2 ==1)) { 160c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh mDhcpRange = DHCP_DEFAULT_RANGE; 1612a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 16277b32ddbbeeb13a07b16f23af705567c75a8e3dfRobert Greenwalt mDunRequired = false; // resample when we turn on 1632a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 1642a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTetherableUsbRegexs = context.getResources().getStringArray( 1652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt com.android.internal.R.array.config_tether_usb_regexs); 1662a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTetherableWifiRegexs = context.getResources().getStringArray( 1672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt com.android.internal.R.array.config_tether_wifi_regexs); 1686fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang mTetherableBluetoothRegexs = context.getResources().getStringArray( 1696fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang com.android.internal.R.array.config_tether_bluetooth_regexs); 170c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt mUpstreamIfaceRegexs = context.getResources().getStringArray( 171c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt com.android.internal.R.array.config_tether_upstream_regexs); 1722a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 1732a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // TODO - remove and rely on real notifications of the current iface 1742a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mDnsServers = new String[2]; 175d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt mDnsServers[0] = DNS_DEFAULT_SERVER1; 176d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt mDnsServers[1] = DNS_DEFAULT_SERVER2; 177d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 178d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 1792a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void interfaceLinkStatusChanged(String iface, boolean link) { 180924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt if (DEBUG) Log.d(TAG, "interfaceLinkStatusChanged " + iface + ", " + link); 1812a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean found = false; 18265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt boolean usb = false; 183a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt if (isWifi(iface)) { 184a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt found = true; 185a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } else if (isUsb(iface)) { 186a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt found = true; 187a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt usb = true; 1886fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang } else if (isBluetooth(iface)) { 1896fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang found = true; 1902a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 1912a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (found == false) return; 1922a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 1932a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt synchronized (mIfaces) { 1942a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = mIfaces.get(iface); 1952a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (link) { 1962a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm == null) { 197dfadaeac088cabce854d8f476405cd412f82593aRobert Greenwalt sm = new TetherInterfaceSM(iface, mLooper, usb); 1982a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mIfaces.put(iface, sm); 1992a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sm.start(); 2002a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 2012a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } else { 2022a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm != null) { 2036a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt sm.sendMessage(TetherInterfaceSM.CMD_INTERFACE_DOWN); 2042a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mIfaces.remove(iface); 2052a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 2062a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 2072a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 208d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 209d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 210a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt private boolean isUsb(String iface) { 211a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt for (String regex : mTetherableUsbRegexs) { 212a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt if (iface.matches(regex)) return true; 213a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } 214a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt return false; 215a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } 216a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt 217a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt public boolean isWifi(String iface) { 218a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt for (String regex : mTetherableWifiRegexs) { 219a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt if (iface.matches(regex)) return true; 220a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } 221a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt return false; 222a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } 223a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt 2246fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang public boolean isBluetooth(String iface) { 2256fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang for (String regex : mTetherableBluetoothRegexs) { 2266fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang if (iface.matches(regex)) return true; 2276fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang } 2286fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang return false; 2296fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang } 2302a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void interfaceAdded(String iface) { 2312a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean found = false; 23265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt boolean usb = false; 233a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt if (isWifi(iface)) { 234a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt found = true; 2352a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 236a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt if (isUsb(iface)) { 237a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt found = true; 238a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt usb = true; 239d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 2406fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang if (isBluetooth(iface)) { 2416fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang found = true; 2426fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang } 2432a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (found == false) { 244924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt if (DEBUG) Log.d(TAG, iface + " is not a tetherable iface, ignoring"); 245d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt return; 246d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 24765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 2482a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt synchronized (mIfaces) { 2492a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = mIfaces.get(iface); 2502a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm != null) { 251924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt if (DEBUG) Log.d(TAG, "active iface (" + iface + ") reported as added, ignoring"); 2522a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return; 2532a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 254dfadaeac088cabce854d8f476405cd412f82593aRobert Greenwalt sm = new TetherInterfaceSM(iface, mLooper, usb); 2552a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mIfaces.put(iface, sm); 2562a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sm.start(); 2572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 258924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt if (DEBUG) Log.d(TAG, "interfaceAdded :" + iface); 259d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 260d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 2612a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void interfaceRemoved(String iface) { 2622a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt synchronized (mIfaces) { 2632a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = mIfaces.get(iface); 2642a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm == null) { 265924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt if (DEBUG) { 266924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt Log.e(TAG, "attempting to remove unknown iface (" + iface + "), ignoring"); 267924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt } 2682a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return; 2692a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 2706a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt sm.sendMessage(TetherInterfaceSM.CMD_INTERFACE_DOWN); 2712a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mIfaces.remove(iface); 272d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 273d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 274d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 2755a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt public int tether(String iface) { 276d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt Log.d(TAG, "Tethering " + iface); 2772a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = null; 2782a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt synchronized (mIfaces) { 2792a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sm = mIfaces.get(iface); 280d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 2812a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm == null) { 2822a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Tried to Tether an unknown iface :" + iface + ", ignoring"); 2835a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE; 284d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 2855a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt if (!sm.isAvailable() && !sm.isErrored()) { 2862a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Tried to Tether an unavailable iface :" + iface + ", ignoring"); 2875a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt return ConnectivityManager.TETHER_ERROR_UNAVAIL_IFACE; 288d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 2896a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt sm.sendMessage(TetherInterfaceSM.CMD_TETHER_REQUESTED); 2905a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt return ConnectivityManager.TETHER_ERROR_NO_ERROR; 291d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 292d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 2935a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt public int untether(String iface) { 294d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt Log.d(TAG, "Untethering " + iface); 2952a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = null; 2962a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt synchronized (mIfaces) { 2972a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sm = mIfaces.get(iface); 2982a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 2992a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm == null) { 3002a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Tried to Untether an unknown iface :" + iface + ", ignoring"); 3015a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE; 302d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 3032a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm.isErrored()) { 3042a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Tried to Untethered an errored iface :" + iface + ", ignoring"); 3055a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt return ConnectivityManager.TETHER_ERROR_UNAVAIL_IFACE; 306d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 3076a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt sm.sendMessage(TetherInterfaceSM.CMD_TETHER_UNREQUESTED); 3085a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt return ConnectivityManager.TETHER_ERROR_NO_ERROR; 3095a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } 3105a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt 3115a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt public int getLastTetherError(String iface) { 3125a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt TetherInterfaceSM sm = null; 3135a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt synchronized (mIfaces) { 3145a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt sm = mIfaces.get(iface); 3155a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } 3165a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt if (sm == null) { 3175a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt Log.e(TAG, "Tried to getLastTetherError on an unknown iface :" + iface + ", ignoring"); 3185a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE; 3195a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } 3205a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt return sm.getLastError(); 3212a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 322d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 3232a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private void sendTetherStateChangedBroadcast() { 3242a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); 325c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b); 326d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt try { 327c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh if (!cm.isTetheringSupported()) return; 3282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (RemoteException e) { 3292a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return; 330d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 331d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 3322a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt ArrayList<String> availableList = new ArrayList<String>(); 3332a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt ArrayList<String> activeList = new ArrayList<String>(); 3342a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt ArrayList<String> erroredList = new ArrayList<String>(); 3352a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 336a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt boolean wifiTethered = false; 337a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt boolean usbTethered = false; 3386fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang boolean bluetoothTethered = false; 339a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt 3402a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt synchronized (mIfaces) { 3412a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Set ifaces = mIfaces.keySet(); 3422a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (Object iface : ifaces) { 3432a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = mIfaces.get(iface); 3442a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm != null) { 3456fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang if (sm.isErrored()) { 3462a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt erroredList.add((String)iface); 3472a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } else if (sm.isAvailable()) { 3482a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt availableList.add((String)iface); 3492a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } else if (sm.isTethered()) { 350a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt if (isUsb((String)iface)) { 351a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt usbTethered = true; 352a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } else if (isWifi((String)iface)) { 353a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt wifiTethered = true; 3546fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang } else if (isBluetooth((String)iface)) { 3556fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang bluetoothTethered = true; 356a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } 3572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt activeList.add((String)iface); 3582a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 3592a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 360d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 361d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 362d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt Intent broadcast = new Intent(ConnectivityManager.ACTION_TETHER_STATE_CHANGED); 363d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt broadcast.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 3642a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt broadcast.putStringArrayListExtra(ConnectivityManager.EXTRA_AVAILABLE_TETHER, 3652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt availableList); 3662a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt broadcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ACTIVE_TETHER, activeList); 3672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt broadcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ERRORED_TETHER, 3682a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt erroredList); 3692a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mContext.sendStickyBroadcast(broadcast); 370924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt if (DEBUG) { 371924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt Log.d(TAG, "sendTetherStateChangedBroadcast " + availableList.size() + ", " + 372924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt activeList.size() + ", " + erroredList.size()); 373924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt } 374a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt 375a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt if (usbTethered) { 3766fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang if (wifiTethered || bluetoothTethered) { 377a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt showTetheredNotification(com.android.internal.R.drawable.stat_sys_tether_general); 378a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } else { 379a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt showTetheredNotification(com.android.internal.R.drawable.stat_sys_tether_usb); 380a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } 381a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } else if (wifiTethered) { 3826fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang if (bluetoothTethered) { 3836fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang showTetheredNotification(com.android.internal.R.drawable.stat_sys_tether_general); 3846fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang } else { 3856fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang showTetheredNotification(com.android.internal.R.drawable.stat_sys_tether_wifi); 3866fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang } 3876fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang } else if (bluetoothTethered) { 3886fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang showTetheredNotification(com.android.internal.R.drawable.stat_sys_tether_bluetooth); 389a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } else { 390a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt clearTetheredNotification(); 391a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } 392a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } 393a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt 394a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt private void showTetheredNotification(int icon) { 395a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt NotificationManager notificationManager = 396a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt (NotificationManager)mContext.getSystemService(Context.NOTIFICATION_SERVICE); 397a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt if (notificationManager == null) { 398a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt return; 399a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } 400a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt 401db3fe9edd4cb638d3dd20b23456f6cdb0a414ed1Robert Greenwalt if (mTetheredNotification != null) { 402db3fe9edd4cb638d3dd20b23456f6cdb0a414ed1Robert Greenwalt if (mTetheredNotification.icon == icon) { 403db3fe9edd4cb638d3dd20b23456f6cdb0a414ed1Robert Greenwalt return; 404db3fe9edd4cb638d3dd20b23456f6cdb0a414ed1Robert Greenwalt } 405db3fe9edd4cb638d3dd20b23456f6cdb0a414ed1Robert Greenwalt notificationManager.cancel(mTetheredNotification.icon); 406db3fe9edd4cb638d3dd20b23456f6cdb0a414ed1Robert Greenwalt } 407db3fe9edd4cb638d3dd20b23456f6cdb0a414ed1Robert Greenwalt 408a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt Intent intent = new Intent(); 409a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt intent.setClassName("com.android.settings", "com.android.settings.TetherSettings"); 410a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); 411a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt 412a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0); 413a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt 414a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt Resources r = Resources.getSystem(); 415a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt CharSequence title = r.getText(com.android.internal.R.string.tethered_notification_title); 416a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt CharSequence message = r.getText(com.android.internal.R.string. 417a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt tethered_notification_message); 418a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt 4196fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang if (mTetheredNotification == null) { 420a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt mTetheredNotification = new Notification(); 421a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt mTetheredNotification.when = 0; 422a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } 423a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt mTetheredNotification.icon = icon; 424a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt mTetheredNotification.defaults &= ~Notification.DEFAULT_SOUND; 425a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt mTetheredNotification.flags = Notification.FLAG_ONGOING_EVENT; 426a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt mTetheredNotification.tickerText = title; 427a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt mTetheredNotification.setLatestEventInfo(mContext, title, message, pi); 428a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt 429a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt notificationManager.notify(mTetheredNotification.icon, mTetheredNotification); 430a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } 431a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt 432a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt private void clearTetheredNotification() { 433a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt NotificationManager notificationManager = 434a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt (NotificationManager)mContext.getSystemService(Context.NOTIFICATION_SERVICE); 435a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt if (notificationManager != null && mTetheredNotification != null) { 436a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt notificationManager.cancel(mTetheredNotification.icon); 437a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt mTetheredNotification = null; 438a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } 4395a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } 4405a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt 441030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt private void updateUsbStatus() { 442030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt boolean enable = mUsbConnected && mUsbMassStorageOff; 443030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt 444030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt if (mBooted) { 445030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt enableUsbIfaces(enable); 446030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt } 447030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt } 448030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt 4492a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private class StateReceiver extends BroadcastReceiver { 450d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt public void onReceive(Context content, Intent intent) { 4512a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt String action = intent.getAction(); 452770126a678ccc9328a89407ffc82f4d998b25427Mike Lockwood if (action.equals(UsbManager.ACTION_USB_STATE)) { 453b92df0f66926252cf60cdda7812bb1d50ce9378eMike Lockwood mUsbConnected = intent.getExtras().getBoolean(UsbManager.USB_CONNECTED); 454b92df0f66926252cf60cdda7812bb1d50ce9378eMike Lockwood updateUsbStatus(); 455030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt } else if (action.equals(Intent.ACTION_MEDIA_SHARED)) { 456030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt mUsbMassStorageOff = false; 457030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt updateUsbStatus(); 458030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt } 459030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt else if (action.equals(Intent.ACTION_MEDIA_UNSHARED)) { 460030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt mUsbMassStorageOff = true; 461030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt updateUsbStatus(); 4622a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { 463924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt if (DEBUG) Log.d(TAG, "Tethering got CONNECTIVITY_ACTION"); 4646a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt mTetherMasterSM.sendMessage(TetherMasterSM.CMD_UPSTREAM_CHANGED); 465c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } else if (action.equals(Intent.ACTION_BOOT_COMPLETED)) { 466c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt mBooted = true; 467030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt updateUsbStatus(); 468d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 469d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 470d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 471d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 47265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt // used on cable insert/remove 473d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt private void enableUsbIfaces(boolean enable) { 4743c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood // add/remove USB interfaces when USB is connected/disconnected 4753c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood for (String intf : mTetherableUsbRegexs) { 4763c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood if (enable) { 4773c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood interfaceAdded(intf); 4783c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood } else { 4793c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood interfaceRemoved(intf); 4803c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood } 4813c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood } 4823c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood 48365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt String[] ifaces = new String[0]; 48465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt try { 485c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh ifaces = mNMService.listInterfaces(); 48665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } catch (Exception e) { 4873c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood Log.e(TAG, "Error listing Interfaces", e); 48865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt return; 48965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 49065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt for (String iface : ifaces) { 491a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt if (isUsb(iface)) { 492a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt if (enable) { 493a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt interfaceAdded(iface); 494a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } else { 495a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt interfaceRemoved(iface); 49665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 49765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 49865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 49965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 50065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 5016fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang // toggled when we enter/leave the fully tethered state 502d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt private boolean enableUsbRndis(boolean enabled) { 503924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt if (DEBUG) Log.d(TAG, "enableUsbRndis(" + enabled + ")"); 50465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 5053c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood UsbManager usbManager = (UsbManager)mContext.getSystemService(Context.USB_SERVICE); 5063c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood if (usbManager == null) { 5073c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood Log.d(TAG, "could not get UsbManager"); 5083c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood return false; 5093c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood } 51065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt try { 51165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt if (enabled) { 5123c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood usbManager.setPrimaryFunction(UsbManager.USB_FUNCTION_RNDIS); 51365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } else { 5143c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood usbManager.setPrimaryFunction(null); 51565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 51665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } catch (Exception e) { 5173c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood Log.e(TAG, "Error toggling usb RNDIS", e); 51865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt return false; 51965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 52065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt return true; 52165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 52265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 52365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt // configured when we start tethering and unconfig'd on error or conclusion 524d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt private boolean configureUsbIface(boolean enabled) { 525924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt if (DEBUG) Log.d(TAG, "configureUsbIface(" + enabled + ")"); 52665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 5273c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood if (enabled) { 5283c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood // must enable RNDIS first to create the interface 5293c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood enableUsbRndis(enabled); 53065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 5313c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood 5323c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood try { 5333c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood // bring toggle the interfaces 5343c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood String[] ifaces = new String[0]; 5353c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood try { 5363c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood ifaces = mNMService.listInterfaces(); 5373c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood } catch (Exception e) { 5383c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood Log.e(TAG, "Error listing Interfaces", e); 5393c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood return false; 5403c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood } 5413c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood for (String iface : ifaces) { 5423c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood if (isUsb(iface)) { 5433c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood InterfaceConfiguration ifcg = null; 5443c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood try { 5453c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood ifcg = mNMService.getInterfaceConfig(iface); 5463c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood if (ifcg != null) { 5473c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood InetAddress addr = NetworkUtils.numericToInetAddress(USB_NEAR_IFACE_ADDR); 5483c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood ifcg.addr = new LinkAddress(addr, USB_PREFIX_LENGTH); 5493c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood if (enabled) { 5503c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood ifcg.interfaceFlags = ifcg.interfaceFlags.replace("down", "up"); 5513c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood } else { 5523c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood ifcg.interfaceFlags = ifcg.interfaceFlags.replace("up", "down"); 5533c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood } 5543c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood ifcg.interfaceFlags = ifcg.interfaceFlags.replace("running", ""); 5553c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood ifcg.interfaceFlags = ifcg.interfaceFlags.replace(" "," "); 5563c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood mNMService.setInterfaceConfig(iface, ifcg); 55765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 5583c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood } catch (Exception e) { 5593c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood Log.e(TAG, "Error configuring interface " + iface, e); 5603c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood return false; 56165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 56265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 5633c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood } 5643c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood } finally { 5653c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood if (!enabled) { 5663c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood enableUsbRndis(false); 56765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 56865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 56965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 57065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt return true; 57165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 57265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 5732a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public String[] getTetherableUsbRegexs() { 5742a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return mTetherableUsbRegexs; 5752a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 5762a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 5772a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public String[] getTetherableWifiRegexs() { 5782a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return mTetherableWifiRegexs; 5792a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 5802a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 5816fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang public String[] getTetherableBluetoothRegexs() { 5826fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang return mTetherableBluetoothRegexs; 5836fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang } 5846fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang 585c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt public String[] getUpstreamIfaceRegexs() { 586c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt return mUpstreamIfaceRegexs; 587c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 588c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt 589c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt public boolean isDunRequired() { 59077b32ddbbeeb13a07b16f23af705567c75a8e3dfRobert Greenwalt boolean defaultVal = mContext.getResources().getBoolean( 59177b32ddbbeeb13a07b16f23af705567c75a8e3dfRobert Greenwalt com.android.internal.R.bool.config_tether_dun_required); 59277b32ddbbeeb13a07b16f23af705567c75a8e3dfRobert Greenwalt boolean result = (Settings.Secure.getInt(mContext.getContentResolver(), 59377b32ddbbeeb13a07b16f23af705567c75a8e3dfRobert Greenwalt Settings.Secure.TETHER_DUN_REQUIRED, (defaultVal ? 1 : 0)) == 1); 59477b32ddbbeeb13a07b16f23af705567c75a8e3dfRobert Greenwalt return result; 595c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 596c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt 5972a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public String[] getTetheredIfaces() { 5982a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt ArrayList<String> list = new ArrayList<String>(); 5992a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt synchronized (mIfaces) { 6002a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Set keys = mIfaces.keySet(); 6012a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (Object key : keys) { 6022a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = mIfaces.get(key); 6032a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm.isTethered()) { 6042a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt list.add((String)key); 6052a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 6062a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 6072a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 6082a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt String[] retVal = new String[list.size()]; 6092a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (int i=0; i < list.size(); i++) { 6102a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retVal[i] = list.get(i); 6112a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 6122a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retVal; 6132a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 6142a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 6152a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public String[] getTetherableIfaces() { 6162a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt ArrayList<String> list = new ArrayList<String>(); 6172a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt synchronized (mIfaces) { 6182a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Set keys = mIfaces.keySet(); 6192a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (Object key : keys) { 6202a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = mIfaces.get(key); 6212a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm.isAvailable()) { 6222a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt list.add((String)key); 6232a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 6242a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 6252a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 6262a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt String[] retVal = new String[list.size()]; 6272a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (int i=0; i < list.size(); i++) { 6282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retVal[i] = list.get(i); 6292a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 6302a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retVal; 6312a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 6322a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 6335a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt public String[] getErroredIfaces() { 6345a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt ArrayList<String> list = new ArrayList<String>(); 6355a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt synchronized (mIfaces) { 6365a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt Set keys = mIfaces.keySet(); 6375a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt for (Object key : keys) { 6385a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt TetherInterfaceSM sm = mIfaces.get(key); 6395a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt if (sm.isErrored()) { 6405a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt list.add((String)key); 6415a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } 6425a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } 6435a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } 6445a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt String[] retVal = new String[list.size()]; 6455a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt for (int i= 0; i< list.size(); i++) { 6465a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt retVal[i] = list.get(i); 6475a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } 6485a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt return retVal; 6495a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } 6505a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt 65101758e81b3ad89934581885bb2fc7006510ec639Kazuhiro Ondo public void handleTetherIfaceChange(String iface) { 65201758e81b3ad89934581885bb2fc7006510ec639Kazuhiro Ondo // check if iface is white listed 65301758e81b3ad89934581885bb2fc7006510ec639Kazuhiro Ondo for (String regex : mUpstreamIfaceRegexs) { 65401758e81b3ad89934581885bb2fc7006510ec639Kazuhiro Ondo if (iface.matches(regex)) { 65501758e81b3ad89934581885bb2fc7006510ec639Kazuhiro Ondo if (DEBUG) Log.d(TAG, "Tethering got Interface Change"); 65601758e81b3ad89934581885bb2fc7006510ec639Kazuhiro Ondo mTetherMasterSM.sendMessage(TetherMasterSM.CMD_IFACE_CHANGED, iface); 65701758e81b3ad89934581885bb2fc7006510ec639Kazuhiro Ondo break; 65801758e81b3ad89934581885bb2fc7006510ec639Kazuhiro Ondo } 65901758e81b3ad89934581885bb2fc7006510ec639Kazuhiro Ondo } 66001758e81b3ad89934581885bb2fc7006510ec639Kazuhiro Ondo } 6612a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 66264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville class TetherInterfaceSM extends StateMachine { 6632a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification from the master SM that it's not in tether mode 6646a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt static final int CMD_TETHER_MODE_DEAD = 1; 6652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // request from the user that it wants to tether 6666a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt static final int CMD_TETHER_REQUESTED = 2; 6672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // request from the user that it wants to untether 6686a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt static final int CMD_TETHER_UNREQUESTED = 3; 6692a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification that this interface is down 6706a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt static final int CMD_INTERFACE_DOWN = 4; 6712a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification that this interface is up 6726a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt static final int CMD_INTERFACE_UP = 5; 6732a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification from the master SM that it had an error turning on cellular dun 6746a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt static final int CMD_CELL_DUN_ERROR = 6; 6752a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification from the master SM that it had trouble enabling IP Forwarding 6766a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt static final int CMD_IP_FORWARDING_ENABLE_ERROR = 7; 6772a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification from the master SM that it had trouble disabling IP Forwarding 6786a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt static final int CMD_IP_FORWARDING_DISABLE_ERROR = 8; 6792a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification from the master SM that it had trouble staring tethering 6806a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt static final int CMD_START_TETHERING_ERROR = 9; 6812a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification from the master SM that it had trouble stopping tethering 6826a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt static final int CMD_STOP_TETHERING_ERROR = 10; 6832a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification from the master SM that it had trouble setting the DNS forwarders 6846a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt static final int CMD_SET_DNS_FORWARDERS_ERROR = 11; 6856a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt // the upstream connection has changed 686951749ba2e014566553d17c512e947472951a060Wink Saville static final int CMD_TETHER_CONNECTION_CHANGED = 12; 6872a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 68864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville private State mDefaultState; 6892a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 69064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville private State mInitialState; 69164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville private State mStartingState; 69264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville private State mTetheredState; 6932a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 69464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville private State mUnavailableState; 6952a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 6962a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private boolean mAvailable; 6972a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private boolean mTethered; 6985a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt int mLastError; 6992a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 7002a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt String mIfaceName; 7016a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt String mMyUpstreamIfaceName; // may change over time 7026a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt 70365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt boolean mUsb; 7042a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 705dfadaeac088cabce854d8f476405cd412f82593aRobert Greenwalt TetherInterfaceSM(String name, Looper looper, boolean usb) { 706dfadaeac088cabce854d8f476405cd412f82593aRobert Greenwalt super(name, looper); 7072a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mIfaceName = name; 70865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt mUsb = usb; 7095a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastError(ConnectivityManager.TETHER_ERROR_NO_ERROR); 7102a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 7112a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mInitialState = new InitialState(); 7122a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mInitialState); 7132a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mStartingState = new StartingState(); 7142a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mStartingState); 7152a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTetheredState = new TetheredState(); 7162a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mTetheredState); 7172a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mUnavailableState = new UnavailableState(); 7182a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mUnavailableState); 7192a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 7202a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setInitialState(mInitialState); 7212a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7222a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 7232a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public String toString() { 7242a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt String res = new String(); 7252a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt res += mIfaceName + " - "; 72664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville IState current = getCurrentState(); 7272a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (current == mInitialState) res += "InitialState"; 7282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (current == mStartingState) res += "StartingState"; 7292a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (current == mTetheredState) res += "TetheredState"; 7302a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (current == mUnavailableState) res += "UnavailableState"; 7312a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (mAvailable) res += " - Available"; 7322a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (mTethered) res += " - Tethered"; 7335a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt res += " - lastError =" + mLastError; 7342a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return res; 7352a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7362a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 7375a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt public synchronized int getLastError() { 7385a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt return mLastError; 7395a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } 7405a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt 7415a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt private synchronized void setLastError(int error) { 7425a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt mLastError = error; 7435a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt 7445a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt if (isErrored()) { 7455a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt if (mUsb) { 7465a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt // note everything's been unwound by this point so nothing to do on 7475a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt // further error.. 7485a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt Tethering.this.configureUsbIface(false); 7495a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } 7505a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } 7515a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } 7525a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt 7532a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // synchronized between this getter and the following setter 7542a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public synchronized boolean isAvailable() { 7552a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return mAvailable; 7562a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 7582a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private synchronized void setAvailable(boolean available) { 7592a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mAvailable = available; 7602a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7612a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 7622a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // synchronized between this getter and the following setter 7632a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public synchronized boolean isTethered() { 7642a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return mTethered; 7652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7662a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 7672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private synchronized void setTethered(boolean tethered) { 7682a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTethered = tethered; 7692a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7702a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 7712a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // synchronized between this getter and the following setter 7722a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public synchronized boolean isErrored() { 7735a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt return (mLastError != ConnectivityManager.TETHER_ERROR_NO_ERROR); 7742a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7752a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 77664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville class InitialState extends State { 7772a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 7782a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 7792a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setAvailable(true); 7802a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setTethered(false); 7812a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendTetherStateChangedBroadcast(); 7822a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7832a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 7842a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 7852a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public boolean processMessage(Message message) { 786924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt if (DEBUG) Log.d(TAG, "InitialState.processMessage what=" + message.what); 7872a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean retValue = true; 7882a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt switch (message.what) { 7892a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_REQUESTED: 7905a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastError(ConnectivityManager.TETHER_ERROR_NO_ERROR); 7916a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt mTetherMasterSM.sendMessage(TetherMasterSM.CMD_TETHER_MODE_REQUESTED, 7926a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt TetherInterfaceSM.this); 7932a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mStartingState); 7942a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 7952a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_INTERFACE_DOWN: 7962a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mUnavailableState); 7972a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 7982a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt default: 7992a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retValue = false; 8002a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 8012a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 8022a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retValue; 8032a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 8042a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 8052a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 80664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville class StartingState extends State { 8072a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 8082a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 8092a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setAvailable(false); 81065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt if (mUsb) { 811d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt if (!Tethering.this.configureUsbIface(true)) { 8126a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt mTetherMasterSM.sendMessage(TetherMasterSM.CMD_TETHER_MODE_UNREQUESTED, 8136a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt TetherInterfaceSM.this); 8145a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastError(ConnectivityManager.TETHER_ERROR_IFACE_CFG_ERROR); 8155a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt 816951749ba2e014566553d17c512e947472951a060Wink Saville transitionTo(mInitialState); 81765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt return; 81865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 81965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 8202a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendTetherStateChangedBroadcast(); 8216a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt 822951749ba2e014566553d17c512e947472951a060Wink Saville // Skipping StartingState 823951749ba2e014566553d17c512e947472951a060Wink Saville transitionTo(mTetheredState); 8242a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 8252a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 8262a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public boolean processMessage(Message message) { 827924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt if (DEBUG) Log.d(TAG, "StartingState.processMessage what=" + message.what); 8282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean retValue = true; 8292a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt switch (message.what) { 8302a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // maybe a parent class? 8312a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_UNREQUESTED: 8326a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt mTetherMasterSM.sendMessage(TetherMasterSM.CMD_TETHER_MODE_UNREQUESTED, 8336a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt TetherInterfaceSM.this); 83465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt if (mUsb) { 835d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt if (!Tethering.this.configureUsbIface(false)) { 8365a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastErrorAndTransitionToInitialState( 8375a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt ConnectivityManager.TETHER_ERROR_IFACE_CFG_ERROR); 83865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt break; 83965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 84065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 8412a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mInitialState); 8422a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 8432a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_CELL_DUN_ERROR: 8442a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_IP_FORWARDING_ENABLE_ERROR: 8452a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_IP_FORWARDING_DISABLE_ERROR: 8462a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_START_TETHERING_ERROR: 8472a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_STOP_TETHERING_ERROR: 8482a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_SET_DNS_FORWARDERS_ERROR: 8495a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastErrorAndTransitionToInitialState( 8505a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt ConnectivityManager.TETHER_ERROR_MASTER_ERROR); 8512a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 8522a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_INTERFACE_DOWN: 8536a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt mTetherMasterSM.sendMessage(TetherMasterSM.CMD_TETHER_MODE_UNREQUESTED, 8546a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt TetherInterfaceSM.this); 8552a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mUnavailableState); 8562a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 8572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt default: 8582a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retValue = false; 8592a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 8602a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retValue; 8612a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 8622a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 8632a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 86464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville class TetheredState extends State { 8652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 8662a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 8672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 868c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh mNMService.tetherInterface(mIfaceName); 8692a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) { 8705a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastError(ConnectivityManager.TETHER_ERROR_TETHER_IFACE_ERROR); 8715a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt 872951749ba2e014566553d17c512e947472951a060Wink Saville transitionTo(mInitialState); 8732a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return; 8742a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 875924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt if (DEBUG) Log.d(TAG, "Tethered " + mIfaceName); 8762a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setAvailable(false); 8772a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setTethered(true); 8782a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendTetherStateChangedBroadcast(); 8792a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 8802a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 8812a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public boolean processMessage(Message message) { 882924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt if (DEBUG) Log.d(TAG, "TetheredState.processMessage what=" + message.what); 8832a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean retValue = true; 8842a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean error = false; 8852a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt switch (message.what) { 8862a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_UNREQUESTED: 8872a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_INTERFACE_DOWN: 8886a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt if (mMyUpstreamIfaceName != null) { 8895a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt try { 890c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh mNMService.disableNat(mIfaceName, mMyUpstreamIfaceName); 891b37f0c6513241f79a6ea0e3c162dc540d028b60cRobert Greenwalt mMyUpstreamIfaceName = null; 8926a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt } catch (Exception e) { 8936a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt try { 894c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh mNMService.untetherInterface(mIfaceName); 8956a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt } catch (Exception ee) {} 8965a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt 8976a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt setLastErrorAndTransitionToInitialState( 8986a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt ConnectivityManager.TETHER_ERROR_DISABLE_NAT_ERROR); 8996a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt break; 9006a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt } 9012a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 9022a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 903c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh mNMService.untetherInterface(mIfaceName); 9042a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) { 9055a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastErrorAndTransitionToInitialState( 9065a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt ConnectivityManager.TETHER_ERROR_UNTETHER_IFACE_ERROR); 9072a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 9082a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 9096a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt mTetherMasterSM.sendMessage(TetherMasterSM.CMD_TETHER_MODE_UNREQUESTED, 9106a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt TetherInterfaceSM.this); 9112a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (message.what == CMD_TETHER_UNREQUESTED) { 91265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt if (mUsb) { 913d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt if (!Tethering.this.configureUsbIface(false)) { 9145a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastError( 9155a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt ConnectivityManager.TETHER_ERROR_IFACE_CFG_ERROR); 91665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 91765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 9185a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt transitionTo(mInitialState); 9192a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } else if (message.what == CMD_INTERFACE_DOWN) { 9202a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mUnavailableState); 9212a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 922924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt if (DEBUG) Log.d(TAG, "Untethered " + mIfaceName); 9232a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 9246a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt case CMD_TETHER_CONNECTION_CHANGED: 9256a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt String newUpstreamIfaceName = (String)(message.obj); 9261039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt if ((mMyUpstreamIfaceName == null && newUpstreamIfaceName == null) || 9271039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt (mMyUpstreamIfaceName != null && 9281039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt mMyUpstreamIfaceName.equals(newUpstreamIfaceName))) { 9291039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt if (DEBUG) Log.d(TAG, "Connection changed noop - dropping"); 9301039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt break; 9311039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt } 9326a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt if (mMyUpstreamIfaceName != null) { 9336a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt try { 934c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh mNMService.disableNat(mIfaceName, mMyUpstreamIfaceName); 935b37f0c6513241f79a6ea0e3c162dc540d028b60cRobert Greenwalt mMyUpstreamIfaceName = null; 9366a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt } catch (Exception e) { 9376a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt try { 938c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh mNMService.untetherInterface(mIfaceName); 9396a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt } catch (Exception ee) {} 9406a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt 9416a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt setLastErrorAndTransitionToInitialState( 9426a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt ConnectivityManager.TETHER_ERROR_DISABLE_NAT_ERROR); 9436a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt break; 9446a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt } 9456a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt } 9466a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt if (newUpstreamIfaceName != null) { 9476a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt try { 948c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh mNMService.enableNat(mIfaceName, newUpstreamIfaceName); 9496a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt } catch (Exception e) { 9506a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt try { 951c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh mNMService.untetherInterface(mIfaceName); 9526a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt } catch (Exception ee) {} 9536a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt 9546a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt setLastError(ConnectivityManager.TETHER_ERROR_ENABLE_NAT_ERROR); 9556a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt transitionTo(mInitialState); 9566a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt return true; 9576a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt } 9586a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt } 9596a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt mMyUpstreamIfaceName = newUpstreamIfaceName; 9606a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt break; 9612a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_CELL_DUN_ERROR: 9622a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_IP_FORWARDING_ENABLE_ERROR: 9632a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_IP_FORWARDING_DISABLE_ERROR: 9642a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_START_TETHERING_ERROR: 9652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_STOP_TETHERING_ERROR: 9662a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_SET_DNS_FORWARDERS_ERROR: 9672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt error = true; 9682a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // fall through 9692a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_MODE_DEAD: 9706a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt if (mMyUpstreamIfaceName != null) { 9715a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt try { 972c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh mNMService.disableNat(mIfaceName, mMyUpstreamIfaceName); 973b37f0c6513241f79a6ea0e3c162dc540d028b60cRobert Greenwalt mMyUpstreamIfaceName = null; 9746a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt } catch (Exception e) { 9756a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt try { 976c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh mNMService.untetherInterface(mIfaceName); 9776a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt } catch (Exception ee) {} 9785a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt 9796a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt setLastErrorAndTransitionToInitialState( 9806a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt ConnectivityManager.TETHER_ERROR_DISABLE_NAT_ERROR); 9816a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt break; 9826a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt } 9832a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 9842a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 985c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh mNMService.untetherInterface(mIfaceName); 9862a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) { 9875a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastErrorAndTransitionToInitialState( 9885a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt ConnectivityManager.TETHER_ERROR_UNTETHER_IFACE_ERROR); 9892a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 9902a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 9912a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (error) { 9925a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastErrorAndTransitionToInitialState( 9935a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt ConnectivityManager.TETHER_ERROR_MASTER_ERROR); 9942a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 9952a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 996924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt if (DEBUG) Log.d(TAG, "Tether lost upstream connection " + mIfaceName); 9972a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendTetherStateChangedBroadcast(); 99865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt if (mUsb) { 999d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt if (!Tethering.this.configureUsbIface(false)) { 10005a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastError(ConnectivityManager.TETHER_ERROR_IFACE_CFG_ERROR); 100165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 100265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 10032a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mInitialState); 10042a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 10052a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt default: 10062a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retValue = false; 10072a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 10082a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 10092a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retValue; 10102a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 10112a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 10122a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 101364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville class UnavailableState extends State { 10142a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 10152a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 10162a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setAvailable(false); 10175a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastError(ConnectivityManager.TETHER_ERROR_NO_ERROR); 10182a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setTethered(false); 10192a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendTetherStateChangedBroadcast(); 10202a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 10212a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 10222a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public boolean processMessage(Message message) { 10232a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean retValue = true; 10242a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt switch (message.what) { 10252a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_INTERFACE_UP: 10262a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mInitialState); 10272a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 10282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt default: 10292a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retValue = false; 10302a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 10312a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 10322a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retValue; 10332a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 10342a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 10352a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 10365a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt void setLastErrorAndTransitionToInitialState(int error) { 10375a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastError(error); 10385a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt transitionTo(mInitialState); 10392a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 104065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 10412a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 10422a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 104364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville class TetherMasterSM extends StateMachine { 10442a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // an interface SM has requested Tethering 10452a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_TETHER_MODE_REQUESTED = 1; 10462a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // an interface SM has unrequested Tethering 10472a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_TETHER_MODE_UNREQUESTED = 2; 10486a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt // upstream connection change - do the right thing 10496a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt static final int CMD_UPSTREAM_CHANGED = 3; 10502a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // we received notice that the cellular DUN connection is up 10516a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt static final int CMD_CELL_CONNECTION_RENEW = 4; 10526a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt // we don't have a valid upstream conn, check again after a delay 1053951749ba2e014566553d17c512e947472951a060Wink Saville static final int CMD_RETRY_UPSTREAM = 5; 105401758e81b3ad89934581885bb2fc7006510ec639Kazuhiro Ondo // received an indication that upstream interface has changed 105501758e81b3ad89934581885bb2fc7006510ec639Kazuhiro Ondo static final int CMD_IFACE_CHANGED = 6; 10562a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 10572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // This indicates what a timeout event relates to. A state that 10582a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // sends itself a delayed timeout event and handles incoming timeout events 10592a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // should inc this when it is entered and whenever it sends a new timeout event. 10602a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // We do not flush the old ones. 10612a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private int mSequenceNumber; 10622a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 106364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville private State mInitialState; 106464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville private State mTetherModeAliveState; 10652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 106664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville private State mSetIpForwardingEnabledErrorState; 106764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville private State mSetIpForwardingDisabledErrorState; 106864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville private State mStartTetheringErrorState; 106964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville private State mStopTetheringErrorState; 107064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville private State mSetDnsForwardersErrorState; 10712a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 10722a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private ArrayList mNotifyList; 10732a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 10741039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt private int mCurrentConnectionSequence; 10751039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt private boolean mMobileReserved = false; 10762a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 1077b37f0c6513241f79a6ea0e3c162dc540d028b60cRobert Greenwalt private String mUpstreamIfaceName = null; 1078b37f0c6513241f79a6ea0e3c162dc540d028b60cRobert Greenwalt 10796a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt private static final int UPSTREAM_SETTLE_TIME_MS = 10000; 10806a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt private static final int CELL_CONNECTION_RENEW_MS = 40000; 10812a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 1082dfadaeac088cabce854d8f476405cd412f82593aRobert Greenwalt TetherMasterSM(String name, Looper looper) { 1083dfadaeac088cabce854d8f476405cd412f82593aRobert Greenwalt super(name, looper); 10842a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 10852a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt //Add states 10862a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mInitialState = new InitialState(); 10872a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mInitialState); 10882a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTetherModeAliveState = new TetherModeAliveState(); 10892a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mTetherModeAliveState); 10902a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 10912a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mSetIpForwardingEnabledErrorState = new SetIpForwardingEnabledErrorState(); 10922a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mSetIpForwardingEnabledErrorState); 10932a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mSetIpForwardingDisabledErrorState = new SetIpForwardingDisabledErrorState(); 10942a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mSetIpForwardingDisabledErrorState); 10952a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mStartTetheringErrorState = new StartTetheringErrorState(); 10962a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mStartTetheringErrorState); 10972a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mStopTetheringErrorState = new StopTetheringErrorState(); 10982a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mStopTetheringErrorState); 10992a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mSetDnsForwardersErrorState = new SetDnsForwardersErrorState(); 11002a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mSetDnsForwardersErrorState); 11012a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 11022a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mNotifyList = new ArrayList(); 11032a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setInitialState(mInitialState); 11042a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 11052a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 110664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville class TetherMasterUtilState extends State { 11076a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt protected final static boolean TRY_TO_SETUP_MOBILE_CONNECTION = true; 11086a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt protected final static boolean WAIT_FOR_NETWORK_TO_SETTLE = false; 11096a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt 1110d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt @Override 1111d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt public boolean processMessage(Message m) { 1112d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return false; 1113d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 11141039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt protected boolean turnOnMobileConnection() { 11151039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt boolean retValue = true; 11161039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt if (mMobileReserved) return retValue; 1117d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); 1118c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b); 11191039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt int result = Phone.APN_REQUEST_FAILED; 1120d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt try { 1121c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh result = cm.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, 1122e32e812b11520b244374371ee49eaed20c84a6e3Robert Greenwalt (mDunRequired ? Phone.FEATURE_ENABLE_DUN_ALWAYS : 1123e32e812b11520b244374371ee49eaed20c84a6e3Robert Greenwalt Phone.FEATURE_ENABLE_HIPRI), new Binder()); 1124d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } catch (Exception e) { 1125d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 11261039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt switch (result) { 11276a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt case Phone.APN_ALREADY_ACTIVE: 11286a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt case Phone.APN_REQUEST_STARTED: 11291039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt mMobileReserved = true; 11301039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt Message m = obtainMessage(CMD_CELL_CONNECTION_RENEW); 11311039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt m.arg1 = ++mCurrentConnectionSequence; 11321039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt sendMessageDelayed(m, CELL_CONNECTION_RENEW_MS); 11336a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt break; 11346a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt case Phone.APN_REQUEST_FAILED: 11356a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt default: 11361039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt retValue = false; 11376a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt break; 11386a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt } 11396a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt 1140d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return retValue; 1141d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 11426a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt protected boolean turnOffMobileConnection() { 11431039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt if (mMobileReserved) { 11446a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); 1145c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b); 11466a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt try { 1147c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh cm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, 114819b9ab46a9faee6031aaf6c78748401943fea117Robert Greenwalt (mDunRequired? Phone.FEATURE_ENABLE_DUN_ALWAYS : 114977e638dee8b8b0f9c0fcb5403f8c6fb97b52826fRobert Greenwalt Phone.FEATURE_ENABLE_HIPRI)); 11506a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt } catch (Exception e) { 11516a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt return false; 11526a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt } 11531039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt mMobileReserved = false; 1154d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1155d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return true; 1156d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 11576a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt protected boolean turnOnMasterTetherSettings() { 1158d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt try { 1159c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh mNMService.setIpForwardingEnabled(true); 1160d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } catch (Exception e) { 1161951749ba2e014566553d17c512e947472951a060Wink Saville transitionTo(mSetIpForwardingEnabledErrorState); 1162d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return false; 1163d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1164d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt try { 1165c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh mNMService.startTethering(mDhcpRange); 1166d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } catch (Exception e) { 1167547e4e757b539e19694ff6e35b3d4a856f965e5bRobert Greenwalt try { 1168c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh mNMService.stopTethering(); 1169c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh mNMService.startTethering(mDhcpRange); 1170547e4e757b539e19694ff6e35b3d4a856f965e5bRobert Greenwalt } catch (Exception ee) { 1171547e4e757b539e19694ff6e35b3d4a856f965e5bRobert Greenwalt transitionTo(mStartTetheringErrorState); 1172547e4e757b539e19694ff6e35b3d4a856f965e5bRobert Greenwalt return false; 1173547e4e757b539e19694ff6e35b3d4a856f965e5bRobert Greenwalt } 1174d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1175d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt try { 1176c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh mNMService.setDnsForwarders(mDnsServers); 1177d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } catch (Exception e) { 1178951749ba2e014566553d17c512e947472951a060Wink Saville transitionTo(mSetDnsForwardersErrorState); 1179d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return false; 1180d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1181d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return true; 1182d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 11836a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt protected boolean turnOffMasterTetherSettings() { 1184d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt try { 1185c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh mNMService.stopTethering(); 1186d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } catch (Exception e) { 1187d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt transitionTo(mStopTetheringErrorState); 1188d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return false; 1189d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1190d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt try { 1191c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh mNMService.setIpForwardingEnabled(false); 1192d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } catch (Exception e) { 1193d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt transitionTo(mSetIpForwardingDisabledErrorState); 1194d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return false; 1195d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1196d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt transitionTo(mInitialState); 1197d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return true; 1198d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 11996a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt protected String findActiveUpstreamIface() { 1200c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt // check for what iface we can use - if none found switch to error. 120105d8936f275762bab0d66c6337e352388c8eeee0Robert Greenwalt IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); 120205d8936f275762bab0d66c6337e352388c8eeee0Robert Greenwalt IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b); 120305d8936f275762bab0d66c6337e352388c8eeee0Robert Greenwalt 120405d8936f275762bab0d66c6337e352388c8eeee0Robert Greenwalt try { 120505d8936f275762bab0d66c6337e352388c8eeee0Robert Greenwalt LinkProperties defaultProp = cm.getActiveLinkProperties(); 120605d8936f275762bab0d66c6337e352388c8eeee0Robert Greenwalt if (defaultProp != null) { 120705d8936f275762bab0d66c6337e352388c8eeee0Robert Greenwalt String iface = defaultProp.getInterfaceName(); 120805d8936f275762bab0d66c6337e352388c8eeee0Robert Greenwalt for(String regex : mUpstreamIfaceRegexs) { 120905d8936f275762bab0d66c6337e352388c8eeee0Robert Greenwalt if (iface.matches(regex)) return iface; 121005d8936f275762bab0d66c6337e352388c8eeee0Robert Greenwalt } 121105d8936f275762bab0d66c6337e352388c8eeee0Robert Greenwalt } 121205d8936f275762bab0d66c6337e352388c8eeee0Robert Greenwalt } catch (RemoteException e) { } 121305d8936f275762bab0d66c6337e352388c8eeee0Robert Greenwalt 1214c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt String[] ifaces = new String[0]; 1215c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt try { 1216c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh ifaces = mNMService.listInterfaces(); 1217c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } catch (Exception e) { 12183c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood Log.e(TAG, "Error listing Interfaces", e); 1219c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt return null; 1220c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 12216a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt 122294260caf2fb3f5dbf6e17b29a269b46ea05f8680TK MUN for (String regex : mUpstreamIfaceRegexs) { 122394260caf2fb3f5dbf6e17b29a269b46ea05f8680TK MUN for (String iface : ifaces) { 1224c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt if (iface.matches(regex)) { 122529552095e19e3faf2006ac1051da41d9bd212d6fIrfan Sheriff // verify it is active 1226c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt InterfaceConfiguration ifcg = null; 1227c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt try { 1228c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh ifcg = mNMService.getInterfaceConfig(iface); 122929552095e19e3faf2006ac1051da41d9bd212d6fIrfan Sheriff if (ifcg.isActive()) { 123029552095e19e3faf2006ac1051da41d9bd212d6fIrfan Sheriff return iface; 123129552095e19e3faf2006ac1051da41d9bd212d6fIrfan Sheriff } 1232c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } catch (Exception e) { 12333c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood Log.e(TAG, "Error getting iface config", e); 1234c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt // ignore - try next 1235c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt continue; 1236c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1237c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1238c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1239c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1240c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt return null; 1241c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 12421039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt 12436a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt protected void chooseUpstreamType(boolean tryCell) { 12446a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt // decide if the current upstream is good or not and if not 12456a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt // do something about it (start up DUN if required or HiPri if not) 12466a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt String iface = findActiveUpstreamIface(); 12476a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); 12486a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b); 12491039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt mMobileReserved = false; 1250924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt if (DEBUG) { 1251924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt Log.d(TAG, "chooseUpstreamType(" + tryCell + "), dunRequired =" 1252924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt + mDunRequired + ", iface=" + iface); 1253924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt } 125477e638dee8b8b0f9c0fcb5403f8c6fb97b52826fRobert Greenwalt if (iface != null) { 12556a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt try { 125677e638dee8b8b0f9c0fcb5403f8c6fb97b52826fRobert Greenwalt if (mDunRequired) { 125777e638dee8b8b0f9c0fcb5403f8c6fb97b52826fRobert Greenwalt // check if Dun is on - we can use that 125877e638dee8b8b0f9c0fcb5403f8c6fb97b52826fRobert Greenwalt NetworkInfo info = cm.getNetworkInfo( 125977e638dee8b8b0f9c0fcb5403f8c6fb97b52826fRobert Greenwalt ConnectivityManager.TYPE_MOBILE_DUN); 126077e638dee8b8b0f9c0fcb5403f8c6fb97b52826fRobert Greenwalt if (info.isConnected()) { 1261924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt if (DEBUG) Log.d(TAG, "setting dun ifacename =" + iface); 126277e638dee8b8b0f9c0fcb5403f8c6fb97b52826fRobert Greenwalt // even if we're already connected - it may be somebody else's 126377e638dee8b8b0f9c0fcb5403f8c6fb97b52826fRobert Greenwalt // refcount, so add our own 126477e638dee8b8b0f9c0fcb5403f8c6fb97b52826fRobert Greenwalt turnOnMobileConnection(); 126577e638dee8b8b0f9c0fcb5403f8c6fb97b52826fRobert Greenwalt } else { 126677e638dee8b8b0f9c0fcb5403f8c6fb97b52826fRobert Greenwalt // verify the iface is not the default mobile - can't use that! 126777e638dee8b8b0f9c0fcb5403f8c6fb97b52826fRobert Greenwalt info = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE); 126877e638dee8b8b0f9c0fcb5403f8c6fb97b52826fRobert Greenwalt if (info.isConnected()) { 126977e638dee8b8b0f9c0fcb5403f8c6fb97b52826fRobert Greenwalt iface = null; // can't accept this one 127077e638dee8b8b0f9c0fcb5403f8c6fb97b52826fRobert Greenwalt } 127177e638dee8b8b0f9c0fcb5403f8c6fb97b52826fRobert Greenwalt } 127277e638dee8b8b0f9c0fcb5403f8c6fb97b52826fRobert Greenwalt } else { 1273924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt if (DEBUG) Log.d(TAG, "checking if hipri brought us this connection"); 12746a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt NetworkInfo info = cm.getNetworkInfo( 12756a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt ConnectivityManager.TYPE_MOBILE_HIPRI); 12766a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt if (info.isConnected()) { 1277924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt if (DEBUG) Log.d(TAG, "yes - hipri in use"); 127877e638dee8b8b0f9c0fcb5403f8c6fb97b52826fRobert Greenwalt // even if we're already connected - it may be sombody else's 127977e638dee8b8b0f9c0fcb5403f8c6fb97b52826fRobert Greenwalt // refcount, so add our own 12806a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt turnOnMobileConnection(); 12812a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 12822a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 128377e638dee8b8b0f9c0fcb5403f8c6fb97b52826fRobert Greenwalt } catch (RemoteException e) { 12843c2a2f6789ee257e3838ffb0f3f117e08825ad5fMike Lockwood Log.e(TAG, "RemoteException calling ConnectivityManager", e); 128577e638dee8b8b0f9c0fcb5403f8c6fb97b52826fRobert Greenwalt iface = null; 12866a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt } 12876a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt } 128877e638dee8b8b0f9c0fcb5403f8c6fb97b52826fRobert Greenwalt // may have been set to null in the if above 128977e638dee8b8b0f9c0fcb5403f8c6fb97b52826fRobert Greenwalt if (iface == null ) { 12901039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt boolean success = false; 129177e638dee8b8b0f9c0fcb5403f8c6fb97b52826fRobert Greenwalt if (tryCell == TRY_TO_SETUP_MOBILE_CONNECTION) { 12921039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt success = turnOnMobileConnection(); 12931039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt } 12941039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt if (!success) { 12951039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt // wait for things to settle and retry 12961039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt sendMessageDelayed(CMD_RETRY_UPSTREAM, UPSTREAM_SETTLE_TIME_MS); 129777e638dee8b8b0f9c0fcb5403f8c6fb97b52826fRobert Greenwalt } 12986a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt } 1299b37f0c6513241f79a6ea0e3c162dc540d028b60cRobert Greenwalt notifyTetheredOfNewUpstreamIface(iface); 13006a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt } 1301b37f0c6513241f79a6ea0e3c162dc540d028b60cRobert Greenwalt protected void notifyTetheredOfNewUpstreamIface(String ifaceName) { 1302924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt if (DEBUG) Log.d(TAG, "notifying tethered with iface =" + ifaceName); 1303b37f0c6513241f79a6ea0e3c162dc540d028b60cRobert Greenwalt mUpstreamIfaceName = ifaceName; 13046a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt for (Object o : mNotifyList) { 13056a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt TetherInterfaceSM sm = (TetherInterfaceSM)o; 13066a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt sm.sendMessage(TetherInterfaceSM.CMD_TETHER_CONNECTION_CHANGED, 13076a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt ifaceName); 13082a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13092a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13102a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13112a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 13126a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt class InitialState extends TetherMasterUtilState { 13132a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 13142a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 13151039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt mMobileReserved = false; 13162a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13172a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 13182a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public boolean processMessage(Message message) { 1319924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt if (DEBUG) Log.d(TAG, "MasterInitialState.processMessage what=" + message.what); 13202a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean retValue = true; 13212a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt switch (message.what) { 13222a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_MODE_REQUESTED: 132377b32ddbbeeb13a07b16f23af705567c75a8e3dfRobert Greenwalt mDunRequired = isDunRequired(); 13242a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM who = (TetherInterfaceSM)message.obj; 1325924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt if (DEBUG) Log.d(TAG, "Tether Mode requested by " + who.toString()); 13262a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mNotifyList.add(who); 13276a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt transitionTo(mTetherModeAliveState); 13282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 13292a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_MODE_UNREQUESTED: 13302a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt who = (TetherInterfaceSM)message.obj; 1331924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt if (DEBUG) Log.d(TAG, "Tether Mode unrequested by " + who.toString()); 13322a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt int index = mNotifyList.indexOf(who); 13332a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (index != -1) { 13346a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt mNotifyList.remove(who); 13352a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13362a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 13372a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt default: 13382a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retValue = false; 13392a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 13402a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13412a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retValue; 13422a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13432a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13442a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 1345d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt class TetherModeAliveState extends TetherMasterUtilState { 134619b9ab46a9faee6031aaf6c78748401943fea117Robert Greenwalt boolean mTryCell = !WAIT_FOR_NETWORK_TO_SETTLE; 13472a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 13482a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 134919b9ab46a9faee6031aaf6c78748401943fea117Robert Greenwalt mTryCell = !WAIT_FOR_NETWORK_TO_SETTLE; // better try something first pass 135019b9ab46a9faee6031aaf6c78748401943fea117Robert Greenwalt // or crazy tests cases will fail 13516a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt chooseUpstreamType(mTryCell); 13526a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt mTryCell = !mTryCell; 13536a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt turnOnMasterTetherSettings(); // may transition us out 13546a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt } 13556a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt @Override 13566a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt public void exit() { 13576a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt turnOffMobileConnection(); 1358b37f0c6513241f79a6ea0e3c162dc540d028b60cRobert Greenwalt notifyTetheredOfNewUpstreamIface(null); 13592a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13602a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 13612a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public boolean processMessage(Message message) { 1362924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt if (DEBUG) Log.d(TAG, "TetherModeAliveState.processMessage what=" + message.what); 13632a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean retValue = true; 13642a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt switch (message.what) { 13652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_MODE_REQUESTED: 13662a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM who = (TetherInterfaceSM)message.obj; 13672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mNotifyList.add(who); 1368b37f0c6513241f79a6ea0e3c162dc540d028b60cRobert Greenwalt who.sendMessage(TetherInterfaceSM.CMD_TETHER_CONNECTION_CHANGED, 1369b37f0c6513241f79a6ea0e3c162dc540d028b60cRobert Greenwalt mUpstreamIfaceName); 13702a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 13712a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_MODE_UNREQUESTED: 13722a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt who = (TetherInterfaceSM)message.obj; 13732a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt int index = mNotifyList.indexOf(who); 13742a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (index != -1) { 13752a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mNotifyList.remove(index); 13762a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (mNotifyList.isEmpty()) { 1377d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt turnOffMasterTetherSettings(); // transitions appropriately 13782a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13792a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13802a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 13816a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt case CMD_UPSTREAM_CHANGED: 138205d8936f275762bab0d66c6337e352388c8eeee0Robert Greenwalt // need to try DUN immediately if Wifi goes down 138305d8936f275762bab0d66c6337e352388c8eeee0Robert Greenwalt mTryCell = !WAIT_FOR_NETWORK_TO_SETTLE; 13846a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt chooseUpstreamType(mTryCell); 13856a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt mTryCell = !mTryCell; 13862a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 13876a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt case CMD_CELL_CONNECTION_RENEW: 13886a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt // make sure we're still using a requested connection - may have found 13896a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt // wifi or something since then. 13901039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt if (mCurrentConnectionSequence == message.arg1) { 1391924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt if (DEBUG) { 1392924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt Log.d(TAG, "renewing mobile connection - requeuing for another " + 1393924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt CELL_CONNECTION_RENEW_MS + "ms"); 1394924cc94caaab5e9ad0714e0877e871290316e2b1Robert Greenwalt } 13951039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt mMobileReserved = false; // need to renew it 13966a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt turnOnMobileConnection(); 13976a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt } 139865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt break; 139901758e81b3ad89934581885bb2fc7006510ec639Kazuhiro Ondo case CMD_RETRY_UPSTREAM: 140001758e81b3ad89934581885bb2fc7006510ec639Kazuhiro Ondo chooseUpstreamType(mTryCell); 140101758e81b3ad89934581885bb2fc7006510ec639Kazuhiro Ondo mTryCell = !mTryCell; 140201758e81b3ad89934581885bb2fc7006510ec639Kazuhiro Ondo break; 140301758e81b3ad89934581885bb2fc7006510ec639Kazuhiro Ondo case CMD_IFACE_CHANGED: 140401758e81b3ad89934581885bb2fc7006510ec639Kazuhiro Ondo String iface = (String)message.obj; 140501758e81b3ad89934581885bb2fc7006510ec639Kazuhiro Ondo if (DEBUG) Log.d(TAG, "Activie upstream interface changed: " + iface); 140601758e81b3ad89934581885bb2fc7006510ec639Kazuhiro Ondo notifyTetheredOfNewUpstreamIface(iface); 140701758e81b3ad89934581885bb2fc7006510ec639Kazuhiro Ondo break; 140801758e81b3ad89934581885bb2fc7006510ec639Kazuhiro Ondo default: 140901758e81b3ad89934581885bb2fc7006510ec639Kazuhiro Ondo retValue = false; 141001758e81b3ad89934581885bb2fc7006510ec639Kazuhiro Ondo break; 14112a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14122a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retValue; 14132a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14142a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14152a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 141664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville class ErrorState extends State { 14172a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt int mErrorNotification; 14182a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 14192a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public boolean processMessage(Message message) { 14202a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean retValue = true; 14212a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt switch (message.what) { 14222a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_MODE_REQUESTED: 14232a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM who = (TetherInterfaceSM)message.obj; 14246a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt who.sendMessage(mErrorNotification); 14252a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 14262a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt default: 14272a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retValue = false; 14282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14292a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retValue; 14302a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14312a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt void notify(int msgType) { 14322a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mErrorNotification = msgType; 14332a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (Object o : mNotifyList) { 14342a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = (TetherInterfaceSM)o; 14356a1967c9088b9f05665462efa9d98210143500bdRobert Greenwalt sm.sendMessage(msgType); 14362a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14372a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14382a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 14392a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14402a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class SetIpForwardingEnabledErrorState extends ErrorState { 14412a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 14422a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 14432a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Error in setIpForwardingEnabled"); 14442a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt notify(TetherInterfaceSM.CMD_IP_FORWARDING_ENABLE_ERROR); 14452a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14462a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14472a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 14482a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class SetIpForwardingDisabledErrorState extends ErrorState { 14492a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 14502a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 14512a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Error in setIpForwardingDisabled"); 14522a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt notify(TetherInterfaceSM.CMD_IP_FORWARDING_DISABLE_ERROR); 14532a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14542a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14552a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 14562a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class StartTetheringErrorState extends ErrorState { 14572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 14582a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 14592a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Error in startTethering"); 14602a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt notify(TetherInterfaceSM.CMD_START_TETHERING_ERROR); 14612a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 1462c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh mNMService.setIpForwardingEnabled(false); 14632a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) {} 14642a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14662a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 14672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class StopTetheringErrorState extends ErrorState { 14682a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 14692a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 14702a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Error in stopTethering"); 14712a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt notify(TetherInterfaceSM.CMD_STOP_TETHERING_ERROR); 14722a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 1473c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh mNMService.setIpForwardingEnabled(false); 14742a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) {} 14752a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14762a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14772a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 14782a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class SetDnsForwardersErrorState extends ErrorState { 14792a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 14802a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 14812a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Error in setDnsForwarders"); 14822a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt notify(TetherInterfaceSM.CMD_SET_DNS_FORWARDERS_ERROR); 14832a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 1484c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh mNMService.stopTethering(); 14852a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) {} 14862a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 1487c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh mNMService.setIpForwardingEnabled(false); 14882a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) {} 14892a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 1490d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 1491d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 1492d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 14932a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 14942a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (mContext.checkCallingOrSelfPermission( 14952a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt android.Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) { 14962a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt pw.println("Permission Denial: can't dump ConnectivityService.Tether " + 14972a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt "from from pid=" + Binder.getCallingPid() + ", uid=" + 14982a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Binder.getCallingUid()); 14992a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return; 15002a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 15012a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 15022a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt pw.println(); 15032a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt pw.println("Tether state:"); 15042a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt synchronized (mIfaces) { 15052a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (Object o : mIfaces.values()) { 15062a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt pw.println(" "+o.toString()); 15072a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 1508d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 15092a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt pw.println(); 15102a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return; 1511d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 1512d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt} 1513