ConnectionServiceWrapper.java revision 50a57136b3aa876c8311b58e1e11720a337fe1cc
163aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon/*
263aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon * Copyright 2014, The Android Open Source Project
363aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon *
463aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon * Licensed under the Apache License, Version 2.0 (the "License");
563aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon * you may not use this file except in compliance with the License.
663aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon * You may obtain a copy of the License at
763aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon *
863aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon *     http://www.apache.org/licenses/LICENSE-2.0
963aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon *
1063aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon * Unless required by applicable law or agreed to in writing, software
1163aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon * distributed under the License is distributed on an "AS IS" BASIS,
1263aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1363aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon * See the License for the specific language governing permissions and
1463aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon * limitations under the License.
1563aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon */
1663aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon
1763aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordonpackage com.android.telecomm;
1863aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon
19a05805b839edea9b9fe3bd4a0fbaf310c2a32838Evan Charltonimport android.os.Bundle;
203d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon
213d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordonimport android.os.Handler;
2263aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordonimport android.os.IBinder;
233d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordonimport android.os.Message;
2463aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordonimport android.os.RemoteException;
256aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepalimport android.telecomm.CallAudioState;
2663aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordonimport android.telecomm.CallInfo;
27a05805b839edea9b9fe3bd4a0fbaf310c2a32838Evan Charltonimport android.telecomm.CallService;
28c5b2269fe4d926f040f10da5f0faf0a4f1ab5cfdBen Giladimport android.telecomm.CallServiceDescriptor;
2983cfe7cb54c12db39e88db176e12992c1641946cSailesh Nepalimport android.telecomm.TelecommConstants;
30a439e1b6d6201dedecfc40b67c9347a8c563b9c1Sailesh Nepal
313d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordonimport com.android.internal.os.SomeArgs;
32a439e1b6d6201dedecfc40b67c9347a8c563b9c1Sailesh Nepalimport com.android.internal.telecomm.ICallService;
33a439e1b6d6201dedecfc40b67c9347a8c563b9c1Sailesh Nepalimport com.android.internal.telecomm.ICallServiceAdapter;
34a439e1b6d6201dedecfc40b67c9347a8c563b9c1Sailesh Nepalimport com.android.internal.telecomm.ICallServiceProvider;
350e5410a58043ce059884fdc8811a280655e5a920Sailesh Nepalimport com.google.common.base.Preconditions;
363d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordonimport com.google.common.collect.ImmutableList;
373d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordonimport com.google.common.collect.Sets;
383d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon
39682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordonimport java.util.HashMap;
40682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordonimport java.util.Map;
413d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordonimport java.util.Set;
4263aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon
4363aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon/**
4463aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon * Wrapper for {@link ICallService}s, handles binding to {@link ICallService} and keeps track of
4563aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon * when the object can safely be unbound. Other classes should not use {@link ICallService} directly
4663aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon * and instead should use this class to invoke methods of {@link ICallService}.
4763aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon */
486192561b1f56d7c4e6c650e178e07ba61ad02667Ben Giladfinal class CallServiceWrapper extends ServiceBinder<ICallService> {
4963aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon
503d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon    private final class Adapter extends ICallServiceAdapter.Stub {
513d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        private static final int MSG_NOTIFY_INCOMING_CALL = 1;
523d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        private static final int MSG_HANDLE_SUCCESSFUL_OUTGOING_CALL = 2;
533d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        private static final int MSG_HANDLE_FAILED_OUTGOING_CALL = 3;
543d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        private static final int MSG_SET_ACTIVE = 4;
553d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        private static final int MSG_SET_RINGING = 5;
563d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        private static final int MSG_SET_DIALING = 6;
573d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        private static final int MSG_SET_DISCONNECTED = 7;
583d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        private static final int MSG_SET_ON_HOLD = 8;
5950a57136b3aa876c8311b58e1e11720a337fe1ccIhab Awad        private static final int MSG_SET_REQUESTING_RINGBACK = 9;
60c195e3613af47a49e76821d3f24c05adb71cf920Santos Cordon
613d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        private final Handler mHandler = new Handler() {
623d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            @Override
633d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            public void handleMessage(Message msg) {
643d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                Call call;
653d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                switch (msg.what) {
663d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                    case MSG_NOTIFY_INCOMING_CALL:
673d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        CallInfo clientCallInfo = (CallInfo) msg.obj;
683d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        call = mCallIdMapper.getCall(clientCallInfo.getId());
69682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                        if (call != null && mPendingIncomingCalls.remove(call) &&
70682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                                call.isIncoming()) {
713d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                            CallInfo callInfo = new CallInfo(null, clientCallInfo.getState(),
723d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                                    clientCallInfo.getHandle());
733d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                            mIncomingCallsManager.handleSuccessfulIncomingCall(call, callInfo);
743d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        } else {
753d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                            Log.w(this, "notifyIncomingCall, unknown incoming call: %s, id: %s",
763d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                                    call,
773d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                                    clientCallInfo.getId());
783d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        }
793d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        break;
80682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                    case MSG_HANDLE_SUCCESSFUL_OUTGOING_CALL: {
81682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                        String callId = (String) msg.obj;
82682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                        if (mPendingOutgoingCalls.containsKey(callId)) {
83682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                            mPendingOutgoingCalls.remove(callId).onResult(true);
843d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        } else {
85682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                            Log.w(this, "handleSuccessfulOutgoingCall, unknown call: %s", callId);
863d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        }
873d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        break;
88682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                    }
893d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                    case MSG_HANDLE_FAILED_OUTGOING_CALL: {
903d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        SomeArgs args = (SomeArgs) msg.obj;
913d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        try {
92682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                            String callId = (String) args.arg1;
933d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                            String reason = (String) args.arg2;
94682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                            // TODO(santoscordon): Do something with 'reason' or get rid of it.
95682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon
96682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                            if (mPendingOutgoingCalls.containsKey(callId)) {
97682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                                mPendingOutgoingCalls.remove(callId).onResult(false);
98682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                                mCallIdMapper.removeCall(callId);
993d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                            } else {
100682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                                Log.w(this, "handleFailedOutgoingCall, unknown call: %s", callId);
1013d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                            }
1023d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        } finally {
1033d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                            args.recycle();
1043d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        }
1053d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        break;
1063d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                    }
1073d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                    case MSG_SET_ACTIVE:
1083d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        call = mCallIdMapper.getCall(msg.obj);
1093d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        if (call != null) {
1103d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                            mCallsManager.markCallAsActive(call);
1113d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        } else {
1123d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                            Log.w(this, "setActive, unknown call id: %s", msg.obj);
1133d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        }
1143d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        break;
1153d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                    case MSG_SET_RINGING:
1163d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        call = mCallIdMapper.getCall(msg.obj);
1173d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        if (call != null) {
1183d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                            mCallsManager.markCallAsRinging(call);
1193d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        } else {
1203d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                            Log.w(this, "setRinging, unknown call id: %s", msg.obj);
1213d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        }
1223d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        break;
1233d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                    case MSG_SET_DIALING:
1243d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        call = mCallIdMapper.getCall(msg.obj);
1253d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        if (call != null) {
1263d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                            mCallsManager.markCallAsDialing(call);
1273d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        } else {
1283d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                            Log.w(this, "setDialing, unknown call id: %s", msg.obj);
1293d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        }
1303d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        break;
1313d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                    case MSG_SET_DISCONNECTED: {
1323d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        SomeArgs args = (SomeArgs) msg.obj;
1333d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        try {
1343d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                            call = mCallIdMapper.getCall(args.arg1);
1353d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                            String disconnectMessage = (String) args.arg2;
1363d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                            int disconnectCause = args.argi1;
1373d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                            if (call != null) {
1383d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                                mCallsManager.markCallAsDisconnected(call, disconnectCause,
1393d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                                        disconnectMessage);
1403d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                            } else {
1413d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                                Log.w(this, "setDisconnected, unknown call id: %s", args.arg1);
1423d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                            }
1433d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        } finally {
1443d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                            args.recycle();
1453d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        }
1463d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        break;
1473d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                    }
1483d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                    case MSG_SET_ON_HOLD:
1493d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        call = mCallIdMapper.getCall(msg.obj);
1503d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        if (call != null) {
1513d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                            mCallsManager.markCallAsOnHold(call);
1523d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        } else {
1533d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                            Log.w(this, "setOnHold, unknown call id: %s", msg.obj);
1543d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        }
1553d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                        break;
15650a57136b3aa876c8311b58e1e11720a337fe1ccIhab Awad                    case MSG_SET_REQUESTING_RINGBACK:
15750a57136b3aa876c8311b58e1e11720a337fe1ccIhab Awad                        SomeArgs args = (SomeArgs) msg.obj;
15850a57136b3aa876c8311b58e1e11720a337fe1ccIhab Awad                        try {
15950a57136b3aa876c8311b58e1e11720a337fe1ccIhab Awad                            call = mCallIdMapper.getCall(args.arg1);
16050a57136b3aa876c8311b58e1e11720a337fe1ccIhab Awad                            boolean ringback = (boolean) args.arg2;
16150a57136b3aa876c8311b58e1e11720a337fe1ccIhab Awad                            if (call != null) {
16250a57136b3aa876c8311b58e1e11720a337fe1ccIhab Awad                                call.setRequestingRingback(ringback);
16350a57136b3aa876c8311b58e1e11720a337fe1ccIhab Awad                            } else {
16450a57136b3aa876c8311b58e1e11720a337fe1ccIhab Awad                                Log.w(this, "setRingback, unknown call id: %s", args.arg1);
16550a57136b3aa876c8311b58e1e11720a337fe1ccIhab Awad                            }
16650a57136b3aa876c8311b58e1e11720a337fe1ccIhab Awad                        } finally {
16750a57136b3aa876c8311b58e1e11720a337fe1ccIhab Awad                            args.recycle();
16850a57136b3aa876c8311b58e1e11720a337fe1ccIhab Awad                        }
16950a57136b3aa876c8311b58e1e11720a337fe1ccIhab Awad                        break;
1703d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                }
1713d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            }
1723d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        };
173c195e3613af47a49e76821d3f24c05adb71cf920Santos Cordon
1743d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        /** {@inheritDoc} */
1753d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        @Override
1763d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        public void setIsCompatibleWith(String callId, boolean isCompatible) {
177682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon            Log.wtf(this, "Not expected.");
1783d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        }
1793d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon
1803d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        /** {@inheritDoc} */
1813d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        @Override
1823d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        public void notifyIncomingCall(CallInfo callInfo) {
1833d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            mCallIdMapper.checkValidCallId(callInfo.getId());
1843d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            mHandler.obtainMessage(MSG_NOTIFY_INCOMING_CALL, callInfo).sendToTarget();
1853d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        }
1863d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon
1873d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        /** {@inheritDoc} */
1883d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        @Override
1893d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        public void handleSuccessfulOutgoingCall(String callId) {
190682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon            Log.d(this, "handleSuccessfulOutgoingCall %s", callId);
1913d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            mCallIdMapper.checkValidCallId(callId);
1923d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            mHandler.obtainMessage(MSG_HANDLE_SUCCESSFUL_OUTGOING_CALL, callId).sendToTarget();
1933d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        }
1943d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon
1953d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        /** {@inheritDoc} */
1963d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        @Override
1973d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        public void handleFailedOutgoingCall(String callId, String reason) {
1983d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            mCallIdMapper.checkValidCallId(callId);
1994f1b7b8ca45e5cbcb76014c80842130d001bed83Santos Cordon            Log.d(this, "handleFailedOutgoingCall %s", callId);
2003d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            SomeArgs args = SomeArgs.obtain();
2013d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            args.arg1 = callId;
2023d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            args.arg2 = reason;
2033d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            mHandler.obtainMessage(MSG_HANDLE_FAILED_OUTGOING_CALL, args).sendToTarget();
2043d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        }
2053d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon
2063d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        /** {@inheritDoc} */
2073d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        @Override
2083d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        public void setActive(String callId) {
2093d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            mCallIdMapper.checkValidCallId(callId);
2103d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            mHandler.obtainMessage(MSG_SET_ACTIVE, callId).sendToTarget();
2113d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        }
2123d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon
2133d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        /** {@inheritDoc} */
2143d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        @Override
2153d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        public void setRinging(String callId) {
2163d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            mCallIdMapper.checkValidCallId(callId);
2173d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            mHandler.obtainMessage(MSG_SET_RINGING, callId).sendToTarget();
2183d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        }
2193d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon
2203d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        /** {@inheritDoc} */
2213d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        @Override
2223d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        public void setDialing(String callId) {
2233d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            mCallIdMapper.checkValidCallId(callId);
2243d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            mHandler.obtainMessage(MSG_SET_DIALING, callId).sendToTarget();
2253d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        }
2263d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon
2273d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        /** {@inheritDoc} */
2283d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        @Override
2293d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        public void setDisconnected(
2303d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                String callId, int disconnectCause, String disconnectMessage) {
2313d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            mCallIdMapper.checkValidCallId(callId);
2323d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            SomeArgs args = SomeArgs.obtain();
2333d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            args.arg1 = callId;
2343d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            args.arg2 = disconnectMessage;
2353d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            args.argi1 = disconnectCause;
2363d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            mHandler.obtainMessage(MSG_SET_DISCONNECTED, args).sendToTarget();
2373d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        }
2383d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon
2393d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        /** {@inheritDoc} */
2403d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        @Override
2413d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        public void setOnHold(String callId) {
2423d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            mCallIdMapper.checkValidCallId(callId);
2433d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            mHandler.obtainMessage(MSG_SET_ON_HOLD, callId).sendToTarget();
2443d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        }
24550a57136b3aa876c8311b58e1e11720a337fe1ccIhab Awad
24650a57136b3aa876c8311b58e1e11720a337fe1ccIhab Awad        /** {@inheritDoc} */
24750a57136b3aa876c8311b58e1e11720a337fe1ccIhab Awad        @Override
24850a57136b3aa876c8311b58e1e11720a337fe1ccIhab Awad        public void setRequestingRingback(String callId, boolean ringback) {
24950a57136b3aa876c8311b58e1e11720a337fe1ccIhab Awad            mCallIdMapper.checkValidCallId(callId);
25050a57136b3aa876c8311b58e1e11720a337fe1ccIhab Awad            SomeArgs args = SomeArgs.obtain();
25150a57136b3aa876c8311b58e1e11720a337fe1ccIhab Awad            args.arg1 = callId;
25250a57136b3aa876c8311b58e1e11720a337fe1ccIhab Awad            args.arg2 = ringback;
25350a57136b3aa876c8311b58e1e11720a337fe1ccIhab Awad            mHandler.obtainMessage(MSG_SET_REQUESTING_RINGBACK, args).sendToTarget();
25450a57136b3aa876c8311b58e1e11720a337fe1ccIhab Awad        }
2553d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon    }
2563d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon
2573d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon    private final Adapter mAdapter = new Adapter();
2583d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon    private final CallsManager mCallsManager = CallsManager.getInstance();
259682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon    private final Set<Call> mPendingIncomingCalls = Sets.newHashSet();
2603d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon    private final CallServiceDescriptor mDescriptor;
2613d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon    private final CallIdMapper mCallIdMapper = new CallIdMapper("CallService");
2623d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon    private final IncomingCallsManager mIncomingCallsManager;
263682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon    private final Map<String, AsyncResultCallback<Boolean>> mPendingOutgoingCalls = new HashMap<>();
264c195e3613af47a49e76821d3f24c05adb71cf920Santos Cordon
2656192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad    private Binder mBinder = new Binder();
2663d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon    private ICallService mServiceInterface;
2676192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad
26863aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon    /**
269e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal     * Creates a call-service for the specified descriptor.
270c195e3613af47a49e76821d3f24c05adb71cf920Santos Cordon     *
27161d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon     * @param descriptor The call-service descriptor from
2723d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon     *            {@link ICallServiceProvider#lookupCallServices}.
273e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal     * @param incomingCallsManager Manages the incoming call initialization flow.
27463aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon     */
275e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal    CallServiceWrapper(
276e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal            CallServiceDescriptor descriptor,
277e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal            IncomingCallsManager incomingCallsManager) {
278a439e1b6d6201dedecfc40b67c9347a8c563b9c1Sailesh Nepal        super(TelecommConstants.ACTION_CALL_SERVICE, descriptor.getServiceComponent());
279c5b2269fe4d926f040f10da5f0faf0a4f1ab5cfdBen Gilad        mDescriptor = descriptor;
2803d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        mIncomingCallsManager = incomingCallsManager;
28163aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon    }
28263aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon
2836192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad    CallServiceDescriptor getDescriptor() {
284c5b2269fe4d926f040f10da5f0faf0a4f1ab5cfdBen Gilad        return mDescriptor;
285c195e3613af47a49e76821d3f24c05adb71cf920Santos Cordon    }
286c195e3613af47a49e76821d3f24c05adb71cf920Santos Cordon
28763aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon    /** See {@link ICallService#setCallServiceAdapter}. */
288e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal    private void setCallServiceAdapter(ICallServiceAdapter callServiceAdapter) {
28961d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon        if (isServiceValid("setCallServiceAdapter")) {
29061d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon            try {
29163aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon                mServiceInterface.setCallServiceAdapter(callServiceAdapter);
29261d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon            } catch (RemoteException e) {
29363aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon            }
29463aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon        }
29563aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon    }
29663aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon
2976192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad    /**
298682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon     * Attempts to place the specified call, see {@link ICallService#call}. Returns the result
299682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon     * asynchronously through the specified callback.
3006192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad     */
301682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon    void call(final Call call, final AsyncResultCallback<Boolean> resultCallback) {
302682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon        Log.d(this, "call(%s) via %s.", call, getComponentName());
3036192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad        BindCallback callback = new BindCallback() {
3043d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            @Override
3053d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            public void onSuccess() {
306682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                String callId = mCallIdMapper.getCallId(call);
307682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                mPendingOutgoingCalls.put(callId, resultCallback);
308682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon
309682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                try {
310682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                    CallInfo callInfo = call.toCallInfo(callId);
311682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                    mServiceInterface.call(callInfo);
312682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                } catch (RemoteException e) {
313682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                    mPendingOutgoingCalls.remove(callId).onResult(false);
3146192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad                }
31563aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon            }
3163d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon
3173d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            @Override
3183d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            public void onFailure() {
319682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                resultCallback.onResult(false);
3206192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad            }
3216192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad        };
3226192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad
3236192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad        mBinder.bind(callback);
32463aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon    }
32563aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon
32674549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad    /** @see CallService#abort(String) */
327e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal    void abort(Call call) {
328682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon        // Clear out any pending outgoing call data
329682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon        String callId = mCallIdMapper.getCallId(call);
330682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon
331682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon        // If still bound, tell the call service to abort.
33228e8ad601cbef0abab1cd6aec8c5a3bc881839c2Ben Gilad        if (isServiceValid("abort")) {
33328e8ad601cbef0abab1cd6aec8c5a3bc881839c2Ben Gilad            try {
334682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                mServiceInterface.abort(callId);
33528e8ad601cbef0abab1cd6aec8c5a3bc881839c2Ben Gilad            } catch (RemoteException e) {
33661d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon            }
33761d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon        }
338682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon
339682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon        removeCall(call);
34061d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon    }
34161d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon
34274549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad    /** @see CallService#hold(String) */
343e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal    void hold(Call call) {
344cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee        if (isServiceValid("hold")) {
345cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee            try {
346e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal                mServiceInterface.hold(mCallIdMapper.getCallId(call));
347cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee            } catch (RemoteException e) {
348cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee            }
349cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee        }
350cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee    }
351cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee
35274549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad    /** @see CallService#unhold(String) */
353e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal    void unhold(Call call) {
354cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee        if (isServiceValid("unhold")) {
355cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee            try {
356e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal                mServiceInterface.unhold(mCallIdMapper.getCallId(call));
357cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee            } catch (RemoteException e) {
358cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee            }
359cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee        }
360cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee    }
361cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee
36274549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad    /** @see CallService#onAudioStateChanged(String,CallAudioState) */
363e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal    void onAudioStateChanged(Call activeCall, CallAudioState audioState) {
3646aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal        if (isServiceValid("onAudioStateChanged")) {
3656aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal            try {
366e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal                mServiceInterface.onAudioStateChanged(mCallIdMapper.getCallId(activeCall),
367e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal                        audioState);
3686aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal            } catch (RemoteException e) {
3696aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal            }
3706aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal        }
3716aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal    }
3726aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal
3736192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad    /**
3746192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad     * Starts retrieval of details for an incoming call. Details are returned through the
3756192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad     * call-service adapter using the specified call ID. Upon failure, the specified error callback
3763d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon     * is invoked. Can be invoked even when the call service is unbound. See
3773d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon     * {@link ICallService#setIncomingCallId}.
3786192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad     *
379e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal     * @param call The call used for the incoming call.
3806192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad     * @param extras The {@link CallService}-provided extras which need to be sent back.
3816192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad     * @param errorCallback The callback to invoke upon failure.
3826192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad     */
383e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal    void setIncomingCallId(final Call call, final Bundle extras, final Runnable errorCallback) {
384e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal        Log.d(this, "setIncomingCall(%s) via %s.", call, getComponentName());
3856192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad        BindCallback callback = new BindCallback() {
3863d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            @Override
3873d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            public void onSuccess() {
3886192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad                if (isServiceValid("setIncomingCallId")) {
389682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                    mPendingIncomingCalls.add(call);
3906192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad                    try {
391e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal                        mServiceInterface.setIncomingCallId(mCallIdMapper.getCallId(call),
392e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal                                extras);
3936192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad                    } catch (RemoteException e) {
3946192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad                    }
3956192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad                }
39663aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon            }
3973d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon
3983d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            @Override
3993d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            public void onFailure() {
4006192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad                errorCallback.run();
4016192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad            }
4026192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad        };
4036192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad
4046192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad        mBinder.bind(callback);
40563aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon    }
40663aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon
40774549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad    /** @see CallService#disconnect(String) */
408e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal    void disconnect(Call call) {
40961d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon        if (isServiceValid("disconnect")) {
41061d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon            try {
411e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal                mServiceInterface.disconnect(mCallIdMapper.getCallId(call));
41261d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon            } catch (RemoteException e) {
41361d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon            }
41461d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon        }
41561d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon    }
41661d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon
41774549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad    /** @see CallService#answer(String) */
418e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal    void answer(Call call) {
41961d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon        if (isServiceValid("answer")) {
42061d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon            try {
421e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal                mServiceInterface.answer(mCallIdMapper.getCallId(call));
42261d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon            } catch (RemoteException e) {
42363aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon            }
42463aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon        }
42563aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon    }
4265c12c6e00101d16d2db776839a027c62c109dea8Santos Cordon
42774549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad    /** @see CallService#reject(String) */
428e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal    void reject(Call call) {
42961d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon        if (isServiceValid("reject")) {
43061d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon            try {
431e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal                mServiceInterface.reject(mCallIdMapper.getCallId(call));
43261d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon            } catch (RemoteException e) {
43374549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad            }
43474549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad        }
43574549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad    }
43674549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad
43774549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad    /** @see CallService#playDtmfTone(String,char) */
438e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal    void playDtmfTone(Call call, char digit) {
43974549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad        if (isServiceValid("playDtmfTone")) {
44074549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad            try {
441e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal                mServiceInterface.playDtmfTone(mCallIdMapper.getCallId(call), digit);
44274549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad            } catch (RemoteException e) {
44374549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad            }
44474549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad        }
44574549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad    }
44674549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad
44774549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad    /** @see CallService#stopDtmfTone(String) */
448e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal    void stopDtmfTone(Call call) {
44974549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad        if (isServiceValid("stopDtmfTone")) {
45074549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad            try {
451e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal                mServiceInterface.stopDtmfTone(mCallIdMapper.getCallId(call));
45274549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad            } catch (RemoteException e) {
4537917d38176b6cc432314433d36d7bb46a09f5afcSantos Cordon            }
4547917d38176b6cc432314433d36d7bb46a09f5afcSantos Cordon        }
4557917d38176b6cc432314433d36d7bb46a09f5afcSantos Cordon    }
4567917d38176b6cc432314433d36d7bb46a09f5afcSantos Cordon
457e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal    void addCall(Call call) {
458e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal        mCallIdMapper.addCall(call);
4597917d38176b6cc432314433d36d7bb46a09f5afcSantos Cordon    }
4607917d38176b6cc432314433d36d7bb46a09f5afcSantos Cordon
4610e5410a58043ce059884fdc8811a280655e5a920Sailesh Nepal    /**
4620e5410a58043ce059884fdc8811a280655e5a920Sailesh Nepal     * Associates newCall with this call service by replacing callToReplace.
4630e5410a58043ce059884fdc8811a280655e5a920Sailesh Nepal     */
4640e5410a58043ce059884fdc8811a280655e5a920Sailesh Nepal    void replaceCall(Call newCall, Call callToReplace) {
4650e5410a58043ce059884fdc8811a280655e5a920Sailesh Nepal        Preconditions.checkState(callToReplace.getCallService() == this);
4660e5410a58043ce059884fdc8811a280655e5a920Sailesh Nepal        mCallIdMapper.replaceCall(newCall, callToReplace);
4670e5410a58043ce059884fdc8811a280655e5a920Sailesh Nepal    }
4680e5410a58043ce059884fdc8811a280655e5a920Sailesh Nepal
469e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal    void removeCall(Call call) {
470682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon        mPendingIncomingCalls.remove(call);
471682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon
472682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon        AsyncResultCallback<Boolean> outgoingResultCallback =
473682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon            mPendingOutgoingCalls.remove(mCallIdMapper.getCallId(call));
474682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon        if (outgoingResultCallback != null) {
475682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon            outgoingResultCallback.onResult(false);
476682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon        }
477682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon
478e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal        mCallIdMapper.removeCall(call);
479adee12dd6b3e85ce3ae419329226c9aa72c184fcYorke Lee    }
480adee12dd6b3e85ce3ae419329226c9aa72c184fcYorke Lee
4815c12c6e00101d16d2db776839a027c62c109dea8Santos Cordon    /** {@inheritDoc} */
4823d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon    @Override
4833d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon    protected void setServiceInterface(IBinder binder) {
4844b2c119562bf29b05c7dc139c77f5893d3d70d2cSantos Cordon        if (binder == null) {
4854b2c119562bf29b05c7dc139c77f5893d3d70d2cSantos Cordon            // We have lost our service connection. Notify the world that this call service is done.
4864b2c119562bf29b05c7dc139c77f5893d3d70d2cSantos Cordon            // We must notify the adapter before CallsManager. The adapter will force any pending
4874b2c119562bf29b05c7dc139c77f5893d3d70d2cSantos Cordon            // outgoing calls to try the next call service. This needs to happen before CallsManager
4884b2c119562bf29b05c7dc139c77f5893d3d70d2cSantos Cordon            // tries to clean up any calls still associated with this call service.
4893d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            handleCallServiceDeath();
4904b2c119562bf29b05c7dc139c77f5893d3d70d2cSantos Cordon            CallsManager.getInstance().handleCallServiceDeath(this);
4914b2c119562bf29b05c7dc139c77f5893d3d70d2cSantos Cordon            mServiceInterface = null;
4924b2c119562bf29b05c7dc139c77f5893d3d70d2cSantos Cordon        } else {
4934b2c119562bf29b05c7dc139c77f5893d3d70d2cSantos Cordon            mServiceInterface = ICallService.Stub.asInterface(binder);
4944b2c119562bf29b05c7dc139c77f5893d3d70d2cSantos Cordon            setCallServiceAdapter(mAdapter);
4954b2c119562bf29b05c7dc139c77f5893d3d70d2cSantos Cordon        }
4965c12c6e00101d16d2db776839a027c62c109dea8Santos Cordon    }
4973d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon
4983d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon    /**
4993d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon     * Called when the associated call service dies.
5003d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon     */
5013d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon    private void handleCallServiceDeath() {
502682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon        if (!mPendingOutgoingCalls.isEmpty()) {
503682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon            for (AsyncResultCallback<Boolean> callback : mPendingOutgoingCalls.values()) {
504682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                callback.onResult(false);
505682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon            }
506682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon            mPendingOutgoingCalls.clear();
507682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon        }
508682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon
509682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon        if (!mPendingIncomingCalls.isEmpty()) {
5103d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            // Iterate through a copy because the code inside the loop will modify the original
5113d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            // list.
512682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon            for (Call call : ImmutableList.copyOf(mPendingIncomingCalls)) {
513682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                Preconditions.checkState(call.isIncoming());
514682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                mIncomingCallsManager.handleFailedIncomingCall(call);
5153d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            }
5163d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon
517682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon            if (!mPendingIncomingCalls.isEmpty()) {
5183d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon                Log.wtf(this, "Pending calls did not get cleared.");
519682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                mPendingIncomingCalls.clear();
5203d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            }
5213d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        }
522682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon
523682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon        mCallIdMapper.clear();
5243d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon    }
52563aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon}
526