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