diff options
author | Robert Greenwalt <rgreenwalt@google.com> | 2012-02-13 11:39:04 -0800 |
---|---|---|
committer | Robert Greenwalt <rgreenwalt@google.com> | 2012-02-14 11:44:09 -0800 |
commit | 2384386f3132839bec0cf460a3f19d068ad28507 (patch) | |
tree | c2a9ee697b4342f8bacd6dd32dd1b323261f1fe7 | |
parent | ffc89899652f5c815b6d156f55a909001420891e (diff) | |
download | frameworks_base-2384386f3132839bec0cf460a3f19d068ad28507.zip frameworks_base-2384386f3132839bec0cf460a3f19d068ad28507.tar.gz frameworks_base-2384386f3132839bec0cf460a3f19d068ad28507.tar.bz2 |
Stop using shared DUN APN when tethering stops.
Backported from master, including a bug fix and a cdma enhancement.
Even if other people are sharing the connection (ie, carrier wants
default and tethered traffic on the same APN) stop using a carrier-
described APN when the tethering stops.
bug:5972599
Change-Id: I25e4831855e6b62c0c3ab3a6f4d4846aaee6ac50
7 files changed, 146 insertions, 39 deletions
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index 97fb0b0..b7dc4a2 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -1031,9 +1031,14 @@ private NetworkStateTracker makeWimaxStateTracker() { if ((ni.isConnectedOrConnecting() == true) && !network.isTeardownRequested()) { if (ni.isConnected() == true) { - // add the pid-specific dns - handleDnsConfigurationChange(usedNetworkType); - if (VDBG) log("special network already active"); + final long token = Binder.clearCallingIdentity(); + try { + // add the pid-specific dns + handleDnsConfigurationChange(usedNetworkType); + if (VDBG) log("special network already active"); + } finally { + Binder.restoreCallingIdentity(token); + } return Phone.APN_ALREADY_ACTIVE; } if (VDBG) log("special network already connecting"); @@ -1221,6 +1226,7 @@ private NetworkStateTracker makeWimaxStateTracker() { } if (!ConnectivityManager.isNetworkTypeValid(networkType)) { + if (DBG) log("requestRouteToHostAddress on invalid network: " + networkType); return false; } NetworkStateTracker tracker = mNetTrackers[networkType]; @@ -1233,11 +1239,16 @@ private NetworkStateTracker makeWimaxStateTracker() { } return false; } + final long token = Binder.clearCallingIdentity(); try { InetAddress addr = InetAddress.getByAddress(hostAddress); LinkProperties lp = tracker.getLinkProperties(); return addRouteToAddress(lp, addr); - } catch (UnknownHostException e) {} + } catch (UnknownHostException e) { + if (DBG) log("requestRouteToHostAddress got " + e.toString()); + } finally { + Binder.restoreCallingIdentity(token); + } return false; } @@ -1277,7 +1288,10 @@ private NetworkStateTracker makeWimaxStateTracker() { private boolean modifyRoute(String ifaceName, LinkProperties lp, RouteInfo r, int cycleCount, boolean doAdd, boolean toDefaultTable) { - if ((ifaceName == null) || (lp == null) || (r == null)) return false; + if ((ifaceName == null) || (lp == null) || (r == null)) { + if (DBG) log("modifyRoute got unexpected null: " + ifaceName + ", " + lp + ", " + r); + return false; + } if (cycleCount > MAX_HOSTROUTE_CYCLE_COUNT) { loge("Error modifying route - too much recursion"); @@ -1309,7 +1323,7 @@ private NetworkStateTracker makeWimaxStateTracker() { } } catch (Exception e) { // never crash - catch them all - if (VDBG) loge("Exception trying to add a route: " + e); + if (DBG) loge("Exception trying to add a route: " + e); return false; } } else { @@ -1323,7 +1337,7 @@ private NetworkStateTracker makeWimaxStateTracker() { mNetd.removeRoute(ifaceName, r); } catch (Exception e) { // never crash - catch them all - if (VDBG) loge("Exception trying to remove a route: " + e); + if (DBG) loge("Exception trying to remove a route: " + e); return false; } } else { @@ -1335,7 +1349,7 @@ private NetworkStateTracker makeWimaxStateTracker() { mNetd.removeSecondaryRoute(ifaceName, r); } catch (Exception e) { // never crash - catch them all - if (VDBG) loge("Exception trying to remove a route: " + e); + if (DBG) loge("Exception trying to remove a route: " + e); return false; } } @@ -2004,7 +2018,7 @@ private NetworkStateTracker makeWimaxStateTracker() { mNetd.removeRoute(ifaceName, r); } catch (Exception e) { // never crash - catch them all - if (VDBG) loge("Exception trying to remove a route: " + e); + if (DBG) loge("Exception trying to remove a route: " + e); } } } @@ -2218,7 +2232,7 @@ private NetworkStateTracker makeWimaxStateTracker() { mNetd.setDnsServersForInterface(iface, NetworkUtils.makeStrings(dnses)); mNetd.setDefaultInterfaceForDns(iface); } catch (Exception e) { - if (VDBG) loge("exception setting default dns interface: " + e); + if (DBG) loge("exception setting default dns interface: " + e); } } if (!domains.equals(SystemProperties.get("net.dns.search"))) { @@ -2248,7 +2262,7 @@ private NetworkStateTracker makeWimaxStateTracker() { mNetd.setDnsServersForInterface(p.getInterfaceName(), NetworkUtils.makeStrings(dnses)); } catch (Exception e) { - if (VDBG) loge("exception setting dns servers: " + e); + if (DBG) loge("exception setting dns servers: " + e); } // set per-pid dns for attached secondary nets List pids = mNetRequestersPids[netType]; diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java index ffe848d..d0e304f 100644 --- a/telephony/java/com/android/internal/telephony/DataConnection.java +++ b/telephony/java/com/android/internal/telephony/DataConnection.java @@ -68,6 +68,8 @@ public abstract class DataConnection extends StateMachine { private List<ApnContext> mApnList = null; PendingIntent mReconnectIntent = null; + private DataConnectionTracker mDataConnectionTracker = null; + /** * Used internally for saving connecting parameters. */ @@ -202,6 +204,7 @@ public abstract class DataConnection extends StateMachine { protected static final int EVENT_DEACTIVATE_DONE = BASE + 3; protected static final int EVENT_DISCONNECT = BASE + 4; protected static final int EVENT_RIL_CONNECTED = BASE + 5; + protected static final int EVENT_DISCONNECT_ALL = BASE + 6; //***** Tag IDs for EventLog protected static final int EVENT_LOG_BAD_DNS_ADDRESS = 50100; @@ -234,10 +237,12 @@ public abstract class DataConnection extends StateMachine { //***** Constructor - protected DataConnection(PhoneBase phone, String name, int id, RetryManager rm) { + protected DataConnection(PhoneBase phone, String name, int id, RetryManager rm, + DataConnectionTracker dct) { super(name); if (DBG) log("DataConnection constructor E"); this.phone = phone; + this.mDataConnectionTracker = dct; mId = id; mRetryMgr = rm; this.cid = -1; @@ -316,11 +321,19 @@ public abstract class DataConnection extends StateMachine { * * @param dp is the DisconnectParams. */ - private void notifyDisconnectCompleted(DisconnectParams dp) { + private void notifyDisconnectCompleted(DisconnectParams dp, boolean sendAll) { if (VDBG) log("NotifyDisconnectCompleted"); + ApnContext alreadySent = null; + String reason = null; + if (dp.onCompletedMsg != null) { + // Get ApnContext, but only valid on GSM devices this is a string on CDMA devices. Message msg = dp.onCompletedMsg; + if (msg.obj instanceof ApnContext) { + alreadySent = (ApnContext)msg.obj; + } + reason = dp.reason; if (VDBG) { log(String.format("msg=%s msg.obj=%s", msg.toString(), ((msg.obj instanceof String) ? (String) msg.obj : "<no-reason>"))); @@ -328,6 +341,17 @@ public abstract class DataConnection extends StateMachine { AsyncResult.forMessage(msg); msg.sendToTarget(); } + if (sendAll) { + for (ApnContext a : mApnList) { + if (a == alreadySent) continue; + if (reason != null) a.setReason(reason); + Message msg = mDataConnectionTracker.obtainMessage( + DataConnectionTracker.EVENT_DISCONNECT_DONE, a); + AsyncResult.forMessage(msg); + msg.sendToTarget(); + } + } + if (DBG) log("NotifyDisconnectCompleted DisconnectParams=" + dp); } @@ -706,6 +730,13 @@ public abstract class DataConnection extends StateMachine { deferMessage(msg); break; + case EVENT_DISCONNECT_ALL: + if (DBG) { + log("DcDefaultState deferring msg.what=EVENT_DISCONNECT_ALL" + mRefCount); + } + deferMessage(msg); + break; + case EVENT_RIL_CONNECTED: ar = (AsyncResult)msg.obj; if (ar.exception == null) { @@ -771,7 +802,7 @@ public abstract class DataConnection extends StateMachine { } if (mDisconnectParams != null) { if (VDBG) log("DcInactiveState: enter notifyDisconnectCompleted"); - notifyDisconnectCompleted(mDisconnectParams); + notifyDisconnectCompleted(mDisconnectParams, true); } clearSettings(); } @@ -812,7 +843,13 @@ public abstract class DataConnection extends StateMachine { case EVENT_DISCONNECT: if (DBG) log("DcInactiveState: msg.what=EVENT_DISCONNECT"); - notifyDisconnectCompleted((DisconnectParams)msg.obj); + notifyDisconnectCompleted((DisconnectParams)msg.obj, false); + retVal = HANDLED; + break; + + case EVENT_DISCONNECT_ALL: + if (DBG) log("DcInactiveState: msg.what=EVENT_DISCONNECT_ALL"); + notifyDisconnectCompleted((DisconnectParams)msg.obj, false); retVal = HANDLED; break; @@ -989,12 +1026,24 @@ public abstract class DataConnection extends StateMachine { transitionTo(mDisconnectingState); } else { if (msg.obj != null) { - notifyDisconnectCompleted((DisconnectParams) msg.obj); + notifyDisconnectCompleted((DisconnectParams) msg.obj, false); } } retVal = HANDLED; break; + case EVENT_DISCONNECT_ALL: + if (DBG) { + log("DcActiveState msg.what=EVENT_DISCONNECT_ALL RefCount=" + mRefCount); + } + mRefCount = 0; + DisconnectParams dp = (DisconnectParams) msg.obj; + dp.tag = mTag; + tearDownData(dp); + transitionTo(mDisconnectingState); + retVal = HANDLED; + break; + default: if (VDBG) { log("DcActiveState not handled msg.what=0x" + @@ -1124,4 +1173,16 @@ public abstract class DataConnection extends StateMachine { public void tearDown(String reason, Message onCompletedMsg) { sendMessage(obtainMessage(EVENT_DISCONNECT, new DisconnectParams(reason, onCompletedMsg))); } + + /** + * Tear down the connection through the apn on the network. Ignores refcount and + * and always tears down. + * + * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object. + * With AsyncResult.userObj set to the original msg.obj. + */ + public void tearDownAll(String reason, Message onCompletedMsg) { + sendMessage(obtainMessage(EVENT_DISCONNECT_ALL, + new DisconnectParams(reason, onCompletedMsg))); + } } diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java index 04ba42d..863235b 100644 --- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java @@ -1030,7 +1030,8 @@ public abstract class DataConnectionTracker extends Handler { } } if (didDisable) { - if (enabledCount == 0) { + if ((enabledCount == 0) || (apnId == APN_DUN_ID)) { + mRequestedApnType = Phone.APN_TYPE_DEFAULT; onCleanUpConnection(true, apnId, Phone.REASON_DATA_DISABLED); } diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java index d55f346..a93d94f 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java @@ -20,6 +20,7 @@ import android.os.Message; import android.util.Log; import com.android.internal.telephony.DataConnection; +import com.android.internal.telephony.DataConnectionTracker; import com.android.internal.telephony.Phone; import com.android.internal.telephony.RILConstants; import com.android.internal.telephony.RetryManager; @@ -32,8 +33,9 @@ public class CdmaDataConnection extends DataConnection { private static final String LOG_TAG = "CDMA"; // ***** Constructor - private CdmaDataConnection(CDMAPhone phone, String name, int id, RetryManager rm) { - super(phone, name, id, rm); + private CdmaDataConnection(CDMAPhone phone, String name, int id, RetryManager rm, + DataConnectionTracker dct) { + super(phone, name, id, rm, dct); } /** @@ -44,12 +46,13 @@ public class CdmaDataConnection extends DataConnection { * @param rm the RetryManager * @return CdmaDataConnection that was created. */ - static CdmaDataConnection makeDataConnection(CDMAPhone phone, int id, RetryManager rm) { + static CdmaDataConnection makeDataConnection(CDMAPhone phone, int id, RetryManager rm, + DataConnectionTracker dct) { synchronized (mCountLock) { mCount += 1; } CdmaDataConnection cdmaDc = new CdmaDataConnection(phone, "CdmaDC-" + mCount, - id, rm); + id, rm, dct); cdmaDc.start(); if (DBG) cdmaDc.log("Made " + cdmaDc.getName()); return cdmaDc; diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java index e2a4a7a..72ca3b5 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java @@ -122,7 +122,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { @Override public void dispose() { - cleanUpConnection(false, null); + cleanUpConnection(false, null, false); super.dispose(); @@ -277,7 +277,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { * @param tearDown true if the underlying DataConnection should be disconnected. * @param reason for the clean up. */ - private void cleanUpConnection(boolean tearDown, String reason) { + private void cleanUpConnection(boolean tearDown, String reason, boolean doAll) { if (DBG) log("cleanUpConnection: reason: " + reason); // Clear the reconnect alarm, if set. @@ -297,9 +297,15 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { DataConnectionAc dcac = mDataConnectionAsyncChannels.get(conn.getDataConnectionId()); if (tearDown) { - if (DBG) log("cleanUpConnection: teardown, call conn.disconnect"); - conn.tearDown(reason, obtainMessage(EVENT_DISCONNECT_DONE, - conn.getDataConnectionId(), 0, reason)); + if (doAll) { + if (DBG) log("cleanUpConnection: teardown, conn.tearDownAll"); + conn.tearDownAll(reason, obtainMessage(EVENT_DISCONNECT_DONE, + conn.getDataConnectionId(), 0, reason)); + } else { + if (DBG) log("cleanUpConnection: teardown, conn.tearDown"); + conn.tearDown(reason, obtainMessage(EVENT_DISCONNECT_DONE, + conn.getDataConnectionId(), 0, reason)); + } notificationDeferred = true; } else { if (DBG) log("cleanUpConnection: !tearDown, call conn.resetSynchronously"); @@ -582,7 +588,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { @Override protected void onEnableNewApn() { // No mRequestedApnType check; only one connection is supported - cleanUpConnection(true, Phone.REASON_APN_SWITCHED); + cleanUpConnection(true, Phone.REASON_APN_SWITCHED, false); } /** @@ -764,13 +770,13 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { @Override protected void onCleanUpConnection(boolean tearDown, int apnId, String reason) { // No apnId check; only one connection is supported - cleanUpConnection(tearDown, reason); + cleanUpConnection(tearDown, reason, (apnId == APN_DUN_ID)); } @Override protected void onCleanUpAllConnections(String cause) { // Only one CDMA connection is supported - cleanUpConnection(true, cause); + cleanUpConnection(true, cause, false); } private void createAllDataConnectionList() { @@ -789,7 +795,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { } int id = mUniqueIdGenerator.getAndIncrement(); - dataConn = CdmaDataConnection.makeDataConnection(mCdmaPhone, id, rm); + dataConn = CdmaDataConnection.makeDataConnection(mCdmaPhone, id, rm, this); mDataConnections.put(id, dataConn); DataConnectionAc dcac = new DataConnectionAc(dataConn, LOG_TAG); int status = dcac.fullyConnectSync(mPhone.getContext(), this, dataConn.getHandler()); @@ -816,7 +822,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { notifyDataConnection(Phone.REASON_CDMA_DATA_DETACHED); } else { if (mState == State.FAILED) { - cleanUpConnection(false, Phone.REASON_CDMA_DATA_DETACHED); + cleanUpConnection(false, Phone.REASON_CDMA_DATA_DETACHED, false); mDataConnections.get(0).resetRetryCount(); CdmaCellLocation loc = (CdmaCellLocation)(mPhone.getCellLocation()); @@ -895,7 +901,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { log("onDataStateChanged: No active connection" + "state is CONNECTED, disconnecting/cleanup"); writeEventLogCdmaDataDrop(); - cleanUpConnection(true, null); + cleanUpConnection(true, null, false); return; } diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java index 1f24b58..1f5b7ab 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java @@ -22,6 +22,7 @@ import android.util.Patterns; import android.text.TextUtils; import com.android.internal.telephony.DataConnection; +import com.android.internal.telephony.DataConnectionTracker; import com.android.internal.telephony.Phone; import com.android.internal.telephony.PhoneBase; import com.android.internal.telephony.RILConstants; @@ -38,8 +39,9 @@ public class GsmDataConnection extends DataConnection { protected int mProfileId = RILConstants.DATA_PROFILE_DEFAULT; protected String mActiveApnType = Phone.APN_TYPE_DEFAULT; //***** Constructor - private GsmDataConnection(PhoneBase phone, String name, int id, RetryManager rm) { - super(phone, name, id, rm); + private GsmDataConnection(PhoneBase phone, String name, int id, RetryManager rm, + DataConnectionTracker dct) { + super(phone, name, id, rm, dct); } /** @@ -50,11 +52,12 @@ public class GsmDataConnection extends DataConnection { * @param rm the RetryManager * @return GsmDataConnection that was created. */ - static GsmDataConnection makeDataConnection(PhoneBase phone, int id, RetryManager rm) { + static GsmDataConnection makeDataConnection(PhoneBase phone, int id, RetryManager rm, + DataConnectionTracker dct) { synchronized (mCountLock) { mCount += 1; } - GsmDataConnection gsmDc = new GsmDataConnection(phone, "GsmDC-" + mCount, id, rm); + GsmDataConnection gsmDc = new GsmDataConnection(phone, "GsmDC-" + mCount, id, rm, dct); gsmDc.start(); if (DBG) gsmDc.log("Made " + gsmDc.getName()); return gsmDc; diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java index 9eaf7a0..95ea107 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java @@ -850,9 +850,28 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { // Connection is still there. Try to clean up. if (dcac != null) { if (apnContext.getState() != State.DISCONNECTING) { - if (DBG) log("cleanUpConnection: tearing down"); + boolean disconnectAll = false; + if (Phone.APN_TYPE_DUN.equals(apnContext.getApnType())) { + ApnSetting dunSetting = fetchDunApn(); + if (dunSetting != null && + dunSetting.equals(apnContext.getApnSetting())) { + if (DBG) log("tearing down dedicated DUN connection"); + // we need to tear it down - we brought it up just for dun and + // other people are camped on it and now dun is done. We need + // to stop using it and let the normal apn list get used to find + // connections for the remaining desired connections + disconnectAll = true; + } + } + if (DBG) { + log("cleanUpConnection: tearing down" + (disconnectAll ? " all" :"")); + } Message msg = obtainMessage(EVENT_DISCONNECT_DONE, apnContext); - apnContext.getDataConnection().tearDown(apnContext.getReason(), msg); + if (disconnectAll) { + apnContext.getDataConnection().tearDownAll(apnContext.getReason(), msg); + } else { + apnContext.getDataConnection().tearDown(apnContext.getReason(), msg); + } apnContext.setState(State.DISCONNECTING); } } else { @@ -2213,7 +2232,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { RetryManager rm = new RetryManager(); int id = mUniqueIdGenerator.getAndIncrement(); - GsmDataConnection conn = GsmDataConnection.makeDataConnection(mPhone, id, rm); + GsmDataConnection conn = GsmDataConnection.makeDataConnection(mPhone, id, rm, this); mDataConnections.put(id, conn); DataConnectionAc dcac = new DataConnectionAc(conn, LOG_TAG); int status = dcac.fullyConnectSync(mPhone.getContext(), this, conn.getHandler()); |