blob: 72e104106bd484e1b2ee417f64a1db992c30ef27 [file] [log] [blame]
Santos Cordon63aeb162014-02-10 09:20:40 -08001/*
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
Evan Charltona05805b2014-03-05 08:21:46 -080019import android.os.Bundle;
Santos Cordon63aeb162014-02-10 09:20:40 -080020import android.os.IBinder;
21import android.os.RemoteException;
22import android.telecomm.CallInfo;
Evan Charltona05805b2014-03-05 08:21:46 -080023import android.telecomm.CallService;
Ben Giladc5b22692014-02-18 20:03:22 -080024import android.telecomm.CallServiceDescriptor;
Santos Cordon63aeb162014-02-10 09:20:40 -080025import android.telecomm.ICallService;
26import android.telecomm.ICallServiceAdapter;
27import android.util.Log;
28
Santos Cordon493e8f22014-02-19 03:15:12 -080029import com.android.telecomm.ServiceBinder.BindCallback;
30
Santos Cordon63aeb162014-02-10 09:20:40 -080031/**
32 * Wrapper for {@link ICallService}s, handles binding to {@link ICallService} and keeps track of
33 * when the object can safely be unbound. Other classes should not use {@link ICallService} directly
34 * and instead should use this class to invoke methods of {@link ICallService}.
35 * TODO(santoscordon): Keep track of when the service can be safely unbound.
36 * TODO(santoscordon): Look into combining with android.telecomm.CallService.
37 */
38public class CallServiceWrapper extends ServiceBinder<ICallService> {
Santos Cordon63aeb162014-02-10 09:20:40 -080039
40 /**
41 * The service action used to bind to ICallService implementations.
42 * TODO(santoscordon): Move this to TelecommConstants.
43 */
44 static final String CALL_SERVICE_ACTION = ICallService.class.getName();
45
Santos Cordonc195e362014-02-11 17:05:31 -080046 private static final String TAG = CallServiceWrapper.class.getSimpleName();
47
48 /** The descriptor of this call service as supplied by the call-service provider. */
Ben Giladc5b22692014-02-18 20:03:22 -080049 private final CallServiceDescriptor mDescriptor;
Santos Cordonc195e362014-02-11 17:05:31 -080050
51 /**
52 * The adapter used by the underlying call-service implementation to communicate with Telecomm.
53 */
54 private final CallServiceAdapter mAdapter;
55
56 /** The actual service implementation. */
57 private ICallService mServiceInterface;
58
Santos Cordon63aeb162014-02-10 09:20:40 -080059 /**
60 * Creates a call-service provider for the specified component.
Santos Cordonc195e362014-02-11 17:05:31 -080061 *
Santos Cordon61d0f702014-02-19 02:52:23 -080062 * @param descriptor The call-service descriptor from
63 * {@link ICallServiceProvider#lookupCallServices}.
Santos Cordonc195e362014-02-11 17:05:31 -080064 * @param adapter The call-service adapter.
Santos Cordon63aeb162014-02-10 09:20:40 -080065 */
Ben Giladc5b22692014-02-18 20:03:22 -080066 public CallServiceWrapper(CallServiceDescriptor descriptor, CallServiceAdapter adapter) {
67 super(CALL_SERVICE_ACTION, descriptor.getServiceComponent());
68 mDescriptor = descriptor;
Santos Cordonc195e362014-02-11 17:05:31 -080069 mAdapter = adapter;
Santos Cordon63aeb162014-02-10 09:20:40 -080070 }
71
Ben Giladc5b22692014-02-18 20:03:22 -080072 public CallServiceDescriptor getDescriptor() {
73 return mDescriptor;
Santos Cordonc195e362014-02-11 17:05:31 -080074 }
75
Santos Cordon63aeb162014-02-10 09:20:40 -080076 /** See {@link ICallService#setCallServiceAdapter}. */
77 public void setCallServiceAdapter(ICallServiceAdapter callServiceAdapter) {
Santos Cordon61d0f702014-02-19 02:52:23 -080078 if (isServiceValid("setCallServiceAdapter")) {
79 try {
Santos Cordon63aeb162014-02-10 09:20:40 -080080 mServiceInterface.setCallServiceAdapter(callServiceAdapter);
Santos Cordon61d0f702014-02-19 02:52:23 -080081 } catch (RemoteException e) {
82 Log.e(TAG, "Failed to setCallServiceAdapter.", e);
Santos Cordon63aeb162014-02-10 09:20:40 -080083 }
Santos Cordon63aeb162014-02-10 09:20:40 -080084 }
85 }
86
87 /** See {@link ICallService#isCompatibleWith}. */
88 public void isCompatibleWith(CallInfo callInfo) {
Santos Cordon61d0f702014-02-19 02:52:23 -080089 if (isServiceValid("isCompatibleWith")) {
90 try {
Santos Cordon63aeb162014-02-10 09:20:40 -080091 mServiceInterface.isCompatibleWith(callInfo);
Santos Cordon61d0f702014-02-19 02:52:23 -080092 } catch (RemoteException e) {
93 Log.e(TAG, "Failed checking isCompatibleWith.", e);
Santos Cordon63aeb162014-02-10 09:20:40 -080094 }
Santos Cordon63aeb162014-02-10 09:20:40 -080095 }
96 }
97
98 /** See {@link ICallService#call}. */
99 public void call(CallInfo callInfo) {
Santos Cordon61d0f702014-02-19 02:52:23 -0800100 if (isServiceValid("call")) {
101 try {
Santos Cordon63aeb162014-02-10 09:20:40 -0800102 mServiceInterface.call(callInfo);
Santos Cordon61d0f702014-02-19 02:52:23 -0800103 } catch (RemoteException e) {
104 Log.e(TAG, "Failed to place call " + callInfo.getId() + ".", e);
Santos Cordon63aeb162014-02-10 09:20:40 -0800105 }
Santos Cordon61d0f702014-02-19 02:52:23 -0800106 }
107 }
108
109 /** See {@link ICallService#setIncomingCallId}. */
Evan Charltona05805b2014-03-05 08:21:46 -0800110 public void setIncomingCallId(String callId, Bundle extras) {
Santos Cordon61d0f702014-02-19 02:52:23 -0800111 if (isServiceValid("setIncomingCallId")) {
112 mAdapter.addPendingIncomingCallId(callId);
113 try {
Evan Charltona05805b2014-03-05 08:21:46 -0800114 mServiceInterface.setIncomingCallId(callId, extras);
Santos Cordon61d0f702014-02-19 02:52:23 -0800115 } catch (RemoteException e) {
116 Log.e(TAG, "Failed to setIncomingCallId for call " + callId, e);
117 mAdapter.removePendingIncomingCallId(callId);
118 }
Santos Cordon63aeb162014-02-10 09:20:40 -0800119 }
120 }
121
122 /** See {@link ICallService#disconnect}. */
123 public void disconnect(String callId) {
Santos Cordon61d0f702014-02-19 02:52:23 -0800124 if (isServiceValid("disconnect")) {
125 try {
Santos Cordon63aeb162014-02-10 09:20:40 -0800126 mServiceInterface.disconnect(callId);
Santos Cordon61d0f702014-02-19 02:52:23 -0800127 } catch (RemoteException e) {
128 Log.e(TAG, "Failed to disconnect call " + callId + ".", e);
Santos Cordon63aeb162014-02-10 09:20:40 -0800129 }
Santos Cordon63aeb162014-02-10 09:20:40 -0800130 }
131 }
Santos Cordon5c12c6e2014-02-13 14:35:31 -0800132
Santos Cordon61d0f702014-02-19 02:52:23 -0800133 /** See {@link ICallService#answer}. */
134 public void answer(String callId) {
135 if (isServiceValid("answer")) {
136 try {
137 mServiceInterface.answer(callId);
138 } catch (RemoteException e) {
139 Log.e(TAG, "Failed to answer call " + callId, e);
Santos Cordon7917d382014-02-14 02:31:18 -0800140 }
Santos Cordon61d0f702014-02-19 02:52:23 -0800141 }
142 }
143
144 /** See {@link ICallService#reject}. */
145 public void reject(String callId) {
146 if (isServiceValid("reject")) {
147 try {
148 mServiceInterface.reject(callId);
149 } catch (RemoteException e) {
150 Log.e(TAG, "Failed to reject call " + callId, e);
151 }
Santos Cordon7917d382014-02-14 02:31:18 -0800152 }
153 }
154
155 /**
Santos Cordon493e8f22014-02-19 03:15:12 -0800156 * Starts retrieval of details for an incoming call. Details are returned through the
157 * call-service adapter using the specified call ID. Upon failure, the specified error callback
158 * is invoked. Can be invoked even when the call service is unbound.
159 *
Evan Charltona05805b2014-03-05 08:21:46 -0800160 * @param callId The call ID used for the incoming call.
161 * @param extras The {@link CallService}-provided extras which need to be sent back.
Santos Cordon493e8f22014-02-19 03:15:12 -0800162 * @param errorCallback The callback invoked upon failure.
163 */
Evan Charltona05805b2014-03-05 08:21:46 -0800164 void retrieveIncomingCall(final String callId, final Bundle extras,
165 final Runnable errorCallback) {
166
Santos Cordon493e8f22014-02-19 03:15:12 -0800167 BindCallback callback = new BindCallback() {
168 @Override public void onSuccess() {
Evan Charltona05805b2014-03-05 08:21:46 -0800169 setIncomingCallId(callId, extras);
Santos Cordon493e8f22014-02-19 03:15:12 -0800170 }
171 @Override public void onFailure() {
172 errorCallback.run();
173 }
174 };
175
176 bind(callback);
177 }
178
179 /**
Santos Cordon61d0f702014-02-19 02:52:23 -0800180 * Cancels the incoming call for the specified call ID.
181 * TODO(santoscordon): This method should be called by IncomingCallsManager when the incoming
182 * call has failed.
Santos Cordon7917d382014-02-14 02:31:18 -0800183 *
184 * @param callId The ID of the call.
185 */
186 void cancelIncomingCall(String callId) {
Santos Cordon61d0f702014-02-19 02:52:23 -0800187 mAdapter.removePendingIncomingCallId(callId);
Santos Cordon7917d382014-02-14 02:31:18 -0800188 }
189
Santos Cordon5c12c6e2014-02-13 14:35:31 -0800190 /** {@inheritDoc} */
191 @Override protected void setServiceInterface(IBinder binder) {
192 mServiceInterface = ICallService.Stub.asInterface(binder);
193 setCallServiceAdapter(mAdapter);
194 }
Santos Cordon61d0f702014-02-19 02:52:23 -0800195
196 private boolean isServiceValid(String actionName) {
197 if (mServiceInterface != null) {
198 return true;
199 }
200
201 Log.wtf(TAG, actionName + " invoked while service is unbound");
202 return false;
203 }
Santos Cordon63aeb162014-02-10 09:20:40 -0800204}