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 android.net.Uri;
20 import android.os.Bundle;
21 import android.telecom.CallEndpoint;
22 import android.telecom.Conference;
23 import android.telecom.Connection;
24 import android.telecom.DisconnectCause;
25 import android.telecom.PhoneAccountHandle;
26 import android.telecom.RemoteConference;
27 import android.telecom.TelecomManager;
28 import android.telecom.VideoProfile;
29 
30 import java.util.ArrayList;
31 import java.util.List;
32 import java.util.concurrent.CompletableFuture;
33 import java.util.concurrent.ExecutionException;
34 import java.util.concurrent.TimeUnit;
35 import java.util.concurrent.TimeoutException;
36 
37 /**
38  * {@link Conference} subclass that immediately performs any state changes that are a result of
39  * callbacks sent from Telecom.
40  */
41 public class MockConference extends Conference {
42 
43     private RemoteConference mRemoteConference = null;
44     private String mDtmfString = "";
45     public TestUtils.InvokeCounter mOnExtrasChanged =
46             new TestUtils.InvokeCounter("onExtrasChanged");
47     public TestUtils.InvokeCounter mCurrentCallEndpoint =
48             new TestUtils.InvokeCounter("mCurrentCallEndpoint");
49     public List<Uri> mParticipants = new ArrayList<>();
50     public CompletableFuture<Void> mLock = new CompletableFuture<>();
51     private int mVideoState = VideoProfile.STATE_AUDIO_ONLY;
52 
MockConference(PhoneAccountHandle phoneAccount)53     public MockConference(PhoneAccountHandle phoneAccount) {
54         super(phoneAccount);
55     }
56 
MockConference(MockConnection a, MockConnection b)57     public MockConference(MockConnection a, MockConnection b) {
58         super(a.getMockPhoneAccountHandle());
59         addConnection(a);
60         addConnection(b);
61         // a is the primary connection, so inherit the properties from it.
62         setConnectionCapabilities(a.getConnectionCapabilities());
63         setStatusHints(a.getStatusHints());
64         setExtras(a.getExtras());
65     }
66 
67     @Override
onDisconnect()68     public void onDisconnect() {
69         super.onDisconnect();
70         for (Connection c : getConnections()) {
71             c.setDisconnected(new DisconnectCause(DisconnectCause.REMOTE));
72             c.destroy();
73         }
74         destroy();
75         if (mRemoteConference != null) {
76             mRemoteConference.disconnect();
77         }
78     }
79 
80     @Override
onReject()81     public void onReject() {
82         super.onReject();
83         for (Connection c : getConnections()) {
84             c.setDisconnected(new DisconnectCause(DisconnectCause.REJECTED));
85             c.destroy();
86         }
87         destroy();
88         if (mRemoteConference != null) {
89             mRemoteConference.disconnect();
90         }
91         mLock.complete(null);
92     }
93 
94     @Override
onSeparate(Connection connection)95     public void onSeparate(Connection connection) {
96         super.onSeparate(connection);
97         if (getConnections().contains(connection)) {
98             removeConnection(connection);
99         }
100         if (mRemoteConference != null) {
101             mRemoteConference.separate(((MockConnection)connection).getRemoteConnection());
102         }
103     }
104 
105     @Override
onMerge()106     public void onMerge() {
107         super.onMerge();
108         // Let's just change the connection display name for testing that onMerge was invoked.
109         for (Connection c : getConnections()) {
110             c.setCallerDisplayName(
111                     TestUtils.MERGE_CALLER_NAME, TelecomManager.PRESENTATION_ALLOWED);
112         }
113         if (mRemoteConference != null) {
114             mRemoteConference.merge();
115         }
116     }
117 
118     @Override
onSwap()119     public void onSwap() {
120         super.onSwap();
121         // Let's just change the connection display name for testing that onSwap was invoked.
122         for (Connection c : getConnections()) {
123             c.setCallerDisplayName(
124                     TestUtils.SWAP_CALLER_NAME, TelecomManager.PRESENTATION_ALLOWED);
125         }
126         if (mRemoteConference != null) {
127             mRemoteConference.swap();
128         }
129     }
130 
131     @Override
onHold()132     public void onHold() {
133         super.onHold();
134         for (Connection c : getConnections()) {
135             c.setOnHold();
136         }
137         setOnHold();
138         if (mRemoteConference != null) {
139             mRemoteConference.hold();
140         }
141     }
142 
143     @Override
onUnhold()144     public void onUnhold() {
145         super.onUnhold();
146         for (Connection c : getConnections()) {
147             c.setActive();
148         }
149         setActive();
150         if (mRemoteConference != null) {
151             mRemoteConference.unhold();
152         }
153     }
154 
155     @Override
onPlayDtmfTone(char c)156     public void onPlayDtmfTone(char c) {
157         super.onPlayDtmfTone(c);
158         mDtmfString += c;
159         if (mRemoteConference != null) {
160             mRemoteConference.playDtmfTone(c);
161         }
162     }
163 
164     @Override
onStopDtmfTone()165     public void onStopDtmfTone() {
166         super.onStopDtmfTone();
167         mDtmfString += ".";
168         if (mRemoteConference != null) {
169             mRemoteConference.stopDtmfTone();
170         }
171     }
172 
173     @Override
onAddConferenceParticipants(List<Uri> participants)174     public void onAddConferenceParticipants(List<Uri> participants) {
175         super.onAddConferenceParticipants(participants);
176         mParticipants.addAll(participants);
177         mLock.complete(null);
178     }
179 
180     @Override
onAnswer(int videoState)181     public void onAnswer(int videoState) {
182         super.onAnswer(videoState);
183         mVideoState = videoState;
184         mLock.complete(null);
185     }
186 
setRemoteConference(RemoteConference remoteConference)187     public void setRemoteConference(RemoteConference remoteConference) {
188         mRemoteConference = remoteConference;
189         Bundle bundle = remoteConference.getExtras();
190         if (bundle != null) {
191             this.putExtras(bundle);
192         }
193     }
194 
getRemoteConference()195     public RemoteConference getRemoteConference() {
196         return mRemoteConference;
197     }
198 
getDtmfString()199     public String getDtmfString() {
200         return mDtmfString;
201     }
202 
getVideoState()203     public int getVideoState() {
204         return mVideoState;
205     }
206 
207     @Override
onExtrasChanged(Bundle extras)208     public void onExtrasChanged(Bundle extras) {
209         setExtras(extras);
210         mOnExtrasChanged.invoke(extras);
211     }
212 
213     @Override
onCallEndpointChanged(CallEndpoint callEndpoint)214     public void onCallEndpointChanged(CallEndpoint callEndpoint) {
215         mCurrentCallEndpoint.invoke(callEndpoint);
216     }
217 
acquireLock(long time, TimeUnit unit)218     public boolean acquireLock(long time, TimeUnit unit) {
219         try {
220             mLock.get(time, unit);
221         } catch (InterruptedException | ExecutionException | TimeoutException e) {
222             return false;
223         }
224         return true;
225     }
226 
resetLock()227     public void resetLock() {
228         mLock = new CompletableFuture<>();
229     }
230 }
231