1 /*
2  * Copyright (C) 2013 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.server.telecom.testapps;
18 
19 import android.net.Uri;
20 import android.telecom.CallAudioState;
21 import android.telecom.Conference;
22 import android.telecom.Connection;
23 import android.telecom.ConnectionRequest;
24 import android.telecom.ConnectionService;
25 import android.telecom.DisconnectCause;
26 import android.telecom.PhoneAccountHandle;
27 import android.telecom.RemoteConference;
28 import android.telecom.RemoteConnection;
29 import android.telecom.StatusHints;
30 import android.telecom.VideoProfile;
31 import android.util.Log;
32 
33 import java.util.ArrayList;
34 import java.util.HashMap;
35 import java.util.List;
36 import java.util.Map;
37 
38 /**
39  * Service which acts as a fake ConnectionManager if so configured.
40  */
41 public class TestConnectionManager extends ConnectionService {
42     public final class TestManagedConnection extends Connection {
43         private final RemoteConnection.Callback mRemoteCallback = new RemoteConnection.Callback() {
44             @Override
45             public void onStateChanged(RemoteConnection connection, int state) {
46                 setState(state);
47             }
48 
49             @Override
50             public void onDisconnected(
51                     RemoteConnection connection, DisconnectCause disconnectCause) {
52                 setDisconnected(disconnectCause);
53                 destroy();
54             }
55 
56             @Override
57             public void onRingbackRequested(RemoteConnection connection, boolean ringback) {
58                 setRingbackRequested(ringback);
59             }
60 
61             @Override
62             public void onConnectionCapabilitiesChanged(RemoteConnection connection,
63                     int connectionCapabilities) {
64                 setConnectionCapabilities(connectionCapabilities);
65             }
66 
67             @Override
68             public void onConnectionPropertiesChanged(RemoteConnection connection,
69                     int connectionProperties) {
70                 setConnectionProperties(connectionProperties);
71             }
72 
73             @Override
74             public void onPostDialWait(RemoteConnection connection, String remainingDigits) {
75                 setPostDialWait(remainingDigits);
76             }
77 
78             @Override
79             public void onVoipAudioChanged(RemoteConnection connection, boolean isVoip) {
80                 setAudioModeIsVoip(isVoip);
81             }
82 
83             @Override
84             public void onStatusHintsChanged(RemoteConnection connection, StatusHints statusHints) {
85                 setStatusHints(statusHints);
86             }
87 
88             @Override
89             public void onVideoStateChanged(RemoteConnection connection, int videoState) {
90                 if (videoState == VideoProfile.STATE_BIDIRECTIONAL) {
91                     setVideoProvider(new TestManagedVideoProvider(connection.getVideoProvider()));
92                 }
93                 setVideoState(videoState);
94             }
95 
96             @Override
97             public void onAddressChanged(
98                     RemoteConnection connection, Uri address, int presentation) {
99                 setAddress(address, presentation);
100             }
101 
102             @Override
103             public void onCallerDisplayNameChanged(
104                     RemoteConnection connection, String callerDisplayName, int presentation) {
105                 setCallerDisplayName(callerDisplayName, presentation);
106             }
107 
108             @Override
109             public void onDestroyed(RemoteConnection connection) {
110                 destroy();
111                 mManagedConnectionByRemote.remove(mRemote);
112             }
113 
114             @Override
115             public void onConferenceableConnectionsChanged(
116                     RemoteConnection connect,
117                     List<RemoteConnection> conferenceable) {
118                 List<Connection> c = new ArrayList<>();
119                 for (RemoteConnection remote : conferenceable) {
120                     if (mManagedConnectionByRemote.containsKey(remote)) {
121                         c.add(mManagedConnectionByRemote.get(remote));
122                     }
123                 }
124                 setConferenceableConnections(c);
125             }
126 
127             @Override
128             public void onRttInitiationSuccess(RemoteConnection connection) {
129                 sendRttInitiationSuccess();
130             }
131 
132             @Override
133             public void onRttInitiationFailure(RemoteConnection connection, int reason) {
134                 sendRttInitiationFailure(reason);
135             }
136 
137             @Override
138             public void onRttSessionRemotelyTerminated(RemoteConnection connection) {
139                 sendRttSessionRemotelyTerminated();
140             }
141 
142             @Override
143             public void onRemoteRttRequest(RemoteConnection connection) {
144                 sendRemoteRttRequest();
145             }
146         };
147 
148         private final RemoteConnection mRemote;
149         private final boolean mIsIncoming;
150 
TestManagedConnection(RemoteConnection remote, boolean isIncoming)151         TestManagedConnection(RemoteConnection remote, boolean isIncoming) {
152             mRemote = remote;
153             mIsIncoming = isIncoming;
154             mRemote.registerCallback(mRemoteCallback);
155             setState(mRemote.getState());
156             setVideoState(mRemote.getVideoState());
157             setConnectionProperties(remote.getConnectionProperties());
158         }
159 
160         @Override
onAbort()161         public void onAbort() {
162             mRemote.abort();
163         }
164 
165         /**
166          * ${inheritDoc}
167          */
168         @Override
onAnswer(int videoState)169         public void onAnswer(int videoState) {
170             mRemote.answer(videoState);
171         }
172 
173         /**
174          * ${inheritDoc}
175          */
176         @Override
onDisconnect()177         public void onDisconnect() {
178             mRemote.disconnect();
179         }
180 
181         @Override
onPlayDtmfTone(char c)182         public void onPlayDtmfTone(char c) {
183             mRemote.playDtmfTone(c);
184         }
185 
186         /**
187          * ${inheritDoc}
188          */
189         @Override
onHold()190         public void onHold() {
191             mRemote.hold();
192         }
193 
194         /**
195          * ${inheritDoc}
196          */
197         @Override
onReject()198         public void onReject() {
199             mRemote.reject();
200         }
201 
202         /**
203          * ${inheritDoc}
204          */
205         @Override
onUnhold()206         public void onUnhold() {
207             mRemote.unhold();
208         }
209 
210         @Override
onCallAudioStateChanged(CallAudioState state)211         public void onCallAudioStateChanged(CallAudioState state) {
212             mRemote.setCallAudioState(state);
213         }
214 
215         @Override
onStartRtt(RttTextStream rttTextStream)216         public void onStartRtt(RttTextStream rttTextStream) {
217             mRemote.startRtt(rttTextStream);
218         }
219 
220         @Override
onStopRtt()221         public void onStopRtt() {
222             mRemote.stopRtt();
223         }
224 
225         @Override
handleRttUpgradeResponse(RttTextStream rttTextStream)226         public void handleRttUpgradeResponse(RttTextStream rttTextStream) {
227             mRemote.sendRttUpgradeResponse(rttTextStream);
228         }
229 
setState(int state)230         private void setState(int state) {
231             log("setState: " + state);
232             switch (state) {
233                 case STATE_ACTIVE:
234                     setActive();
235                     break;
236                 case STATE_HOLDING:
237                     setOnHold();
238                     break;
239                 case STATE_DIALING:
240                     setDialing();
241                     break;
242                 case STATE_RINGING:
243                     setRinging();
244                     break;
245             }
246         }
247     }
248     public final class TestManagedConference extends Conference {
249         private final RemoteConference.Callback mRemoteCallback = new RemoteConference.Callback() {
250             @Override
251             public void onStateChanged(RemoteConference conference, int oldState, int newState) {
252                 switch (newState) {
253                     case Connection.STATE_DISCONNECTED:
254                         // See onDisconnected below
255                         break;
256                     case Connection.STATE_HOLDING:
257                         setOnHold();
258                         break;
259                     case Connection.STATE_ACTIVE:
260                         setActive();
261                         break;
262                     default:
263                         log("unrecognized state for Conference: " + newState);
264                         break;
265                 }
266             }
267 
268             @Override
269             public void onDisconnected(RemoteConference conference,
270                     DisconnectCause disconnectCause) {
271                 setDisconnected(disconnectCause);
272             }
273 
274             @Override
275             public void onConnectionAdded(
276                     RemoteConference conference,
277                     RemoteConnection connection) {
278                 TestManagedConnection c = mManagedConnectionByRemote.get(connection);
279                 if (c == null) {
280                     log("onConnectionAdded cannot find remote connection: " + connection);
281                 } else {
282                     addConnection(c);
283                 }
284             }
285 
286             @Override
287             public void onConnectionRemoved(
288                     RemoteConference conference,
289                     RemoteConnection connection) {
290                 TestManagedConnection c = mManagedConnectionByRemote.get(connection);
291                 if (c == null) {
292                     log("onConnectionRemoved cannot find remote connection: " + connection);
293                 } else {
294                     removeConnection(c);
295                 }
296             }
297 
298             @Override
299             public void onConnectionCapabilitiesChanged(RemoteConference conference,
300                     int connectionCapabilities) {
301                 setConnectionCapabilities(connectionCapabilities);
302             }
303 
304             @Override
305             public void onConnectionPropertiesChanged(RemoteConference conference,
306                     int connectionProperties) {
307                 setConnectionProperties(connectionProperties);
308             }
309 
310             @Override
311             public void onDestroyed(RemoteConference conference) {
312                 destroy();
313                 mRemote.unregisterCallback(mRemoteCallback);
314                 mManagedConferenceByRemote.remove(mRemote);
315             }
316 
317         };
318 
319         @Override
onPlayDtmfTone(char c)320         public void onPlayDtmfTone(char c) {
321             mRemote.playDtmfTone(c);
322         };
323 
324         @Override
onStopDtmfTone()325         public void onStopDtmfTone() {
326             mRemote.stopDtmfTone();
327         };
328 
329         private final RemoteConference mRemote;
330 
TestManagedConference(RemoteConference remote)331         public TestManagedConference(RemoteConference remote) {
332             super(null);
333             mRemote = remote;
334             remote.registerCallback(mRemoteCallback);
335             setActive();
336             for (RemoteConnection r : remote.getConnections()) {
337                 TestManagedConnection c = mManagedConnectionByRemote.get(r);
338                 if (c != null) {
339                     addConnection(c);
340                 }
341             }
342         }
343     }
344 
log(String msg)345     static void log(String msg) {
346         Log.w("telecomtestcs", "[TestConnectionManager] " + msg);
347     }
348 
349     private final Map<RemoteConference, TestManagedConference> mManagedConferenceByRemote
350             = new HashMap<>();
351     private final Map<RemoteConnection, TestManagedConnection> mManagedConnectionByRemote
352             = new HashMap<>();
353 
354     @Override
onCreateOutgoingConnection( PhoneAccountHandle connectionManagerAccount, final ConnectionRequest request)355     public Connection onCreateOutgoingConnection(
356             PhoneAccountHandle connectionManagerAccount,
357             final ConnectionRequest request) {
358         return makeConnection(request, false);
359     }
360 
361     @Override
onCreateIncomingConnection( PhoneAccountHandle connectionManagerAccount, final ConnectionRequest request)362     public Connection onCreateIncomingConnection(
363             PhoneAccountHandle connectionManagerAccount,
364             final ConnectionRequest request) {
365         return makeConnection(request, true);
366     }
367 
368     @Override
onConference(Connection a, Connection b)369     public void onConference(Connection a, Connection b) {
370         conferenceRemoteConnections(
371                 ((TestManagedConnection) a).mRemote,
372                 ((TestManagedConnection) b).mRemote);
373     }
374 
375     @Override
onRemoteConferenceAdded(RemoteConference remoteConference)376     public void onRemoteConferenceAdded(RemoteConference remoteConference) {
377         addConference(new TestManagedConference(remoteConference));
378     }
379 
getManagedConnectionByRemote()380     Map<RemoteConnection, TestManagedConnection> getManagedConnectionByRemote() {
381         return mManagedConnectionByRemote;
382     }
383 
makeConnection(ConnectionRequest request, boolean incoming)384     private Connection makeConnection(ConnectionRequest request, boolean incoming) {
385         RemoteConnection remote = incoming
386                 ? createRemoteIncomingConnection(request.getAccountHandle(), request)
387                 : createRemoteOutgoingConnection(request.getAccountHandle(), request);
388         TestManagedConnection local = new TestManagedConnection(remote, false);
389         mManagedConnectionByRemote.put(remote, local);
390         return local;
391     }
392 }
393