Support bearer-specific DUN APN on CDMA
Robert Greenwalt [Mon, 22 Sep 2014 20:55:17 +0000 (13:55 -0700)]
The DUN apn needs to be listed last, and this should only be used on networks
that don't show the apn editor.

bug:17571681
Change-Id: Iefa676d3c741ffb2eef201a8683429ed9dbe44d1

src/java/com/android/internal/telephony/dataconnection/DataConnection.java
src/java/com/android/internal/telephony/dataconnection/DcTracker.java

index e1072b8..50ae740 100644 (file)
@@ -1939,9 +1939,13 @@ public final class DataConnection extends StateMachine {
         }
 
         protected void unwanted() {
+            if (mNetworkAgent != this) {
+                log("unwanted found mNetworkAgent=" + mNetworkAgent +
+                        ", which isn't me.  Aborting unwanted");
+                return;
+            }
             // this can only happen if our exit has been called - we're already disconnected
             if (mApnContexts == null) return;
-
             for (ApnContext apnContext : mApnContexts) {
                 Message msg = mDct.obtainMessage(DctConstants.EVENT_DISCONNECT_DONE, apnContext);
                 DisconnectParams dp = new DisconnectParams(apnContext, apnContext.getReason(), msg);
index 64e813e..21d4b2f 100644 (file)
@@ -966,9 +966,7 @@ public final class DcTracker extends DcTrackerBase {
                         if (PhoneConstants.APN_TYPE_DUN.equals(apnContext.getApnType())) {
                             // CAF_MSIM is this below condition required.
                             // if (PhoneConstants.APN_TYPE_DUN.equals(PhoneConstants.APN_TYPE_DEFAULT)) {
-                            ApnSetting dunSetting = fetchDunApn();
-                            if (dunSetting != null &&
-                                    dunSetting.equals(apnContext.getApnSetting())) {
+                            if (teardownForDun()) {
                                 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
@@ -1018,6 +1016,17 @@ public final class DcTracker extends DcTrackerBase {
     }
 
     /**
+     * Determine if DUN connection is special and we need to teardown on start/stop
+     */
+    private boolean teardownForDun() {
+        // CDMA always needs to do this the profile id is correct
+        final int rilRat = mPhone.getServiceState().getRilDataRadioTechnology();
+        if (ServiceState.isCdma(rilRat)) return true;
+
+        return (fetchDunApn() != null);
+    }
+
+    /**
      * Cancels the alarm associated with apnContext.
      *
      * @param apnContext on which the alarm should be stopped.
@@ -1201,7 +1210,7 @@ public final class DcTracker extends DcTrackerBase {
     private boolean setupData(ApnContext apnContext, int radioTech) {
         if (DBG) log("setupData: apnContext=" + apnContext);
         ApnSetting apnSetting;
-        DcAsyncChannel dcac;
+        DcAsyncChannel dcac = null;
 
         apnSetting = apnContext.getNextWaitingApn();
         if (apnSetting == null) {
@@ -1214,13 +1223,20 @@ public final class DcTracker extends DcTrackerBase {
             profileId = getApnProfileID(apnContext.getApnType());
         }
 
-        dcac = checkForCompatibleConnectedApnContext(apnContext);
-        if (dcac != null) {
-            // Get the dcacApnSetting for the connection we want to share.
-            ApnSetting dcacApnSetting = dcac.getApnSettingSync();
-            if (dcacApnSetting != null) {
-                // Setting is good, so use it.
-                apnSetting = dcacApnSetting;
+        // On CDMA, if we're explicitly asking for DUN, we need have
+        // a dun-profiled connection so we can't share an existing one
+        // On GSM/LTE we can share existing apn connections provided they support
+        // this type.
+        if (apnContext.getApnType() != PhoneConstants.APN_TYPE_DUN ||
+                teardownForDun() == false) {
+            dcac = checkForCompatibleConnectedApnContext(apnContext);
+            if (dcac != null) {
+                // Get the dcacApnSetting for the connection we want to share.
+                ApnSetting dcacApnSetting = dcac.getApnSettingSync();
+                if (dcacApnSetting != null) {
+                    // Setting is good, so use it.
+                    apnSetting = dcacApnSetting;
+                }
             }
         }
         if (dcac == null) {
@@ -1509,7 +1525,17 @@ public final class DcTracker extends DcTrackerBase {
                 // If ConnectivityService has disabled this network, stop trying to bring
                 // it up, but do not tear it down - ConnectivityService will do that
                 // directly by talking with the DataConnection.
-                cleanup = false;
+                //
+                // This doesn't apply to DUN, however.  Those connections have special
+                // requirements from carriers and we need stop using them when the dun
+                // request goes away.  This applies to both CDMA and GSM because they both
+                // can declare the DUN APN sharable by default traffic, thus still satisfying
+                // those requests and not torn down organically.
+                if (apnContext.getApnType() == PhoneConstants.APN_TYPE_DUN && teardownForDun()) {
+                    cleanup = true;
+                } else {
+                    cleanup = false;
+                }
             } else {
                 apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_UNMET);
             }