blob: 4a4590265d59840b4d0bcdb86151f4881666da7b [file] [log] [blame]
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001/*
2 * Copyright 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
14 * limitations under the License.
15 */
16
17package com.android.telecomm;
18
Sailesh Nepal9d58de52014-07-18 14:53:19 -070019import android.app.PendingIntent;
Sailesh Nepalc92c4362014-07-04 18:33:21 -070020import android.content.ComponentName;
Sailesh Nepale8ecb982014-07-11 17:19:42 -070021import android.net.Uri;
Sailesh Nepalc92c4362014-07-04 18:33:21 -070022import android.os.Bundle;
23import android.os.Handler;
24import android.os.IBinder;
25import android.os.Message;
26import android.os.RemoteException;
27import android.telecomm.CallAudioState;
Sailesh Nepalc92c4362014-07-04 18:33:21 -070028import android.telecomm.ConnectionRequest;
Santos Cordonf2f14ef2014-07-20 18:00:20 -070029import android.telecomm.ConnectionService;
Sailesh Nepalc92c4362014-07-04 18:33:21 -070030import android.telecomm.GatewayInfo;
Santos Cordon72890ce2014-07-21 01:32:04 -070031import android.telecomm.ParcelableConnection;
Ihab Awadb78b2762014-07-25 15:16:23 -070032import android.telecomm.PhoneAccount;
33import android.telecomm.PhoneAccountHandle;
Sailesh Nepal35faf8c2014-07-08 22:02:34 -070034import android.telecomm.StatusHints;
Sailesh Nepalc92c4362014-07-04 18:33:21 -070035import android.telephony.DisconnectCause;
36
37import com.android.internal.os.SomeArgs;
Sailesh Nepalc92c4362014-07-04 18:33:21 -070038import com.android.internal.telecomm.IConnectionService;
39import com.android.internal.telecomm.IConnectionServiceAdapter;
Andrew Lee3bcf9352014-07-23 12:36:05 -070040import com.android.internal.telecomm.IVideoCallProvider;
Sailesh Nepalc92c4362014-07-04 18:33:21 -070041import com.android.internal.telecomm.RemoteServiceCallback;
Sailesh Nepalc92c4362014-07-04 18:33:21 -070042import com.google.common.base.Preconditions;
Sailesh Nepalc92c4362014-07-04 18:33:21 -070043
Ihab Awadb78b2762014-07-25 15:16:23 -070044import java.io.IOException;
Sailesh Nepalc92c4362014-07-04 18:33:21 -070045import java.util.ArrayList;
46import java.util.Collection;
Ihab Awadb78b2762014-07-25 15:16:23 -070047import java.util.Collections;
Sailesh Nepalc92c4362014-07-04 18:33:21 -070048import java.util.HashMap;
49import java.util.HashSet;
50import java.util.List;
51import java.util.Map;
52import java.util.Set;
53
54/**
55 * Wrapper for {@link IConnectionService}s, handles binding to {@link IConnectionService} and keeps
56 * track of when the object can safely be unbound. Other classes should not use
57 * {@link IConnectionService} directly and instead should use this class to invoke methods of
58 * {@link IConnectionService}.
59 */
60final class ConnectionServiceWrapper extends ServiceBinder<IConnectionService> {
Sailesh Nepal664837f2014-07-14 16:31:51 -070061 private static final int MSG_HANDLE_CREATE_CONNECTION_SUCCESSFUL = 1;
62 private static final int MSG_HANDLE_CREATE_CONNECTION_FAILED = 2;
63 private static final int MSG_HANDLE_CREATE_CONNECTION_CANCELLED = 3;
64 private static final int MSG_SET_ACTIVE = 4;
65 private static final int MSG_SET_RINGING = 5;
66 private static final int MSG_SET_DIALING = 6;
67 private static final int MSG_SET_DISCONNECTED = 7;
68 private static final int MSG_SET_ON_HOLD = 8;
69 private static final int MSG_SET_REQUESTING_RINGBACK = 9;
70 private static final int MSG_SET_CALL_CAPABILITIES = 10;
71 private static final int MSG_SET_IS_CONFERENCED = 11;
72 private static final int MSG_ADD_CONFERENCE_CALL = 12;
73 private static final int MSG_REMOVE_CALL = 13;
74 private static final int MSG_ON_POST_DIAL_WAIT = 14;
75 private static final int MSG_QUERY_REMOTE_CALL_SERVICES = 15;
76 private static final int MSG_SET_CALL_VIDEO_PROVIDER = 16;
77 private static final int MSG_SET_AUDIO_MODE_IS_VOIP = 17;
78 private static final int MSG_SET_STATUS_HINTS = 18;
79 private static final int MSG_SET_HANDLE = 19;
80 private static final int MSG_SET_CALLER_DISPLAY_NAME = 20;
Tyler Gunn0a388fc2014-07-17 12:21:17 -070081 private static final int MSG_SET_VIDEO_STATE = 21;
Santos Cordon12d61822014-07-29 16:02:20 -070082 private static final int MSG_SET_CONFERENCEABLE_CONNECTIONS = 22;
83 private static final int MSG_START_ACTIVITY_FROM_IN_CALL = 23;
Sailesh Nepalc92c4362014-07-04 18:33:21 -070084
85 private final Handler mHandler = new Handler() {
86 @Override
87 public void handleMessage(Message msg) {
88 Call call;
89 switch (msg.what) {
Sailesh Nepal664837f2014-07-14 16:31:51 -070090 case MSG_HANDLE_CREATE_CONNECTION_SUCCESSFUL: {
Santos Cordon72890ce2014-07-21 01:32:04 -070091 SomeArgs args = (SomeArgs) msg.obj;
92 try {
93 ConnectionRequest request = (ConnectionRequest) args.arg1;
94 if (mPendingResponses.containsKey(request.getCallId())) {
95 ParcelableConnection connection = (ParcelableConnection) args.arg2;
96 mPendingResponses.remove(request.getCallId()).
97 handleCreateConnectionSuccessful(request, connection);
98 }
99 } finally {
100 args.recycle();
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700101 }
102 break;
103 }
Sailesh Nepal664837f2014-07-14 16:31:51 -0700104 case MSG_HANDLE_CREATE_CONNECTION_FAILED: {
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700105 SomeArgs args = (SomeArgs) msg.obj;
106 try {
Sailesh Nepala49c6432014-07-07 22:47:11 -0700107 ConnectionRequest request = (ConnectionRequest) args.arg1;
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700108 int statusCode = args.argi1;
109 String statusMsg = (String) args.arg2;
Santos Cordonfd6ca442014-07-24 15:34:01 -0700110 removeCall(
111 mCallIdMapper.getCall(request.getCallId()),
112 statusCode,
113 statusMsg);
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700114 } finally {
115 args.recycle();
116 }
117 break;
118 }
Sailesh Nepal664837f2014-07-14 16:31:51 -0700119 case MSG_HANDLE_CREATE_CONNECTION_CANCELLED: {
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700120 ConnectionRequest request = (ConnectionRequest) msg.obj;
Sailesh Nepal664837f2014-07-14 16:31:51 -0700121 if (mPendingResponses.containsKey(request.getCallId())) {
122 mPendingResponses.remove(
123 request.getCallId()).handleCreateConnectionCancelled();
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700124 } else {
Sailesh Nepal664837f2014-07-14 16:31:51 -0700125 //Log.w(this, "handleCreateConnectionCancelled, unknown call: %s", callId);
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700126 }
127 break;
128 }
129 case MSG_SET_ACTIVE:
130 call = mCallIdMapper.getCall(msg.obj);
131 if (call != null) {
132 mCallsManager.markCallAsActive(call);
133 } else {
134 //Log.w(this, "setActive, unknown call id: %s", msg.obj);
135 }
136 break;
137 case MSG_SET_RINGING:
138 call = mCallIdMapper.getCall(msg.obj);
139 if (call != null) {
140 mCallsManager.markCallAsRinging(call);
141 } else {
142 //Log.w(this, "setRinging, unknown call id: %s", msg.obj);
143 }
144 break;
145 case MSG_SET_DIALING:
146 call = mCallIdMapper.getCall(msg.obj);
147 if (call != null) {
148 mCallsManager.markCallAsDialing(call);
149 } else {
150 //Log.w(this, "setDialing, unknown call id: %s", msg.obj);
151 }
152 break;
153 case MSG_SET_DISCONNECTED: {
154 SomeArgs args = (SomeArgs) msg.obj;
155 try {
156 call = mCallIdMapper.getCall(args.arg1);
157 String disconnectMessage = (String) args.arg2;
158 int disconnectCause = args.argi1;
159 if (call != null) {
160 mCallsManager.markCallAsDisconnected(call, disconnectCause,
161 disconnectMessage);
162 } else {
163 //Log.w(this, "setDisconnected, unknown call id: %s", args.arg1);
164 }
165 } finally {
166 args.recycle();
167 }
168 break;
169 }
170 case MSG_SET_ON_HOLD:
171 call = mCallIdMapper.getCall(msg.obj);
172 if (call != null) {
173 mCallsManager.markCallAsOnHold(call);
174 } else {
175 //Log.w(this, "setOnHold, unknown call id: %s", msg.obj);
176 }
177 break;
178 case MSG_SET_REQUESTING_RINGBACK: {
Sailesh Nepal9d58de52014-07-18 14:53:19 -0700179 call = mCallIdMapper.getCall(msg.obj);
180 if (call != null) {
181 call.setRequestingRingback(msg.arg1 == 1);
182 } else {
183 //Log.w(this, "setRingback, unknown call id: %s", args.arg1);
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700184 }
185 break;
186 }
Sailesh Nepale20bc972014-07-09 21:22:36 -0700187 case MSG_SET_CALL_CAPABILITIES: {
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700188 call = mCallIdMapper.getCall(msg.obj);
189 if (call != null) {
Sailesh Nepale20bc972014-07-09 21:22:36 -0700190 call.setCallCapabilities(msg.arg1);
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700191 } else {
192 //Log.w(ConnectionServiceWrapper.this,
Sailesh Nepale20bc972014-07-09 21:22:36 -0700193 // "setCallCapabilities, unknown call id: %s", msg.obj);
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700194 }
195 break;
196 }
197 case MSG_SET_IS_CONFERENCED: {
198 SomeArgs args = (SomeArgs) msg.obj;
199 try {
200 Call childCall = mCallIdMapper.getCall(args.arg1);
201 if (childCall != null) {
202 String conferenceCallId = (String) args.arg2;
203 if (conferenceCallId == null) {
204 childCall.setParentCall(null);
205 } else {
206 Call conferenceCall = mCallIdMapper.getCall(conferenceCallId);
207 if (conferenceCall != null &&
208 !mPendingConferenceCalls.contains(conferenceCall)) {
209 childCall.setParentCall(conferenceCall);
210 } else {
211 //Log.w(this, "setIsConferenced, unknown conference id %s",
212 // conferenceCallId);
213 }
214 }
215 } else {
216 //Log.w(this, "setIsConferenced, unknown call id: %s", args.arg1);
217 }
218 } finally {
219 args.recycle();
220 }
221 break;
222 }
223 case MSG_ADD_CONFERENCE_CALL: {
224 Call conferenceCall = mCallIdMapper.getCall(msg.obj);
225 if (mPendingConferenceCalls.remove(conferenceCall)) {
226 Log.v(this, "confirming conf call %s", conferenceCall);
227 conferenceCall.confirmConference();
228 } else {
229 //Log.w(this, "addConference, unknown call id: %s", callId);
230 }
231 break;
232 }
233 case MSG_REMOVE_CALL:
234 break;
235 case MSG_ON_POST_DIAL_WAIT: {
236 SomeArgs args = (SomeArgs) msg.obj;
237 try {
238 call = mCallIdMapper.getCall(args.arg1);
239 if (call != null) {
240 String remaining = (String) args.arg2;
241 call.onPostDialWait(remaining);
242 } else {
243 //Log.w(this, "onPostDialWait, unknown call id: %s", args.arg1);
244 }
245 } finally {
246 args.recycle();
247 }
248 break;
249 }
250 case MSG_QUERY_REMOTE_CALL_SERVICES: {
Sailesh Nepal664837f2014-07-14 16:31:51 -0700251 queryRemoteConnectionServices((RemoteServiceCallback) msg.obj);
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700252 break;
253 }
254 case MSG_SET_CALL_VIDEO_PROVIDER: {
255 SomeArgs args = (SomeArgs) msg.obj;
256 try {
257 call = mCallIdMapper.getCall(args.arg1);
Andrew Lee3bcf9352014-07-23 12:36:05 -0700258 IVideoCallProvider videoCallProvider = (IVideoCallProvider) args.arg2;
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700259 if (call != null) {
Andrew Lee3bcf9352014-07-23 12:36:05 -0700260 call.setVideoCallProvider(videoCallProvider);
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700261 }
262 } finally {
263 args.recycle();
264 }
265 break;
266 }
Sailesh Nepal7e669572014-07-08 21:29:12 -0700267 case MSG_SET_AUDIO_MODE_IS_VOIP: {
Sailesh Nepale20bc972014-07-09 21:22:36 -0700268 call = mCallIdMapper.getCall(msg.obj);
269 if (call != null) {
270 call.setAudioModeIsVoip(msg.arg1 == 1);
Sailesh Nepal7e669572014-07-08 21:29:12 -0700271 }
272 break;
273 }
Sailesh Nepal35faf8c2014-07-08 22:02:34 -0700274 case MSG_SET_STATUS_HINTS: {
275 SomeArgs args = (SomeArgs) msg.obj;
276 try {
277 call = mCallIdMapper.getCall(args.arg1);
278 StatusHints statusHints = (StatusHints) args.arg2;
279 if (call != null) {
280 call.setStatusHints(statusHints);
281 }
282 } finally {
283 args.recycle();
284 }
285 break;
286 }
Sailesh Nepale8ecb982014-07-11 17:19:42 -0700287 case MSG_SET_HANDLE: {
288 SomeArgs args = (SomeArgs) msg.obj;
289 try {
290 call = mCallIdMapper.getCall(args.arg1);
291 if (call != null) {
292 call.setHandle((Uri) args.arg2, args.argi1);
293 }
294 } finally {
295 args.recycle();
296 }
297 break;
298 }
299 case MSG_SET_CALLER_DISPLAY_NAME: {
300 SomeArgs args = (SomeArgs) msg.obj;
301 try {
302 call = mCallIdMapper.getCall(args.arg1);
303 if (call != null) {
304 call.setCallerDisplayName((String) args.arg2, args.argi1);
305 }
306 } finally {
307 args.recycle();
308 }
309 break;
310 }
Tyler Gunn0a388fc2014-07-17 12:21:17 -0700311 case MSG_SET_VIDEO_STATE: {
312 call = mCallIdMapper.getCall(msg.obj);
313 if (call != null) {
314 call.setVideoState(msg.arg1);
315 }
Tyler Gunn7e0df312014-07-21 14:34:58 -0700316 break;
Tyler Gunn0a388fc2014-07-17 12:21:17 -0700317 }
Santos Cordon12d61822014-07-29 16:02:20 -0700318 case MSG_SET_CONFERENCEABLE_CONNECTIONS: {
319 SomeArgs args = (SomeArgs) msg.obj;
320 try {
321 call = mCallIdMapper.getCall(args.arg1);
322 if (call != null ){
323 @SuppressWarnings("unchecked")
324 List<String> conferenceableIds = (List<String>) args.arg2;
325 List<Call> conferenceableCalls =
326 new ArrayList<>(conferenceableIds.size());
327 for (String otherId : (List<String>) args.arg2) {
328 Call otherCall = mCallIdMapper.getCall(otherId);
329 if (otherCall != null && otherCall != call) {
330 conferenceableCalls.add(otherCall);
331 }
332 }
333 call.setConferenceableCalls(conferenceableCalls);
334 }
335 } finally {
336 args.recycle();
337 }
338 break;
339 }
Sailesh Nepal9d58de52014-07-18 14:53:19 -0700340 case MSG_START_ACTIVITY_FROM_IN_CALL: {
341 SomeArgs args = (SomeArgs) msg.obj;
342 try {
343 call = mCallIdMapper.getCall(args.arg1);
344 if (call != null) {
345 call.startActivityFromInCall((PendingIntent) args.arg2);
346 }
347 } finally {
348 args.recycle();
349 }
350 break;
351 }
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700352 }
353 }
354 };
355
356 private final class Adapter extends IConnectionServiceAdapter.Stub {
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700357 @Override
Santos Cordon72890ce2014-07-21 01:32:04 -0700358 public void handleCreateConnectionSuccessful(
359 ConnectionRequest request, ParcelableConnection connection) {
360
Sailesh Nepal664837f2014-07-14 16:31:51 -0700361 logIncoming("handleCreateConnectionSuccessful %s", request);
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700362 mCallIdMapper.checkValidCallId(request.getCallId());
Santos Cordon72890ce2014-07-21 01:32:04 -0700363 SomeArgs args = SomeArgs.obtain();
364 args.arg1 = request;
365 args.arg2 = connection;
366 mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_SUCCESSFUL, args).sendToTarget();
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700367 }
368
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700369 @Override
Sailesh Nepal664837f2014-07-14 16:31:51 -0700370 public void handleCreateConnectionFailed(
371 ConnectionRequest request, int errorCode, String errorMsg) {
372 logIncoming("handleCreateConnectionFailed %s %d %s", request, errorCode, errorMsg);
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700373 mCallIdMapper.checkValidCallId(request.getCallId());
374 SomeArgs args = SomeArgs.obtain();
375 args.arg1 = request;
376 args.argi1 = errorCode;
377 args.arg2 = errorMsg;
Sailesh Nepal664837f2014-07-14 16:31:51 -0700378 mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_FAILED, args).sendToTarget();
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700379 }
380
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700381 @Override
Sailesh Nepal664837f2014-07-14 16:31:51 -0700382 public void handleCreateConnectionCancelled(ConnectionRequest request) {
383 logIncoming("handleCreateConnectionCancelled %s", request);
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700384 mCallIdMapper.checkValidCallId(request.getCallId());
Sailesh Nepal664837f2014-07-14 16:31:51 -0700385 mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_CANCELLED, request).sendToTarget();
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700386 }
387
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700388 @Override
389 public void setActive(String callId) {
390 logIncoming("setActive %s", callId);
391 mCallIdMapper.checkValidCallId(callId);
392 mHandler.obtainMessage(MSG_SET_ACTIVE, callId).sendToTarget();
393 }
394
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700395 @Override
396 public void setRinging(String callId) {
397 logIncoming("setRinging %s", callId);
398 mCallIdMapper.checkValidCallId(callId);
399 mHandler.obtainMessage(MSG_SET_RINGING, callId).sendToTarget();
400 }
401
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700402 @Override
Andrew Lee3bcf9352014-07-23 12:36:05 -0700403 public void setVideoCallProvider(String callId, IVideoCallProvider videoCallProvider) {
404 logIncoming("setVideoCallProvider %s", callId);
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700405 mCallIdMapper.checkValidCallId(callId);
406 SomeArgs args = SomeArgs.obtain();
407 args.arg1 = callId;
Andrew Lee3bcf9352014-07-23 12:36:05 -0700408 args.arg2 = videoCallProvider;
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700409 mHandler.obtainMessage(MSG_SET_CALL_VIDEO_PROVIDER, args).sendToTarget();
410 }
411
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700412 @Override
413 public void setDialing(String callId) {
414 logIncoming("setDialing %s", callId);
415 mCallIdMapper.checkValidCallId(callId);
416 mHandler.obtainMessage(MSG_SET_DIALING, callId).sendToTarget();
417 }
418
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700419 @Override
420 public void setDisconnected(
421 String callId, int disconnectCause, String disconnectMessage) {
422 logIncoming("setDisconnected %s %d %s", callId, disconnectCause, disconnectMessage);
423 mCallIdMapper.checkValidCallId(callId);
424 SomeArgs args = SomeArgs.obtain();
425 args.arg1 = callId;
426 args.arg2 = disconnectMessage;
427 args.argi1 = disconnectCause;
428 mHandler.obtainMessage(MSG_SET_DISCONNECTED, args).sendToTarget();
429 }
430
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700431 @Override
432 public void setOnHold(String callId) {
433 logIncoming("setOnHold %s", callId);
434 mCallIdMapper.checkValidCallId(callId);
435 mHandler.obtainMessage(MSG_SET_ON_HOLD, callId).sendToTarget();
436 }
437
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700438 @Override
439 public void setRequestingRingback(String callId, boolean ringback) {
440 logIncoming("setRequestingRingback %s %b", callId, ringback);
441 mCallIdMapper.checkValidCallId(callId);
Sailesh Nepal9d58de52014-07-18 14:53:19 -0700442 mHandler.obtainMessage(MSG_SET_REQUESTING_RINGBACK, ringback ? 1 : 0, 0, callId)
443 .sendToTarget();
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700444 }
445
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700446 @Override
447 public void removeCall(String callId) {
448 logIncoming("removeCall %s", callId);
449 }
450
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700451 @Override
Sailesh Nepale20bc972014-07-09 21:22:36 -0700452 public void setCallCapabilities(String callId, int callCapabilities) {
453 logIncoming("setCallCapabilities %s %d", callId, callCapabilities);
454 mHandler.obtainMessage(MSG_SET_CALL_CAPABILITIES, callCapabilities, 0, callId)
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700455 .sendToTarget();
456 }
457
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700458 @Override
459 public void setIsConferenced(String callId, String conferenceCallId) {
460 logIncoming("setIsConferenced %s %s", callId, conferenceCallId);
461 SomeArgs args = SomeArgs.obtain();
462 args.arg1 = callId;
463 args.arg2 = conferenceCallId;
464 mHandler.obtainMessage(MSG_SET_IS_CONFERENCED, args).sendToTarget();
465 }
466
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700467 @Override
468 public void addConferenceCall(String callId) {
469 logIncoming("addConferenceCall %s", callId);
470 mCallIdMapper.checkValidCallId(callId);
471 mHandler.obtainMessage(MSG_ADD_CONFERENCE_CALL, callId).sendToTarget();
472 }
473
474 @Override
475 public void onPostDialWait(String callId, String remaining) throws RemoteException {
476 logIncoming("onPostDialWait %s %s", callId, remaining);
477 mCallIdMapper.checkValidCallId(callId);
478 SomeArgs args = SomeArgs.obtain();
479 args.arg1 = callId;
480 args.arg2 = remaining;
481 mHandler.obtainMessage(MSG_ON_POST_DIAL_WAIT, args).sendToTarget();
482 }
483
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700484 @Override
485 public void queryRemoteConnectionServices(RemoteServiceCallback callback) {
486 logIncoming("queryRemoteCSs");
487 mHandler.obtainMessage(MSG_QUERY_REMOTE_CALL_SERVICES, callback).sendToTarget();
488 }
489
490 @Override
Tyler Gunn0a388fc2014-07-17 12:21:17 -0700491 public void setVideoState(String callId, int videoState) {
492 logIncoming("setVideoState %s %d", callId, videoState);
493 mCallIdMapper.checkValidCallId(callId);
494 mHandler.obtainMessage(MSG_SET_VIDEO_STATE, videoState, 0, callId).sendToTarget();
495 }
496
497 @Override
Sailesh Nepal7e669572014-07-08 21:29:12 -0700498 public void setAudioModeIsVoip(String callId, boolean isVoip) {
Sailesh Nepal7fa33ca2014-07-10 15:28:21 -0700499 logIncoming("setAudioModeIsVoip %s %b", callId, isVoip);
Sailesh Nepal7e669572014-07-08 21:29:12 -0700500 mCallIdMapper.checkValidCallId(callId);
Sailesh Nepale20bc972014-07-09 21:22:36 -0700501 mHandler.obtainMessage(MSG_SET_AUDIO_MODE_IS_VOIP, isVoip ? 1 : 0, 0,
502 callId).sendToTarget();
Sailesh Nepal7e669572014-07-08 21:29:12 -0700503 }
Sailesh Nepal35faf8c2014-07-08 22:02:34 -0700504
505 @Override
506 public void setStatusHints(String callId, StatusHints statusHints) {
507 logIncoming("setStatusHints %s %s", callId, statusHints);
508 mCallIdMapper.checkValidCallId(callId);
509 SomeArgs args = SomeArgs.obtain();
510 args.arg1 = callId;
511 args.arg2 = statusHints;
512 mHandler.obtainMessage(MSG_SET_STATUS_HINTS, args).sendToTarget();
513 }
Sailesh Nepale8ecb982014-07-11 17:19:42 -0700514
515 @Override
516 public void setHandle(String callId, Uri handle, int presentation) {
517 logIncoming("setHandle %s %s %d", callId, handle, presentation);
518 mCallIdMapper.checkValidCallId(callId);
519 SomeArgs args = SomeArgs.obtain();
520 args.arg1 = callId;
521 args.arg2 = handle;
522 args.argi1 = presentation;
523 mHandler.obtainMessage(MSG_SET_HANDLE, args).sendToTarget();
524 }
525
526 @Override
527 public void setCallerDisplayName(
528 String callId, String callerDisplayName, int presentation) {
529 logIncoming("setCallerDisplayName %s %s %d", callId, callerDisplayName, presentation);
530 mCallIdMapper.checkValidCallId(callId);
531 SomeArgs args = SomeArgs.obtain();
532 args.arg1 = callId;
533 args.arg2 = callerDisplayName;
534 args.argi1 = presentation;
535 mHandler.obtainMessage(MSG_SET_CALLER_DISPLAY_NAME, args).sendToTarget();
536 }
Sailesh Nepal9d58de52014-07-18 14:53:19 -0700537
538 @Override
Santos Cordon12d61822014-07-29 16:02:20 -0700539 public void setConferenceableConnections(
540 String callId, List<String> conferenceableCallIds) {
541 logIncoming("setConferenceableConnections %s %s", callId, conferenceableCallIds);
542 mCallIdMapper.checkValidCallId(callId);
543 SomeArgs args = SomeArgs.obtain();
544 args.arg1 = callId;
545 args.arg2 = conferenceableCallIds;
546 mHandler.obtainMessage(MSG_SET_CONFERENCEABLE_CONNECTIONS, args).sendToTarget();
547 }
548
549 @Override
Sailesh Nepal9d58de52014-07-18 14:53:19 -0700550 public void startActivityFromInCall(String callId, PendingIntent intent) {
551 logIncoming("startActivityFromInCall %s %s", callId, intent);
552 mCallIdMapper.checkValidCallId(callId);
553 SomeArgs args = SomeArgs.obtain();
554 args.arg1 = callId;
555 args.arg2 = intent;
556 mHandler.obtainMessage(MSG_START_ACTIVITY_FROM_IN_CALL, args).sendToTarget();
557 }
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700558 }
559
560 private final Adapter mAdapter = new Adapter();
561 private final CallsManager mCallsManager = CallsManager.getInstance();
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700562 private final Set<Call> mPendingConferenceCalls = new HashSet<>();
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700563 private final CallIdMapper mCallIdMapper = new CallIdMapper("ConnectionService");
Sailesh Nepal664837f2014-07-14 16:31:51 -0700564 private final Map<String, CreateConnectionResponse> mPendingResponses = new HashMap<>();
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700565
566 private Binder mBinder = new Binder();
567 private IConnectionService mServiceInterface;
Sailesh Nepal905dfba2014-07-14 08:20:41 -0700568 private final ConnectionServiceRepository mConnectionServiceRepository;
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700569
570 /**
Sailesh Nepal905dfba2014-07-14 08:20:41 -0700571 * Creates a connection service.
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700572 *
Sailesh Nepal905dfba2014-07-14 08:20:41 -0700573 * @param componentName The component name of the service with which to bind.
Sailesh Nepal905dfba2014-07-14 08:20:41 -0700574 * @param connectionServiceRepository Connection service repository.
Ihab Awadb78b2762014-07-25 15:16:23 -0700575 * @param phoneAccountRegistrar Phone account registrar
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700576 */
577 ConnectionServiceWrapper(
Ihab Awadb78b2762014-07-25 15:16:23 -0700578 ComponentName componentName,
579 ConnectionServiceRepository connectionServiceRepository,
580 PhoneAccountRegistrar phoneAccountRegistrar) {
Santos Cordonf2f14ef2014-07-20 18:00:20 -0700581 super(ConnectionService.SERVICE_INTERFACE, componentName);
Sailesh Nepal905dfba2014-07-14 08:20:41 -0700582 mConnectionServiceRepository = connectionServiceRepository;
Ihab Awadb78b2762014-07-25 15:16:23 -0700583 phoneAccountRegistrar.addListener(new PhoneAccountRegistrar.Listener() {
584 // TODO -- Upon changes to PhoneAccountRegistrar, need to re-wire connections
585 // To do this, we must proxy remote ConnectionService objects
586 });
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700587 }
588
589 /** See {@link IConnectionService#addConnectionServiceAdapter}. */
590 private void addConnectionServiceAdapter(IConnectionServiceAdapter adapter) {
591 if (isServiceValid("addConnectionServiceAdapter")) {
592 try {
Sailesh Nepal3fe8b722014-07-08 10:07:26 -0700593 logOutgoing("addConnectionServiceAdapter %s", adapter);
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700594 mServiceInterface.addConnectionServiceAdapter(adapter);
595 } catch (RemoteException e) {
596 }
597 }
598 }
599
600 /**
Sailesh Nepal664837f2014-07-14 16:31:51 -0700601 * Creates a new connection for a new outgoing call or to attach to an existing incoming call.
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700602 */
Sailesh Nepal664837f2014-07-14 16:31:51 -0700603 void createConnection(final Call call, final CreateConnectionResponse response) {
604 Log.d(this, "createConnection(%s) via %s.", call, getComponentName());
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700605 BindCallback callback = new BindCallback() {
606 @Override
607 public void onSuccess() {
608 String callId = mCallIdMapper.getCallId(call);
Sailesh Nepal664837f2014-07-14 16:31:51 -0700609 mPendingResponses.put(callId, response);
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700610
611 GatewayInfo gatewayInfo = call.getGatewayInfo();
612 Bundle extras = call.getExtras();
613 if (gatewayInfo != null && gatewayInfo.getGatewayProviderPackageName() != null &&
614 gatewayInfo.getOriginalHandle() != null) {
615 extras = (Bundle) extras.clone();
616 extras.putString(
617 NewOutgoingCallIntentBroadcaster.EXTRA_GATEWAY_PROVIDER_PACKAGE,
618 gatewayInfo.getGatewayProviderPackageName());
619 extras.putParcelable(
620 NewOutgoingCallIntentBroadcaster.EXTRA_GATEWAY_ORIGINAL_URI,
621 gatewayInfo.getOriginalHandle());
622 }
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700623
624 try {
Ihab Awadb78b2762014-07-25 15:16:23 -0700625 mServiceInterface.createConnection(
626 call.getConnectionManagerPhoneAccount(),
627 new ConnectionRequest(
628 call.getTargetPhoneAccount(),
629 callId,
630 call.getHandle(),
631 call.getHandlePresentation(),
632 extras,
633 call.getVideoState()),
634 call.isIncoming());
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700635 } catch (RemoteException e) {
Sailesh Nepal664837f2014-07-14 16:31:51 -0700636 Log.e(this, e, "Failure to createConnection -- %s", getComponentName());
637 mPendingResponses.remove(callId).handleCreateConnectionFailed(
Santos Cordonfd6ca442014-07-24 15:34:01 -0700638 DisconnectCause.OUTGOING_FAILURE, e.toString());
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700639 }
640 }
641
642 @Override
643 public void onFailure() {
Sailesh Nepal905dfba2014-07-14 08:20:41 -0700644 Log.e(this, new Exception(), "Failure to call %s", getComponentName());
Santos Cordonfd6ca442014-07-24 15:34:01 -0700645 response.handleCreateConnectionFailed(DisconnectCause.OUTGOING_FAILURE, null);
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700646 }
647 };
648
649 mBinder.bind(callback);
650 }
651
652 /** @see ConnectionService#abort(String) */
653 void abort(Call call) {
654 // Clear out any pending outgoing call data
655 String callId = mCallIdMapper.getCallId(call);
656
657 // If still bound, tell the connection service to abort.
658 if (isServiceValid("abort")) {
659 try {
660 logOutgoing("abort %s", callId);
661 mServiceInterface.abort(callId);
662 } catch (RemoteException e) {
663 }
664 }
665
Santos Cordonfd6ca442014-07-24 15:34:01 -0700666 removeCall(call, DisconnectCause.LOCAL, null);
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700667 }
668
669 /** @see ConnectionService#hold(String) */
670 void hold(Call call) {
671 if (isServiceValid("hold")) {
672 try {
673 logOutgoing("hold %s", mCallIdMapper.getCallId(call));
674 mServiceInterface.hold(mCallIdMapper.getCallId(call));
675 } catch (RemoteException e) {
676 }
677 }
678 }
679
680 /** @see ConnectionService#unhold(String) */
681 void unhold(Call call) {
682 if (isServiceValid("unhold")) {
683 try {
684 logOutgoing("unhold %s", mCallIdMapper.getCallId(call));
685 mServiceInterface.unhold(mCallIdMapper.getCallId(call));
686 } catch (RemoteException e) {
687 }
688 }
689 }
690
691 /** @see ConnectionService#onAudioStateChanged(String,CallAudioState) */
692 void onAudioStateChanged(Call activeCall, CallAudioState audioState) {
693 if (isServiceValid("onAudioStateChanged")) {
694 try {
695 logOutgoing("onAudioStateChanged %s %s",
696 mCallIdMapper.getCallId(activeCall), audioState);
697 mServiceInterface.onAudioStateChanged(mCallIdMapper.getCallId(activeCall),
698 audioState);
699 } catch (RemoteException e) {
700 }
701 }
702 }
703
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700704 /** @see ConnectionService#disconnect(String) */
705 void disconnect(Call call) {
706 if (isServiceValid("disconnect")) {
707 try {
708 logOutgoing("disconnect %s", mCallIdMapper.getCallId(call));
709 mServiceInterface.disconnect(mCallIdMapper.getCallId(call));
710 } catch (RemoteException e) {
711 }
712 }
713 }
714
Ihab Awadb78b2762014-07-25 15:16:23 -0700715 /** @see ConnectionService#answer(String,int) */
Andrew Lee38931d02014-07-16 10:17:36 -0700716 void answer(Call call, int videoState) {
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700717 if (isServiceValid("answer")) {
718 try {
Andrew Lee38931d02014-07-16 10:17:36 -0700719 logOutgoing("answer %s %d", mCallIdMapper.getCallId(call), videoState);
720 mServiceInterface.answer(mCallIdMapper.getCallId(call), videoState);
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700721 } catch (RemoteException e) {
722 }
723 }
724 }
725
726 /** @see ConnectionService#reject(String) */
727 void reject(Call call) {
728 if (isServiceValid("reject")) {
729 try {
730 logOutgoing("reject %s", mCallIdMapper.getCallId(call));
731 mServiceInterface.reject(mCallIdMapper.getCallId(call));
732 } catch (RemoteException e) {
733 }
734 }
735 }
736
737 /** @see ConnectionService#playDtmfTone(String,char) */
738 void playDtmfTone(Call call, char digit) {
739 if (isServiceValid("playDtmfTone")) {
740 try {
741 logOutgoing("playDtmfTone %s %c", mCallIdMapper.getCallId(call), digit);
742 mServiceInterface.playDtmfTone(mCallIdMapper.getCallId(call), digit);
743 } catch (RemoteException e) {
744 }
745 }
746 }
747
748 /** @see ConnectionService#stopDtmfTone(String) */
749 void stopDtmfTone(Call call) {
750 if (isServiceValid("stopDtmfTone")) {
751 try {
752 logOutgoing("stopDtmfTone %s", mCallIdMapper.getCallId(call));
753 mServiceInterface.stopDtmfTone(mCallIdMapper.getCallId(call));
754 } catch (RemoteException e) {
755 }
756 }
757 }
758
759 void addCall(Call call) {
760 if (mCallIdMapper.getCallId(call) == null) {
761 mCallIdMapper.addCall(call);
762 }
763 }
764
765 /**
766 * Associates newCall with this connection service by replacing callToReplace.
767 */
768 void replaceCall(Call newCall, Call callToReplace) {
769 Preconditions.checkState(callToReplace.getConnectionService() == this);
770 mCallIdMapper.replaceCall(newCall, callToReplace);
771 }
772
773 void removeCall(Call call) {
Santos Cordonfd6ca442014-07-24 15:34:01 -0700774 removeCall(call, DisconnectCause.ERROR_UNSPECIFIED, null);
775 }
776
777 void removeCall(Call call, int disconnectCause, String disconnectMessage) {
Sailesh Nepal664837f2014-07-14 16:31:51 -0700778 CreateConnectionResponse response = mPendingResponses.remove(mCallIdMapper.getCallId(call));
779 if (response != null) {
Santos Cordonfd6ca442014-07-24 15:34:01 -0700780 response.handleCreateConnectionFailed(disconnectCause, disconnectMessage);
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700781 }
782
783 mCallIdMapper.removeCall(call);
784 }
785
786 void onPostDialContinue(Call call, boolean proceed) {
787 if (isServiceValid("onPostDialContinue")) {
788 try {
789 logOutgoing("onPostDialContinue %s %b", mCallIdMapper.getCallId(call), proceed);
790 mServiceInterface.onPostDialContinue(mCallIdMapper.getCallId(call), proceed);
791 } catch (RemoteException ignored) {
792 }
793 }
794 }
795
796 void onPhoneAccountClicked(Call call) {
797 if (isServiceValid("onPhoneAccountClicked")) {
798 try {
799 logOutgoing("onPhoneAccountClicked %s", mCallIdMapper.getCallId(call));
800 mServiceInterface.onPhoneAccountClicked(mCallIdMapper.getCallId(call));
801 } catch (RemoteException ignored) {
802 }
803 }
804 }
805
806 void conference(final Call conferenceCall, Call call) {
807 if (isServiceValid("conference")) {
808 try {
809 conferenceCall.setConnectionService(this);
810 mPendingConferenceCalls.add(conferenceCall);
811 mHandler.postDelayed(new Runnable() {
812 @Override public void run() {
813 if (mPendingConferenceCalls.remove(conferenceCall)) {
814 conferenceCall.expireConference();
815 Log.i(this, "Conference call expired: %s", conferenceCall);
816 }
817 }
818 }, Timeouts.getConferenceCallExpireMillis());
819
820 logOutgoing("conference %s %s",
821 mCallIdMapper.getCallId(conferenceCall),
822 mCallIdMapper.getCallId(call));
823 mServiceInterface.conference(
824 mCallIdMapper.getCallId(conferenceCall),
825 mCallIdMapper.getCallId(call));
826 } catch (RemoteException ignored) {
827 }
828 }
829 }
830
831 void splitFromConference(Call call) {
832 if (isServiceValid("splitFromConference")) {
833 try {
834 logOutgoing("splitFromConference %s", mCallIdMapper.getCallId(call));
835 mServiceInterface.splitFromConference(mCallIdMapper.getCallId(call));
836 } catch (RemoteException ignored) {
837 }
838 }
839 }
840
Sailesh Nepale8ecb982014-07-11 17:19:42 -0700841 void swapWithBackgroundCall(Call call) {
842 if (isServiceValid("swapWithBackgroundCall")) {
843 try {
844 logOutgoing("swapWithBackgroundCall %s", mCallIdMapper.getCallId(call));
845 mServiceInterface.swapWithBackgroundCall(mCallIdMapper.getCallId(call));
846 } catch (RemoteException ignored) {
847 }
848 }
849 }
850
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700851 /** {@inheritDoc} */
852 @Override
853 protected void setServiceInterface(IBinder binder) {
854 if (binder == null) {
855 // We have lost our service connection. Notify the world that this service is done.
856 // We must notify the adapter before CallsManager. The adapter will force any pending
857 // outgoing calls to try the next service. This needs to happen before CallsManager
858 // tries to clean up any calls still associated with this service.
859 handleConnectionServiceDeath();
860 CallsManager.getInstance().handleConnectionServiceDeath(this);
861 mServiceInterface = null;
862 } else {
863 mServiceInterface = IConnectionService.Stub.asInterface(binder);
864 addConnectionServiceAdapter(mAdapter);
865 }
866 }
867
868 /**
869 * Called when the associated connection service dies.
870 */
871 private void handleConnectionServiceDeath() {
Sailesh Nepal664837f2014-07-14 16:31:51 -0700872 if (!mPendingResponses.isEmpty()) {
873 CreateConnectionResponse[] responses = mPendingResponses.values().toArray(
874 new CreateConnectionResponse[mPendingResponses.values().size()]);
875 mPendingResponses.clear();
876 for (int i = 0; i < responses.length; i++) {
877 responses[i].handleCreateConnectionFailed(DisconnectCause.ERROR_UNSPECIFIED, null);
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700878 }
879 }
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700880 mCallIdMapper.clear();
881 }
882
883 private void logIncoming(String msg, Object... params) {
884 Log.d(this, "ConnectionService -> Telecomm: " + msg, params);
885 }
886
887 private void logOutgoing(String msg, Object... params) {
888 Log.d(this, "Telecomm -> ConnectionService: " + msg, params);
889 }
890
891 private void queryRemoteConnectionServices(final RemoteServiceCallback callback) {
Ihab Awadb78b2762014-07-25 15:16:23 -0700892 PhoneAccountRegistrar registrar = TelecommApp.getInstance().getPhoneAccountRegistrar();
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700893
Ihab Awadb78b2762014-07-25 15:16:23 -0700894 // Only give remote connection services to this connection service if it is listed as
895 // the connection manager.
896 PhoneAccountHandle simCallManager = registrar.getSimCallManager();
Ihab Awadc17294c2014-08-04 19:23:37 -0700897 Log.d(this, "queryRemoteConnectionServices finds simCallManager = %s", simCallManager);
Ihab Awadb78b2762014-07-25 15:16:23 -0700898 if (simCallManager == null ||
899 !simCallManager.getComponentName().equals(getComponentName())) {
900 noRemoteServices(callback);
901 return;
902 }
Sailesh Nepal664837f2014-07-14 16:31:51 -0700903
Ihab Awadb78b2762014-07-25 15:16:23 -0700904 // Make a list of ConnectionServices that are listed as being associated with SIM accounts
905 final Set<ConnectionServiceWrapper> simServices = new HashSet<>();
906 for (PhoneAccountHandle handle : registrar.getEnabledPhoneAccounts()) {
907 PhoneAccount account = registrar.getPhoneAccount(handle);
908 if ((account.getCapabilities() & PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) != 0) {
909 ConnectionServiceWrapper service =
910 mConnectionServiceRepository.getService(handle.getComponentName());
911 if (service != null) {
912 simServices.add(service);
913 }
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700914 }
Sailesh Nepal905dfba2014-07-14 08:20:41 -0700915 }
Ihab Awadb78b2762014-07-25 15:16:23 -0700916
917 final List<ComponentName> simServiceComponentNames = new ArrayList<>();
918 final List<IBinder> simServiceBinders = new ArrayList<>();
919
920 Log.v(this, "queryRemoteConnectionServices, simServices = %s", simServices);
921
922 for (ConnectionServiceWrapper simService : simServices) {
923 if (simService == this) {
924 // Only happens in the unlikely case that a SIM service is also a SIM call manager
925 continue;
926 }
927
928 final ConnectionServiceWrapper currentSimService = simService;
929
930 currentSimService.mBinder.bind(new BindCallback() {
931 @Override
932 public void onSuccess() {
933 Log.d(this, "Adding simService %s", currentSimService.getComponentName());
934 simServiceComponentNames.add(currentSimService.getComponentName());
935 simServiceBinders.add(currentSimService.mServiceInterface.asBinder());
936 maybeComplete();
937 }
938
939 @Override
940 public void onFailure() {
941 Log.d(this, "Failed simService %s", currentSimService.getComponentName());
942 // We know maybeComplete() will always be a no-op from now on, so go ahead and
943 // signal failure of the entire request
944 noRemoteServices(callback);
945 }
946
947 private void maybeComplete() {
948 if (simServiceComponentNames.size() == simServices.size()) {
949 setRemoteServices(callback, simServiceComponentNames, simServiceBinders);
950 }
951 }
952 });
953 }
954 }
955
956 private void setRemoteServices(
957 RemoteServiceCallback callback,
958 List<ComponentName> componentNames,
959 List<IBinder> binders) {
960 try {
961 callback.onResult(componentNames, binders);
962 } catch (RemoteException e) {
963 Log.e(this, e, "Contacting ConnectionService %s",
964 ConnectionServiceWrapper.this.getComponentName());
965 }
966 }
967
968 private void noRemoteServices(RemoteServiceCallback callback) {
969 try {
970 callback.onResult(Collections.EMPTY_LIST, Collections.EMPTY_LIST);
971 } catch (RemoteException e) {
972 Log.e(this, e, "Contacting ConnectionService %s", this.getComponentName());
973 }
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700974 }
975}