When we disconnect shutdown the StateMachine. DO NOT MERGE

Need to stop the StateMachine threads and release
all resources when we disconnect.

bug: 6342470
Change-Id: Ibf7a2ebf4f7ecd667c5d95579e66ecd5086103ea
diff --git a/core/java/com/android/internal/util/AsyncChannel.java b/core/java/com/android/internal/util/AsyncChannel.java
index d1c2d2e..5093b4d 100644
--- a/core/java/com/android/internal/util/AsyncChannel.java
+++ b/core/java/com/android/internal/util/AsyncChannel.java
@@ -444,6 +444,16 @@
         if ((mConnection != null) && (mSrcContext != null)) {
             mSrcContext.unbindService(mConnection);
         }
+        try {
+            // Send the DISCONNECTED, although it may not be received
+            // but its the best we can do.
+            Message msg = Message.obtain();
+            msg.what = CMD_CHANNEL_DISCONNECTED;
+            msg.replyTo = mSrcMessenger;
+            mDstMessenger.send(msg);
+        } catch(Exception e) {
+        }
+        // Tell source we're disconnected.
         if (mSrcHandler != null) {
             replyDisconnected(STATUS_SUCCESSFUL);
         }
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index 02f0d03..a6bd85e 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -17,7 +17,6 @@
 package com.android.internal.telephony;
 
 
-import com.android.internal.telephony.DataCallState.SetupResult;
 import com.android.internal.util.AsyncChannel;
 import com.android.internal.util.Protocol;
 import com.android.internal.util.State;
@@ -39,6 +38,7 @@
 import java.util.Calendar;
 import java.util.HashMap;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * {@hide}
@@ -65,8 +65,7 @@
     protected static final boolean DBG = true;
     protected static final boolean VDBG = false;
 
-    protected static Object mCountLock = new Object();
-    protected static int mCount;
+    protected static AtomicInteger mCount = new AtomicInteger(0);
     protected AsyncChannel mAc;
 
     protected List<ApnContext> mApnList = null;
@@ -260,7 +259,6 @@
 
     protected abstract void log(String s);
 
-
    //***** Constructor
     protected DataConnection(PhoneBase phone, String name, int id, RetryManager rm,
             DataConnectionTracker dct) {
@@ -287,6 +285,27 @@
     }
 
     /**
+     * Shut down this instance and its state machine.
+     */
+    private void shutDown() {
+        if (DBG) log("shutDown");
+
+        if (mAc != null) {
+            mAc.disconnected();
+            mAc = null;
+        }
+        mApnList = null;
+        mReconnectIntent = null;
+        mDataConnectionTracker = null;
+        mApn = null;
+        phone = null;
+        mLinkProperties = null;
+        mCapabilities = null;
+        lastFailCause = null;
+        userData = null;
+    }
+
+    /**
      * TearDown the data connection.
      *
      * @param o will be returned in AsyncResult.userObj
@@ -619,9 +638,11 @@
         @Override
         public void exit() {
             phone.mCM.unregisterForRilConnected(getHandler());
+            shutDown();
         }
         @Override
         public boolean processMessage(Message msg) {
+            boolean retVal = HANDLED;
             AsyncResult ar;
 
             switch (msg.what) {
@@ -639,14 +660,9 @@
                     }
                     break;
                 }
-                case AsyncChannel.CMD_CHANNEL_DISCONNECT: {
-                    if (VDBG) log("CMD_CHANNEL_DISCONNECT");
-                    mAc.disconnect();
-                    break;
-                }
                 case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
                     if (VDBG) log("CMD_CHANNEL_DISCONNECTED");
-                    mAc = null;
+                    quit();
                     break;
                 }
                 case DataConnectionAc.REQ_IS_INACTIVE: {
@@ -784,7 +800,7 @@
                     break;
             }
 
-            return HANDLED;
+            return retVal;
         }
     }
     private DcDefaultState mDefaultState = new DcDefaultState();
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
index 4ef05ea..141736c 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
@@ -51,11 +51,8 @@
      */
     static CdmaDataConnection makeDataConnection(CDMAPhone phone, int id, RetryManager rm,
             DataConnectionTracker dct) {
-        synchronized (mCountLock) {
-            mCount += 1;
-        }
-        CdmaDataConnection cdmaDc = new CdmaDataConnection(phone, "CdmaDC-" + mCount,
-                id, rm, dct);
+        CdmaDataConnection cdmaDc = new CdmaDataConnection(phone,
+                "CdmaDC-" + mCount.incrementAndGet(), id, rm, dct);
         cdmaDc.start();
         if (DBG) cdmaDc.log("Made " + cdmaDc.getName());
         return cdmaDc;
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
index 9801721..3e6d9a5 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
@@ -56,10 +56,8 @@
      */
     static GsmDataConnection makeDataConnection(PhoneBase phone, int id, RetryManager rm,
             DataConnectionTracker dct) {
-        synchronized (mCountLock) {
-            mCount += 1;
-        }
-        GsmDataConnection gsmDc = new GsmDataConnection(phone, "GsmDC-" + mCount, id, rm, dct);
+        GsmDataConnection gsmDc = new GsmDataConnection(phone,
+                "GsmDC-" + mCount.incrementAndGet(), id, rm, dct);
         gsmDc.start();
         if (DBG) gsmDc.log("Made " + gsmDc.getName());
         return gsmDc;