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 android.telecom.cts; 18 19 import static android.telecom.CallAudioState.*; 20 21 import android.net.Uri; 22 import android.os.Bundle; 23 import android.telecom.CallAudioState; 24 import android.telecom.CallScreeningService; 25 import android.telecom.Connection; 26 import android.telecom.DisconnectCause; 27 import android.telecom.PhoneAccountHandle; 28 import android.telecom.RemoteConnection; 29 import android.telecom.VideoProfile; 30 import android.telecom.cts.TestUtils.InvokeCounter; 31 import android.util.SparseArray; 32 33 import java.util.List; 34 35 /** 36 * {@link Connection} subclass that immediately performs any state changes that are a result of 37 * callbacks sent from Telecom. 38 */ 39 public class MockConnection extends Connection { 40 public static final int ON_POST_DIAL_WAIT = 1; 41 public static final int ON_CALL_EVENT = 2; 42 public static final int ON_PULL_EXTERNAL_CALL = 3; 43 public static final int ON_EXTRAS_CHANGED = 4; 44 public static final int ON_START_RTT = 5; 45 public static final int ON_RTT_REQUEST_RESPONSE = 6; 46 public static final int ON_STOP_RTT = 7; 47 public static final int ON_DEFLECT = 8; 48 public static final int ON_SILENCE = 9; 49 public static final int ON_ADD_CONFERENCE_PARTICIPANTS = 10; 50 public static final int ON_CALL_FILTERING_COMPLETED = 11; 51 public static final int ON_ANSWER_CALLED = 12; 52 public static final int ON_ANSWER_VIDEO_CALLED = 13; 53 54 private CallAudioState mCallAudioState = 55 new CallAudioState(false, CallAudioState.ROUTE_EARPIECE, ROUTE_EARPIECE | ROUTE_SPEAKER); 56 private int mState = STATE_NEW; 57 public int videoState = VideoProfile.STATE_AUDIO_ONLY; 58 private String mDtmfString = ""; 59 private MockVideoProvider mMockVideoProvider; 60 private PhoneAccountHandle mPhoneAccountHandle; 61 private RemoteConnection mRemoteConnection = null; 62 private RttTextStream mRttTextStream; 63 private boolean mAutoDestroy = true; 64 65 private SparseArray<InvokeCounter> mInvokeCounterMap = new SparseArray<>(13); 66 67 @Override onAnswer()68 public void onAnswer() { 69 super.onAnswer(); 70 if (mInvokeCounterMap.get(ON_ANSWER_CALLED) != null) { 71 mInvokeCounterMap.get(ON_ANSWER_CALLED).invoke(); 72 } 73 } 74 75 @Override onAnswer(int videoState)76 public void onAnswer(int videoState) { 77 super.onAnswer(videoState); 78 this.videoState = videoState; 79 setActive(); 80 if (mRemoteConnection != null) { 81 mRemoteConnection.answer(); 82 } 83 if (mInvokeCounterMap.get(ON_ANSWER_VIDEO_CALLED) != null) { 84 mInvokeCounterMap.get(ON_ANSWER_VIDEO_CALLED).invoke(videoState); 85 } 86 } 87 88 @Override onReject()89 public void onReject() { 90 super.onReject(); 91 setDisconnected(new DisconnectCause(DisconnectCause.REJECTED)); 92 if (mRemoteConnection != null) { 93 mRemoteConnection.reject(); 94 } 95 if (mAutoDestroy) destroy(); 96 } 97 98 @Override onReject(int rejectReason)99 public void onReject(int rejectReason) { 100 super.onReject(rejectReason); 101 setDisconnected(new DisconnectCause(DisconnectCause.REJECTED, 102 Integer.toString(rejectReason))); 103 if (mAutoDestroy) destroy(); 104 } 105 106 @Override onReject(String reason)107 public void onReject(String reason) { 108 super.onReject(); 109 setDisconnected(new DisconnectCause(DisconnectCause.REJECTED, reason)); 110 if (mRemoteConnection != null) { 111 mRemoteConnection.reject(); 112 } 113 if (mAutoDestroy) destroy(); 114 } 115 116 @Override onHold()117 public void onHold() { 118 super.onHold(); 119 setOnHold(); 120 if (mRemoteConnection != null) { 121 mRemoteConnection.hold(); 122 } 123 } 124 125 @Override onUnhold()126 public void onUnhold() { 127 super.onUnhold(); 128 setActive(); 129 if (mRemoteConnection != null) { 130 mRemoteConnection.unhold(); 131 } 132 } 133 134 @Override onDisconnect()135 public void onDisconnect() { 136 super.onDisconnect(); 137 setDisconnected(new DisconnectCause(DisconnectCause.LOCAL)); 138 if (mRemoteConnection != null) { 139 mRemoteConnection.disconnect(); 140 } 141 if (mAutoDestroy) destroy(); 142 } 143 144 @Override onAbort()145 public void onAbort() { 146 super.onAbort(); 147 setDisconnected(new DisconnectCause(DisconnectCause.UNKNOWN)); 148 if (mRemoteConnection != null) { 149 mRemoteConnection.abort(); 150 } 151 if (mAutoDestroy) destroy(); 152 } 153 154 @Override onPlayDtmfTone(char c)155 public void onPlayDtmfTone(char c) { 156 super.onPlayDtmfTone(c); 157 mDtmfString += c; 158 if (mRemoteConnection != null) { 159 mRemoteConnection.playDtmfTone(c); 160 } 161 } 162 163 @Override onStopDtmfTone()164 public void onStopDtmfTone() { 165 super.onStopDtmfTone(); 166 mDtmfString += "."; 167 if (mRemoteConnection != null) { 168 mRemoteConnection.stopDtmfTone(); 169 } 170 } 171 172 @Override onCallAudioStateChanged(CallAudioState state)173 public void onCallAudioStateChanged(CallAudioState state) { 174 super.onCallAudioStateChanged(state); 175 mCallAudioState = state; 176 if (mRemoteConnection != null) { 177 mRemoteConnection.setCallAudioState(state); 178 } 179 } 180 181 @Override onStateChanged(int state)182 public void onStateChanged(int state) { 183 super.onStateChanged(state); 184 mState = state; 185 } 186 187 @Override onPostDialContinue(boolean proceed)188 public void onPostDialContinue(boolean proceed) { 189 super.onPostDialContinue(proceed); 190 if (mInvokeCounterMap.get(ON_POST_DIAL_WAIT) != null) { 191 mInvokeCounterMap.get(ON_POST_DIAL_WAIT).invoke(proceed); 192 } 193 } 194 195 @Override onCallEvent(String event, Bundle extras)196 public void onCallEvent(String event, Bundle extras) { 197 super.onCallEvent(event, extras); 198 if (mInvokeCounterMap.get(ON_CALL_EVENT) != null) { 199 mInvokeCounterMap.get(ON_CALL_EVENT).invoke(event, extras); 200 } 201 } 202 203 @Override onPullExternalCall()204 public void onPullExternalCall() { 205 super.onPullExternalCall(); 206 if (mInvokeCounterMap.get(ON_PULL_EXTERNAL_CALL) != null) { 207 mInvokeCounterMap.get(ON_PULL_EXTERNAL_CALL).invoke(); 208 } 209 } 210 211 @Override onAddConferenceParticipants(List<Uri> participants)212 public void onAddConferenceParticipants(List<Uri> participants) { 213 super.onAddConferenceParticipants(participants); 214 if (mInvokeCounterMap.get(ON_ADD_CONFERENCE_PARTICIPANTS) != null) { 215 mInvokeCounterMap.get(ON_ADD_CONFERENCE_PARTICIPANTS).invoke(participants); 216 } 217 } 218 219 @Override onExtrasChanged(Bundle extras)220 public void onExtrasChanged(Bundle extras) { 221 super.onExtrasChanged(extras); 222 if (mInvokeCounterMap.get(ON_EXTRAS_CHANGED) != null) { 223 mInvokeCounterMap.get(ON_EXTRAS_CHANGED).invoke(extras); 224 } 225 } 226 227 @Override onStartRtt(RttTextStream rttTextStream)228 public void onStartRtt(RttTextStream rttTextStream) { 229 super.onStartRtt(rttTextStream); 230 if (mInvokeCounterMap.get(ON_START_RTT) != null) { 231 mInvokeCounterMap.get(ON_START_RTT).invoke(rttTextStream); 232 } 233 } 234 235 @Override handleRttUpgradeResponse(RttTextStream rttTextStream)236 public void handleRttUpgradeResponse(RttTextStream rttTextStream) { 237 super.handleRttUpgradeResponse(rttTextStream); 238 if (rttTextStream != null) { 239 setRttTextStream(rttTextStream); 240 setConnectionProperties(getConnectionProperties() | PROPERTY_IS_RTT); 241 } 242 243 if (mInvokeCounterMap.get(ON_RTT_REQUEST_RESPONSE) != null) { 244 mInvokeCounterMap.get(ON_RTT_REQUEST_RESPONSE).invoke(rttTextStream); 245 } 246 } 247 248 @Override onStopRtt()249 public void onStopRtt() { 250 super.onStopRtt(); 251 252 if (mInvokeCounterMap.get(ON_STOP_RTT) != null) { 253 mInvokeCounterMap.get(ON_STOP_RTT).invoke(); 254 } 255 } 256 257 @Override onDeflect(Uri address)258 public void onDeflect(Uri address) { 259 if (mInvokeCounterMap.get(ON_DEFLECT) != null) { 260 mInvokeCounterMap.get(ON_DEFLECT).invoke(address); 261 } 262 } 263 264 @Override onSilence()265 public void onSilence() { 266 super.onSilence(); 267 268 if (mInvokeCounterMap.get(ON_SILENCE) != null) { 269 mInvokeCounterMap.get(ON_SILENCE).invoke(); 270 } 271 } 272 273 @Override onCallFilteringCompleted( Connection.CallFilteringCompletionInfo callFilteringCompletionInfo)274 public void onCallFilteringCompleted( 275 Connection.CallFilteringCompletionInfo callFilteringCompletionInfo) { 276 getInvokeCounter(ON_CALL_FILTERING_COMPLETED).invoke(callFilteringCompletionInfo); 277 278 if (mRemoteConnection != null) { 279 mRemoteConnection.onCallFilteringCompleted(callFilteringCompletionInfo); 280 } 281 } 282 283 /** 284 * Do not destroy after setting disconnected for cases that need finer state control. If 285 * disabled the caller will need to call destroy manually. 286 */ disableAutoDestroy()287 public void disableAutoDestroy() { 288 mAutoDestroy = false; 289 } 290 getCurrentState()291 public int getCurrentState() { 292 return mState; 293 } 294 getCurrentCallAudioState()295 public CallAudioState getCurrentCallAudioState() { 296 return mCallAudioState; 297 } 298 getDtmfString()299 public String getDtmfString() { 300 return mDtmfString; 301 } 302 getInvokeCounter(int counterIndex)303 public InvokeCounter getInvokeCounter(int counterIndex) { 304 if (mInvokeCounterMap.get(counterIndex) == null) { 305 mInvokeCounterMap.put(counterIndex, 306 new InvokeCounter(getCounterLabel(counterIndex))); 307 } 308 return mInvokeCounterMap.get(counterIndex); 309 } 310 311 /** 312 * Creates a mock video provider for this connection. 313 */ createMockVideoProvider()314 public void createMockVideoProvider() { 315 final MockVideoProvider mockVideoProvider = new MockVideoProvider(this); 316 mMockVideoProvider = mockVideoProvider; 317 setVideoProvider(mockVideoProvider); 318 } 319 sendMockVideoQuality(int videoQuality)320 public void sendMockVideoQuality(int videoQuality) { 321 if (mMockVideoProvider == null) { 322 return; 323 } 324 mMockVideoProvider.sendMockVideoQuality(videoQuality); 325 } 326 sendMockCallSessionEvent(int event)327 public void sendMockCallSessionEvent(int event) { 328 if (mMockVideoProvider == null) { 329 return; 330 } 331 mMockVideoProvider.sendMockCallSessionEvent(event); 332 } 333 sendMockPeerWidth(int width)334 public void sendMockPeerWidth(int width) { 335 if (mMockVideoProvider == null) { 336 return; 337 } 338 mMockVideoProvider.sendMockPeerWidth(width); 339 } 340 sendMockSessionModifyRequest(VideoProfile request)341 public void sendMockSessionModifyRequest(VideoProfile request) { 342 if (mMockVideoProvider == null) { 343 return; 344 } 345 mMockVideoProvider.sendMockSessionModifyRequest(request); 346 } 347 getMockVideoProvider()348 public MockVideoProvider getMockVideoProvider() { 349 return mMockVideoProvider; 350 } 351 setMockPhoneAccountHandle(PhoneAccountHandle handle)352 public void setMockPhoneAccountHandle(PhoneAccountHandle handle) { 353 mPhoneAccountHandle = handle; 354 } 355 getMockPhoneAccountHandle()356 public PhoneAccountHandle getMockPhoneAccountHandle() { 357 return mPhoneAccountHandle; 358 } 359 setRemoteConnection(RemoteConnection remoteConnection)360 public void setRemoteConnection(RemoteConnection remoteConnection) { 361 mRemoteConnection = remoteConnection; 362 } 363 getRemoteConnection()364 public RemoteConnection getRemoteConnection() { 365 return mRemoteConnection; 366 } 367 setRttTextStream(RttTextStream rttTextStream)368 public void setRttTextStream(RttTextStream rttTextStream) { 369 mRttTextStream = rttTextStream; 370 } 371 getRttTextStream()372 public RttTextStream getRttTextStream() { 373 return mRttTextStream; 374 } 375 getCounterLabel(int counterIndex)376 private static String getCounterLabel(int counterIndex) { 377 switch (counterIndex) { 378 case ON_POST_DIAL_WAIT: 379 return "onPostDialWait"; 380 case ON_CALL_EVENT: 381 return "onCallEvent"; 382 case ON_PULL_EXTERNAL_CALL: 383 return "onPullExternalCall"; 384 case ON_EXTRAS_CHANGED: 385 return "onExtrasChanged"; 386 case ON_START_RTT: 387 return "onStartRtt"; 388 case ON_RTT_REQUEST_RESPONSE: 389 return "onRttRequestResponse"; 390 case ON_STOP_RTT: 391 return "onStopRtt"; 392 case ON_DEFLECT: 393 return "onDeflect"; 394 case ON_SILENCE: 395 return "onSilence"; 396 case ON_ADD_CONFERENCE_PARTICIPANTS: 397 return "onAddConferenceParticipants"; 398 default: 399 return "Callback"; 400 } 401 } 402 } 403