Home | History | Annotate | Download | only in cts
      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.*;
     20 
     21 import static org.hamcrest.CoreMatchers.instanceOf;
     22 import static org.junit.Assert.assertThat;
     23 
     24 import android.graphics.drawable.Icon;
     25 import android.os.Bundle;
     26 import android.net.Uri;
     27 import android.telecom.Call;
     28 import android.telecom.Connection;
     29 import android.telecom.ConnectionRequest;
     30 import android.telecom.DisconnectCause;
     31 import android.telecom.GatewayInfo;
     32 import android.telecom.PhoneAccount;
     33 import android.telecom.PhoneAccountHandle;
     34 import android.telecom.StatusHints;
     35 import android.telecom.TelecomManager;
     36 
     37 import java.util.Arrays;
     38 import java.util.List;
     39 
     40 /**
     41  * Suites of tests that verifies the various Call details.
     42  */
     43 public class CallDetailsTest extends BaseTelecomTestWithMockServices {
     44 
     45     /**
     46      * {@link Connection#PROPERTY_HIGH_DEF_AUDIO} is @hide, so define it here for now.
     47      */
     48     public static final int PROPERTY_HIGH_DEF_AUDIO = 1<<2;
     49 
     50     /**
     51      * {@link Connection#PROPERTY_WIFI} is @hide, so define it here for now.
     52      */
     53     public static final int PROPERTY_WIFI = 1<<3;
     54     public static final int CONNECTION_PROPERTIES =  PROPERTY_HIGH_DEF_AUDIO | PROPERTY_WIFI;
     55     public static final int CONNECTION_CAPABILITIES =
     56             Connection.CAPABILITY_HOLD | Connection.CAPABILITY_MUTE;
     57     public static final int CALL_CAPABILITIES =
     58             Call.Details.CAPABILITY_HOLD | Call.Details.CAPABILITY_MUTE;
     59     public static final int CALL_PROPERTIES =
     60             Call.Details.PROPERTY_HIGH_DEF_AUDIO | Call.Details.PROPERTY_WIFI;
     61     public static final String CALLER_DISPLAY_NAME = "CTS test";
     62     public static final int CALLER_DISPLAY_NAME_PRESENTATION = TelecomManager.PRESENTATION_ALLOWED;
     63     public static final String TEST_SUBJECT = "test";
     64     public static final String TEST_CHILD_NUMBER = "650-555-1212";
     65     public static final String TEST_FORWARDED_NUMBER = "650-555-1212";
     66     public static final String TEST_EXTRA_KEY = "com.test.extra.TEST";
     67     public static final String TEST_EXTRA_KEY2 = "com.test.extra.TEST2";
     68     public static final String TEST_EXTRA_KEY3 = "com.test.extra.TEST3";
     69     public static final int TEST_EXTRA_VALUE = 10;
     70     public static final String TEST_EVENT = "com.test.event.TEST";
     71     public static final Uri TEST_DEFLECT_URI = Uri.fromParts("tel", "+16505551212", null);
     72     private StatusHints mStatusHints;
     73     private Bundle mExtras = new Bundle();
     74 
     75     private MockInCallService mInCallService;
     76     private Call mCall;
     77     private MockConnection mConnection;
     78 
     79     @Override
     80     protected void setUp() throws Exception {
     81         super.setUp();
     82         if (mShouldTestTelecom) {
     83             PhoneAccount account = setupConnectionService(
     84                     new MockConnectionService() {
     85                         @Override
     86                         public Connection onCreateOutgoingConnection(
     87                                 PhoneAccountHandle connectionManagerPhoneAccount,
     88                                 ConnectionRequest request) {
     89                             Connection connection = super.onCreateOutgoingConnection(
     90                                     connectionManagerPhoneAccount,
     91                                     request);
     92                             mConnection = (MockConnection) connection;
     93                             // Modify the connection object created with local values.
     94                             connection.setConnectionCapabilities(CONNECTION_CAPABILITIES);
     95                             connection.setConnectionProperties(CONNECTION_PROPERTIES);
     96                             connection.setCallerDisplayName(
     97                                     CALLER_DISPLAY_NAME,
     98                                     CALLER_DISPLAY_NAME_PRESENTATION);
     99                             connection.setExtras(mExtras);
    100                             mStatusHints = new StatusHints(
    101                                     "CTS test",
    102                                     Icon.createWithResource(
    103                                             getInstrumentation().getContext(),
    104                                             R.drawable.ic_phone_24dp),
    105                                             null);
    106                             connection.setStatusHints(mStatusHints);
    107                             lock.release();
    108                             return connection;
    109                         }
    110                     }, FLAG_REGISTER | FLAG_ENABLE);
    111 
    112             /** Place a call as a part of the setup before we test the various
    113              *  Call details.
    114              */
    115             placeAndVerifyCall();
    116             verifyConnectionForOutgoingCall();
    117 
    118             mInCallService = mInCallCallbacks.getService();
    119             mCall = mInCallService.getLastCall();
    120 
    121             assertCallState(mCall, Call.STATE_DIALING);
    122         }
    123     }
    124 
    125     /**
    126      * Tests whether the getAccountHandle() getter returns the correct object.
    127      */
    128     public void testAccountHandle() {
    129         if (!mShouldTestTelecom) {
    130             return;
    131         }
    132 
    133         assertThat(mCall.getDetails().getAccountHandle(), instanceOf(PhoneAccountHandle.class));
    134         assertEquals(TEST_PHONE_ACCOUNT_HANDLE, mCall.getDetails().getAccountHandle());
    135     }
    136 
    137     /**
    138      * Tests whether the getCallCapabilities() getter returns the correct object.
    139      */
    140     public void testCallCapabilities() {
    141         if (!mShouldTestTelecom) {
    142             return;
    143         }
    144 
    145         assertThat(mCall.getDetails().getCallCapabilities(), instanceOf(Integer.class));
    146         assertEquals(CALL_CAPABILITIES, mCall.getDetails().getCallCapabilities());
    147         assertTrue(mCall.getDetails().can(Call.Details.CAPABILITY_HOLD));
    148         assertTrue(mCall.getDetails().can(Call.Details.CAPABILITY_MUTE));
    149         assertFalse(mCall.getDetails().can(Call.Details.CAPABILITY_MANAGE_CONFERENCE));
    150         assertFalse(mCall.getDetails().can(Call.Details.CAPABILITY_RESPOND_VIA_TEXT));
    151     }
    152 
    153     /**
    154      * Tests propagation of the local video capabilities from telephony through to in-call.
    155      */
    156     public void testCallLocalVideoCapability() {
    157         if (!mShouldTestTelecom) {
    158             return;
    159         }
    160 
    161         // Note: Local support for video is disabled when a call is in dialing state.
    162         mConnection.setConnectionCapabilities(
    163                 Connection.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL);
    164         assertCallCapabilities(mCall, 0);
    165 
    166         mConnection.setConnectionCapabilities(Connection.CAPABILITY_SUPPORTS_VT_LOCAL_RX);
    167         assertCallCapabilities(mCall, 0);
    168 
    169         mConnection.setConnectionCapabilities(Connection.CAPABILITY_SUPPORTS_VT_LOCAL_TX);
    170         assertCallCapabilities(mCall, 0);
    171 
    172         mConnection.setConnectionCapabilities(
    173                 Connection.CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL);
    174         assertCallCapabilities(mCall, 0);
    175 
    176         mConnection.setConnectionCapabilities(Connection.CAPABILITY_SUPPORTS_VT_REMOTE_RX);
    177         assertCallCapabilities(mCall, 0);
    178 
    179         mConnection.setConnectionCapabilities(Connection.CAPABILITY_SUPPORTS_VT_REMOTE_TX);
    180         assertCallCapabilities(mCall, 0);
    181 
    182         // Set call active; we expect the capabilities to make it through now.
    183         mConnection.setActive();
    184 
    185         mConnection.setConnectionCapabilities(
    186                 Connection.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL);
    187         assertCallCapabilities(mCall, Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL);
    188 
    189         mConnection.setConnectionCapabilities(Connection.CAPABILITY_SUPPORTS_VT_LOCAL_RX);
    190         assertCallCapabilities(mCall, Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_RX);
    191 
    192         mConnection.setConnectionCapabilities(Connection.CAPABILITY_SUPPORTS_VT_LOCAL_TX);
    193         assertCallCapabilities(mCall, Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_TX);
    194 
    195         mConnection.setConnectionCapabilities(
    196                 Connection.CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL);
    197         assertCallCapabilities(mCall, Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL);
    198 
    199         mConnection.setConnectionCapabilities(Connection.CAPABILITY_SUPPORTS_VT_REMOTE_RX);
    200         assertCallCapabilities(mCall, Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_RX);
    201 
    202         mConnection.setConnectionCapabilities(Connection.CAPABILITY_SUPPORTS_VT_REMOTE_TX);
    203         assertCallCapabilities(mCall, Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_TX);
    204     }
    205 
    206     /**
    207      * Tests passing call capabilities from Connections to Calls.
    208      */
    209     public void testCallCapabilityPropagation() {
    210         if (!mShouldTestTelecom) {
    211             return;
    212         }
    213 
    214         mConnection.setConnectionCapabilities(Connection.CAPABILITY_CAN_PAUSE_VIDEO);
    215         assertCallCapabilities(mCall, Call.Details.CAPABILITY_CAN_PAUSE_VIDEO);
    216 
    217         mConnection.setConnectionCapabilities(Connection.CAPABILITY_HOLD);
    218         assertCallCapabilities(mCall, Call.Details.CAPABILITY_HOLD);
    219 
    220         mConnection.setConnectionCapabilities(Connection.CAPABILITY_MANAGE_CONFERENCE);
    221         assertCallCapabilities(mCall, Call.Details.CAPABILITY_MANAGE_CONFERENCE);
    222 
    223         mConnection.setConnectionCapabilities(Connection.CAPABILITY_MERGE_CONFERENCE);
    224         assertCallCapabilities(mCall, Call.Details.CAPABILITY_MERGE_CONFERENCE);
    225 
    226         mConnection.setConnectionCapabilities(Connection.CAPABILITY_MUTE);
    227         assertCallCapabilities(mCall, Call.Details.CAPABILITY_MUTE);
    228 
    229         mConnection.setConnectionCapabilities(Connection.CAPABILITY_RESPOND_VIA_TEXT);
    230         assertCallCapabilities(mCall, Call.Details.CAPABILITY_RESPOND_VIA_TEXT);
    231 
    232         mConnection.setConnectionCapabilities(Connection.CAPABILITY_SEPARATE_FROM_CONFERENCE);
    233         assertCallCapabilities(mCall, Call.Details.CAPABILITY_SEPARATE_FROM_CONFERENCE);
    234 
    235         mConnection.setConnectionCapabilities(Connection.CAPABILITY_SUPPORT_HOLD);
    236         assertCallCapabilities(mCall, Call.Details.CAPABILITY_SUPPORT_HOLD);
    237 
    238         mConnection.setConnectionCapabilities(Connection.CAPABILITY_SWAP_CONFERENCE);
    239         assertCallCapabilities(mCall, Call.Details.CAPABILITY_SWAP_CONFERENCE);
    240     }
    241 
    242     /**
    243      * Tests whether the getCallerDisplayName() getter returns the correct object.
    244      */
    245     public void testCallerDisplayName() {
    246         if (!mShouldTestTelecom) {
    247             return;
    248         }
    249 
    250         assertThat(mCall.getDetails().getCallerDisplayName(), instanceOf(String.class));
    251         assertEquals(CALLER_DISPLAY_NAME, mCall.getDetails().getCallerDisplayName());
    252     }
    253 
    254     /**
    255      * Tests whether the getCallerDisplayNamePresentation() getter returns the correct object.
    256      */
    257     public void testCallerDisplayNamePresentation() {
    258         if (!mShouldTestTelecom) {
    259             return;
    260         }
    261 
    262         assertThat(mCall.getDetails().getCallerDisplayNamePresentation(), instanceOf(Integer.class));
    263         assertEquals(CALLER_DISPLAY_NAME_PRESENTATION, mCall.getDetails().getCallerDisplayNamePresentation());
    264     }
    265 
    266     /**
    267      * Tests whether the getCallProperties() getter returns the correct object.
    268      */
    269     public void testCallProperties() {
    270         if (!mShouldTestTelecom) {
    271             return;
    272         }
    273 
    274         assertThat(mCall.getDetails().getCallProperties(), instanceOf(Integer.class));
    275 
    276         assertEquals(CALL_PROPERTIES, mCall.getDetails().getCallProperties());
    277     }
    278 
    279     /**
    280      * Tests whether the getConnectTimeMillis() getter returns the correct object.
    281      */
    282     public void testConnectTimeMillis() {
    283         if (!mShouldTestTelecom) {
    284             return;
    285         }
    286 
    287         assertThat(mCall.getDetails().getConnectTimeMillis(), instanceOf(Long.class));
    288     }
    289 
    290     /**
    291      * Tests whether the getCreationTimeMillis() getter returns the correct object.
    292      */
    293     public void testCreationTimeMillis() {
    294         if (!mShouldTestTelecom) {
    295             return;
    296         }
    297 
    298         assertThat(mCall.getDetails().getCreationTimeMillis(), instanceOf(Long.class));
    299     }
    300 
    301     /**
    302      * Tests whether the getDisconnectCause() getter returns the correct object.
    303      */
    304     public void testDisconnectCause() {
    305         if (!mShouldTestTelecom) {
    306             return;
    307         }
    308 
    309         assertThat(mCall.getDetails().getDisconnectCause(), instanceOf(DisconnectCause.class));
    310     }
    311 
    312     /**
    313      * Tests whether the getExtras() getter returns the correct object.
    314      */
    315     public void testExtras() {
    316         if (!mShouldTestTelecom) {
    317             return;
    318         }
    319 
    320         if (mCall.getDetails().getExtras() != null) {
    321             assertThat(mCall.getDetails().getExtras(), instanceOf(Bundle.class));
    322         }
    323     }
    324 
    325     /**
    326      * Tests whether the getIntentExtras() getter returns the correct object.
    327      */
    328     public void testIntentExtras() {
    329         if (!mShouldTestTelecom) {
    330             return;
    331         }
    332 
    333         assertThat(mCall.getDetails().getIntentExtras(), instanceOf(Bundle.class));
    334     }
    335 
    336     /**
    337      * Tests whether the getGatewayInfo() getter returns the correct object.
    338      */
    339     public void testGatewayInfo() {
    340         if (!mShouldTestTelecom) {
    341             return;
    342         }
    343 
    344         if (mCall.getDetails().getGatewayInfo() != null) {
    345             assertThat(mCall.getDetails().getGatewayInfo(), instanceOf(GatewayInfo.class));
    346         }
    347     }
    348 
    349     /**
    350      * Tests whether the getHandle() getter returns the correct object.
    351      */
    352     public void testHandle() {
    353         if (!mShouldTestTelecom) {
    354             return;
    355         }
    356 
    357         assertThat(mCall.getDetails().getHandle(), instanceOf(Uri.class));
    358         assertEquals(getTestNumber(), mCall.getDetails().getHandle());
    359     }
    360 
    361     /**
    362      * Tests whether the getHandlePresentation() getter returns the correct object.
    363      */
    364     public void testHandlePresentation() {
    365         if (!mShouldTestTelecom) {
    366             return;
    367         }
    368 
    369         assertThat(mCall.getDetails().getHandlePresentation(), instanceOf(Integer.class));
    370         assertEquals(MockConnectionService.CONNECTION_PRESENTATION, mCall.getDetails().getHandlePresentation());
    371     }
    372 
    373     /**
    374      * Tests whether the getStatusHints() getter returns the correct object.
    375      */
    376     public void testStatusHints() {
    377         if (!mShouldTestTelecom) {
    378             return;
    379         }
    380 
    381         assertThat(mCall.getDetails().getStatusHints(), instanceOf(StatusHints.class));
    382         assertEquals(mStatusHints.getLabel(), mCall.getDetails().getStatusHints().getLabel());
    383         assertEquals(
    384                 mStatusHints.getIcon().toString(),
    385                 mCall.getDetails().getStatusHints().getIcon().toString());
    386         assertEquals(mStatusHints.getExtras(), mCall.getDetails().getStatusHints().getExtras());
    387     }
    388 
    389     /**
    390      * Tests whether the getVideoState() getter returns the correct object.
    391      */
    392     public void testVideoState() {
    393         if (!mShouldTestTelecom) {
    394             return;
    395         }
    396 
    397         assertThat(mCall.getDetails().getVideoState(), instanceOf(Integer.class));
    398     }
    399 
    400     /**
    401      * Tests communication of {@link Connection#setExtras(Bundle)} through to
    402      * {@link Call.Details#getExtras()}.
    403      */
    404     public void testExtrasPropagation() {
    405         if (!mShouldTestTelecom) {
    406             return;
    407         }
    408 
    409         Bundle exampleExtras = new Bundle();
    410         exampleExtras.putString(Connection.EXTRA_CALL_SUBJECT, TEST_SUBJECT);
    411         exampleExtras.putString(Connection.EXTRA_CHILD_ADDRESS, TEST_CHILD_NUMBER);
    412         exampleExtras.putString(Connection.EXTRA_LAST_FORWARDED_NUMBER, TEST_FORWARDED_NUMBER);
    413         exampleExtras.putInt(TEST_EXTRA_KEY, TEST_EXTRA_VALUE);
    414         mConnection.setExtras(exampleExtras);
    415 
    416         // Make sure we got back a bundle with the call subject key set.
    417         assertCallExtras(mCall, Connection.EXTRA_CALL_SUBJECT);
    418 
    419         Bundle callExtras = mCall.getDetails().getExtras();
    420         assertEquals(TEST_SUBJECT, callExtras.getString(Connection.EXTRA_CALL_SUBJECT));
    421         assertEquals(TEST_CHILD_NUMBER, callExtras.getString(Connection.EXTRA_CHILD_ADDRESS));
    422         assertEquals(TEST_FORWARDED_NUMBER,
    423                 callExtras.getString(Connection.EXTRA_LAST_FORWARDED_NUMBER));
    424         assertEquals(TEST_EXTRA_VALUE, callExtras.getInt(TEST_EXTRA_KEY));
    425     }
    426 
    427     /**
    428      * Tests that {@link Connection} extras changes made via {@link Connection#putExtras(Bundle)}
    429      * are propagated to the {@link Call} via
    430      * {@link android.telecom.Call.Callback#onDetailsChanged(Call, Call.Details)}.
    431      */
    432     public void testConnectionPutExtras() {
    433         if (!mShouldTestTelecom) {
    434             return;
    435         }
    436 
    437         Bundle testBundle = new Bundle();
    438         testBundle.putString(TEST_EXTRA_KEY, TEST_SUBJECT);
    439         testBundle.putInt(TEST_EXTRA_KEY2, TEST_EXTRA_VALUE);
    440         mConnection.putExtras(testBundle);
    441         // Wait for the 2nd invocation; setExtras is called in the setup method.
    442         mOnExtrasChangedCounter.waitForCount(2, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
    443 
    444         Bundle extras = mCall.getDetails().getExtras();
    445         assertTrue(extras.containsKey(TEST_EXTRA_KEY));
    446         assertEquals(TEST_SUBJECT, extras.getString(TEST_EXTRA_KEY));
    447         assertTrue(extras.containsKey(TEST_EXTRA_KEY2));
    448         assertEquals(TEST_EXTRA_VALUE, extras.getInt(TEST_EXTRA_KEY2));
    449     }
    450 
    451     /**
    452      * Tests that {@link Connection} extras changes made via {@link Connection#removeExtras(List)}
    453      * are propagated to the {@link Call} via
    454      * {@link android.telecom.Call.Callback#onDetailsChanged(Call, Call.Details)}.
    455      */
    456     public void testConnectionRemoveExtras() {
    457         if (!mShouldTestTelecom) {
    458             return;
    459         }
    460 
    461         testConnectionPutExtras();
    462 
    463         mConnection.removeExtras(Arrays.asList(TEST_EXTRA_KEY));
    464         verifyRemoveConnectionExtras();
    465     }
    466 
    467     /**
    468      * Tests that {@link Connection} extras changes made via {@link Connection#removeExtras(List)}
    469      * are propagated to the {@link Call} via
    470      * {@link android.telecom.Call.Callback#onDetailsChanged(Call, Call.Details)}.
    471      */
    472     public void testConnectionRemoveExtras2() {
    473         if (!mShouldTestTelecom) {
    474             return;
    475         }
    476 
    477         testConnectionPutExtras();
    478 
    479         mConnection.removeExtras(TEST_EXTRA_KEY);
    480         // testConnectionPutExtra will have waited for the 2nd invocation, so wait for the 3rd here.
    481         verifyRemoveConnectionExtras();
    482     }
    483 
    484     private void verifyRemoveConnectionExtras() {
    485         // testConnectionPutExtra will have waited for the 2nd invocation, so wait for the 3rd here.
    486         mOnExtrasChangedCounter.waitForCount(3, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
    487 
    488         Bundle extras = mCall.getDetails().getExtras();
    489         assertFalse(extras.containsKey(TEST_EXTRA_KEY));
    490         assertTrue(extras.containsKey(TEST_EXTRA_KEY2));
    491         assertEquals(TEST_EXTRA_VALUE, extras.getInt(TEST_EXTRA_KEY2));
    492     }
    493 
    494     /**
    495      * Tests that {@link Call} extras changes made via {@link Call#putExtras(Bundle)} are propagated
    496      * to {@link Connection#onExtrasChanged(Bundle)}.
    497      */
    498     public void testCallPutExtras() {
    499         if (!mShouldTestTelecom) {
    500             return;
    501         }
    502 
    503         Bundle testBundle = new Bundle();
    504         testBundle.putString(TEST_EXTRA_KEY, TEST_SUBJECT);
    505         final InvokeCounter counter = mConnection.getInvokeCounter(
    506                 MockConnection.ON_EXTRAS_CHANGED);
    507         mCall.putExtras(testBundle);
    508         counter.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
    509         Bundle extras = mConnection.getExtras();
    510 
    511         assertNotNull(extras);
    512         assertTrue(extras.containsKey(TEST_EXTRA_KEY));
    513         assertEquals(TEST_SUBJECT, extras.getString(TEST_EXTRA_KEY));
    514     }
    515 
    516     /**
    517      * Tests that {@link Call} extra operations using {@link Call#removeExtras(List)} are propagated
    518      * to the {@link Connection} via {@link Connection#onExtrasChanged(Bundle)}.
    519      *
    520      * This test specifically tests addition and removal of extras values.
    521      */
    522     public void testCallRemoveExtras() {
    523         if (!mShouldTestTelecom) {
    524             return;
    525         }
    526 
    527         final InvokeCounter counter = setupCallExtras();
    528         Bundle extras;
    529 
    530         mCall.removeExtras(Arrays.asList(TEST_EXTRA_KEY));
    531         counter.waitForCount(2, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
    532         extras = mConnection.getExtras();
    533         assertNotNull(extras);
    534         assertFalse(extras.containsKey(TEST_EXTRA_KEY));
    535         assertTrue(extras.containsKey(TEST_EXTRA_KEY2));
    536         assertEquals(TEST_EXTRA_VALUE, extras.getInt(TEST_EXTRA_KEY2));
    537         assertTrue(extras.containsKey(TEST_EXTRA_KEY3));
    538         assertEquals(TEST_SUBJECT, extras.getString(TEST_EXTRA_KEY3));
    539 
    540         mCall.removeExtras(Arrays.asList(TEST_EXTRA_KEY2, TEST_EXTRA_KEY3));
    541         counter.waitForCount(3, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
    542         extras = mConnection.getExtras();
    543         assertFalse(extras.containsKey(TEST_EXTRA_KEY2));
    544         assertFalse(extras.containsKey(TEST_EXTRA_KEY3));
    545     }
    546 
    547     /**
    548      * Tests that {@link Call} extra operations using {@link Call#removeExtras(String[])} are
    549      * propagated to the {@link Connection} via {@link Connection#onExtrasChanged(Bundle)}.
    550      *
    551      * This test specifically tests addition and removal of extras values.
    552      */
    553     public void testCallRemoveExtras2() {
    554         if (!mShouldTestTelecom) {
    555             return;
    556         }
    557 
    558         final InvokeCounter counter = setupCallExtras();
    559         Bundle extras;
    560 
    561         mCall.removeExtras(TEST_EXTRA_KEY);
    562         counter.waitForCount(2, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
    563         extras = mConnection.getExtras();
    564         assertNotNull(extras);
    565         assertFalse(extras.containsKey(TEST_EXTRA_KEY));
    566         assertTrue(extras.containsKey(TEST_EXTRA_KEY2));
    567         assertEquals(TEST_EXTRA_VALUE, extras.getInt(TEST_EXTRA_KEY2));
    568         assertTrue(extras.containsKey(TEST_EXTRA_KEY3));
    569         assertEquals(TEST_SUBJECT, extras.getString(TEST_EXTRA_KEY3));
    570     }
    571 
    572     private InvokeCounter setupCallExtras() {
    573         Bundle testBundle = new Bundle();
    574         testBundle.putString(TEST_EXTRA_KEY, TEST_SUBJECT);
    575         testBundle.putInt(TEST_EXTRA_KEY2, TEST_EXTRA_VALUE);
    576         testBundle.putString(TEST_EXTRA_KEY3, TEST_SUBJECT);
    577         final InvokeCounter counter = mConnection.getInvokeCounter(
    578                 MockConnection.ON_EXTRAS_CHANGED);
    579         mCall.putExtras(testBundle);
    580         counter.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
    581         Bundle extras = mConnection.getExtras();
    582 
    583         assertNotNull(extras);
    584         assertTrue(extras.containsKey(TEST_EXTRA_KEY));
    585         assertEquals(TEST_SUBJECT, extras.getString(TEST_EXTRA_KEY));
    586         assertTrue(extras.containsKey(TEST_EXTRA_KEY2));
    587         assertEquals(TEST_EXTRA_VALUE, extras.getInt(TEST_EXTRA_KEY2));
    588         assertTrue(extras.containsKey(TEST_EXTRA_KEY3));
    589         assertEquals(TEST_SUBJECT, extras.getString(TEST_EXTRA_KEY3));
    590         return counter;
    591     }
    592 
    593     /**
    594      * Tests that {@link Connection} events are propagated from
    595      * {@link Connection#sendConnectionEvent(String, Bundle)} to
    596      * {@link android.telecom.Call.Callback#onConnectionEvent(Call, String, Bundle)}.
    597      */
    598     public void testConnectionEvent() {
    599         if (!mShouldTestTelecom) {
    600             return;
    601         }
    602 
    603         Bundle testBundle = new Bundle();
    604         testBundle.putString(TEST_EXTRA_KEY, TEST_SUBJECT);
    605 
    606         mConnection.sendConnectionEvent(Connection.EVENT_CALL_PULL_FAILED, testBundle);
    607         mOnConnectionEventCounter.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
    608         String event = (String) (mOnConnectionEventCounter.getArgs(0)[1]);
    609         Bundle extras = (Bundle) (mOnConnectionEventCounter.getArgs(0)[2]);
    610 
    611         assertEquals(Connection.EVENT_CALL_PULL_FAILED, event);
    612         assertNotNull(extras);
    613         assertTrue(extras.containsKey(TEST_EXTRA_KEY));
    614         assertEquals(TEST_SUBJECT, extras.getString(TEST_EXTRA_KEY));
    615     }
    616 
    617     /**
    618      * Verifies that a request to deflect a ringing {@link Call} is relayed to a {@link Connection}.
    619      */
    620     public void testDeflect() {
    621         if (!mShouldTestTelecom) {
    622             return;
    623         }
    624         // Only ringing calls support deflection
    625         mConnection.setRinging();
    626         assertCallState(mCall, Call.STATE_RINGING);
    627 
    628         final InvokeCounter counter = mConnection.getInvokeCounter(MockConnection.ON_DEFLECT);
    629         mCall.deflect(TEST_DEFLECT_URI);
    630         counter.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
    631         Uri address = (Uri) (counter.getArgs(0)[0]);
    632 
    633         assertEquals(TEST_DEFLECT_URI, address);
    634     }
    635 
    636     /**
    637      * Tests that {@link Call} events are propagated from {@link Call#sendCallEvent(String, Bundle)}
    638      * to {@link Connection#onCallEvent(String, Bundle)}.
    639      */
    640     public void testCallEvent() {
    641         if (!mShouldTestTelecom) {
    642             return;
    643         }
    644 
    645         Bundle testBundle = new Bundle();
    646         testBundle.putString(TEST_EXTRA_KEY, TEST_SUBJECT);
    647         final InvokeCounter counter = mConnection.getInvokeCounter(MockConnection.ON_CALL_EVENT);
    648         mCall.sendCallEvent(TEST_EVENT, testBundle);
    649         counter.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
    650 
    651         String event = (String) (counter.getArgs(0)[0]);
    652         Bundle extras = (Bundle) (counter.getArgs(0)[1]);
    653 
    654         assertEquals(TEST_EVENT, event);
    655         assertNotNull(extras);
    656         assertTrue(extras.containsKey(TEST_EXTRA_KEY));
    657         assertEquals(TEST_SUBJECT, extras.getString(TEST_EXTRA_KEY));
    658     }
    659 
    660     /**
    661      * Asserts that a call's extras contain a specified key.
    662      *
    663      * @param call The call.
    664      * @param expectedKey The expected extras key.
    665      */
    666     private void assertCallExtras(final Call call, final String expectedKey) {
    667         waitUntilConditionIsTrueOrTimeout(
    668                 new Condition() {
    669                     @Override
    670                     public Object expected() {
    671                         return expectedKey;
    672                     }
    673 
    674                     @Override
    675                     public Object actual() {
    676                         return call.getDetails().getExtras().containsKey(expectedKey) ? expectedKey
    677                                 : "";
    678                     }
    679                 },
    680                 TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
    681                 "Call should have extras key " + expectedKey
    682         );
    683     }
    684 }
    685