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 17package com.android.services.telephony; 18 19import android.os.AsyncResult; 20import android.os.Handler; 21import android.telephony.ServiceState; 22import android.support.test.runner.AndroidJUnit4; 23import android.support.test.filters.FlakyTest; 24import android.test.suitebuilder.annotation.SmallTest; 25 26import com.android.TelephonyTestBase; 27import com.android.internal.telephony.Phone; 28import com.android.internal.telephony.PhoneConstants; 29import com.android.internal.telephony.ServiceStateTracker; 30 31import org.junit.After; 32import org.junit.Before; 33import org.junit.Test; 34import org.junit.runner.RunWith; 35import org.mockito.Mock; 36 37import static org.mockito.Matchers.anyBoolean; 38import static org.mockito.Matchers.isNull; 39import static org.mockito.Mockito.never; 40import static org.mockito.Mockito.times; 41import static org.mockito.Mockito.verify; 42import static org.mockito.Mockito.any; 43import static org.mockito.Mockito.eq; 44import 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) 52public 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