Conference event package performance improvement.
- Instead of sending each participant to the telephony conference
controller, all participants are sent at once. This way the conference
only needs to be recalculated once.
- New connections are created with state NEW so that they are not shown
in the InCall UI.
- Once the conference is established, the state of the connections is
set appropriately based on the information in the conference event
package.
Bug: 18057361
Change-Id: Ibdb5cb940f15ab6d872bf1ef8c99a1a9ebae7b6e
diff --git a/src/com/android/services/telephony/TelephonyConference.java b/src/com/android/services/telephony/TelephonyConference.java
index 21dac0c..7736dc1 100644
--- a/src/com/android/services/telephony/TelephonyConference.java
+++ b/src/com/android/services/telephony/TelephonyConference.java
@@ -33,6 +33,12 @@
*/
public class TelephonyConference extends Conference {
+ /**
+ * When {@code true}, indicates that conference participant information from an IMS conference
+ * event package has been received.
+ */
+ private boolean mParticipantsReceived = false;
+
public TelephonyConference(PhoneAccountHandle phoneAccount) {
super(phoneAccount);
setCapabilities(
@@ -133,7 +139,10 @@
public void onConnectionAdded(Connection connection) {
// If the conference was an IMS connection currently or before, disable MANAGE_CONFERENCE
// as the default behavior. If there is a conference event package, this may be overridden.
- if (((TelephonyConnection) connection).wasImsConnection()) {
+ // If a conference event package was received, do not attempt to remove manage conference.
+ if (connection instanceof TelephonyConnection &&
+ ((TelephonyConnection) connection).wasImsConnection() &&
+ !mParticipantsReceived) {
int capabilities = getCapabilities();
if (PhoneCapabilities.can(capabilities, PhoneCapabilities.MANAGE_CONFERENCE)) {
int newCapabilities =
@@ -191,4 +200,17 @@
}
return (TelephonyConnection) connections.get(0);
}
+
+ /**
+ * Flags the conference to indicate that a conference event package has been received and there
+ * is now participant data present which would permit conference management.
+ */
+ public void setParticipantsReceived() {
+ if (!mParticipantsReceived) {
+ int capabilities = getCapabilities();
+ capabilities |= PhoneCapabilities.MANAGE_CONFERENCE;
+ setCapabilities(capabilities);
+ }
+ mParticipantsReceived = true;
+ }
}
diff --git a/src/com/android/services/telephony/TelephonyConferenceController.java b/src/com/android/services/telephony/TelephonyConferenceController.java
index 43385fd..f726c55 100644
--- a/src/com/android/services/telephony/TelephonyConferenceController.java
+++ b/src/com/android/services/telephony/TelephonyConferenceController.java
@@ -61,23 +61,22 @@
}
/**
- * Handles notifications from an connection that a participant in a conference has changed
+ * Handles notifications from an connection that participant(s) in a conference have changed
* state.
*
* @param c The connection.
- * @param participant The participant information.
+ * @param participants The participant information.
*/
@Override
- public void onConferenceParticipantChanged(Connection c,
- ConferenceParticipant participant) {
+ public void onConferenceParticipantsChanged(Connection c,
+ List<ConferenceParticipant> participants) {
if (c == null) {
return;
}
+ Log.v(this, "onConferenceParticipantsChanged: %d participants", participants.size());
TelephonyConnection telephonyConnection = (TelephonyConnection) c;
-
- Log.v(this, "onConferenceParticipantChanged: %s", participant);
- handleConferenceParticipantUpdate(telephonyConnection, participant);
+ handleConferenceParticipantsUpdate(telephonyConnection, participants);
}
};
@@ -219,6 +218,8 @@
Log.d(this, "Recalculate conference calls %s %s.",
mTelephonyConference, conferencedConnections);
+ boolean wasParticipantsAdded = false;
+
// If the number of telephony connections drops below the limit, the conference can be
// considered terminated.
// We must have less than 2 GSM connections and less than 1 IMS connection.
@@ -240,7 +241,8 @@
List<Connection> existingConnections = mTelephonyConference.getConnections();
// Remove any that no longer exist
for (Connection connection : existingConnections) {
- if (!conferencedConnections.contains(connection)) {
+ if (connection instanceof TelephonyConnection &&
+ !conferencedConnections.contains(connection)) {
mTelephonyConference.removeConnection(connection);
}
}
@@ -256,8 +258,9 @@
for (Connection conferenceParticipant :
mConferenceParticipantConnections.values()) {
- if (conferenceParticipant.getState() == Connection.STATE_ACTIVE) {
+ if (conferenceParticipant.getState() == Connection.STATE_NEW) {
if (!existingConnections.contains(conferenceParticipant)) {
+ wasParticipantsAdded = true;
mTelephonyConference.addConnection(conferenceParticipant);
}
}
@@ -273,12 +276,19 @@
// Add the conference participants
for (Connection conferenceParticipant :
mConferenceParticipantConnections.values()) {
+ wasParticipantsAdded = true;
mTelephonyConference.addConnection(conferenceParticipant);
}
mConnectionService.addConference(mTelephonyConference);
}
+ // If we added conference participants (e.g. via an IMS conference event package),
+ // notify the conference so that the MANAGE_CONFERENCE capability can be added.
+ if (wasParticipantsAdded) {
+ mTelephonyConference.setParticipantsReceived();
+ }
+
// Set the conference state to the same state as its child connections.
Connection conferencedConnection = mTelephonyConference.getPrimaryConnection();
switch (conferencedConnection.getState()) {
@@ -310,21 +320,40 @@
}
/**
- * Handles state changes for a conference participant.
+ * Handles state changes for conference participant(s).
*
* @param parent The connection which was notified of the conference participant.
- * @param participant The conference participant.
+ * @param participants The conference participant information.
*/
- private void handleConferenceParticipantUpdate(
- TelephonyConnection parent, ConferenceParticipant participant) {
+ private void handleConferenceParticipantsUpdate(
+ TelephonyConnection parent, List<ConferenceParticipant> participants) {
- Uri endpoint = participant.getEndpoint();
- if (!mConferenceParticipantConnections.containsKey(endpoint)) {
- createConferenceParticipantConnection(parent, participant);
- } else {
- ConferenceParticipantConnection connection =
- mConferenceParticipantConnections.get(endpoint);
- connection.updateState(participant.getState());
+ boolean recalculateConference = false;
+ ArrayList<ConferenceParticipant> newParticipants = new ArrayList<>(participants.size());
+
+ for (ConferenceParticipant participant : participants) {
+ Uri endpoint = participant.getEndpoint();
+ if (!mConferenceParticipantConnections.containsKey(endpoint)) {
+ createConferenceParticipantConnection(parent, participant);
+ newParticipants.add(participant);
+ recalculateConference = true;
+ } else {
+ ConferenceParticipantConnection connection =
+ mConferenceParticipantConnections.get(endpoint);
+ connection.updateState(participant.getState());
+ }
+ }
+
+ if (recalculateConference) {
+ // Recalculate to add new connections to the conference.
+ recalculateConference();
+
+ // Now that conference is established, set the state for all participants.
+ for (ConferenceParticipant newParticipant : newParticipants) {
+ ConferenceParticipantConnection connection =
+ mConferenceParticipantConnections.get(newParticipant.getEndpoint());
+ connection.updateState(newParticipant.getState());
+ }
}
}
@@ -346,13 +375,9 @@
ConferenceParticipantConnection connection = new ConferenceParticipantConnection(
parent, participant);
connection.addConnectionListener(mConnectionListener);
- connection.updateState(Connection.STATE_HOLDING);
mConferenceParticipantConnections.put(participant.getEndpoint(), connection);
PhoneAccountHandle phoneAccountHandle =
- TelecomAccountRegistry.makePstnPhoneAccountHandle(parent.getPhone());
+ TelecomAccountRegistry.makePstnPhoneAccountHandle(parent.getPhone());
mConnectionService.addExistingConnection(phoneAccountHandle, connection);
- // Recalculate to add to the conference and set its state appropriately.
- recalculateConference();
- connection.updateState(participant.getState());
}
}
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index da3de63..30312bb 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -35,6 +35,7 @@
import java.lang.Override;
import java.util.Collections;
+import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -155,14 +156,14 @@
}
/**
- * Handles a change in the state of a conference participant, as reported by the
+ * Handles a change in the state of conference participant(s), as reported by the
* {@link com.android.internal.telephony.Connection}.
*
- * @param participant The participant which changed.
+ * @param participants The participant(s) which changed.
*/
@Override
- public void onConferenceParticipantChanged(ConferenceParticipant participant) {
- updateConferenceParticipant(participant);
+ public void onConferenceParticipantsChanged(List<ConferenceParticipant> participants) {
+ updateConferenceParticipants(participants);
}
};
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index c402409..8ef9ae8 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -429,8 +429,10 @@
@Override
public void removeConnection(Connection connection) {
super.removeConnection(connection);
- TelephonyConnection telephonyConnection = (TelephonyConnection)connection;
- telephonyConnection.removeTelephonyConnectionListener(mTelephonyConnectionListener);
+ if (connection instanceof TelephonyConnection) {
+ TelephonyConnection telephonyConnection = (TelephonyConnection) connection;
+ telephonyConnection.removeTelephonyConnectionListener(mTelephonyConnectionListener);
+ }
}
/**