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