summaryrefslogtreecommitdiffstats
path: root/services/java/com/android/server/connectivity
diff options
context:
space:
mode:
authorRobert Greenwalt <rgreenwalt@google.com>2011-06-22 14:41:09 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-06-22 14:41:09 -0700
commit7af34ab8366b2fcddfea1ddc90a89746aaaab856 (patch)
tree14d77a2d2c020b3fe28c0e1858f3d84eb0e22590 /services/java/com/android/server/connectivity
parentbd67cddd0d7b1f6e971228eeb883291875ba721f (diff)
parent5ff886e5319c519a6b644a999680ea651e208981 (diff)
downloadframeworks_base-7af34ab8366b2fcddfea1ddc90a89746aaaab856.zip
frameworks_base-7af34ab8366b2fcddfea1ddc90a89746aaaab856.tar.gz
frameworks_base-7af34ab8366b2fcddfea1ddc90a89746aaaab856.tar.bz2
Merge "resolved conflicts for merge of 7a652bc8 to master"
Diffstat (limited to 'services/java/com/android/server/connectivity')
-rw-r--r--services/java/com/android/server/connectivity/Tethering.java251
1 files changed, 115 insertions, 136 deletions
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index 946a270..911cac2 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -57,7 +57,9 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;
/**
@@ -82,7 +84,15 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
private String[] mTetherableUsbRegexs;
private String[] mTetherableWifiRegexs;
private String[] mTetherableBluetoothRegexs;
- private String[] mUpstreamIfaceRegexs;
+ private Collection<Integer> mUpstreamIfaceTypes;
+
+ private static final Integer MOBILE_TYPE = new Integer(ConnectivityManager.TYPE_MOBILE);
+ private static final Integer HIPRI_TYPE = new Integer(ConnectivityManager.TYPE_MOBILE_HIPRI);
+ private static final Integer DUN_TYPE = new Integer(ConnectivityManager.TYPE_MOBILE_DUN);
+
+ // if we have to connect to mobile, what APN type should we use? Calculated by examining the
+ // upstream type list and the DUN_REQUIRED secure-setting
+ private int mPreferredUpstreamMobileApn = ConnectivityManager.TYPE_NONE;
private INetworkManagementService mNMService;
private Looper mLooper;
@@ -112,9 +122,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
private static final String DNS_DEFAULT_SERVER1 = "8.8.8.8";
private static final String DNS_DEFAULT_SERVER2 = "8.8.4.4";
- // resampled each time we turn on tethering - used as cache for settings/config-val
- private boolean mDunRequired; // configuration info - must use DUN apn on 3g
-
private StateMachine mTetherMasterSM;
private Notification mTetheredNotification;
@@ -159,7 +166,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
if ((mDhcpRange.length == 0) || (mDhcpRange.length % 2 ==1)) {
mDhcpRange = DHCP_DEFAULT_RANGE;
}
- mDunRequired = false; // resample when we turn on
mTetherableUsbRegexs = context.getResources().getStringArray(
com.android.internal.R.array.config_tether_usb_regexs);
@@ -167,8 +173,15 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
com.android.internal.R.array.config_tether_wifi_regexs);
mTetherableBluetoothRegexs = context.getResources().getStringArray(
com.android.internal.R.array.config_tether_bluetooth_regexs);
- mUpstreamIfaceRegexs = context.getResources().getStringArray(
- com.android.internal.R.array.config_tether_upstream_regexs);
+ int ifaceTypes[] = context.getResources().getIntArray(
+ com.android.internal.R.array.config_tether_upstream_types);
+ mUpstreamIfaceTypes = new ArrayList();
+ for (int i : ifaceTypes) {
+ mUpstreamIfaceTypes.add(new Integer(i));
+ }
+
+ // check if the upstream type list needs to be modified due to secure-settings
+ checkDunRequired();
// TODO - remove and rely on real notifications of the current iface
mDnsServers = new String[2];
@@ -582,16 +595,44 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
return mTetherableBluetoothRegexs;
}
- public String[] getUpstreamIfaceRegexs() {
- return mUpstreamIfaceRegexs;
+ public int[] getUpstreamIfaceTypes() {
+ int values[] = new int[mUpstreamIfaceTypes.size()];
+ Iterator<Integer> iterator = mUpstreamIfaceTypes.iterator();
+ for (int i=0; i < mUpstreamIfaceTypes.size(); i++) {
+ values[i] = iterator.next();
+ }
+ return values;
}
- public boolean isDunRequired() {
- boolean defaultVal = mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_tether_dun_required);
- boolean result = (Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.TETHER_DUN_REQUIRED, (defaultVal ? 1 : 0)) == 1);
- return result;
+ public void checkDunRequired() {
+ int requiredApn = ((Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.TETHER_DUN_REQUIRED, 0) == 1) ?
+ ConnectivityManager.TYPE_MOBILE_DUN :
+ ConnectivityManager.TYPE_MOBILE_HIPRI);
+ if (mPreferredUpstreamMobileApn != requiredApn) {
+ if (requiredApn == ConnectivityManager.TYPE_MOBILE_DUN) {
+ while (mUpstreamIfaceTypes.contains(MOBILE_TYPE)) {
+ mUpstreamIfaceTypes.remove(MOBILE_TYPE);
+ }
+ while (mUpstreamIfaceTypes.contains(HIPRI_TYPE)) {
+ mUpstreamIfaceTypes.remove(HIPRI_TYPE);
+ }
+ if (mUpstreamIfaceTypes.contains(DUN_TYPE) == false) {
+ mUpstreamIfaceTypes.add(DUN_TYPE);
+ }
+ } else {
+ while (mUpstreamIfaceTypes.contains(DUN_TYPE)) {
+ mUpstreamIfaceTypes.remove(DUN_TYPE);
+ }
+ if (mUpstreamIfaceTypes.contains(MOBILE_TYPE) == false) {
+ mUpstreamIfaceTypes.add(MOBILE_TYPE);
+ }
+ if (mUpstreamIfaceTypes.contains(HIPRI_TYPE) == false) {
+ mUpstreamIfaceTypes.add(HIPRI_TYPE);
+ }
+ }
+ mPreferredUpstreamMobileApn = requiredApn;
+ }
}
public String[] getTetheredIfaces() {
@@ -648,17 +689,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
return retVal;
}
- public void handleTetherIfaceChange(String iface) {
- // check if iface is white listed
- for (String regex : mUpstreamIfaceRegexs) {
- if (iface.matches(regex)) {
- if (DEBUG) Log.d(TAG, "Tethering got Interface Change");
- mTetherMasterSM.sendMessage(TetherMasterSM.CMD_IFACE_CHANGED, iface);
- break;
- }
- }
- }
-
class TetherInterfaceSM extends StateMachine {
// notification from the master SM that it's not in tether mode
static final int CMD_TETHER_MODE_DEAD = 1;
@@ -1051,8 +1081,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
static final int CMD_CELL_CONNECTION_RENEW = 4;
// we don't have a valid upstream conn, check again after a delay
static final int CMD_RETRY_UPSTREAM = 5;
- // received an indication that upstream interface has changed
- static final int CMD_IFACE_CHANGED = 6;
// This indicates what a timeout event relates to. A state that
// sends itself a delayed timeout event and handles incoming timeout events
@@ -1072,7 +1100,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
private ArrayList mNotifyList;
private int mCurrentConnectionSequence;
- private boolean mMobileReserved = false;
+ private int mMobileApnReserved = ConnectivityManager.TYPE_NONE;
private String mUpstreamIfaceName = null;
@@ -1111,22 +1139,34 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
public boolean processMessage(Message m) {
return false;
}
- protected boolean turnOnMobileConnection() {
+ protected String enableString(int apnType) {
+ switch (apnType) {
+ case ConnectivityManager.TYPE_MOBILE_DUN:
+ return Phone.FEATURE_ENABLE_DUN_ALWAYS;
+ case ConnectivityManager.TYPE_MOBILE:
+ case ConnectivityManager.TYPE_MOBILE_HIPRI:
+ return Phone.FEATURE_ENABLE_HIPRI;
+ }
+ return null;
+ }
+ protected boolean turnOnUpstreamMobileConnection(int apnType) {
boolean retValue = true;
- if (mMobileReserved) return retValue;
+ if (apnType == ConnectivityManager.TYPE_NONE) return false;
+ if (apnType != mMobileApnReserved) turnOffUpstreamMobileConnection();
IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b);
int result = Phone.APN_REQUEST_FAILED;
+ String enableString = enableString(apnType);
+ if (enableString == null) return false;
try {
result = cm.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
- (mDunRequired ? Phone.FEATURE_ENABLE_DUN_ALWAYS :
- Phone.FEATURE_ENABLE_HIPRI), new Binder());
+ enableString, new Binder());
} catch (Exception e) {
}
switch (result) {
case Phone.APN_ALREADY_ACTIVE:
case Phone.APN_REQUEST_STARTED:
- mMobileReserved = true;
+ mMobileApnReserved = apnType;
Message m = obtainMessage(CMD_CELL_CONNECTION_RENEW);
m.arg1 = ++mCurrentConnectionSequence;
sendMessageDelayed(m, CELL_CONNECTION_RENEW_MS);
@@ -1139,18 +1179,17 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
return retValue;
}
- protected boolean turnOffMobileConnection() {
- if (mMobileReserved) {
+ protected boolean turnOffUpstreamMobileConnection() {
+ if (mMobileApnReserved != ConnectivityManager.TYPE_NONE) {
IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b);
try {
cm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
- (mDunRequired? Phone.FEATURE_ENABLE_DUN_ALWAYS :
- Phone.FEATURE_ENABLE_HIPRI));
+ enableString(mMobileApnReserved));
} catch (Exception e) {
return false;
}
- mMobileReserved = false;
+ mMobileApnReserved = ConnectivityManager.TYPE_NONE;
}
return true;
}
@@ -1196,108 +1235,55 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
transitionTo(mInitialState);
return true;
}
- protected String findActiveUpstreamIface() {
- // check for what iface we can use - if none found switch to error.
+
+ protected void chooseUpstreamType(boolean tryCell) {
IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b);
+ int upType = ConnectivityManager.TYPE_NONE;
+ String iface = null;
- try {
- LinkProperties defaultProp = cm.getActiveLinkProperties();
- if (defaultProp != null) {
- String iface = defaultProp.getInterfaceName();
- for(String regex : mUpstreamIfaceRegexs) {
- if (iface.matches(regex)) return iface;
- }
- }
- } catch (RemoteException e) { }
-
- String[] ifaces = new String[0];
- try {
- ifaces = mNMService.listInterfaces();
- } catch (Exception e) {
- Log.e(TAG, "Error listing Interfaces", e);
- return null;
- }
-
- for (String regex : mUpstreamIfaceRegexs) {
- for (String iface : ifaces) {
- if (iface.matches(regex)) {
- // verify it is active
- InterfaceConfiguration ifcg = null;
- try {
- ifcg = mNMService.getInterfaceConfig(iface);
- if (ifcg.isActive()) {
- return iface;
- }
- } catch (Exception e) {
- Log.e(TAG, "Error getting iface config", e);
- // ignore - try next
- continue;
- }
- }
+ for (Integer netType : mUpstreamIfaceTypes) {
+ NetworkInfo info = null;
+ try {
+ info = cm.getNetworkInfo(netType.intValue());
+ } catch (RemoteException e) { }
+ if ((info != null) && info.isConnected()) {
+ upType = netType.intValue();
+ break;
}
}
- return null;
- }
- protected void chooseUpstreamType(boolean tryCell) {
- // decide if the current upstream is good or not and if not
- // do something about it (start up DUN if required or HiPri if not)
- String iface = findActiveUpstreamIface();
- IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
- IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b);
- mMobileReserved = false;
if (DEBUG) {
- Log.d(TAG, "chooseUpstreamType(" + tryCell + "), dunRequired ="
- + mDunRequired + ", iface=" + iface);
+ Log.d(TAG, "chooseUpstreamType(" + tryCell + "), preferredApn ="
+ + mPreferredUpstreamMobileApn + ", got type=" + upType);
}
- if (iface != null) {
- try {
- if (mDunRequired) {
- // check if Dun is on - we can use that
- NetworkInfo info = cm.getNetworkInfo(
- ConnectivityManager.TYPE_MOBILE_DUN);
- if (info.isConnected()) {
- if (DEBUG) Log.d(TAG, "setting dun ifacename =" + iface);
- // even if we're already connected - it may be somebody else's
- // refcount, so add our own
- turnOnMobileConnection();
- } else {
- // verify the iface is not the default mobile - can't use that!
- info = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
- if (info.isConnected()) {
- iface = null; // can't accept this one
- }
- }
- } else {
- if (DEBUG) Log.d(TAG, "checking if hipri brought us this connection");
- NetworkInfo info = cm.getNetworkInfo(
- ConnectivityManager.TYPE_MOBILE_HIPRI);
- if (info.isConnected()) {
- if (DEBUG) Log.d(TAG, "yes - hipri in use");
- // even if we're already connected - it may be sombody else's
- // refcount, so add our own
- turnOnMobileConnection();
- }
- }
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException calling ConnectivityManager", e);
- iface = null;
- }
+
+ // if we're on DUN, put our own grab on it
+ if (upType == ConnectivityManager.TYPE_MOBILE_DUN ||
+ upType == ConnectivityManager.TYPE_MOBILE_HIPRI) {
+ turnOnUpstreamMobileConnection(upType);
}
- // may have been set to null in the if above
- if (iface == null ) {
- boolean success = false;
- if (tryCell == TRY_TO_SETUP_MOBILE_CONNECTION) {
- success = turnOnMobileConnection();
+
+ if (upType == ConnectivityManager.TYPE_NONE) {
+ boolean tryAgainLater = true;
+ if ((tryCell == TRY_TO_SETUP_MOBILE_CONNECTION) &&
+ (turnOnUpstreamMobileConnection(mPreferredUpstreamMobileApn) == true)) {
+ // we think mobile should be coming up - don't set a retry
+ tryAgainLater = false;
}
- if (!success) {
- // wait for things to settle and retry
+ if (tryAgainLater) {
sendMessageDelayed(CMD_RETRY_UPSTREAM, UPSTREAM_SETTLE_TIME_MS);
}
+ } else {
+ LinkProperties linkProperties = null;
+ try {
+ linkProperties = cm.getLinkProperties(upType);
+ } catch (RemoteException e) { }
+ if (linkProperties != null) iface = linkProperties.getInterfaceName();
}
notifyTetheredOfNewUpstreamIface(iface);
}
+
protected void notifyTetheredOfNewUpstreamIface(String ifaceName) {
if (DEBUG) Log.d(TAG, "notifying tethered with iface =" + ifaceName);
mUpstreamIfaceName = ifaceName;
@@ -1312,7 +1298,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
class InitialState extends TetherMasterUtilState {
@Override
public void enter() {
- mMobileReserved = false;
}
@Override
public boolean processMessage(Message message) {
@@ -1320,7 +1305,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
boolean retValue = true;
switch (message.what) {
case CMD_TETHER_MODE_REQUESTED:
- mDunRequired = isDunRequired();
+ checkDunRequired();
TetherInterfaceSM who = (TetherInterfaceSM)message.obj;
if (DEBUG) Log.d(TAG, "Tether Mode requested by " + who.toString());
mNotifyList.add(who);
@@ -1354,7 +1339,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
}
@Override
public void exit() {
- turnOffMobileConnection();
+ turnOffUpstreamMobileConnection();
notifyTetheredOfNewUpstreamIface(null);
}
@Override
@@ -1392,19 +1377,13 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
Log.d(TAG, "renewing mobile connection - requeuing for another " +
CELL_CONNECTION_RENEW_MS + "ms");
}
- mMobileReserved = false; // need to renew it
- turnOnMobileConnection();
+ turnOnUpstreamMobileConnection(mMobileApnReserved);
}
break;
case CMD_RETRY_UPSTREAM:
chooseUpstreamType(mTryCell);
mTryCell = !mTryCell;
break;
- case CMD_IFACE_CHANGED:
- String iface = (String)message.obj;
- if (DEBUG) Log.d(TAG, "Activie upstream interface changed: " + iface);
- notifyTetheredOfNewUpstreamIface(iface);
- break;
default:
retValue = false;
break;