Tethering.java revision c9d5fb7c95f158d9a31d534895373afcfad77806
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; 36d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.os.IBinder; 37d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.os.INetworkManagementService; 382a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport android.os.Message; 39d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.os.RemoteException; 40d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.os.ServiceManager; 41d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.provider.Settings; 42d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport android.util.Log; 43d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 442a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport com.android.internal.telephony.Phone; 452a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport com.android.internal.util.HierarchicalState; 462a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport com.android.internal.util.HierarchicalStateMachine; 472a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 482a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport java.io.FileDescriptor; 492a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport java.io.PrintWriter; 50d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport java.util.ArrayList; 512a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport java.util.HashMap; 522a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwaltimport java.util.Set; 53d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt/** 54d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt * @hide 552a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt * 562a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt * Timeout 572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt * TODO - review error states - they currently are dead-ends with no recovery possible 582a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt * 592a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt * TODO - look for parent classes and code sharing 60d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt */ 6165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 62d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltpublic class Tethering extends INetworkManagementEventObserver.Stub { 63d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 64d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt private Notification mTetheringNotification; 65d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt private Context mContext; 66d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt private final String TAG = "Tethering"; 67d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 68d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt private boolean mPlaySounds = false; 69c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt private boolean mBooted = false; 70c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt //used to remember if we got connected before boot finished 71c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt private boolean mDeferedUsbConnection = false; 72d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 732a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // TODO - remove both of these - should be part of interface inspection/selection stuff 742a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private String[] mTetherableUsbRegexs; 752a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private String[] mTetherableWifiRegexs; 76c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt private String[] mUpstreamIfaceRegexs; 772a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 782a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HashMap<String, TetherInterfaceSM> mIfaces; 79d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 80d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt private ArrayList<String> mActiveTtys; 81d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 82d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt private BroadcastReceiver mStateReceiver; 83d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 84d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt private static final String USB_NEAR_IFACE_ADDR = "169.254.2.1"; 85d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt 862a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private String[] mDhcpRange; 87d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt private static final String DHCP_DEFAULT_RANGE_START = "169.254.2.10"; 88d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt private static final String DHCP_DEFAULT_RANGE_STOP = "169.254.2.64"; 892a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 902a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private String[] mDnsServers; 91d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt private static final String DNS_DEFAULT_SERVER1 = "8.8.8.8"; 92d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt private static final String DNS_DEFAULT_SERVER2 = "4.2.2.2"; 932a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 94c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt private boolean mDunRequired; 95c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt private boolean mUseHiPri; 962a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private String mUpstreamIfaceName; 972a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 982a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt HierarchicalStateMachine mTetherMasterSM; 992a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 100d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt public Tethering(Context context) { 101d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt Log.d(TAG, "Tethering starting"); 102d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt mContext = context; 103d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 104d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt // register for notifications from NetworkManagement Service 105d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 106d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt INetworkManagementService service = INetworkManagementService.Stub.asInterface(b); 107d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt try { 108d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt service.registerObserver(this); 109d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } catch (RemoteException e) { 110d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt Log.e(TAG, "Error registering observer :" + e); 111d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 112d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 1132a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mIfaces = new HashMap<String, TetherInterfaceSM>(); 114d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt mActiveTtys = new ArrayList<String>(); 115d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 1162a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTetherMasterSM = new TetherMasterSM("TetherMaster"); 1172a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTetherMasterSM.start(); 1182a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 119d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt // TODO - remove this hack after real USB connections are detected. 120d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt IntentFilter filter = new IntentFilter(); 1211cb3cb1a94342e03b54fabfaf361c9e2e26f23feMike Lockwood filter.addAction(Intent.ACTION_BATTERY_CHANGED); 1222a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); 123c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt filter.addAction(Intent.ACTION_BOOT_COMPLETED); 1242a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mStateReceiver = new StateReceiver(); 125d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt mContext.registerReceiver(mStateReceiver, filter); 1262a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 1272a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mDhcpRange = context.getResources().getStringArray( 1282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt com.android.internal.R.array.config_tether_dhcp_range); 1292a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (mDhcpRange.length == 0) { 1302a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mDhcpRange = new String[2]; 131d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt mDhcpRange[0] = DHCP_DEFAULT_RANGE_START; 132d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt mDhcpRange[1] = DHCP_DEFAULT_RANGE_STOP; 1332a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } else if(mDhcpRange.length == 1) { 1342a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt String[] tmp = new String[2]; 1352a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt tmp[0] = mDhcpRange[0]; 1362a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt tmp[1] = new String(""); 1372a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mDhcpRange = tmp; 1382a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 139c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt mDunRequired = context.getResources().getBoolean( 140c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt com.android.internal.R.bool.config_tether_dun_required); 1412a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 1422a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTetherableUsbRegexs = context.getResources().getStringArray( 1432a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt com.android.internal.R.array.config_tether_usb_regexs); 1442a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTetherableWifiRegexs = context.getResources().getStringArray( 1452a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt com.android.internal.R.array.config_tether_wifi_regexs); 146c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt mUpstreamIfaceRegexs = context.getResources().getStringArray( 147c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt com.android.internal.R.array.config_tether_upstream_regexs); 1482a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 1492a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // TODO - remove and rely on real notifications of the current iface 1502a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mDnsServers = new String[2]; 151d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt mDnsServers[0] = DNS_DEFAULT_SERVER1; 152d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt mDnsServers[1] = DNS_DEFAULT_SERVER2; 153d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 154d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 1552a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void interfaceLinkStatusChanged(String iface, boolean link) { 156d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt Log.d(TAG, "interfaceLinkStatusChanged " + iface + ", " + link); 1572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean found = false; 15865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt boolean usb = false; 1592a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (String regex : mTetherableWifiRegexs) { 1602a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (iface.matches(regex)) { 1612a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt found = true; 1622a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 1632a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 1642a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 1652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (String regex: mTetherableUsbRegexs) { 1662a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (iface.matches(regex)) { 1672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt found = true; 16865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt usb = true; 1692a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 1702a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 1712a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 1722a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (found == false) return; 1732a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 1742a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt synchronized (mIfaces) { 1752a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = mIfaces.get(iface); 1762a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (link) { 1772a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm == null) { 17865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt sm = new TetherInterfaceSM(iface, usb); 1792a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mIfaces.put(iface, sm); 1802a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sm.start(); 1812a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 1822a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } else { 1832a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm != null) { 1842a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sm.sendMessage(sm.obtainMessage(TetherInterfaceSM.CMD_INTERFACE_DOWN)); 1852a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mIfaces.remove(iface); 1862a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 1872a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 1882a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 189d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 190d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 1912a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void interfaceAdded(String iface) { 19265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 19365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt INetworkManagementService service = INetworkManagementService.Stub.asInterface(b); 1942a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean found = false; 19565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt boolean usb = false; 1962a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (String regex : mTetherableWifiRegexs) { 1972a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (iface.matches(regex)) { 1982a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt found = true; 1992a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 2002a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 2012a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 2022a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (String regex : mTetherableUsbRegexs) { 2032a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (iface.matches(regex)) { 2042a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt found = true; 20565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt usb = true; 2062a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 2072a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 208d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 2092a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (found == false) { 2102a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.d(TAG, iface + " is not a tetherable iface, ignoring"); 211d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt return; 212d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 21365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 2142a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt synchronized (mIfaces) { 2152a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = mIfaces.get(iface); 2162a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm != null) { 2172a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "active iface (" + iface + ") reported as added, ignoring"); 2182a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return; 2192a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 22065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt sm = new TetherInterfaceSM(iface, usb); 2212a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mIfaces.put(iface, sm); 2222a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sm.start(); 2232a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 224d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt Log.d(TAG, "interfaceAdded :" + iface); 225d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 226d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 2272a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void interfaceRemoved(String iface) { 2282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt synchronized (mIfaces) { 2292a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = mIfaces.get(iface); 2302a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm == null) { 2312a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "attempting to remove unknown iface (" + iface + "), ignoring"); 2322a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return; 2332a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 2342a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sm.sendMessage(sm.obtainMessage(TetherInterfaceSM.CMD_INTERFACE_DOWN)); 2352a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mIfaces.remove(iface); 236d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 237d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 238d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 2392a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public boolean tether(String iface) { 240d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt Log.d(TAG, "Tethering " + iface); 2412a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = null; 2422a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt synchronized (mIfaces) { 2432a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sm = mIfaces.get(iface); 244d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 2452a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm == null) { 2462a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Tried to Tether an unknown iface :" + iface + ", ignoring"); 247d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt return false; 248d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 2492a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm.isErrored()) { 2502a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Tried to Tether to an errored iface :" + iface + ", ignoring"); 251d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt return false; 252d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 2532a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (!sm.isAvailable()) { 2542a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Tried to Tether an unavailable iface :" + iface + ", ignoring"); 255d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt return false; 256d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 2572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sm.sendMessage(sm.obtainMessage(TetherInterfaceSM.CMD_TETHER_REQUESTED)); 258d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt return true; 259d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 260d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 2612a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public boolean untether(String iface) { 262d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt Log.d(TAG, "Untethering " + iface); 2632a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = null; 2642a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt synchronized (mIfaces) { 2652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sm = mIfaces.get(iface); 2662a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 2672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm == null) { 2682a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Tried to Untether an unknown iface :" + iface + ", ignoring"); 269d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt return false; 270d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 2712a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm.isErrored()) { 2722a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Tried to Untethered an errored iface :" + iface + ", ignoring"); 273d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt return false; 274d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 2752a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sm.sendMessage(sm.obtainMessage(TetherInterfaceSM.CMD_TETHER_UNREQUESTED)); 2762a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return true; 2772a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 278d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 2792a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private void sendTetherStateChangedBroadcast() { 2802a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); 2812a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt IConnectivityManager service = IConnectivityManager.Stub.asInterface(b); 282d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt try { 2832a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (!service.isTetheringSupported()) return; 2842a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (RemoteException e) { 2852a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return; 286d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 287d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 2882a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt ArrayList<String> availableList = new ArrayList<String>(); 2892a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt ArrayList<String> activeList = new ArrayList<String>(); 2902a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt ArrayList<String> erroredList = new ArrayList<String>(); 2912a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 2922a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt synchronized (mIfaces) { 2932a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Set ifaces = mIfaces.keySet(); 2942a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (Object iface : ifaces) { 2952a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = mIfaces.get(iface); 2962a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm != null) { 2972a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if(sm.isErrored()) { 2982a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt erroredList.add((String)iface); 2992a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } else if (sm.isAvailable()) { 3002a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt availableList.add((String)iface); 3012a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } else if (sm.isTethered()) { 3022a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt activeList.add((String)iface); 3032a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 3042a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 305d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 306d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 307d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt Intent broadcast = new Intent(ConnectivityManager.ACTION_TETHER_STATE_CHANGED); 308d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt broadcast.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 3092a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt broadcast.putStringArrayListExtra(ConnectivityManager.EXTRA_AVAILABLE_TETHER, 3102a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt availableList); 3112a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt broadcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ACTIVE_TETHER, activeList); 3122a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt broadcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ERRORED_TETHER, 3132a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt erroredList); 3142a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mContext.sendStickyBroadcast(broadcast); 315d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt Log.d(TAG, "sendTetherStateChangedBroadcast " + availableList.size() + ", " + 316d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt activeList.size() + ", " + erroredList.size()); 3172a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // check if we need to send a USB notification 3182a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // Check if the user wants to be bothered 3192a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean tellUser = (Settings.Secure.getInt(mContext.getContentResolver(), 3202a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Settings.Secure.TETHER_NOTIFY, 0) == 1); 3212a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (Object o : activeList) { 3222a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt String s = (String)o; 3232a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (Object regexObject : mTetherableUsbRegexs) { 3242a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (s.matches((String)regexObject)) { 3252a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt showTetheredNotification(); 3262a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return; 3272a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 3282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 3292a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 3302a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (tellUser) { 3312a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (Object o : availableList) { 3322a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt String s = (String)o; 33365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt for (String match : mTetherableUsbRegexs) { 33465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt if (s.matches(match)) { 3352a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt showTetherAvailableNotification(); 3362a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return; 3372a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 3382a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 3392a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 340d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 3412a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt clearNotification(); 342d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 343d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 344d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt private void showTetherAvailableNotification() { 345d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt NotificationManager notificationManager = (NotificationManager)mContext. 346d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt getSystemService(Context.NOTIFICATION_SERVICE); 347d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt if (notificationManager == null) { 348d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt return; 349d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 350d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt Intent intent = new Intent(); 351d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt intent.setClass(mContext, com.android.internal.app.TetherActivity.class); 352d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 353d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 354d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0); 355d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 356d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt Resources r = Resources.getSystem(); 357d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt CharSequence title = r.getText(com.android.internal.R.string. 358d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt tether_available_notification_title); 359d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt CharSequence message = r.getText(com.android.internal.R.string. 360d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt tether_available_notification_message); 361d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 362d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt if(mTetheringNotification == null) { 363d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt mTetheringNotification = new Notification(); 364d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt mTetheringNotification.when = 0; 365d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 366d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt mTetheringNotification.icon = com.android.internal.R.drawable.stat_sys_tether_usb; 367d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 368d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt boolean playSounds = false; 369d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt //playSounds = SystemProperties.get("persist.service.mount.playsnd", "1").equals("1"); 370d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt if (playSounds) { 371d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt mTetheringNotification.defaults |= Notification.DEFAULT_SOUND; 372d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } else { 373d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt mTetheringNotification.defaults &= ~Notification.DEFAULT_SOUND; 374d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 375d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 376d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt mTetheringNotification.flags = Notification.FLAG_ONGOING_EVENT; 377d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt mTetheringNotification.tickerText = title; 378d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt mTetheringNotification.setLatestEventInfo(mContext, title, message, pi); 379d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 380d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt notificationManager.notify(mTetheringNotification.icon, mTetheringNotification); 381d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 382d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 383d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 384d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt private void showTetheredNotification() { 385d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt NotificationManager notificationManager = (NotificationManager)mContext. 386d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt getSystemService(Context.NOTIFICATION_SERVICE); 387d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt if (notificationManager == null) { 388d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt return; 389d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 390d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 391d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt Intent intent = new Intent(); 392d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt intent.setClass(mContext, com.android.internal.app.TetherActivity.class); 393d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 394d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 395d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0); 396d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 397d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt Resources r = Resources.getSystem(); 398d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt CharSequence title = r.getText(com.android.internal.R.string. 399d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt tether_stop_notification_title); 400d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt CharSequence message = r.getText(com.android.internal.R.string. 401d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt tether_stop_notification_message); 402d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 403d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt if(mTetheringNotification == null) { 404d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt mTetheringNotification = new Notification(); 405d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt mTetheringNotification.when = 0; 406d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 407d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt mTetheringNotification.icon = com.android.internal.R.drawable.stat_sys_tether_usb; 408d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 409d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt boolean playSounds = false; 410d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt //playSounds = SystemProperties.get("persist.service.mount.playsnd", "1").equals("1"); 411d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt if (playSounds) { 412d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt mTetheringNotification.defaults |= Notification.DEFAULT_SOUND; 413d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } else { 414d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt mTetheringNotification.defaults &= ~Notification.DEFAULT_SOUND; 415d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 416d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 417d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt mTetheringNotification.flags = Notification.FLAG_ONGOING_EVENT; 418d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt mTetheringNotification.tickerText = title; 419d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt mTetheringNotification.setLatestEventInfo(mContext, title, message, pi); 420d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 421d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt notificationManager.notify(mTetheringNotification.icon, mTetheringNotification); 422d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 423d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 424d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt private void clearNotification() { 425d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt NotificationManager notificationManager = (NotificationManager)mContext. 426d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt getSystemService(Context.NOTIFICATION_SERVICE); 427d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt if (notificationManager != null && mTetheringNotification != null) { 428d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt notificationManager.cancel(mTetheringNotification.icon); 429d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt mTetheringNotification = null; 430d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 431d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 432d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 4332a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private class StateReceiver extends BroadcastReceiver { 434d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt public void onReceive(Context content, Intent intent) { 4352a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt String action = intent.getAction(); 4361cb3cb1a94342e03b54fabfaf361c9e2e26f23feMike Lockwood if (action.equals(Intent.ACTION_BATTERY_CHANGED)) { 4371cb3cb1a94342e03b54fabfaf361c9e2e26f23feMike Lockwood boolean usbConnected = (intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) 4381cb3cb1a94342e03b54fabfaf361c9e2e26f23feMike Lockwood == BatteryManager.BATTERY_PLUGGED_USB); 439c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt if (mBooted) { 440c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt Tethering.this.enableUsbIfaces(usbConnected); // add or remove them 441c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } else { 442c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt mDeferedUsbConnection = usbConnected; 443c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 4442a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { 4452a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); 44665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt IConnectivityManager service = IConnectivityManager.Stub.asInterface(b); 4472a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 448c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt int netType = (mUseHiPri ? ConnectivityManager.TYPE_MOBILE_HIPRI: 449c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt ConnectivityManager.TYPE_MOBILE_DUN); 450c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt NetworkInfo info = service.getNetworkInfo(netType); 4512a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt int msg; 452a4437fc93a993c7ab326b592d22c05be2f11b543Mike Lockwood if (info != null && info.isConnected() == true) { 4532a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt msg = TetherMasterSM.CMD_CELL_DUN_ENABLED; 4542a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } else { 4552a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt msg = TetherMasterSM.CMD_CELL_DUN_DISABLED; 4562a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 4572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTetherMasterSM.sendMessage(mTetherMasterSM.obtainMessage(msg)); 4582a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (RemoteException e) {} 459c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } else if (action.equals(Intent.ACTION_BOOT_COMPLETED)) { 460c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt mBooted = true; 461c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt if (mDeferedUsbConnection) { 462c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt Tethering.this.enableUsbIfaces(true); 463c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 464d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 465d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 466d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 467d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 46865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt // used on cable insert/remove 469d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt private void enableUsbIfaces(boolean enable) { 47065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 47165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt INetworkManagementService service = INetworkManagementService.Stub.asInterface(b); 47265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt String[] ifaces = new String[0]; 47365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt try { 47465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt ifaces = service.listInterfaces(); 47565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } catch (Exception e) { 47665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt Log.e(TAG, "Error listing Interfaces :" + e); 47765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt return; 47865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 47965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt for (String iface : ifaces) { 48065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt for (String regex : mTetherableUsbRegexs) { 48165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt if (iface.matches(regex)) { 482d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt if (enable) { 48365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt interfaceAdded(iface); 48465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } else { 48565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt interfaceRemoved(iface); 48665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 48765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 48865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 48965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 49065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 49165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 49265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt // toggled when we enter/leave the fully teathered state 493d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt private boolean enableUsbRndis(boolean enabled) { 494d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt Log.d(TAG, "enableUsbRndis(" + enabled + ")"); 49565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 49665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt INetworkManagementService service = INetworkManagementService.Stub.asInterface(b); 49765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 49865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt try { 49965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt if (enabled) { 50065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt synchronized (this) { 50165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt if (!service.isUsbRNDISStarted()) { 50265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt service.startUsbRNDIS(); 50365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 50465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 50565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } else { 50665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt if (service.isUsbRNDISStarted()) { 50765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt service.stopUsbRNDIS(); 50865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 50965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 51065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } catch (Exception e) { 51165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt Log.e(TAG, "Error toggling usb RNDIS :" + e); 51265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt return false; 51365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 51465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt return true; 51565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 51665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 51765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt // configured when we start tethering and unconfig'd on error or conclusion 518d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt private boolean configureUsbIface(boolean enabled) { 519d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt Log.d(TAG, "configureUsbIface(" + enabled + ")"); 52065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 52165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 52265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt INetworkManagementService service = INetworkManagementService.Stub.asInterface(b); 52365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 52465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt // bring toggle the interfaces 52565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt String[] ifaces = new String[0]; 52665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt try { 52765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt ifaces = service.listInterfaces(); 52865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } catch (Exception e) { 52965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt Log.e(TAG, "Error listing Interfaces :" + e); 53065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt return false; 53165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 53265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt for (String iface : ifaces) { 53365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt for (String regex : mTetherableUsbRegexs) { 53465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt if (iface.matches(regex)) { 53565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt InterfaceConfiguration ifcg = null; 53665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt try { 53765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt ifcg = service.getInterfaceConfig(iface); 53865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt if (ifcg != null) { 53965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt ifcg.ipAddr = (169 << 24) + (254 << 16) + (2 << 8) + 1; 54065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt ifcg.netmask = (255 << 24) + (255 << 16) + (255 << 8) + 0; 54165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt if (enabled) { 54265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt ifcg.interfaceFlags = ifcg.interfaceFlags.replace("down", "up"); 54365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } else { 54465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt ifcg.interfaceFlags = ifcg.interfaceFlags.replace("up", "down"); 545d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt // TODO - clean this up - maybe a better regex? 546c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt ifcg.interfaceFlags = ifcg.interfaceFlags.replace("running", ""); 547c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt ifcg.interfaceFlags = ifcg.interfaceFlags.replace(" "," "); 54865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 54965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt service.setInterfaceConfig(iface, ifcg); 55065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 55165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } catch (Exception e) { 55265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt Log.e(TAG, "Error configuring interface " + iface + ", :" + e); 55365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt return false; 55465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 55565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 55665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 55765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 55865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 55965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt return true; 56065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 56165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 5622a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public String[] getTetherableUsbRegexs() { 5632a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return mTetherableUsbRegexs; 5642a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 5652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 5662a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public String[] getTetherableWifiRegexs() { 5672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return mTetherableWifiRegexs; 5682a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 5692a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 570c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt public String[] getUpstreamIfaceRegexs() { 571c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt return mUpstreamIfaceRegexs; 572c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 573c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt 574c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt public boolean isDunRequired() { 575c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt return mDunRequired; 576c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 577c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt 5782a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public String[] getTetheredIfaces() { 5792a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt ArrayList<String> list = new ArrayList<String>(); 5802a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt synchronized (mIfaces) { 5812a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Set keys = mIfaces.keySet(); 5822a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (Object key : keys) { 5832a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = mIfaces.get(key); 5842a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm.isTethered()) { 5852a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt list.add((String)key); 5862a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 5872a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 5882a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 5892a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt String[] retVal = new String[list.size()]; 5902a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (int i=0; i < list.size(); i++) { 5912a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retVal[i] = list.get(i); 5922a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 5932a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retVal; 5942a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 5952a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 5962a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public String[] getTetherableIfaces() { 5972a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt ArrayList<String> list = new ArrayList<String>(); 5982a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt synchronized (mIfaces) { 5992a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Set keys = mIfaces.keySet(); 6002a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (Object key : keys) { 6012a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = mIfaces.get(key); 6022a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (sm.isAvailable()) { 6032a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt list.add((String)key); 6042a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 6052a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 6062a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 6072a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt String[] retVal = new String[list.size()]; 6082a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (int i=0; i < list.size(); i++) { 6092a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retVal[i] = list.get(i); 6102a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 6112a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retVal; 6122a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 6132a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 6142a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 6152a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class TetherInterfaceSM extends HierarchicalStateMachine { 6162a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification from the master SM that it's in tether mode 6172a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_TETHER_MODE_ALIVE = 1; 6182a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification from the master SM that it's not in tether mode 6192a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_TETHER_MODE_DEAD = 2; 6202a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // request from the user that it wants to tether 6212a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_TETHER_REQUESTED = 3; 6222a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // request from the user that it wants to untether 6232a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_TETHER_UNREQUESTED = 4; 6242a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification that this interface is down 6252a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_INTERFACE_DOWN = 5; 6262a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification that this interface is up 6272a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_INTERFACE_UP = 6; 6282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification from the master SM that it had an error turning on cellular dun 6292a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_CELL_DUN_ERROR = 10; 6302a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification from the master SM that it had trouble enabling IP Forwarding 6312a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_IP_FORWARDING_ENABLE_ERROR = 11; 6322a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification from the master SM that it had trouble disabling IP Forwarding 6332a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_IP_FORWARDING_DISABLE_ERROR = 12; 6342a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification from the master SM that it had trouble staring tethering 6352a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_START_TETHERING_ERROR = 13; 6362a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification from the master SM that it had trouble stopping tethering 6372a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_STOP_TETHERING_ERROR = 14; 6382a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // notification from the master SM that it had trouble setting the DNS forwarders 6392a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_SET_DNS_FORWARDERS_ERROR = 15; 6402a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // a mechanism to transition self to error state from an enter function 6412a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_TRANSITION_TO_ERROR = 16; 6422a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 6432a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mDefaultState; 6442a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 6452a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mInitialState; 6462a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mStartingState; 6472a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mTetheredState; 6482a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 6492a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mMasterTetherErrorState; 6502a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mTetherInterfaceErrorState; 6512a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mUntetherInterfaceErrorState; 6522a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mEnableNatErrorState; 6532a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mDisableNatErrorState; 65465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt private HierarchicalState mUsbConfigurationErrorState; 6552a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 6562a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mUnavailableState; 6572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 6582a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private boolean mAvailable; 6592a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private boolean mErrored; 6602a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private boolean mTethered; 6612a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 6622a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt String mIfaceName; 66365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt boolean mUsb; 6642a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 66565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt TetherInterfaceSM(String name, boolean usb) { 6662a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt super(name); 6672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mIfaceName = name; 66865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt mUsb = usb; 6692a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 6702a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mInitialState = new InitialState(); 6712a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mInitialState); 6722a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mStartingState = new StartingState(); 6732a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mStartingState); 6742a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTetheredState = new TetheredState(); 6752a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mTetheredState); 6762a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mMasterTetherErrorState = new MasterTetherErrorState(); 6772a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mMasterTetherErrorState); 6782a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTetherInterfaceErrorState = new TetherInterfaceErrorState(); 6792a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mTetherInterfaceErrorState); 6802a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mUntetherInterfaceErrorState = new UntetherInterfaceErrorState(); 6812a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mUntetherInterfaceErrorState); 6822a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mEnableNatErrorState = new EnableNatErrorState(); 6832a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mEnableNatErrorState); 6842a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mDisableNatErrorState = new DisableNatErrorState(); 6852a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mDisableNatErrorState); 68665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt mUsbConfigurationErrorState = new UsbConfigurationErrorState(); 68765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt addState(mUsbConfigurationErrorState); 6882a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mUnavailableState = new UnavailableState(); 6892a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mUnavailableState); 6902a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 6912a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setInitialState(mInitialState); 6922a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 6932a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 6942a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public String toString() { 6952a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt String res = new String(); 6962a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt res += mIfaceName + " - "; 6972a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt HierarchicalState current = getCurrentState(); 6982a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (current == mInitialState) res += "InitialState"; 6992a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (current == mStartingState) res += "StartingState"; 7002a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (current == mTetheredState) res += "TetheredState"; 7012a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (current == mMasterTetherErrorState) res += "MasterTetherErrorState"; 7022a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (current == mTetherInterfaceErrorState) res += "TetherInterfaceErrorState"; 7032a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (current == mUntetherInterfaceErrorState) res += "UntetherInterfaceErrorState"; 7042a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (current == mEnableNatErrorState) res += "EnableNatErrorState"; 7052a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (current == mDisableNatErrorState) res += "DisableNatErrorState"; 70665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt if (current == mUsbConfigurationErrorState) res += "UsbConfigurationErrorState"; 7072a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (current == mUnavailableState) res += "UnavailableState"; 7082a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (mAvailable) res += " - Available"; 7092a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (mTethered) res += " - Tethered"; 7102a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (mErrored) res += " - ERRORED"; 7112a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return res; 7122a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7132a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 7142a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // synchronized between this getter and the following setter 7152a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public synchronized boolean isAvailable() { 7162a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return mAvailable; 7172a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7182a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 7192a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private synchronized void setAvailable(boolean available) { 7202a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mAvailable = available; 7212a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7222a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 7232a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // synchronized between this getter and the following setter 7242a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public synchronized boolean isTethered() { 7252a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return mTethered; 7262a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7272a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 7282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private synchronized void setTethered(boolean tethered) { 7292a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTethered = tethered; 7302a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7312a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 7322a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // synchronized between this getter and the following setter 7332a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public synchronized boolean isErrored() { 7342a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return mErrored; 7352a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7362a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 73765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt private void setErrored(boolean errored) { 73865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt synchronized (this) { 73965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt mErrored = errored; 74065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 74165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt if (errored && mUsb) { 74265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt // note everything's been unwound by this point so nothing to do on 74365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt // further error.. 744d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt Tethering.this.configureUsbIface(false); 74565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 7462a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7472a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 7482a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class InitialState extends HierarchicalState { 7492a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 7502a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 7512a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setAvailable(true); 7522a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setTethered(false); 7532a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setErrored(false); 7542a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendTetherStateChangedBroadcast(); 7552a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7562a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 7572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 7582a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public boolean processMessage(Message message) { 7592a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.d(TAG, "InitialState.processMessage what=" + message.what); 7602a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean retValue = true; 7612a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt switch (message.what) { 7622a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_REQUESTED: 7632a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Message m = mTetherMasterSM.obtainMessage( 7642a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherMasterSM.CMD_TETHER_MODE_REQUESTED); 7652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt m.obj = TetherInterfaceSM.this; 7662a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTetherMasterSM.sendMessage(m); 7672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mStartingState); 7682a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 7692a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_INTERFACE_DOWN: 7702a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mUnavailableState); 7712a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 7722a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt default: 7732a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retValue = false; 7742a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 7752a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7762a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retValue; 7772a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7782a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7792a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 7802a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class StartingState extends HierarchicalState { 7812a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 7822a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 7832a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setAvailable(false); 78465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt if (mUsb) { 785d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt if (!Tethering.this.configureUsbIface(true)) { 78665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt Message m = mTetherMasterSM.obtainMessage( 78765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt TetherMasterSM.CMD_TETHER_MODE_UNREQUESTED); 78865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt m.obj = TetherInterfaceSM.this; 78965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt mTetherMasterSM.sendMessage(m); 79065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 79165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt m = obtainMessage(CMD_TRANSITION_TO_ERROR); 79265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt m.obj = mUsbConfigurationErrorState; 79365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt sendMessageAtFrontOfQueue(m); 79465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt return; 79565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 79665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 7972a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendTetherStateChangedBroadcast(); 7982a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 7992a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 8002a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public boolean processMessage(Message message) { 8012a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.d(TAG, "StartingState.processMessage what=" + message.what); 8022a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean retValue = true; 8032a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt switch (message.what) { 8042a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // maybe a parent class? 8052a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_UNREQUESTED: 8062a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Message m = mTetherMasterSM.obtainMessage( 8072a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherMasterSM.CMD_TETHER_MODE_UNREQUESTED); 8082a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt m.obj = TetherInterfaceSM.this; 8092a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTetherMasterSM.sendMessage(m); 81065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt if (mUsb) { 811d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt if (!Tethering.this.configureUsbIface(false)) { 81265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt transitionTo(mUsbConfigurationErrorState); 81365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt break; 81465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 81565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 8162a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mInitialState); 8172a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 8182a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_MODE_ALIVE: 8192a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mTetheredState); 8202a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 8212a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_CELL_DUN_ERROR: 8222a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_IP_FORWARDING_ENABLE_ERROR: 8232a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_IP_FORWARDING_DISABLE_ERROR: 8242a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_START_TETHERING_ERROR: 8252a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_STOP_TETHERING_ERROR: 8262a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_SET_DNS_FORWARDERS_ERROR: 8272a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mMasterTetherErrorState); 8282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 8292a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_INTERFACE_DOWN: 8302a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt m = mTetherMasterSM.obtainMessage( 8312a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherMasterSM.CMD_TETHER_MODE_UNREQUESTED); 8322a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt m.obj = TetherInterfaceSM.this; 8332a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTetherMasterSM.sendMessage(m); 8342a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mUnavailableState); 8352a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 83665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt case CMD_TRANSITION_TO_ERROR: 83765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt HierarchicalState s = (HierarchicalState)(message.obj); 83865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt transitionTo(s); 83965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt break; 8402a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt default: 8412a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retValue = false; 8422a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 8432a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retValue; 8442a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 8452a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 8462a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 8472a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class TetheredState extends HierarchicalState { 8482a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 8492a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 8502a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 8512a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt INetworkManagementService service = 8522a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt INetworkManagementService.Stub.asInterface(b); 8532a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 8542a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt service.tetherInterface(mIfaceName); 8552a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) { 8562a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Message m = obtainMessage(CMD_TRANSITION_TO_ERROR); 8572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt m.obj = mTetherInterfaceErrorState; 8582a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendMessageAtFrontOfQueue(m); 8592a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return; 8602a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 8612a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 8622a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt service.enableNat(mIfaceName, mUpstreamIfaceName); 8632a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) { 8642a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Message m = obtainMessage(CMD_TRANSITION_TO_ERROR); 8652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt m.obj = mEnableNatErrorState; 8662a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendMessageAtFrontOfQueue(m); 8672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return; 8682a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 869d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt if (mUsb) Tethering.this.enableUsbRndis(true); 8702a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.d(TAG, "Tethered " + mIfaceName); 8712a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setAvailable(false); 8722a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setTethered(true); 8732a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendTetherStateChangedBroadcast(); 8742a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 8752a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 87665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt public void exit() { 877d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt if (mUsb) Tethering.this.enableUsbRndis(false); 87865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 87965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt @Override 8802a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public boolean processMessage(Message message) { 8812a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.d(TAG, "TetheredState.processMessage what=" + message.what); 8822a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean retValue = true; 8832a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean error = false; 8842a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt switch (message.what) { 8852a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_UNREQUESTED: 8862a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_INTERFACE_DOWN: 8872a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 8882a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt INetworkManagementService service = 8892a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt INetworkManagementService.Stub.asInterface(b); 8902a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 8912a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt service.disableNat(mIfaceName, mUpstreamIfaceName); 8922a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) { 8932a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mDisableNatErrorState); 8942a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 8952a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 8962a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 8972a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt service.untetherInterface(mIfaceName); 8982a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) { 8992a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mUntetherInterfaceErrorState); 9002a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 9012a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 9022a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Message m = mTetherMasterSM.obtainMessage( 9032a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherMasterSM.CMD_TETHER_MODE_UNREQUESTED); 9042a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt m.obj = TetherInterfaceSM.this; 9052a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTetherMasterSM.sendMessage(m); 9062a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (message.what == CMD_TETHER_UNREQUESTED) { 90765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt if (mUsb) { 908d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt if (!Tethering.this.configureUsbIface(false)) { 90965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt transitionTo(mUsbConfigurationErrorState); 91065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } else { 9116142a0b68fffb2d9595c364ebf4f8be996f37f77Robert Greenwalt transitionTo(mInitialState); 91265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 9136142a0b68fffb2d9595c364ebf4f8be996f37f77Robert Greenwalt } else { 9146142a0b68fffb2d9595c364ebf4f8be996f37f77Robert Greenwalt transitionTo(mInitialState); 91565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 9162a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } else if (message.what == CMD_INTERFACE_DOWN) { 9172a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mUnavailableState); 9182a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 9192a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.d(TAG, "Untethered " + mIfaceName); 9202a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 9212a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_CELL_DUN_ERROR: 9222a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_IP_FORWARDING_ENABLE_ERROR: 9232a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_IP_FORWARDING_DISABLE_ERROR: 9242a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_START_TETHERING_ERROR: 9252a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_STOP_TETHERING_ERROR: 9262a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_SET_DNS_FORWARDERS_ERROR: 9272a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt error = true; 9282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // fall through 9292a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_MODE_DEAD: 9302a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 9312a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt service = INetworkManagementService.Stub.asInterface(b); 9322a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 9332a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt service.disableNat(mIfaceName, mUpstreamIfaceName); 9342a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) { 9352a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mDisableNatErrorState); 9362a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 9372a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 9382a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 9392a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt service.untetherInterface(mIfaceName); 9402a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) { 9412a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mUntetherInterfaceErrorState); 9422a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 9432a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 9442a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (error) { 9452a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mMasterTetherErrorState); 9462a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 9472a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 9482a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.d(TAG, "Tether lost upstream connection " + mIfaceName); 9492a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendTetherStateChangedBroadcast(); 95065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt if (mUsb) { 951d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt if (!Tethering.this.configureUsbIface(false)) { 9526142a0b68fffb2d9595c364ebf4f8be996f37f77Robert Greenwalt transitionTo(mUsbConfigurationErrorState); 95365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt break; 95465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 95565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 9562a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mInitialState); 9572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 9582a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TRANSITION_TO_ERROR: 9592a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt HierarchicalState s = (HierarchicalState)(message.obj); 9602a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(s); 9612a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 9622a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt default: 9632a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retValue = false; 9642a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 9652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 9662a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retValue; 9672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 9682a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 9692a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 9702a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class UnavailableState extends HierarchicalState { 9712a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 9722a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 9732a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setAvailable(false); 9742a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setErrored(false); 9752a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setTethered(false); 9762a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendTetherStateChangedBroadcast(); 9772a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 9782a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 9792a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public boolean processMessage(Message message) { 9802a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean retValue = true; 9812a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt switch (message.what) { 9822a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_INTERFACE_UP: 9832a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mInitialState); 9842a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 9852a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt default: 9862a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retValue = false; 9872a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 9882a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 9892a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retValue; 9902a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 9912a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 9922a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 9932a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 9942a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class ErrorState extends HierarchicalState { 9952a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt int mErrorNotification; 9962a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 9972a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public boolean processMessage(Message message) { 9982a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean retValue = true; 9992a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt switch (message.what) { 10002a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_REQUESTED: 10012a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendTetherStateChangedBroadcast(); 10022a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 10032a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt default: 10042a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retValue = false; 10052a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 10062a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 10072a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retValue; 10082a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 10092a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 10102a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 10112a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class MasterTetherErrorState extends ErrorState { 10122a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 10132a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 10142a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Error in Master Tether state " + mIfaceName); 10152a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setAvailable(false); 10162a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setErrored(true); 10172a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendTetherStateChangedBroadcast(); 10182a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 10192a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 10202a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 10212a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class TetherInterfaceErrorState extends ErrorState { 10222a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 10232a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 10242a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Error trying to tether " + mIfaceName); 10252a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setAvailable(false); 10262a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setErrored(true); 10272a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendTetherStateChangedBroadcast(); 10282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 10292a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 10302a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 10312a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class UntetherInterfaceErrorState extends ErrorState { 10322a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 10332a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 10342a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Error trying to untether " + mIfaceName); 10352a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setAvailable(false); 10362a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setErrored(true); 10372a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendTetherStateChangedBroadcast(); 10382a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 10392a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 10402a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 10412a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class EnableNatErrorState extends ErrorState { 10422a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 10432a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 10442a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Error trying to enable NAT " + mIfaceName); 10452a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setAvailable(false); 10462a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setErrored(true); 10472a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 10482a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 10492a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt INetworkManagementService service = INetworkManagementService.Stub.asInterface(b); 10502a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 10512a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt service.untetherInterface(mIfaceName); 10522a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) {} 10532a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendTetherStateChangedBroadcast(); 10542a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 10552a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 10562a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 10572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 10582a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class DisableNatErrorState extends ErrorState { 10592a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 10602a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 10612a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Error trying to disable NAT " + mIfaceName); 10622a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setAvailable(false); 10632a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setErrored(true); 10642a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 10652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 10662a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt INetworkManagementService service = INetworkManagementService.Stub.asInterface(b); 10672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 10682a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt service.untetherInterface(mIfaceName); 10692a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) {} 10702a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendTetherStateChangedBroadcast(); 10712a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 10722a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 107365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt 107465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt class UsbConfigurationErrorState extends ErrorState { 107565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt @Override 107665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt public void enter() { 107765ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt Log.e(TAG, "Error trying to configure USB " + mIfaceName); 107865ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt setAvailable(false); 107965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt setErrored(true); 108065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 108165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt } 10822a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 10832a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 10842a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class TetherMasterSM extends HierarchicalStateMachine { 10852a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // an interface SM has requested Tethering 10862a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_TETHER_MODE_REQUESTED = 1; 10872a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // an interface SM has unrequested Tethering 10882a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_TETHER_MODE_UNREQUESTED = 2; 10892a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // we received notice that the cellular DUN connection is up 10902a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_CELL_DUN_ENABLED = 3; 10912a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // we received notice that the cellular DUN connection is down 10922a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_CELL_DUN_DISABLED = 4; 10932a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // we timed out on a cellular DUN toggle 10942a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_CELL_DUN_TIMEOUT = 5; 10952a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // it's time to renew our cellular DUN reservation 10962a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt static final int CMD_CELL_DUN_RENEW = 6; 10972a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 10982a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // This indicates what a timeout event relates to. A state that 10992a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // sends itself a delayed timeout event and handles incoming timeout events 11002a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // should inc this when it is entered and whenever it sends a new timeout event. 11012a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt // We do not flush the old ones. 11022a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private int mSequenceNumber; 11032a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 11042a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mInitialState; 11052a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mCellDunRequestedState; 11062a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mCellDunAliveState; 11072a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mTetherModeAliveState; 11082a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 11092a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mCellDunErrorState; 11102a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mSetIpForwardingEnabledErrorState; 11112a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mSetIpForwardingDisabledErrorState; 11122a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mStartTetheringErrorState; 11132a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mStopTetheringErrorState; 11142a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private HierarchicalState mSetDnsForwardersErrorState; 11152a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 11162a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private ArrayList mNotifyList; 11172a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 11182a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 11192a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private static final int CELL_DUN_TIMEOUT_MS = 45000; 11202a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private static final int CELL_DISABLE_DUN_TIMEOUT_MS = 3000; 11212a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt private static final int CELL_DUN_RENEW_MS = 40000; 11222a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 11232a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherMasterSM(String name) { 11242a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt super(name); 11252a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 11262a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt //Add states 11272a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mInitialState = new InitialState(); 11282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mInitialState); 11292a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mCellDunRequestedState = new CellDunRequestedState(); 11302a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mCellDunRequestedState); 11312a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mCellDunAliveState = new CellDunAliveState(); 11322a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mCellDunAliveState); 11332a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mTetherModeAliveState = new TetherModeAliveState(); 11342a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mTetherModeAliveState); 11352a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 11362a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mCellDunErrorState = new CellDunErrorState(); 11372a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mCellDunErrorState); 11382a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mSetIpForwardingEnabledErrorState = new SetIpForwardingEnabledErrorState(); 11392a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mSetIpForwardingEnabledErrorState); 11402a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mSetIpForwardingDisabledErrorState = new SetIpForwardingDisabledErrorState(); 11412a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mSetIpForwardingDisabledErrorState); 11422a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mStartTetheringErrorState = new StartTetheringErrorState(); 11432a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mStartTetheringErrorState); 11442a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mStopTetheringErrorState = new StopTetheringErrorState(); 11452a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mStopTetheringErrorState); 11462a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mSetDnsForwardersErrorState = new SetDnsForwardersErrorState(); 11472a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt addState(mSetDnsForwardersErrorState); 11482a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 11492a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mNotifyList = new ArrayList(); 11502a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 11512a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt setInitialState(mInitialState); 11522a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 11532a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 1154d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt class TetherMasterUtilState extends HierarchicalState { 1155d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt @Override 1156d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt public boolean processMessage(Message m) { 1157d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return false; 1158d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1159d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt public int turnOnMobileDun() { 1160d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); 1161d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt IConnectivityManager service = IConnectivityManager.Stub.asInterface(b); 1162d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt int retValue = Phone.APN_REQUEST_FAILED; 1163d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt try { 1164d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt retValue = service.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, 1165c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt (mUseHiPri ? Phone.FEATURE_ENABLE_HIPRI : Phone.FEATURE_ENABLE_DUN), 1166c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt new Binder()); 1167d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } catch (Exception e) { 1168d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1169d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return retValue; 1170d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1171d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt public boolean turnOffMobileDun() { 1172d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); 1173d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt IConnectivityManager service = 1174d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt IConnectivityManager.Stub.asInterface(b); 1175d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt try { 1176d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt service.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, 1177c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt (mUseHiPri ? Phone.FEATURE_ENABLE_HIPRI : Phone.FEATURE_ENABLE_DUN)); 1178d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } catch (Exception e) { 1179d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return false; 1180d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1181d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return true; 1182d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1183d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt public boolean turnOnMasterTetherSettings() { 1184d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 1185d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt INetworkManagementService service = 1186d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt INetworkManagementService.Stub.asInterface(b); 1187d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt try { 1188d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt service.setIpForwardingEnabled(true); 1189d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } catch (Exception e) { 1190d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt transitionTo(mSetIpForwardingEnabledErrorState); 1191d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return false; 1192d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1193d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt try { 1194d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt service.startTethering(mDhcpRange[0], mDhcpRange[1]); 1195d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } catch (Exception e) { 1196d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt transitionTo(mStartTetheringErrorState); 1197d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return false; 1198d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1199d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt try { 1200d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt service.setDnsForwarders(mDnsServers); 1201d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } catch (Exception e) { 1202d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt transitionTo(mSetDnsForwardersErrorState); 1203d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return false; 1204d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1205d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt transitionTo(mTetherModeAliveState); 1206d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return true; 1207d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1208d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt public boolean turnOffMasterTetherSettings() { 1209d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 1210d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt INetworkManagementService service = 1211d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt INetworkManagementService.Stub.asInterface(b); 1212d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt try { 1213d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt service.stopTethering(); 1214d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } catch (Exception e) { 1215d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt transitionTo(mStopTetheringErrorState); 1216d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return false; 1217d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1218d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt try { 1219d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt service.setIpForwardingEnabled(false); 1220d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } catch (Exception e) { 1221d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt transitionTo(mSetIpForwardingDisabledErrorState); 1222d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return false; 1223d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1224d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt transitionTo(mInitialState); 1225d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt return true; 1226d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 1227c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt public String findActiveUpstreamIface() { 1228c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt // check for what iface we can use - if none found switch to error. 1229c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 1230c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt INetworkManagementService service = INetworkManagementService.Stub.asInterface(b); 1231c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt 1232c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt String[] ifaces = new String[0]; 1233c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt try { 1234c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt ifaces = service.listInterfaces(); 1235c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } catch (Exception e) { 1236c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt Log.e(TAG, "Error listing Interfaces :" + e); 1237c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt return null; 1238c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1239c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt for (String iface : ifaces) { 1240c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt for (String regex : mUpstreamIfaceRegexs) { 1241c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt if (iface.matches(regex)) { 1242c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt // verify it is up! 1243c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt InterfaceConfiguration ifcg = null; 1244c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt try { 1245c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt ifcg = service.getInterfaceConfig(iface); 1246c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } catch (Exception e) { 1247c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt Log.e(TAG, "Error getting iface config :" + e); 1248c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt // ignore - try next 1249c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt continue; 1250c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1251c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt if (ifcg.interfaceFlags.contains("up")) { 1252c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt return iface; 1253c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1254c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1255c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1256c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1257c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt return null; 1258c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1259d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt } 12602a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 1261d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt class InitialState extends TetherMasterUtilState { 12622a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 1263c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt public void enter() { 1264c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt mUseHiPri = false; 1265c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1266c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt @Override 12672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public boolean processMessage(Message message) { 12682a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.d(TAG, "MasterInitialState.processMessage what=" + message.what); 12692a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean retValue = true; 12702a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt switch (message.what) { 12712a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_MODE_REQUESTED: 12722a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM who = (TetherInterfaceSM)message.obj; 12732a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.d(TAG, "Tether Mode requested by " + who.toString()); 12742a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mNotifyList.add(who); 12752a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mCellDunRequestedState); 12762a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 12772a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_MODE_UNREQUESTED: 12782a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt who = (TetherInterfaceSM)message.obj; 12792a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.d(TAG, "Tether Mode unrequested by " + who.toString()); 12802a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt int index = mNotifyList.indexOf(who); 12812a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (index != -1) { 12822a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mNotifyList.remove(who); 12832a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 12842a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 12852a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_CELL_DUN_ENABLED: 12862a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mCellDunAliveState); 12872a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 12882a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt default: 12892a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retValue = false; 12902a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 12912a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 12922a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retValue; 12932a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 12942a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 1295d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt class CellDunRequestedState extends TetherMasterUtilState { 12962a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 12972a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 1298c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt mUseHiPri = (findActiveUpstreamIface() == null && !mDunRequired); 1299c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt if (mDunRequired || mUseHiPri) { 1300c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt ++mSequenceNumber; 1301c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt int result = turnOnMobileDun(); 1302c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt switch (result) { 1303c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt case Phone.APN_ALREADY_ACTIVE: 1304c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt Log.d(TAG, "Dun already active"); 1305c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt sendMessage(obtainMessage(CMD_CELL_DUN_ENABLED)); 1306c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt break; 1307c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt case Phone.APN_REQUEST_FAILED: 1308c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt case Phone.APN_TYPE_NOT_AVAILABLE: 1309c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt Log.d(TAG, "Error bringing up Dun connection"); 1310c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt Message m = obtainMessage(CMD_CELL_DUN_TIMEOUT); 1311c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt m.arg1 = mSequenceNumber; 1312c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt sendMessage(m); 1313c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt break; 1314c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt case Phone.APN_REQUEST_STARTED: 1315c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt Log.d(TAG, "Started bringing up Dun connection"); 1316c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt m = obtainMessage(CMD_CELL_DUN_TIMEOUT); 1317c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt m.arg1 = mSequenceNumber; 1318c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt sendMessageDelayed(m, CELL_DUN_TIMEOUT_MS); 1319c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt break; 1320c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt default: 1321c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt Log.e(TAG, "Unknown return value from startUsingNetworkFeature " + 1322c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt result); 1323c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1324c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } else { 1325c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt Log.d(TAG, "no Dun Required. Skipping to Active"); 1326c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt sendMessage(obtainMessage(CMD_CELL_DUN_ENABLED)); 13272a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13292a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 13302a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 13312a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public boolean processMessage(Message message) { 13322a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.d(TAG, "CellDunRequestedState.processMessage what=" + message.what); 13332a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean retValue = true; 13342a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt switch (message.what) { 13352a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_MODE_REQUESTED: 13362a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM who = (TetherInterfaceSM)message.obj; 13372a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mNotifyList.add(who); 13382a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 13392a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_MODE_UNREQUESTED: 13402a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt who = (TetherInterfaceSM)message.obj; 13412a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt int index = mNotifyList.indexOf(who); 13422a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (index != -1) { 13432a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mNotifyList.remove(index); 13442a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (mNotifyList.isEmpty()) { 1345c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt if (mDunRequired || mUseHiPri) { 1346c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt turnOffMobileDun(); 1347c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1348d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt transitionTo(mInitialState); 13492a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13502a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13512a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 13522a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_CELL_DUN_ENABLED: 1353d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt turnOnMasterTetherSettings(); 13542a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 13552a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_CELL_DUN_DISABLED: 13562a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 13572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_CELL_DUN_TIMEOUT: 13582a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (message.arg1 == mSequenceNumber) { 13592a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mCellDunErrorState); 13602a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13612a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 13622a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt default: 13632a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retValue = false; 13642a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 13652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13662a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retValue; 13672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13682a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13692a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 1370d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt class CellDunAliveState extends TetherMasterUtilState { 13712a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 13722a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 137365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt Log.d(TAG, "renewing Dun in " + CELL_DUN_RENEW_MS + "ms"); 13742a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendMessageDelayed(obtainMessage(CMD_CELL_DUN_RENEW), CELL_DUN_RENEW_MS); 13752a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13762a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 13772a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 13782a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public boolean processMessage(Message message) { 13792a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.d(TAG, "CellDunAliveState.processMessage what=" + message.what); 13802a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean retValue = true; 13812a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt switch (message.what) { 13822a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_MODE_REQUESTED: 13832a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM who = (TetherInterfaceSM)message.obj; 13842a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mNotifyList.add(who); 1385d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt turnOnMasterTetherSettings(); 13862a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 13872a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_MODE_UNREQUESTED: 13882a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt who = (TetherInterfaceSM)message.obj; 13892a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt int index = mNotifyList.indexOf(who); 13902a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (index != -1) { 13912a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mNotifyList.remove(index); 13922a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (mNotifyList.isEmpty()) { 1393c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt if (mDunRequired || mUseHiPri) { 1394c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt turnOffMobileDun(); 1395c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1396d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt transitionTo(mInitialState); 13972a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13982a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 13992a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 14002a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_CELL_DUN_DISABLED: 14012a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt transitionTo(mInitialState); 14022a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 14032a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_CELL_DUN_RENEW: 140465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt Log.d(TAG, "renewing dun connection - requeuing for another " + 140565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt CELL_DUN_RENEW_MS + "ms"); 1406d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt turnOnMobileDun(); 14072a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sendMessageDelayed(obtainMessage(CMD_CELL_DUN_RENEW), CELL_DUN_RENEW_MS); 14082a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 14092a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt default: 14102a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retValue = false; 14112a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 14122a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14132a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retValue; 14142a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14152a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14162a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 1417d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt class TetherModeAliveState extends TetherMasterUtilState { 14182a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 14192a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 1420c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt if (mDunRequired || mUseHiPri) { 1421c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt Log.d(TAG, "renewing Dun in " + CELL_DUN_RENEW_MS + "ms"); 1422c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt sendMessageDelayed(obtainMessage(CMD_CELL_DUN_RENEW), CELL_DUN_RENEW_MS); 1423c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1424c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt mUpstreamIfaceName = findActiveUpstreamIface(); 1425c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt if (mUpstreamIfaceName == null) { 1426c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt Log.d(TAG, "Erroring our of tether - no upstream ifaces available"); 1427c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt sendMessage(obtainMessage(CMD_CELL_DUN_DISABLED)); 1428c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } else { 1429c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt for (Object o : mNotifyList) { 1430c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt TetherInterfaceSM sm = (TetherInterfaceSM)o; 1431c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt sm.sendMessage(sm.obtainMessage(TetherInterfaceSM.CMD_TETHER_MODE_ALIVE)); 1432c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 14332a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14342a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14352a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 14362a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public boolean processMessage(Message message) { 14372a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.d(TAG, "TetherModeAliveState.processMessage what=" + message.what); 14382a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean retValue = true; 14392a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt switch (message.what) { 14402a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_MODE_REQUESTED: 14412a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM who = (TetherInterfaceSM)message.obj; 14422a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mNotifyList.add(who); 14432a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt who.sendMessage(who.obtainMessage(TetherInterfaceSM.CMD_TETHER_MODE_ALIVE)); 14442a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 14452a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_MODE_UNREQUESTED: 14462a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt who = (TetherInterfaceSM)message.obj; 14472a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt int index = mNotifyList.indexOf(who); 14482a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (index != -1) { 14492a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mNotifyList.remove(index); 14502a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (mNotifyList.isEmpty()) { 1451c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt if (mDunRequired || mUseHiPri) { 1452c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt turnOffMobileDun(); 1453c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt } 1454d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt turnOffMasterTetherSettings(); // transitions appropriately 1455c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt mUpstreamIfaceName = null; 14562a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14582a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 14592a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_CELL_DUN_DISABLED: 14602a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt int size = mNotifyList.size(); 14612a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (int i = 0; i < size; i++) { 14622a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = (TetherInterfaceSM)mNotifyList.get(i); 14632a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mNotifyList.remove(i); 14642a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sm.sendMessage(sm.obtainMessage( 14652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM.CMD_TETHER_MODE_DEAD)); 14662a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 1467d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt turnOffMasterTetherSettings(); // transitions appropriately 1468c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt mUpstreamIfaceName = null; 14692a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 147065ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt case CMD_CELL_DUN_RENEW: 147165ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt Log.d(TAG, "renewing dun connection - requeuing for another " + 147265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt CELL_DUN_RENEW_MS + "ms"); 1473d70a3d4e2d356aab4cac313f1f9d8272a5e3e8d0Robert Greenwalt turnOnMobileDun(); 147465ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt sendMessageDelayed(obtainMessage(CMD_CELL_DUN_RENEW), CELL_DUN_RENEW_MS); 147565ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt break; 14762a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt default: 14772a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retValue = false; 14782a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 14792a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14802a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retValue; 14812a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14822a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14832a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 14842a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class ErrorState extends HierarchicalState { 14852a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt int mErrorNotification; 14862a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 14872a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public boolean processMessage(Message message) { 14882a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt boolean retValue = true; 14892a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt switch (message.what) { 14902a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt case CMD_TETHER_MODE_REQUESTED: 14912a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM who = (TetherInterfaceSM)message.obj; 14922a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt who.sendMessage(who.obtainMessage(mErrorNotification)); 14932a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt break; 14942a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt default: 14952a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt retValue = false; 14962a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14972a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return retValue; 14982a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 14992a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt void notify(int msgType) { 15002a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt mErrorNotification = msgType; 15012a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (Object o : mNotifyList) { 15022a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt TetherInterfaceSM sm = (TetherInterfaceSM)o; 15032a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt sm.sendMessage(sm.obtainMessage(msgType)); 15042a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 15052a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 15062a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 15072a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 15082a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class CellDunErrorState extends ErrorState { 15092a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 15102a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 15112a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Error trying to enable Cell DUN"); 15122a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt notify(TetherInterfaceSM.CMD_CELL_DUN_ERROR); 15132a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 15142a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 15152a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 15162a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class SetIpForwardingEnabledErrorState extends ErrorState { 15172a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 15182a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 15192a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Error in setIpForwardingEnabled"); 15202a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt notify(TetherInterfaceSM.CMD_IP_FORWARDING_ENABLE_ERROR); 15212a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 15222a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 15232a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 15242a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class SetIpForwardingDisabledErrorState extends ErrorState { 15252a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 15262a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 15272a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Error in setIpForwardingDisabled"); 15282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt notify(TetherInterfaceSM.CMD_IP_FORWARDING_DISABLE_ERROR); 15292a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 15302a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 15312a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 15322a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class StartTetheringErrorState extends ErrorState { 15332a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 15342a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 15352a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Error in startTethering"); 15362a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt notify(TetherInterfaceSM.CMD_START_TETHERING_ERROR); 15372a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 15382a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt INetworkManagementService service = 15392a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt INetworkManagementService.Stub.asInterface(b); 15402a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 15412a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt service.setIpForwardingEnabled(false); 15422a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) {} 15432a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 15442a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 15452a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 15462a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class StopTetheringErrorState extends ErrorState { 15472a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 15482a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 15492a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Error in stopTethering"); 15502a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt notify(TetherInterfaceSM.CMD_STOP_TETHERING_ERROR); 15512a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 15522a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt INetworkManagementService service = 15532a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt INetworkManagementService.Stub.asInterface(b); 15542a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 15552a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt service.setIpForwardingEnabled(false); 15562a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) {} 15572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 15582a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 15592a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 15602a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt class SetDnsForwardersErrorState extends ErrorState { 15612a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt @Override 15622a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void enter() { 15632a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Log.e(TAG, "Error in setDnsForwarders"); 15642a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt notify(TetherInterfaceSM.CMD_SET_DNS_FORWARDERS_ERROR); 15652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 15662a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt INetworkManagementService service = 15672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt INetworkManagementService.Stub.asInterface(b); 15682a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 15692a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt service.stopTethering(); 15702a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) {} 15712a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt try { 15722a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt service.setIpForwardingEnabled(false); 15732a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } catch (Exception e) {} 15742a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 1575d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 1576d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 1577d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt 15782a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 15792a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt if (mContext.checkCallingOrSelfPermission( 15802a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt android.Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) { 15812a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt pw.println("Permission Denial: can't dump ConnectivityService.Tether " + 15822a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt "from from pid=" + Binder.getCallingPid() + ", uid=" + 15832a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt Binder.getCallingUid()); 15842a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return; 15852a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 15862a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt 15872a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt pw.println(); 15882a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt pw.println("Tether state:"); 15892a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt synchronized (mIfaces) { 15902a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt for (Object o : mIfaces.values()) { 15912a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt pw.println(" "+o.toString()); 15922a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt } 1593d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 15942a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt pw.println(); 15952a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt return; 1596d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt } 1597d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt} 1598