Home | History | Annotate | Download | only in imsphone
      1 /*
      2  * Copyright (C) 2016 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 package com.android.internal.telephony.imsphone;
     17 
     18 import android.os.AsyncResult;
     19 import android.os.Bundle;
     20 import android.os.Handler;
     21 import android.os.Looper;
     22 import android.os.Message;
     23 import android.telephony.DisconnectCause;
     24 import android.telephony.PhoneNumberUtils;
     25 import android.telephony.ServiceState;
     26 import android.telephony.ims.ImsCallProfile;
     27 import android.test.suitebuilder.annotation.MediumTest;
     28 import android.test.suitebuilder.annotation.SmallTest;
     29 
     30 import com.android.internal.telephony.Call;
     31 import com.android.internal.telephony.Connection;
     32 import com.android.internal.telephony.GsmCdmaCall;
     33 import com.android.internal.telephony.PhoneConstants;
     34 import com.android.internal.telephony.TelephonyTest;
     35 
     36 import org.junit.After;
     37 import org.junit.Assert;
     38 import org.junit.Before;
     39 import org.junit.Test;
     40 import org.mockito.Mock;
     41 import org.mockito.invocation.InvocationOnMock;
     42 import org.mockito.stubbing.Answer;
     43 
     44 import java.lang.reflect.Field;
     45 
     46 import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
     47 import static org.junit.Assert.assertEquals;
     48 import static org.junit.Assert.assertFalse;
     49 import static org.junit.Assert.assertNull;
     50 import static org.junit.Assert.assertTrue;
     51 import static org.mockito.Mockito.any;
     52 import static org.mockito.Mockito.anyChar;
     53 import static org.mockito.Mockito.doAnswer;
     54 import static org.mockito.Mockito.doReturn;
     55 import static org.mockito.Mockito.eq;
     56 import static org.mockito.Mockito.times;
     57 import static org.mockito.Mockito.verify;
     58 
     59 public class ImsPhoneConnectionTest extends TelephonyTest {
     60     private ImsPhoneConnection mConnectionUT;
     61     private Bundle mBundle = new Bundle();
     62     @Mock
     63     private ImsPhoneCall mForeGroundCall;
     64     @Mock
     65     private ImsPhoneCall mBackGroundCall;
     66     @Mock
     67     private ImsPhoneCall mRingGroundCall;
     68 
     69     @Before
     70     public void setUp() throws Exception {
     71         super.setUp(getClass().getSimpleName());
     72         replaceInstance(Handler.class, "mLooper", mImsCT, Looper.getMainLooper());
     73         replaceInstance(ImsPhoneCallTracker.class, "mForegroundCall", mImsCT, mForeGroundCall);
     74         replaceInstance(ImsPhoneCallTracker.class, "mBackgroundCall", mImsCT, mBackGroundCall);
     75         replaceInstance(ImsPhoneCallTracker.class, "mRingingCall", mImsCT, mRingGroundCall);
     76         replaceInstance(ImsPhoneCallTracker.class, "mPhone", mImsCT, mImsPhone);
     77 
     78         mImsCallProfile.mCallExtras = mBundle;
     79         doReturn(ImsPhoneCall.State.IDLE).when(mForeGroundCall).getState();
     80     }
     81 
     82     @After
     83     public void tearDown() throws Exception {
     84         super.tearDown();
     85     }
     86 
     87     @Test
     88     @SmallTest
     89     public void testImsConnectionSanity() {
     90         logd("Testing initial state of MT ImsPhoneConnection");
     91         mConnectionUT = new ImsPhoneConnection(mImsPhone, mImsCall, mImsCT, mForeGroundCall, false);
     92 
     93         assertEquals(ImsPhoneCall.State.IDLE, mConnectionUT.getState());
     94         assertEquals(PhoneConstants.PRESENTATION_UNKNOWN, mConnectionUT.getNumberPresentation());
     95         assertEquals(PhoneConstants.PRESENTATION_UNKNOWN, mConnectionUT.getCnapNamePresentation());
     96         assertEquals(Connection.PostDialState.NOT_STARTED, mConnectionUT.getPostDialState());
     97         assertEquals(0, mConnectionUT.getDisconnectTime());
     98         assertEquals(0, mConnectionUT.getHoldDurationMillis());
     99         assertNull(mConnectionUT.getOrigDialString());
    100         assertFalse(mConnectionUT.isMultiparty());
    101         assertFalse(mConnectionUT.isConferenceHost());
    102         verify(mForeGroundCall, times(1)).attach((Connection) any(),
    103                 eq(ImsPhoneCall.State.INCOMING));
    104 
    105         logd("Testing initial state of MO ImsPhoneConnection");
    106         mConnectionUT = new ImsPhoneConnection(mImsPhone, String.format("+1 (700).555-41NN%c1234",
    107                 PhoneNumberUtils.PAUSE), mImsCT, mForeGroundCall, false);
    108         assertEquals(PhoneConstants.PRESENTATION_ALLOWED, mConnectionUT.getNumberPresentation());
    109         assertEquals(PhoneConstants.PRESENTATION_ALLOWED, mConnectionUT.getCnapNamePresentation());
    110         assertEquals("+1 (700).555-41NN,1234", mConnectionUT.getOrigDialString());
    111         verify(mForeGroundCall, times(1)).attachFake((Connection) any(),
    112                 eq(ImsPhoneCall.State.DIALING));
    113     }
    114 
    115     @Test
    116     @SmallTest
    117     public void testImsUpdateStateForeGround() {
    118         // MO Foreground Connection dailing -> active
    119         mConnectionUT = new ImsPhoneConnection(mImsPhone, "+1 (700).555-41NN1234", mImsCT,
    120                 mForeGroundCall, false);
    121         // initially in dialing state
    122         doReturn(Call.State.DIALING).when(mForeGroundCall).getState();
    123         assertTrue(mConnectionUT.update(mImsCall, Call.State.ACTIVE));
    124         // for Ringing/Dialing upadte postDialState
    125         assertEquals(Connection.PostDialState.COMPLETE, mConnectionUT.getPostDialState());
    126         verify(mForeGroundCall, times(1)).update(eq(mConnectionUT), eq(mImsCall),
    127                 eq(Call.State.ACTIVE));
    128     }
    129 
    130     @Test
    131     @SmallTest
    132     public void testImsUpdateStateBackGround() {
    133         // MT background Connection dialing -> active
    134         mConnectionUT = new ImsPhoneConnection(mImsPhone, mImsCall, mImsCT, mBackGroundCall, false);
    135         doReturn(Call.State.HOLDING).when(mBackGroundCall).getState();
    136         assertFalse(mConnectionUT.update(mImsCall, Call.State.ACTIVE));
    137         verify(mBackGroundCall, times(1)).detach(eq(mConnectionUT));
    138         verify(mForeGroundCall, times(1)).attach(eq(mConnectionUT));
    139         verify(mForeGroundCall, times(1)).update(eq(mConnectionUT), eq(mImsCall),
    140                 eq(Call.State.ACTIVE));
    141         assertEquals(Connection.PostDialState.NOT_STARTED, mConnectionUT.getPostDialState());
    142     }
    143 
    144     @Test
    145     @SmallTest
    146     public void testImsUpdateStatePendingHold() {
    147         mConnectionUT = new ImsPhoneConnection(mImsPhone, "+1 (700).555-41NN1234", mImsCT,
    148                 mForeGroundCall, false);
    149         doReturn(true).when(mImsCall).isPendingHold();
    150         assertFalse(mConnectionUT.update(mImsCall, Call.State.ACTIVE));
    151         verify(mForeGroundCall, times(0)).update(eq(mConnectionUT), eq(mImsCall),
    152                 eq(Call.State.ACTIVE));
    153         assertEquals(Connection.PostDialState.NOT_STARTED, mConnectionUT.getPostDialState());
    154     }
    155 
    156     @Test
    157     @SmallTest
    158     public void testUpdateAddressDisplay() {
    159         mConnectionUT = new ImsPhoneConnection(mImsPhone, mImsCall, mImsCT, mForeGroundCall, false);
    160         assertEquals(PhoneConstants.PRESENTATION_UNKNOWN, mConnectionUT.getNumberPresentation());
    161         assertEquals(PhoneConstants.PRESENTATION_UNKNOWN, mConnectionUT.getCnapNamePresentation());
    162         mImsCallProfile.setCallExtraInt(ImsCallProfile.EXTRA_CNAP,
    163                 ImsCallProfile.OIR_PRESENTATION_PAYPHONE);
    164         mImsCallProfile.setCallExtraInt(ImsCallProfile.EXTRA_OIR,
    165                 ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED);
    166 
    167         mConnectionUT.updateAddressDisplay(mImsCall);
    168         assertEquals(ImsCallProfile.OIRToPresentation(ImsCallProfile.OIR_PRESENTATION_PAYPHONE),
    169                 mConnectionUT.getCnapNamePresentation());
    170         assertEquals(ImsCallProfile.OIRToPresentation(
    171                         ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED),
    172                 mConnectionUT.getNumberPresentation());
    173     }
    174 
    175     @Test
    176     @SmallTest
    177     public void testConnectionDisconnect() {
    178         //Mock we have an active connection
    179         testImsUpdateStateForeGround();
    180         waitForMs(50);
    181         mConnectionUT.onDisconnect(DisconnectCause.LOCAL);
    182         assertEquals(DisconnectCause.LOCAL, mConnectionUT.getDisconnectCause());
    183         assertEquals(GsmCdmaCall.State.DISCONNECTED, mConnectionUT.getState());
    184         assertTrue(mConnectionUT.getDisconnectTime() <= System.currentTimeMillis());
    185         assertTrue(mConnectionUT.getDurationMillis() >= 50);
    186     }
    187 
    188     @Test
    189     @SmallTest
    190     public void testPostDialWait() {
    191         mConnectionUT = new ImsPhoneConnection(mImsPhone, String.format("+1 (700).555-41NN%c1234",
    192                 PhoneNumberUtils.WAIT), mImsCT, mForeGroundCall, false);
    193         doReturn(Call.State.DIALING).when(mForeGroundCall).getState();
    194         doAnswer(new Answer() {
    195             @Override
    196             public Void answer(InvocationOnMock invocation) throws Throwable {
    197                 Message msg = (Message) invocation.getArguments()[1];
    198                 AsyncResult.forMessage(msg);
    199                 msg.sendToTarget();
    200                 return  null;
    201             }
    202         }).when(mImsCT).sendDtmf(anyChar(), (Message) any());
    203         // process post dial string during update
    204         assertTrue(mConnectionUT.update(mImsCall, Call.State.ACTIVE));
    205         assertEquals(Connection.PostDialState.WAIT, mConnectionUT.getPostDialState());
    206         mConnectionUT.proceedAfterWaitChar();
    207         waitForMs(50);
    208         assertEquals(Connection.PostDialState.COMPLETE, mConnectionUT.getPostDialState());
    209     }
    210 
    211     @Test
    212     @MediumTest
    213     public void testPostDialPause() {
    214         mConnectionUT = new ImsPhoneConnection(mImsPhone, String.format("+1 (700).555-41NN%c1234",
    215                 PhoneNumberUtils.PAUSE), mImsCT, mForeGroundCall, false);
    216         doReturn(Call.State.DIALING).when(mForeGroundCall).getState();
    217         doAnswer(new Answer() {
    218             @Override
    219             public Void answer(InvocationOnMock invocation) throws Throwable {
    220                 Message msg = (Message) invocation.getArguments()[1];
    221                 AsyncResult.forMessage(msg);
    222                 msg.sendToTarget();
    223                 return null;
    224             }
    225         }).when(mImsCT).sendDtmf(anyChar(), (Message) any());
    226 
    227         // process post dial string during update
    228         assertTrue(mConnectionUT.update(mImsCall, Call.State.ACTIVE));
    229         assertEquals(Connection.PostDialState.STARTED, mConnectionUT.getPostDialState());
    230         try {
    231             Field field = ImsPhoneConnection.class.getDeclaredField("PAUSE_DELAY_MILLIS");
    232             field.setAccessible(true);
    233             waitForMs((Integer) field.get(null) + 50);
    234         } catch (Exception ex) {
    235             Assert.fail("unexpected exception thrown" + ex.getMessage());
    236         }
    237         assertEquals(Connection.PostDialState.COMPLETE, mConnectionUT.getPostDialState());
    238     }
    239 
    240     @Test
    241     @SmallTest
    242     public void testSetWifi() {
    243         mConnectionUT = new ImsPhoneConnection(mImsPhone, mImsCall, mImsCT, mForeGroundCall, false);
    244         assertFalse(mConnectionUT.isWifi());
    245         // ImsCall.isWifiCall is tested elsewhere
    246         doReturn(true).when(mImsCall).isWifiCall();
    247         mBundle.putString(ImsCallProfile.EXTRA_CALL_RAT_TYPE,
    248                 ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN + "");
    249         assertTrue(mConnectionUT.update(mImsCall, Call.State.ACTIVE));
    250         assertTrue(mConnectionUT.isWifi());
    251     }
    252 
    253     @Test
    254     @SmallTest
    255     public void testSetWifi2() {
    256         mConnectionUT = new ImsPhoneConnection(mImsPhone, mImsCall, mImsCT, mForeGroundCall, false);
    257         assertFalse(mConnectionUT.isWifi());
    258         // ImsCall.isWifiCall is tested elsewhere
    259         doReturn(true).when(mImsCall).isWifiCall();
    260         // Tests to make sure that the EXTRA_CALL_RAT_TYPE_ALT string is set correctly for newer
    261         // devices.
    262         mBundle.putString(ImsCallProfile.EXTRA_CALL_RAT_TYPE_ALT,
    263                 ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN + "");
    264         assertTrue(mConnectionUT.update(mImsCall, Call.State.ACTIVE));
    265         assertTrue(mConnectionUT.isWifi());
    266     }
    267 
    268     /**
    269      * Test updates to address for incoming calls.
    270      */
    271     @Test
    272     @SmallTest
    273     public void testAddressUpdate() {
    274         String[] testAddressMappingSet[] = {
    275                 /* {"inputAddress", "updateAddress", "ExpectResult"} */
    276                 {"12345", "12345", "12345"},
    277                 {"12345", "67890", "67890"},
    278                 {"12345*00000", "12345", "12345*00000"},
    279                 {"12345*00000", "67890", "67890"},
    280                 {"12345*00000", "12345*00000", "12345*00000"},
    281                 {"12345;11111*00000", "12345", "12345"},
    282                 {"12345*00000;11111", "12345", "12345*00000"},
    283                 {"18412345*00000", "18412345", "18412345*00000"},
    284                 {"+8112345*00000", "+8112345", "+8112345*00000"},
    285                 {"12345*00000", "12346", "12346"}};
    286         for (String[] testAddress : testAddressMappingSet) {
    287             mConnectionUT = new ImsPhoneConnection(mImsPhone, testAddress[0], mImsCT,
    288                     mForeGroundCall, false);
    289             mConnectionUT.setIsIncoming(true);
    290             mImsCallProfile.setCallExtra(ImsCallProfile.EXTRA_OI, testAddress[1]);
    291             mConnectionUT.updateAddressDisplay(mImsCall);
    292             assertEquals(testAddress[2], mConnectionUT.getAddress());
    293         }
    294     }
    295 
    296     /**
    297      * Ensure updates to the address for outgoing calls are ignored.
    298      */
    299     @Test
    300     @SmallTest
    301     public void testSetAddressOnOutgoing() {
    302         String inputAddress = "12345";
    303         String updateAddress = "6789";
    304 
    305         mConnectionUT = new ImsPhoneConnection(mImsPhone, inputAddress, mImsCT, mForeGroundCall,
    306                 false);
    307         mConnectionUT.setIsIncoming(false);
    308         mImsCallProfile.setCallExtra(ImsCallProfile.EXTRA_OI, updateAddress);
    309         mConnectionUT.updateAddressDisplay(mImsCall);
    310         assertEquals(inputAddress, mConnectionUT.getAddress());
    311     }
    312 }
    313