blob: 1a955ce07e3302116943537252481c523023fbae [file] [log] [blame]
Santos Cordon681663d2014-01-30 04:32:15 -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
Sailesh Nepala439e1b2014-03-11 18:19:58 -070019import com.android.internal.telecomm.ICallServiceSelector;
Santos Cordon681663d2014-01-30 04:32:15 -080020import com.google.common.collect.Maps;
21
Sailesh Nepal18386a82014-03-19 10:22:40 -070022import java.util.Collection;
Santos Cordon681663d2014-01-30 04:32:15 -080023import java.util.Map;
24import java.util.Set;
25
26/**
27 * Responsible for placing all outgoing calls. For each outgoing call, this class creates an
28 * instance of {@link OutgoingCallProcessor} which handles the details of connecting to the
Sailesh Nepale59bb192014-04-01 18:33:59 -070029 * appropriate call service and placing the call. This class maintains a mapping from call
Santos Cordon681663d2014-01-30 04:32:15 -080030 * to {@link OutgoingCallProcessor} so that other classes (Switchboard, CallServiceAdapter, etc),
31 * can simply call into this class instead of individual OutgoingCallProcessors.
32 */
33final class OutgoingCallsManager {
Santos Cordon681663d2014-01-30 04:32:15 -080034 private final Switchboard mSwitchboard;
35
36 /**
Sailesh Nepale59bb192014-04-01 18:33:59 -070037 * Maps call to {@link OutgoingCallProcessor}s.
Santos Cordon681663d2014-01-30 04:32:15 -080038 */
Sailesh Nepale59bb192014-04-01 18:33:59 -070039 private Map<Call, OutgoingCallProcessor> mOutgoingCallProcessors = Maps.newHashMap();
Santos Cordon681663d2014-01-30 04:32:15 -080040
41 /** Persists specified parameters. */
42 OutgoingCallsManager(Switchboard switchboard) {
43 mSwitchboard = switchboard;
44 }
45
46 /**
47 * Starts the process of placing a call by constructing an outgoing call processor and asking
48 * it to place the call. Upon success, execution will continue (via {@link CallServiceAdapter})
Ben Gilad13329fd2014-02-11 17:20:29 -080049 * to {@link #handleSuccessfulCallAttempt}. Upon failure, execution will return to
50 * {@link #handleFailedCallAttempt}.
Santos Cordon681663d2014-01-30 04:32:15 -080051 *
52 * @param call The call to place.
53 * @param callServices The set of call services which can potentially place the call.
54 * @param selectors The ordered list of selectors used in placing the call.
55 */
56 void placeCall(
Sailesh Nepal18386a82014-03-19 10:22:40 -070057 Call call,
58 Set<CallServiceWrapper> callServices,
59 Collection<CallServiceSelectorWrapper> selectors) {
Santos Cordon681663d2014-01-30 04:32:15 -080060
Sailesh Nepale59bb192014-04-01 18:33:59 -070061 Log.i(this, "Placing an outgoing call: %s", call);
Santos Cordon681663d2014-01-30 04:32:15 -080062
63 // Create the processor for this (outgoing) call and store it in a map such that call
64 // attempts can be aborted etc.
65 // TODO(gilad): Consider passing mSelector as an immutable set.
66 OutgoingCallProcessor processor =
67 new OutgoingCallProcessor(call, callServices, selectors, this, mSwitchboard);
68
Sailesh Nepale59bb192014-04-01 18:33:59 -070069 mOutgoingCallProcessors.put(call, processor);
Santos Cordon681663d2014-01-30 04:32:15 -080070 processor.process();
71 }
72
73 /**
Sailesh Nepale59bb192014-04-01 18:33:59 -070074 * Forwards the compatibility status from the call-service to the corresponding outgoing-call
75 * processor.
Ben Gilad61925612014-03-11 19:06:36 -070076 *
Sailesh Nepale59bb192014-04-01 18:33:59 -070077 * @param isCompatible True if the call-service is compatible with the call.
Ben Gilad61925612014-03-11 19:06:36 -070078 */
Sailesh Nepale59bb192014-04-01 18:33:59 -070079 void setIsCompatibleWith(Call call, boolean isCompatible) {
80 Log.v(this, "setIsCompatibleWith, call %s, isCompatible: %b", call, isCompatible);
81 OutgoingCallProcessor processor = mOutgoingCallProcessors.get(call);
Ben Gilad61925612014-03-11 19:06:36 -070082 if (processor == null) {
83 // Shouldn't happen, so log a wtf if it does.
84 Log.wtf(this, "Received unexpected setCompatibleWith notification.");
85 } else {
Sailesh Nepale59bb192014-04-01 18:33:59 -070086 processor.setIsCompatibleWith(call, isCompatible);
Ben Gilad61925612014-03-11 19:06:36 -070087 }
88 }
89
90 /**
Santos Cordon681663d2014-01-30 04:32:15 -080091 * Removes the outgoing call processor mapping for the successful call and returns execution to
92 * the switchboard. This method is invoked from {@link CallServiceAdapter} after a call service
93 * has notified Telecomm that it successfully placed the call.
Santos Cordon681663d2014-01-30 04:32:15 -080094 */
Sailesh Nepale59bb192014-04-01 18:33:59 -070095 void handleSuccessfulCallAttempt(Call call) {
96 Log.v(this, "handleSuccessfulCallAttempt, call: %s", call);
97 OutgoingCallProcessor processor = mOutgoingCallProcessors.remove(call);
Santos Cordon681663d2014-01-30 04:32:15 -080098
99 if (processor == null) {
100 // Shouldn't happen, so log a wtf if it does.
Sailesh Nepalf1c191d2014-03-07 18:17:39 -0800101 Log.wtf(this, "Received an unexpected placed-call notification.");
Santos Cordon681663d2014-01-30 04:32:15 -0800102 } else {
103 processor.handleSuccessfulCallAttempt();
104 }
105 }
106
107 /**
108 * Notifies the appropriate outgoing call processor that a call attempt to place the call has
109 * failed and the processor should continue attempting to place the call with the next call
110 * service. This method is called from {@link CallServiceAdapter} after a call service has
111 * notified Telecomm that it could not place the call.
112 *
Santos Cordon681663d2014-01-30 04:32:15 -0800113 * @param reason The call-service supplied reason for the failed call attempt.
114 */
Sailesh Nepale59bb192014-04-01 18:33:59 -0700115 void handleFailedCallAttempt(Call call, String reason) {
116 Log.v(this, "handleFailedCallAttempt, call: %s, reason: %s", call, reason);
117 OutgoingCallProcessor processor = mOutgoingCallProcessors.get(call);
Santos Cordon681663d2014-01-30 04:32:15 -0800118
Santos Cordon681663d2014-01-30 04:32:15 -0800119 if (processor == null) {
120 // Shouldn't happen, so log a wtf if it does.
Sailesh Nepalf1c191d2014-03-07 18:17:39 -0800121 Log.wtf(this, "Received an unexpected failed-call notification.");
Santos Cordon681663d2014-01-30 04:32:15 -0800122 } else {
123 processor.handleFailedCallAttempt(reason);
124 }
125 }
126
127 /**
128 * Removes the outgoing call processor mapping for the failed call and returns execution to the
129 * switchboard. In contrast to handleFailedCallAttempt which comes from the call-service and
130 * goes to the outgoing-call processor indicating a single failed call attempt, this method is
131 * invoked by the outgoing-call processor to indicate that the entire process has failed and we
132 * should cleanup and notify Switchboard.
133 *
134 * @param call The failed outgoing call.
Sailesh Nepal810735e2014-03-18 18:15:46 -0700135 * @param isAborted True if the call timedout and is aborted.
Santos Cordon681663d2014-01-30 04:32:15 -0800136 */
Sailesh Nepal810735e2014-03-18 18:15:46 -0700137 void handleFailedOutgoingCall(Call call, boolean isAborted) {
138 Log.v(this, "handleFailedOutgoingCall, call: %s", call);
Sailesh Nepale59bb192014-04-01 18:33:59 -0700139 mOutgoingCallProcessors.remove(call);
Sailesh Nepal810735e2014-03-18 18:15:46 -0700140 mSwitchboard.handleFailedOutgoingCall(call, isAborted);
Santos Cordon681663d2014-01-30 04:32:15 -0800141 }
Ben Gilad8e55d1d2014-02-26 16:25:56 -0800142
143 /**
144 * Aborts any ongoing attempts to connect the specified (outgoing) call.
145 *
146 * @param call The call to be aborted.
147 */
148 void abort(Call call) {
Sailesh Nepal810735e2014-03-18 18:15:46 -0700149 Log.v(this, "abort, call: %s", call);
Sailesh Nepale59bb192014-04-01 18:33:59 -0700150 OutgoingCallProcessor processor = mOutgoingCallProcessors.remove(call);
Ben Gilad8e55d1d2014-02-26 16:25:56 -0800151 if (processor != null) {
152 processor.abort();
153 }
154 }
Santos Cordon681663d2014-01-30 04:32:15 -0800155}