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