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
This commit is contained in:
Wink Saville
2010-03-12 15:31:56 -08:00
parent e1748c6714
commit abeff9479f
3 changed files with 50 additions and 13 deletions

View File

@@ -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 : "<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();
}
@@ -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

View File

@@ -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);
}
}

View File

@@ -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);
}
}