Fix crash during outgoing call + incoming SM call
When an outgoing call is in SELECT_PHONE_ACCOUNT state and an
incoming Self-Managed call is received, it will cause a crash
because we assume that the target PhoneAccount is set.
Instead, only count unholdable calls using Calls that have had
their target PhoneAccount set. This convention is set because
calls are not considered "active focus" until they have had their
PhoneAccount set. Otherwise, we could show UX to end the outgoing
call to accept the incoming call, which will put Telecom in a
bad state because it does not properly end the call in
SELECT_PHONE_ACCOUNT state.
Bug: 285161098
Test: place outgoing managed call and put into SELECT_PHONE_ACCOUNT
and then create incoming Self-Managed call.
Test: atest TelecomUnitTests
Change-Id: Ica350292275a75936a3b529111ee0c3527d9dd8a
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 4eb22f4..777f301 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -4738,15 +4738,21 @@
/**
* Determines the number of unholdable calls present in a connection service other than the one
- * the passed phone account belonds to.
+ * the passed phone account belongs to. If a ConnectionService has not been associated with an
+ * outgoing call yet (for example, it is in the SELECT_PHONE_ACCOUNT state), then we do not
+ * count that call because it is not tracked as an active call yet.
* @param phoneAccountHandle The handle of the PhoneAccount.
* @return Number of unholdable calls owned by other connection service.
*/
public int getNumUnholdableCallsForOtherConnectionService(
PhoneAccountHandle phoneAccountHandle) {
return (int) mCalls.stream().filter(call ->
- !phoneAccountHandle.getComponentName().equals(
- call.getTargetPhoneAccount().getComponentName())
+ // If this convention needs to be changed, answerCall will need to be modified to
+ // change what an "active call" is so that the call in SELECT_PHONE_ACCOUNT state
+ // will be properly cancelled.
+ call.getTargetPhoneAccount() != null
+ && !phoneAccountHandle.getComponentName().equals(
+ call.getTargetPhoneAccount().getComponentName())
&& call.getParentCall() == null
&& !call.isExternalCall()
&& !canHold(call)).count();