blob: ab980e8259e722cd5494788b5ea941fa2b1774d9 [file] [log] [blame]
Santos Cordon52d8a152014-06-17 19:08:45 -07001/*
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
17package android.telecomm;
18
Sailesh Nepal2ab88cc2014-07-18 14:49:18 -070019import android.app.PendingIntent;
Santos Cordon52d8a152014-06-17 19:08:45 -070020import android.net.Uri;
Santos Cordon52d8a152014-06-17 19:08:45 -070021import android.os.RemoteException;
22import android.telephony.DisconnectCause;
23
Sailesh Nepal2a46b902014-07-04 17:21:07 -070024import com.android.internal.telecomm.IConnectionService;
Santos Cordon52d8a152014-06-17 19:08:45 -070025
26import java.util.HashSet;
27import java.util.Set;
28
29/**
30 * RemoteConnection object used by RemoteConnectionService.
31 */
32public final class RemoteConnection {
Evan Charltonbf11f982014-07-20 22:06:28 -070033 public static abstract class Listener {
34 public void onStateChanged(RemoteConnection connection, int state) {}
35 public void onDisconnected(RemoteConnection connection, int cause, String message) {}
36 public void onRequestingRingback(RemoteConnection connection, boolean ringback) {}
37 public void onCallCapabilitiesChanged(RemoteConnection connection, int callCapabilities) {}
38 public void onPostDialWait(RemoteConnection connection, String remainingDigits) {}
39 public void onAudioModeIsVoipChanged(RemoteConnection connection, boolean isVoip) {}
40 public void onStatusHintsChanged(RemoteConnection connection, StatusHints statusHints) {}
41 public void onHandleChanged(RemoteConnection connection, Uri handle, int presentation) {}
42 public void onCallerDisplayNameChanged(
43 RemoteConnection connection, String callerDisplayName, int presentation) {}
44 public void onVideoStateChanged(RemoteConnection connection, int videoState) {}
45 public void onStartActivityFromInCall(RemoteConnection connection, PendingIntent intent) {}
46 public void onDestroyed(RemoteConnection connection) {}
Santos Cordon52d8a152014-06-17 19:08:45 -070047 }
48
Evan Charltonbf11f982014-07-20 22:06:28 -070049 private IConnectionService mConnectionService;
Santos Cordon52d8a152014-06-17 19:08:45 -070050 private final String mConnectionId;
51 private final Set<Listener> mListeners = new HashSet<>();
52
Sailesh Nepalade3f252014-07-01 17:25:37 -070053 private int mState = Connection.State.NEW;
Santos Cordon52d8a152014-06-17 19:08:45 -070054 private int mDisconnectCause = DisconnectCause.NOT_VALID;
55 private String mDisconnectMessage;
56 private boolean mRequestingRingback;
57 private boolean mConnected;
Sailesh Nepal1a7061b2014-07-09 21:03:20 -070058 private int mCallCapabilities;
Tyler Gunnaa07df82014-07-17 07:50:22 -070059 private int mVideoState;
Sailesh Nepal33aaae42014-07-07 22:49:44 -070060 private boolean mAudioModeIsVoip;
Sailesh Nepale7ef59a2014-07-08 21:48:22 -070061 private StatusHints mStatusHints;
Sailesh Nepal61203862014-07-11 14:50:13 -070062 private Uri mHandle;
63 private int mHandlePresentation;
64 private String mCallerDisplayName;
65 private int mCallerDisplayNamePresentation;
Evan Charltonbf11f982014-07-20 22:06:28 -070066 private int mFailureCode;
67 private String mFailureMessage;
Santos Cordon52d8a152014-06-17 19:08:45 -070068
69 /**
70 * @hide
71 */
Evan Charltonbf11f982014-07-20 22:06:28 -070072 RemoteConnection(IConnectionService connectionService, ConnectionRequest request,
73 boolean isIncoming) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -070074 mConnectionService = connectionService;
Evan Charltonbf11f982014-07-20 22:06:28 -070075 mConnectionId = request.getCallId();
Santos Cordon52d8a152014-06-17 19:08:45 -070076
77 mConnected = true;
Evan Charltonbf11f982014-07-20 22:06:28 -070078 mState = Connection.State.INITIALIZING;
79 }
80
81 /**
82 * Create a RemoteConnection which is used for failed connections. Note that using it for any
83 * "real" purpose will almost certainly fail. Callers should note the failure and act
84 * accordingly (moving on to another RemoteConnection, for example)
85 *
86 * @param failureCode
87 * @param failureMessage
88 */
89 private RemoteConnection(int failureCode, String failureMessage) {
90 this(null, null, true);
91 mConnected = false;
92 mState = Connection.State.FAILED;
93 mFailureCode = failureCode;
94 mFailureMessage = failureMessage;
Santos Cordon52d8a152014-06-17 19:08:45 -070095 }
96
97 public void addListener(Listener listener) {
98 mListeners.add(listener);
99 }
100
101 public void removeListener(Listener listener) {
102 mListeners.remove(listener);
103 }
104
Sailesh Nepalade3f252014-07-01 17:25:37 -0700105 public int getState() {
106 return mState;
107 }
108
Santos Cordon52d8a152014-06-17 19:08:45 -0700109 public int getDisconnectCause() {
110 return mDisconnectCause;
111 }
112
113 public String getDisconnectMessage() {
114 return mDisconnectMessage;
115 }
116
Sailesh Nepal1a7061b2014-07-09 21:03:20 -0700117 public int getCallCapabilities() {
118 return mCallCapabilities;
119 }
120
Sailesh Nepal33aaae42014-07-07 22:49:44 -0700121 public boolean getAudioModeIsVoip() {
122 return mAudioModeIsVoip;
123 }
124
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700125 public StatusHints getStatusHints() {
126 return mStatusHints;
127 }
128
Sailesh Nepal61203862014-07-11 14:50:13 -0700129 public Uri getHandle() {
130 return mHandle;
131 }
132
133 public int getHandlePresentation() {
134 return mHandlePresentation;
135 }
136
137 public String getCallerDisplayName() {
138 return mCallerDisplayName;
139 }
140
141 public int getCallerDisplayNamePresentation() {
142 return mCallerDisplayNamePresentation;
143 }
144
Tyler Gunnaa07df82014-07-17 07:50:22 -0700145 public int getVideoState() {
146 return mVideoState;
147 }
148
Evan Charltonbf11f982014-07-20 22:06:28 -0700149 public int getFailureCode() {
150 return mFailureCode;
151 }
152
153 public String getFailureMessage() {
154 return mFailureMessage;
155 }
156
Sailesh Nepal091768c2014-06-30 15:15:23 -0700157 public void abort() {
158 try {
159 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700160 mConnectionService.abort(mConnectionId);
Sailesh Nepal091768c2014-06-30 15:15:23 -0700161 }
162 } catch (RemoteException ignored) {
163 }
164 }
165
Andrew Lee8da4c3c2014-07-16 10:11:42 -0700166 public void answer(int videoState) {
Santos Cordon52d8a152014-06-17 19:08:45 -0700167 try {
168 if (mConnected) {
Andrew Lee8da4c3c2014-07-16 10:11:42 -0700169 mConnectionService.answer(mConnectionId, videoState);
Santos Cordon52d8a152014-06-17 19:08:45 -0700170 }
171 } catch (RemoteException ignored) {
172 }
173 }
174
175 public void reject() {
176 try {
177 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700178 mConnectionService.reject(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700179 }
180 } catch (RemoteException ignored) {
181 }
182 }
183
184 public void hold() {
185 try {
186 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700187 mConnectionService.hold(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700188 }
189 } catch (RemoteException ignored) {
190 }
191 }
192
193 public void unhold() {
194 try {
195 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700196 mConnectionService.unhold(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700197 }
198 } catch (RemoteException ignored) {
199 }
200 }
201
202 public void disconnect() {
203 try {
204 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700205 mConnectionService.disconnect(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700206 }
207 } catch (RemoteException ignored) {
208 }
209 }
210
211 public void playDtmf(char digit) {
212 try {
213 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700214 mConnectionService.playDtmfTone(mConnectionId, digit);
Santos Cordon52d8a152014-06-17 19:08:45 -0700215 }
216 } catch (RemoteException ignored) {
217 }
218 }
219
220 public void stopDtmf() {
221 try {
222 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700223 mConnectionService.stopDtmfTone(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700224 }
225 } catch (RemoteException ignored) {
226 }
227 }
228
229 public void postDialContinue(boolean proceed) {
230 try {
231 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700232 mConnectionService.onPostDialContinue(mConnectionId, proceed);
Santos Cordon52d8a152014-06-17 19:08:45 -0700233 }
234 } catch (RemoteException ignored) {
235 }
236 }
237
Sailesh Nepal61203862014-07-11 14:50:13 -0700238 public void swapWithBackgroundCall() {
239 try {
240 if (mConnected) {
241 mConnectionService.swapWithBackgroundCall(mConnectionId);
242 }
243 } catch (RemoteException ignored) {
244 }
245 }
246
Sailesh Nepal091768c2014-06-30 15:15:23 -0700247 public void setAudioState(CallAudioState state) {
248 try {
249 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700250 mConnectionService.onAudioStateChanged(mConnectionId, state);
Sailesh Nepal091768c2014-06-30 15:15:23 -0700251 }
252 } catch (RemoteException ignored) {
253 }
254 }
255
Santos Cordon52d8a152014-06-17 19:08:45 -0700256 /**
257 * @hide
258 */
259 void setState(int state) {
260 if (mState != state) {
261 mState = state;
262 for (Listener l: mListeners) {
263 l.onStateChanged(this, state);
264 }
265 }
266 }
267
268 /**
269 * @hide
270 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700271 void setDisconnected(int cause, String message) {
272 if (mState != Connection.State.DISCONNECTED) {
273 mState = Connection.State.DISCONNECTED;
274 mDisconnectCause = cause;
275 mDisconnectMessage = message;
276
277 for (Listener l : mListeners) {
278 l.onDisconnected(this, cause, message);
279 }
280 }
281 }
282
283 /**
284 * @hide
285 */
286 void setRequestingRingback(boolean ringback) {
287 if (mRequestingRingback != ringback) {
288 mRequestingRingback = ringback;
289 for (Listener l : mListeners) {
290 l.onRequestingRingback(this, ringback);
291 }
292 }
293 }
294
295 /**
296 * @hide
297 */
Sailesh Nepal1a7061b2014-07-09 21:03:20 -0700298 void setCallCapabilities(int callCapabilities) {
299 mCallCapabilities = callCapabilities;
300 for (Listener l : mListeners) {
301 l.onCallCapabilitiesChanged(this, callCapabilities);
302 }
303 }
304
305 /**
306 * @hide
307 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700308 void setDestroyed() {
309 if (!mListeners.isEmpty()) {
310 // Make sure that the listeners are notified that the call is destroyed first.
311 if (mState != Connection.State.DISCONNECTED) {
312 setDisconnected(DisconnectCause.ERROR_UNSPECIFIED, "Connection destroyed.");
313 }
314
315 Set<Listener> listeners = new HashSet<Listener>(mListeners);
316 mListeners.clear();
317 for (Listener l : listeners) {
318 l.onDestroyed(this);
319 }
320
321 mConnected = false;
322 }
323 }
324
325 /**
326 * @hide
327 */
328 void setPostDialWait(String remainingDigits) {
329 for (Listener l : mListeners) {
330 l.onPostDialWait(this, remainingDigits);
331 }
332 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700333
Tyler Gunnaa07df82014-07-17 07:50:22 -0700334 /**
335 * @hide
336 */
337 void setVideoState(int videoState) {
338 mVideoState = videoState;
339 for (Listener l : mListeners) {
340 l.onVideoStateChanged(this, videoState);
341 }
342 }
343
Sailesh Nepal33aaae42014-07-07 22:49:44 -0700344 /** @hide */
345 void setAudioModeIsVoip(boolean isVoip) {
346 mAudioModeIsVoip = isVoip;
347 for (Listener l : mListeners) {
Sailesh Nepal61203862014-07-11 14:50:13 -0700348 l.onAudioModeIsVoipChanged(this, isVoip);
Sailesh Nepal33aaae42014-07-07 22:49:44 -0700349 }
350 }
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700351
352 /** @hide */
353 void setStatusHints(StatusHints statusHints) {
354 mStatusHints = statusHints;
355 for (Listener l : mListeners) {
Sailesh Nepal61203862014-07-11 14:50:13 -0700356 l.onStatusHintsChanged(this, statusHints);
357 }
358 }
359
360 /** @hide */
361 void setHandle(Uri handle, int presentation) {
362 mHandle = handle;
363 mHandlePresentation = presentation;
364 for (Listener l : mListeners) {
365 l.onHandleChanged(this, handle, presentation);
366 }
367 }
368
369 /** @hide */
370 void setCallerDisplayName(String callerDisplayName, int presentation) {
371 mCallerDisplayName = callerDisplayName;
372 mCallerDisplayNamePresentation = presentation;
373 for (Listener l : mListeners) {
374 l.onCallerDisplayNameChanged(this, callerDisplayName, presentation);
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700375 }
376 }
Sailesh Nepal2ab88cc2014-07-18 14:49:18 -0700377
378 /** @hide */
379 void startActivityFromInCall(PendingIntent intent) {
380 for (Listener l : mListeners) {
381 l.onStartActivityFromInCall(this, intent);
382 }
383 }
Evan Charltonbf11f982014-07-20 22:06:28 -0700384
385 /** @hide */
386 void setConnectionService(IConnectionService connectionService) {
387 mConnectionService = connectionService;
388 mConnectionService = null;
389 setState(Connection.State.NEW);
390 }
391
392 /**
393 * Create a RemoteConnection which is in the {@link Connection.State#FAILED} state. Attempting
394 * to use it for anything will almost certainly result in bad things happening. Do not do this.
395 *
396 * @return a failed {@link RemoteConnection}
397 *
398 * @hide
399 *
400 */
401 public static RemoteConnection failure(int failureCode, String failureMessage) {
402 return new RemoteConnection(failureCode, failureMessage);
403 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700404}