Merge "Change sequence of call removal from Phone's db." into mnc-dev

This commit is contained in:
Roshan Pius
2015-07-08 22:03:22 +00:00
committed by Android (Google) Code Review

View File

@ -921,7 +921,8 @@ public final class Call {
*/
public void registerCallback(Callback callback, Handler handler) {
unregisterCallback(callback);
if (callback != null && handler != null) {
// Don't allow new callback registration if the call is already being destroyed.
if (callback != null && handler != null && mState != STATE_DISCONNECTED) {
mCallbackRecords.add(new CallbackRecord<Callback>(callback, handler));
}
}
@ -932,7 +933,8 @@ public final class Call {
* @param callback A {@code Callback}.
*/
public void unregisterCallback(Callback callback) {
if (callback != null) {
// Don't allow callback deregistration if the call is already being destroyed.
if (callback != null && mState != STATE_DISCONNECTED) {
for (CallbackRecord<Callback> record : mCallbackRecords) {
if (record.getCallback() == callback) {
mCallbackRecords.remove(record);
@ -1080,7 +1082,6 @@ public final class Call {
// DISCONNECTED Call while still relying on the existence of that Call in the Phone's list.
if (mState == STATE_DISCONNECTED) {
fireCallDestroyed();
mPhone.internalRemoveCall(this);
}
}
@ -1096,7 +1097,6 @@ public final class Call {
mState = Call.STATE_DISCONNECTED;
fireStateChanged(mState);
fireCallDestroyed();
mPhone.internalRemoveCall(this);
}
}
@ -1192,13 +1192,42 @@ public final class Call {
}
private void fireCallDestroyed() {
for (CallbackRecord<Callback> record: mCallbackRecords) {
final Call call = this;
/**
* To preserve the ordering of the Call's onCallDestroyed callback and Phone's
* onCallRemoved callback, we remove this call from the Phone's record
* only once all of the registered onCallDestroyed callbacks are executed.
* All the callbacks get removed from our records as a part of this operation
* since onCallDestroyed is the final callback.
*/
final Call call = this;
if (mCallbackRecords.isEmpty()) {
// No callbacks registered, remove the call from Phone's record.
mPhone.internalRemoveCall(call);
}
for (final CallbackRecord<Callback> record : mCallbackRecords) {
final Callback callback = record.getCallback();
record.getHandler().post(new Runnable() {
@Override
public void run() {
callback.onCallDestroyed(call);
boolean isFinalRemoval = false;
RuntimeException toThrow = null;
try {
callback.onCallDestroyed(call);
} catch (RuntimeException e) {
toThrow = e;
}
synchronized(Call.this) {
mCallbackRecords.remove(record);
if (mCallbackRecords.isEmpty()) {
isFinalRemoval = true;
}
}
if (isFinalRemoval) {
mPhone.internalRemoveCall(call);
}
if (toThrow != null) {
throw toThrow;
}
}
});
}