summaryrefslogtreecommitdiffstats
path: root/telecomm
diff options
context:
space:
mode:
authorRoshan Pius <rpius@google.com>2015-07-08 22:03:22 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2015-07-08 22:03:25 +0000
commit8f596907a5241badad821a6d3490eb2cd7dd23c5 (patch)
tree823d434a0ee51868bfc582beed3d5931906b09dc /telecomm
parent6d712e06f7c35d4120ce8ded5961d3bb97c44cab (diff)
parent1ca6207a1ec5bf9c12027c4f09a4fe18bd3f825c (diff)
downloadframeworks_base-8f596907a5241badad821a6d3490eb2cd7dd23c5.zip
frameworks_base-8f596907a5241badad821a6d3490eb2cd7dd23c5.tar.gz
frameworks_base-8f596907a5241badad821a6d3490eb2cd7dd23c5.tar.bz2
Merge "Change sequence of call removal from Phone's db." into mnc-dev
Diffstat (limited to 'telecomm')
-rw-r--r--telecomm/java/android/telecom/Call.java43
1 files changed, 36 insertions, 7 deletions
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index e756a57..4569549 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);
@@ -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;
+ }
}
});
}