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 com.android.compatibility.common.util.ApiLevelUtil; 22 23 import android.net.Uri; 24 import android.os.Build; 25 import android.os.Bundle; 26 import android.telecom.Connection; 27 import android.telecom.DisconnectCause; 28 import android.telecom.StatusHints; 29 import android.telecom.TelecomManager; 30 import android.test.AndroidTestCase; 31 32 import java.util.Arrays; 33 import java.util.List; 34 import java.util.concurrent.Semaphore; 35 import java.util.concurrent.TimeUnit; 36 37 public class ConnectionTest extends AndroidTestCase { 38 39 public void testStateCallbacks() { 40 if (!shouldTestTelecom(getContext())) { 41 return; 42 } 43 44 final Semaphore lock = new Semaphore(0); 45 Connection connection = createConnection(lock); 46 47 waitForStateChange(lock); 48 assertEquals(Connection.STATE_NEW, connection.getState()); 49 50 connection.setInitializing(); 51 waitForStateChange(lock); 52 assertEquals(Connection.STATE_INITIALIZING, connection.getState()); 53 54 connection.setInitialized(); 55 waitForStateChange(lock); 56 assertEquals(Connection.STATE_NEW, connection.getState()); 57 58 connection.setRinging(); 59 waitForStateChange(lock); 60 assertEquals(Connection.STATE_RINGING, connection.getState()); 61 62 connection.setDialing(); 63 waitForStateChange(lock); 64 assertEquals(Connection.STATE_DIALING, connection.getState()); 65 66 connection.setActive(); 67 waitForStateChange(lock); 68 assertEquals(Connection.STATE_ACTIVE, connection.getState()); 69 70 connection.setOnHold(); 71 waitForStateChange(lock); 72 assertEquals(Connection.STATE_HOLDING, connection.getState()); 73 74 connection.setPulling(); 75 waitForStateChange(lock); 76 assertEquals(Connection.STATE_PULLING_CALL, connection.getState()); 77 78 connection.setDisconnected( 79 new DisconnectCause(DisconnectCause.LOCAL, "Test call")); 80 waitForStateChange(lock); 81 assertEquals(Connection.STATE_DISCONNECTED, connection.getState()); 82 83 connection.setRinging(); 84 waitForStateChange(lock); 85 assertEquals("Connection should not move out of STATE_DISCONNECTED.", 86 Connection.STATE_DISCONNECTED, connection.getState()); 87 } 88 89 /** 90 * {@link UnsupportedOperationException} is only thrown in L MR1+. 91 */ 92 public void testFailedState() { 93 if (ApiLevelUtil.isBefore(Build.VERSION_CODES.LOLLIPOP_MR1)) { 94 return; 95 } 96 Connection connection = Connection.createFailedConnection( 97 new DisconnectCause(DisconnectCause.LOCAL, "Test call")); 98 assertEquals(Connection.STATE_DISCONNECTED, connection.getState()); 99 100 try { 101 connection.setRinging(); 102 } catch (UnsupportedOperationException e) { 103 return; 104 } 105 fail("Connection should not move out of STATE_DISCONNECTED"); 106 } 107 108 /** 109 * {@link UnsupportedOperationException} is only thrown in L MR1+. 110 */ 111 public void testCanceledState() { 112 if (ApiLevelUtil.isBefore(Build.VERSION_CODES.LOLLIPOP_MR1)) { 113 return; 114 } 115 Connection connection = Connection.createCanceledConnection(); 116 assertEquals(Connection.STATE_DISCONNECTED, connection.getState()); 117 118 try { 119 connection.setDialing(); 120 } catch (UnsupportedOperationException e) { 121 return; 122 } 123 fail("Connection should not move out of STATE_DISCONNECTED"); 124 } 125 126 public void testSetAndGetCallerDisplayName() { 127 if (!shouldTestTelecom(getContext())) { 128 return; 129 } 130 131 final Semaphore lock = new Semaphore(0); 132 Connection connection = createConnection(lock); 133 waitForStateChange(lock); 134 135 connection.setCallerDisplayName("Test User", TelecomManager.PRESENTATION_ALLOWED); 136 assertEquals("Test User", connection.getCallerDisplayName()); 137 assertEquals(TelecomManager.PRESENTATION_ALLOWED, 138 connection.getCallerDisplayNamePresentation()); 139 } 140 141 public void testSetAndGetAddress() { 142 if (!shouldTestTelecom(getContext())) { 143 return; 144 } 145 146 final Semaphore lock = new Semaphore(0); 147 Connection connection = createConnection(lock); 148 waitForStateChange(lock); 149 150 final Uri address = Uri.fromParts("tel", "1234567", null); 151 connection.setAddress(address, TelecomManager.PRESENTATION_UNKNOWN); 152 assertEquals(address, connection.getAddress()); 153 assertEquals(TelecomManager.PRESENTATION_UNKNOWN, connection.getAddressPresentation()); 154 } 155 156 public void testSetAndGetConnectionCapabilities() { 157 if (!shouldTestTelecom(getContext())) { 158 return; 159 } 160 161 final Semaphore lock = new Semaphore(0); 162 Connection connection = createConnection(lock); 163 waitForStateChange(lock); 164 165 final int capabilities = Connection.CAPABILITY_HOLD | Connection.CAPABILITY_CAN_PAUSE_VIDEO 166 | Connection.CAPABILITY_MANAGE_CONFERENCE | Connection.CAPABILITY_RESPOND_VIA_TEXT; 167 168 connection.setConnectionCapabilities(capabilities); 169 170 assertEquals(capabilities, connection.getConnectionCapabilities()); 171 } 172 173 public void testSetAndGetConnectionProperties() { 174 if (!shouldTestTelecom(getContext())) { 175 return; 176 } 177 178 final Semaphore lock = new Semaphore(0); 179 Connection connection = createConnection(lock); 180 waitForStateChange(lock); 181 182 final int properties = Connection.PROPERTY_IS_EXTERNAL_CALL; 183 184 connection.setConnectionProperties(properties); 185 186 assertEquals(properties, connection.getConnectionProperties()); 187 } 188 189 public void testSetAndGetDisconnectCause() { 190 if (!shouldTestTelecom(getContext())) { 191 return; 192 } 193 194 final Semaphore lock = new Semaphore(0); 195 Connection connection = createConnection(lock); 196 waitForStateChange(lock); 197 assertEquals(Connection.STATE_NEW, connection.getState()); 198 199 final DisconnectCause disconnectCause = new DisconnectCause(DisconnectCause.REJECTED, 200 "No friends", "No friends to talk to", "No friends to talk to"); 201 202 connection.setDisconnected(disconnectCause); 203 204 assertEquals(Connection.STATE_DISCONNECTED, connection.getState()); 205 assertEquals(disconnectCause, connection.getDisconnectCause()); 206 } 207 208 public void testSetAndGetAudioModeIsVoip() { 209 if (!shouldTestTelecom(getContext())) { 210 return; 211 } 212 213 final Semaphore lock = new Semaphore(0); 214 Connection connection = createConnection(lock); 215 waitForStateChange(lock); 216 217 assertFalse(connection.getAudioModeIsVoip()); 218 connection.setAudioModeIsVoip(true); 219 assertTrue(connection.getAudioModeIsVoip()); 220 } 221 222 public void testSetAndGetExtras() { 223 if (!shouldTestTelecom(getContext())) { 224 return; 225 } 226 227 final Semaphore lock = new Semaphore(0); 228 Connection connection = createConnection(lock); 229 waitForStateChange(lock); 230 231 assertEquals(null, connection.getExtras()); 232 233 final Bundle extras = new Bundle(); 234 extras.putBoolean("test-extra-key", true); 235 connection.setExtras(extras); 236 237 final Bundle retrieved = connection.getExtras(); 238 assertNotNull(retrieved); 239 assertTrue(extras.getBoolean("test-extra-key")); 240 } 241 242 /** 243 * Basic local test of adding extra keys via {@link Connection#removeExtras(List)}. 244 * 245 * Extended end-to-end passing of extras is verified in 246 * {@link CallDetailsTest#testConnectionPutExtras()} and 247 * @link CallDetailsTest#testConnectionRemoveExtras()}. 248 */ 249 public void testPutExtras() { 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 assertEquals(null, connection.getExtras()); 259 260 final Bundle extras = new Bundle(); 261 extras.putBoolean("test-extra-key", true); 262 connection.putExtras(extras); 263 264 final Bundle retrieved = connection.getExtras(); 265 assertNotNull(retrieved); 266 assertTrue(extras.getBoolean("test-extra-key")); 267 } 268 269 /** 270 * Basic local test of removing extra keys via {@link Connection#removeExtras(List)}. 271 * 272 * Extended end-to-end passing of extras is verified in 273 * {@link CallDetailsTest#testConnectionPutExtras()} and 274 * @link CallDetailsTest#testConnectionRemoveExtras()}. 275 */ 276 public void testRemoveExtras() { 277 if (!shouldTestTelecom(getContext())) { 278 return; 279 } 280 281 final Semaphore lock = new Semaphore(0); 282 Connection connection = createConnection(lock); 283 waitForStateChange(lock); 284 285 assertEquals(null, connection.getExtras()); 286 287 final Bundle extras = new Bundle(); 288 extras.putBoolean("test-extra-key", true); 289 connection.putExtras(extras); 290 connection.removeExtras(Arrays.asList("test-extra-key")); 291 292 final Bundle retrieved = connection.getExtras(); 293 assertNotNull(retrieved); 294 assertFalse(retrieved.containsKey("test-extra-key")); 295 } 296 297 /** 298 * Basic local test of removing extra keys via {@link Connection#removeExtras(String...)}. 299 * 300 * Extended end-to-end passing of extras is verified in 301 * {@link CallDetailsTest#testConnectionPutExtras()} and 302 * @link CallDetailsTest#testConnectionRemoveExtras()}. 303 */ 304 public void testRemoveExtrasVariable() { 305 if (!shouldTestTelecom(getContext())) { 306 return; 307 } 308 309 final Semaphore lock = new Semaphore(0); 310 Connection connection = createConnection(lock); 311 waitForStateChange(lock); 312 313 assertEquals(null, connection.getExtras()); 314 315 final Bundle extras = new Bundle(); 316 extras.putBoolean("test-extra-key", true); 317 extras.putBoolean("test-extra-key2", true); 318 connection.putExtras(extras); 319 connection.removeExtras("test-extra-key", "test-extra-key2"); 320 321 final Bundle retrieved = connection.getExtras(); 322 assertNotNull(retrieved); 323 assertFalse(retrieved.containsKey("test-extra-key")); 324 assertFalse(retrieved.containsKey("test-extra-key2")); 325 } 326 327 /** 328 * Tests that the {@link Connection#sendConnectionEvent(String, Bundle)} method exists and can 329 * be called. 330 * 331 * Actual end-to-end tests can be found in {@link CallDetailsTest#testConnectionEvent()}. 332 */ 333 public void testSendConnectionEvent() { 334 if (!shouldTestTelecom(getContext())) { 335 return; 336 } 337 338 final Semaphore lock = new Semaphore(0); 339 Connection connection = createConnection(lock); 340 waitForStateChange(lock); 341 342 connection.sendConnectionEvent("test", null); 343 } 344 345 public void testSetAndGetStatusHints() { 346 if (!shouldTestTelecom(getContext())) { 347 return; 348 } 349 350 final Semaphore lock = new Semaphore(0); 351 Connection connection = createConnection(lock); 352 waitForStateChange(lock); 353 354 assertEquals(null, connection.getStatusHints()); 355 356 final StatusHints statusHints = new StatusHints("Test", null, null); 357 connection.setStatusHints(statusHints); 358 assertEquals(statusHints, connection.getStatusHints()); 359 } 360 361 public void testSetAndGetRingbackRequested() { 362 if (!shouldTestTelecom(getContext())) { 363 return; 364 } 365 366 final Semaphore lock = new Semaphore(0); 367 Connection connection = createConnection(lock); 368 waitForStateChange(lock); 369 370 assertFalse(connection.isRingbackRequested()); 371 372 connection.setRingbackRequested(true); 373 assertTrue(connection.isRingbackRequested()); 374 } 375 376 public void testSetAndGetVideoProvider() { 377 if (!shouldTestTelecom(getContext())) { 378 return; 379 } 380 381 final Semaphore lock = new Semaphore(0); 382 Connection connection = createConnection(lock); 383 waitForStateChange(lock); 384 385 assertNull(connection.getVideoProvider()); 386 387 final Connection.VideoProvider videoProvider = new MockVideoProvider(null); 388 connection.setVideoProvider(videoProvider); 389 assertEquals(videoProvider, connection.getVideoProvider()); 390 } 391 392 public void testStateToString() { 393 if (!shouldTestTelecom(getContext())) { 394 return; 395 } 396 397 assertEquals("INITIALIZING", Connection.stateToString(Connection.STATE_INITIALIZING)); 398 assertEquals("NEW", Connection.stateToString(Connection.STATE_NEW)); 399 assertEquals("RINGING", Connection.stateToString(Connection.STATE_RINGING)); 400 assertEquals("DIALING", Connection.stateToString(Connection.STATE_DIALING)); 401 assertEquals("ACTIVE", Connection.stateToString(Connection.STATE_ACTIVE)); 402 assertEquals("HOLDING", Connection.stateToString(Connection.STATE_HOLDING)); 403 assertEquals("DISCONNECTED", Connection.stateToString(Connection.STATE_DISCONNECTED)); 404 } 405 406 public void testCapabilitiesToString() { 407 if (!shouldTestTelecom(getContext())) { 408 return; 409 } 410 411 assertEquals("[Capabilities: CAPABILITY_HOLD]", 412 Connection.capabilitiesToString(Connection.CAPABILITY_HOLD)); 413 assertEquals("[Capabilities: CAPABILITY_MUTE]", 414 Connection.capabilitiesToString(Connection.CAPABILITY_MUTE)); 415 assertEquals("[Capabilities: CAPABILITY_HOLD " 416 + "CAPABILITY_RESPOND_VIA_TEXT " 417 + "CAPABILITY_MANAGE_CONFERENCE]", 418 Connection.capabilitiesToString(Connection.CAPABILITY_HOLD 419 | Connection.CAPABILITY_RESPOND_VIA_TEXT 420 | Connection.CAPABILITY_MANAGE_CONFERENCE)); 421 } 422 423 /** 424 * Tests the {@link Connection#propertiesToString(int)} method. 425 */ 426 public void testPropertiesToString() { 427 if (!shouldTestTelecom(getContext())) { 428 return; 429 } 430 431 assertEquals("[Properties: PROPERTY_IS_EXTERNAL_CALL]", 432 Connection.propertiesToString(Connection.PROPERTY_IS_EXTERNAL_CALL)); 433 } 434 435 private static Connection createConnection(final Semaphore lock) { 436 BasicConnection connection = new BasicConnection(); 437 connection.setLock(lock); 438 return connection; 439 } 440 441 private static void waitForStateChange(Semaphore lock) { 442 try { 443 lock.tryAcquire(1000, TimeUnit.MILLISECONDS); 444 } catch (InterruptedException e) { 445 fail("State transition timed out"); 446 } 447 } 448 449 private static final class BasicConnection extends Connection { 450 private Semaphore mLock; 451 452 public void setLock(Semaphore lock) { 453 mLock = lock; 454 } 455 456 @Override 457 public void onStateChanged(int state) { 458 mLock.release(); 459 } 460 } 461 } 462