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 android.app.Activity;
20import android.app.IApplicationThread;
21import android.content.BroadcastReceiver;
22import android.content.IIntentReceiver;
23import android.content.Intent;
24import android.os.AsyncResult;
25import android.os.Bundle;
26import android.os.Handler;
27import android.os.HandlerThread;
28import android.os.Message;
29import android.os.PersistableBundle;
30import android.os.SystemProperties;
31import android.platform.test.annotations.Postsubmit;
32import android.telephony.CarrierConfigManager;
33import android.test.suitebuilder.annotation.SmallTest;
34
35import com.android.ims.ImsCallProfile;
36import com.android.ims.ImsEcbmStateListener;
37import com.android.ims.ImsManager;
38import com.android.ims.ImsReasonInfo;
39import com.android.ims.ImsStreamMediaProfile;
40import com.android.ims.ImsUtInterface;
41import com.android.internal.telephony.Call;
42import com.android.internal.telephony.CommandsInterface;
43import com.android.internal.telephony.Connection;
44import com.android.internal.telephony.Phone;
45import com.android.internal.telephony.PhoneConstants;
46import com.android.internal.telephony.PhoneInternalInterface;
47import com.android.internal.telephony.TelephonyIntents;
48import com.android.internal.telephony.TelephonyProperties;
49import com.android.internal.telephony.TelephonyTest;
50import com.android.internal.telephony.gsm.SuppServiceNotification;
51
52import org.junit.After;
53import org.junit.Before;
54import org.junit.Test;
55import org.mockito.ArgumentCaptor;
56import org.mockito.Mock;
57
58import java.util.List;
59
60import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ENABLE;
61import static com.android.internal.telephony.CommandsInterface.CF_REASON_UNCONDITIONAL;
62import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
63import static org.junit.Assert.assertEquals;
64import static org.junit.Assert.assertFalse;
65import static org.junit.Assert.assertNotNull;
66import static org.junit.Assert.fail;
67import static org.mockito.Matchers.any;
68import static org.mockito.Matchers.anyChar;
69import static org.mockito.Matchers.anyInt;
70import static org.mockito.Matchers.anyLong;
71import static org.mockito.Matchers.anyString;
72import static org.mockito.Mockito.atLeast;
73import static org.mockito.Mockito.doNothing;
74import static org.mockito.Mockito.doReturn;
75import static org.mockito.Mockito.eq;
76import static org.mockito.Mockito.times;
77import static org.mockito.Mockito.verify;
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.quitSafely();
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, videoState);
393        verify(mImsCT).dial(dialString, videoState, null);
394    }
395
396    @Test
397    @SmallTest
398    public void testDtmf() {
399        // case 1
400        doReturn(PhoneConstants.State.IDLE).when(mImsCT).getState();
401        mImsPhoneUT.sendDtmf('-');
402        verify(mImsCT, times(0)).sendDtmf(anyChar(), any(Message.class));
403
404        // case 2
405        mImsPhoneUT.sendDtmf('0');
406        verify(mImsCT, times(0)).sendDtmf(eq('0'), any(Message.class));
407
408        // case 3
409        doReturn(PhoneConstants.State.OFFHOOK).when(mImsCT).getState();
410        mImsPhoneUT.sendDtmf('-');
411        verify(mImsCT, times(0)).sendDtmf(eq('0'), any(Message.class));
412
413        // case 4
414        mImsPhoneUT.sendDtmf('0');
415        verify(mImsCT, times(1)).sendDtmf(anyChar(), any(Message.class));
416
417        mImsPhoneUT.startDtmf('-');
418        verify(mImsCT, times(0)).startDtmf(anyChar());
419
420        mImsPhoneUT.startDtmf('0');
421        verify(mImsCT, times(1)).startDtmf('0');
422
423        mImsPhoneUT.stopDtmf();
424        verify(mImsCT).stopDtmf();
425    }
426
427    @Test
428    @SmallTest
429    public void testIncomingRing() {
430        doReturn(PhoneConstants.State.IDLE).when(mImsCT).getState();
431        mImsPhoneUT.notifyIncomingRing();
432        waitForMs(100);
433        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
434        verify(mTestHandler, times(1)).sendMessageAtTime(messageArgumentCaptor.capture(),
435                anyLong());
436        Message message = messageArgumentCaptor.getValue();
437        assertEquals(EVENT_INCOMING_RING, message.what);
438    }
439
440    @Test
441    @SmallTest
442    public void testOutgoingCallerIdDisplay() throws Exception {
443        Message msg = mTestHandler.obtainMessage();
444        mImsPhoneUT.getOutgoingCallerIdDisplay(msg);
445
446        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
447        verify(mImsUtInterface).queryCLIR(messageArgumentCaptor.capture());
448        assertEquals(msg, messageArgumentCaptor.getValue().obj);
449
450        mImsPhoneUT.setOutgoingCallerIdDisplay(1234, msg);
451        verify(mImsUtInterface).updateCLIR(eq(1234), messageArgumentCaptor.capture());
452        assertEquals(msg, messageArgumentCaptor.getValue().obj);
453    }
454
455    @Postsubmit
456    @Test
457    @SmallTest
458    public void testCallForwardingOption() throws Exception {
459        Message msg = mTestHandler.obtainMessage();
460        mImsPhoneUT.getCallForwardingOption(CF_REASON_UNCONDITIONAL, msg);
461
462        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
463        verify(mImsUtInterface).queryCallForward(eq(ImsUtInterface.CDIV_CF_UNCONDITIONAL),
464                (String) eq(null), messageArgumentCaptor.capture());
465        assertEquals(msg, messageArgumentCaptor.getValue().obj);
466
467        mImsPhoneUT.setCallForwardingOption(CF_ACTION_ENABLE, CF_REASON_UNCONDITIONAL, "1234", 0,
468                msg);
469        verify(mImsUtInterface).updateCallForward(eq(ImsUtInterface.ACTION_ACTIVATION),
470                eq(ImsUtInterface.CDIV_CF_UNCONDITIONAL), eq("1234"),
471                eq(CommandsInterface.SERVICE_CLASS_VOICE), eq(0), eq(msg));
472    }
473
474    @Test
475    @SmallTest
476    public void testCallWaiting() throws Exception {
477        Message msg = mTestHandler.obtainMessage();
478        mImsPhoneUT.getCallWaiting(msg);
479
480        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
481        verify(mImsUtInterface).queryCallWaiting(messageArgumentCaptor.capture());
482        assertEquals(msg, messageArgumentCaptor.getValue().obj);
483
484        mImsPhoneUT.setCallWaiting(true, msg);
485        verify(mImsUtInterface).updateCallWaiting(eq(true),
486                eq(CommandsInterface.SERVICE_CLASS_VOICE), messageArgumentCaptor.capture());
487        assertEquals(msg, messageArgumentCaptor.getValue().obj);
488    }
489
490    @Test
491    @SmallTest
492    public void testCellBarring() throws Exception {
493        Message msg = mTestHandler.obtainMessage();
494        mImsPhoneUT.getCallBarring(CommandsInterface.CB_FACILITY_BAOC, msg);
495
496        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
497        verify(mImsUtInterface).queryCallBarring(eq(ImsUtInterface.CB_BAOC),
498                messageArgumentCaptor.capture());
499        assertEquals(msg, messageArgumentCaptor.getValue().obj);
500
501        mImsPhoneUT.setCallBarring(CommandsInterface.CB_FACILITY_BAOIC, true, "abc", msg);
502        verify(mImsUtInterface).updateCallBarring(eq(ImsUtInterface.CB_BOIC),
503                eq(CommandsInterface.CF_ACTION_ENABLE), messageArgumentCaptor.capture(),
504                (String[]) eq(null));
505        assertEquals(msg, messageArgumentCaptor.getValue().obj);
506
507        mImsPhoneUT.setCallBarring(CommandsInterface.CB_FACILITY_BAOICxH, false, "abc", msg);
508        verify(mImsUtInterface).updateCallBarring(eq(ImsUtInterface.CB_BOIC_EXHC),
509                eq(CommandsInterface.CF_ACTION_DISABLE), messageArgumentCaptor.capture(),
510                (String[])eq(null));
511        assertEquals(msg, messageArgumentCaptor.getValue().obj);
512    }
513
514    @Test
515    @SmallTest
516    public void testEcbm() throws Exception {
517        ImsEcbmStateListener imsEcbmStateListener = mImsPhoneUT.getImsEcbmStateListener();
518
519        // verify handling of emergency callback mode
520        imsEcbmStateListener.onECBMEntered();
521
522        // verify ACTION_EMERGENCY_CALLBACK_MODE_CHANGED
523        ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
524        verify(mIActivityManager, atLeast(1)).broadcastIntent(eq((IApplicationThread)null),
525                intentArgumentCaptor.capture(),
526                eq((String)null),
527                eq((IIntentReceiver)null),
528                eq(Activity.RESULT_OK),
529                eq((String)null),
530                eq((Bundle)null),
531                eq((String[])null),
532                anyInt(),
533                eq((Bundle)null),
534                eq(false),
535                eq(true),
536                anyInt());
537
538        Intent intent = intentArgumentCaptor.getValue();
539        assertEquals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED, intent.getAction());
540        assertEquals(true, intent.getBooleanExtra(PhoneConstants.PHONE_IN_ECM_STATE, false));
541
542        // verify that wakeLock is acquired in ECM
543        assertEquals(true, mImsPhoneUT.getWakeLock().isHeld());
544
545        mImsPhoneUT.setOnEcbModeExitResponse(mTestHandler, EVENT_EMERGENCY_CALLBACK_MODE_EXIT,
546                null);
547
548        // verify handling of emergency callback mode exit
549        imsEcbmStateListener.onECBMExited();
550
551        // verify ACTION_EMERGENCY_CALLBACK_MODE_CHANGED
552        verify(mIActivityManager, atLeast(2)).broadcastIntent(eq((IApplicationThread)null),
553                intentArgumentCaptor.capture(),
554                eq((String)null),
555                eq((IIntentReceiver)null),
556                eq(Activity.RESULT_OK),
557                eq((String)null),
558                eq((Bundle)null),
559                eq((String[])null),
560                anyInt(),
561                eq((Bundle)null),
562                eq(false),
563                eq(true),
564                anyInt());
565
566        intent = intentArgumentCaptor.getValue();
567        assertEquals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED, intent.getAction());
568        assertEquals(false, intent.getBooleanExtra(PhoneConstants.PHONE_IN_ECM_STATE, true));
569
570        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
571
572        // verify EcmExitRespRegistrant is notified
573        verify(mTestHandler).sendMessageAtTime(messageArgumentCaptor.capture(),
574                anyLong());
575        assertEquals(EVENT_EMERGENCY_CALLBACK_MODE_EXIT, messageArgumentCaptor.getValue().what);
576
577        // verify wakeLock released
578        assertEquals(false, mImsPhoneUT.getWakeLock().isHeld());
579    }
580
581    @Postsubmit
582    @Test
583    @SmallTest
584    public void testProcessDisconnectReason() throws Exception {
585        // set up CarrierConfig
586        PersistableBundle bundle = mContextFixture.getCarrierConfigBundle();
587        bundle.putStringArray(CarrierConfigManager.KEY_WFC_OPERATOR_ERROR_CODES_STRING_ARRAY,
588                new String[]{"REG09|0"});
589
590        // set up overlays
591        String title = "title";
592        String messageAlert = "Alert!";
593        String messageNotification = "Notification!";
594        mContextFixture.putStringArrayResource(
595                com.android.internal.R.array.wfcOperatorErrorAlertMessages,
596                new String[]{messageAlert});
597        mContextFixture.putStringArrayResource(
598                com.android.internal.R.array.wfcOperatorErrorNotificationMessages,
599                new String[]{messageNotification});
600        mContextFixture.putResource(com.android.internal.R.string.wfcRegErrorTitle, title);
601
602        mImsPhoneUT.processDisconnectReason(
603                new ImsReasonInfo(ImsReasonInfo.CODE_REGISTRATION_ERROR, 0, "REG09"));
604
605        // TODO: Verify that WFC has been turned off (can't do it right now because
606        // setWfcSetting is static).
607        //verify(mImsManager).setWfcSetting(any(), eq(false));
608
609        ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
610        verify(mContext).sendOrderedBroadcast(
611                intent.capture(), anyString(), any(BroadcastReceiver.class), any(),
612                eq(Activity.RESULT_OK), anyString(), any());
613        assertEquals(ImsManager.ACTION_IMS_REGISTRATION_ERROR, intent.getValue().getAction());
614        assertEquals(title, intent.getValue().getStringExtra(Phone.EXTRA_KEY_ALERT_TITLE));
615        assertEquals(messageAlert, intent.getValue().getStringExtra(Phone.EXTRA_KEY_ALERT_MESSAGE));
616        assertEquals(messageNotification,
617                intent.getValue().getStringExtra(Phone.EXTRA_KEY_NOTIFICATION_MESSAGE));
618    }
619}
620