Support Conferences in Remote Connections
Bug: 16957997
Change-Id: I009924eac0f06a863b4c4c4148ecbcf27d220e14
diff --git a/src/com/android/telecomm/Call.java b/src/com/android/telecomm/Call.java
index 4fa39e8..dc3fa07 100644
--- a/src/com/android/telecomm/Call.java
+++ b/src/com/android/telecomm/Call.java
@@ -616,7 +616,9 @@
}
@Override
- public void handleCreateConnectionSuccess(ParcelableConnection connection) {
+ public void handleCreateConnectionSuccess(
+ CallIdMapper idMapper,
+ ParcelableConnection connection) {
Log.v(this, "handleCreateConnectionSuccessful %s", connection);
mCreateConnectionProcessor = null;
setTargetPhoneAccount(connection.getPhoneAccount());
@@ -630,6 +632,11 @@
setAudioModeIsVoip(connection.getAudioModeIsVoip());
setStatusHints(connection.getStatusHints());
+ mConferenceableCalls.clear();
+ for (String id : connection.getConferenceableConnectionIds()) {
+ mConferenceableCalls.add(idMapper.getCall(id));
+ }
+
if (mIsIncoming) {
// We do not handle incoming calls immediately when they are verified by the connection
// service. We allow the caller-info-query code to execute first so that we can read the
diff --git a/src/com/android/telecomm/ConnectionServiceWrapper.java b/src/com/android/telecomm/ConnectionServiceWrapper.java
index 7d1f01a..5fcb9bd 100644
--- a/src/com/android/telecomm/ConnectionServiceWrapper.java
+++ b/src/com/android/telecomm/ConnectionServiceWrapper.java
@@ -894,7 +894,8 @@
} else {
// Successful connection
if (mPendingResponses.containsKey(callId)) {
- mPendingResponses.remove(callId).handleCreateConnectionSuccess(connection);
+ mPendingResponses.remove(callId)
+ .handleCreateConnectionSuccess(mCallIdMapper, connection);
}
}
}
diff --git a/src/com/android/telecomm/CreateConnectionProcessor.java b/src/com/android/telecomm/CreateConnectionProcessor.java
index d8fd00a..cc2e8c0 100644
--- a/src/com/android/telecomm/CreateConnectionProcessor.java
+++ b/src/com/android/telecomm/CreateConnectionProcessor.java
@@ -272,7 +272,9 @@
}
@Override
- public void handleCreateConnectionSuccess(ParcelableConnection connection) {
+ public void handleCreateConnectionSuccess(
+ CallIdMapper idMapper,
+ ParcelableConnection connection) {
if (mResponse == null) {
// Nobody is listening for this connection attempt any longer; ask the responsible
// ConnectionService to tear down any resources associated with the call
@@ -280,7 +282,7 @@
} else {
// Success -- share the good news and remember that we are no longer interested
// in hearing about any more attempts
- mResponse.handleCreateConnectionSuccess(connection);
+ mResponse.handleCreateConnectionSuccess(idMapper, connection);
mResponse = null;
}
}
diff --git a/src/com/android/telecomm/CreateConnectionResponse.java b/src/com/android/telecomm/CreateConnectionResponse.java
index b907e3a..13d1573 100644
--- a/src/com/android/telecomm/CreateConnectionResponse.java
+++ b/src/com/android/telecomm/CreateConnectionResponse.java
@@ -22,6 +22,6 @@
* A callback for providing the result of creating a connection.
*/
interface CreateConnectionResponse {
- void handleCreateConnectionSuccess(ParcelableConnection connection);
+ void handleCreateConnectionSuccess(CallIdMapper idMapper, ParcelableConnection connection);
void handleCreateConnectionFailure(int code, String message);
}
diff --git a/tests/src/com/android/telecomm/testapps/CallNotificationReceiver.java b/tests/src/com/android/telecomm/testapps/CallNotificationReceiver.java
index e941c2d..fb44069 100644
--- a/tests/src/com/android/telecomm/testapps/CallNotificationReceiver.java
+++ b/tests/src/com/android/telecomm/testapps/CallNotificationReceiver.java
@@ -70,7 +70,7 @@
private void sendIncomingCallIntent(Context context, boolean isVideoCall) {
PhoneAccountHandle phoneAccount = new PhoneAccountHandle(
new ComponentName(context, TestConnectionService.class),
- CallServiceNotifier.CALL_PROVIDER_ID);
+ CallServiceNotifier.SIM_SUBSCRIPTION_ID);
// For the purposes of testing, indicate whether the incoming call is a video call by
// stashing an indicator in the EXTRA_INCOMING_CALL_EXTRAS.
diff --git a/tests/src/com/android/telecomm/testapps/TestConnectionManager.java b/tests/src/com/android/telecomm/testapps/TestConnectionManager.java
index 902ace7..95f0718 100644
--- a/tests/src/com/android/telecomm/testapps/TestConnectionManager.java
+++ b/tests/src/com/android/telecomm/testapps/TestConnectionManager.java
@@ -19,28 +19,28 @@
import android.app.PendingIntent;
import android.net.Uri;
import android.telecomm.AudioState;
+import android.telecomm.Conference;
import android.telecomm.Connection;
import android.telecomm.ConnectionRequest;
import android.telecomm.ConnectionService;
import android.telecomm.PhoneAccountHandle;
+import android.telecomm.RemoteConference;
import android.telecomm.RemoteConnection;
import android.telecomm.StatusHints;
import android.util.Log;
-import java.util.Random;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
/**
* Service which acts as a fake ConnectionManager if so configured.
* TODO(santoscordon): Rename all classes in the directory to Dummy* (e.g., DummyConnectionService).
*/
public class TestConnectionManager extends ConnectionService {
- /**
- * Random number generator used to generate phone numbers.
- */
- private Random mRandom = new Random();
-
- private final class TestManagedConnection extends Connection {
- private final RemoteConnection.Listener mProxyListener = new RemoteConnection.Listener() {
+ public final class TestManagedConnection extends Connection {
+ private final RemoteConnection.Listener mRemoteListener = new RemoteConnection.Listener() {
@Override
public void onStateChanged(RemoteConnection connection, int state) {
setState(state);
@@ -103,62 +103,76 @@
@Override
public void onDestroyed(RemoteConnection connection) {
destroy();
+ mManagedConnectionByRemote.remove(mRemote);
+ }
+
+ @Override
+ public void onConferenceableConnectionsChanged(
+ RemoteConnection connect,
+ List<RemoteConnection> conferenceable) {
+ List<Connection> c = new ArrayList<>();
+ for (RemoteConnection remote : conferenceable) {
+ if (mManagedConnectionByRemote.containsKey(remote)) {
+ c.add(mManagedConnectionByRemote.get(remote));
+ }
+ }
+ setConferenceableConnections(c);
}
};
- private final RemoteConnection mRemoteConnection;
+ private final RemoteConnection mRemote;
private final boolean mIsIncoming;
- TestManagedConnection(RemoteConnection remoteConnection, boolean isIncoming) {
- mRemoteConnection = remoteConnection;
+ TestManagedConnection(RemoteConnection remote, boolean isIncoming) {
+ mRemote = remote;
mIsIncoming = isIncoming;
- mRemoteConnection.addListener(mProxyListener);
- setState(mRemoteConnection.getState());
+ mRemote.addListener(mRemoteListener);
+ setState(mRemote.getState());
}
@Override
public void onAbort() {
- mRemoteConnection.abort();
+ mRemote.abort();
}
/** ${inheritDoc} */
@Override
public void onAnswer(int videoState) {
- mRemoteConnection.answer(videoState);
+ mRemote.answer(videoState);
}
/** ${inheritDoc} */
@Override
public void onDisconnect() {
- mRemoteConnection.disconnect();
+ mRemote.disconnect();
}
@Override
public void onPlayDtmfTone(char c) {
- mRemoteConnection.playDtmfTone(c);
+ mRemote.playDtmfTone(c);
}
/** ${inheritDoc} */
@Override
public void onHold() {
- mRemoteConnection.hold();
+ mRemote.hold();
}
/** ${inheritDoc} */
@Override
public void onReject() {
- mRemoteConnection.reject();
+ mRemote.reject();
}
/** ${inheritDoc} */
@Override
public void onUnhold() {
- mRemoteConnection.unhold();
+ mRemote.unhold();
}
@Override
public void onSetAudioState(AudioState state) {
- mRemoteConnection.setAudioState(state);
+ mRemote.setAudioState(state);
}
private void setState(int state) {
@@ -180,29 +194,125 @@
}
}
+ public final class TestManagedConference extends Conference {
+ private final RemoteConference.Listener mRemoteListener = new RemoteConference.Listener() {
+ @Override
+ public void onStateChanged(RemoteConference conference, int oldState, int newState) {
+ switch (newState) {
+ case Connection.STATE_DISCONNECTED:
+ // See onDisconnected below
+ break;
+ case Connection.STATE_HOLDING:
+ setOnHold();
+ break;
+ case Connection.STATE_ACTIVE:
+ setActive();
+ break;
+ default:
+ log("unrecognized state for Conference: " + newState);
+ break;
+ }
+ }
+
+ @Override
+ public void onDisconnected(RemoteConference conference, int cause, String message) {
+ setDisconnected(cause, message);
+ }
+
+ @Override
+ public void onConnectionAdded(
+ RemoteConference conference,
+ RemoteConnection connection) {
+ TestManagedConnection c = mManagedConnectionByRemote.get(connection);
+ if (c == null) {
+ log("onConnectionAdded cannot find remote connection: " + connection);
+ } else {
+ addConnection(c);
+ }
+ }
+
+ @Override
+ public void onConnectionRemoved(
+ RemoteConference conference,
+ RemoteConnection connection) {
+ TestManagedConnection c = mManagedConnectionByRemote.get(connection);
+ if (c == null) {
+ log("onConnectionRemoved cannot find remote connection: " + connection);
+ } else {
+ removeConnection(c);
+ }
+ }
+
+ @Override
+ public void onCapabilitiesChanged(RemoteConference conference, int capabilities) {
+ setCapabilities(capabilities);
+ }
+
+ @Override
+ public void onDestroyed(RemoteConference conference) {
+ destroy();
+ mRemote.removeListener(mRemoteListener);
+ mManagedConferenceByRemote.remove(mRemote);
+ }
+ };
+
+ private final RemoteConference mRemote;
+
+ public TestManagedConference(RemoteConference remote) {
+ super(null);
+ mRemote = remote;
+ remote.addListener(mRemoteListener);
+ setActive();
+ for (RemoteConnection r : remote.getConnections()) {
+ TestManagedConnection c = mManagedConnectionByRemote.get(r);
+ if (c != null) {
+ addConnection(c);
+ }
+ }
+ }
+ }
+
private static void log(String msg) {
Log.w("telecomtestcs", "[TestConnectionManager] " + msg);
}
+ private final Map<RemoteConference, TestManagedConference> mManagedConferenceByRemote
+ = new HashMap<>();
+ private final Map<RemoteConnection, TestManagedConnection> mManagedConnectionByRemote
+ = new HashMap<>();
+
@Override
public Connection onCreateOutgoingConnection(
PhoneAccountHandle connectionManagerAccount,
final ConnectionRequest request) {
- return new TestManagedConnection(
- createRemoteOutgoingConnection(
- request.getAccountHandle(),
- request),
- false);
+ return makeConnection(request, false);
}
@Override
public Connection onCreateIncomingConnection(
PhoneAccountHandle connectionManagerAccount,
final ConnectionRequest request) {
- return new TestManagedConnection(
- createRemoteIncomingConnection(
- request.getAccountHandle(),
- request),
- true);
+ return makeConnection(request, true);
+ }
+
+ @Override
+ public void onConference(Connection a, Connection b) {
+ conferenceRemoteConnections(
+ ((TestManagedConnection) a).mRemote,
+ ((TestManagedConnection) b).mRemote);
+ }
+
+ @Override
+ public void onRemoteConferenceAdded(RemoteConference remoteConference) {
+ addConference(new TestManagedConference(remoteConference));
+ }
+
+ private Connection makeConnection(ConnectionRequest request, boolean incoming) {
+ RemoteConnection remote = incoming
+ ? createRemoteIncomingConnection(request.getAccountHandle(), request)
+ : createRemoteOutgoingConnection(request.getAccountHandle(), request);
+ TestManagedConnection local = new TestManagedConnection(remote, false);
+ mManagedConnectionByRemote.put(remote, local);
+ return local;
}
}
diff --git a/tests/src/com/android/telecomm/testapps/TestConnectionService.java b/tests/src/com/android/telecomm/testapps/TestConnectionService.java
index 09a8929..c50e7ab 100644
--- a/tests/src/com/android/telecomm/testapps/TestConnectionService.java
+++ b/tests/src/com/android/telecomm/testapps/TestConnectionService.java
Binary files differ