blob: 8daa16e627c48208377c0fb1fe19d7a17913dc55 [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;
22import android.telecomm.ICallServiceAdapter;
23
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} */
Santos Cordon681663d2014-01-30 04:32:15 -080077 @Override public void setCompatibleWith(String callId, boolean isCompatible) {
78 // TODO(santoscordon): fill in.
79 }
80
Santos Cordon7917d382014-02-14 02:31:18 -080081 /** {@inheritDoc} */
Santos Cordon61d0f702014-02-19 02:52:23 -080082 @Override public void handleIncomingCall(final CallInfo callInfo) {
Santos Cordon7917d382014-02-14 02:31:18 -080083 checkValidCallId(callInfo.getId());
84 mHandler.post(new Runnable() {
85 @Override public void run() {
Santos Cordon61d0f702014-02-19 02:52:23 -080086 if (mPendingIncomingCallIds.remove(callInfo.getId())) {
Santos Cordon493e8f22014-02-19 03:15:12 -080087 mIncomingCallsManager.handleSuccessfulIncomingCall(callInfo);
Santos Cordon7917d382014-02-14 02:31:18 -080088 } else {
Sailesh Nepalf1c191d2014-03-07 18:17:39 -080089 Log.wtf(CallServiceAdapter.this,
Ben Gilad28e8ad62014-03-06 17:01:54 -080090 "Unknown incoming call: %s", callInfo);
Santos Cordon7917d382014-02-14 02:31:18 -080091 }
92 }
93 });
Santos Cordon681663d2014-01-30 04:32:15 -080094 }
95
96 /** {@inheritDoc} */
97 @Override public void handleSuccessfulOutgoingCall(final String callId) {
98 checkValidCallId(callId);
99 mHandler.post(new Runnable() {
100 @Override public void run() {
Ben Gilad28e8ad62014-03-06 17:01:54 -0800101 if (mPendingOutgoingCallIds.remove(callId)) {
102 mOutgoingCallsManager.handleSuccessfulCallAttempt(callId);
103 } else {
104 // TODO(gilad): Figure out how to wire up the callService.abort() call.
105 Log.wtf(CallServiceAdapter.this,
106 "Unknown outgoing call: %s", callId);
107 }
Santos Cordon681663d2014-01-30 04:32:15 -0800108 }
109 });
110 }
111
112 /** {@inheritDoc} */
113 @Override public void handleFailedOutgoingCall(final String callId, final String reason) {
114 checkValidCallId(callId);
115 mHandler.post(new Runnable() {
116 @Override public void run() {
Ben Gilad28e8ad62014-03-06 17:01:54 -0800117 if (mPendingOutgoingCallIds.remove(callId)) {
118 mOutgoingCallsManager.handleFailedCallAttempt(callId, reason);
119 } else {
120 Log.wtf(CallServiceAdapter.this,
121 "Unknown outgoing call: %s", callId);
122 }
Santos Cordon681663d2014-01-30 04:32:15 -0800123 }
124 });
125 }
126
127 /** {@inheritDoc} */
128 @Override public void setActive(final String callId) {
129 checkValidCallId(callId);
130 mHandler.post(new Runnable() {
131 @Override public void run() {
132 mCallsManager.markCallAsActive(callId);
133 }
134 });
135 }
136
137 /** {@inheritDoc} */
138 @Override public void setRinging(final String callId) {
139 checkValidCallId(callId);
140 mHandler.post(new Runnable() {
141 @Override public void run() {
142 mCallsManager.markCallAsRinging(callId);
143 }
144 });
145 }
146
147 /** {@inheritDoc} */
148 @Override public void setDialing(final String callId) {
149 checkValidCallId(callId);
150 mHandler.post(new Runnable() {
151 @Override public void run() {
152 mCallsManager.markCallAsDialing(callId);
153 }
154 });
155 }
156
157 /** {@inheritDoc} */
Ben Gilad28e8ad62014-03-06 17:01:54 -0800158 // TODO(gilad): Ensure that any communication from the underlying ICallService
159 // implementation is expected (or otherwise suppressed at the adapter level).
Santos Cordon681663d2014-01-30 04:32:15 -0800160 @Override public void setDisconnected(final String callId) {
161 checkValidCallId(callId);
162 mHandler.post(new Runnable() {
163 @Override public void run() {
164 mCallsManager.markCallAsDisconnected(callId);
165 }
166 });
167 }
168
169 /**
Ben Gilad28e8ad62014-03-06 17:01:54 -0800170 * Adds the specified call ID to the list of pending outgoing call IDs.
171 * TODO(gilad): Consider passing the call processor (instead of the ID) both here and in the
172 * remove case (same for incoming) such that the detour via the *CallsManager can be avoided.
173 *
174 * @param callId The ID of the call.
175 */
176 void addPendingOutgoingCallId(String callId) {
177 mPendingOutgoingCallIds.add(callId);
178 }
179
180 /**
181 * Removes the specified call ID from the list of pending outgoing call IDs.
182 *
183 * @param callId The ID of the call.
184 */
185 void removePendingOutgoingCallId(String callId) {
186 mPendingOutgoingCallIds.remove(callId);
187 }
188
189 /**
Santos Cordon61d0f702014-02-19 02:52:23 -0800190 * Adds a call ID to the list of pending incoming call IDs. Only calls with call IDs in the
191 * list will be handled by {@link #handleIncomingCall}.
Santos Cordon7917d382014-02-14 02:31:18 -0800192 *
193 * @param callId The ID of the call.
194 */
Santos Cordon61d0f702014-02-19 02:52:23 -0800195 void addPendingIncomingCallId(String callId) {
196 mPendingIncomingCallIds.add(callId);
Santos Cordon7917d382014-02-14 02:31:18 -0800197 }
198
199 /**
Ben Gilad28e8ad62014-03-06 17:01:54 -0800200 * Removes the specified call ID from the list of pending incoming call IDs.
Santos Cordon7917d382014-02-14 02:31:18 -0800201 *
202 * @param callId The ID of the call.
203 */
Santos Cordon61d0f702014-02-19 02:52:23 -0800204 void removePendingIncomingCallId(String callId) {
205 mPendingIncomingCallIds.remove(callId);
Santos Cordon7917d382014-02-14 02:31:18 -0800206 }
207
208 /**
Santos Cordon681663d2014-01-30 04:32:15 -0800209 * Throws an IllegalArgumentException if the specified call ID is invalid.
210 *
211 * @param callId The call ID to check.
212 */
213 private void checkValidCallId(String callId) {
214 if (Strings.isNullOrEmpty(callId)) {
Santos Cordon7917d382014-02-14 02:31:18 -0800215 throw new IllegalArgumentException("Invalid call ID.");
Santos Cordon681663d2014-01-30 04:32:15 -0800216 }
217 }
Ben Gilad9f2bed32013-12-12 17:43:26 -0800218}