Merge "Fix tethering upstream determination." into honeycomb-LTE
This commit is contained in:
committed by
Android (Google) Code Review
commit
b427f0e696
@@ -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.
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
if (DEBUG) {
|
||||||
NetworkInfo info = cm.getNetworkInfo(
|
Log.d(TAG, "chooseUpstreamType(" + tryCell + "), preferredApn ="
|
||||||
ConnectivityManager.TYPE_MOBILE_HIPRI);
|
+ mPreferredUpstreamMobileApn + ", got type=" + upType);
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if we're on DUN, put our own grab on it
|
||||||
|
if (upType == ConnectivityManager.TYPE_MOBILE_DUN ||
|
||||||
|
upType == ConnectivityManager.TYPE_MOBILE_HIPRI) {
|
||||||
|
turnOnUpstreamMobileConnection(upType);
|
||||||
}
|
}
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "RemoteException calling ConnectivityManager " + e);
|
if (upType == ConnectivityManager.TYPE_NONE) {
|
||||||
iface = null;
|
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 (tryAgainLater) {
|
||||||
// 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 (!success) {
|
|
||||||
// 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;
|
||||||
|
|||||||
Reference in New Issue
Block a user