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