Ensure ImsConferenceController recalcs when a conference is no longer full.
When the capacity of the conference changes, ImsConference will now
notify ImsConferenceController to trigger a recalculate of the
conferenceable connections.
When a conference becomes full, if a participant leaves, this change means
we can now re-enable the merge button.
Test: Manual live network test; create full conference then add another
call, disconnect one of the conference participants and verify we can
now merge.
Test: Added unit test to ImsConference to verify it will signal on
fullness change.
Fixes: 242837209
Change-Id: I099d9d51b40117def6f71e6967acb0d21ed7cc41
diff --git a/src/com/android/services/telephony/ImsConference.java b/src/com/android/services/telephony/ImsConference.java
index c62b4fa..7bbe9cf 100644
--- a/src/com/android/services/telephony/ImsConference.java
+++ b/src/com/android/services/telephony/ImsConference.java
@@ -968,6 +968,7 @@
// of the participants, we can get into a situation where the participant is added twice.
synchronized (mUpdateSyncRoot) {
int oldParticipantCount = mConferenceParticipantConnections.size();
+ boolean wasFullConference = isFullConference();
boolean newParticipantsAdded = false;
boolean oldParticipantsRemoved = false;
ArrayList<ConferenceParticipant> newParticipants = new ArrayList<>(participants.size());
@@ -1102,6 +1103,12 @@
updateManageConference();
}
+ // If the "fullness" of the conference changed, we need to inform listeners.
+ // Ie tell ImsConferenceController.
+ if (wasFullConference != isFullConference()) {
+ notifyConferenceCapacityChanged();
+ }
+
// If the conference is empty and we're supposed to do a local disconnect, do so now.
if (mCarrierConfig.shouldLocalDisconnectEmptyConference()
// If we dropped from > 0 participants to zero
diff --git a/src/com/android/services/telephony/ImsConferenceController.java b/src/com/android/services/telephony/ImsConferenceController.java
index 4200904..35b493a 100644
--- a/src/com/android/services/telephony/ImsConferenceController.java
+++ b/src/com/android/services/telephony/ImsConferenceController.java
@@ -52,6 +52,14 @@
private final TelephonyConferenceBase.TelephonyConferenceListener mConferenceListener =
new TelephonyConferenceBase.TelephonyConferenceListener() {
@Override
+ public void onConferenceCapacityChanged() {
+ // If the conference reached or is no longer at capacity then we need to recalculate
+ // as it may be possible to merge or not merge now.
+ Log.i(ImsConferenceController.this, "onConferenceCapacityChanged: recalc");
+ recalculateConferenceable();
+ }
+
+ @Override
public void onDestroyed(Conference conference) {
if (Log.VERBOSE) {
Log.v(ImsConferenceController.class, "onDestroyed: %s", conference);
diff --git a/src/com/android/services/telephony/TelephonyConferenceBase.java b/src/com/android/services/telephony/TelephonyConferenceBase.java
index 1c81fb9..1e7f956 100644
--- a/src/com/android/services/telephony/TelephonyConferenceBase.java
+++ b/src/com/android/services/telephony/TelephonyConferenceBase.java
@@ -60,6 +60,11 @@
* @param conference The conference.
*/
public void onDestroyed(Conference conference) {}
+
+ /**
+ * Listener called when a conference either reaches capacity or is no longer at capacity.
+ */
+ public void onConferenceCapacityChanged() {}
}
private final Set<TelephonyConferenceListener> mListeners = Collections.newSetFromMap(
@@ -237,6 +242,14 @@
}
/**
+ * Notifies the {@link TelephonyConferenceListener}s when the capacity of the conference has
+ * changed.
+ */
+ public void notifyConferenceCapacityChanged() {
+ mListeners.forEach(l -> l.onConferenceCapacityChanged());
+ }
+
+ /**
* Notifies {@link TelephonyConferenceListener}s of a conference being destroyed
*/
private void notifyDestroyed() {
diff --git a/tests/src/com/android/services/telephony/ImsConferenceTest.java b/tests/src/com/android/services/telephony/ImsConferenceTest.java
index 9d2f5ac..fcef25a 100644
--- a/tests/src/com/android/services/telephony/ImsConferenceTest.java
+++ b/tests/src/com/android/services/telephony/ImsConferenceTest.java
@@ -23,6 +23,7 @@
import static org.junit.Assert.assertNotNull;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
@@ -121,6 +122,58 @@
}
}
+ /**
+ * Verifies that an ImsConference will inform listeners when the "fullness" of the conference
+ * changes as participants come and go.
+ */
+ @Test
+ @SmallTest
+ public void testNotifyOnConferenceCapacityChanged() {
+ ImsConference imsConference = new ImsConference(mMockTelecomAccountRegistry,
+ mMockTelephonyConnectionServiceProxy, mConferenceHost,
+ null /* phoneAccountHandle */, () -> true /* featureFlagProxy */,
+ new ImsConference.CarrierConfiguration.Builder()
+ .setIsMaximumConferenceSizeEnforced(true)
+ .setMaximumConferenceSize(2)
+ .build());
+ TelephonyConferenceBase.TelephonyConferenceListener listener =
+ mock(TelephonyConferenceBase.TelephonyConferenceListener.class);
+ imsConference.addTelephonyConferenceListener(listener);
+
+ ConferenceParticipant participant1 = new ConferenceParticipant(
+ Uri.parse("tel:6505551212"),
+ "A",
+ Uri.parse("sip:6505551212@testims.com"),
+ Connection.STATE_ACTIVE,
+ Call.Details.DIRECTION_OUTGOING);
+ ConferenceParticipant participant2 = new ConferenceParticipant(
+ Uri.parse("tel:6505551213"),
+ "A",
+ Uri.parse("sip:6505551213@testims.com"),
+ Connection.STATE_ACTIVE,
+ Call.Details.DIRECTION_INCOMING);
+
+ // no capacity change since we haven't hit the limit yet.
+ imsConference.handleConferenceParticipantsUpdate(mConferenceHost,
+ Arrays.asList(participant1));
+ verify(listener, never()).onConferenceCapacityChanged();
+
+ // Now we should get a capacity change
+ imsConference.handleConferenceParticipantsUpdate(mConferenceHost,
+ Arrays.asList(participant1, participant2));
+ verify(listener, times(1)).onConferenceCapacityChanged();
+
+ // And another when we go back to a non-full conference.
+ imsConference.handleConferenceParticipantsUpdate(mConferenceHost,
+ Arrays.asList(participant1));
+ verify(listener, times(2)).onConferenceCapacityChanged();
+
+ // But not when we reduce count further.
+ imsConference.handleConferenceParticipantsUpdate(mConferenceHost,
+ Collections.emptyList());
+ verify(listener, times(2)).onConferenceCapacityChanged();
+ }
+
@Test
@SmallTest
public void testSinglePartyEmulation() {