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.incallui;
18 
19 import static org.mockito.Mockito.never;
20 import static org.mockito.Mockito.verify;
21 import static org.mockito.Mockito.when;
22 
23 import android.content.Context;
24 import android.content.Intent;
25 import android.telecom.PhoneAccountHandle;
26 import android.telephony.TelephonyManager;
27 import android.test.InstrumentationTestCase;
28 import android.test.suitebuilder.annotation.MediumTest;
29 
30 import com.android.incallui.InCallPresenter.InCallState;
31 
32 import org.mockito.Mock;
33 import org.mockito.Mockito;
34 import org.mockito.MockitoAnnotations;
35 
36 @MediumTest
37 public class InCallPresenterTest extends InstrumentationTestCase {
38     private MockCallListWrapper mCallList;
39     @Mock private InCallActivity mInCallActivity;
40     @Mock private AudioModeProvider mAudioModeProvider;
41     @Mock private StatusBarNotifier mStatusBarNotifier;
42     @Mock private ContactInfoCache mContactInfoCache;
43     @Mock private ProximitySensor mProximitySensor;
44 
45     InCallPresenter mInCallPresenter;
46     @Mock private Context mContext;
47     @Mock private TelephonyManager mTelephonyManager;
48 
49     @Override
setUp()50     protected void setUp() throws Exception {
51         super.setUp();
52         System.setProperty("dexmaker.dexcache",
53                 getInstrumentation().getTargetContext().getCacheDir().getPath());
54         MockitoAnnotations.initMocks(this);
55         mCallList = new MockCallListWrapper();
56 
57         when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
58 
59         mInCallPresenter = InCallPresenter.getInstance();
60         mInCallPresenter.setUp(mContext, mCallList.getCallList(), mAudioModeProvider,
61                 mStatusBarNotifier, mContactInfoCache, mProximitySensor);
62     }
63 
64     @Override
tearDown()65     protected void tearDown() throws Exception {
66         // The tear down method needs to run in the main thread since there is an explicit check
67         // inside TelecomAdapter.getInstance().
68         getInstrumentation().runOnMainSync(new Runnable() {
69             @Override
70             public void run() {
71                 mInCallPresenter.unsetActivity(mInCallActivity);
72                 mInCallPresenter.tearDown();
73                 InCallPresenter.setInstance(null);
74             }
75         });
76     }
77 
testOnActivitySet_finishesActivityWhenNoCalls()78     public void testOnActivitySet_finishesActivityWhenNoCalls() {
79         mInCallPresenter.setActivity(mInCallActivity);
80 
81         verify(mInCallActivity).finish();
82     }
83 
testOnCallListChange_sendsNotificationWhenInCall()84     public void testOnCallListChange_sendsNotificationWhenInCall() {
85         mCallList.setHasCall(Call.State.INCOMING, true);
86 
87         mInCallPresenter.onCallListChange(mCallList.getCallList());
88 
89         verify(mStatusBarNotifier).updateNotification(InCallState.INCOMING,
90                 mCallList.getCallList());
91         verifyInCallActivityNotStarted();
92     }
93 
94     /**
95      * This behavior is required to ensure that the screen is turned on again by the restarting
96      * activity.
97      */
testOnCallListChange_handlesCallWaitingWhenScreenOffShouldRestartActivity()98     public void testOnCallListChange_handlesCallWaitingWhenScreenOffShouldRestartActivity() {
99         mCallList.setHasCall(Call.State.ACTIVE, true);
100 
101         mInCallPresenter.onCallListChange(mCallList.getCallList());
102         mInCallPresenter.setActivity(mInCallActivity);
103 
104         // Pretend that there is a call waiting and the screen is off
105         when(mInCallActivity.isDestroyed()).thenReturn(false);
106         when(mInCallActivity.isFinishing()).thenReturn(false);
107         when(mProximitySensor.isScreenReallyOff()).thenReturn(true);
108         mCallList.setHasCall(Call.State.INCOMING, true);
109 
110         mInCallPresenter.onCallListChange(mCallList.getCallList());
111         verify(mInCallActivity).finish();
112     }
113 
114     /**
115      * Verifies that the PENDING_OUTGOING -> IN_CALL transition brings up InCallActivity so
116      * that it can display an error dialog.
117      */
testOnCallListChange_pendingOutgoingToInCallTransitionShowsUiForErrorDialog()118     public void testOnCallListChange_pendingOutgoingToInCallTransitionShowsUiForErrorDialog() {
119         mCallList.setHasCall(Call.State.CONNECTING, true);
120 
121         mInCallPresenter.onCallListChange(mCallList.getCallList());
122 
123         mCallList.setHasCall(Call.State.CONNECTING, false);
124         mCallList.setHasCall(Call.State.ACTIVE, true);
125 
126         mInCallPresenter.onCallListChange(mCallList.getCallList());
127 
128         verify(mContext).startActivity(InCallPresenter.getInstance().getInCallIntent(false, false));
129         verifyIncomingCallNotificationNotSent();
130     }
131 
132     /**
133      * Verifies that if there is a call in the SELECT_PHONE_ACCOUNT state, InCallActivity is displayed
134      * to display the account picker.
135      */
testOnCallListChange_noAccountProvidedForCallShowsUiForAccountPicker()136     public void testOnCallListChange_noAccountProvidedForCallShowsUiForAccountPicker() {
137         mCallList.setHasCall(Call.State.SELECT_PHONE_ACCOUNT, true);
138         mInCallPresenter.onCallListChange(mCallList.getCallList());
139 
140         verify(mContext).startActivity(InCallPresenter.getInstance().getInCallIntent(false, false));
141         verifyIncomingCallNotificationNotSent();
142     }
143 
144     /**
145      * Verifies that for an expected call state change (e.g. NO_CALLS -> PENDING_OUTGOING),
146      * InCallActivity is not displayed.
147      */
testOnCallListChange_noCallsToPendingOutgoingDoesNotShowUi()148     public void testOnCallListChange_noCallsToPendingOutgoingDoesNotShowUi() {
149         mCallList.setHasCall(Call.State.CONNECTING, true);
150         mInCallPresenter.onCallListChange(mCallList.getCallList());
151 
152         verifyInCallActivityNotStarted();
153         verifyIncomingCallNotificationNotSent();
154     }
155 
testOnCallListChange_LastCallDisconnectedNoCallsLeftFinishesUi()156     public void testOnCallListChange_LastCallDisconnectedNoCallsLeftFinishesUi() {
157         mCallList.setHasCall(Call.State.DISCONNECTED, true);
158         mInCallPresenter.onCallListChange(mCallList.getCallList());
159 
160         mInCallPresenter.setActivity(mInCallActivity);
161 
162         verify(mInCallActivity, never()).finish();
163 
164         // Last remaining disconnected call is removed from CallList, activity should shut down.
165         mCallList.setHasCall(Call.State.DISCONNECTED, false);
166         mInCallPresenter.onCallListChange(mCallList.getCallList());
167         verify(mInCallActivity).finish();
168     }
169 
170 
171     //TODO
testCircularReveal_startsCircularRevealForOutgoingCalls()172     public void testCircularReveal_startsCircularRevealForOutgoingCalls() {
173 
174     }
175 
testCircularReveal_waitTillCircularRevealSentBeforeShowingCallCard()176     public void testCircularReveal_waitTillCircularRevealSentBeforeShowingCallCard() {
177     }
178 
testHangupOngoingCall_disconnectsCallCorrectly()179     public void testHangupOngoingCall_disconnectsCallCorrectly() {
180     }
181 
testAnswerIncomingCall()182     public void testAnswerIncomingCall() {
183     }
184 
testDeclineIncomingCall()185     public void testDeclineIncomingCall() {
186     }
187 
verifyInCallActivityNotStarted()188     private void verifyInCallActivityNotStarted() {
189         verify(mContext, never()).startActivity(Mockito.any(Intent.class));
190     }
191 
verifyIncomingCallNotificationNotSent()192     private void verifyIncomingCallNotificationNotSent() {
193         verify(mStatusBarNotifier, never()).updateNotification(Mockito.any(InCallState.class),
194                 Mockito.any(CallList.class));
195     }
196 }
197