Merge "docs: move USB installation info into the OEM USB Drivers document because the Google USB Driver is deprecated, so consolidating the USB info makes more sense for the common case of needing an OEM driver A few changes to the device setup doc also; such as removing the "unknown sources" step, because that doesn't apply to adb installs." into ics-mr1
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_wimax_signal_3_fully.png b/core/res/res/drawable-hdpi/stat_sys_data_wimax_signal_3_fully.png
index c2e4b78..f58a19c 100644
--- a/core/res/res/drawable-hdpi/stat_sys_data_wimax_signal_3_fully.png
+++ b/core/res/res/drawable-hdpi/stat_sys_data_wimax_signal_3_fully.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_wimax_signal_disconnected.png b/core/res/res/drawable-hdpi/stat_sys_data_wimax_signal_disconnected.png
index 51b839f..744b1fa 100644
--- a/core/res/res/drawable-hdpi/stat_sys_data_wimax_signal_disconnected.png
+++ b/core/res/res/drawable-hdpi/stat_sys_data_wimax_signal_disconnected.png
Binary files differ
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 5eb09e6..37a8edb 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -227,6 +227,13 @@
         <item>4</item>
     </integer-array>
 
+    <!-- If the DUN connection for this CDMA device supports more than just DUN -->
+    <!-- traffic you should list them here. -->
+    <!-- If this device is not CDMA this is ignored.  If this list is empty on -->
+    <!-- a DUN-requiring CDMA device, the DUN APN will just support just DUN. -->
+    <string-array translatable="false" name="config_cdma_dun_supported_types">
+    </string-array>
+
     <!-- String containing the apn value for tethering.  May be overriden by secure settings
          TETHER_DUN_APN.  Value is a comma separated series of strings:
          "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
diff --git a/docs/html/index.jd b/docs/html/index.jd
index b9d6758..431a7d2 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -154,7 +154,7 @@
 + "href='https://plus.google.com/108967384991768947849'>+Android Developers</a>. "
 + "We'll use it to host Hangouts for developers, talk about the latest releases, "
 + "development and design tips, and much more.</p>"
-+ "<div style='margin:.7em 0 0 -1.2em'><g:plus href='https://plus.google.com/108967384991768947849' "
++ "<div style='margin:.7em 0 0 0'><g:plus href='https://plus.google.com/108967384991768947849' "
 + "size=\"smallbadge\" width=\"275\"></g:plus></div>"
     },
 
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 @@
                 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 @@
         }
 
         if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
+            if (DBG) log("requestRouteToHostAddress on invalid network: " + networkType);
             return false;
         }
         NetworkStateTracker tracker = mNetTrackers[networkType];
@@ -1233,11 +1239,16 @@
             }
             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 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 @@
                 }
             } 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 @@
                         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 @@
                     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 @@
                         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 @@
                 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 @@
                     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 @@
     private List<ApnContext> mApnList = null;
     PendingIntent mReconnectIntent = null;
 
+    private DataConnectionTracker mDataConnectionTracker = null;
+
     /**
      * Used internally for saving connecting parameters.
      */
@@ -202,6 +204,7 @@
     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 @@
 
 
    //***** 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 @@
      *
      * @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 @@
             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 @@
                     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 @@
             }
             if (mDisconnectParams != null) {
                 if (VDBG) log("DcInactiveState: enter notifyDisconnectCompleted");
-                notifyDisconnectCompleted(mDisconnectParams);
+                notifyDisconnectCompleted(mDisconnectParams, true);
             }
             clearSettings();
         }
@@ -812,7 +843,13 @@
 
                 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 @@
                         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 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 @@
                 }
             }
             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.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 @@
     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 @@
      * @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..26a028b 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -93,6 +93,9 @@
             Phone.APN_TYPE_MMS,
             Phone.APN_TYPE_HIPRI };
 
+    private String[] mDunApnTypes = {
+            Phone.APN_TYPE_DUN };
+
     private static final int mDefaultApnId = DataConnectionTracker.APN_DEFAULT_ID;
 
     /* Constructor */
@@ -118,11 +121,26 @@
 
         createAllDataConnectionList();
         broadcastMessenger();
+
+        Context c = mCdmaPhone.getContext();
+        String[] t = c.getResources().getStringArray(
+                com.android.internal.R.array.config_cdma_dun_supported_types);
+        if (t != null && t.length > 0) {
+            ArrayList<String> temp = new ArrayList<String>();
+            for(int i=0; i< t.length; i++) {
+                if (!Phone.APN_TYPE_DUN.equalsIgnoreCase(t[i])) {
+                    temp.add(t[i]);
+                }
+            }
+            temp.add(0, Phone.APN_TYPE_DUN);
+            mDunApnTypes = temp.toArray(t);
+        }
+
     }
 
     @Override
     public void dispose() {
-        cleanUpConnection(false, null);
+        cleanUpConnection(false, null, false);
 
         super.dispose();
 
@@ -277,7 +295,7 @@
      * @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 +315,15 @@
                 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");
@@ -343,8 +367,7 @@
         String[] types;
         int apnId;
         if (mRequestedApnType.equals(Phone.APN_TYPE_DUN)) {
-            types = new String[1];
-            types[0] = Phone.APN_TYPE_DUN;
+            types = mDunApnTypes;
             apnId = DataConnectionTracker.APN_DUN_ID;
         } else {
             types = mDefaultApnTypes;
@@ -582,7 +605,7 @@
     @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 +787,13 @@
     @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 +812,7 @@
             }
 
             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 +839,7 @@
             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 +918,7 @@
                 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.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 @@
     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 @@
      * @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 @@
                 // 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 @@
 
         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());