Add connections to conference controllers when original connection is valid
The only way that we can determine if we should use the Telephony or CDMA
conference controllers are once the underlying original connection is set.
Until it is set, we cannot guarantee that we'll get it right. This CL introduces
some plumbing that allows the TelephonyConnection to notify the
TelephonyConnectionService when this occurs so that it can take action
at the appropriate time.
Bug: 18240234
Bug: 18056632
Change-Id: I54b4d9821b94085e639c35f2fe3569b4eed67f88
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index c8f26f8..0ed1070 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -34,7 +34,10 @@
import com.android.internal.telephony.imsphone.ImsPhoneConnection;
import java.lang.Override;
+import java.util.Collections;
import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
/**
* Base class for CDMA and GSM connections.
@@ -78,6 +81,15 @@
}
};
+ /**
+ * A listener/callback mechanism that is specific communication from TelephonyConnections
+ * to TelephonyConnectionService (for now). It is more specific that Connection.Listener
+ * because it is only exposed in Telephony.
+ */
+ public abstract static class TelephonyConnectionListener {
+ public void onOriginalConnectionConfigured(TelephonyConnection c) {}
+ }
+
private final PostDialListener mPostDialListener = new PostDialListener() {
@Override
public void onPostDialWait() {
@@ -186,6 +198,12 @@
*/
private int mAudioQuality;
+ /**
+ * Listeners to our TelephonyConnection specific callbacks
+ */
+ private final Set<TelephonyConnectionListener> mTelephonyListeners = Collections.newSetFromMap(
+ new ConcurrentHashMap<TelephonyConnectionListener, Boolean>(8, 0.9f, 1));
+
protected TelephonyConnection(com.android.internal.telephony.Connection originalConnection) {
if (originalConnection != null) {
setOriginalConnection(originalConnection);
@@ -470,6 +488,7 @@
mWasImsConnection = true;
}
+ fireOnOriginalConnectionConfigured();
updateAddress();
}
@@ -824,4 +843,37 @@
int newCapabilities = capabilities & ~capability;
return newCapabilities;
}
+
+ /**
+ * Register a listener for {@link TelephonyConnection} specific triggers.
+ * @param l The instance of the listener to add
+ * @return The connection being listened to
+ */
+ public final TelephonyConnection addTelephonyConnectionListener(TelephonyConnectionListener l) {
+ mTelephonyListeners.add(l);
+ return this;
+ }
+
+ /**
+ * Remove a listener for {@link TelephonyConnection} specific triggers.
+ * @param l The instance of the listener to remove
+ * @return The connection being listened to
+ */
+ public final TelephonyConnection removeTelephonyConnectionListener(
+ TelephonyConnectionListener l) {
+ if (l != null) {
+ mTelephonyListeners.remove(l);
+ }
+ return this;
+ }
+
+ /**
+ * Fire a callback to the various listeners for when the original connection is
+ * set in this {@link TelephonyConnection}
+ */
+ private final void fireOnOriginalConnectionConfigured() {
+ for (TelephonyConnectionListener l : mTelephonyListeners) {
+ l.onOriginalConnectionConfigured(this);
+ }
+ }
}
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 91f164b..c402409 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -56,6 +56,17 @@
private EmergencyCallHelper mEmergencyCallHelper;
private EmergencyTonePlayer mEmergencyTonePlayer;
+ /**
+ * A listener to actionable events specific to the TelephonyConnection.
+ */
+ private final TelephonyConnection.TelephonyConnectionListener mTelephonyConnectionListener =
+ new TelephonyConnection.TelephonyConnectionListener() {
+ @Override
+ public void onOriginalConnectionConfigured(TelephonyConnection c) {
+ addConnectionToConferenceController(c);
+ }
+ };
+
@Override
public void onCreate() {
super.onCreate();
@@ -345,24 +356,20 @@
Phone phone,
com.android.internal.telephony.Connection originalConnection,
boolean isOutgoing) {
+ TelephonyConnection returnConnection = null;
int phoneType = phone.getPhoneType();
if (phoneType == TelephonyManager.PHONE_TYPE_GSM) {
- GsmConnection connection = new GsmConnection(originalConnection);
- mTelephonyConferenceController.add(connection);
- return connection;
+ returnConnection = new GsmConnection(originalConnection);
} else if (phoneType == TelephonyManager.PHONE_TYPE_CDMA) {
boolean allowMute = allowMute(phone);
- CdmaConnection connection = new CdmaConnection(
+ returnConnection = new CdmaConnection(
originalConnection, mEmergencyTonePlayer, allowMute, isOutgoing);
- if (connection.isImsConnection()) {
- mTelephonyConferenceController.add(connection);
- } else {
- mCdmaConferenceController.add(connection);
- }
- return connection;
- } else {
- return null;
}
+ if (returnConnection != null) {
+ // Listen to Telephony specific callbacks from the connection
+ returnConnection.addTelephonyConnectionListener(mTelephonyConnectionListener);
+ }
+ return returnConnection;
}
private boolean isOriginalConnectionKnown(
@@ -418,4 +425,38 @@
return true;
}
+
+ @Override
+ public void removeConnection(Connection connection) {
+ super.removeConnection(connection);
+ TelephonyConnection telephonyConnection = (TelephonyConnection)connection;
+ telephonyConnection.removeTelephonyConnectionListener(mTelephonyConnectionListener);
+ }
+
+ /**
+ * When a {@link TelephonyConnection} has its underlying original connection configured,
+ * we need to add it to the correct conference controller.
+ *
+ * @param connection The connection to be added to the controller
+ */
+ public void addConnectionToConferenceController(TelephonyConnection connection) {
+ // TODO: Do we need to handle the case of the original connection changing
+ // and triggering this callback multiple times for the same connection?
+ // If that is the case, we might want to remove this connection from all
+ // conference controllers first before re-adding it.
+ if (connection.isImsConnection()) {
+ Log.d(this, "Adding IMS connection to conference controller: " + connection);
+ mTelephonyConferenceController.add(connection);
+ } else {
+ int phoneType = connection.getCall().getPhone().getPhoneType();
+ if (phoneType == TelephonyManager.PHONE_TYPE_GSM) {
+ Log.d(this, "Adding GSM connection to conference controller: " + connection);
+ mTelephonyConferenceController.add(connection);
+ } else if (phoneType == TelephonyManager.PHONE_TYPE_CDMA &&
+ connection instanceof CdmaConnection) {
+ Log.d(this, "Adding CDMA connection to conference controller: " + connection);
+ mCdmaConferenceController.add((CdmaConnection)connection);
+ }
+ }
+ }
}