Simplify deallocation/unbinding of services.
Call counts of call services and selectors are kept current during call
and during the outgoing call process. This allows us to unbind simply
when the call-count goes down to 0.
A second optimization that can be made is to remove associated-call
counts from ServiceBinder and use the callIdMapper to maintain counts of
the associated calls. This binds the call count to the mapper items,
however there are two small roadblocks:
1. It isn't as easy to deal with the replace() scenario, but doable
2. The caller-ID mapper implementations between CS and selectors are
separate and it's nice to keep a single associated count implementation
for all ServiceBinders...this is also addressable, just not that
important at the moment.
Change-Id: Ibbf894ed5b7dd9ede1b088e530dd9cc2e0e649c2
diff --git a/src/com/android/telecomm/Call.java b/src/com/android/telecomm/Call.java
index 024d7d4..e21f3de 100644
--- a/src/com/android/telecomm/Call.java
+++ b/src/com/android/telecomm/Call.java
@@ -278,9 +278,17 @@
*/
void clearCallService() {
if (mCallService != null) {
- decrementAssociatedCallCount(mCallService);
- mCallService.removeCall(this);
+ CallServiceWrapper callServiceTemp = mCallService;
mCallService = null;
+ callServiceTemp.removeCall(this);
+
+ // Decrementing the count can cause the service to unbind, which itself can trigger the
+ // service-death code. Since the service death code tries to clean up any associated
+ // calls, we need to make sure to remove that information (e.g., removeCall()) before
+ // we decrement. Technically, invoking removeCall() prior to decrementing is all that is
+ // necessary, but cleaning up mCallService prior to triggering an unbind is good to do.
+ // If you change this, make sure to update {@link clearCallServiceSelector} as well.
+ decrementAssociatedCallCount(callServiceTemp);
}
}
@@ -293,16 +301,19 @@
clearCallServiceSelector();
+ selector.incrementAssociatedCallCount();
mCallServiceSelector = selector;
mCallServiceSelector.addCall(this);
}
void clearCallServiceSelector() {
if (mCallServiceSelector != null) {
- // TODO(sail): Stop leaking selectors.
- // decrementAssociatedCallCount(mCallServiceSelector);
- mCallServiceSelector.removeCall(this);
+ CallServiceSelectorWrapper selectorTemp = mCallServiceSelector;
mCallServiceSelector = null;
+ selectorTemp.removeCall(this);
+
+ // See comment on {@link #clearCallService}.
+ decrementAssociatedCallCount(selectorTemp);
}
}