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.assertTrue;
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 import java.util.Collections;
33 
34 /**
35  * This is the official ConnectionService for Telecom's CTS App. Since telecom requires that a
36  * CS be registered in the AndroidManifest.xml file, we have to have a single implementation
37  * of a CS and this is it. To test specific CS behavior, tests will implement their own CS and
38  * tell CtsConnectionService to forward any method invocations to that test's implementation.
39  * This is set up using {@link #setUp} and should be cleaned up before the end of the test using
40  * {@link #tearDown}.
41  *
42  * sConnectionService: Contains the connection service object provided by the current test in
43  *                     progress. We use this object to forward any communication received from the
44  *                     Telecom framework to the test connection service.
45  * sTelecomConnectionService: Contains the connection service object registered to the Telecom
46  *                            framework. We use this object to forward any communication from the
47  *                            test connection service to the Telecom framework.
48  *
49  */
50 public class CtsConnectionService extends ConnectionService {
51     private static String LOG_TAG = "CtsConnectionService";
52     // This is the connection service implemented by the test
53     private static ConnectionService sConnectionService;
54     // This is the connection service registered with Telecom
55     private static ConnectionService sTelecomConnectionService;
56     private static boolean mIsServiceBound = false;
57 
CtsConnectionService()58     public CtsConnectionService() throws Exception {
59         super();
60         sTelecomConnectionService = this;
61         // Cant override the onBind method for ConnectionService, so reset it here.
62         mIsServiceBound = true;
63     }
64 
65     // ConnectionService used by default as a fallback if no connection service is specified
66     // during test setup.
67     private static ConnectionService mMockConnectionService = new MockConnectionService();
68 
69     /**
70      * Used to control whether the {@link MockVideoProvider} will be created when connections are
71      * created.  Used by {@link VideoCallTest#testVideoCallDelayProvider()} to test scenario where
72      * the {@link MockVideoProvider} is not created immediately when the Connection is created.
73      */
74     private static Object sLock = new Object();
75 
setUp(PhoneAccountHandle phoneAccountHandle, ConnectionService connectionService)76     public static void setUp(PhoneAccountHandle phoneAccountHandle,
77             ConnectionService connectionService) throws Exception {
78         synchronized(sLock) {
79             if (sConnectionService != null) {
80                 throw new Exception("Mock ConnectionService exists.  Failed to call tearDown().");
81             }
82             sConnectionService = connectionService;
83         }
84     }
85 
tearDown()86     public static void tearDown() {
87         synchronized(sLock) {
88             sTelecomConnectionService = null;
89             sConnectionService = null;
90         }
91     }
92 
93     @Override
onCreateOutgoingConnection(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request)94     public Connection onCreateOutgoingConnection(PhoneAccountHandle connectionManagerPhoneAccount,
95             ConnectionRequest request) {
96         synchronized(sLock) {
97             if (sConnectionService != null) {
98                 return sConnectionService.onCreateOutgoingConnection(
99                         connectionManagerPhoneAccount, request);
100             } else {
101                 return mMockConnectionService.onCreateOutgoingConnection(
102                         connectionManagerPhoneAccount, request);
103             }
104         }
105     }
106 
107     @Override
onCreateIncomingConnection(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request)108     public Connection onCreateIncomingConnection(PhoneAccountHandle connectionManagerPhoneAccount,
109             ConnectionRequest request) {
110         synchronized(sLock) {
111             if (sConnectionService != null) {
112                 return sConnectionService.onCreateIncomingConnection(
113                         connectionManagerPhoneAccount, request);
114             } else {
115                 return mMockConnectionService.onCreateIncomingConnection(
116                         connectionManagerPhoneAccount, request);
117             }
118         }
119     }
120 
121     @Override
onConference(Connection connection1, Connection connection2)122     public void onConference(Connection connection1, Connection connection2) {
123         synchronized(sLock) {
124             if (sConnectionService != null) {
125                 sConnectionService.onConference(connection1, connection2);
126             } else {
127                 mMockConnectionService.onConference(connection1, connection2);
128             }
129         }
130     }
131 
132     @Override
onRemoteExistingConnectionAdded(RemoteConnection connection)133     public void onRemoteExistingConnectionAdded(RemoteConnection connection) {
134         synchronized(sLock) {
135             if (sConnectionService != null) {
136                 sConnectionService.onRemoteExistingConnectionAdded(connection);
137             } else {
138                 mMockConnectionService.onRemoteExistingConnectionAdded(connection);
139             }
140         }
141     }
142 
addConferenceToTelecom(Conference conference)143     public static void addConferenceToTelecom(Conference conference) {
144         synchronized(sLock) {
145             sTelecomConnectionService.addConference(conference);
146         }
147     }
148 
addExistingConnectionToTelecom( PhoneAccountHandle phoneAccountHandle, Connection connection)149     public static void addExistingConnectionToTelecom(
150             PhoneAccountHandle phoneAccountHandle, Connection connection) {
151         synchronized(sLock) {
152             sTelecomConnectionService.addExistingConnection(phoneAccountHandle, connection);
153         }
154     }
155 
getAllConnectionsFromTelecom()156     public static Collection<Connection> getAllConnectionsFromTelecom() {
157         synchronized(sLock) {
158             if (sTelecomConnectionService == null) {
159                 return Collections.EMPTY_LIST;
160             }
161             return sTelecomConnectionService.getAllConnections();
162         }
163     }
164 
createRemoteOutgoingConnectionToTelecom( PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request)165     public static RemoteConnection createRemoteOutgoingConnectionToTelecom(
166             PhoneAccountHandle connectionManagerPhoneAccount,
167             ConnectionRequest request) {
168         synchronized(sLock) {
169             return sTelecomConnectionService.createRemoteOutgoingConnection(
170                     connectionManagerPhoneAccount, request);
171         }
172     }
173 
createRemoteIncomingConnectionToTelecom( PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request)174     public static RemoteConnection createRemoteIncomingConnectionToTelecom(
175             PhoneAccountHandle connectionManagerPhoneAccount,
176             ConnectionRequest request) {
177         synchronized(sLock) {
178             return sTelecomConnectionService.createRemoteIncomingConnection(
179                     connectionManagerPhoneAccount, request);
180         }
181     }
182 
183     @Override
onRemoteConferenceAdded(RemoteConference conference)184     public void onRemoteConferenceAdded(RemoteConference conference) {
185         synchronized(sLock) {
186             if (sConnectionService != null) {
187                 sConnectionService.onRemoteConferenceAdded(conference);
188             } else {
189                 mMockConnectionService.onRemoteConferenceAdded(conference);
190             }
191         }
192     }
193 
194     @Override
onUnbind(Intent intent)195     public boolean onUnbind(Intent intent) {
196         Log.i(LOG_TAG, "Service has been unbound");
197         assertTrue(mIsServiceBound);
198         mIsServiceBound = false;
199         return super.onUnbind(intent);
200     }
201 
isServiceBound()202     public static boolean isServiceBound() {
203         return mIsServiceBound;
204     }
205 
isServiceRegisteredToTelecom()206     public static boolean isServiceRegisteredToTelecom() {
207         return sTelecomConnectionService != null;
208     }
209 }
210