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