Fix ConnectivityManager's handling of apn switch.
It was clearing the interfacename when it was needed later in the process - the prevented us
from clearing the route to private dns servers and clearing the flag that this was set.
Consequently future uses would not set the private dns servers (since it thought they were already
set) and our lookups would fail.
bug: 2146929
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index d8db4c1..709766b 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -157,7 +157,8 @@
// if we're not enabled but the APN Type is supported by this connection
// we should record the interface name if one's provided. If the user
// turns on this network we will need the interfacename but won't get
- // a fresh connected message - TODO fix this..
+ // a fresh connected message - TODO fix this when we get per-APN
+ // notifications
if (state == Phone.DataState.CONNECTED) {
if (DBG) Log.d(TAG, "replacing old mInterfaceName (" +
mInterfaceName + ") with " +
@@ -186,10 +187,13 @@
if (mInterfaceName != null) {
NetworkUtils.resetConnections(mInterfaceName);
}
- if (DBG) Log.d(TAG, "clearing mInterfaceName for "+ mApnType +
- " as it DISCONNECTED");
- mInterfaceName = null;
- mDefaultGatewayAddr = 0;
+ // can't do this here - ConnectivityService needs it to clear stuff
+ // it's ok though - just leave it to be refreshed next time
+ // we connect.
+ //if (DBG) Log.d(TAG, "clearing mInterfaceName for "+ mApnType +
+ // " as it DISCONNECTED");
+ //mInterfaceName = null;
+ //mDefaultGatewayAddr = 0;
break;
case CONNECTING:
setDetailedState(DetailedState.CONNECTING, reason, apnName);
@@ -310,6 +314,11 @@
*/
@Override
public boolean teardown() {
+ // since we won't get a notification currently (TODO - per APN notifications)
+ // we won't get a disconnect message until all APN's on the current connection's
+ // APN list are disabled. That means privateRoutes for DNS and such will remain on -
+ // not a problem since that's all shared with whatever other APN is still on, but
+ // ugly.
setTeardownRequested(true);
return (setEnableApn(mApnType, false) != Phone.APN_REQUEST_FAILED);
}
@@ -321,6 +330,7 @@
setTeardownRequested(false);
switch (setEnableApn(mApnType, true)) {
case Phone.APN_ALREADY_ACTIVE:
+ // TODO - remove this when we get per-apn notifications
mEnabled = true;
// need to set self to CONNECTING so the below message is handled.
mMobileDataState = Phone.DataState.CONNECTING;
diff --git a/core/java/android/net/NetworkStateTracker.java b/core/java/android/net/NetworkStateTracker.java
index 54529ae..d3e4ea5 100644
--- a/core/java/android/net/NetworkStateTracker.java
+++ b/core/java/android/net/NetworkStateTracker.java
@@ -124,11 +124,12 @@
public void addPrivateDnsRoutes() {
if (DBG) Log.d(TAG, "addPrivateDnsRoutes for " + this +
- "(" + mInterfaceName + ")");
+ "(" + mInterfaceName + ") - mPrivateDnsRouteSet = "+mPrivateDnsRouteSet);
if (mInterfaceName != null && !mPrivateDnsRouteSet) {
for (String addrString : getNameServers()) {
int addr = NetworkUtils.lookupHost(addrString);
- if (addr != -1) {
+ if (addr != -1 && addr != 0) {
+ if (DBG) Log.d(TAG, " adding "+addrString+" ("+addr+")");
NetworkUtils.addHostRoute(mInterfaceName, addr);
}
}
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index 5581a24..1f0e5a5 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -425,26 +425,28 @@
* will be sent by the ConnectivityManager when a connection to
* the APN has been established.
*/
- public int enableApnType(String type) {
+ public synchronized int enableApnType(String type) {
int id = apnTypeToId(type);
if (id == APN_INVALID_ID) {
return Phone.APN_REQUEST_FAILED;
}
- // If already active, return
if(DBG) Log.d(LOG_TAG, "enableApnType("+type+"), isApnTypeActive = "
+ isApnTypeActive(type) + " and state = " + state);
- if (isApnTypeActive(type)) {
- if (state == State.INITING) return Phone.APN_REQUEST_STARTED;
- else if (state == State.CONNECTED) return Phone.APN_ALREADY_ACTIVE;
- }
-
if (!isApnTypeAvailable(type)) {
return Phone.APN_TYPE_NOT_AVAILABLE;
}
+ // just because it's active doesn't mean we had it explicitly requested before
+ // (a broad default may handle many types). make sure we mark it enabled
+ // so if the default is disabled we keep the connection for others
setEnabled(id, true);
+
+ if (isApnTypeActive(type)) {
+ if (state == State.INITING) return Phone.APN_REQUEST_STARTED;
+ else if (state == State.CONNECTED) return Phone.APN_ALREADY_ACTIVE;
+ }
return Phone.APN_REQUEST_STARTED;
}
@@ -490,20 +492,21 @@
protected synchronized void onEnableApn(int apnId, int enabled) {
if (DBG) {
- Log.d(LOG_TAG, "got EVENT_APN_ENABLE_REQUEST with apnType = " + apnId +
- " and enable = " + enabled);
- Log.d(LOG_TAG, "dataEnabled[apnId] = " + dataEnabled[apnId] +
- ", enabledCount = " + enabledCount);
+ Log.d(LOG_TAG, "EVENT_APN_ENABLE_REQUEST " + apnId + ", " + enabled);
+ Log.d(LOG_TAG, " dataEnabled = " + dataEnabled[apnId] +
+ ", enabledCount = " + enabledCount +
+ ", isApnTypeActive = " + isApnTypeActive(apnIdToType(apnId)));
}
if (enabled == APN_ENABLED) {
if (!dataEnabled[apnId]) {
- mRequestedApnType = apnIdToType(apnId);
- onEnableNewApn();
-
dataEnabled[apnId] = true;
enabledCount++;
}
- onTrySetupData(null);
+ String type = apnIdToType(apnId);
+ if (!isApnTypeActive(type)) {
+ mRequestedApnType = type;
+ onEnableNewApn();
+ }
} else {
// disable
if (dataEnabled[apnId]) {
@@ -511,7 +514,8 @@
enabledCount--;
if (enabledCount == 0) {
onCleanUpConnection(true, Phone.REASON_DATA_DISABLED);
- } else if (dataEnabled[APN_DEFAULT_ID] == true) {
+ } else if (dataEnabled[APN_DEFAULT_ID] == true &&
+ !isApnTypeActive(Phone.APN_TYPE_DEFAULT)) {
mRequestedApnType = Phone.APN_TYPE_DEFAULT;
onEnableNewApn();
}