From d1aca6aa73b0f1e22229829db89b1f3513a16aa8 Mon Sep 17 00:00:00 2001 From: Robert Greenwalt Date: Fri, 25 Sep 2009 14:52:34 -0700 Subject: [PATCH] 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 --- .../android/net/MobileDataStateTracker.java | 20 ++++++++--- .../java/android/net/NetworkStateTracker.java | 5 +-- .../telephony/DataConnectionTracker.java | 36 ++++++++++--------- 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java index d8db4c1f69170..709766b486849 100644 --- a/core/java/android/net/MobileDataStateTracker.java +++ b/core/java/android/net/MobileDataStateTracker.java @@ -157,7 +157,8 @@ public class MobileDataStateTracker extends NetworkStateTracker { // 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 @@ public class MobileDataStateTracker extends NetworkStateTracker { 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 @@ public class MobileDataStateTracker extends NetworkStateTracker { */ @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 @@ public class MobileDataStateTracker extends NetworkStateTracker { 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 54529aee7f36e..d3e4ea5e73136 100644 --- a/core/java/android/net/NetworkStateTracker.java +++ b/core/java/android/net/NetworkStateTracker.java @@ -124,11 +124,12 @@ public abstract class NetworkStateTracker extends Handler { 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 5581a247e5f46..1f0e5a5c91ca7 100644 --- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java @@ -425,26 +425,28 @@ public abstract class DataConnectionTracker extends Handler { * 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 @@ public abstract class DataConnectionTracker extends Handler { 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 @@ public abstract class DataConnectionTracker extends Handler { 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(); }