blob: 1e830d5850ca424a89f4c360632de7d284055d47 [file] [log] [blame]
Santos Cordon681663d2014-01-30 04:32:15 -08001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Ben Gilad9f2bed32013-12-12 17:43:26 -080017package com.android.telecomm;
18
Santos Cordon681663d2014-01-30 04:32:15 -080019import android.os.Handler;
20import android.os.Looper;
21import android.telecomm.CallInfo;
Santos Cordon681663d2014-01-30 04:32:15 -080022
Sailesh Nepala439e1b2014-03-11 18:19:58 -070023import com.android.internal.telecomm.ICallServiceAdapter;
Santos Cordon7917d382014-02-14 02:31:18 -080024import com.google.android.collect.Sets;
Santos Cordon681663d2014-01-30 04:32:15 -080025import com.google.common.base.Strings;
26
Santos Cordon7917d382014-02-14 02:31:18 -080027import java.util.Set;
28
Ben Gilad9f2bed32013-12-12 17:43:26 -080029/**
Santos Cordon681663d2014-01-30 04:32:15 -080030 * Used by call services in order to update state and control calls while the call service is bound
31 * to Telecomm. Each call service is given its own instance for the lifetime of the binding between
32 * Telecomm and the call service.
33 * TODO(santoscordon): Whenever we get any method invocations from the call service, we need to
34 * check that the invocation is expected from that call service.
35 * TODO(santoscordon): Move away from Runnable objects and into messages so that we create fewer
36 * objects per IPC method call.
Santos Cordon63aeb162014-02-10 09:20:40 -080037 * TODO(santoscordon): Do we need Binder.clear/restoreCallingIdentity() in the service methods?
Ben Gilad9f2bed32013-12-12 17:43:26 -080038 */
Santos Cordon681663d2014-01-30 04:32:15 -080039public final class CallServiceAdapter extends ICallServiceAdapter.Stub {
Santos Cordon681663d2014-01-30 04:32:15 -080040 private final CallsManager mCallsManager;
Ben Gilad9f2bed32013-12-12 17:43:26 -080041
Santos Cordon681663d2014-01-30 04:32:15 -080042 private final OutgoingCallsManager mOutgoingCallsManager;
43
Santos Cordon493e8f22014-02-19 03:15:12 -080044 private final IncomingCallsManager mIncomingCallsManager;
45
Santos Cordon681663d2014-01-30 04:32:15 -080046 /** Used to run code (e.g. messages, Runnables) on the main (UI) thread. */
47 private final Handler mHandler = new Handler(Looper.getMainLooper());
48
Ben Gilad28e8ad62014-03-06 17:01:54 -080049 /**
50 * The set of pending outgoing call IDs. Any {@link #handleSuccessfulOutgoingCall} and
51 * {@link #handleFailedOutgoingCall} invocations with a call ID that is not in this set
52 * are ignored.
53 */
54 private final Set<String> mPendingOutgoingCallIds = Sets.newHashSet();
55
56 /**
57 * The set of pending incoming call IDs. Any {@link #handleIncomingCall} invocations with
58 * a call ID not in this set are ignored.
Santos Cordon7917d382014-02-14 02:31:18 -080059 */
Santos Cordon61d0f702014-02-19 02:52:23 -080060 private final Set<String> mPendingIncomingCallIds = Sets.newHashSet();
Santos Cordon7917d382014-02-14 02:31:18 -080061
Santos Cordon681663d2014-01-30 04:32:15 -080062 /**
63 * Persists the specified parameters.
Santos Cordon493e8f22014-02-19 03:15:12 -080064 *
65 * @param outgoingCallsManager Manages the placing of outgoing calls.
66 * @param incomingCallsManager Manages the incoming call initialization flow.
Santos Cordon681663d2014-01-30 04:32:15 -080067 */
Santos Cordon493e8f22014-02-19 03:15:12 -080068 CallServiceAdapter(
69 OutgoingCallsManager outgoingCallsManager, IncomingCallsManager incomingCallsManager) {
70
Santos Cordon681663d2014-01-30 04:32:15 -080071 mCallsManager = CallsManager.getInstance();
72 mOutgoingCallsManager = outgoingCallsManager;
Santos Cordon493e8f22014-02-19 03:15:12 -080073 mIncomingCallsManager = incomingCallsManager;
Santos Cordon681663d2014-01-30 04:32:15 -080074 }
75
76 /** {@inheritDoc} */
Ben Gilad61925612014-03-11 19:06:36 -070077 @Override public void setIsCompatibleWith(final String callId, final boolean isCompatible) {
78 checkValidCallId(callId);
79 mHandler.post(new Runnable() {
80 @Override public void run() {
81 if (mPendingOutgoingCallIds.contains(callId)) {
82 mOutgoingCallsManager.setIsCompatibleWith(callId, isCompatible);
83 } else {
84 Log.wtf(CallServiceAdapter.this, "Unknown outgoing call: %s", callId);
85 }
86 }
87 });
Santos Cordon681663d2014-01-30 04:32:15 -080088 }
89
Santos Cordon7917d382014-02-14 02:31:18 -080090 /** {@inheritDoc} */
Sailesh Nepala439e1b2014-03-11 18:19:58 -070091 @Override public void notifyIncomingCall(final CallInfo callInfo) {
Santos Cordon7917d382014-02-14 02:31:18 -080092 checkValidCallId(callInfo.getId());
93 mHandler.post(new Runnable() {
94 @Override public void run() {
Santos Cordon61d0f702014-02-19 02:52:23 -080095 if (mPendingIncomingCallIds.remove(callInfo.getId())) {
Santos Cordon493e8f22014-02-19 03:15:12 -080096 mIncomingCallsManager.handleSuccessfulIncomingCall(callInfo);
Santos Cordon7917d382014-02-14 02:31:18 -080097 } else {
Ben Gilad61925612014-03-11 19:06:36 -070098 Log.wtf(CallServiceAdapter.this, "Unknown incoming call: %s", callInfo);
Santos Cordon7917d382014-02-14 02:31:18 -080099 }
100 }
101 });
Santos Cordon681663d2014-01-30 04:32:15 -0800102 }
103
104 /** {@inheritDoc} */
105 @Override public void handleSuccessfulOutgoingCall(final String callId) {
106 checkValidCallId(callId);
107 mHandler.post(new Runnable() {
108 @Override public void run() {
Ben Gilad28e8ad62014-03-06 17:01:54 -0800109 if (mPendingOutgoingCallIds.remove(callId)) {
110 mOutgoingCallsManager.handleSuccessfulCallAttempt(callId);
111 } else {
112 // TODO(gilad): Figure out how to wire up the callService.abort() call.
Ben Gilad61925612014-03-11 19:06:36 -0700113 Log.wtf(CallServiceAdapter.this, "Unknown outgoing call: %s", callId);
Ben Gilad28e8ad62014-03-06 17:01:54 -0800114 }
Santos Cordon681663d2014-01-30 04:32:15 -0800115 }
116 });
117 }
118
119 /** {@inheritDoc} */
120 @Override public void handleFailedOutgoingCall(final String callId, final String reason) {
121 checkValidCallId(callId);
122 mHandler.post(new Runnable() {
123 @Override public void run() {
Ben Gilad28e8ad62014-03-06 17:01:54 -0800124 if (mPendingOutgoingCallIds.remove(callId)) {
125 mOutgoingCallsManager.handleFailedCallAttempt(callId, reason);
126 } else {
Ben Gilad61925612014-03-11 19:06:36 -0700127 Log.wtf(CallServiceAdapter.this, "Unknown outgoing call: %s", callId);
Ben Gilad28e8ad62014-03-06 17:01:54 -0800128 }
Santos Cordon681663d2014-01-30 04:32:15 -0800129 }
130 });
131 }
132
133 /** {@inheritDoc} */
134 @Override public void setActive(final String callId) {
135 checkValidCallId(callId);
136 mHandler.post(new Runnable() {
137 @Override public void run() {
138 mCallsManager.markCallAsActive(callId);
139 }
140 });
141 }
142
143 /** {@inheritDoc} */
144 @Override public void setRinging(final String callId) {
145 checkValidCallId(callId);
146 mHandler.post(new Runnable() {
147 @Override public void run() {
148 mCallsManager.markCallAsRinging(callId);
149 }
150 });
151 }
152
153 /** {@inheritDoc} */
154 @Override public void setDialing(final String callId) {
155 checkValidCallId(callId);
156 mHandler.post(new Runnable() {
157 @Override public void run() {
158 mCallsManager.markCallAsDialing(callId);
159 }
160 });
161 }
162
163 /** {@inheritDoc} */
Ben Gilad28e8ad62014-03-06 17:01:54 -0800164 // TODO(gilad): Ensure that any communication from the underlying ICallService
165 // implementation is expected (or otherwise suppressed at the adapter level).
Santos Cordon681663d2014-01-30 04:32:15 -0800166 @Override public void setDisconnected(final String callId) {
167 checkValidCallId(callId);
168 mHandler.post(new Runnable() {
169 @Override public void run() {
170 mCallsManager.markCallAsDisconnected(callId);
171 }
172 });
173 }
174
175 /**
Ben Gilad28e8ad62014-03-06 17:01:54 -0800176 * Adds the specified call ID to the list of pending outgoing call IDs.
177 * TODO(gilad): Consider passing the call processor (instead of the ID) both here and in the
178 * remove case (same for incoming) such that the detour via the *CallsManager can be avoided.
179 *
180 * @param callId The ID of the call.
181 */
182 void addPendingOutgoingCallId(String callId) {
183 mPendingOutgoingCallIds.add(callId);
184 }
185
186 /**
187 * Removes the specified call ID from the list of pending outgoing call IDs.
188 *
189 * @param callId The ID of the call.
190 */
191 void removePendingOutgoingCallId(String callId) {
192 mPendingOutgoingCallIds.remove(callId);
193 }
194
195 /**
Santos Cordon61d0f702014-02-19 02:52:23 -0800196 * Adds a call ID to the list of pending incoming call IDs. Only calls with call IDs in the
197 * list will be handled by {@link #handleIncomingCall}.
Santos Cordon7917d382014-02-14 02:31:18 -0800198 *
199 * @param callId The ID of the call.
200 */
Santos Cordon61d0f702014-02-19 02:52:23 -0800201 void addPendingIncomingCallId(String callId) {
202 mPendingIncomingCallIds.add(callId);
Santos Cordon7917d382014-02-14 02:31:18 -0800203 }
204
205 /**
Ben Gilad28e8ad62014-03-06 17:01:54 -0800206 * Removes the specified call ID from the list of pending incoming call IDs.
Santos Cordon7917d382014-02-14 02:31:18 -0800207 *
208 * @param callId The ID of the call.
209 */
Santos Cordon61d0f702014-02-19 02:52:23 -0800210 void removePendingIncomingCallId(String callId) {
211 mPendingIncomingCallIds.remove(callId);
Santos Cordon7917d382014-02-14 02:31:18 -0800212 }
213
214 /**
Santos Cordon681663d2014-01-30 04:32:15 -0800215 * Throws an IllegalArgumentException if the specified call ID is invalid.
216 *
217 * @param callId The call ID to check.
218 */
219 private void checkValidCallId(String callId) {
220 if (Strings.isNullOrEmpty(callId)) {
Santos Cordon7917d382014-02-14 02:31:18 -0800221 throw new IllegalArgumentException("Invalid call ID.");
Santos Cordon681663d2014-01-30 04:32:15 -0800222 }
223 }
Ben Gilad9f2bed32013-12-12 17:43:26 -0800224}