blob: b82ed05eb312f70b638b486a73ecc9d38fffb9eb [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.telecom.cts;
import static android.telecom.cts.TestUtils.*;
import android.telecom.Call;
import android.telecom.Connection;
import android.telecom.ConnectionRequest;
import android.telecom.PhoneAccountHandle;
import android.telecom.RemoteConference;
import android.telecom.RemoteConnection;
import java.util.ArrayList;
import java.util.List;
/**
* Extended suite of tests that use {@link CtsConnectionService} and {@link MockInCallService} to
* verify the functionality of Remote Conferences.
* We make 2 connections on the {@link CtsConnectionService} & we create 2 connections on the
* {@link CtsRemoteConnectionService} via the {@link RemoteConnection} object. We store this
* corresponding RemoteConnection object on the connections to plumb the modifications on
* the connections in {@link CtsConnectionService} to the connections on
* {@link CtsRemoteConnectionService}. Then we create a remote conference on the
* {@link CtsRemoteConnectionService} and control it via the {@link RemoteConference}
* object. The onConference method on the managerConnectionService will initiate a remote conference
* creation on the remoteConnectionService and once that is completed, we create a local conference
* on the managerConnectionService.
*/
public class RemoteConferenceTest extends BaseRemoteTelecomTest {
public static final int CONF_CAPABILITIES = Connection.CAPABILITY_SEPARATE_FROM_CONFERENCE |
Connection.CAPABILITY_DISCONNECT_FROM_CONFERENCE | Connection.CAPABILITY_HOLD |
Connection.CAPABILITY_MERGE_CONFERENCE | Connection.CAPABILITY_SWAP_CONFERENCE;
MockConnection mConnection1, mConnection2;
MockConnection mRemoteConnection1, mRemoteConnection2;
Call mCall1, mCall2;
MockConference mConference, mRemoteConference;
RemoteConference mRemoteConferenceObject;
@Override
protected void setUp() throws Exception {
super.setUp();
mContext = getInstrumentation().getContext();
if (shouldTestTelecom(mContext)) {
addRemoteConferenceCall();
verifyRemoteConferenceObject(mRemoteConferenceObject, mRemoteConference, mConference);
}
}
public void testRemoteConferenceCreate() {
if (!shouldTestTelecom(mContext)) {
return;
}
final Call confCall = mInCallCallbacks.getService().getLastConferenceCall();
assertCallState(confCall, Call.STATE_ACTIVE);
if (mCall1.getParent() != confCall || mCall2.getParent() != confCall) {
fail("The 2 participating calls should contain the conference call as its parent");
}
if (!(confCall.getChildren().contains(mCall1) && confCall.getChildren().contains(mCall2))) {
fail("The conference call should contain the 2 participating calls as its children");
}
assertConnectionState(mConnection1, Connection.STATE_ACTIVE);
assertConnectionState(mConnection2, Connection.STATE_ACTIVE);
assertConnectionState(mRemoteConnection1, Connection.STATE_ACTIVE);
assertConnectionState(mRemoteConnection2, Connection.STATE_ACTIVE);
assertConferenceState(mConference, Connection.STATE_ACTIVE);
assertConferenceState(mRemoteConference, Connection.STATE_ACTIVE);
assertRemoteConferenceState(mRemoteConferenceObject, Connection.STATE_ACTIVE);
}
public void testRemoteConferenceSplit() {
if (!shouldTestTelecom(mContext)) {
return;
}
final Call confCall = mInCallCallbacks.getService().getLastConferenceCall();
assertCallState(confCall, Call.STATE_ACTIVE);
if (!(mCall1.getParent() == confCall) && (confCall.getChildren().contains(mCall1))) {
fail("Call 1 not conferenced");
}
assertTrue(mConference.getConnections().contains(mConnection1));
assertTrue(mRemoteConference.getConnections().contains(mRemoteConnection1));
splitFromConferenceCall(mCall1);
if ((mCall1.getParent() == confCall) || (confCall.getChildren().contains(mCall1))) {
fail("Call 1 should not be still conferenced");
}
assertFalse(mConference.getConnections().contains(mConnection1));
assertFalse(mRemoteConference.getConnections().contains(mRemoteConnection1));
}
public void testRemoteConferenceHoldAndUnhold() {
if (!shouldTestTelecom(mContext)) {
return;
}
final Call confCall = mInCallCallbacks.getService().getLastConferenceCall();
assertCallState(confCall, Call.STATE_ACTIVE);
confCall.hold();
assertCallState(confCall, Call.STATE_HOLDING);
assertCallState(mCall1, Call.STATE_HOLDING);
assertCallState(mCall2, Call.STATE_HOLDING);
assertConnectionState(mConnection1, Connection.STATE_HOLDING);
assertConnectionState(mConnection2, Connection.STATE_HOLDING);
assertConnectionState(mRemoteConnection1, Connection.STATE_HOLDING);
assertConnectionState(mRemoteConnection2, Connection.STATE_HOLDING);
assertConferenceState(mConference, Connection.STATE_HOLDING);
assertConferenceState(mRemoteConference, Connection.STATE_HOLDING);
assertRemoteConferenceState(mRemoteConferenceObject, Connection.STATE_HOLDING);
confCall.unhold();
assertCallState(confCall, Call.STATE_ACTIVE);
assertCallState(mCall1, Call.STATE_ACTIVE);
assertCallState(mCall2, Call.STATE_ACTIVE);
assertConnectionState(mConnection1, Connection.STATE_ACTIVE);
assertConnectionState(mConnection2, Connection.STATE_ACTIVE);
assertConnectionState(mRemoteConnection1, Connection.STATE_ACTIVE);
assertConnectionState(mRemoteConnection2, Connection.STATE_ACTIVE);
assertConferenceState(mConference, Connection.STATE_ACTIVE);
assertConferenceState(mRemoteConference, Connection.STATE_ACTIVE);
assertRemoteConferenceState(mRemoteConferenceObject, Connection.STATE_ACTIVE);
}
public void testRemoteConferenceMergeAndSwap() {
if (!shouldTestTelecom(mContext)) {
return;
}
final Call confCall = mInCallCallbacks.getService().getLastConferenceCall();
assertCallState(confCall, Call.STATE_ACTIVE);
confCall.mergeConference();
assertCallDisplayName(mCall1, TestUtils.MERGE_CALLER_NAME);
assertCallDisplayName(mCall2, TestUtils.MERGE_CALLER_NAME);
assertConnectionCallDisplayName(mConnection1,
TestUtils.MERGE_CALLER_NAME);
assertConnectionCallDisplayName(mConnection2,
TestUtils.MERGE_CALLER_NAME);
assertConnectionCallDisplayName(mRemoteConnection1,
TestUtils.MERGE_CALLER_NAME);
assertConnectionCallDisplayName(mRemoteConnection2,
TestUtils.MERGE_CALLER_NAME);
confCall.swapConference();
assertCallDisplayName(mCall1, TestUtils.SWAP_CALLER_NAME);
assertCallDisplayName(mCall2, TestUtils.SWAP_CALLER_NAME);
assertConnectionCallDisplayName(mConnection1,
TestUtils.SWAP_CALLER_NAME);
assertConnectionCallDisplayName(mConnection2,
TestUtils.SWAP_CALLER_NAME);
assertConnectionCallDisplayName(mRemoteConnection1,
TestUtils.SWAP_CALLER_NAME);
assertConnectionCallDisplayName(mRemoteConnection2,
TestUtils.SWAP_CALLER_NAME);
}
private void verifyRemoteConferenceObject(RemoteConference remoteConferenceObject,
MockConference remoteConference, MockConference conference) {
assertEquals(remoteConference.getConnectionCapabilities(),
remoteConferenceObject.getConnectionCapabilities());
assertTrue(remoteConferenceObject.getConferenceableConnections().isEmpty());
List<RemoteConnection> remoteConnections = new ArrayList<>();
for (Connection c: conference.getConnections()) {
remoteConnections.add(((MockConnection)c).getRemoteConnection());
}
assertEquals(remoteConnections, remoteConferenceObject.getConnections());
assertEquals(remoteConference.getDisconnectCause(), remoteConferenceObject.getDisconnectCause());
assertEquals(remoteConference.getExtras(), remoteConferenceObject.getExtras());
}
private void addRemoteConnectionOutgoingCalls() {
try {
MockConnectionService managerConnectionService = new MockConnectionService() {
@Override
public Connection onCreateOutgoingConnection(
PhoneAccountHandle connectionManagerPhoneAccount,
ConnectionRequest request) {
MockConnection connection = (MockConnection)super.onCreateOutgoingConnection(
connectionManagerPhoneAccount, request);
ConnectionRequest remoteRequest = new ConnectionRequest(
TEST_REMOTE_PHONE_ACCOUNT_HANDLE,
request.getAddress(),
request.getExtras());
RemoteConnection remoteConnection =
CtsConnectionService.createRemoteOutgoingConnectionToTelecom(
TEST_REMOTE_PHONE_ACCOUNT_HANDLE, remoteRequest);
connection.setRemoteConnection(remoteConnection);
// Modify the connection object created with local values.
int capabilities = connection.getConnectionCapabilities();
connection.setConnectionCapabilities(capabilities | CONF_CAPABILITIES);
return connection;
}
@Override
public void onConference(Connection connection1, Connection connection2) {
/**
* Fetch the corresponding remoteConnection objects and instantiate a remote
* conference creation on the remoteConnectionService instead of this
* managerConnectionService.
*/
RemoteConnection remoteConnection1 =
((MockConnection)connection1).getRemoteConnection();
RemoteConnection remoteConnection2 =
((MockConnection)connection2).getRemoteConnection();
if (remoteConnection1.getConference() == null &&
remoteConnection2.getConference() == null) {
conferenceRemoteConnections(remoteConnection1, remoteConnection2);
}
}
@Override
public void onRemoteConferenceAdded(RemoteConference remoteConference) {
/**
* Now that the remote conference has been created,
* let's create a local conference on this ConnectionService.
*/
MockConference conference = new MockConference(mConnection1, mConnection2);
conference.setRemoteConference(remoteConference);
CtsConnectionService.addConferenceToTelecom(conference);
conferences.add(conference);
lock.release();
}
};
/**
* We want the conference to be instantiated on the remoteConnectionService registered
* with telecom.
*/
MockConnectionService remoteConnectionService= new MockConnectionService() {
@Override
public Connection onCreateOutgoingConnection(
PhoneAccountHandle connectionManagerPhoneAccount,
ConnectionRequest request) {
Connection connection = super.onCreateOutgoingConnection(
connectionManagerPhoneAccount,
request);
// Modify the connection object created with local values.
int capabilities = connection.getConnectionCapabilities();
connection.setConnectionCapabilities(capabilities | CONF_CAPABILITIES);
return connection;
}
@Override
public void onConference(Connection connection1, Connection connection2) {
// Make sure that these connections are already not conferenced.
if (connection1.getConference() == null &&
connection2.getConference() == null) {
MockConference conference = new MockConference(
(MockConnection)connection1, (MockConnection)connection2);
CtsRemoteConnectionService.addConferenceToTelecom(conference);
conferences.add(conference);
lock.release();
}
}
};
setupConnectionServices(managerConnectionService, remoteConnectionService,
FLAG_REGISTER | FLAG_ENABLE);
} catch(Exception e) {
fail("Error in setting up the connection services");
}
placeAndVerifyCall();
mConnection1 = verifyConnectionForOutgoingCall(0);
mRemoteConnection1 = verifyConnectionForOutgoingCallOnRemoteCS(0);
mCall1 = mInCallCallbacks.getService().getLastCall();
assertCallState(mCall1, Call.STATE_DIALING);
mConnection1.setActive();
mRemoteConnection1.setActive();
assertCallState(mCall1, Call.STATE_ACTIVE);
placeAndVerifyCall();
mConnection2 = verifyConnectionForOutgoingCall(1);
mRemoteConnection2 = verifyConnectionForOutgoingCallOnRemoteCS(1);
mCall2 = mInCallCallbacks.getService().getLastCall();
assertCallState(mCall2, Call.STATE_DIALING);
mConnection2.setActive();
mRemoteConnection2.setActive();
assertCallState(mCall2, Call.STATE_ACTIVE);
setAndVerifyConferenceablesForOutgoingConnection(0);
setAndVerifyConferenceablesForOutgoingConnection(1);
setAndVerifyConferenceablesForOutgoingConnectionOnRemoteCS(0);
setAndVerifyConferenceablesForOutgoingConnectionOnRemoteCS(1);
}
private void addRemoteConferenceCall() {
addRemoteConnectionOutgoingCalls();
/**
* We've 2 connections on the local connectionService which have 2 corresponding
* connections on the remoteConnectionService controlled via 2 RemoteConnection objects
* on the connectionService. We now create a conference on the local two connections
* which triggers a creation of conference on the remoteConnectionService via the
* RemoteConference object.
*/
addConferenceCall(mCall1, mCall2);
mConference = verifyConferenceForOutgoingCall();
mRemoteConference = verifyConferenceForOutgoingCallOnRemoteCS();
mRemoteConferenceObject = mConference.getRemoteConference();
mRemoteConnection1 = (MockConnection)mRemoteConference.getConnections().get(0);
mRemoteConnection2 = (MockConnection)mRemoteConference.getConnections().get(1);
}
}