diff options
author | Roshan Pius <rpius@google.com> | 2015-07-08 22:08:46 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2015-07-08 22:08:46 +0000 |
commit | f08a7ada3aaeb2cb167609f50fa77217e12243f7 (patch) | |
tree | 7edc8d4515bbff58c0d1cadf956d9ff5d2a0e787 /telecomm/java | |
parent | b0ca50264552c5451be6cf012422587ab612ecd2 (diff) | |
parent | 8f596907a5241badad821a6d3490eb2cd7dd23c5 (diff) | |
download | frameworks_base-f08a7ada3aaeb2cb167609f50fa77217e12243f7.zip frameworks_base-f08a7ada3aaeb2cb167609f50fa77217e12243f7.tar.gz frameworks_base-f08a7ada3aaeb2cb167609f50fa77217e12243f7.tar.bz2 |
am 8f596907: Merge "Change sequence of call removal from Phone\'s db." into mnc-dev
* commit '8f596907a5241badad821a6d3490eb2cd7dd23c5':
Change sequence of call removal from Phone's db.
Diffstat (limited to 'telecomm/java')
-rw-r--r-- | telecomm/java/android/telecom/Call.java | 43 |
1 files changed, 36 insertions, 7 deletions
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java index 6c1c118..49f738b 100644 --- a/telecomm/java/android/telecom/Call.java +++ b/telecomm/java/android/telecom/Call.java @@ -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); @@ -1087,7 +1089,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); } } @@ -1103,7 +1104,6 @@ public final class Call { mState = Call.STATE_DISCONNECTED; fireStateChanged(mState); fireCallDestroyed(); - mPhone.internalRemoveCall(this); } } @@ -1199,13 +1199,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; + } } }); } |