Merge "Fix tethering upstream determination." into honeycomb-LTE

This commit is contained in:
Robert Greenwalt
2011-06-20 11:47:49 -07:00
committed by Android (Google) Code Review
4 changed files with 133 additions and 170 deletions

View File

@@ -163,6 +163,12 @@ public class ConnectivityManager
*/ */
public static final String EXTRA_ERRORED_TETHER = "erroredArray"; public static final String EXTRA_ERRORED_TETHER = "erroredArray";
/**
* The absence of APN..
* @hide
*/
public static final int TYPE_NONE = -1;
/** /**
* The Default Mobile data connection. When active, all data traffic * The Default Mobile data connection. When active, all data traffic
* will use this connection by default. * will use this connection by default.

View File

@@ -98,7 +98,7 @@
<!-- This string array should be overridden by the device to present a list of network <!-- This string array should be overridden by the device to present a list of network
attributes. This is used by the connectivity manager to decide which networks can coexist attributes. This is used by the connectivity manager to decide which networks can coexist
based on the hardware --> based on the hardware -->
<!-- An Array of "[Connection name],[ConnectivityManager connection type], <!-- An Array of "[Connection name],[ConnectivityManager.TYPE_xxxx],
[associated radio-type],[priority],[restoral-timer(ms)],[dependencyMet] --> [associated radio-type],[priority],[restoral-timer(ms)],[dependencyMet] -->
<!-- the 5th element "resore-time" indicates the number of milliseconds to delay <!-- the 5th element "resore-time" indicates the number of milliseconds to delay
before automatically restore the default connection. Set -1 if the connection before automatically restore the default connection. Set -1 if the connection
@@ -154,16 +154,13 @@
<string-array translatable="false" name="config_tether_dhcp_range"> <string-array translatable="false" name="config_tether_dhcp_range">
</string-array> </string-array>
<!-- Regex array of allowable upstream ifaces for tethering - for example if you want <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
tethering on a new interface called "foo2" add <item>"foo\\d"</item> to the array --> <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
<string-array translatable="false" name="config_tether_upstream_regexs"> <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
</string-array> <integer-array translatable="false" name="config_tether_upstream_types">
<item>1</item>
<!-- Boolean indicating if we require the use of DUN on mobile for tethering. <item>4</item>
Note that this defaults to false so that if you move to a carrier that </integer-array>
hasn't configured anything tethering will still work. If you'd rather
make the device untetherable on unconfigured devices, set to true -->
<bool translatable="false" name="config_tether_dun_required">false</bool>
<!-- String containing the apn value for tethering. May be overriden by secure settings <!-- String containing the apn value for tethering. May be overriden by secure settings
TETHER_DUN_APN. Value is a comma separated series of strings: TETHER_DUN_APN. Value is a comma separated series of strings:

View File

@@ -431,12 +431,10 @@ public class ConnectivityService extends IConnectivityManager.Stub {
} }
mTethering = new Tethering(mContext, mHandler.getLooper()); mTethering = new Tethering(mContext, mHandler.getLooper());
mTetheringConfigValid = (((mNetTrackers[ConnectivityManager.TYPE_MOBILE_DUN] != null) || mTetheringConfigValid = ((mTethering.getTetherableUsbRegexs().length != 0 ||
!mTethering.isDunRequired()) &&
(mTethering.getTetherableUsbRegexs().length != 0 ||
mTethering.getTetherableWifiRegexs().length != 0 || mTethering.getTetherableWifiRegexs().length != 0 ||
mTethering.getTetherableBluetoothRegexs().length != 0) && mTethering.getTetherableBluetoothRegexs().length != 0) &&
mTethering.getUpstreamIfaceRegexs().length != 0); mTethering.getUpstreamIfaceTypes().length != 0);
if (DBG) { if (DBG) {
mInetLog = new ArrayList(); mInetLog = new ArrayList();
@@ -1400,12 +1398,6 @@ public class ConnectivityService extends IConnectivityManager.Stub {
} else { } else {
addPrivateDnsRoutes(mNetTrackers[netType]); addPrivateDnsRoutes(mNetTrackers[netType]);
} }
/** Notify TetheringService if interface name has been changed. */
if (TextUtils.equals(mNetTrackers[netType].getNetworkInfo().getReason(),
Phone.REASON_LINK_PROPERTIES_CHANGED)) {
handleTetherIfaceChange(netType);
}
} else { } else {
if (mNetConfigs[netType].isDefault()) { if (mNetConfigs[netType].isDefault()) {
removeDefaultRoute(mNetTrackers[netType]); removeDefaultRoute(mNetTrackers[netType]);
@@ -2253,14 +2245,6 @@ public class ConnectivityService extends IConnectivityManager.Stub {
} }
} }
private void handleTetherIfaceChange(int type) {
String iface = mNetTrackers[type].getLinkProperties().getInterfaceName();
if (isTetheringSupported()) {
mTethering.handleTetherIfaceChange(iface);
}
}
private void log(String s) { private void log(String s) {
Slog.d(TAG, s); Slog.d(TAG, s);
} }

View File

@@ -57,7 +57,9 @@ import java.io.FileDescriptor;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.Set; import java.util.Set;
/** /**
@@ -82,7 +84,15 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
private String[] mTetherableUsbRegexs; private String[] mTetherableUsbRegexs;
private String[] mTetherableWifiRegexs; private String[] mTetherableWifiRegexs;
private String[] mTetherableBluetoothRegexs; 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 Looper mLooper; private Looper mLooper;
private HandlerThread mThread; private HandlerThread mThread;
@@ -120,9 +130,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
private static final String DNS_DEFAULT_SERVER1 = "8.8.8.8"; private static final String DNS_DEFAULT_SERVER1 = "8.8.8.8";
private static final String DNS_DEFAULT_SERVER2 = "8.8.4.4"; 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 StateMachine mTetherMasterSM;
private Notification mTetheredNotification; private Notification mTetheredNotification;
@@ -189,7 +196,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
mDhcpRange[12] = DHCP_DEFAULT_RANGE7_START; mDhcpRange[12] = DHCP_DEFAULT_RANGE7_START;
mDhcpRange[13] = DHCP_DEFAULT_RANGE7_STOP; mDhcpRange[13] = DHCP_DEFAULT_RANGE7_STOP;
} }
mDunRequired = false; // resample when we turn on
mTetherableUsbRegexs = context.getResources().getStringArray( mTetherableUsbRegexs = context.getResources().getStringArray(
com.android.internal.R.array.config_tether_usb_regexs); com.android.internal.R.array.config_tether_usb_regexs);
@@ -197,8 +203,15 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
com.android.internal.R.array.config_tether_wifi_regexs); com.android.internal.R.array.config_tether_wifi_regexs);
mTetherableBluetoothRegexs = context.getResources().getStringArray( mTetherableBluetoothRegexs = context.getResources().getStringArray(
com.android.internal.R.array.config_tether_bluetooth_regexs); com.android.internal.R.array.config_tether_bluetooth_regexs);
mUpstreamIfaceRegexs = context.getResources().getStringArray( int ifaceTypes[] = context.getResources().getIntArray(
com.android.internal.R.array.config_tether_upstream_regexs); 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 // TODO - remove and rely on real notifications of the current iface
mDnsServers = new String[2]; mDnsServers = new String[2];
@@ -602,16 +615,44 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
return mTetherableBluetoothRegexs; return mTetherableBluetoothRegexs;
} }
public String[] getUpstreamIfaceRegexs() { public int[] getUpstreamIfaceTypes() {
return mUpstreamIfaceRegexs; 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() { public void checkDunRequired() {
boolean defaultVal = mContext.getResources().getBoolean( int requiredApn = ((Settings.Secure.getInt(mContext.getContentResolver(),
com.android.internal.R.bool.config_tether_dun_required); Settings.Secure.TETHER_DUN_REQUIRED, 0) == 1) ?
boolean result = (Settings.Secure.getInt(mContext.getContentResolver(), ConnectivityManager.TYPE_MOBILE_DUN :
Settings.Secure.TETHER_DUN_REQUIRED, (defaultVal ? 1 : 0)) == 1); ConnectivityManager.TYPE_MOBILE_HIPRI);
return result; 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() { public String[] getTetheredIfaces() {
@@ -668,17 +709,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
return retVal; 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 { class TetherInterfaceSM extends StateMachine {
// notification from the master SM that it's not in tether mode // notification from the master SM that it's not in tether mode
static final int CMD_TETHER_MODE_DEAD = 1; static final int CMD_TETHER_MODE_DEAD = 1;
@@ -1086,8 +1116,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
static final int CMD_CELL_CONNECTION_RENEW = 4; static final int CMD_CELL_CONNECTION_RENEW = 4;
// we don't have a valid upstream conn, check again after a delay // we don't have a valid upstream conn, check again after a delay
static final int CMD_RETRY_UPSTREAM = 5; 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 // This indicates what a timeout event relates to. A state that
// sends itself a delayed timeout event and handles incoming timeout events // sends itself a delayed timeout event and handles incoming timeout events
@@ -1107,7 +1135,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
private ArrayList mNotifyList; private ArrayList mNotifyList;
private int mCurrentConnectionSequence; private int mCurrentConnectionSequence;
private boolean mMobileReserved = false; private int mMobileApnReserved = ConnectivityManager.TYPE_NONE;
private String mUpstreamIfaceName = null; private String mUpstreamIfaceName = null;
@@ -1146,22 +1174,34 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
public boolean processMessage(Message m) { public boolean processMessage(Message m) {
return false; 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; 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); IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
IConnectivityManager service = IConnectivityManager.Stub.asInterface(b); IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
int result = Phone.APN_REQUEST_FAILED; int result = Phone.APN_REQUEST_FAILED;
String enableString = enableString(apnType);
if (enableString == null) return false;
try { try {
result = service.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, result = service.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
(mDunRequired ? Phone.FEATURE_ENABLE_DUN_ALWAYS : enableString, new Binder());
Phone.FEATURE_ENABLE_HIPRI), new Binder());
} catch (Exception e) { } catch (Exception e) {
} }
switch (result) { switch (result) {
case Phone.APN_ALREADY_ACTIVE: case Phone.APN_ALREADY_ACTIVE:
case Phone.APN_REQUEST_STARTED: case Phone.APN_REQUEST_STARTED:
mMobileReserved = true; mMobileApnReserved = apnType;
Message m = obtainMessage(CMD_CELL_CONNECTION_RENEW); Message m = obtainMessage(CMD_CELL_CONNECTION_RENEW);
m.arg1 = ++mCurrentConnectionSequence; m.arg1 = ++mCurrentConnectionSequence;
sendMessageDelayed(m, CELL_CONNECTION_RENEW_MS); sendMessageDelayed(m, CELL_CONNECTION_RENEW_MS);
@@ -1174,19 +1214,18 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
return retValue; return retValue;
} }
protected boolean turnOffMobileConnection() { protected boolean turnOffUpstreamMobileConnection() {
if (mMobileReserved) { if (mMobileApnReserved != ConnectivityManager.TYPE_NONE) {
IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
IConnectivityManager service = IConnectivityManager service =
IConnectivityManager.Stub.asInterface(b); IConnectivityManager.Stub.asInterface(b);
try { try {
service.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, service.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
(mDunRequired? Phone.FEATURE_ENABLE_DUN_ALWAYS : enableString(mMobileApnReserved));
Phone.FEATURE_ENABLE_HIPRI));
} catch (Exception e) { } catch (Exception e) {
return false; return false;
} }
mMobileReserved = false; mMobileApnReserved = ConnectivityManager.TYPE_NONE;
} }
return true; return true;
} }
@@ -1238,111 +1277,55 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
transitionTo(mInitialState); transitionTo(mInitialState);
return true; return true;
} }
protected String findActiveUpstreamIface() {
// check for what iface we can use - if none found switch to error.
IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b);
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) { }
b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
INetworkManagementService service = INetworkManagementService.Stub.asInterface(b);
String[] ifaces = new String[0];
try {
ifaces = service.listInterfaces();
} catch (Exception e) {
Log.e(TAG, "Error listing Interfaces :" + e);
return null;
}
for (String iface : ifaces) {
for (String regex : mUpstreamIfaceRegexs) {
if (iface.matches(regex)) {
// verify it is active
InterfaceConfiguration ifcg = null;
try {
ifcg = service.getInterfaceConfig(iface);
if (ifcg.isActive()) {
return iface;
}
} catch (Exception e) {
Log.e(TAG, "Error getting iface config :" + e);
// ignore - try next
continue;
}
}
}
}
return null;
}
protected void chooseUpstreamType(boolean tryCell) { 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); IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b); IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b);
mMobileReserved = false; int upType = ConnectivityManager.TYPE_NONE;
if (DEBUG) { String iface = null;
Log.d(TAG, "chooseUpstreamType(" + tryCell + "), dunRequired ="
+ mDunRequired + ", iface=" + iface); for (Integer netType : mUpstreamIfaceTypes) {
} NetworkInfo info = null;
if (iface != null) {
try { try {
if (mDunRequired) { info = cm.getNetworkInfo(netType.intValue());
// check if Dun is on - we can use that } catch (RemoteException e) { }
NetworkInfo info = cm.getNetworkInfo( if ((info != null) && info.isConnected()) {
ConnectivityManager.TYPE_MOBILE_DUN); upType = netType.intValue();
if (info.isConnected()) { break;
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;
} }
} }
// may have been set to null in the if above
if (iface == null ) { if (DEBUG) {
boolean success = false; Log.d(TAG, "chooseUpstreamType(" + tryCell + "), preferredApn ="
if (tryCell == TRY_TO_SETUP_MOBILE_CONNECTION) { + mPreferredUpstreamMobileApn + ", got type=" + upType);
success = turnOnMobileConnection(); }
// if we're on DUN, put our own grab on it
if (upType == ConnectivityManager.TYPE_MOBILE_DUN ||
upType == ConnectivityManager.TYPE_MOBILE_HIPRI) {
turnOnUpstreamMobileConnection(upType);
}
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) { if (tryAgainLater) {
// wait for things to settle and retry
sendMessageDelayed(CMD_RETRY_UPSTREAM, UPSTREAM_SETTLE_TIME_MS); 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); notifyTetheredOfNewUpstreamIface(iface);
} }
protected void notifyTetheredOfNewUpstreamIface(String ifaceName) { protected void notifyTetheredOfNewUpstreamIface(String ifaceName) {
if (DEBUG) Log.d(TAG, "notifying tethered with iface =" + ifaceName); if (DEBUG) Log.d(TAG, "notifying tethered with iface =" + ifaceName);
mUpstreamIfaceName = ifaceName; mUpstreamIfaceName = ifaceName;
@@ -1357,7 +1340,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
class InitialState extends TetherMasterUtilState { class InitialState extends TetherMasterUtilState {
@Override @Override
public void enter() { public void enter() {
mMobileReserved = false;
} }
@Override @Override
public boolean processMessage(Message message) { public boolean processMessage(Message message) {
@@ -1365,7 +1347,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
boolean retValue = true; boolean retValue = true;
switch (message.what) { switch (message.what) {
case CMD_TETHER_MODE_REQUESTED: case CMD_TETHER_MODE_REQUESTED:
mDunRequired = isDunRequired(); checkDunRequired();
TetherInterfaceSM who = (TetherInterfaceSM)message.obj; TetherInterfaceSM who = (TetherInterfaceSM)message.obj;
if (DEBUG) Log.d(TAG, "Tether Mode requested by " + who.toString()); if (DEBUG) Log.d(TAG, "Tether Mode requested by " + who.toString());
mNotifyList.add(who); mNotifyList.add(who);
@@ -1399,7 +1381,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
} }
@Override @Override
public void exit() { public void exit() {
turnOffMobileConnection(); turnOffUpstreamMobileConnection();
notifyTetheredOfNewUpstreamIface(null); notifyTetheredOfNewUpstreamIface(null);
} }
@Override @Override
@@ -1437,19 +1419,13 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
Log.d(TAG, "renewing mobile connection - requeuing for another " + Log.d(TAG, "renewing mobile connection - requeuing for another " +
CELL_CONNECTION_RENEW_MS + "ms"); CELL_CONNECTION_RENEW_MS + "ms");
} }
mMobileReserved = false; // need to renew it turnOnUpstreamMobileConnection(mMobileApnReserved);
turnOnMobileConnection();
} }
break; break;
case CMD_RETRY_UPSTREAM: case CMD_RETRY_UPSTREAM:
chooseUpstreamType(mTryCell); chooseUpstreamType(mTryCell);
mTryCell = !mTryCell; mTryCell = !mTryCell;
break; break;
case CMD_IFACE_CHANGED:
String iface = (String)message.obj;
if (DEBUG) Log.d(TAG, "Activie upstream interface changed: " + iface);
notifyTetheredOfNewUpstreamIface(iface);
break;
default: default:
retValue = false; retValue = false;
break; break;