blob: 1577a0f925f3e7834b0efd57a9ee255a45675cff [file] [log] [blame]
Santos Cordon52d8a152014-06-17 19:08:45 -07001/*
2 * Copyright (C) 2014 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
Ihab Awadb19a0bc2014-08-07 19:46:01 -070014 * limitations under the License.
Santos Cordon52d8a152014-06-17 19:08:45 -070015 */
16
Tyler Gunnef9f6f92014-09-12 22:16:17 -070017package android.telecom;
Santos Cordon52d8a152014-06-17 19:08:45 -070018
Santos Cordon52d8a152014-06-17 19:08:45 -070019import android.net.Uri;
Santos Cordon6b7f9552015-05-27 17:21:45 -070020import android.os.Bundle;
Ihab Awad5d0410f2014-07-30 10:07:40 -070021import android.os.IBinder;
Santos Cordone8dc4be2014-07-21 01:28:28 -070022import android.os.IBinder.DeathRecipient;
Santos Cordon52d8a152014-06-17 19:08:45 -070023import android.os.RemoteException;
Santos Cordon52d8a152014-06-17 19:08:45 -070024
Tyler Gunnef9f6f92014-09-12 22:16:17 -070025import com.android.internal.telecom.IConnectionService;
26import com.android.internal.telecom.IConnectionServiceAdapter;
27import com.android.internal.telecom.IVideoProvider;
28import com.android.internal.telecom.RemoteServiceCallback;
Santos Cordon52d8a152014-06-17 19:08:45 -070029
Ihab Awadb8e85c72014-08-23 20:34:57 -070030import java.util.ArrayList;
Ihab Awad5d0410f2014-07-30 10:07:40 -070031import java.util.HashMap;
32import java.util.HashSet;
33import java.util.Map;
34import java.util.Set;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -070035import java.util.List;
Santos Cordon52d8a152014-06-17 19:08:45 -070036import java.util.UUID;
37
38/**
39 * Remote connection service which other connection services can use to place calls on their behalf.
Sailesh Nepal091768c2014-06-30 15:15:23 -070040 *
41 * @hide
Santos Cordon52d8a152014-06-17 19:08:45 -070042 */
Ihab Awad5d0410f2014-07-30 10:07:40 -070043final class RemoteConnectionService {
Sailesh Nepal48031592014-07-18 14:21:23 -070044
Tyler Gunn4a57b9b2014-10-30 14:27:48 -070045 // Note: Casting null to avoid ambiguous constructor reference.
Ihab Awadb8e85c72014-08-23 20:34:57 -070046 private static final RemoteConnection NULL_CONNECTION =
Tyler Gunn4a57b9b2014-10-30 14:27:48 -070047 new RemoteConnection("NULL", null, (ConnectionRequest) null);
Ihab Awadb8e85c72014-08-23 20:34:57 -070048
49 private static final RemoteConference NULL_CONFERENCE =
50 new RemoteConference("NULL", null);
Santos Cordon52d8a152014-06-17 19:08:45 -070051
Ihab Awad5d0410f2014-07-30 10:07:40 -070052 private final IConnectionServiceAdapter mServantDelegate = new IConnectionServiceAdapter() {
Sailesh Nepal48031592014-07-18 14:21:23 -070053 @Override
Ihab Awad6107bab2014-08-18 09:23:25 -070054 public void handleCreateConnectionComplete(
Ihab Awadb19a0bc2014-08-07 19:46:01 -070055 String id,
56 ConnectionRequest request,
Ihab Awad5d0410f2014-07-30 10:07:40 -070057 ParcelableConnection parcel) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -070058 RemoteConnection connection =
59 findConnectionForAction(id, "handleCreateConnectionSuccessful");
Ihab Awad5d0410f2014-07-30 10:07:40 -070060 if (connection != NULL_CONNECTION && mPendingConnections.contains(connection)) {
61 mPendingConnections.remove(connection);
Ihab Awad6107bab2014-08-18 09:23:25 -070062 // Unconditionally initialize the connection ...
Ihab Awad5c9c86e2014-11-12 13:41:16 -080063 connection.setConnectionCapabilities(parcel.getConnectionCapabilities());
Tyler Gunn720c6642016-03-22 09:02:47 -070064 connection.setConnectionProperties(parcel.getConnectionProperties());
Sailesh Nepal2d3ced72015-01-31 20:17:35 -080065 if (parcel.getHandle() != null
66 || parcel.getState() != Connection.STATE_DISCONNECTED) {
67 connection.setAddress(parcel.getHandle(), parcel.getHandlePresentation());
68 }
69 if (parcel.getCallerDisplayName() != null
70 || parcel.getState() != Connection.STATE_DISCONNECTED) {
71 connection.setCallerDisplayName(
72 parcel.getCallerDisplayName(),
73 parcel.getCallerDisplayNamePresentation());
74 }
Sailesh Nepal70638f12014-09-09 21:49:14 -070075 // Set state after handle so that the client can identify the connection.
Sailesh Nepalc2a978d2014-09-20 18:23:05 -070076 if (parcel.getState() == Connection.STATE_DISCONNECTED) {
77 connection.setDisconnected(parcel.getDisconnectCause());
78 } else {
79 connection.setState(parcel.getState());
80 }
Ihab Awadb8e85c72014-08-23 20:34:57 -070081 List<RemoteConnection> conferenceable = new ArrayList<>();
82 for (String confId : parcel.getConferenceableConnectionIds()) {
83 if (mConnectionById.containsKey(confId)) {
84 conferenceable.add(mConnectionById.get(confId));
85 }
86 }
87 connection.setConferenceableConnections(conferenceable);
Ihab Awada64627c2014-08-20 09:36:40 -070088 connection.setVideoState(parcel.getVideoState());
Ihab Awad6107bab2014-08-18 09:23:25 -070089 if (connection.getState() == Connection.STATE_DISCONNECTED) {
90 // ... then, if it was created in a disconnected state, that indicates
91 // failure on the providing end, so immediately mark it destroyed
92 connection.setDestroyed();
93 }
Sailesh Nepal48031592014-07-18 14:21:23 -070094 }
95 }
Sailesh Nepal2ab88cc2014-07-18 14:49:18 -070096
Sailesh Nepal2a46b902014-07-04 17:21:07 -070097 @Override
Ihab Awad5d0410f2014-07-30 10:07:40 -070098 public void setActive(String callId) {
Ihab Awadb8e85c72014-08-23 20:34:57 -070099 if (mConnectionById.containsKey(callId)) {
100 findConnectionForAction(callId, "setActive")
101 .setState(Connection.STATE_ACTIVE);
102 } else {
103 findConferenceForAction(callId, "setActive")
104 .setState(Connection.STATE_ACTIVE);
105 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700106 }
107
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700108 @Override
Ihab Awad5d0410f2014-07-30 10:07:40 -0700109 public void setRinging(String callId) {
110 findConnectionForAction(callId, "setRinging")
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700111 .setState(Connection.STATE_RINGING);
Andrew Lee5ffbe8b2014-06-20 16:29:33 -0700112 }
113
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700114 @Override
Ihab Awad5d0410f2014-07-30 10:07:40 -0700115 public void setDialing(String callId) {
116 findConnectionForAction(callId, "setDialing")
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700117 .setState(Connection.STATE_DIALING);
Santos Cordon52d8a152014-06-17 19:08:45 -0700118 }
119
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700120 @Override
Tyler Gunnc96b5e02016-07-07 22:53:57 -0700121 public void setPulling(String callId) {
122 findConnectionForAction(callId, "setPulling")
123 .setState(Connection.STATE_PULLING_CALL);
124 }
125
126 @Override
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700127 public void setDisconnected(String callId, DisconnectCause disconnectCause) {
Ihab Awadb8e85c72014-08-23 20:34:57 -0700128 if (mConnectionById.containsKey(callId)) {
129 findConnectionForAction(callId, "setDisconnected")
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700130 .setDisconnected(disconnectCause);
Ihab Awadb8e85c72014-08-23 20:34:57 -0700131 } else {
132 findConferenceForAction(callId, "setDisconnected")
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700133 .setDisconnected(disconnectCause);
Ihab Awadb8e85c72014-08-23 20:34:57 -0700134 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700135 }
136
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700137 @Override
Ihab Awad5d0410f2014-07-30 10:07:40 -0700138 public void setOnHold(String callId) {
Ihab Awadb8e85c72014-08-23 20:34:57 -0700139 if (mConnectionById.containsKey(callId)) {
140 findConnectionForAction(callId, "setOnHold")
141 .setState(Connection.STATE_HOLDING);
142 } else {
143 findConferenceForAction(callId, "setOnHold")
144 .setState(Connection.STATE_HOLDING);
145 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700146 }
147
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700148 @Override
Andrew Lee100e2932014-09-08 15:34:24 -0700149 public void setRingbackRequested(String callId, boolean ringing) {
150 findConnectionForAction(callId, "setRingbackRequested")
151 .setRingbackRequested(ringing);
Santos Cordon52d8a152014-06-17 19:08:45 -0700152 }
153
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700154 @Override
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800155 public void setConnectionCapabilities(String callId, int connectionCapabilities) {
Ihab Awadb8e85c72014-08-23 20:34:57 -0700156 if (mConnectionById.containsKey(callId)) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800157 findConnectionForAction(callId, "setConnectionCapabilities")
158 .setConnectionCapabilities(connectionCapabilities);
Ihab Awadb8e85c72014-08-23 20:34:57 -0700159 } else {
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800160 findConferenceForAction(callId, "setConnectionCapabilities")
161 .setConnectionCapabilities(connectionCapabilities);
Ihab Awadb8e85c72014-08-23 20:34:57 -0700162 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700163 }
164
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700165 @Override
Tyler Gunn720c6642016-03-22 09:02:47 -0700166 public void setConnectionProperties(String callId, int connectionProperties) {
167 if (mConnectionById.containsKey(callId)) {
168 findConnectionForAction(callId, "setConnectionProperties")
169 .setConnectionProperties(connectionProperties);
170 } else {
171 findConferenceForAction(callId, "setConnectionProperties")
172 .setConnectionProperties(connectionProperties);
173 }
174 }
175
176 @Override
Ihab Awad5d0410f2014-07-30 10:07:40 -0700177 public void setIsConferenced(String callId, String conferenceCallId) {
Ihab Awadb8e85c72014-08-23 20:34:57 -0700178 // Note: callId should not be null; conferenceCallId may be null
179 RemoteConnection connection =
180 findConnectionForAction(callId, "setIsConferenced");
181 if (connection != NULL_CONNECTION) {
182 if (conferenceCallId == null) {
183 // 'connection' is being split from its conference
184 if (connection.getConference() != null) {
185 connection.getConference().removeConnection(connection);
186 }
187 } else {
188 RemoteConference conference =
189 findConferenceForAction(conferenceCallId, "setIsConferenced");
190 if (conference != NULL_CONFERENCE) {
191 conference.addConnection(connection);
192 }
193 }
194 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700195 }
196
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700197 @Override
Anthony Lee17455a32015-04-24 15:25:29 -0700198 public void setConferenceMergeFailed(String callId) {
199 // Nothing to do here.
200 // The event has already been handled and there is no state to update
201 // in the underlying connection or conference objects
202 }
203
204 @Override
Ihab Awadb8e85c72014-08-23 20:34:57 -0700205 public void addConferenceCall(
206 final String callId,
207 ParcelableConference parcel) {
208 RemoteConference conference = new RemoteConference(callId,
209 mOutgoingConnectionServiceRpc);
210
211 for (String id : parcel.getConnectionIds()) {
212 RemoteConnection c = mConnectionById.get(id);
213 if (c != null) {
214 conference.addConnection(c);
215 }
216 }
Ihab Awadb8e85c72014-08-23 20:34:57 -0700217 if (conference.getConnections().size() == 0) {
218 // A conference was created, but none of its connections are ones that have been
219 // created by, and therefore being tracked by, this remote connection service. It
220 // is of no interest to us.
Tyler Gunn2282bb92016-10-17 15:48:19 -0700221 Log.d(this, "addConferenceCall - skipping");
Ihab Awadb8e85c72014-08-23 20:34:57 -0700222 return;
223 }
224
225 conference.setState(parcel.getState());
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800226 conference.setConnectionCapabilities(parcel.getConnectionCapabilities());
Tyler Gunn04ce7572016-08-15 10:56:12 -0700227 conference.setConnectionProperties(parcel.getConnectionProperties());
Tyler Gunn2282bb92016-10-17 15:48:19 -0700228 conference.putExtras(parcel.getExtras());
Ihab Awadb8e85c72014-08-23 20:34:57 -0700229 mConferenceById.put(callId, conference);
Tyler Gunn2282bb92016-10-17 15:48:19 -0700230
231 // Stash the original connection ID as it exists in the source ConnectionService.
232 // Telecom will use this to avoid adding duplicates later.
233 // See comments on Connection.EXTRA_ORIGINAL_CONNECTION_ID for more information.
234 Bundle newExtras = new Bundle();
235 newExtras.putString(Connection.EXTRA_ORIGINAL_CONNECTION_ID, callId);
236 conference.putExtras(newExtras);
237
Andrew Lee100e2932014-09-08 15:34:24 -0700238 conference.registerCallback(new RemoteConference.Callback() {
Ihab Awadb8e85c72014-08-23 20:34:57 -0700239 @Override
240 public void onDestroyed(RemoteConference c) {
241 mConferenceById.remove(callId);
242 maybeDisconnectAdapter();
243 }
244 });
245
246 mOurConnectionServiceImpl.addRemoteConference(conference);
Santos Cordon52d8a152014-06-17 19:08:45 -0700247 }
248
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700249 @Override
Ihab Awad5d0410f2014-07-30 10:07:40 -0700250 public void removeCall(String callId) {
Ihab Awadb8e85c72014-08-23 20:34:57 -0700251 if (mConnectionById.containsKey(callId)) {
252 findConnectionForAction(callId, "removeCall")
253 .setDestroyed();
254 } else {
255 findConferenceForAction(callId, "removeCall")
256 .setDestroyed();
257 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700258 }
259
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700260 @Override
Ihab Awad5d0410f2014-07-30 10:07:40 -0700261 public void onPostDialWait(String callId, String remaining) {
262 findConnectionForAction(callId, "onPostDialWait")
263 .setPostDialWait(remaining);
Santos Cordon52d8a152014-06-17 19:08:45 -0700264 }
265
Santos Cordon52d8a152014-06-17 19:08:45 -0700266 @Override
Nancy Chen27d1c2d2014-12-15 16:12:50 -0800267 public void onPostDialChar(String callId, char nextChar) {
268 findConnectionForAction(callId, "onPostDialChar")
269 .onPostDialChar(nextChar);
270 }
271
272 @Override
Santos Cordon52d8a152014-06-17 19:08:45 -0700273 public void queryRemoteConnectionServices(RemoteServiceCallback callback) {
Ihab Awad5d0410f2014-07-30 10:07:40 -0700274 // Not supported from remote connection service.
Santos Cordon52d8a152014-06-17 19:08:45 -0700275 }
Tyler Gunn8d83fa92014-07-01 11:31:21 -0700276
Sailesh Nepal33aaae42014-07-07 22:49:44 -0700277 @Override
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700278 public void setVideoProvider(String callId, IVideoProvider videoProvider) {
Sailesh Nepal11aeae52015-01-28 16:54:09 -0800279 RemoteConnection.VideoProvider remoteVideoProvider = null;
280 if (videoProvider != null) {
281 remoteVideoProvider = new RemoteConnection.VideoProvider(videoProvider);
282 }
Ihab Awada64627c2014-08-20 09:36:40 -0700283 findConnectionForAction(callId, "setVideoProvider")
Sailesh Nepal11aeae52015-01-28 16:54:09 -0800284 .setVideoProvider(remoteVideoProvider);
Tyler Gunnaa07df82014-07-17 07:50:22 -0700285 }
286
287 @Override
Ihab Awad5d0410f2014-07-30 10:07:40 -0700288 public void setVideoState(String callId, int videoState) {
289 findConnectionForAction(callId, "setVideoState")
290 .setVideoState(videoState);
Sailesh Nepal33aaae42014-07-07 22:49:44 -0700291 }
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700292
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700293 @Override
Andrew Lee100e2932014-09-08 15:34:24 -0700294 public void setIsVoipAudioMode(String callId, boolean isVoip) {
295 findConnectionForAction(callId, "setIsVoipAudioMode")
296 .setIsVoipAudioMode(isVoip);
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700297 }
Sailesh Nepal61203862014-07-11 14:50:13 -0700298
299 @Override
Ihab Awad5d0410f2014-07-30 10:07:40 -0700300 public void setStatusHints(String callId, StatusHints statusHints) {
301 findConnectionForAction(callId, "setStatusHints")
302 .setStatusHints(statusHints);
Sailesh Nepal61203862014-07-11 14:50:13 -0700303 }
304
305 @Override
Andrew Lee100e2932014-09-08 15:34:24 -0700306 public void setAddress(String callId, Uri address, int presentation) {
307 findConnectionForAction(callId, "setAddress")
308 .setAddress(address, presentation);
Sailesh Nepal61203862014-07-11 14:50:13 -0700309 }
Sailesh Nepal2ab88cc2014-07-18 14:49:18 -0700310
311 @Override
Ihab Awad5d0410f2014-07-30 10:07:40 -0700312 public void setCallerDisplayName(String callId, String callerDisplayName,
313 int presentation) {
314 findConnectionForAction(callId, "setCallerDisplayName")
315 .setCallerDisplayName(callerDisplayName, presentation);
316 }
317
318 @Override
Ihab Awad5d0410f2014-07-30 10:07:40 -0700319 public IBinder asBinder() {
320 throw new UnsupportedOperationException();
Sailesh Nepal2ab88cc2014-07-18 14:49:18 -0700321 }
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700322
323 @Override
324 public final void setConferenceableConnections(
325 String callId, List<String> conferenceableConnectionIds) {
Ihab Awadb8e85c72014-08-23 20:34:57 -0700326 List<RemoteConnection> conferenceable = new ArrayList<>();
327 for (String id : conferenceableConnectionIds) {
328 if (mConnectionById.containsKey(id)) {
329 conferenceable.add(mConnectionById.get(id));
330 }
331 }
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700332
Ihab Awad50e35062014-09-30 09:17:03 -0700333 if (hasConnection(callId)) {
334 findConnectionForAction(callId, "setConferenceableConnections")
335 .setConferenceableConnections(conferenceable);
336 } else {
337 findConferenceForAction(callId, "setConferenceableConnections")
338 .setConferenceableConnections(conferenceable);
339 }
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700340 }
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700341
342 @Override
Tyler Gunn2282bb92016-10-17 15:48:19 -0700343 public void addExistingConnection(final String callId, ParcelableConnection connection) {
344 RemoteConnection remoteConnection = new RemoteConnection(callId,
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700345 mOutgoingConnectionServiceRpc, connection);
Tyler Gunn2282bb92016-10-17 15:48:19 -0700346 mConnectionById.put(callId, remoteConnection);
347 remoteConnection.registerCallback(new RemoteConnection.Callback() {
348 @Override
349 public void onDestroyed(RemoteConnection connection) {
350 mConnectionById.remove(callId);
351 maybeDisconnectAdapter();
352 }
353 });
354 mOurConnectionServiceImpl.addRemoteExistingConnection(remoteConnection);
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700355 }
Santos Cordon6b7f9552015-05-27 17:21:45 -0700356
357 @Override
Tyler Gunndee56a82016-03-23 16:06:34 -0700358 public void putExtras(String callId, Bundle extras) {
359 if (hasConnection(callId)) {
360 findConnectionForAction(callId, "putExtras").putExtras(extras);
Santos Cordon6b7f9552015-05-27 17:21:45 -0700361 } else {
Tyler Gunndee56a82016-03-23 16:06:34 -0700362 findConferenceForAction(callId, "putExtras").putExtras(extras);
363 }
364 }
365
366 @Override
367 public void removeExtras(String callId, List<String> keys) {
368 if (hasConnection(callId)) {
369 findConnectionForAction(callId, "removeExtra").removeExtras(keys);
370 } else {
371 findConferenceForAction(callId, "removeExtra").removeExtras(keys);
Santos Cordon6b7f9552015-05-27 17:21:45 -0700372 }
373 }
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -0800374
375 @Override
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700376 public void onConnectionEvent(String callId, String event, Bundle extras) {
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -0800377 if (mConnectionById.containsKey(callId)) {
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700378 findConnectionForAction(callId, "onConnectionEvent").onConnectionEvent(event,
379 extras);
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -0800380 }
381 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700382 };
383
Ihab Awad5d0410f2014-07-30 10:07:40 -0700384 private final ConnectionServiceAdapterServant mServant =
385 new ConnectionServiceAdapterServant(mServantDelegate);
Santos Cordon52d8a152014-06-17 19:08:45 -0700386
Ihab Awad5d0410f2014-07-30 10:07:40 -0700387 private final DeathRecipient mDeathRecipient = new DeathRecipient() {
388 @Override
389 public void binderDied() {
390 for (RemoteConnection c : mConnectionById.values()) {
391 c.setDestroyed();
392 }
Ihab Awadb8e85c72014-08-23 20:34:57 -0700393 for (RemoteConference c : mConferenceById.values()) {
394 c.setDestroyed();
395 }
Ihab Awad5d0410f2014-07-30 10:07:40 -0700396 mConnectionById.clear();
Ihab Awadb8e85c72014-08-23 20:34:57 -0700397 mConferenceById.clear();
Ihab Awad5d0410f2014-07-30 10:07:40 -0700398 mPendingConnections.clear();
Ihab Awadb8e85c72014-08-23 20:34:57 -0700399 mOutgoingConnectionServiceRpc.asBinder().unlinkToDeath(mDeathRecipient, 0);
Ihab Awad5d0410f2014-07-30 10:07:40 -0700400 }
401 };
402
Ihab Awadb8e85c72014-08-23 20:34:57 -0700403 private final IConnectionService mOutgoingConnectionServiceRpc;
404 private final ConnectionService mOurConnectionServiceImpl;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700405 private final Map<String, RemoteConnection> mConnectionById = new HashMap<>();
Ihab Awadb8e85c72014-08-23 20:34:57 -0700406 private final Map<String, RemoteConference> mConferenceById = new HashMap<>();
Ihab Awad5d0410f2014-07-30 10:07:40 -0700407 private final Set<RemoteConnection> mPendingConnections = new HashSet<>();
408
Ihab Awadb8e85c72014-08-23 20:34:57 -0700409 RemoteConnectionService(
410 IConnectionService outgoingConnectionServiceRpc,
411 ConnectionService ourConnectionServiceImpl) throws RemoteException {
412 mOutgoingConnectionServiceRpc = outgoingConnectionServiceRpc;
413 mOutgoingConnectionServiceRpc.asBinder().linkToDeath(mDeathRecipient, 0);
414 mOurConnectionServiceImpl = ourConnectionServiceImpl;
Santos Cordon52d8a152014-06-17 19:08:45 -0700415 }
416
417 @Override
418 public String toString() {
Ihab Awadb8e85c72014-08-23 20:34:57 -0700419 return "[RemoteCS - " + mOutgoingConnectionServiceRpc.asBinder().toString() + "]";
Santos Cordon52d8a152014-06-17 19:08:45 -0700420 }
421
Ihab Awadf8b69882014-07-25 15:14:01 -0700422 final RemoteConnection createRemoteConnection(
423 PhoneAccountHandle connectionManagerPhoneAccount,
424 ConnectionRequest request,
425 boolean isIncoming) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700426 final String id = UUID.randomUUID().toString();
Ihab Awad8aecfed2014-08-08 17:06:11 -0700427 final ConnectionRequest newRequest = new ConnectionRequest(
Ihab Awad5d0410f2014-07-30 10:07:40 -0700428 request.getAccountHandle(),
Nancy Chenea38cca2014-09-05 16:38:49 -0700429 request.getAddress(),
Ihab Awad5d0410f2014-07-30 10:07:40 -0700430 request.getExtras(),
431 request.getVideoState());
432 try {
Ihab Awad8aecfed2014-08-08 17:06:11 -0700433 if (mConnectionById.isEmpty()) {
Ihab Awadb8e85c72014-08-23 20:34:57 -0700434 mOutgoingConnectionServiceRpc.addConnectionServiceAdapter(mServant.getStub());
Ihab Awad8aecfed2014-08-08 17:06:11 -0700435 }
436 RemoteConnection connection =
Ihab Awadb8e85c72014-08-23 20:34:57 -0700437 new RemoteConnection(id, mOutgoingConnectionServiceRpc, newRequest);
Ihab Awad8aecfed2014-08-08 17:06:11 -0700438 mPendingConnections.add(connection);
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700439 mConnectionById.put(id, connection);
Ihab Awadb8e85c72014-08-23 20:34:57 -0700440 mOutgoingConnectionServiceRpc.createConnection(
Ihab Awad5d0410f2014-07-30 10:07:40 -0700441 connectionManagerPhoneAccount,
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700442 id,
Ihab Awad5d0410f2014-07-30 10:07:40 -0700443 newRequest,
Yorke Leec3cf9822014-10-02 09:38:39 -0700444 isIncoming,
445 false /* isUnknownCall */);
Andrew Lee100e2932014-09-08 15:34:24 -0700446 connection.registerCallback(new RemoteConnection.Callback() {
Ihab Awad8aecfed2014-08-08 17:06:11 -0700447 @Override
448 public void onDestroyed(RemoteConnection connection) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700449 mConnectionById.remove(id);
Ihab Awadb8e85c72014-08-23 20:34:57 -0700450 maybeDisconnectAdapter();
Ihab Awad8aecfed2014-08-08 17:06:11 -0700451 }
452 });
Ihab Awad5d0410f2014-07-30 10:07:40 -0700453 return connection;
454 } catch (RemoteException e) {
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700455 return RemoteConnection.failure(
456 new DisconnectCause(DisconnectCause.ERROR, e.toString()));
Santos Cordon52d8a152014-06-17 19:08:45 -0700457 }
458 }
459
Ihab Awad50e35062014-09-30 09:17:03 -0700460 private boolean hasConnection(String callId) {
mike dooley879142b2014-10-08 13:39:28 -0700461 return mConnectionById.containsKey(callId);
Ihab Awad50e35062014-09-30 09:17:03 -0700462 }
463
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700464 private RemoteConnection findConnectionForAction(
465 String callId, String action) {
Ihab Awad5d0410f2014-07-30 10:07:40 -0700466 if (mConnectionById.containsKey(callId)) {
467 return mConnectionById.get(callId);
468 }
469 Log.w(this, "%s - Cannot find Connection %s", action, callId);
470 return NULL_CONNECTION;
Santos Cordon52d8a152014-06-17 19:08:45 -0700471 }
Ihab Awadb8e85c72014-08-23 20:34:57 -0700472
473 private RemoteConference findConferenceForAction(
474 String callId, String action) {
475 if (mConferenceById.containsKey(callId)) {
476 return mConferenceById.get(callId);
477 }
478 Log.w(this, "%s - Cannot find Conference %s", action, callId);
479 return NULL_CONFERENCE;
480 }
481
482 private void maybeDisconnectAdapter() {
483 if (mConnectionById.isEmpty() && mConferenceById.isEmpty()) {
484 try {
485 mOutgoingConnectionServiceRpc.removeConnectionServiceAdapter(mServant.getStub());
486 } catch (RemoteException e) {
487 }
488 }
489 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700490}