Tethering.java revision bb51d9feea260e1527628b878319c0cf76adadeb
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; 22d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.content.BroadcastReceiver; 23d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.content.ContentResolver; 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; 29d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.net.ConnectivityManager; 3065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwaltimport android.net.InterfaceConfiguration; 312a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport android.net.IConnectivityManager; 32d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.net.INetworkManagementEventObserver; 332a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport android.net.NetworkInfo; 341cb3cb1a94342e03b54fabfaf361c9e2e26f23feMike Lockwoodimport android.os.BatteryManager; 352a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport android.os.Binder; 36030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwaltimport android.os.Environment; 37d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.os.IBinder; 38d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.os.INetworkManagementService; 39dfadaeac088cabce854d8f476405cd412f82593aRobert Greenwaltimport android.os.Looper; 402a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport android.os.Message; 41d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.os.RemoteException; 42d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.os.ServiceManager; 43d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.provider.Settings; 44d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.util.Log; 45d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 462a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport com.android.internal.telephony.Phone; 472a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport com.android.internal.util.HierarchicalState; 482a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport com.android.internal.util.HierarchicalStateMachine; 492a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 502a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport java.io.FileDescriptor; 512a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport java.io.PrintWriter; 52d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport java.util.ArrayList; 532a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport java.util.HashMap; 542a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport java.util.Set; 55d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt/** 56d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt * @hide 572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt * 582a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt * Timeout 592a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt * 602a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt * TODO - look for parent classes and code sharing 61d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt */ 6265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 63d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltpublic class Tethering extends INetworkManagementEventObserver.Stub { 64d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 65d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt private Context mContext; 66d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt private final String TAG = "Tethering"; 67d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 68c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt private boolean mBooted = false; 69c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt //used to remember if we got connected before boot finished 70c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt private boolean mDeferedUsbConnection = false; 71d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 722a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // TODO - remove both of these - should be part of interface inspection/selection stuff 732a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private String[] mTetherableUsbRegexs; 742a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private String[] mTetherableWifiRegexs; 75c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt private String[] mUpstreamIfaceRegexs; 762a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 77dfadaeac088cabce854d8f476405cd412f82593aRobert Greenwalt private Looper mLooper; // given to us at construction time.. 78dfadaeac088cabce854d8f476405cd412f82593aRobert Greenwalt 79030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt private HashMap<String, TetherInterfaceSM> mIfaces; // all tethered/tetherable ifaces 80d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 81d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt private BroadcastReceiver mStateReceiver; 82d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 83d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt private static final String USB_NEAR_IFACE_ADDR = "169.254.2.1"; 84d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt 852a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private String[] mDhcpRange; 86d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt private static final String DHCP_DEFAULT_RANGE_START = "169.254.2.10"; 87d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt private static final String DHCP_DEFAULT_RANGE_STOP = "169.254.2.64"; 882a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 892a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private String[] mDnsServers; 90d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt private static final String DNS_DEFAULT_SERVER1 = "8.8.8.8"; 91d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt private static final String DNS_DEFAULT_SERVER2 = "4.2.2.2"; 922a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 93030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt private boolean mDunRequired; // configuration info - must use DUN apn on 3g 94c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt private boolean mUseHiPri; 95030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt 962a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private String mUpstreamIfaceName; 972a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 98a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt private HierarchicalStateMachine mTetherMasterSM; 99a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt 100a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt private Notification mTetheredNotification; 1012a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 102030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt // whether we can tether is the && of these two - they come in as separate 103030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt // broadcasts so track them so we can decide what to do when either changes 104030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt private boolean mUsbMassStorageOff; // track the status of USB Mass Storage 105030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt private boolean mUsbConnected; // track the status of USB connection 106030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt 107dfadaeac088cabce854d8f476405cd412f82593aRobert Greenwalt public Tethering(Context context, Looper looper) { 108d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt Log.d(TAG, "Tethering starting"); 109d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt mContext = context; 110dfadaeac088cabce854d8f476405cd412f82593aRobert Greenwalt mLooper = looper; 111d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 112d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt // register for notifications from NetworkManagement Service 113d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 114d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt INetworkManagementService service = INetworkManagementService.Stub.asInterface(b); 115d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt try { 116d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt service.registerObserver(this); 117d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } catch (RemoteException e) { 118d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt Log.e(TAG, "Error registering observer :" + e); 119d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 120d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 1212a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mIfaces = new HashMap<String, TetherInterfaceSM>(); 122d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 123dfadaeac088cabce854d8f476405cd412f82593aRobert Greenwalt mTetherMasterSM = new TetherMasterSM("TetherMaster", mLooper); 1242a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTetherMasterSM.start(); 1252a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 126bb51d9feea260e1527628b878319c0cf76adadebRobert Greenwalt mStateReceiver = new StateReceiver(); 127d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt IntentFilter filter = new IntentFilter(); 1281cb3cb1a94342e03b54fabfaf361c9e2e26f23feMike Lockwood filter.addAction(Intent.ACTION_BATTERY_CHANGED); 1292a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); 130c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt filter.addAction(Intent.ACTION_BOOT_COMPLETED); 131bb51d9feea260e1527628b878319c0cf76adadebRobert Greenwalt mContext.registerReceiver(mStateReceiver, filter); 132bb51d9feea260e1527628b878319c0cf76adadebRobert Greenwalt 133bb51d9feea260e1527628b878319c0cf76adadebRobert Greenwalt filter = new IntentFilter(); 134030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt filter.addAction(Intent.ACTION_MEDIA_SHARED); 135030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt filter.addAction(Intent.ACTION_MEDIA_UNSHARED); 136bb51d9feea260e1527628b878319c0cf76adadebRobert Greenwalt filter.addDataScheme("file"); 137bb51d9feea260e1527628b878319c0cf76adadebRobert Greenwalt mContext.registerReceiver(mStateReceiver, filter); 138bb51d9feea260e1527628b878319c0cf76adadebRobert Greenwalt 139030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt mUsbMassStorageOff = !Environment.MEDIA_SHARED.equals( 140030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt Environment.getExternalStorageState()); 1412a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 1422a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mDhcpRange = context.getResources().getStringArray( 1432a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt com.android.internal.R.array.config_tether_dhcp_range); 1442a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (mDhcpRange.length == 0) { 1452a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mDhcpRange = new String[2]; 146d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt mDhcpRange[0] = DHCP_DEFAULT_RANGE_START; 147d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt mDhcpRange[1] = DHCP_DEFAULT_RANGE_STOP; 1482a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } else if(mDhcpRange.length == 1) { 1492a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt String[] tmp = new String[2]; 1502a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt tmp[0] = mDhcpRange[0]; 1512a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt tmp[1] = new String(""); 1522a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mDhcpRange = tmp; 1532a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 154c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt mDunRequired = context.getResources().getBoolean( 155c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt com.android.internal.R.bool.config_tether_dun_required); 1562a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 1572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTetherableUsbRegexs = context.getResources().getStringArray( 1582a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt com.android.internal.R.array.config_tether_usb_regexs); 1592a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTetherableWifiRegexs = context.getResources().getStringArray( 1602a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt com.android.internal.R.array.config_tether_wifi_regexs); 161c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt mUpstreamIfaceRegexs = context.getResources().getStringArray( 162c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt com.android.internal.R.array.config_tether_upstream_regexs); 1632a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 1642a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // TODO - remove and rely on real notifications of the current iface 1652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mDnsServers = new String[2]; 166d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt mDnsServers[0] = DNS_DEFAULT_SERVER1; 167d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt mDnsServers[1] = DNS_DEFAULT_SERVER2; 168d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 169d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 1702a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void interfaceLinkStatusChanged(String iface, boolean link) { 171d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt Log.d(TAG, "interfaceLinkStatusChanged " + iface + ", " + link); 1722a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean found = false; 17365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt boolean usb = false; 174a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt if (isWifi(iface)) { 175a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt found = true; 176a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } else if (isUsb(iface)) { 177a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt found = true; 178a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt usb = true; 1792a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 1802a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (found == false) return; 1812a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 1822a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt synchronized (mIfaces) { 1832a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = mIfaces.get(iface); 1842a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (link) { 1852a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm == null) { 186dfadaeac088cabce854d8f476405cd412f82593aRobert Greenwalt sm = new TetherInterfaceSM(iface, mLooper, usb); 1872a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mIfaces.put(iface, sm); 1882a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sm.start(); 1892a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 1902a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } else { 1912a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm != null) { 1922a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sm.sendMessage(sm.obtainMessage(TetherInterfaceSM.CMD_INTERFACE_DOWN)); 1932a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mIfaces.remove(iface); 1942a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 1952a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 1962a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 197d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 198d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 199a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt private boolean isUsb(String iface) { 200a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt for (String regex : mTetherableUsbRegexs) { 201a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt if (iface.matches(regex)) return true; 202a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } 203a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt return false; 204a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } 205a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt 206a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt public boolean isWifi(String iface) { 207a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt for (String regex : mTetherableWifiRegexs) { 208a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt if (iface.matches(regex)) return true; 209a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } 210a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt return false; 211a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } 212a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt 2132a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void interfaceAdded(String iface) { 21465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 21565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt INetworkManagementService service = INetworkManagementService.Stub.asInterface(b); 2162a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean found = false; 21765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt boolean usb = false; 218a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt if (isWifi(iface)) { 219a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt found = true; 2202a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 221a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt if (isUsb(iface)) { 222a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt found = true; 223a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt usb = true; 224d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 2252a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (found == false) { 2262a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.d(TAG, iface + " is not a tetherable iface, ignoring"); 227d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt return; 228d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 22965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 2302a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt synchronized (mIfaces) { 2312a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = mIfaces.get(iface); 2322a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm != null) { 2332a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "active iface (" + iface + ") reported as added, ignoring"); 2342a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return; 2352a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 236dfadaeac088cabce854d8f476405cd412f82593aRobert Greenwalt sm = new TetherInterfaceSM(iface, mLooper, usb); 2372a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mIfaces.put(iface, sm); 2382a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sm.start(); 2392a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 240d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt Log.d(TAG, "interfaceAdded :" + iface); 241d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 242d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 2432a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void interfaceRemoved(String iface) { 2442a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt synchronized (mIfaces) { 2452a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = mIfaces.get(iface); 2462a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm == null) { 2472a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "attempting to remove unknown iface (" + iface + "), ignoring"); 2482a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return; 2492a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 2502a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sm.sendMessage(sm.obtainMessage(TetherInterfaceSM.CMD_INTERFACE_DOWN)); 2512a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mIfaces.remove(iface); 252d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 253d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 254d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 2555a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt public int tether(String iface) { 256d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt Log.d(TAG, "Tethering " + iface); 2572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = null; 2582a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt synchronized (mIfaces) { 2592a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sm = mIfaces.get(iface); 260d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 2612a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm == null) { 2622a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Tried to Tether an unknown iface :" + iface + ", ignoring"); 2635a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE; 264d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 2655a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt if (!sm.isAvailable() && !sm.isErrored()) { 2662a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Tried to Tether an unavailable iface :" + iface + ", ignoring"); 2675a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt return ConnectivityManager.TETHER_ERROR_UNAVAIL_IFACE; 268d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 2692a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sm.sendMessage(sm.obtainMessage(TetherInterfaceSM.CMD_TETHER_REQUESTED)); 2705a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt return ConnectivityManager.TETHER_ERROR_NO_ERROR; 271d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 272d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 2735a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt public int untether(String iface) { 274d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt Log.d(TAG, "Untethering " + iface); 2752a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = null; 2762a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt synchronized (mIfaces) { 2772a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sm = mIfaces.get(iface); 2782a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 2792a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm == null) { 2802a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Tried to Untether an unknown iface :" + iface + ", ignoring"); 2815a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE; 282d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 2832a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm.isErrored()) { 2842a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Tried to Untethered an errored iface :" + iface + ", ignoring"); 2855a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt return ConnectivityManager.TETHER_ERROR_UNAVAIL_IFACE; 286d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 2872a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sm.sendMessage(sm.obtainMessage(TetherInterfaceSM.CMD_TETHER_UNREQUESTED)); 2885a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt return ConnectivityManager.TETHER_ERROR_NO_ERROR; 2895a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } 2905a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt 2915a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt public int getLastTetherError(String iface) { 2925a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt TetherInterfaceSM sm = null; 2935a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt synchronized (mIfaces) { 2945a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt sm = mIfaces.get(iface); 2955a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } 2965a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt if (sm == null) { 2975a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt Log.e(TAG, "Tried to getLastTetherError on an unknown iface :" + iface + ", ignoring"); 2985a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE; 2995a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } 3005a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt return sm.getLastError(); 3012a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 302d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 3032a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private void sendTetherStateChangedBroadcast() { 3042a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); 3052a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt IConnectivityManager service = IConnectivityManager.Stub.asInterface(b); 306d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt try { 3072a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (!service.isTetheringSupported()) return; 3082a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (RemoteException e) { 3092a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return; 310d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 311d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 3122a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt ArrayList<String> availableList = new ArrayList<String>(); 3132a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt ArrayList<String> activeList = new ArrayList<String>(); 3142a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt ArrayList<String> erroredList = new ArrayList<String>(); 3152a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 316a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt boolean wifiTethered = false; 317a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt boolean usbTethered = false; 318a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt 3192a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt synchronized (mIfaces) { 3202a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Set ifaces = mIfaces.keySet(); 3212a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (Object iface : ifaces) { 3222a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = mIfaces.get(iface); 3232a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm != null) { 3242a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if(sm.isErrored()) { 3252a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt erroredList.add((String)iface); 3262a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } else if (sm.isAvailable()) { 3272a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt availableList.add((String)iface); 3282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } else if (sm.isTethered()) { 329a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt if (isUsb((String)iface)) { 330a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt usbTethered = true; 331a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } else if (isWifi((String)iface)) { 332a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt wifiTethered = true; 333a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } 3342a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt activeList.add((String)iface); 3352a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 3362a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 337d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 338d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 339d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt Intent broadcast = new Intent(ConnectivityManager.ACTION_TETHER_STATE_CHANGED); 340d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt broadcast.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 3412a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt broadcast.putStringArrayListExtra(ConnectivityManager.EXTRA_AVAILABLE_TETHER, 3422a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt availableList); 3432a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt broadcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ACTIVE_TETHER, activeList); 3442a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt broadcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ERRORED_TETHER, 3452a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt erroredList); 3462a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mContext.sendStickyBroadcast(broadcast); 347d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt Log.d(TAG, "sendTetherStateChangedBroadcast " + availableList.size() + ", " + 348d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt activeList.size() + ", " + erroredList.size()); 349a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt 350a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt if (usbTethered) { 351a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt if (wifiTethered) { 352a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt showTetheredNotification(com.android.internal.R.drawable.stat_sys_tether_general); 353a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } else { 354a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt showTetheredNotification(com.android.internal.R.drawable.stat_sys_tether_usb); 355a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } 356a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } else if (wifiTethered) { 357a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt showTetheredNotification(com.android.internal.R.drawable.stat_sys_tether_wifi); 358a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } else { 359a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt clearTetheredNotification(); 360a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } 361a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } 362a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt 363a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt private void showTetheredNotification(int icon) { 364a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt NotificationManager notificationManager = 365a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt (NotificationManager)mContext.getSystemService(Context.NOTIFICATION_SERVICE); 366a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt if (notificationManager == null) { 367a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt return; 368a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } 369a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt 370a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt Intent intent = new Intent(); 371a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt intent.setClassName("com.android.settings", "com.android.settings.TetherSettings"); 372a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); 373a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt 374a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0); 375a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt 376a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt Resources r = Resources.getSystem(); 377a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt CharSequence title = r.getText(com.android.internal.R.string.tethered_notification_title); 378a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt CharSequence message = r.getText(com.android.internal.R.string. 379a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt tethered_notification_message); 380a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt 381a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt if(mTetheredNotification == null) { 382a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt mTetheredNotification = new Notification(); 383a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt mTetheredNotification.when = 0; 384a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } 385a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt mTetheredNotification.icon = icon; 386a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt mTetheredNotification.defaults &= ~Notification.DEFAULT_SOUND; 387a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt mTetheredNotification.flags = Notification.FLAG_ONGOING_EVENT; 388a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt mTetheredNotification.tickerText = title; 389a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt mTetheredNotification.setLatestEventInfo(mContext, title, message, pi); 390a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt 391a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt notificationManager.notify(mTetheredNotification.icon, mTetheredNotification); 392a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } 393a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt 394a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt private void clearTetheredNotification() { 395a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt NotificationManager notificationManager = 396a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt (NotificationManager)mContext.getSystemService(Context.NOTIFICATION_SERVICE); 397a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt if (notificationManager != null && mTetheredNotification != null) { 398a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt notificationManager.cancel(mTetheredNotification.icon); 399a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt mTetheredNotification = null; 400a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } 4015a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } 4025a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt 403030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt private void updateUsbStatus() { 404030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt boolean enable = mUsbConnected && mUsbMassStorageOff; 405030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt 406030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt if (mBooted) { 407030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt enableUsbIfaces(enable); 408030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt } 409030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt } 410030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt 4112a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private class StateReceiver extends BroadcastReceiver { 412d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt public void onReceive(Context content, Intent intent) { 4132a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt String action = intent.getAction(); 4141cb3cb1a94342e03b54fabfaf361c9e2e26f23feMike Lockwood if (action.equals(Intent.ACTION_BATTERY_CHANGED)) { 415030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt mUsbConnected = (intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) 4161cb3cb1a94342e03b54fabfaf361c9e2e26f23feMike Lockwood == BatteryManager.BATTERY_PLUGGED_USB); 417030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt Tethering.this.updateUsbStatus(); 418030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt } else if (action.equals(Intent.ACTION_MEDIA_SHARED)) { 419030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt mUsbMassStorageOff = false; 420030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt updateUsbStatus(); 421030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt } 422030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt else if (action.equals(Intent.ACTION_MEDIA_UNSHARED)) { 423030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt mUsbMassStorageOff = true; 424030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt updateUsbStatus(); 4252a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { 4262a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); 42765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt IConnectivityManager service = IConnectivityManager.Stub.asInterface(b); 4282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 429c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt int netType = (mUseHiPri ? ConnectivityManager.TYPE_MOBILE_HIPRI: 430c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt ConnectivityManager.TYPE_MOBILE_DUN); 431c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt NetworkInfo info = service.getNetworkInfo(netType); 4322a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt int msg; 433a4437fc93a993c7ab326b592d22c05be2f11b543Mike Lockwood if (info != null && info.isConnected() == true) { 4342a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt msg = TetherMasterSM.CMD_CELL_DUN_ENABLED; 4352a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } else { 4362a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt msg = TetherMasterSM.CMD_CELL_DUN_DISABLED; 4372a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 4382a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTetherMasterSM.sendMessage(mTetherMasterSM.obtainMessage(msg)); 4392a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (RemoteException e) {} 440c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } else if (action.equals(Intent.ACTION_BOOT_COMPLETED)) { 441c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt mBooted = true; 442030f5e18dfa71673708deb75e8aa1f196bebbd99Robert Greenwalt updateUsbStatus(); 443d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 444d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 445d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 446d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 44765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt // used on cable insert/remove 448d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt private void enableUsbIfaces(boolean enable) { 44965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 45065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt INetworkManagementService service = INetworkManagementService.Stub.asInterface(b); 45165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt String[] ifaces = new String[0]; 45265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt try { 45365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt ifaces = service.listInterfaces(); 45465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } catch (Exception e) { 45565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt Log.e(TAG, "Error listing Interfaces :" + e); 45665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt return; 45765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 45865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt for (String iface : ifaces) { 459a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt if (isUsb(iface)) { 460a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt if (enable) { 461a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt interfaceAdded(iface); 462a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } else { 463a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt interfaceRemoved(iface); 46465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 46565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 46665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 46765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 46865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 46965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt // toggled when we enter/leave the fully teathered state 470d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt private boolean enableUsbRndis(boolean enabled) { 471d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt Log.d(TAG, "enableUsbRndis(" + enabled + ")"); 47265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 47365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt INetworkManagementService service = INetworkManagementService.Stub.asInterface(b); 47465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 47565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt try { 47665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt if (enabled) { 47765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt synchronized (this) { 47865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt if (!service.isUsbRNDISStarted()) { 47965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt service.startUsbRNDIS(); 48065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 48165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 48265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } else { 48365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt if (service.isUsbRNDISStarted()) { 48465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt service.stopUsbRNDIS(); 48565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 48665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 48765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } catch (Exception e) { 48865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt Log.e(TAG, "Error toggling usb RNDIS :" + e); 48965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt return false; 49065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 49165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt return true; 49265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 49365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 49465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt // configured when we start tethering and unconfig'd on error or conclusion 495d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt private boolean configureUsbIface(boolean enabled) { 496d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt Log.d(TAG, "configureUsbIface(" + enabled + ")"); 49765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 49865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 49965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt INetworkManagementService service = INetworkManagementService.Stub.asInterface(b); 50065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 50165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt // bring toggle the interfaces 50265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt String[] ifaces = new String[0]; 50365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt try { 50465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt ifaces = service.listInterfaces(); 50565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } catch (Exception e) { 50665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt Log.e(TAG, "Error listing Interfaces :" + e); 50765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt return false; 50865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 50965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt for (String iface : ifaces) { 510a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt if (isUsb(iface)) { 511a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt InterfaceConfiguration ifcg = null; 512a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt try { 513a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt ifcg = service.getInterfaceConfig(iface); 514a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt if (ifcg != null) { 515a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt ifcg.ipAddr = (169 << 24) + (254 << 16) + (2 << 8) + 1; 516a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt ifcg.netmask = (255 << 24) + (255 << 16) + (255 << 8) + 0; 517a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt if (enabled) { 518a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt ifcg.interfaceFlags = ifcg.interfaceFlags.replace("down", "up"); 519a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } else { 520a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt ifcg.interfaceFlags = ifcg.interfaceFlags.replace("up", "down"); 52165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 522a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt ifcg.interfaceFlags = ifcg.interfaceFlags.replace("running", ""); 523a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt ifcg.interfaceFlags = ifcg.interfaceFlags.replace(" "," "); 524a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt service.setInterfaceConfig(iface, ifcg); 52565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 526a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt } catch (Exception e) { 527a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt Log.e(TAG, "Error configuring interface " + iface + ", :" + e); 528a599fe7c0d8b4d4bdf4accb099cb17bebcb9088bRobert Greenwalt return false; 52965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 53065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 53165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 53265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 53365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt return true; 53465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 53565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 5362a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public String[] getTetherableUsbRegexs() { 5372a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return mTetherableUsbRegexs; 5382a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 5392a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 5402a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public String[] getTetherableWifiRegexs() { 5412a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return mTetherableWifiRegexs; 5422a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 5432a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 544c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt public String[] getUpstreamIfaceRegexs() { 545c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt return mUpstreamIfaceRegexs; 546c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 547c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt 548c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt public boolean isDunRequired() { 549c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt return mDunRequired; 550c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 551c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt 5522a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public String[] getTetheredIfaces() { 5532a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt ArrayList<String> list = new ArrayList<String>(); 5542a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt synchronized (mIfaces) { 5552a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Set keys = mIfaces.keySet(); 5562a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (Object key : keys) { 5572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = mIfaces.get(key); 5582a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm.isTethered()) { 5592a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt list.add((String)key); 5602a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 5612a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 5622a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 5632a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt String[] retVal = new String[list.size()]; 5642a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (int i=0; i < list.size(); i++) { 5652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retVal[i] = list.get(i); 5662a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 5672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retVal; 5682a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 5692a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 5702a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public String[] getTetherableIfaces() { 5712a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt ArrayList<String> list = new ArrayList<String>(); 5722a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt synchronized (mIfaces) { 5732a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Set keys = mIfaces.keySet(); 5742a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (Object key : keys) { 5752a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = mIfaces.get(key); 5762a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm.isAvailable()) { 5772a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt list.add((String)key); 5782a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 5792a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 5802a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 5812a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt String[] retVal = new String[list.size()]; 5822a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (int i=0; i < list.size(); i++) { 5832a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retVal[i] = list.get(i); 5842a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 5852a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retVal; 5862a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 5872a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 5885a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt public String[] getErroredIfaces() { 5895a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt ArrayList<String> list = new ArrayList<String>(); 5905a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt synchronized (mIfaces) { 5915a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt Set keys = mIfaces.keySet(); 5925a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt for (Object key : keys) { 5935a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt TetherInterfaceSM sm = mIfaces.get(key); 5945a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt if (sm.isErrored()) { 5955a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt list.add((String)key); 5965a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } 5975a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } 5985a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } 5995a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt String[] retVal = new String[list.size()]; 6005a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt for (int i= 0; i< list.size(); i++) { 6015a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt retVal[i] = list.get(i); 6025a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } 6035a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt return retVal; 6045a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } 6055a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt 6062a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 6072a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class TetherInterfaceSM extends HierarchicalStateMachine { 6082a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification from the master SM that it's in tether mode 6092a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_TETHER_MODE_ALIVE = 1; 6102a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification from the master SM that it's not in tether mode 6112a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_TETHER_MODE_DEAD = 2; 6122a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // request from the user that it wants to tether 6132a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_TETHER_REQUESTED = 3; 6142a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // request from the user that it wants to untether 6152a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_TETHER_UNREQUESTED = 4; 6162a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification that this interface is down 6172a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_INTERFACE_DOWN = 5; 6182a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification that this interface is up 6192a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_INTERFACE_UP = 6; 6202a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification from the master SM that it had an error turning on cellular dun 6212a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_CELL_DUN_ERROR = 10; 6222a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification from the master SM that it had trouble enabling IP Forwarding 6232a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_IP_FORWARDING_ENABLE_ERROR = 11; 6242a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification from the master SM that it had trouble disabling IP Forwarding 6252a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_IP_FORWARDING_DISABLE_ERROR = 12; 6262a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification from the master SM that it had trouble staring tethering 6272a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_START_TETHERING_ERROR = 13; 6282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification from the master SM that it had trouble stopping tethering 6292a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_STOP_TETHERING_ERROR = 14; 6302a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification from the master SM that it had trouble setting the DNS forwarders 6312a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_SET_DNS_FORWARDERS_ERROR = 15; 6325a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt // a mechanism to transition self to another state from an enter function 6335a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt static final int CMD_TRANSITION_TO_STATE = 16; 6342a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 6352a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mDefaultState; 6362a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 6372a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mInitialState; 6382a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mStartingState; 6392a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mTetheredState; 6402a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 6412a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mUnavailableState; 6422a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 6432a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private boolean mAvailable; 6442a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private boolean mTethered; 6455a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt int mLastError; 6462a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 6472a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt String mIfaceName; 64865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt boolean mUsb; 6492a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 650dfadaeac088cabce854d8f476405cd412f82593aRobert Greenwalt TetherInterfaceSM(String name, Looper looper, boolean usb) { 651dfadaeac088cabce854d8f476405cd412f82593aRobert Greenwalt super(name, looper); 6522a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mIfaceName = name; 65365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt mUsb = usb; 6545a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastError(ConnectivityManager.TETHER_ERROR_NO_ERROR); 6552a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 6562a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mInitialState = new InitialState(); 6572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mInitialState); 6582a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mStartingState = new StartingState(); 6592a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mStartingState); 6602a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTetheredState = new TetheredState(); 6612a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mTetheredState); 6622a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mUnavailableState = new UnavailableState(); 6632a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mUnavailableState); 6642a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 6652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setInitialState(mInitialState); 6662a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 6672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 6682a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public String toString() { 6692a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt String res = new String(); 6702a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt res += mIfaceName + " - "; 6712a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt HierarchicalState current = getCurrentState(); 6722a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (current == mInitialState) res += "InitialState"; 6732a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (current == mStartingState) res += "StartingState"; 6742a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (current == mTetheredState) res += "TetheredState"; 6752a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (current == mUnavailableState) res += "UnavailableState"; 6762a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (mAvailable) res += " - Available"; 6772a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (mTethered) res += " - Tethered"; 6785a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt res += " - lastError =" + mLastError; 6792a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return res; 6802a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 6812a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 6825a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt public synchronized int getLastError() { 6835a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt return mLastError; 6845a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } 6855a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt 6865a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt private synchronized void setLastError(int error) { 6875a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt mLastError = error; 6885a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt 6895a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt if (isErrored()) { 6905a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt if (mUsb) { 6915a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt // note everything's been unwound by this point so nothing to do on 6925a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt // further error.. 6935a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt Tethering.this.configureUsbIface(false); 6945a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } 6955a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } 6965a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } 6975a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt 6982a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // synchronized between this getter and the following setter 6992a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public synchronized boolean isAvailable() { 7002a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return mAvailable; 7012a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7022a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 7032a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private synchronized void setAvailable(boolean available) { 7042a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mAvailable = available; 7052a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7062a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 7072a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // synchronized between this getter and the following setter 7082a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public synchronized boolean isTethered() { 7092a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return mTethered; 7102a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7112a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 7122a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private synchronized void setTethered(boolean tethered) { 7132a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTethered = tethered; 7142a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7152a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 7162a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // synchronized between this getter and the following setter 7172a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public synchronized boolean isErrored() { 7185a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt return (mLastError != ConnectivityManager.TETHER_ERROR_NO_ERROR); 7192a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7202a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 7212a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class InitialState extends HierarchicalState { 7222a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 7232a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 7242a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setAvailable(true); 7252a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setTethered(false); 7262a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendTetherStateChangedBroadcast(); 7272a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 7292a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 7302a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public boolean processMessage(Message message) { 7312a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.d(TAG, "InitialState.processMessage what=" + message.what); 7322a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean retValue = true; 7332a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt switch (message.what) { 7342a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_REQUESTED: 7355a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastError(ConnectivityManager.TETHER_ERROR_NO_ERROR); 7362a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Message m = mTetherMasterSM.obtainMessage( 7372a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherMasterSM.CMD_TETHER_MODE_REQUESTED); 7382a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt m.obj = TetherInterfaceSM.this; 7392a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTetherMasterSM.sendMessage(m); 7402a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mStartingState); 7412a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 7422a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_INTERFACE_DOWN: 7432a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mUnavailableState); 7442a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 7452a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt default: 7462a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retValue = false; 7472a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 7482a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7492a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retValue; 7502a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7512a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7522a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 7532a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class StartingState extends HierarchicalState { 7542a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 7552a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 7562a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setAvailable(false); 75765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt if (mUsb) { 758d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt if (!Tethering.this.configureUsbIface(true)) { 75965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt Message m = mTetherMasterSM.obtainMessage( 76065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt TetherMasterSM.CMD_TETHER_MODE_UNREQUESTED); 76165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt m.obj = TetherInterfaceSM.this; 76265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt mTetherMasterSM.sendMessage(m); 76365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 7645a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastError(ConnectivityManager.TETHER_ERROR_IFACE_CFG_ERROR); 7655a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt 7665a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt m = obtainMessage(CMD_TRANSITION_TO_STATE); 7675a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt m.obj = mInitialState; 76865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt sendMessageAtFrontOfQueue(m); 76965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt return; 77065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 77165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 7722a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendTetherStateChangedBroadcast(); 7732a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7742a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 7752a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public boolean processMessage(Message message) { 7762a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.d(TAG, "StartingState.processMessage what=" + message.what); 7772a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean retValue = true; 7782a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt switch (message.what) { 7792a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // maybe a parent class? 7802a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_UNREQUESTED: 7812a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Message m = mTetherMasterSM.obtainMessage( 7822a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherMasterSM.CMD_TETHER_MODE_UNREQUESTED); 7832a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt m.obj = TetherInterfaceSM.this; 7842a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTetherMasterSM.sendMessage(m); 78565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt if (mUsb) { 786d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt if (!Tethering.this.configureUsbIface(false)) { 7875a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastErrorAndTransitionToInitialState( 7885a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt ConnectivityManager.TETHER_ERROR_IFACE_CFG_ERROR); 78965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt break; 79065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 79165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 7922a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mInitialState); 7932a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 7942a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_MODE_ALIVE: 7952a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mTetheredState); 7962a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 7972a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_CELL_DUN_ERROR: 7982a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_IP_FORWARDING_ENABLE_ERROR: 7992a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_IP_FORWARDING_DISABLE_ERROR: 8002a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_START_TETHERING_ERROR: 8012a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_STOP_TETHERING_ERROR: 8022a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_SET_DNS_FORWARDERS_ERROR: 8035a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastErrorAndTransitionToInitialState( 8045a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt ConnectivityManager.TETHER_ERROR_MASTER_ERROR); 8052a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 8062a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_INTERFACE_DOWN: 8072a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt m = mTetherMasterSM.obtainMessage( 8082a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherMasterSM.CMD_TETHER_MODE_UNREQUESTED); 8092a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt m.obj = TetherInterfaceSM.this; 8102a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTetherMasterSM.sendMessage(m); 8112a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mUnavailableState); 8122a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 8135a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt case CMD_TRANSITION_TO_STATE: 81465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt HierarchicalState s = (HierarchicalState)(message.obj); 81565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt transitionTo(s); 81665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt break; 8172a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt default: 8182a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retValue = false; 8192a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 8202a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retValue; 8212a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 8222a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 8232a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 8242a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class TetheredState extends HierarchicalState { 8252a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 8262a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 8272a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 8282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt INetworkManagementService service = 8292a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt INetworkManagementService.Stub.asInterface(b); 8302a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 8312a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt service.tetherInterface(mIfaceName); 8322a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) { 8335a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastError(ConnectivityManager.TETHER_ERROR_TETHER_IFACE_ERROR); 8345a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt 8355a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt Message m = obtainMessage(CMD_TRANSITION_TO_STATE); 8365a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt m.obj = mInitialState; 8372a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendMessageAtFrontOfQueue(m); 8382a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return; 8392a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 8402a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 8412a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt service.enableNat(mIfaceName, mUpstreamIfaceName); 8422a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) { 8435a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt try { 8445a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt service.untetherInterface(mIfaceName); 8455a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } catch (Exception ee) {} 8465a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt 8475a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastError(ConnectivityManager.TETHER_ERROR_ENABLE_NAT_ERROR); 8485a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt 8495a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt Message m = obtainMessage(CMD_TRANSITION_TO_STATE); 8505a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt m.obj = mInitialState; 8512a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendMessageAtFrontOfQueue(m); 8522a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return; 8532a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 854d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt if (mUsb) Tethering.this.enableUsbRndis(true); 8552a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.d(TAG, "Tethered " + mIfaceName); 8562a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setAvailable(false); 8572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setTethered(true); 8582a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendTetherStateChangedBroadcast(); 8592a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 8602a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 86165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt public void exit() { 862d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt if (mUsb) Tethering.this.enableUsbRndis(false); 86365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 86465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt @Override 8652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public boolean processMessage(Message message) { 8662a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.d(TAG, "TetheredState.processMessage what=" + message.what); 8672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean retValue = true; 8682a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean error = false; 8692a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt switch (message.what) { 8702a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_UNREQUESTED: 8712a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_INTERFACE_DOWN: 8722a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 8732a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt INetworkManagementService service = 8742a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt INetworkManagementService.Stub.asInterface(b); 8752a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 8762a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt service.disableNat(mIfaceName, mUpstreamIfaceName); 8772a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) { 8785a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt try { 8795a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt service.untetherInterface(mIfaceName); 8805a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } catch (Exception ee) {} 8815a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt 8825a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastErrorAndTransitionToInitialState( 8835a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt ConnectivityManager.TETHER_ERROR_DISABLE_NAT_ERROR); 8842a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 8852a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 8862a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 8872a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt service.untetherInterface(mIfaceName); 8882a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) { 8895a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastErrorAndTransitionToInitialState( 8905a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt ConnectivityManager.TETHER_ERROR_UNTETHER_IFACE_ERROR); 8912a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 8922a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 8932a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Message m = mTetherMasterSM.obtainMessage( 8942a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherMasterSM.CMD_TETHER_MODE_UNREQUESTED); 8952a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt m.obj = TetherInterfaceSM.this; 8962a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTetherMasterSM.sendMessage(m); 8972a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (message.what == CMD_TETHER_UNREQUESTED) { 89865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt if (mUsb) { 899d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt if (!Tethering.this.configureUsbIface(false)) { 9005a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastError( 9015a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt ConnectivityManager.TETHER_ERROR_IFACE_CFG_ERROR); 90265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 90365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 9045a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt transitionTo(mInitialState); 9052a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } else if (message.what == CMD_INTERFACE_DOWN) { 9062a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mUnavailableState); 9072a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 9082a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.d(TAG, "Untethered " + mIfaceName); 9092a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 9102a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_CELL_DUN_ERROR: 9112a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_IP_FORWARDING_ENABLE_ERROR: 9122a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_IP_FORWARDING_DISABLE_ERROR: 9132a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_START_TETHERING_ERROR: 9142a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_STOP_TETHERING_ERROR: 9152a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_SET_DNS_FORWARDERS_ERROR: 9162a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt error = true; 9172a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // fall through 9182a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_MODE_DEAD: 9192a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 9202a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt service = INetworkManagementService.Stub.asInterface(b); 9212a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 9222a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt service.disableNat(mIfaceName, mUpstreamIfaceName); 9232a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) { 9245a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt try { 9255a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt service.untetherInterface(mIfaceName); 9265a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt } catch (Exception ee) {} 9275a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt 9285a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastErrorAndTransitionToInitialState( 9295a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt ConnectivityManager.TETHER_ERROR_DISABLE_NAT_ERROR); 9302a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 9312a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 9322a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 9332a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt service.untetherInterface(mIfaceName); 9342a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) { 9355a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastErrorAndTransitionToInitialState( 9365a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt ConnectivityManager.TETHER_ERROR_UNTETHER_IFACE_ERROR); 9372a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 9382a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 9392a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (error) { 9405a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastErrorAndTransitionToInitialState( 9415a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt ConnectivityManager.TETHER_ERROR_MASTER_ERROR); 9422a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 9432a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 9442a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.d(TAG, "Tether lost upstream connection " + mIfaceName); 9452a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendTetherStateChangedBroadcast(); 94665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt if (mUsb) { 947d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt if (!Tethering.this.configureUsbIface(false)) { 9485a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastError(ConnectivityManager.TETHER_ERROR_IFACE_CFG_ERROR); 94965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 95065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 9512a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mInitialState); 9522a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 9535a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt case CMD_TRANSITION_TO_STATE: 9542a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt HierarchicalState s = (HierarchicalState)(message.obj); 9552a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(s); 9562a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 9572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt default: 9582a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retValue = false; 9592a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 9602a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 9612a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retValue; 9622a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 9632a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 9642a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 9652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class UnavailableState extends HierarchicalState { 9662a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 9672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 9682a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setAvailable(false); 9695a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastError(ConnectivityManager.TETHER_ERROR_NO_ERROR); 9702a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setTethered(false); 9712a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendTetherStateChangedBroadcast(); 9722a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 9732a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 9742a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public boolean processMessage(Message message) { 9752a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean retValue = true; 9762a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt switch (message.what) { 9772a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_INTERFACE_UP: 9782a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mInitialState); 9792a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 9802a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt default: 9812a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retValue = false; 9822a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 9832a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 9842a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retValue; 9852a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 9862a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 9872a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 9885a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt void setLastErrorAndTransitionToInitialState(int error) { 9895a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt setLastError(error); 9905a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt transitionTo(mInitialState); 9912a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 99265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 9932a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 9942a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 9952a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class TetherMasterSM extends HierarchicalStateMachine { 9962a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // an interface SM has requested Tethering 9972a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_TETHER_MODE_REQUESTED = 1; 9982a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // an interface SM has unrequested Tethering 9992a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_TETHER_MODE_UNREQUESTED = 2; 10002a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // we received notice that the cellular DUN connection is up 10012a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_CELL_DUN_ENABLED = 3; 10022a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // we received notice that the cellular DUN connection is down 10032a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_CELL_DUN_DISABLED = 4; 10042a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // we timed out on a cellular DUN toggle 10052a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_CELL_DUN_TIMEOUT = 5; 10062a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // it's time to renew our cellular DUN reservation 10072a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_CELL_DUN_RENEW = 6; 10082a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 10092a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // This indicates what a timeout event relates to. A state that 10102a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // sends itself a delayed timeout event and handles incoming timeout events 10112a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // should inc this when it is entered and whenever it sends a new timeout event. 10122a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // We do not flush the old ones. 10132a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private int mSequenceNumber; 10142a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 10152a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mInitialState; 10162a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mCellDunRequestedState; 10172a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mCellDunAliveState; 10182a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mTetherModeAliveState; 10192a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 10202a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mCellDunErrorState; 10212a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mSetIpForwardingEnabledErrorState; 10222a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mSetIpForwardingDisabledErrorState; 10232a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mStartTetheringErrorState; 10242a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mStopTetheringErrorState; 10252a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mSetDnsForwardersErrorState; 10262a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 10272a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private ArrayList mNotifyList; 10282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 10292a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 10302a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private static final int CELL_DUN_TIMEOUT_MS = 45000; 10312a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private static final int CELL_DISABLE_DUN_TIMEOUT_MS = 3000; 10322a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private static final int CELL_DUN_RENEW_MS = 40000; 10332a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 1034dfadaeac088cabce854d8f476405cd412f82593aRobert Greenwalt TetherMasterSM(String name, Looper looper) { 1035dfadaeac088cabce854d8f476405cd412f82593aRobert Greenwalt super(name, looper); 10362a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 10372a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt //Add states 10382a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mInitialState = new InitialState(); 10392a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mInitialState); 10402a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mCellDunRequestedState = new CellDunRequestedState(); 10412a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mCellDunRequestedState); 10422a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mCellDunAliveState = new CellDunAliveState(); 10432a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mCellDunAliveState); 10442a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTetherModeAliveState = new TetherModeAliveState(); 10452a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mTetherModeAliveState); 10462a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 10472a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mCellDunErrorState = new CellDunErrorState(); 10482a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mCellDunErrorState); 10492a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mSetIpForwardingEnabledErrorState = new SetIpForwardingEnabledErrorState(); 10502a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mSetIpForwardingEnabledErrorState); 10512a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mSetIpForwardingDisabledErrorState = new SetIpForwardingDisabledErrorState(); 10522a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mSetIpForwardingDisabledErrorState); 10532a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mStartTetheringErrorState = new StartTetheringErrorState(); 10542a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mStartTetheringErrorState); 10552a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mStopTetheringErrorState = new StopTetheringErrorState(); 10562a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mStopTetheringErrorState); 10572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mSetDnsForwardersErrorState = new SetDnsForwardersErrorState(); 10582a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mSetDnsForwardersErrorState); 10592a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 10602a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mNotifyList = new ArrayList(); 10612a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 10622a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setInitialState(mInitialState); 10632a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 10642a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 1065d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt class TetherMasterUtilState extends HierarchicalState { 1066d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt @Override 1067d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt public boolean processMessage(Message m) { 1068d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return false; 1069d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1070d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt public int turnOnMobileDun() { 1071d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); 1072d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt IConnectivityManager service = IConnectivityManager.Stub.asInterface(b); 1073d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt int retValue = Phone.APN_REQUEST_FAILED; 1074d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt try { 1075d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt retValue = service.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, 1076c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt (mUseHiPri ? Phone.FEATURE_ENABLE_HIPRI : Phone.FEATURE_ENABLE_DUN), 1077c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt new Binder()); 1078d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } catch (Exception e) { 1079d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1080d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return retValue; 1081d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1082d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt public boolean turnOffMobileDun() { 1083d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); 1084d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt IConnectivityManager service = 1085d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt IConnectivityManager.Stub.asInterface(b); 1086d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt try { 1087d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt service.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, 1088c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt (mUseHiPri ? Phone.FEATURE_ENABLE_HIPRI : Phone.FEATURE_ENABLE_DUN)); 1089d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } catch (Exception e) { 1090d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return false; 1091d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1092d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return true; 1093d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1094d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt public boolean turnOnMasterTetherSettings() { 1095d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 1096d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt INetworkManagementService service = 1097d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt INetworkManagementService.Stub.asInterface(b); 1098d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt try { 1099d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt service.setIpForwardingEnabled(true); 1100d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } catch (Exception e) { 1101d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt transitionTo(mSetIpForwardingEnabledErrorState); 1102d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return false; 1103d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1104d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt try { 1105d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt service.startTethering(mDhcpRange[0], mDhcpRange[1]); 1106d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } catch (Exception e) { 1107d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt transitionTo(mStartTetheringErrorState); 1108d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return false; 1109d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1110d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt try { 1111d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt service.setDnsForwarders(mDnsServers); 1112d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } catch (Exception e) { 1113d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt transitionTo(mSetDnsForwardersErrorState); 1114d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return false; 1115d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1116d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt transitionTo(mTetherModeAliveState); 1117d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return true; 1118d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1119d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt public boolean turnOffMasterTetherSettings() { 1120d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 1121d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt INetworkManagementService service = 1122d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt INetworkManagementService.Stub.asInterface(b); 1123d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt try { 1124d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt service.stopTethering(); 1125d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } catch (Exception e) { 1126d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt transitionTo(mStopTetheringErrorState); 1127d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return false; 1128d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1129d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt try { 1130d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt service.setIpForwardingEnabled(false); 1131d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } catch (Exception e) { 1132d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt transitionTo(mSetIpForwardingDisabledErrorState); 1133d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return false; 1134d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1135d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt transitionTo(mInitialState); 1136d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return true; 1137d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1138c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt public String findActiveUpstreamIface() { 1139c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt // check for what iface we can use - if none found switch to error. 1140c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 1141c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt INetworkManagementService service = INetworkManagementService.Stub.asInterface(b); 1142c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt 1143c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt String[] ifaces = new String[0]; 1144c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt try { 1145c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt ifaces = service.listInterfaces(); 1146c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } catch (Exception e) { 1147c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt Log.e(TAG, "Error listing Interfaces :" + e); 1148c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt return null; 1149c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1150c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt for (String iface : ifaces) { 1151c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt for (String regex : mUpstreamIfaceRegexs) { 1152c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt if (iface.matches(regex)) { 1153c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt // verify it is up! 1154c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt InterfaceConfiguration ifcg = null; 1155c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt try { 1156c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt ifcg = service.getInterfaceConfig(iface); 1157c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } catch (Exception e) { 1158c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt Log.e(TAG, "Error getting iface config :" + e); 1159c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt // ignore - try next 1160c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt continue; 1161c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1162c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt if (ifcg.interfaceFlags.contains("up")) { 1163c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt return iface; 1164c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1165c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1166c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1167c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1168c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt return null; 1169c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1170d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 11712a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 1172d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt class InitialState extends TetherMasterUtilState { 11732a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 1174c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt public void enter() { 1175c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt mUseHiPri = false; 1176c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1177c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt @Override 11782a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public boolean processMessage(Message message) { 11792a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.d(TAG, "MasterInitialState.processMessage what=" + message.what); 11802a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean retValue = true; 11812a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt switch (message.what) { 11822a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_MODE_REQUESTED: 11832a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM who = (TetherInterfaceSM)message.obj; 11842a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.d(TAG, "Tether Mode requested by " + who.toString()); 11852a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mNotifyList.add(who); 11862a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mCellDunRequestedState); 11872a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 11882a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_MODE_UNREQUESTED: 11892a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt who = (TetherInterfaceSM)message.obj; 11902a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.d(TAG, "Tether Mode unrequested by " + who.toString()); 11912a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt int index = mNotifyList.indexOf(who); 11922a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (index != -1) { 11932a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mNotifyList.remove(who); 11942a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 11952a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 11962a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_CELL_DUN_ENABLED: 11972a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mCellDunAliveState); 11982a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 11992a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt default: 12002a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retValue = false; 12012a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 12022a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 12032a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retValue; 12042a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 12052a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 1206d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt class CellDunRequestedState extends TetherMasterUtilState { 12072a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 12082a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 1209c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt mUseHiPri = (findActiveUpstreamIface() == null && !mDunRequired); 1210c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt if (mDunRequired || mUseHiPri) { 1211c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt ++mSequenceNumber; 1212c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt int result = turnOnMobileDun(); 1213c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt switch (result) { 1214c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt case Phone.APN_ALREADY_ACTIVE: 1215c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt Log.d(TAG, "Dun already active"); 1216c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt sendMessage(obtainMessage(CMD_CELL_DUN_ENABLED)); 1217c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt break; 1218c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt case Phone.APN_REQUEST_FAILED: 1219c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt case Phone.APN_TYPE_NOT_AVAILABLE: 1220c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt Log.d(TAG, "Error bringing up Dun connection"); 1221c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt Message m = obtainMessage(CMD_CELL_DUN_TIMEOUT); 1222c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt m.arg1 = mSequenceNumber; 1223c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt sendMessage(m); 1224c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt break; 1225c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt case Phone.APN_REQUEST_STARTED: 1226c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt Log.d(TAG, "Started bringing up Dun connection"); 1227c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt m = obtainMessage(CMD_CELL_DUN_TIMEOUT); 1228c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt m.arg1 = mSequenceNumber; 1229c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt sendMessageDelayed(m, CELL_DUN_TIMEOUT_MS); 1230c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt break; 1231c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt default: 1232c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt Log.e(TAG, "Unknown return value from startUsingNetworkFeature " + 1233c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt result); 1234c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1235c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } else { 1236c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt Log.d(TAG, "no Dun Required. Skipping to Active"); 1237c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt sendMessage(obtainMessage(CMD_CELL_DUN_ENABLED)); 12382a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 12392a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 12402a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 12412a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 12422a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public boolean processMessage(Message message) { 12432a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.d(TAG, "CellDunRequestedState.processMessage what=" + message.what); 12442a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean retValue = true; 12452a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt switch (message.what) { 12462a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_MODE_REQUESTED: 12472a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM who = (TetherInterfaceSM)message.obj; 12482a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mNotifyList.add(who); 12492a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 12502a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_MODE_UNREQUESTED: 12512a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt who = (TetherInterfaceSM)message.obj; 12522a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt int index = mNotifyList.indexOf(who); 12532a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (index != -1) { 12542a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mNotifyList.remove(index); 12552a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (mNotifyList.isEmpty()) { 1256c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt if (mDunRequired || mUseHiPri) { 1257c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt turnOffMobileDun(); 1258c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1259d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt transitionTo(mInitialState); 12602a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 12612a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 12622a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 12632a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_CELL_DUN_ENABLED: 1264d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt turnOnMasterTetherSettings(); 12652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 12662a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_CELL_DUN_DISABLED: 12672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 12682a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_CELL_DUN_TIMEOUT: 12692a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (message.arg1 == mSequenceNumber) { 12702a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mCellDunErrorState); 12712a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 12722a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 12732a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt default: 12742a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retValue = false; 12752a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 12762a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 12772a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retValue; 12782a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 12792a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 12802a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 1281d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt class CellDunAliveState extends TetherMasterUtilState { 12822a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 12832a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 128465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt Log.d(TAG, "renewing Dun in " + CELL_DUN_RENEW_MS + "ms"); 12852a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendMessageDelayed(obtainMessage(CMD_CELL_DUN_RENEW), CELL_DUN_RENEW_MS); 12862a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 12872a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 12882a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 12892a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public boolean processMessage(Message message) { 12902a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.d(TAG, "CellDunAliveState.processMessage what=" + message.what); 12912a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean retValue = true; 12922a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt switch (message.what) { 12932a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_MODE_REQUESTED: 12942a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM who = (TetherInterfaceSM)message.obj; 12952a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mNotifyList.add(who); 1296d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt turnOnMasterTetherSettings(); 12972a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 12982a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_MODE_UNREQUESTED: 12992a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt who = (TetherInterfaceSM)message.obj; 13002a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt int index = mNotifyList.indexOf(who); 13012a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (index != -1) { 13022a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mNotifyList.remove(index); 13032a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (mNotifyList.isEmpty()) { 1304c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt if (mDunRequired || mUseHiPri) { 1305c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt turnOffMobileDun(); 1306c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1307d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt transitionTo(mInitialState); 13082a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13092a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13102a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 13112a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_CELL_DUN_DISABLED: 13122a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mInitialState); 13132a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 13142a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_CELL_DUN_RENEW: 131565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt Log.d(TAG, "renewing dun connection - requeuing for another " + 131665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt CELL_DUN_RENEW_MS + "ms"); 1317d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt turnOnMobileDun(); 13182a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendMessageDelayed(obtainMessage(CMD_CELL_DUN_RENEW), CELL_DUN_RENEW_MS); 13192a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 13202a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt default: 13212a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retValue = false; 13222a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 13232a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13242a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retValue; 13252a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13262a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13272a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 1328d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt class TetherModeAliveState extends TetherMasterUtilState { 13292a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 13302a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 1331c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt if (mDunRequired || mUseHiPri) { 1332c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt Log.d(TAG, "renewing Dun in " + CELL_DUN_RENEW_MS + "ms"); 1333c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt sendMessageDelayed(obtainMessage(CMD_CELL_DUN_RENEW), CELL_DUN_RENEW_MS); 1334c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1335c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt mUpstreamIfaceName = findActiveUpstreamIface(); 1336c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt if (mUpstreamIfaceName == null) { 1337c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt Log.d(TAG, "Erroring our of tether - no upstream ifaces available"); 1338c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt sendMessage(obtainMessage(CMD_CELL_DUN_DISABLED)); 1339c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } else { 1340c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt for (Object o : mNotifyList) { 1341c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt TetherInterfaceSM sm = (TetherInterfaceSM)o; 1342c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt sm.sendMessage(sm.obtainMessage(TetherInterfaceSM.CMD_TETHER_MODE_ALIVE)); 1343c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 13442a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13452a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13462a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 13472a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public boolean processMessage(Message message) { 13482a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.d(TAG, "TetherModeAliveState.processMessage what=" + message.what); 13492a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean retValue = true; 13502a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt switch (message.what) { 13512a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_MODE_REQUESTED: 13522a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM who = (TetherInterfaceSM)message.obj; 13532a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mNotifyList.add(who); 13542a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt who.sendMessage(who.obtainMessage(TetherInterfaceSM.CMD_TETHER_MODE_ALIVE)); 13552a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 13562a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_MODE_UNREQUESTED: 13572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt who = (TetherInterfaceSM)message.obj; 13582a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt int index = mNotifyList.indexOf(who); 13592a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (index != -1) { 13602a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mNotifyList.remove(index); 13612a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (mNotifyList.isEmpty()) { 1362c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt if (mDunRequired || mUseHiPri) { 1363c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt turnOffMobileDun(); 1364c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1365d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt turnOffMasterTetherSettings(); // transitions appropriately 1366c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt mUpstreamIfaceName = null; 13672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13682a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13692a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 13702a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_CELL_DUN_DISABLED: 13712a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt int size = mNotifyList.size(); 13722a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (int i = 0; i < size; i++) { 13732a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = (TetherInterfaceSM)mNotifyList.get(i); 13742a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mNotifyList.remove(i); 13752a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sm.sendMessage(sm.obtainMessage( 13762a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM.CMD_TETHER_MODE_DEAD)); 13772a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 1378d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt turnOffMasterTetherSettings(); // transitions appropriately 1379c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt mUpstreamIfaceName = null; 13802a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 138165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt case CMD_CELL_DUN_RENEW: 138265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt Log.d(TAG, "renewing dun connection - requeuing for another " + 138365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt CELL_DUN_RENEW_MS + "ms"); 1384d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt turnOnMobileDun(); 138565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt sendMessageDelayed(obtainMessage(CMD_CELL_DUN_RENEW), CELL_DUN_RENEW_MS); 138665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt break; 13872a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt default: 13882a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retValue = false; 13892a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 13902a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13912a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retValue; 13922a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13932a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13942a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 13952a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class ErrorState extends HierarchicalState { 13962a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt int mErrorNotification; 13972a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 13982a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public boolean processMessage(Message message) { 13992a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean retValue = true; 14002a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt switch (message.what) { 14012a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_MODE_REQUESTED: 14022a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM who = (TetherInterfaceSM)message.obj; 14032a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt who.sendMessage(who.obtainMessage(mErrorNotification)); 14042a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 14052a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt default: 14062a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retValue = false; 14072a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14082a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retValue; 14092a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14102a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt void notify(int msgType) { 14112a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mErrorNotification = msgType; 14122a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (Object o : mNotifyList) { 14132a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = (TetherInterfaceSM)o; 14142a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sm.sendMessage(sm.obtainMessage(msgType)); 14152a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14162a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14172a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 14182a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14192a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class CellDunErrorState extends ErrorState { 14202a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 14212a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 14222a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Error trying to enable Cell DUN"); 14232a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt notify(TetherInterfaceSM.CMD_CELL_DUN_ERROR); 14242a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14252a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14262a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 14272a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class SetIpForwardingEnabledErrorState extends ErrorState { 14282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 14292a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 14302a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Error in setIpForwardingEnabled"); 14312a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt notify(TetherInterfaceSM.CMD_IP_FORWARDING_ENABLE_ERROR); 14322a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14332a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14342a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 14352a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class SetIpForwardingDisabledErrorState extends ErrorState { 14362a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 14372a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 14382a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Error in setIpForwardingDisabled"); 14392a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt notify(TetherInterfaceSM.CMD_IP_FORWARDING_DISABLE_ERROR); 14402a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14412a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14422a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 14432a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class StartTetheringErrorState extends ErrorState { 14442a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 14452a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 14462a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Error in startTethering"); 14472a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt notify(TetherInterfaceSM.CMD_START_TETHERING_ERROR); 14482a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 14492a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt INetworkManagementService service = 14502a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt INetworkManagementService.Stub.asInterface(b); 14512a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 14522a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt service.setIpForwardingEnabled(false); 14532a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) {} 14542a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14552a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14562a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 14572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class StopTetheringErrorState extends ErrorState { 14582a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 14592a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 14602a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Error in stopTethering"); 14612a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt notify(TetherInterfaceSM.CMD_STOP_TETHERING_ERROR); 14622a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 14632a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt INetworkManagementService service = 14642a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt INetworkManagementService.Stub.asInterface(b); 14652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 14662a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt service.setIpForwardingEnabled(false); 14672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) {} 14682a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14692a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14702a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 14712a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class SetDnsForwardersErrorState extends ErrorState { 14722a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 14732a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 14742a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Error in setDnsForwarders"); 14752a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt notify(TetherInterfaceSM.CMD_SET_DNS_FORWARDERS_ERROR); 14762a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 14772a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt INetworkManagementService service = 14782a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt INetworkManagementService.Stub.asInterface(b); 14792a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 14802a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt service.stopTethering(); 14812a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) {} 14822a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 14832a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt service.setIpForwardingEnabled(false); 14842a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) {} 14852a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 1486d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 1487d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 1488d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 14892a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 14902a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (mContext.checkCallingOrSelfPermission( 14912a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt android.Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) { 14922a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt pw.println("Permission Denial: can't dump ConnectivityService.Tether " + 14932a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt "from from pid=" + Binder.getCallingPid() + ", uid=" + 14942a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Binder.getCallingUid()); 14952a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return; 14962a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14972a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 14982a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt pw.println(); 14992a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt pw.println("Tether state:"); 15002a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt synchronized (mIfaces) { 15012a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (Object o : mIfaces.values()) { 15022a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt pw.println(" "+o.toString()); 15032a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 1504d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 15052a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt pw.println(); 15062a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return; 1507d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 1508d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt} 1509