Fix data error handling.

In change I5776324a I made DataConnection.reset asynchronous.
That was a mistake as callers to cleanUpConnection assumed
it was synchronous. Added DataConnection.resetSynchronously
as a fix, someday the trackers will become asynchronous and
this won't be necessary.

Change-Id: I4669901e5c47a712212bb388c35fbb9f9ff603a7
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index 521072e..70fdadf 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -135,15 +135,26 @@
     }
 
     /**
+     * An instance used for notification of blockingReset.
+     * TODO: Remove when blockingReset is removed.
+     */
+    class ResetSynchronouslyLock {
+    }
+
+    /**
      * Used internally for saving disconnecting parameters.
      */
     protected static class DisconnectParams {
         public DisconnectParams(Message onCompletedMsg) {
             this.onCompletedMsg = onCompletedMsg;
         }
+        public DisconnectParams(ResetSynchronouslyLock lockObj) {
+            this.lockObj = lockObj;
+        }
 
         public int tag;
         public Message onCompletedMsg;
+        public ResetSynchronouslyLock lockObj;
     }
 
     /**
@@ -339,11 +350,18 @@
     private void notifyDisconnectCompleted(DisconnectParams dp) {
         if (DBG) log("NotifyDisconnectCompleted");
 
-        Message msg = dp.onCompletedMsg;
-        log(String.format("msg.what=%d msg.obj=%s",
-                msg.what, ((msg.obj instanceof String) ? (String) msg.obj : "<no-reason>")));
-        AsyncResult.forMessage(msg);
-        msg.sendToTarget();
+        if (dp.onCompletedMsg != null) {
+            Message msg = dp.onCompletedMsg;
+            log(String.format("msg.what=%d msg.obj=%s",
+                    msg.what, ((msg.obj instanceof String) ? (String) msg.obj : "<no-reason>")));
+            AsyncResult.forMessage(msg);
+            msg.sendToTarget();
+        }
+        if (dp.lockObj != null) {
+            synchronized(dp.lockObj) {
+                dp.lockObj.notify();
+            }
+        }
 
         clearSettings();
     }
@@ -778,6 +796,23 @@
     }
 
     /**
+     * Reset the connection and wait for it to complete.
+     * TODO: Remove when all callers only need the asynchronous
+     * reset defined above.
+     */
+    public void resetSynchronously() {
+        ResetSynchronouslyLock lockObj = new ResetSynchronouslyLock();
+        synchronized(lockObj) {
+            sendMessage(obtainMessage(EVENT_RESET, new DisconnectParams(lockObj)));
+            try {
+                lockObj.wait();
+            } catch (InterruptedException e) {
+                log("blockingReset: unexpected interrupted of wait()");
+            }
+        }
+    }
+
+    /**
      * Connect to the apn and return an AsyncResult in onCompletedMsg.
      * Used for cellular networks that use Acess Point Names (APN) such
      * as GSM networks.
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
index 9218715..af9c652 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -386,18 +386,19 @@
                 if (tearDown) {
                     if (DBG) log("cleanUpConnection: teardown, call conn.disconnect");
                     conn.disconnect(obtainMessage(EVENT_DISCONNECT_DONE, reason));
+                    notificationDeferred = true;
                 } else {
-                    if (DBG) log("cleanUpConnection: !tearDown, call conn.reset");
-                    conn.reset(obtainMessage(EVENT_RESET_DONE, reason));
+                    if (DBG) log("cleanUpConnection: !tearDown, call conn.resetSynchronously");
+                    conn.resetSynchronously();
+                    notificationDeferred = false;
                 }
-                notificationDeferred = true;
             }
         }
 
         stopNetStatPoll();
 
         if (!notificationDeferred) {
-            if (DBG) log("cleanupConnection: !tearDown && !resettingConn");
+            if (DBG) log("cleanupConnection: !notificationDeferred");
             gotoIdleAndNotifyDataConnection(reason);
         }
     }
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index f26e54e..f968652 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -507,16 +507,17 @@
             if (tearDown) {
                 if (DBG) log("cleanUpConnection: teardown, call conn.disconnect");
                 conn.disconnect(obtainMessage(EVENT_DISCONNECT_DONE, reason));
+                notificationDeferred = true;
             } else {
-                if (DBG) log("cleanUpConnection: !tearDown, call conn.reset");
-                conn.reset(obtainMessage(EVENT_RESET_DONE, reason));
+                if (DBG) log("cleanUpConnection: !tearDown, call conn.resetSynchronously");
+                conn.resetSynchronously();
+                notificationDeferred = false;
             }
-            notificationDeferred = true;
         }
         stopNetStatPoll();
 
         if (!notificationDeferred) {
-            if (DBG) log("cleanupConnection: !tearDown && !resettingConn");
+            if (DBG) log("cleanupConnection: !notificationDeferred");
             gotoIdleAndNotifyDataConnection(reason);
         }
     }