Fix bubble for conference call.
Fix bubble conference call bugs once and for all.
ReturnToCallController.onDsconnect() is called twice when ending the last call
in conference call: one for the last call itself, one for the parent call. And
we should do nothing for the parent call. This change avoids extra handling in
Bubble.showText() and Bubble.hideAndReset().
Test: ReturnToCallControllerTest
PiperOrigin-RevId: 165195412
Change-Id: Ib21fac6dd7ad9fe85c3070ce1295f63a91c61a02
diff --git a/java/com/android/incallui/ReturnToCallController.java b/java/com/android/incallui/ReturnToCallController.java
index 8e4b9cc..b0bafac 100644
--- a/java/com/android/incallui/ReturnToCallController.java
+++ b/java/com/android/incallui/ReturnToCallController.java
@@ -142,13 +142,22 @@
@Override
public void onDisconnect(DialerCall call) {
- boolean hasAnotherCall = CallList.getInstance().getActiveOrBackgroundCall() != null;
+ if (call.wasParentCall()) {
+ // It's disconnected after the last child call is disconnected, and we already did everything
+ // for the last child.
+ LogUtil.i(
+ "ReturnToCallController.onDisconnect", "being called for a parent call and do nothing");
+ return;
+ }
if (bubble != null
&& bubble.isVisible()
- && (!TelecomUtil.isInCall(context) || hasAnotherCall)) {
+ && (!TelecomUtil.isInCall(context)
+ || CallList.getInstance().getActiveOrBackgroundCall() != null)) {
bubble.showText(context.getText(R.string.incall_call_ended));
}
- if (!hasAnotherCall) {
+ // For conference call, we should hideAndReset for the last disconnected child call while the
+ // parent call is still there.
+ if (!CallList.getInstance().hasNonParentActiveOrBackgroundCall()) {
hideAndReset();
}
}
diff --git a/java/com/android/incallui/call/CallList.java b/java/com/android/incallui/call/CallList.java
index d932c24..d0931dd 100644
--- a/java/com/android/incallui/call/CallList.java
+++ b/java/com/android/incallui/call/CallList.java
@@ -536,6 +536,22 @@
}
/**
+ * Return if there is any active or background call which was not a parent call (never had a child
+ * call)
+ */
+ public boolean hasNonParentActiveOrBackgroundCall() {
+ for (DialerCall call : mCallById.values()) {
+ if ((call.getState() == State.ACTIVE
+ || call.getState() == State.ONHOLD
+ || call.getState() == State.CONFERENCED)
+ && !call.wasParentCall()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
* This is called when the service disconnects, either expectedly or unexpectedly. For the
* expected case, it's because we have no calls left. For the unexpected case, it is likely a
* crash of phone and we need to clean up our calls manually. Without phone, there can be no
diff --git a/java/com/android/incallui/call/DialerCall.java b/java/com/android/incallui/call/DialerCall.java
index a954ee9..378f920 100644
--- a/java/com/android/incallui/call/DialerCall.java
+++ b/java/com/android/incallui/call/DialerCall.java
@@ -429,6 +429,10 @@
}
}
+ public boolean wasParentCall() {
+ return mLogState.conferencedCalls != 0;
+ }
+
private void update() {
Trace.beginSection("DialerCall.update");
int oldState = getState();