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 android.telecom.cts.TestUtils.shouldTestTelecom;
20 
21 import android.net.Uri;
22 import android.os.Build;
23 import android.os.Bundle;
24 import android.telecom.Connection;
25 import android.telecom.DisconnectCause;
26 import android.telecom.StatusHints;
27 import android.telecom.TelecomManager;
28 import android.test.AndroidTestCase;
29 
30 import java.util.concurrent.Semaphore;
31 import java.util.concurrent.TimeUnit;
32 
33 public class ConnectionTest extends AndroidTestCase {
34 
testStateCallbacks()35     public void testStateCallbacks() {
36         if (!shouldTestTelecom(getContext())) {
37             return;
38         }
39 
40         final Semaphore lock = new Semaphore(0);
41         Connection connection = createConnection(lock);
42 
43         waitForStateChange(lock);
44         assertEquals(Connection.STATE_NEW, connection.getState());
45 
46         connection.setInitializing();
47         waitForStateChange(lock);
48         assertEquals(Connection.STATE_INITIALIZING, connection.getState());
49 
50         connection.setInitialized();
51         waitForStateChange(lock);
52         assertEquals(Connection.STATE_NEW, connection.getState());
53 
54         connection.setRinging();
55         waitForStateChange(lock);
56         assertEquals(Connection.STATE_RINGING, connection.getState());
57 
58         connection.setDialing();
59         waitForStateChange(lock);
60         assertEquals(Connection.STATE_DIALING, connection.getState());
61 
62         connection.setActive();
63         waitForStateChange(lock);
64         assertEquals(Connection.STATE_ACTIVE, connection.getState());
65 
66         connection.setOnHold();
67         waitForStateChange(lock);
68         assertEquals(Connection.STATE_HOLDING, connection.getState());
69 
70         connection.setDisconnected(
71                 new DisconnectCause(DisconnectCause.LOCAL, "Test call"));
72         waitForStateChange(lock);
73         assertEquals(Connection.STATE_DISCONNECTED, connection.getState());
74 
75         connection.setRinging();
76         waitForStateChange(lock);
77         assertEquals("Connection should not move out of STATE_DISCONNECTED.",
78                 Connection.STATE_DISCONNECTED, connection.getState());
79     }
80 
81     /**
82      * {@link UnsupportedOperationException} is only thrown in L MR1+.
83      */
testFailedState()84     public void testFailedState() {
85         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {
86             return;
87         }
88         Connection connection = Connection.createFailedConnection(
89                 new DisconnectCause(DisconnectCause.LOCAL, "Test call"));
90         assertEquals(Connection.STATE_DISCONNECTED, connection.getState());
91 
92         try {
93             connection.setRinging();
94         } catch (UnsupportedOperationException e) {
95             return;
96         }
97         fail("Connection should not move out of STATE_DISCONNECTED");
98     }
99 
100     /**
101      * {@link UnsupportedOperationException} is only thrown in L MR1+.
102      */
testCanceledState()103     public void testCanceledState() {
104         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {
105             return;
106         }
107         Connection connection = Connection.createCanceledConnection();
108         assertEquals(Connection.STATE_DISCONNECTED, connection.getState());
109 
110         try {
111             connection.setDialing();
112         } catch (UnsupportedOperationException e) {
113             return;
114         }
115         fail("Connection should not move out of STATE_DISCONNECTED");
116     }
117 
testSetAndGetCallerDisplayName()118     public void testSetAndGetCallerDisplayName() {
119         if (!shouldTestTelecom(getContext())) {
120             return;
121         }
122 
123         final Semaphore lock = new Semaphore(0);
124         Connection connection = createConnection(lock);
125         waitForStateChange(lock);
126 
127         connection.setCallerDisplayName("Test User", TelecomManager.PRESENTATION_ALLOWED);
128         assertEquals("Test User", connection.getCallerDisplayName());
129         assertEquals(TelecomManager.PRESENTATION_ALLOWED,
130                 connection.getCallerDisplayNamePresentation());
131     }
132 
testSetAndGetAddress()133     public void testSetAndGetAddress() {
134         if (!shouldTestTelecom(getContext())) {
135             return;
136         }
137 
138         final Semaphore lock = new Semaphore(0);
139         Connection connection = createConnection(lock);
140         waitForStateChange(lock);
141 
142         final Uri address = Uri.fromParts("tel", "1234567", null);
143         connection.setAddress(address, TelecomManager.PRESENTATION_UNKNOWN);
144         assertEquals(address, connection.getAddress());
145         assertEquals(TelecomManager.PRESENTATION_UNKNOWN, connection.getAddressPresentation());
146     }
147 
testSetAndGetConnectionCapabilities()148     public void testSetAndGetConnectionCapabilities() {
149         if (!shouldTestTelecom(getContext())) {
150             return;
151         }
152 
153         final Semaphore lock = new Semaphore(0);
154         Connection connection = createConnection(lock);
155         waitForStateChange(lock);
156 
157         final int capabilities = Connection.CAPABILITY_HOLD | Connection.CAPABILITY_CAN_PAUSE_VIDEO
158                 | Connection.CAPABILITY_MANAGE_CONFERENCE | Connection.CAPABILITY_RESPOND_VIA_TEXT;
159 
160         connection.setConnectionCapabilities(capabilities);
161 
162         assertEquals(capabilities, connection.getConnectionCapabilities());
163     }
164 
testSetAndGetDisconnectCause()165     public void testSetAndGetDisconnectCause() {
166         if (!shouldTestTelecom(getContext())) {
167             return;
168         }
169 
170         final Semaphore lock = new Semaphore(0);
171         Connection connection = createConnection(lock);
172         waitForStateChange(lock);
173         assertEquals(Connection.STATE_NEW, connection.getState());
174 
175         final DisconnectCause disconnectCause = new DisconnectCause(DisconnectCause.REJECTED,
176                 "No friends", "No friends to talk to", "No friends to talk to");
177 
178         connection.setDisconnected(disconnectCause);
179 
180         assertEquals(Connection.STATE_DISCONNECTED, connection.getState());
181         assertEquals(disconnectCause, connection.getDisconnectCause());
182     }
183 
testSetAndGetAudioModeIsVoip()184     public void testSetAndGetAudioModeIsVoip() {
185         if (!shouldTestTelecom(getContext())) {
186             return;
187         }
188 
189         final Semaphore lock = new Semaphore(0);
190         Connection connection = createConnection(lock);
191         waitForStateChange(lock);
192 
193         assertFalse(connection.getAudioModeIsVoip());
194         connection.setAudioModeIsVoip(true);
195         assertTrue(connection.getAudioModeIsVoip());
196     }
197 
testSetAndGetExtras()198     public void testSetAndGetExtras() {
199         if (!shouldTestTelecom(getContext())) {
200             return;
201         }
202 
203         final Semaphore lock = new Semaphore(0);
204         Connection connection = createConnection(lock);
205         waitForStateChange(lock);
206 
207         assertEquals(null, connection.getExtras());
208 
209         final Bundle extras = new Bundle();
210         extras.putBoolean("test-extra-key", true);
211         connection.setExtras(extras);
212 
213         final Bundle retrieved = connection.getExtras();
214         assertNotNull(retrieved);
215         assertTrue(extras.getBoolean("test-extra-key"));
216     }
217 
testSetAndGetStatusHints()218     public void testSetAndGetStatusHints() {
219         if (!shouldTestTelecom(getContext())) {
220             return;
221         }
222 
223         final Semaphore lock = new Semaphore(0);
224         Connection connection = createConnection(lock);
225         waitForStateChange(lock);
226 
227         assertEquals(null, connection.getStatusHints());
228 
229         final StatusHints statusHints = new StatusHints("Test", null, null);
230         connection.setStatusHints(statusHints);
231         assertEquals(statusHints, connection.getStatusHints());
232     }
233 
testSetAndGetRingbackRequested()234     public void testSetAndGetRingbackRequested() {
235         if (!shouldTestTelecom(getContext())) {
236             return;
237         }
238 
239         final Semaphore lock = new Semaphore(0);
240         Connection connection = createConnection(lock);
241         waitForStateChange(lock);
242 
243         assertFalse(connection.isRingbackRequested());
244 
245         connection.setRingbackRequested(true);
246         assertTrue(connection.isRingbackRequested());
247     }
248 
testSetAndGetVideoProvider()249     public void testSetAndGetVideoProvider() {
250         if (!shouldTestTelecom(getContext())) {
251             return;
252         }
253 
254         final Semaphore lock = new Semaphore(0);
255         Connection connection = createConnection(lock);
256         waitForStateChange(lock);
257 
258         assertNull(connection.getVideoProvider());
259 
260         final Connection.VideoProvider videoProvider = new MockVideoProvider(null);
261         connection.setVideoProvider(videoProvider);
262         assertEquals(videoProvider, connection.getVideoProvider());
263     }
264 
testStateToString()265     public void testStateToString() {
266         if (!shouldTestTelecom(getContext())) {
267             return;
268         }
269 
270         assertEquals("INITIALIZING", Connection.stateToString(Connection.STATE_INITIALIZING));
271         assertEquals("NEW", Connection.stateToString(Connection.STATE_NEW));
272         assertEquals("RINGING", Connection.stateToString(Connection.STATE_RINGING));
273         assertEquals("DIALING", Connection.stateToString(Connection.STATE_DIALING));
274         assertEquals("ACTIVE", Connection.stateToString(Connection.STATE_ACTIVE));
275         assertEquals("HOLDING", Connection.stateToString(Connection.STATE_HOLDING));
276         assertEquals("DISCONNECTED", Connection.stateToString(Connection.STATE_DISCONNECTED));
277     }
278 
testCapabilitiesToString()279     public void testCapabilitiesToString() {
280         if (!shouldTestTelecom(getContext())) {
281             return;
282         }
283 
284         assertEquals("[Capabilities: CAPABILITY_HOLD]",
285                 Connection.capabilitiesToString(Connection.CAPABILITY_HOLD));
286         assertEquals("[Capabilities: CAPABILITY_MUTE]",
287                 Connection.capabilitiesToString(Connection.CAPABILITY_MUTE));
288         assertEquals("[Capabilities: CAPABILITY_HOLD "
289                 + "CAPABILITY_RESPOND_VIA_TEXT "
290                 + "CAPABILITY_MANAGE_CONFERENCE]",
291                 Connection.capabilitiesToString(Connection.CAPABILITY_HOLD
292                         | Connection.CAPABILITY_RESPOND_VIA_TEXT
293                         | Connection.CAPABILITY_MANAGE_CONFERENCE));
294     }
295 
createConnection(final Semaphore lock)296     private static Connection createConnection(final Semaphore lock) {
297         BasicConnection connection = new BasicConnection();
298         connection.setLock(lock);
299         return connection;
300     }
301 
waitForStateChange(Semaphore lock)302     private static void waitForStateChange(Semaphore lock) {
303         try {
304             lock.tryAcquire(1000, TimeUnit.MILLISECONDS);
305         } catch (InterruptedException e) {
306             fail("State transition timed out");
307         }
308     }
309 
310     private static final class BasicConnection extends Connection {
311         private Semaphore mLock;
312 
setLock(Semaphore lock)313         public void setLock(Semaphore lock) {
314             mLock = lock;
315         }
316 
317         @Override
onStateChanged(int state)318         public void onStateChanged(int state) {
319             mLock.release();
320         }
321     }
322 }
323