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