NewOutgoingCallIntentBroadcasterTest.java revision c9cf54407720d32fdb1b69e0254657a6061b9f56
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 17package com.android.server.telecom.tests; 18 19import android.Manifest; 20import android.app.Activity; 21import android.app.AppOpsManager; 22import android.content.BroadcastReceiver; 23import android.content.ComponentName; 24import android.content.Context; 25import android.content.Intent; 26import android.net.Uri; 27import android.os.Bundle; 28import android.os.Handler; 29import android.os.UserHandle; 30import android.telecom.GatewayInfo; 31import android.telecom.TelecomManager; 32import android.telecom.VideoProfile; 33import android.telephony.DisconnectCause; 34import android.test.suitebuilder.annotation.SmallTest; 35 36import com.android.server.telecom.Call; 37import com.android.server.telecom.CallsManager; 38import com.android.server.telecom.NewOutgoingCallIntentBroadcaster; 39import com.android.server.telecom.PhoneNumberUtilsAdapter; 40import com.android.server.telecom.PhoneNumberUtilsAdapterImpl; 41import com.android.server.telecom.TelecomSystem; 42 43import org.mockito.ArgumentCaptor; 44import org.mockito.Mock; 45 46import static org.mockito.Matchers.any; 47import static org.mockito.Matchers.anyBoolean; 48import static org.mockito.Matchers.anyInt; 49import static org.mockito.Matchers.anyString; 50import static org.mockito.Matchers.eq; 51import static org.mockito.Matchers.isNotNull; 52import static org.mockito.Matchers.isNull; 53import static org.mockito.Mockito.doReturn; 54import static org.mockito.Mockito.never; 55import static org.mockito.Mockito.spy; 56import static org.mockito.Mockito.verify; 57import static org.mockito.Mockito.when; 58 59public class NewOutgoingCallIntentBroadcasterTest extends TelecomTestCase { 60 private static class ReceiverIntentPair { 61 public BroadcastReceiver receiver; 62 public Intent intent; 63 64 public ReceiverIntentPair(BroadcastReceiver receiver, Intent intent) { 65 this.receiver = receiver; 66 this.intent = intent; 67 } 68 } 69 70 @Mock private CallsManager mCallsManager; 71 @Mock private Call mCall; 72 73 private PhoneNumberUtilsAdapter mPhoneNumberUtilsAdapterSpy; 74 75 @Override 76 public void setUp() throws Exception { 77 super.setUp(); 78 mContext = mComponentContextFixture.getTestDouble().getApplicationContext(); 79 mPhoneNumberUtilsAdapterSpy = spy(new PhoneNumberUtilsAdapterImpl()); 80 when(mCall.getInitiatingUser()).thenReturn(UserHandle.CURRENT); 81 when(mCallsManager.getLock()).thenReturn(new TelecomSystem.SyncRoot() { }); 82 } 83 84 @SmallTest 85 public void testNullHandle() { 86 Intent intent = new Intent(Intent.ACTION_CALL, null); 87 int result = processIntent(intent, true); 88 assertEquals(DisconnectCause.INVALID_NUMBER, result); 89 verifyNoBroadcastSent(); 90 verifyNoCallPlaced(); 91 } 92 93 @SmallTest 94 public void testVoicemailCall() { 95 String voicemailNumber = "voicemail:18005551234"; 96 Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(voicemailNumber)); 97 intent.putExtra(TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE, true); 98 99 int result = processIntent(intent, true); 100 101 assertEquals(DisconnectCause.NOT_DISCONNECTED, result); 102 verify(mCallsManager).placeOutgoingCall(eq(mCall), eq(Uri.parse(voicemailNumber)), 103 any(GatewayInfo.class), eq(true), eq(VideoProfile.STATE_AUDIO_ONLY)); 104 } 105 106 @SmallTest 107 public void testVoicemailCallWithBadAction() { 108 badCallActionHelper(Uri.parse("voicemail:18005551234"), DisconnectCause.OUTGOING_CANCELED); 109 } 110 111 @SmallTest 112 public void testTelCallWithBadCallAction() { 113 badCallActionHelper(Uri.parse("tel:6505551234"), DisconnectCause.INVALID_NUMBER); 114 } 115 116 @SmallTest 117 public void testSipCallWithBadCallAction() { 118 badCallActionHelper(Uri.parse("sip:testuser@testsite.com"), DisconnectCause.INVALID_NUMBER); 119 } 120 121 private void badCallActionHelper(Uri handle, int expectedCode) { 122 Intent intent = new Intent(Intent.ACTION_ALARM_CHANGED, handle); 123 124 int result = processIntent(intent, true); 125 126 assertEquals(expectedCode, result); 127 verifyNoBroadcastSent(); 128 verifyNoCallPlaced(); 129 } 130 131 @SmallTest 132 public void testAlreadyDisconnectedCall() { 133 Uri handle = Uri.parse("tel:6505551234"); 134 doReturn(true).when(mCall).isDisconnected(); 135 Intent callIntent = buildIntent(handle, Intent.ACTION_CALL, null); 136 ReceiverIntentPair result = regularCallTestHelper(callIntent, null); 137 138 result.receiver.setResultData( 139 result.intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER)); 140 141 result.receiver.onReceive(mContext, result.intent); 142 verifyNoCallPlaced(); 143 } 144 145 @SmallTest 146 public void testNoNumberSupplied() { 147 Uri handle = Uri.parse("tel:"); 148 Intent intent = new Intent(Intent.ACTION_CALL, handle); 149 150 int result = processIntent(intent, true); 151 152 assertEquals(DisconnectCause.NO_PHONE_NUMBER_SUPPLIED, result); 153 verifyNoBroadcastSent(); 154 verifyNoCallPlaced(); 155 } 156 157 @SmallTest 158 public void testEmergencyCallWithNonDefaultDialer() { 159 Uri handle = Uri.parse("tel:6505551911"); 160 doReturn(true).when(mPhoneNumberUtilsAdapterSpy).isPotentialLocalEmergencyNumber( 161 any(Context.class), eq(handle.getSchemeSpecificPart())); 162 Intent intent = new Intent(Intent.ACTION_CALL, handle); 163 164 String ui_package_string = "sample_string_1"; 165 String dialer_default_class_string = "sample_string_2"; 166 mComponentContextFixture.putResource(R.string.ui_default_package, ui_package_string); 167 mComponentContextFixture.putResource(R.string.dialer_default_class, 168 dialer_default_class_string); 169 170 int result = processIntent(intent, false); 171 172 assertEquals(DisconnectCause.OUTGOING_CANCELED, result); 173 verifyNoBroadcastSent(); 174 verifyNoCallPlaced(); 175 176 ArgumentCaptor<Intent> dialerIntentCaptor = ArgumentCaptor.forClass(Intent.class); 177 verify(mContext).startActivityAsUser(dialerIntentCaptor.capture(), any(UserHandle.class)); 178 Intent dialerIntent = dialerIntentCaptor.getValue(); 179 assertEquals(new ComponentName(ui_package_string, dialer_default_class_string), 180 dialerIntent.getComponent()); 181 assertEquals(Intent.ACTION_DIAL, dialerIntent.getAction()); 182 assertEquals(handle, dialerIntent.getData()); 183 assertEquals(Intent.FLAG_ACTIVITY_NEW_TASK, dialerIntent.getFlags()); 184 } 185 186 @SmallTest 187 public void testActionCallEmergencyCall() { 188 Uri handle = Uri.parse("tel:6505551911"); 189 Intent intent = buildIntent(handle, Intent.ACTION_CALL, null); 190 emergencyCallTestHelper(intent, null); 191 } 192 193 @SmallTest 194 public void testActionEmergencyWithEmergencyNumber() { 195 Uri handle = Uri.parse("tel:6505551911"); 196 Intent intent = buildIntent(handle, Intent.ACTION_CALL_EMERGENCY, null); 197 emergencyCallTestHelper(intent, null); 198 } 199 200 @SmallTest 201 public void testActionPrivCallWithEmergencyNumber() { 202 Uri handle = Uri.parse("tel:6505551911"); 203 Intent intent = buildIntent(handle, Intent.ACTION_CALL_PRIVILEGED, null); 204 emergencyCallTestHelper(intent, null); 205 } 206 207 @SmallTest 208 public void testEmergencyCallWithGatewayExtras() { 209 Uri handle = Uri.parse("tel:6505551911"); 210 Bundle gatewayExtras = new Bundle(); 211 gatewayExtras.putString(NewOutgoingCallIntentBroadcaster.EXTRA_GATEWAY_PROVIDER_PACKAGE, 212 "sample1"); 213 gatewayExtras.putString(NewOutgoingCallIntentBroadcaster.EXTRA_GATEWAY_URI, "sample2"); 214 215 Intent intent = buildIntent(handle, Intent.ACTION_CALL, gatewayExtras); 216 emergencyCallTestHelper(intent, gatewayExtras); 217 } 218 219 @SmallTest 220 public void testActionEmergencyWithNonEmergencyNumber() { 221 Uri handle = Uri.parse("tel:6505551911"); 222 doReturn(false).when(mPhoneNumberUtilsAdapterSpy).isPotentialLocalEmergencyNumber( 223 any(Context.class), eq(handle.getSchemeSpecificPart())); 224 Intent intent = new Intent(Intent.ACTION_CALL_EMERGENCY, handle); 225 int result = processIntent(intent, true); 226 227 assertEquals(DisconnectCause.OUTGOING_CANCELED, result); 228 verifyNoCallPlaced(); 229 verifyNoBroadcastSent(); 230 } 231 232 private void emergencyCallTestHelper(Intent intent, Bundle expectedAdditionalExtras) { 233 Uri handle = intent.getData(); 234 int videoState = VideoProfile.STATE_BIDIRECTIONAL; 235 boolean isSpeakerphoneOn = true; 236 doReturn(true).when(mPhoneNumberUtilsAdapterSpy).isPotentialLocalEmergencyNumber( 237 any(Context.class), eq(handle.getSchemeSpecificPart())); 238 intent.putExtra(TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE, isSpeakerphoneOn); 239 intent.putExtra(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, videoState); 240 int result = processIntent(intent, true); 241 242 assertEquals(DisconnectCause.NOT_DISCONNECTED, result); 243 verify(mCallsManager).placeOutgoingCall(eq(mCall), eq(handle), isNull(GatewayInfo.class), 244 eq(isSpeakerphoneOn), eq(videoState)); 245 246 Bundle expectedExtras = createNumberExtras(handle.getSchemeSpecificPart()); 247 if (expectedAdditionalExtras != null) { 248 expectedExtras.putAll(expectedAdditionalExtras); 249 } 250 BroadcastReceiver receiver = verifyBroadcastSent(handle.getSchemeSpecificPart(), 251 expectedExtras).receiver; 252 assertNull(receiver); 253 } 254 255 @SmallTest 256 public void testUnmodifiedRegularCall() { 257 Uri handle = Uri.parse("tel:6505551234"); 258 Intent callIntent = buildIntent(handle, Intent.ACTION_CALL, null); 259 ReceiverIntentPair result = regularCallTestHelper(callIntent, null); 260 261 result.receiver.setResultData( 262 result.intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER)); 263 264 result.receiver.onReceive(mContext, result.intent); 265 266 verify(mCallsManager).placeOutgoingCall(eq(mCall), eq(handle), isNull(GatewayInfo.class), 267 eq(true), eq(VideoProfile.STATE_BIDIRECTIONAL)); 268 } 269 270 @SmallTest 271 public void testUnmodifiedSipCall() { 272 Uri handle = Uri.parse("sip:test@test.com"); 273 Intent callIntent = buildIntent(handle, Intent.ACTION_CALL, null); 274 ReceiverIntentPair result = regularCallTestHelper(callIntent, null); 275 276 result.receiver.setResultData( 277 result.intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER)); 278 279 result.receiver.onReceive(mContext, result.intent); 280 281 Uri encHandle = Uri.fromParts(handle.getScheme(), 282 handle.getSchemeSpecificPart(), null); 283 verify(mCallsManager).placeOutgoingCall(eq(mCall), eq(encHandle), isNull(GatewayInfo.class), 284 eq(true), eq(VideoProfile.STATE_BIDIRECTIONAL)); 285 } 286 287 @SmallTest 288 public void testCallWithGatewayInfo() { 289 Uri handle = Uri.parse("tel:6505551234"); 290 Intent callIntent = buildIntent(handle, Intent.ACTION_CALL, null); 291 292 callIntent.putExtra(NewOutgoingCallIntentBroadcaster 293 .EXTRA_GATEWAY_PROVIDER_PACKAGE, "sample1"); 294 callIntent.putExtra(NewOutgoingCallIntentBroadcaster.EXTRA_GATEWAY_URI, "sample2"); 295 ReceiverIntentPair result = regularCallTestHelper(callIntent, callIntent.getExtras()); 296 297 result.receiver.setResultData( 298 result.intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER)); 299 300 result.receiver.onReceive(mContext, result.intent); 301 302 verify(mCallsManager).placeOutgoingCall(eq(mCall), eq(handle), 303 isNotNull(GatewayInfo.class), eq(true), eq(VideoProfile.STATE_BIDIRECTIONAL)); 304 } 305 306 @SmallTest 307 public void testCallNumberModifiedToNull() { 308 Uri handle = Uri.parse("tel:6505551234"); 309 Intent callIntent = buildIntent(handle, Intent.ACTION_CALL, null); 310 ReceiverIntentPair result = regularCallTestHelper(callIntent, null); 311 312 result.receiver.setResultData(null); 313 314 result.receiver.onReceive(mContext, result.intent); 315 verifyNoCallPlaced(); 316 verify(mCall).disconnect(true); 317 } 318 319 @SmallTest 320 public void testCallModifiedToEmergency() { 321 Uri handle = Uri.parse("tel:6505551234"); 322 Intent callIntent = buildIntent(handle, Intent.ACTION_CALL, null); 323 ReceiverIntentPair result = regularCallTestHelper(callIntent, null); 324 325 String newEmergencyNumber = "1234567890"; 326 result.receiver.setResultData(newEmergencyNumber); 327 328 doReturn(true).when(mPhoneNumberUtilsAdapterSpy).isPotentialLocalEmergencyNumber( 329 any(Context.class), eq(newEmergencyNumber)); 330 result.receiver.onReceive(mContext, result.intent); 331 verify(mCall).disconnect(true); 332 } 333 334 private ReceiverIntentPair regularCallTestHelper(Intent intent, 335 Bundle expectedAdditionalExtras) { 336 Uri handle = intent.getData(); 337 int videoState = VideoProfile.STATE_BIDIRECTIONAL; 338 boolean isSpeakerphoneOn = true; 339 intent.putExtra(TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE, isSpeakerphoneOn); 340 intent.putExtra(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, videoState); 341 342 int result = processIntent(intent, true); 343 344 assertEquals(DisconnectCause.NOT_DISCONNECTED, result); 345 Bundle expectedExtras = createNumberExtras(handle.getSchemeSpecificPart()); 346 if (expectedAdditionalExtras != null) { 347 expectedExtras.putAll(expectedAdditionalExtras); 348 } 349 return verifyBroadcastSent(handle.getSchemeSpecificPart(), expectedExtras); 350 } 351 352 private Intent buildIntent(Uri handle, String action, Bundle extras) { 353 Intent i = new Intent(action, handle); 354 if (extras != null) { 355 i.putExtras(extras); 356 } 357 return i; 358 } 359 360 private int processIntent(Intent intent, 361 boolean isDefaultPhoneApp) { 362 NewOutgoingCallIntentBroadcaster b = new NewOutgoingCallIntentBroadcaster( 363 mContext, mCallsManager, mCall, intent, mPhoneNumberUtilsAdapterSpy, 364 isDefaultPhoneApp); 365 return b.processIntent(); 366 } 367 368 private ReceiverIntentPair verifyBroadcastSent(String number, Bundle expectedExtras) { 369 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 370 ArgumentCaptor<BroadcastReceiver> receiverCaptor = 371 ArgumentCaptor.forClass(BroadcastReceiver.class); 372 373 verify(mContext).sendOrderedBroadcastAsUser( 374 intentCaptor.capture(), 375 eq(UserHandle.CURRENT), 376 eq(Manifest.permission.PROCESS_OUTGOING_CALLS), 377 eq(AppOpsManager.OP_PROCESS_OUTGOING_CALLS), 378 receiverCaptor.capture(), 379 isNull(Handler.class), 380 eq(Activity.RESULT_OK), 381 eq(number), 382 isNull(Bundle.class)); 383 384 Intent capturedIntent = intentCaptor.getValue(); 385 assertEquals(Intent.ACTION_NEW_OUTGOING_CALL, capturedIntent.getAction()); 386 assertEquals(Intent.FLAG_RECEIVER_FOREGROUND, capturedIntent.getFlags()); 387 assertTrue(areBundlesEqual(expectedExtras, capturedIntent.getExtras())); 388 389 BroadcastReceiver receiver = receiverCaptor.getValue(); 390 if (receiver != null) { 391 receiver.setPendingResult( 392 new BroadcastReceiver.PendingResult(0, "", null, 0, true, false, null, 0, 0)); 393 } 394 395 return new ReceiverIntentPair(receiver, capturedIntent); 396 } 397 398 private Bundle createNumberExtras(String number) { 399 Bundle b = new Bundle(); 400 b.putString(Intent.EXTRA_PHONE_NUMBER, number); 401 return b; 402 } 403 404 private void verifyNoCallPlaced() { 405 verify(mCallsManager, never()).placeOutgoingCall(any(Call.class), any(Uri.class), 406 any(GatewayInfo.class), anyBoolean(), anyInt()); 407 } 408 409 private void verifyNoBroadcastSent() { 410 verify(mContext, never()).sendOrderedBroadcastAsUser( 411 any(Intent.class), 412 any(UserHandle.class), 413 anyString(), 414 anyInt(), 415 any(BroadcastReceiver.class), 416 any(Handler.class), 417 anyInt(), 418 anyString(), 419 any(Bundle.class)); 420 } 421 422 private static boolean areBundlesEqual(Bundle b1, Bundle b2) { 423 for (String key1 : b1.keySet()) { 424 if (!b1.get(key1).equals(b2.get(key1))) { 425 return false; 426 } 427 } 428 429 for (String key2 : b2.keySet()) { 430 if (!b2.get(key2).equals(b1.get(key2))) { 431 return false; 432 } 433 } 434 return true; 435 } 436} 437