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 17 package com.android.services.telephony; 18 19 import android.content.AttributionSource; 20 import android.content.ContentResolver; 21 import android.os.Process; 22 import android.os.UserHandle; 23 import android.telephony.TelephonyManager; 24 25 import static org.mockito.ArgumentMatchers.any; 26 import static org.mockito.ArgumentMatchers.anyInt; 27 import static org.mockito.ArgumentMatchers.anyString; 28 import static org.mockito.ArgumentMatchers.notNull; 29 import static org.mockito.Mockito.doNothing; 30 import static org.mockito.Mockito.mock; 31 import static org.mockito.Mockito.when; 32 33 import android.content.Context; 34 import android.content.res.Resources; 35 import android.os.Bundle; 36 import android.os.PersistableBundle; 37 import android.telecom.PhoneAccountHandle; 38 import android.telecom.VideoProfile; 39 import android.telephony.CarrierConfigManager; 40 41 import com.android.ims.ImsCall; 42 import com.android.internal.telephony.Call; 43 import com.android.internal.telephony.CallStateException; 44 import com.android.internal.telephony.Connection; 45 import com.android.internal.telephony.Phone; 46 import com.android.internal.telephony.PhoneConstants; 47 import com.android.internal.telephony.emergency.EmergencyNumberTracker; 48 import com.android.internal.telephony.imsphone.ImsExternalConnection; 49 import com.android.internal.telephony.imsphone.ImsPhoneConnection; 50 51 import org.mockito.Mock; 52 import org.mockito.MockitoAnnotations; 53 import org.mockito.invocation.InvocationOnMock; 54 import org.mockito.stubbing.Answer; 55 56 import java.util.ArrayList; 57 import java.util.List; 58 59 /** 60 * Mock Telephony Connection used in TelephonyConferenceController.java for testing purpose 61 */ 62 63 public class TestTelephonyConnection extends TelephonyConnection { 64 65 @Mock 66 com.android.internal.telephony.Connection mMockRadioConnection; 67 68 @Mock 69 Call mMockCall; 70 71 @Mock 72 Context mMockContext; 73 74 @Mock 75 ContentResolver mMockContentResolver; 76 77 @Mock 78 Resources mMockResources; 79 80 @Mock 81 TelephonyManager mMockTelephonyManager; 82 83 @Mock 84 EmergencyNumberTracker mEmergencyNumberTracker; 85 86 @Mock 87 ImsPhoneConnection mImsPhoneConnection; 88 89 @Mock 90 ImsExternalConnection mImsExternalConnection; 91 92 @Mock 93 ImsCall mImsCall; 94 95 @Mock 96 TelecomAccountRegistry mTelecomAccountRegistry; 97 98 @Mock 99 CarrierConfigManager mCarrierConfigManager; 100 101 private boolean mIsImsConnection; 102 private boolean mIsImsExternalConnection; 103 private boolean mIsConferenceSupported = true; 104 private Phone mMockPhone; 105 private int mNotifyPhoneAccountChangedCount = 0; 106 private List<String> mLastConnectionEvents = new ArrayList<>(); 107 private List<Bundle> mLastConnectionEventExtras = new ArrayList<>(); 108 private Object mLock = new Object(); 109 private PersistableBundle mCarrierConfig = new PersistableBundle(); 110 111 @Override getOriginalConnection()112 public com.android.internal.telephony.Connection getOriginalConnection() { 113 if (mIsImsExternalConnection) { 114 return mImsExternalConnection; 115 } else if (mIsImsConnection) { 116 return mImsPhoneConnection; 117 } else { 118 return mMockRadioConnection; 119 } 120 } 121 122 @Override getCall()123 protected Call getCall() { 124 return mMockCall; 125 } 126 TestTelephonyConnection()127 public TestTelephonyConnection() { 128 super(null, null, android.telecom.Call.Details.DIRECTION_INCOMING); 129 MockitoAnnotations.initMocks(this); 130 131 AttributionSource attributionSource = new AttributionSource.Builder( 132 Process.myUid()).build(); 133 134 mIsImsConnection = false; 135 mIsImsExternalConnection = false; 136 mMockPhone = mock(Phone.class); 137 mMockContext = mock(Context.class); 138 mMockTelephonyManager = mock(TelephonyManager.class); 139 mOriginalConnection = mMockRadioConnection; 140 // Set up mMockRadioConnection and mMockPhone to contain an active call 141 when(mMockRadioConnection.getState()).thenReturn(Call.State.ACTIVE); 142 when(mOriginalConnection.getState()).thenReturn(Call.State.ACTIVE); 143 when(mMockRadioConnection.getAudioCodec()).thenReturn( 144 android.telecom.Connection.AUDIO_CODEC_AMR); 145 when(mImsPhoneConnection.getAudioCodec()).thenReturn( 146 android.telecom.Connection.AUDIO_CODEC_AMR); 147 when(mMockRadioConnection.getCall()).thenReturn(mMockCall); 148 when(mMockRadioConnection.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_IMS); 149 when(mImsPhoneConnection.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_IMS); 150 doNothing().when(mMockRadioConnection).addListener(any(Connection.Listener.class)); 151 doNothing().when(mMockRadioConnection).addPostDialListener( 152 any(Connection.PostDialListener.class)); 153 when(mEmergencyNumberTracker.getEmergencyNumber(anyString())).thenReturn(null); 154 when(mMockPhone.getEmergencyNumberTracker()).thenReturn(mEmergencyNumberTracker); 155 when(mMockPhone.getRingingCall()).thenReturn(mMockCall); 156 when(mMockPhone.getContext()).thenReturn(mMockContext); 157 when(mMockPhone.getCurrentSubscriberUris()).thenReturn(null); 158 when(mMockContext.getResources()).thenReturn(mMockResources); 159 when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver); 160 when(mMockContext.getSystemService(Context.TELEPHONY_SERVICE)) 161 .thenReturn(mMockTelephonyManager); 162 when(mMockContext.getAttributionSource()).thenReturn(attributionSource); 163 when(mMockContentResolver.getUserId()).thenReturn(UserHandle.USER_CURRENT); 164 when(mMockContentResolver.getAttributionSource()).thenReturn(attributionSource); 165 when(mMockResources.getBoolean(anyInt())).thenReturn(false); 166 when(mMockPhone.getDefaultPhone()).thenReturn(mMockPhone); 167 when(mMockPhone.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_IMS); 168 when(mMockCall.getState()).thenReturn(Call.State.ACTIVE); 169 when(mMockCall.getPhone()).thenReturn(mMockPhone); 170 when(mMockPhone.getDefaultPhone()).thenReturn(mMockPhone); 171 when(mImsPhoneConnection.getImsCall()).thenReturn(mImsCall); 172 when(mTelecomAccountRegistry.isMergeCallSupported(notNull(PhoneAccountHandle.class))) 173 .thenReturn(mIsConferenceSupported); 174 when(mTelecomAccountRegistry.isMergeImsCallSupported(notNull(PhoneAccountHandle.class))) 175 .thenReturn(mIsImsConnection); 176 when(mTelecomAccountRegistry 177 .isVideoConferencingSupported(notNull(PhoneAccountHandle.class))).thenReturn(false); 178 when(mTelecomAccountRegistry 179 .isMergeOfWifiCallsAllowedWhenVoWifiOff(notNull(PhoneAccountHandle.class))) 180 .thenReturn(false); 181 try { 182 doNothing().when(mMockCall).hangup(); 183 } catch (CallStateException e) { 184 e.printStackTrace(); 185 } 186 } 187 setMockPhone(Phone newPhone)188 public void setMockPhone(Phone newPhone) { 189 mMockPhone = newPhone; 190 } 191 192 @Override getPhone()193 public Phone getPhone() { 194 return mMockPhone; 195 } 196 cloneConnection()197 public TelephonyConnection cloneConnection() { 198 return this; 199 } 200 201 @Override notifyPhoneAccountChanged(PhoneAccountHandle pHandle)202 public void notifyPhoneAccountChanged(PhoneAccountHandle pHandle) { 203 mNotifyPhoneAccountChangedCount++; 204 } 205 206 @Override sendConnectionEvent(String event, Bundle extras)207 public void sendConnectionEvent(String event, Bundle extras) { 208 mLastConnectionEvents.add(event); 209 mLastConnectionEventExtras.add(extras); 210 } 211 212 @Override clearOriginalConnection()213 void clearOriginalConnection() { 214 // Do nothing since the original connection is mock object 215 } 216 217 @Override getCarrierConfig()218 public PersistableBundle getCarrierConfig() { 219 // Depends on PhoneGlobals for context in TelephonyConnection, do not implement during 220 // testing. 221 return mCarrierConfig; 222 } 223 224 @Override refreshConferenceSupported()225 public void refreshConferenceSupported() { 226 if (mIsImsConnection) { 227 super.refreshConferenceSupported(); 228 } 229 } 230 231 @Override getResourceText(int messageId)232 public CharSequence getResourceText(int messageId) { 233 return "TEST"; 234 } 235 236 @Override getResourceString(int id)237 public String getResourceString(int id) { 238 return "TEST"; 239 } 240 241 @Override setConferenceSupported(boolean conferenceSupported)242 public void setConferenceSupported(boolean conferenceSupported) { 243 mIsConferenceSupported = conferenceSupported; 244 } 245 246 @Override isConferenceSupported()247 public boolean isConferenceSupported() { 248 return mIsConferenceSupported; 249 } 250 251 @Override getTelecomAccountRegistry(Context context)252 public TelecomAccountRegistry getTelecomAccountRegistry(Context context) { 253 return mTelecomAccountRegistry; 254 } 255 setIsVideoCall(boolean isVideoCall)256 public void setIsVideoCall(boolean isVideoCall) { 257 if (isVideoCall) { 258 setVideoState(VideoProfile.STATE_TX_ENABLED); 259 } else { 260 setVideoState(VideoProfile.STATE_AUDIO_ONLY); 261 } 262 } 263 setWasVideoCall(boolean wasVideoCall)264 public void setWasVideoCall(boolean wasVideoCall) { 265 when(mImsCall.wasVideoCall()).thenReturn(wasVideoCall); 266 } 267 268 @Override isWfcEnabled(Phone phone)269 boolean isWfcEnabled(Phone phone) { 270 // Requires ImsManager dependencies, mock for test. 271 return true; 272 } 273 getNotifyPhoneAccountChangedCount()274 public int getNotifyPhoneAccountChangedCount() { 275 return mNotifyPhoneAccountChangedCount; 276 } 277 getLastConnectionEvents()278 public List<String> getLastConnectionEvents() { 279 return mLastConnectionEvents; 280 } 281 getLastConnectionEventExtras()282 public List<Bundle> getLastConnectionEventExtras() { 283 return mLastConnectionEventExtras; 284 } 285 setIsImsConnection(boolean isImsConnection)286 public void setIsImsConnection(boolean isImsConnection) { 287 mIsImsConnection = isImsConnection; 288 when(mTelecomAccountRegistry.isMergeImsCallSupported(notNull(PhoneAccountHandle.class))) 289 .thenReturn(isImsConnection && mIsConferenceSupported); 290 } 291 setIsImsExternalConnection(boolean isExternalConnection)292 public void setIsImsExternalConnection(boolean isExternalConnection) { 293 mIsImsExternalConnection = isExternalConnection; 294 } 295 setDownGradeVideoCall(boolean downgrade)296 public void setDownGradeVideoCall(boolean downgrade) { 297 PersistableBundle bundle = new PersistableBundle(); 298 bundle.putBoolean(CarrierConfigManager.KEY_TREAT_DOWNGRADED_VIDEO_CALLS_AS_VIDEO_CALLS_BOOL, 299 downgrade); 300 when(mMockContext.getSystemService(Context.CARRIER_CONFIG_SERVICE)) 301 .thenReturn(mCarrierConfigManager); 302 when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(bundle); 303 } 304 getCarrierConfigBundle()305 public PersistableBundle getCarrierConfigBundle() { 306 return mCarrierConfig; 307 } 308 getMockImsPhoneConnection()309 public ImsPhoneConnection getMockImsPhoneConnection() { 310 return mImsPhoneConnection; 311 } 312 setMockImsPhoneConnection(ImsPhoneConnection connection)313 public void setMockImsPhoneConnection(ImsPhoneConnection connection) { 314 mImsPhoneConnection = connection; 315 } 316 } 317