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