summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
authorRobert Greenwalt <robdroid@android.com>2009-08-12 16:08:25 -0700
committerRobert Greenwalt <robdroid@android.com>2009-08-12 16:08:25 -0700
commit42acef37339afe6ac608c842f1637870ee9c4f6c (patch)
tree22b2f834f5bcd73389e8e9e3bd1a40348e5767fe /core/java/android
parenteeb175fb120668336e241e4708459a24faf103ec (diff)
downloadframeworks_base-42acef37339afe6ac608c842f1637870ee9c4f6c.zip
frameworks_base-42acef37339afe6ac608c842f1637870ee9c4f6c.tar.gz
frameworks_base-42acef37339afe6ac608c842f1637870ee9c4f6c.tar.bz2
Add net type to mobile for mobile-required traffic
This also refactors ConnectivityService a bit towards supporting multiple simultaneous connections by making each a seem like a seperate Network with it's own stateTracker, etc. Also adds tracking of process death to clean orphaned startUsingNetworkFeature features.
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/net/ConnectivityManager.java59
-rw-r--r--core/java/android/net/IConnectivityManager.aidl4
-rw-r--r--core/java/android/net/MobileDataStateTracker.java265
-rw-r--r--core/java/android/net/NetworkStateTracker.java73
4 files changed, 214 insertions, 187 deletions
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 1429bc1..a127df0 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -18,6 +18,7 @@ package android.net;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.os.Binder;
import android.os.RemoteException;
/**
@@ -114,15 +115,64 @@ public class ConnectivityManager
public static final String ACTION_BACKGROUND_DATA_SETTING_CHANGED =
"android.net.conn.BACKGROUND_DATA_SETTING_CHANGED";
- public static final int TYPE_MOBILE = 0;
- public static final int TYPE_WIFI = 1;
+ /**
+ * The Default Mobile data connection. When active, all data traffic
+ * will use this connection by default. Should not coexist with other
+ * default connections.
+ */
+ public static final int TYPE_MOBILE = 0;
+ /**
+ * The Default WIFI data connection. When active, all data traffic
+ * will use this connection by default. Should not coexist with other
+ * default connections.
+ */
+ public static final int TYPE_WIFI = 1;
+ /**
+ * An MMS-specific Mobile data connection. This connection may be the
+ * same as {@link #TYPEMOBILE} but it may be different. This is used
+ * by applications needing to talk to the carrier's Multimedia Messaging
+ * Service servers. It may coexist with default data connections.
+ * {@hide}
+ */
+ public static final int TYPE_MOBILE_MMS = 2;
+ /**
+ * A SUPL-specific Mobile data connection. This connection may be the
+ * same as {@link #TYPEMOBILE} but it may be different. This is used
+ * by applications needing to talk to the carrier's Secure User Plane
+ * Location servers for help locating the device. It may coexist with
+ * default data connections.
+ * {@hide}
+ */
+ public static final int TYPE_MOBILE_SUPL = 3;
+ /**
+ * A DUN-specific Mobile data connection. This connection may be the
+ * same as {@link #TYPEMOBILE} but it may be different. This is used
+ * by applicaitons performing a Dial Up Networking bridge so that
+ * the carrier is aware of DUN traffic. It may coexist with default data
+ * connections.
+ * {@hide}
+ */
+ public static final int TYPE_MOBILE_DUN = 4;
+ /**
+ * A High Priority Mobile data connection. This connection is typically
+ * the same as {@link #TYPEMOBILE} but the routing setup is different.
+ * Only requesting processes will have access to the Mobile DNS servers
+ * and only IP's explicitly requested via {@link #requestRouteToHost}
+ * will route over this interface.
+ *{@hide}
+ */
+ public static final int TYPE_MOBILE_HIPRI = 5;
+ /** {@hide} */
+ public static final int MAX_RADIO_TYPE = TYPE_WIFI;
+ /** {@hide} */
+ public static final int MAX_NETWORK_TYPE = TYPE_MOBILE_HIPRI;
public static final int DEFAULT_NETWORK_PREFERENCE = TYPE_WIFI;
private IConnectivityManager mService;
static public boolean isNetworkTypeValid(int networkType) {
- return networkType == TYPE_WIFI || networkType == TYPE_MOBILE;
+ return networkType >= 0 && networkType <= MAX_NETWORK_TYPE;
}
public void setNetworkPreference(int preference) {
@@ -195,7 +245,8 @@ public class ConnectivityManager
*/
public int startUsingNetworkFeature(int networkType, String feature) {
try {
- return mService.startUsingNetworkFeature(networkType, feature);
+ return mService.startUsingNetworkFeature(networkType, feature,
+ new Binder());
} catch (RemoteException e) {
return -1;
}
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index de68598..9f59cce 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -17,6 +17,7 @@
package android.net;
import android.net.NetworkInfo;
+import android.os.IBinder;
/**
* Interface that answers queries about, and allows changing, the
@@ -39,7 +40,8 @@ interface IConnectivityManager
boolean setRadio(int networkType, boolean turnOn);
- int startUsingNetworkFeature(int networkType, in String feature);
+ int startUsingNetworkFeature(int networkType, in String feature,
+ in IBinder binder);
int stopUsingNetworkFeature(int networkType, in String feature);
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index 1064fb6..6b00900 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -32,9 +32,6 @@ import android.telephony.TelephonyManager;
import android.util.Log;
import android.text.TextUtils;
-import java.util.List;
-import java.util.ArrayList;
-
/**
* Track the state of mobile data connectivity. This is done by
* receiving broadcast intents from the Phone process whenever
@@ -45,36 +42,47 @@ import java.util.ArrayList;
public class MobileDataStateTracker extends NetworkStateTracker {
private static final String TAG = "MobileDataStateTracker";
- private static final boolean DBG = false;
+ private static final boolean DBG = true;
private Phone.DataState mMobileDataState;
private ITelephony mPhoneService;
- private static final String[] sDnsPropNames = {
- "net.rmnet0.dns1",
- "net.rmnet0.dns2",
- "net.eth0.dns1",
- "net.eth0.dns2",
- "net.eth0.dns3",
- "net.eth0.dns4",
- "net.gprs.dns1",
- "net.gprs.dns2"
- };
- private List<String> mDnsServers;
- private String mInterfaceName;
- private int mDefaultGatewayAddr;
- private int mLastCallingPid = -1;
+
+ private String mApnType;
+ private boolean mEnabled;
+ private boolean mTeardownRequested;
/**
* Create a new MobileDataStateTracker
* @param context the application context of the caller
* @param target a message handler for getting callbacks about state changes
+ * @param netType the ConnectivityManager network type
+ * @param apnType the Phone apnType
+ * @param tag the name of this network
*/
- public MobileDataStateTracker(Context context, Handler target) {
- super(context, target, ConnectivityManager.TYPE_MOBILE,
- TelephonyManager.getDefault().getNetworkType(), "MOBILE",
- TelephonyManager.getDefault().getNetworkTypeName());
+ public MobileDataStateTracker(Context context, Handler target,
+ int netType, String apnType, String tag) {
+ super(context, target, netType,
+ TelephonyManager.getDefault().getNetworkType(), tag,
+ TelephonyManager.getDefault().getNetworkTypeName());
+ mApnType = apnType;
mPhoneService = null;
- mDnsServers = new ArrayList<String>();
+ mTeardownRequested = false;
+ if(netType == ConnectivityManager.TYPE_MOBILE) {
+ mEnabled = true;
+ } else {
+ mEnabled = false;
+ }
+
+ mDnsPropNames = new String[] {
+ "net.rmnet0.dns1",
+ "net.rmnet0.dns2",
+ "net.eth0.dns1",
+ "net.eth0.dns2",
+ "net.eth0.dns3",
+ "net.eth0.dns4",
+ "net.gprs.dns1",
+ "net.gprs.dns2"};
+
}
/**
@@ -93,31 +101,70 @@ public class MobileDataStateTracker extends NetworkStateTracker {
mMobileDataState = Phone.DataState.DISCONNECTED;
}
- private static Phone.DataState getMobileDataState(Intent intent) {
+ private Phone.DataState getMobileDataState(Intent intent) {
String str = intent.getStringExtra(Phone.STATE_KEY);
- if (str != null)
- return Enum.valueOf(Phone.DataState.class, str);
- else
- return Phone.DataState.DISCONNECTED;
+ if (str != null) {
+ String apnTypeList =
+ intent.getStringExtra(Phone.DATA_APN_TYPES_KEY);
+ if (isApnTypeIncluded(apnTypeList)) {
+ return Enum.valueOf(Phone.DataState.class, str);
+ }
+ }
+ return Phone.DataState.DISCONNECTED;
+ }
+
+ private boolean isApnTypeIncluded(String typeList) {
+ /* comma seperated list - split and check */
+ if (typeList == null)
+ return false;
+
+ String[] list = typeList.split(",");
+ for(int i=0; i< list.length; i++) {
+ if (TextUtils.equals(list[i], mApnType) ||
+ TextUtils.equals(list[i], Phone.APN_TYPE_ALL)) {
+ return true;
+ }
+ }
+ return false;
}
private class MobileDataStateReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equals(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) {
+ if (intent.getAction().equals(TelephonyIntents.
+ ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) {
Phone.DataState state = getMobileDataState(intent);
- String reason = intent.getStringExtra(Phone.STATE_CHANGE_REASON_KEY);
+ String reason =
+ intent.getStringExtra(Phone.STATE_CHANGE_REASON_KEY);
String apnName = intent.getStringExtra(Phone.DATA_APN_KEY);
- boolean unavailable = intent.getBooleanExtra(Phone.NETWORK_UNAVAILABLE_KEY, false);
- if (DBG) Log.d(TAG, "Received " + intent.getAction() +
- " broadcast - state = " + state
- + ", unavailable = " + unavailable
- + ", reason = " + (reason == null ? "(unspecified)" : reason));
+
+ String apnTypeList =
+ intent.getStringExtra(Phone.DATA_APN_TYPES_KEY);
+
+ boolean unavailable = intent.getBooleanExtra(
+ Phone.NETWORK_UNAVAILABLE_KEY, false);
+ if (DBG) Log.d(TAG, mApnType + " Received "
+ + intent.getAction() + " broadcast - state = "
+ + state + ", unavailable = " + unavailable
+ + ", reason = "
+ + (reason == null ? "(unspecified)" : reason));
+
+ if ((!isApnTypeIncluded(apnTypeList)) || mEnabled == false) {
+ if (DBG) Log.e(TAG, " dropped - mEnabled = "+mEnabled);
+ return;
+ }
+
+
mNetworkInfo.setIsAvailable(!unavailable);
if (mMobileDataState != state) {
mMobileDataState = state;
switch (state) {
case DISCONNECTED:
+ if(mTeardownRequested) {
+ mEnabled = false;
+ mTeardownRequested = false;
+ }
+
setDetailedState(DetailedState.DISCONNECTED, reason, apnName);
if (mInterfaceName != null) {
NetworkUtils.resetConnections(mInterfaceName);
@@ -136,12 +183,12 @@ public class MobileDataStateTracker extends NetworkStateTracker {
if (mInterfaceName == null) {
Log.d(TAG, "CONNECTED event did not supply interface name.");
}
- setupDnsProperties();
setDetailedState(DetailedState.CONNECTED, reason, apnName);
break;
}
}
} else if (intent.getAction().equals(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED)) {
+ mEnabled = false;
String reason = intent.getStringExtra(Phone.FAILURE_REASON_KEY);
String apnName = intent.getStringExtra(Phone.DATA_APN_KEY);
if (DBG) Log.d(TAG, "Received " + intent.getAction() + " broadcast" +
@@ -154,40 +201,6 @@ public class MobileDataStateTracker extends NetworkStateTracker {
}
}
- /**
- * Make sure that route(s) exist to the carrier DNS server(s).
- */
- public void addPrivateRoutes() {
- if (mInterfaceName != null) {
- for (String addrString : mDnsServers) {
- int addr = NetworkUtils.lookupHost(addrString);
- if (addr != -1) {
- NetworkUtils.addHostRoute(mInterfaceName, addr);
- }
- }
- }
- }
-
- public void removePrivateRoutes() {
- if(mInterfaceName != null) {
- NetworkUtils.removeHostRoutes(mInterfaceName);
- }
- }
-
- public void removeDefaultRoute() {
- if(mInterfaceName != null) {
- mDefaultGatewayAddr = NetworkUtils.getDefaultRoute(mInterfaceName);
- NetworkUtils.removeDefaultRoute(mInterfaceName);
- }
- }
-
- public void restoreDefaultRoute() {
- // 0 is not a valid address for a gateway
- if (mInterfaceName != null && mDefaultGatewayAddr != 0) {
- NetworkUtils.setDefaultRoute(mInterfaceName, mDefaultGatewayAddr);
- }
- }
-
private void getPhoneService(boolean forceRefresh) {
if ((mPhoneService == null) || forceRefresh) {
mPhoneService = ITelephony.Stub.asInterface(ServiceManager.getService("phone"));
@@ -219,15 +232,6 @@ public class MobileDataStateTracker extends NetworkStateTracker {
}
/**
- * Return the IP addresses of the DNS servers available for the mobile data
- * network interface.
- * @return a list of DNS addresses, with no holes.
- */
- public String[] getNameServers() {
- return getNameServerList(sDnsPropNames);
- }
-
- /**
* {@inheritDoc}
* The mobile data network subtype indicates what generation network technology is in effect,
* e.g., GPRS, EDGE, UMTS, etc.
@@ -273,54 +277,19 @@ public class MobileDataStateTracker extends NetworkStateTracker {
*/
@Override
public boolean teardown() {
- getPhoneService(false);
- /*
- * If the phone process has crashed in the past, we'll get a
- * RemoteException and need to re-reference the service.
- */
- for (int retry = 0; retry < 2; retry++) {
- if (mPhoneService == null) {
- Log.w(TAG,
- "Ignoring mobile data teardown request because could not acquire PhoneService");
- break;
- }
-
- try {
- return mPhoneService.disableDataConnectivity();
- } catch (RemoteException e) {
- if (retry == 0) getPhoneService(true);
- }
- }
-
- Log.w(TAG, "Failed to tear down mobile data connectivity");
- return false;
+ mTeardownRequested = true;
+ return (setEnableApn(mApnType, false) != Phone.APN_REQUEST_FAILED);
}
/**
* Re-enable mobile data connectivity after a {@link #teardown()}.
*/
public boolean reconnect() {
- getPhoneService(false);
- /*
- * If the phone process has crashed in the past, we'll get a
- * RemoteException and need to re-reference the service.
- */
- for (int retry = 0; retry < 2; retry++) {
- if (mPhoneService == null) {
- Log.w(TAG,
- "Ignoring mobile data connect request because could not acquire PhoneService");
- break;
- }
-
- try {
- return mPhoneService.enableDataConnectivity();
- } catch (RemoteException e) {
- if (retry == 0) getPhoneService(true);
- }
- }
-
- Log.w(TAG, "Failed to set up mobile data connectivity");
- return false;
+ mEnabled = true;
+ mTeardownRequested = false;
+ mEnabled = (setEnableApn(mApnType, true) !=
+ Phone.APN_REQUEST_FAILED);
+ return mEnabled;
}
/**
@@ -374,14 +343,7 @@ public class MobileDataStateTracker extends NetworkStateTracker {
* </ul>
*/
public int startUsingNetworkFeature(String feature, int callingPid, int callingUid) {
- if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_MMS)) {
- mLastCallingPid = callingPid;
- return setEnableApn(Phone.APN_TYPE_MMS, true);
- } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_SUPL)) {
- return setEnableApn(Phone.APN_TYPE_SUPL, true);
- } else {
- return -1;
- }
+ return -1;
}
/**
@@ -397,13 +359,7 @@ public class MobileDataStateTracker extends NetworkStateTracker {
* the value {@code -1} always indicates failure.
*/
public int stopUsingNetworkFeature(String feature, int callingPid, int callingUid) {
- if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_MMS)) {
- return setEnableApn(Phone.APN_TYPE_MMS, false);
- } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_SUPL)) {
- return setEnableApn(Phone.APN_TYPE_SUPL, false);
- } else {
- return -1;
- }
+ return -1;
}
/**
@@ -433,43 +389,6 @@ public class MobileDataStateTracker extends NetworkStateTracker {
return sb.toString();
}
- private void setupDnsProperties() {
- mDnsServers.clear();
- // Set up per-process DNS server list on behalf of the MMS process
- int i = 1;
- if (mInterfaceName != null) {
- for (String propName : sDnsPropNames) {
- if (propName.indexOf(mInterfaceName) != -1) {
- String propVal = SystemProperties.get(propName);
- if (propVal != null && propVal.length() != 0 && !propVal.equals("0.0.0.0")) {
- mDnsServers.add(propVal);
- if (mLastCallingPid != -1) {
- SystemProperties.set("net.dns" + i + "." + mLastCallingPid, propVal);
- }
- ++i;
- }
- }
- }
- }
- if (i == 1) {
- Log.d(TAG, "DNS server addresses are not known.");
- } else if (mLastCallingPid != -1) {
- /*
- * Bump the property that tells the name resolver library
- * to reread the DNS server list from the properties.
- */
- String propVal = SystemProperties.get("net.dnschange");
- if (propVal.length() != 0) {
- try {
- int n = Integer.parseInt(propVal);
- SystemProperties.set("net.dnschange", "" + (n+1));
- } catch (NumberFormatException e) {
- }
- }
- }
- mLastCallingPid = -1;
- }
-
/**
* Internal method supporting the ENABLE_MMS feature.
* @param apnType the type of APN to be enabled or disabled (e.g., mms)
diff --git a/core/java/android/net/NetworkStateTracker.java b/core/java/android/net/NetworkStateTracker.java
index 37087ac..418f511 100644
--- a/core/java/android/net/NetworkStateTracker.java
+++ b/core/java/android/net/NetworkStateTracker.java
@@ -27,6 +27,7 @@ import android.text.TextUtils;
import android.util.Config;
import android.util.Log;
+
/**
* Each subclass of this class keeps track of the state of connectivity
* of a network interface. All state information for a network should
@@ -40,11 +41,16 @@ public abstract class NetworkStateTracker extends Handler {
protected NetworkInfo mNetworkInfo;
protected Context mContext;
protected Handler mTarget;
+ protected String mInterfaceName;
+ protected String[] mDnsPropNames;
+ private boolean mPrivateDnsRouteSet;
+ protected int mDefaultGatewayAddr;
+ private boolean mDefaultRouteSet;
private boolean mTeardownRequested;
- private static boolean DBG = Config.LOGV;
+ private static boolean DBG = Config.LOGV;
private static final String TAG = "NetworkStateTracker";
-
+
public static final int EVENT_STATE_CHANGED = 1;
public static final int EVENT_SCAN_RESULTS_AVAILABLE = 2;
/**
@@ -56,6 +62,7 @@ public abstract class NetworkStateTracker extends Handler {
public static final int EVENT_CONFIGURATION_CHANGED = 4;
public static final int EVENT_ROAMING_CHANGED = 5;
public static final int EVENT_NETWORK_SUBTYPE_CHANGED = 6;
+ public static final int EVENT_RESTORE_DEFAULT_NETWORK = 7;
public NetworkStateTracker(Context context,
Handler target,
@@ -67,6 +74,7 @@ public abstract class NetworkStateTracker extends Handler {
mContext = context;
mTarget = target;
mTeardownRequested = false;
+
this.mNetworkInfo = new NetworkInfo(networkType, subType, typeName, subtypeName);
}
@@ -75,19 +83,21 @@ public abstract class NetworkStateTracker extends Handler {
}
/**
- * Return the list of DNS servers associated with this network.
- * @return a list of the IP addresses of the DNS servers available
- * for the network.
- */
- public abstract String[] getNameServers();
-
- /**
* Return the system properties name associated with the tcp buffer sizes
* for this network.
*/
public abstract String getTcpBufferSizesPropName();
/**
+ * Return the IP addresses of the DNS servers available for the mobile data
+ * network interface.
+ * @return a list of DNS addresses, with no holes.
+ */
+ public String[] getNameServers() {
+ return getNameServerList(mDnsPropNames);
+ }
+
+ /**
* Return the IP addresses of the DNS servers available for this
* network interface.
* @param propertyNames the names of the system properties whose values
@@ -112,6 +122,50 @@ public abstract class NetworkStateTracker extends Handler {
return dnsAddresses;
}
+ public void addPrivateDnsRoutes() {
+ if (DBG) Log.d(TAG, "addPrivateDnsRoutes for " + this +
+ "(" + mInterfaceName + ")");
+ if (mInterfaceName != null && !mPrivateDnsRouteSet) {
+ for (String addrString : getNameServers()) {
+ int addr = NetworkUtils.lookupHost(addrString);
+ if (addr != -1) {
+ NetworkUtils.addHostRoute(mInterfaceName, addr);
+ }
+ }
+ mPrivateDnsRouteSet = true;
+ }
+ }
+
+ public void removePrivateDnsRoutes() {
+ if (DBG) Log.d(TAG, "removePrivateDnsRoutes for " + this +
+ "(" + mInterfaceName + ")");
+ // TODO - we should do this explicitly but the NetUtils api doesnt
+ // support this yet - must remove all. No worse than before
+ if (mInterfaceName != null && mPrivateDnsRouteSet) {
+ NetworkUtils.removeHostRoutes(mInterfaceName);
+ mPrivateDnsRouteSet = false;
+ }
+ }
+
+ public void addDefaultRoute() {
+ if (DBG) Log.d(TAG, "addDefaultRoute for " + this + "(" +
+ mInterfaceName + "), GatewayAddr=" + mDefaultGatewayAddr);
+ if ((mInterfaceName != null) && (mDefaultGatewayAddr != 0) &&
+ mDefaultRouteSet == false) {
+ NetworkUtils.setDefaultRoute(mInterfaceName, mDefaultGatewayAddr);
+ mDefaultRouteSet = true;
+ }
+ }
+
+ public void removeDefaultRoute() {
+ if (DBG) Log.d(TAG, "removeDefaultRoute for " + this + "(" +
+ mInterfaceName + ")");
+ if (mInterfaceName != null && mDefaultRouteSet == true) {
+ NetworkUtils.removeDefaultRoute(mInterfaceName);
+ mDefaultRouteSet = false;
+ }
+ }
+
/**
* Reads the network specific TCP buffer sizes from SystemProperties
* net.tcp.buffersize.[default|wifi|umts|edge|gprs] and set them for system
@@ -209,6 +263,7 @@ public abstract class NetworkStateTracker extends Handler {
* @param extraInfo optional {@code String} providing extra information about the state change
*/
public void setDetailedState(NetworkInfo.DetailedState state, String reason, String extraInfo) {
+ if (DBG) Log.d(TAG, "setDetailed state, old ="+mNetworkInfo.getDetailedState()+" and new state="+state);
if (state != mNetworkInfo.getDetailedState()) {
boolean wasConnecting = (mNetworkInfo.getState() == NetworkInfo.State.CONNECTING);
String lastReason = mNetworkInfo.getReason();