Home | History | Annotate | Download | only in telephony
      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 
     17 package com.android.services.telephony;
     18 
     19 import android.os.AsyncResult;
     20 import android.os.Handler;
     21 import android.telephony.ServiceState;
     22 import android.support.test.runner.AndroidJUnit4;
     23 import android.support.test.filters.FlakyTest;
     24 import android.test.suitebuilder.annotation.SmallTest;
     25 
     26 import com.android.TelephonyTestBase;
     27 import com.android.internal.telephony.Phone;
     28 import com.android.internal.telephony.PhoneConstants;
     29 import com.android.internal.telephony.ServiceStateTracker;
     30 
     31 import org.junit.After;
     32 import org.junit.Before;
     33 import org.junit.Test;
     34 import org.junit.runner.RunWith;
     35 import org.mockito.Mock;
     36 
     37 import static org.mockito.Matchers.anyBoolean;
     38 import static org.mockito.Matchers.isNull;
     39 import static org.mockito.Mockito.never;
     40 import static org.mockito.Mockito.times;
     41 import static org.mockito.Mockito.verify;
     42 import static org.mockito.Mockito.any;
     43 import static org.mockito.Mockito.eq;
     44 import static org.mockito.Mockito.when;
     45 
     46 /**
     47  * Tests the EmergencyCallStateListener, which listens to one Phone and waits until its service
     48  * state changes to accepting emergency calls or in service. If it can not find a tower to camp onto
     49  * for emergency calls, then it will fail after a timeout period.
     50  */
     51 @RunWith(AndroidJUnit4.class)
     52 public class EmergencyCallStateListenerTest extends TelephonyTestBase {
     53 
     54     private static final long TIMEOUT_MS = 100;
     55 
     56     @Mock Phone mMockPhone;
     57     @Mock ServiceStateTracker mMockServiceStateTracker;
     58     @Mock EmergencyCallStateListener.Callback mCallback;
     59     EmergencyCallStateListener mListener;
     60 
     61     @Before
     62     public void setUp() throws Exception {
     63         super.setUp();
     64         mListener = new EmergencyCallStateListener();
     65     }
     66 
     67     @After
     68     public void tearDown() throws Exception {
     69         mListener.getHandler().removeCallbacksAndMessages(null);
     70         super.tearDown();
     71     }
     72 
     73     /**
     74      * Ensure that we successfully register for the ServiceState changed messages in Telephony.
     75      */
     76     @Test
     77     @SmallTest
     78     public void testRegisterForCallback() {
     79         mListener.waitForRadioOn(mMockPhone, mCallback);
     80 
     81         waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
     82 
     83         verify(mMockPhone).unregisterForServiceStateChanged(any(Handler.class));
     84         verify(mMockPhone).registerForServiceStateChanged(any(Handler.class),
     85                 eq(EmergencyCallStateListener.MSG_SERVICE_STATE_CHANGED), isNull());
     86     }
     87 
     88     /**
     89      * Prerequisites:
     90      *  - Phone is IN_SERVICE
     91      *  - Radio is on
     92      *
     93      * Test: Send SERVICE_STATE_CHANGED message
     94      *
     95      * Result: callback's onComplete is called with the isRadioReady=true
     96      */
     97     @Test
     98     @SmallTest
     99     public void testPhoneChangeState_InService() {
    100         ServiceState state = new ServiceState();
    101         state.setState(ServiceState.STATE_IN_SERVICE);
    102         when(mMockPhone.getState()).thenReturn(PhoneConstants.State.IDLE);
    103         when(mMockPhone.getServiceStateTracker()).thenReturn(mMockServiceStateTracker);
    104         when(mMockServiceStateTracker.isRadioOn()).thenReturn(true);
    105         mListener.waitForRadioOn(mMockPhone, mCallback);
    106         waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
    107 
    108         mListener.getHandler().obtainMessage(EmergencyCallStateListener.MSG_SERVICE_STATE_CHANGED,
    109                 new AsyncResult(null, state, null)).sendToTarget();
    110 
    111         waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
    112         verify(mCallback).onComplete(eq(mListener), eq(true));
    113     }
    114 
    115     /**
    116      * Prerequisites:
    117      *  - Phone is OUT_OF_SERVICE (emergency calls only)
    118      *  - Radio is on
    119      *
    120      * Test: Send SERVICE_STATE_CHANGED message
    121      *
    122      * Result: callback's onComplete is called with the isRadioReady=true
    123      */
    124     @Test
    125     @SmallTest
    126     public void testPhoneChangeState_EmergencyCalls() {
    127         ServiceState state = new ServiceState();
    128         state.setState(ServiceState.STATE_OUT_OF_SERVICE);
    129         state.setEmergencyOnly(true);
    130         when(mMockPhone.getState()).thenReturn(PhoneConstants.State.IDLE);
    131         when(mMockPhone.getServiceState()).thenReturn(state);
    132         when(mMockPhone.getServiceStateTracker()).thenReturn(mMockServiceStateTracker);
    133         when(mMockServiceStateTracker.isRadioOn()).thenReturn(true);
    134         mListener.waitForRadioOn(mMockPhone, mCallback);
    135         waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
    136 
    137         mListener.getHandler().obtainMessage(EmergencyCallStateListener.MSG_SERVICE_STATE_CHANGED,
    138                 new AsyncResult(null, state, null)).sendToTarget();
    139 
    140         waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
    141         verify(mCallback).onComplete(eq(mListener), eq(true));
    142     }
    143 
    144     /**
    145      * Prerequisites:
    146      *  - Phone is OUT_OF_SERVICE
    147      *  - Radio is on
    148      *
    149      * Test: Send SERVICE_STATE_CHANGED message
    150      *
    151      * Result: callback's onComplete is called with the isRadioReady=true. Even though the radio is
    152      * not reporting emergency calls only, we still send onComplete so that the radio can trigger
    153      * the emergency call.
    154      */
    155     @Test
    156     @SmallTest
    157     public void testPhoneChangeState_OutOfService() {
    158         ServiceState state = new ServiceState();
    159         state.setState(ServiceState.STATE_OUT_OF_SERVICE);
    160         when(mMockPhone.getState()).thenReturn(PhoneConstants.State.IDLE);
    161         when(mMockPhone.getServiceState()).thenReturn(state);
    162         when(mMockPhone.getServiceStateTracker()).thenReturn(mMockServiceStateTracker);
    163         when(mMockServiceStateTracker.isRadioOn()).thenReturn(true);
    164         mListener.waitForRadioOn(mMockPhone, mCallback);
    165         waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
    166 
    167         // Still expect an answer because we will be sending the onComplete message as soon as the
    168         // radio is confirmed to be on, whether or not it is out of service or not.
    169         mListener.getHandler().obtainMessage(EmergencyCallStateListener.MSG_SERVICE_STATE_CHANGED,
    170                 new AsyncResult(null, state, null)).sendToTarget();
    171 
    172         waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
    173         verify(mCallback).onComplete(eq(mListener), eq(true));
    174     }
    175 
    176     /**
    177      * Prerequisites:
    178      *  - Phone is OUT_OF_SERVICE (emergency calls only)
    179      *  - Radio is on
    180      *
    181      * Test: Wait for retry timer to complete (don't send ServiceState changed message)
    182      *
    183      * Result: callback's onComplete is called with the isRadioReady=true.
    184      */
    185     @Test
    186     @FlakyTest
    187     @SmallTest
    188     public void testTimeout_EmergencyCalls() {
    189         ServiceState state = new ServiceState();
    190         state.setState(ServiceState.STATE_OUT_OF_SERVICE);
    191         state.setEmergencyOnly(true);
    192         when(mMockPhone.getState()).thenReturn(PhoneConstants.State.IDLE);
    193         when(mMockPhone.getServiceState()).thenReturn(state);
    194         when(mMockPhone.getServiceStateTracker()).thenReturn(mMockServiceStateTracker);
    195         when(mMockServiceStateTracker.isRadioOn()).thenReturn(true);
    196         mListener.setTimeBetweenRetriesMillis(100);
    197 
    198         // Wait for the timer to expire and check state manually in onRetryTimeout
    199         mListener.waitForRadioOn(mMockPhone, mCallback);
    200         waitForHandlerActionDelayed(mListener.getHandler(), TIMEOUT_MS, 500);
    201 
    202         verify(mCallback).onComplete(eq(mListener), eq(true));
    203     }
    204 
    205     /**
    206      * Prerequisites:
    207      *  - Phone is OUT_OF_SERVICE
    208      *  - Radio is off
    209      *
    210      * Test: Wait for retry timer to complete, no ServiceState changed messages received.
    211      *
    212      * Result:
    213      * - callback's onComplete is called with the isRadioReady=false.
    214      * - setRadioPower was send twice (tried to turn on the radio)
    215      */
    216     @Test
    217     @FlakyTest
    218     @SmallTest
    219     public void testTimeout_RetryFailure() {
    220         ServiceState state = new ServiceState();
    221         state.setState(ServiceState.STATE_POWER_OFF);
    222         when(mMockPhone.getState()).thenReturn(PhoneConstants.State.IDLE);
    223         when(mMockPhone.getServiceState()).thenReturn(state);
    224         when(mMockPhone.getServiceStateTracker()).thenReturn(mMockServiceStateTracker);
    225         when(mMockServiceStateTracker.isRadioOn()).thenReturn(false);
    226         mListener.setTimeBetweenRetriesMillis(50);
    227         mListener.setMaxNumRetries(2);
    228 
    229         // Wait for the timer to expire and check state manually in onRetryTimeout
    230         mListener.waitForRadioOn(mMockPhone, mCallback);
    231         waitForHandlerActionDelayed(mListener.getHandler(), TIMEOUT_MS, 500);
    232 
    233         verify(mCallback).onComplete(eq(mListener), eq(false));
    234         verify(mMockPhone, times(2)).setRadioPower(eq(true));
    235     }
    236 
    237 }
    238