1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.telecom.cts;
18 
19 import static org.junit.Assert.assertFalse;
20 
21 import android.content.Intent;
22 import android.telecom.Conference;
23 import android.telecom.Connection;
24 import android.telecom.ConnectionRequest;
25 import android.telecom.ConnectionService;
26 import android.telecom.PhoneAccountHandle;
27 import android.telecom.RemoteConference;
28 import android.telecom.RemoteConnection;
29 import android.util.Log;
30 
31 import java.util.Collection;
32 
33 /**
34  * This is the official ConnectionService for Telecom's CTS App. Since telecom requires that a
35  * CS be registered in the AndroidManifest.xml file, we have to have a single implementation
36  * of a CS and this is it. To test specific CS behavior, tests will implement their own CS and
37  * tell CtsConnectionService to forward any method invocations to that test's implementation.
38  * This is set up using {@link #setUp} and should be cleaned up before the end of the test using
39  * {@link #tearDown}.
40  *
41  * sConnectionService: Contains the connection service object provided by the current test in
42  *                     progress. We use this object to forward any communication received from the
43  *                     Telecom framework to the test connection service.
44  * sTelecomConnectionService: Contains the connection service object registered to the Telecom
45  *                            framework. We use this object to forward any communication from the
46  *                            test connection service to the Telecom framework.
47  *
48  */
49 public class CtsConnectionService extends ConnectionService {
50     private static String LOG_TAG = "CtsConnectionService";
51     // This is the connection service implemented by the test
52     private static ConnectionService sConnectionService;
53     // This is the connection service registered with Telecom
54     private static ConnectionService sTelecomConnectionService;
55     private static boolean mIsServiceUnbound;
56 
CtsConnectionService()57     public CtsConnectionService() throws Exception {
58         super();
59         sTelecomConnectionService = this;
60     }
61 
62     // ConnectionService used by default as a fallback if no connection service is specified
63     // during test setup.
64     private static ConnectionService mMockConnectionService = new MockConnectionService();
65 
66     /**
67      * Used to control whether the {@link MockVideoProvider} will be created when connections are
68      * created.  Used by {@link VideoCallTest#testVideoCallDelayProvider()} to test scenario where
69      * the {@link MockVideoProvider} is not created immediately when the Connection is created.
70      */
71     private static Object sLock = new Object();
72 
setUp(PhoneAccountHandle phoneAccountHandle, ConnectionService connectionService)73     public static void setUp(PhoneAccountHandle phoneAccountHandle,
74             ConnectionService connectionService) throws Exception {
75         synchronized(sLock) {
76             if (sConnectionService != null) {
77                 throw new Exception("Mock ConnectionService exists.  Failed to call tearDown().");
78             }
79             sConnectionService = connectionService;
80             // Cant override the onBind method for ConnectionService, so reset it here.
81             mIsServiceUnbound = false;
82         }
83     }
84 
tearDown()85     public static void tearDown() {
86         synchronized(sLock) {
87             sConnectionService = null;
88         }
89     }
90 
91     @Override
onCreateOutgoingConnection(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request)92     public Connection onCreateOutgoingConnection(PhoneAccountHandle connectionManagerPhoneAccount,
93             ConnectionRequest request) {
94         synchronized(sLock) {
95             if (sConnectionService != null) {
96                 return sConnectionService.onCreateOutgoingConnection(
97                         connectionManagerPhoneAccount, request);
98             } else {
99                 return mMockConnectionService.onCreateOutgoingConnection(
100                         connectionManagerPhoneAccount, request);
101             }
102         }
103     }
104 
105     @Override
onCreateIncomingConnection(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request)106     public Connection onCreateIncomingConnection(PhoneAccountHandle connectionManagerPhoneAccount,
107             ConnectionRequest request) {
108         synchronized(sLock) {
109             if (sConnectionService != null) {
110                 return sConnectionService.onCreateIncomingConnection(
111                         connectionManagerPhoneAccount, request);
112             } else {
113                 return mMockConnectionService.onCreateIncomingConnection(
114                         connectionManagerPhoneAccount, request);
115             }
116         }
117     }
118 
119     @Override
onConference(Connection connection1, Connection connection2)120     public void onConference(Connection connection1, Connection connection2) {
121         synchronized(sLock) {
122             if (sConnectionService != null) {
123                 sConnectionService.onConference(connection1, connection2);
124             } else {
125                 mMockConnectionService.onConference(connection1, connection2);
126             }
127         }
128     }
129 
130     @Override
onRemoteExistingConnectionAdded(RemoteConnection connection)131     public void onRemoteExistingConnectionAdded(RemoteConnection connection) {
132         synchronized(sLock) {
133             if (sConnectionService != null) {
134                 sConnectionService.onRemoteExistingConnectionAdded(connection);
135             } else {
136                 mMockConnectionService.onRemoteExistingConnectionAdded(connection);
137             }
138         }
139     }
140 
addConferenceToTelecom(Conference conference)141     public static void addConferenceToTelecom(Conference conference) {
142         synchronized(sLock) {
143             sTelecomConnectionService.addConference(conference);
144         }
145     }
146 
addExistingConnectionToTelecom( PhoneAccountHandle phoneAccountHandle, Connection connection)147     public static void addExistingConnectionToTelecom(
148             PhoneAccountHandle phoneAccountHandle, Connection connection) {
149         synchronized(sLock) {
150             sTelecomConnectionService.addExistingConnection(phoneAccountHandle, connection);
151         }
152     }
153 
getAllConnectionsFromTelecom()154     public static Collection<Connection> getAllConnectionsFromTelecom() {
155         synchronized(sLock) {
156             return sTelecomConnectionService.getAllConnections();
157         }
158     }
159 
createRemoteOutgoingConnectionToTelecom( PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request)160     public static RemoteConnection createRemoteOutgoingConnectionToTelecom(
161             PhoneAccountHandle connectionManagerPhoneAccount,
162             ConnectionRequest request) {
163         synchronized(sLock) {
164             return sTelecomConnectionService.createRemoteOutgoingConnection(
165                     connectionManagerPhoneAccount, request);
166         }
167     }
168 
createRemoteIncomingConnectionToTelecom( PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request)169     public static RemoteConnection createRemoteIncomingConnectionToTelecom(
170             PhoneAccountHandle connectionManagerPhoneAccount,
171             ConnectionRequest request) {
172         synchronized(sLock) {
173             return sTelecomConnectionService.createRemoteIncomingConnection(
174                     connectionManagerPhoneAccount, request);
175         }
176     }
177 
178     @Override
onRemoteConferenceAdded(RemoteConference conference)179     public void onRemoteConferenceAdded(RemoteConference conference) {
180         synchronized(sLock) {
181             if (sConnectionService != null) {
182                 sConnectionService.onRemoteConferenceAdded(conference);
183             } else {
184                 mMockConnectionService.onRemoteConferenceAdded(conference);
185             }
186         }
187     }
188 
189     @Override
onUnbind(Intent intent)190     public boolean onUnbind(Intent intent) {
191         Log.i(LOG_TAG, "Service unbounded");
192         assertFalse(mIsServiceUnbound);
193         mIsServiceUnbound = true;
194         return super.onUnbind(intent);
195     }
196 
isServiceUnbound()197     public static boolean isServiceUnbound() {
198         return mIsServiceUnbound;
199     }
200 }
201