From abeff9479fae6b0b92e56bd7bd9d043cdfd9317a Mon Sep 17 00:00:00 2001 From: Wink Saville Date: Fri, 12 Mar 2010 15:31:56 -0800 Subject: [PATCH] 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 --- .../internal/telephony/DataConnection.java | 45 ++++++++++++++++--- .../cdma/CdmaDataConnectionTracker.java | 9 ++-- .../gsm/GsmDataConnectionTracker.java | 9 ++-- 3 files changed, 50 insertions(+), 13 deletions(-) diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java index 521072e48f34e..70fdadfb29bef 100644 --- a/telephony/java/com/android/internal/telephony/DataConnection.java +++ b/telephony/java/com/android/internal/telephony/DataConnection.java @@ -134,6 +134,13 @@ public abstract class DataConnection extends HierarchicalStateMachine { public Message onCompletedMsg; } + /** + * An instance used for notification of blockingReset. + * TODO: Remove when blockingReset is removed. + */ + class ResetSynchronouslyLock { + } + /** * Used internally for saving disconnecting parameters. */ @@ -141,9 +148,13 @@ public abstract class DataConnection extends HierarchicalStateMachine { 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 @@ public abstract class DataConnection extends HierarchicalStateMachine { 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 : ""))); - 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 : ""))); + AsyncResult.forMessage(msg); + msg.sendToTarget(); + } + if (dp.lockObj != null) { + synchronized(dp.lockObj) { + dp.lockObj.notify(); + } + } clearSettings(); } @@ -777,6 +795,23 @@ public abstract class DataConnection extends HierarchicalStateMachine { sendMessage(obtainMessage(EVENT_RESET, new DisconnectParams(onCompletedMsg))); } + /** + * 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 diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java index 9218715604ce0..af9c65241db00 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 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { 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 f26e54e6ab64d..f96865239d886 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 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { 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); } }