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.internal.telephony.imsphone;
18
19import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ENABLE;
20import static com.android.internal.telephony.CommandsInterface.CF_REASON_UNCONDITIONAL;
21import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
22
23import static org.junit.Assert.assertEquals;
24import static org.junit.Assert.assertNotNull;
25import static org.mockito.Matchers.any;
26import static org.mockito.Matchers.anyChar;
27import static org.mockito.Matchers.anyInt;
28import static org.mockito.Matchers.anyLong;
29import static org.mockito.Matchers.nullable;
30import static org.mockito.Mockito.atLeast;
31import static org.mockito.Mockito.doReturn;
32import static org.mockito.Mockito.eq;
33import static org.mockito.Mockito.never;
34import static org.mockito.Mockito.reset;
35import static org.mockito.Mockito.times;
36import static org.mockito.Mockito.verify;
37
38import android.app.Activity;
39import android.app.IApplicationThread;
40import android.content.BroadcastReceiver;
41import android.content.IIntentReceiver;
42import android.content.Intent;
43import android.os.AsyncResult;
44import android.os.Bundle;
45import android.os.Handler;
46import android.os.HandlerThread;
47import android.os.Message;
48import android.os.PersistableBundle;
49import android.os.SystemProperties;
50import android.support.test.filters.FlakyTest;
51import android.telephony.CarrierConfigManager;
52import android.telephony.ServiceState;
53import android.test.suitebuilder.annotation.SmallTest;
54
55import android.telephony.ims.ImsCallProfile;
56import com.android.ims.ImsEcbmStateListener;
57import com.android.ims.ImsManager;
58import android.telephony.ims.ImsReasonInfo;
59import com.android.ims.ImsUtInterface;
60import com.android.internal.telephony.Call;
61import com.android.internal.telephony.CommandsInterface;
62import com.android.internal.telephony.Connection;
63import com.android.internal.telephony.Phone;
64import com.android.internal.telephony.PhoneConstants;
65import com.android.internal.telephony.TelephonyIntents;
66import com.android.internal.telephony.TelephonyProperties;
67import com.android.internal.telephony.TelephonyTest;
68import com.android.internal.telephony.gsm.SuppServiceNotification;
69
70import org.junit.After;
71import org.junit.Before;
72import org.junit.Ignore;
73import org.junit.Test;
74import org.mockito.ArgumentCaptor;
75import org.mockito.Mock;
76
77import java.util.List;
78
79public class ImsPhoneTest extends TelephonyTest {
80    @Mock
81    private ImsPhoneCall mForegroundCall;
82    @Mock
83    private ImsPhoneCall mBackgroundCall;
84    @Mock
85    private ImsPhoneCall mRingingCall;
86    @Mock
87    private Handler mTestHandler;
88    @Mock
89    Connection mConnection;
90    @Mock
91    ImsUtInterface mImsUtInterface;
92
93    private ImsPhone mImsPhoneUT;
94    private ImsPhoneTestHandler mImsPhoneTestHandler;
95    private boolean mDoesRilSendMultipleCallRing;
96    private static final int EVENT_SUPP_SERVICE_NOTIFICATION = 1;
97    private static final int EVENT_SUPP_SERVICE_FAILED = 2;
98    private static final int EVENT_INCOMING_RING = 3;
99    private static final int EVENT_EMERGENCY_CALLBACK_MODE_EXIT = 4;
100
101    private class ImsPhoneTestHandler extends HandlerThread {
102
103        private ImsPhoneTestHandler(String name) {
104            super(name);
105        }
106
107        @Override
108        public void onLooperPrepared() {
109            mImsPhoneUT = new ImsPhone(mContext, mNotifier, mPhone, true);
110            setReady(true);
111        }
112    }
113
114    @Before
115    public void setUp() throws Exception {
116        super.setUp(getClass().getSimpleName());
117
118        mImsCT.mForegroundCall = mForegroundCall;
119        mImsCT.mBackgroundCall = mBackgroundCall;
120        mImsCT.mRingingCall = mRingingCall;
121        doReturn(Call.State.IDLE).when(mForegroundCall).getState();
122        doReturn(Call.State.IDLE).when(mBackgroundCall).getState();
123        doReturn(Call.State.IDLE).when(mRingingCall).getState();
124
125        mContextFixture.putBooleanResource(com.android.internal.R.bool.config_voice_capable, true);
126
127        mImsPhoneTestHandler = new ImsPhoneTestHandler(TAG);
128        mImsPhoneTestHandler.start();
129        waitUntilReady();
130
131        mDoesRilSendMultipleCallRing = SystemProperties.getBoolean(
132                TelephonyProperties.PROPERTY_RIL_SENDS_MULTIPLE_CALL_RING, true);
133        replaceInstance(Handler.class, "mLooper", mTestHandler, mImsPhoneUT.getLooper());
134        replaceInstance(Phone.class, "mLooper", mPhone, mImsPhoneUT.getLooper());
135        mImsPhoneUT.registerForSuppServiceNotification(mTestHandler,
136                EVENT_SUPP_SERVICE_NOTIFICATION, null);
137        mImsPhoneUT.registerForSuppServiceFailed(mTestHandler,
138                EVENT_SUPP_SERVICE_FAILED, null);
139        mImsPhoneUT.registerForIncomingRing(mTestHandler,
140                EVENT_INCOMING_RING, null);
141        doReturn(mImsUtInterface).when(mImsCT).getUtInterface();
142    }
143
144
145    @After
146    public void tearDown() throws Exception {
147        mImsPhoneUT = null;
148        mImsPhoneTestHandler.quit();
149        super.tearDown();
150    }
151
152    @Test
153    @SmallTest
154    public void testHandleInCallMmiCommandCallDeflection() throws Exception {
155        doReturn(Call.State.INCOMING).when(mRingingCall).getState();
156
157        // dial string length > 1
158        assertEquals(false, mImsPhoneUT.handleInCallMmiCommands("00"));
159
160        // ringing call is not idle
161        assertEquals(true, mImsPhoneUT.handleInCallMmiCommands("0"));
162        verify(mImsCT).rejectCall();
163
164        // ringing is idle, background call is not idle
165        doReturn(Call.State.IDLE).when(mRingingCall).getState();
166        doReturn(Call.State.ACTIVE).when(mBackgroundCall).getState();
167        assertEquals(true, mImsPhoneUT.handleInCallMmiCommands("0"));
168        verify(mImsCT).hangup(mBackgroundCall);
169    }
170
171    @Test
172    @SmallTest
173    public void testHandleInCallMmiCommandCallWaiting() throws Exception {
174        doReturn(Call.State.ACTIVE).when(mForegroundCall).getState();
175
176        // dial string length > 2
177        assertEquals(false, mImsPhoneUT.handleInCallMmiCommands("100"));
178
179        // dial string length > 1
180        assertEquals(true, mImsPhoneUT.handleInCallMmiCommands("10"));
181        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
182        verify(mTestHandler).sendMessageAtTime(messageArgumentCaptor.capture(), anyLong());
183        assertEquals(EVENT_SUPP_SERVICE_FAILED, messageArgumentCaptor.getValue().what);
184        assertEquals(Phone.SuppService.HANGUP,
185                ((AsyncResult)messageArgumentCaptor.getValue().obj).result);
186
187        // foreground call is not idle
188        assertEquals(true, mImsPhoneUT.handleInCallMmiCommands("1"));
189        verify(mImsCT).hangup(any(ImsPhoneCall.class));
190
191        // foreground call is idle
192        doReturn(Call.State.IDLE).when(mForegroundCall).getState();
193        doReturn(Call.State.INCOMING).when(mRingingCall).getState();
194        assertEquals(true, mImsPhoneUT.handleInCallMmiCommands("1"));
195        verify(mImsCT).switchWaitingOrHoldingAndActive();
196    }
197
198    @Test
199    @SmallTest
200    public void testHandleInCallMmiCommandCallHold() throws Exception {
201        doReturn(Call.State.ACTIVE).when(mForegroundCall).getState();
202
203        // dial string length > 2
204        assertEquals(false, mImsPhoneUT.handleInCallMmiCommands("200"));
205
206        // dial string length > 1
207        assertEquals(true, mImsPhoneUT.handleInCallMmiCommands("20"));
208        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
209        verify(mTestHandler).sendMessageAtTime(messageArgumentCaptor.capture(), anyLong());
210        assertEquals(EVENT_SUPP_SERVICE_FAILED, messageArgumentCaptor.getValue().what);
211        assertEquals(Phone.SuppService.SEPARATE,
212                ((AsyncResult) messageArgumentCaptor.getValue().obj).result);
213
214        // ringing call is idle
215        assertEquals(true, mImsPhoneUT.handleInCallMmiCommands("2"));
216        verify(mImsCT).switchWaitingOrHoldingAndActive();
217
218        // ringing call is not idle
219        doReturn(Call.State.INCOMING).when(mRingingCall).getState();
220        assertEquals(true, mImsPhoneUT.handleInCallMmiCommands("2"));
221        verify(mImsCT).acceptCall(ImsCallProfile.CALL_TYPE_VOICE);
222    }
223
224    @Test
225    @SmallTest
226    public void testHandleInCallMmiCommandMultiparty() {
227        doReturn(Call.State.ACTIVE).when(mForegroundCall).getState();
228
229        // dial string length > 1
230        assertEquals(false, mImsPhoneUT.handleInCallMmiCommands("30"));
231
232        // dial string length == 1
233        assertEquals(true, mImsPhoneUT.handleInCallMmiCommands("3"));
234        verify(mImsCT).conference();
235    }
236
237    @Test
238    @SmallTest
239    public void testHandleInCallMmiCommandCallEct() {
240        doReturn(Call.State.ACTIVE).when(mForegroundCall).getState();
241
242        // dial string length > 1
243        assertEquals(false, mImsPhoneUT.handleInCallMmiCommands("40"));
244
245        // dial string length == 1
246        assertEquals(true, mImsPhoneUT.handleInCallMmiCommands("4"));
247        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
248        verify(mTestHandler).sendMessageAtTime(messageArgumentCaptor.capture(), anyLong());
249        assertEquals(EVENT_SUPP_SERVICE_FAILED, messageArgumentCaptor.getValue().what);
250        assertEquals(Phone.SuppService.TRANSFER,
251                ((AsyncResult) messageArgumentCaptor.getValue().obj).result);
252    }
253
254    @Test
255    @SmallTest
256    public void testHandleInCallMmiCommandCallCcbs() {
257        doReturn(Call.State.ACTIVE).when(mForegroundCall).getState();
258
259        // dial string length > 1
260        assertEquals(false, mImsPhoneUT.handleInCallMmiCommands("50"));
261
262        // dial string length == 1
263        assertEquals(true, mImsPhoneUT.handleInCallMmiCommands("5"));
264        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
265        verify(mTestHandler).sendMessageAtTime(messageArgumentCaptor.capture(), anyLong());
266        assertEquals(EVENT_SUPP_SERVICE_FAILED, messageArgumentCaptor.getValue().what);
267        assertEquals(Phone.SuppService.UNKNOWN,
268                ((AsyncResult)messageArgumentCaptor.getValue().obj).result);
269    }
270
271    @Test
272    @SmallTest
273    public void testDispose() {
274        // add MMI to verify that dispose removes it
275        mImsPhoneUT.sendUssdResponse("1234");
276        verify(mImsCT).sendUSSD(eq("1234"), any(Message.class));
277        List<?> list = mImsPhoneUT.getPendingMmiCodes();
278        assertNotNull(list);
279        assertEquals(1, list.size());
280
281        mImsPhoneUT.dispose();
282        assertEquals(0, list.size());
283        verify(mImsCT).dispose();
284        verify(mSST).unregisterForDataRegStateOrRatChanged(mImsPhoneUT);
285    }
286
287    @Test
288    @SmallTest
289    public void testGettersAndPassThroughs() throws Exception {
290        Message msg = mTestHandler.obtainMessage();
291
292        assertNotNull(mImsPhoneUT.getServiceState());
293        assertEquals(mImsCT, mImsPhoneUT.getCallTracker());
294
295        mImsPhoneUT.acceptCall(0);
296        verify(mImsCT).acceptCall(0);
297
298        mImsPhoneUT.rejectCall();
299        verify(mImsCT).rejectCall();
300
301        mImsPhoneUT.switchHoldingAndActive();
302        verify(mImsCT).switchWaitingOrHoldingAndActive();
303
304        assertEquals(false, mImsPhoneUT.canConference());
305        doReturn(true).when(mImsCT).canConference();
306        assertEquals(true, mImsPhoneUT.canConference());
307        verify(mImsCT, times(2)).canConference();
308
309        assertEquals(false, mImsPhoneUT.canDial());
310        doReturn(true).when(mImsCT).canDial();
311        assertEquals(true, mImsPhoneUT.canDial());
312        verify(mImsCT, times(2)).canDial();
313
314        mImsPhoneUT.conference();
315        verify(mImsCT).conference();
316
317        mImsPhoneUT.clearDisconnected();
318        verify(mImsCT).clearDisconnected();
319
320        assertEquals(false, mImsPhoneUT.canTransfer());
321        doReturn(true).when(mImsCT).canTransfer();
322        assertEquals(true, mImsPhoneUT.canTransfer());
323        verify(mImsCT, times(2)).canTransfer();
324
325        mImsPhoneUT.explicitCallTransfer();
326        verify(mImsCT).explicitCallTransfer();
327
328        assertEquals(mForegroundCall, mImsPhoneUT.getForegroundCall());
329        assertEquals(mBackgroundCall, mImsPhoneUT.getBackgroundCall());
330        assertEquals(mRingingCall, mImsPhoneUT.getRingingCall());
331
332        mImsPhoneUT.notifyNewRingingConnection(mConnection);
333        verify(mPhone).notifyNewRingingConnectionP(mConnection);
334
335        mImsPhoneUT.notifyForVideoCapabilityChanged(true);
336        verify(mPhone).notifyForVideoCapabilityChanged(true);
337
338        mImsPhoneUT.setMute(true);
339        verify(mImsCT).setMute(true);
340
341        mImsPhoneUT.setUiTTYMode(1234, null);
342        verify(mImsCT).setUiTTYMode(1234, null);
343
344        doReturn(false).when(mImsCT).getMute();
345        assertEquals(false, mImsPhoneUT.getMute());
346        doReturn(true).when(mImsCT).getMute();
347        assertEquals(true, mImsPhoneUT.getMute());
348        verify(mImsCT, times(2)).getMute();
349
350        doReturn(PhoneConstants.State.IDLE).when(mImsCT).getState();
351        assertEquals(PhoneConstants.State.IDLE, mImsPhoneUT.getState());
352        doReturn(PhoneConstants.State.RINGING).when(mImsCT).getState();
353        assertEquals(PhoneConstants.State.RINGING, mImsPhoneUT.getState());
354
355        mImsPhoneUT.sendUSSD("1234", msg);
356        verify(mImsCT).sendUSSD("1234", msg);
357
358        mImsPhoneUT.cancelUSSD();
359        verify(mImsCT).cancelUSSD();
360
361    }
362
363    @Test
364    @SmallTest
365    public void testSuppServiceNotification() {
366        SuppServiceNotification ssn = new SuppServiceNotification();
367        mImsPhoneUT.notifySuppSvcNotification(ssn);
368
369        // verify registrants are notified
370        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
371        verify(mTestHandler, times(1)).sendMessageAtTime(messageArgumentCaptor.capture(),
372                anyLong());
373        Message message = messageArgumentCaptor.getValue();
374        assertEquals(EVENT_SUPP_SERVICE_NOTIFICATION, message.what);
375        assertEquals(ssn, ((AsyncResult) message.obj).result);
376        assertEquals(null, ((AsyncResult) message.obj).userObj);
377        assertEquals(null, ((AsyncResult) message.obj).exception);
378
379        // verify no notification is received after unregister (verify() still sees only 1
380        // notification)
381        mImsPhoneUT.unregisterForSuppServiceNotification(mTestHandler);
382        mImsPhoneUT.notifySuppSvcNotification(ssn);
383        verify(mTestHandler, times(1)).sendMessageAtTime(any(Message.class), anyLong());
384    }
385
386    @Test
387    @SmallTest
388    public void testDial() throws Exception {
389        String dialString = "1234567890";
390        int videoState = 0;
391
392        mImsPhoneUT.dial(dialString,
393                new ImsPhone.ImsDialArgs.Builder().setVideoState(videoState).build());
394        verify(mImsCT).dial(eq(dialString), any(ImsPhone.ImsDialArgs.class));
395    }
396
397    @Test
398    @SmallTest
399    public void testDtmf() {
400        // case 1
401        doReturn(PhoneConstants.State.IDLE).when(mImsCT).getState();
402        mImsPhoneUT.sendDtmf('-');
403        verify(mImsCT, times(0)).sendDtmf(anyChar(), nullable(Message.class));
404
405        // case 2
406        mImsPhoneUT.sendDtmf('0');
407        verify(mImsCT, times(0)).sendDtmf(eq('0'), nullable(Message.class));
408
409        // case 3
410        doReturn(PhoneConstants.State.OFFHOOK).when(mImsCT).getState();
411        mImsPhoneUT.sendDtmf('-');
412        verify(mImsCT, times(0)).sendDtmf(eq('0'), nullable(Message.class));
413
414        // case 4
415        mImsPhoneUT.sendDtmf('0');
416        verify(mImsCT, times(1)).sendDtmf(anyChar(), nullable(Message.class));
417
418        mImsPhoneUT.startDtmf('-');
419        verify(mImsCT, times(0)).startDtmf(anyChar());
420
421        mImsPhoneUT.startDtmf('0');
422        verify(mImsCT, times(1)).startDtmf('0');
423
424        mImsPhoneUT.stopDtmf();
425        verify(mImsCT).stopDtmf();
426    }
427
428    @Test
429    @SmallTest
430    public void testIncomingRing() {
431        doReturn(PhoneConstants.State.IDLE).when(mImsCT).getState();
432        mImsPhoneUT.notifyIncomingRing();
433        waitForMs(100);
434        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
435        verify(mTestHandler, times(1)).sendMessageAtTime(messageArgumentCaptor.capture(),
436                anyLong());
437        Message message = messageArgumentCaptor.getValue();
438        assertEquals(EVENT_INCOMING_RING, message.what);
439    }
440
441    @Test
442    @SmallTest
443    public void testOutgoingCallerIdDisplay() throws Exception {
444        Message msg = mTestHandler.obtainMessage();
445        mImsPhoneUT.getOutgoingCallerIdDisplay(msg);
446
447        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
448        verify(mImsUtInterface).queryCLIR(messageArgumentCaptor.capture());
449        assertEquals(msg, messageArgumentCaptor.getValue().obj);
450
451        mImsPhoneUT.setOutgoingCallerIdDisplay(1234, msg);
452        verify(mImsUtInterface).updateCLIR(eq(1234), messageArgumentCaptor.capture());
453        assertEquals(msg, messageArgumentCaptor.getValue().obj);
454    }
455
456    @FlakyTest
457    @Test
458    @Ignore
459    public void testCallForwardingOption() throws Exception {
460        Message msg = mTestHandler.obtainMessage();
461        mImsPhoneUT.getCallForwardingOption(CF_REASON_UNCONDITIONAL, msg);
462
463        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
464        verify(mImsUtInterface).queryCallForward(eq(ImsUtInterface.CDIV_CF_UNCONDITIONAL),
465                (String) eq(null), messageArgumentCaptor.capture());
466        assertEquals(msg, messageArgumentCaptor.getValue().obj);
467
468        mImsPhoneUT.setCallForwardingOption(CF_ACTION_ENABLE, CF_REASON_UNCONDITIONAL, "1234", 0,
469                msg);
470        verify(mImsUtInterface).updateCallForward(eq(ImsUtInterface.ACTION_ACTIVATION),
471                eq(ImsUtInterface.CDIV_CF_UNCONDITIONAL), eq("1234"),
472                eq(CommandsInterface.SERVICE_CLASS_VOICE), eq(0), eq(msg));
473    }
474
475    @Test
476    @SmallTest
477    public void testCallWaiting() throws Exception {
478        Message msg = mTestHandler.obtainMessage();
479        mImsPhoneUT.getCallWaiting(msg);
480
481        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
482        verify(mImsUtInterface).queryCallWaiting(messageArgumentCaptor.capture());
483        assertEquals(msg, messageArgumentCaptor.getValue().obj);
484
485        mImsPhoneUT.setCallWaiting(true, msg);
486        verify(mImsUtInterface).updateCallWaiting(eq(true),
487                eq(CommandsInterface.SERVICE_CLASS_VOICE), messageArgumentCaptor.capture());
488        assertEquals(msg, messageArgumentCaptor.getValue().obj);
489    }
490
491    @Test
492    public void testShouldSendNotificationWhenServiceStateIsChanged() {
493        mImsPhoneUT.setServiceState(ServiceState.STATE_IN_SERVICE);
494        reset(mSST);
495
496        mImsPhoneUT.setServiceState(ServiceState.STATE_OUT_OF_SERVICE);
497        verify(mSST).onImsServiceStateChanged();
498    }
499
500    @Test
501    public void testShouldNotSendNotificationWhenServiceStateIsNotChanged() {
502        mImsPhoneUT.setServiceState(ServiceState.STATE_IN_SERVICE);
503        reset(mSST);
504
505        mImsPhoneUT.setServiceState(ServiceState.STATE_IN_SERVICE);
506        verify(mSST, never()).onImsServiceStateChanged();
507    }
508
509    @Test
510    @SmallTest
511    public void testCellBarring() throws Exception {
512        Message msg = mTestHandler.obtainMessage();
513        mImsPhoneUT.getCallBarring(CommandsInterface.CB_FACILITY_BAOC, msg,
514                CommandsInterface.SERVICE_CLASS_NONE);
515
516        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
517        verify(mImsUtInterface).queryCallBarring(eq(ImsUtInterface.CB_BAOC),
518                messageArgumentCaptor.capture(), eq(CommandsInterface.SERVICE_CLASS_NONE));
519        assertEquals(msg, messageArgumentCaptor.getValue().obj);
520
521        mImsPhoneUT.setCallBarring(CommandsInterface.CB_FACILITY_BAOIC, true, "abc", msg,
522                CommandsInterface.SERVICE_CLASS_NONE);
523        verify(mImsUtInterface).updateCallBarring(eq(ImsUtInterface.CB_BOIC),
524                eq(CommandsInterface.CF_ACTION_ENABLE), messageArgumentCaptor.capture(),
525                (String[]) eq(null), eq(CommandsInterface.SERVICE_CLASS_NONE));
526        assertEquals(msg, messageArgumentCaptor.getValue().obj);
527
528        mImsPhoneUT.setCallBarring(CommandsInterface.CB_FACILITY_BAOICxH, false, "abc", msg,
529                CommandsInterface.SERVICE_CLASS_NONE);
530        verify(mImsUtInterface).updateCallBarring(eq(ImsUtInterface.CB_BOIC_EXHC),
531                eq(CommandsInterface.CF_ACTION_DISABLE), messageArgumentCaptor.capture(),
532                (String[])eq(null), eq(CommandsInterface.SERVICE_CLASS_NONE));
533        assertEquals(msg, messageArgumentCaptor.getValue().obj);
534    }
535
536    @FlakyTest
537    @Test
538    @Ignore
539    public void testEcbm() throws Exception {
540        ImsEcbmStateListener imsEcbmStateListener = mImsPhoneUT.getImsEcbmStateListener();
541
542        // verify handling of emergency callback mode
543        imsEcbmStateListener.onECBMEntered();
544
545        // verify ACTION_EMERGENCY_CALLBACK_MODE_CHANGED
546        ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
547        verify(mIActivityManager, atLeast(1)).broadcastIntent(eq((IApplicationThread)null),
548                intentArgumentCaptor.capture(),
549                eq((String)null),
550                eq((IIntentReceiver)null),
551                eq(Activity.RESULT_OK),
552                eq((String)null),
553                eq((Bundle)null),
554                eq((String[])null),
555                anyInt(),
556                eq((Bundle)null),
557                eq(false),
558                eq(true),
559                anyInt());
560
561        Intent intent = intentArgumentCaptor.getValue();
562        assertEquals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED, intent.getAction());
563        assertEquals(true, intent.getBooleanExtra(PhoneConstants.PHONE_IN_ECM_STATE, false));
564
565        // verify that wakeLock is acquired in ECM
566        assertEquals(true, mImsPhoneUT.getWakeLock().isHeld());
567
568        mImsPhoneUT.setOnEcbModeExitResponse(mTestHandler, EVENT_EMERGENCY_CALLBACK_MODE_EXIT,
569                null);
570
571        // verify handling of emergency callback mode exit
572        imsEcbmStateListener.onECBMExited();
573
574        // verify ACTION_EMERGENCY_CALLBACK_MODE_CHANGED
575        verify(mIActivityManager, atLeast(2)).broadcastIntent(eq((IApplicationThread)null),
576                intentArgumentCaptor.capture(),
577                eq((String)null),
578                eq((IIntentReceiver)null),
579                eq(Activity.RESULT_OK),
580                eq((String)null),
581                eq((Bundle)null),
582                eq((String[])null),
583                anyInt(),
584                eq((Bundle)null),
585                eq(false),
586                eq(true),
587                anyInt());
588
589        intent = intentArgumentCaptor.getValue();
590        assertEquals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED, intent.getAction());
591        assertEquals(false, intent.getBooleanExtra(PhoneConstants.PHONE_IN_ECM_STATE, true));
592
593        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
594
595        // verify EcmExitRespRegistrant is notified
596        verify(mTestHandler).sendMessageAtTime(messageArgumentCaptor.capture(),
597                anyLong());
598        assertEquals(EVENT_EMERGENCY_CALLBACK_MODE_EXIT, messageArgumentCaptor.getValue().what);
599
600        // verify wakeLock released
601        assertEquals(false, mImsPhoneUT.getWakeLock().isHeld());
602    }
603
604    @FlakyTest
605    @Test
606    @SmallTest
607    @Ignore
608    public void testProcessDisconnectReason() throws Exception {
609        // set up CarrierConfig
610        PersistableBundle bundle = mContextFixture.getCarrierConfigBundle();
611        bundle.putStringArray(CarrierConfigManager.KEY_WFC_OPERATOR_ERROR_CODES_STRING_ARRAY,
612                new String[]{"REG09|0"});
613
614        // set up overlays
615        String title = "title";
616        String messageAlert = "Alert!";
617        String messageNotification = "Notification!";
618        mContextFixture.putStringArrayResource(
619                com.android.internal.R.array.wfcOperatorErrorAlertMessages,
620                new String[]{messageAlert});
621        mContextFixture.putStringArrayResource(
622                com.android.internal.R.array.wfcOperatorErrorNotificationMessages,
623                new String[]{messageNotification});
624        mContextFixture.putResource(com.android.internal.R.string.wfcRegErrorTitle, title);
625
626        mImsPhoneUT.processDisconnectReason(
627                new ImsReasonInfo(ImsReasonInfo.CODE_REGISTRATION_ERROR, 0, "REG09"));
628
629        // TODO: Verify that WFC has been turned off (can't do it right now because
630        // setWfcSetting is static).
631        //verify(mImsManager).setWfcSetting(any(), eq(false));
632
633        ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
634        verify(mContext).sendOrderedBroadcast(
635                intent.capture(), nullable(String.class), any(BroadcastReceiver.class),
636                nullable(Handler.class), eq(Activity.RESULT_OK), nullable(String.class),
637                nullable(Bundle.class));
638        assertEquals(ImsManager.ACTION_IMS_REGISTRATION_ERROR, intent.getValue().getAction());
639        assertEquals(title, intent.getValue().getStringExtra(Phone.EXTRA_KEY_ALERT_TITLE));
640        assertEquals(messageAlert, intent.getValue().getStringExtra(Phone.EXTRA_KEY_ALERT_MESSAGE));
641        assertEquals(messageNotification,
642                intent.getValue().getStringExtra(Phone.EXTRA_KEY_NOTIFICATION_MESSAGE));
643    }
644}
645