blob: 673515af6a96a852e8d184f0c238ccbec532fd98 [file] [log] [blame]
Sailesh Nepalab5d2822014-03-08 18:01:06 -08001/*
2 * Copyright (C) 2013 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
Tyler Gunnef9f6f92014-09-12 22:16:17 -070017package android.telecom;
Sailesh Nepalab5d2822014-03-08 18:01:06 -080018
Tyler Gunn2ac40102014-08-18 16:23:10 -070019import android.annotation.SdkConstant;
Santos Cordon2f42b112014-07-19 13:19:37 -070020import android.app.Service;
21import android.content.Intent;
Sailesh Nepalab5d2822014-03-08 18:01:06 -080022import android.os.Handler;
23import android.os.IBinder;
24import android.os.Looper;
25import android.os.Message;
Andrew Lee50aca232014-07-22 16:41:54 -070026import android.view.Surface;
Sailesh Nepalab5d2822014-03-08 18:01:06 -080027
Ihab Awad2f236642014-03-10 15:33:45 -070028import com.android.internal.os.SomeArgs;
Tyler Gunnef9f6f92014-09-12 22:16:17 -070029import com.android.internal.telecom.IInCallAdapter;
30import com.android.internal.telecom.IInCallService;
Sailesh Nepalab5d2822014-03-08 18:01:06 -080031
Andrew Lee50aca232014-07-22 16:41:54 -070032import java.lang.String;
33
Sailesh Nepalab5d2822014-03-08 18:01:06 -080034/**
35 * This service is implemented by any app that wishes to provide the user-interface for managing
Tyler Gunnef9f6f92014-09-12 22:16:17 -070036 * phone calls. Telecom binds to this service while there exists a live (active or incoming) call,
Santos Cordon2f42b112014-07-19 13:19:37 -070037 * and uses it to notify the in-call app of any live and and recently disconnected calls.
Sailesh Nepalab5d2822014-03-08 18:01:06 -080038 */
Santos Cordon2f42b112014-07-19 13:19:37 -070039public abstract class InCallService extends Service {
Tyler Gunn2ac40102014-08-18 16:23:10 -070040
41 /**
42 * The {@link Intent} that must be declared as handled by the service.
43 */
44 @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
Tyler Gunnef9f6f92014-09-12 22:16:17 -070045 public static final String SERVICE_INTERFACE = "android.telecom.InCallService";
Tyler Gunn2ac40102014-08-18 16:23:10 -070046
Sailesh Nepalab5d2822014-03-08 18:01:06 -080047 private static final int MSG_SET_IN_CALL_ADAPTER = 1;
48 private static final int MSG_ADD_CALL = 2;
Sailesh Nepal60437932014-04-05 16:44:55 -070049 private static final int MSG_UPDATE_CALL = 3;
Ihab Awad5d0410f2014-07-30 10:07:40 -070050 private static final int MSG_SET_POST_DIAL_WAIT = 4;
51 private static final int MSG_ON_AUDIO_STATE_CHANGED = 5;
52 private static final int MSG_BRING_TO_FOREGROUND = 6;
Santos Cordon6c912b72014-11-07 16:05:09 -080053 private static final int MSG_ON_CAN_ADD_CALL_CHANGED = 7;
Sailesh Nepalab5d2822014-03-08 18:01:06 -080054
55 /** Default Handler used to consolidate binder method calls onto a single thread. */
56 private final Handler mHandler = new Handler(Looper.getMainLooper()) {
57 @Override
58 public void handleMessage(Message msg) {
Jay Shrauner5e6162d2014-09-22 20:47:45 -070059 if (mPhone == null && msg.what != MSG_SET_IN_CALL_ADAPTER) {
60 return;
61 }
62
Sailesh Nepalab5d2822014-03-08 18:01:06 -080063 switch (msg.what) {
64 case MSG_SET_IN_CALL_ADAPTER:
Ihab Awade63fadb2014-07-09 21:52:04 -070065 mPhone = new Phone(new InCallAdapter((IInCallAdapter) msg.obj));
66 onPhoneCreated(mPhone);
Sailesh Nepalab5d2822014-03-08 18:01:06 -080067 break;
68 case MSG_ADD_CALL:
Santos Cordon88b771d2014-07-19 13:10:40 -070069 mPhone.internalAddCall((ParcelableCall) msg.obj);
Sailesh Nepalab5d2822014-03-08 18:01:06 -080070 break;
Sailesh Nepal60437932014-04-05 16:44:55 -070071 case MSG_UPDATE_CALL:
Santos Cordon88b771d2014-07-19 13:10:40 -070072 mPhone.internalUpdateCall((ParcelableCall) msg.obj);
Ihab Awad2f236642014-03-10 15:33:45 -070073 break;
Ihab Awad2f236642014-03-10 15:33:45 -070074 case MSG_SET_POST_DIAL_WAIT: {
75 SomeArgs args = (SomeArgs) msg.obj;
76 try {
77 String callId = (String) args.arg1;
78 String remaining = (String) args.arg2;
Ihab Awade63fadb2014-07-09 21:52:04 -070079 mPhone.internalSetPostDialWait(callId, remaining);
Ihab Awad2f236642014-03-10 15:33:45 -070080 } finally {
81 args.recycle();
82 }
83 break;
84 }
Sailesh Nepal4cff3922014-03-19 10:15:37 -070085 case MSG_ON_AUDIO_STATE_CHANGED:
Ihab Awadb19a0bc2014-08-07 19:46:01 -070086 mPhone.internalAudioStateChanged((AudioState) msg.obj);
Sailesh Nepalb632e5b2014-04-03 12:54:33 -070087 break;
Santos Cordon3534ede2014-05-29 13:07:10 -070088 case MSG_BRING_TO_FOREGROUND:
Ihab Awade63fadb2014-07-09 21:52:04 -070089 mPhone.internalBringToForeground(msg.arg1 == 1);
Santos Cordon3534ede2014-05-29 13:07:10 -070090 break;
Santos Cordon6c912b72014-11-07 16:05:09 -080091 case MSG_ON_CAN_ADD_CALL_CHANGED:
92 mPhone.internalSetCanAddCall(msg.arg1 == 1);
93 break;
Sailesh Nepalab5d2822014-03-08 18:01:06 -080094 default:
95 break;
96 }
97 }
98 };
99
100 /** Manages the binder calls so that the implementor does not need to deal with it. */
101 private final class InCallServiceBinder extends IInCallService.Stub {
Sailesh Nepalab5d2822014-03-08 18:01:06 -0800102 @Override
103 public void setInCallAdapter(IInCallAdapter inCallAdapter) {
104 mHandler.obtainMessage(MSG_SET_IN_CALL_ADAPTER, inCallAdapter).sendToTarget();
105 }
106
Sailesh Nepalab5d2822014-03-08 18:01:06 -0800107 @Override
Santos Cordon88b771d2014-07-19 13:10:40 -0700108 public void addCall(ParcelableCall call) {
Sailesh Nepal60437932014-04-05 16:44:55 -0700109 mHandler.obtainMessage(MSG_ADD_CALL, call).sendToTarget();
Sailesh Nepalab5d2822014-03-08 18:01:06 -0800110 }
111
Sailesh Nepalab5d2822014-03-08 18:01:06 -0800112 @Override
Santos Cordon88b771d2014-07-19 13:10:40 -0700113 public void updateCall(ParcelableCall call) {
Sailesh Nepal60437932014-04-05 16:44:55 -0700114 mHandler.obtainMessage(MSG_UPDATE_CALL, call).sendToTarget();
Ihab Awad2f236642014-03-10 15:33:45 -0700115 }
116
117 @Override
118 public void setPostDial(String callId, String remaining) {
Ihab Awad5d0410f2014-07-30 10:07:40 -0700119 // TODO: Unused
Ihab Awad2f236642014-03-10 15:33:45 -0700120 }
121
122 @Override
123 public void setPostDialWait(String callId, String remaining) {
124 SomeArgs args = SomeArgs.obtain();
125 args.arg1 = callId;
126 args.arg2 = remaining;
127 mHandler.obtainMessage(MSG_SET_POST_DIAL_WAIT, args).sendToTarget();
128 }
Sailesh Nepalb632e5b2014-04-03 12:54:33 -0700129
130 @Override
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700131 public void onAudioStateChanged(AudioState audioState) {
Sailesh Nepal60437932014-04-05 16:44:55 -0700132 mHandler.obtainMessage(MSG_ON_AUDIO_STATE_CHANGED, audioState).sendToTarget();
Sailesh Nepalb632e5b2014-04-03 12:54:33 -0700133 }
Santos Cordon3534ede2014-05-29 13:07:10 -0700134
Santos Cordon3534ede2014-05-29 13:07:10 -0700135 @Override
136 public void bringToForeground(boolean showDialpad) {
137 mHandler.obtainMessage(MSG_BRING_TO_FOREGROUND, showDialpad ? 1 : 0, 0).sendToTarget();
138 }
Santos Cordon6c912b72014-11-07 16:05:09 -0800139
140 @Override
141 public void onCanAddCallChanged(boolean canAddCall) {
142 mHandler.obtainMessage(MSG_ON_CAN_ADD_CALL_CHANGED, canAddCall ? 1 : 0, 0)
143 .sendToTarget();
144 }
Sailesh Nepalab5d2822014-03-08 18:01:06 -0800145 }
146
Ihab Awade63fadb2014-07-09 21:52:04 -0700147 private Phone mPhone;
Sailesh Nepalab5d2822014-03-08 18:01:06 -0800148
Santos Cordon2f42b112014-07-19 13:19:37 -0700149 public InCallService() {
150 }
Evan Charlton924748f2014-04-03 08:36:38 -0700151
Santos Cordon2f42b112014-07-19 13:19:37 -0700152 @Override
153 public IBinder onBind(Intent intent) {
Ihab Awade63fadb2014-07-09 21:52:04 -0700154 return new InCallServiceBinder();
Sailesh Nepalab5d2822014-03-08 18:01:06 -0800155 }
156
Santos Cordonf30d7e92014-08-26 09:54:33 -0700157 @Override
158 public boolean onUnbind(Intent intent) {
Santos Cordon619b3c02014-09-02 17:13:45 -0700159 if (mPhone != null) {
160 Phone oldPhone = mPhone;
161 mPhone = null;
Santos Cordonf30d7e92014-08-26 09:54:33 -0700162
Santos Cordon619b3c02014-09-02 17:13:45 -0700163 oldPhone.destroy();
164 onPhoneDestroyed(oldPhone);
165 }
Santos Cordonf30d7e92014-08-26 09:54:33 -0700166 return false;
167 }
168
Sailesh Nepalab5d2822014-03-08 18:01:06 -0800169 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700170 * Obtain the {@code Phone} associated with this {@code InCallService}.
171 *
172 * @return The {@code Phone} object associated with this {@code InCallService}, or {@code null}
Santos Cordon2f42b112014-07-19 13:19:37 -0700173 * if the {@code InCallService} is not in a state where it has an associated
174 * {@code Phone}.
Sailesh Nepalab5d2822014-03-08 18:01:06 -0800175 */
Jay Shrauner164a0ac2015-04-14 18:16:10 -0700176 public final Phone getPhone() {
Ihab Awade63fadb2014-07-09 21:52:04 -0700177 return mPhone;
Evan Charlton924748f2014-04-03 08:36:38 -0700178 }
179
180 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700181 * Invoked when the {@code Phone} has been created. This is a signal to the in-call experience
182 * to start displaying in-call information to the user. Each instance of {@code InCallService}
Santos Cordon2f42b112014-07-19 13:19:37 -0700183 * will have only one {@code Phone}, and this method will be called exactly once in the lifetime
184 * of the {@code InCallService}.
Evan Charlton924748f2014-04-03 08:36:38 -0700185 *
Ihab Awade63fadb2014-07-09 21:52:04 -0700186 * @param phone The {@code Phone} object associated with this {@code InCallService}.
Evan Charlton924748f2014-04-03 08:36:38 -0700187 */
Santos Cordon2f42b112014-07-19 13:19:37 -0700188 public void onPhoneCreated(Phone phone) {
189 }
Sailesh Nepalab5d2822014-03-08 18:01:06 -0800190
191 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700192 * Invoked when a {@code Phone} has been destroyed. This is a signal to the in-call experience
193 * to stop displaying in-call information to the user. This method will be called exactly once
194 * in the lifetime of the {@code InCallService}, and it will always be called after a previous
195 * call to {@link #onPhoneCreated(Phone)}.
Sailesh Nepalab5d2822014-03-08 18:01:06 -0800196 *
Ihab Awade63fadb2014-07-09 21:52:04 -0700197 * @param phone The {@code Phone} object associated with this {@code InCallService}.
Sailesh Nepalab5d2822014-03-08 18:01:06 -0800198 */
Santos Cordon2f42b112014-07-19 13:19:37 -0700199 public void onPhoneDestroyed(Phone phone) {
200 }
Andrew Lee50aca232014-07-22 16:41:54 -0700201
202 /**
203 * Class to invoke functionality related to video calls.
204 */
205 public static abstract class VideoCall {
206
207 /**
Andrew Leeda80c872015-04-15 14:09:50 -0700208 * Registers a callback to receive c ommands and state changes for video calls.
Andrew Lee50aca232014-07-22 16:41:54 -0700209 *
Andrew Leeda80c872015-04-15 14:09:50 -0700210 * @param callback The vdieo call callback.
Andrew Lee50aca232014-07-22 16:41:54 -0700211 */
Andrew Leeda80c872015-04-15 14:09:50 -0700212 public abstract void registerCallback(VideoCall.Callback callback);
213
214 /**
215 * @deprecated Use {@code VideoCall#registerCallback} instead.
216 */
217 @Deprecated
218 public void setVideoCallListener(VideoCall.Listener videoCallListener) {
219 registerCallback(videoCallListener);
220 }
Andrew Lee50aca232014-07-22 16:41:54 -0700221
222 /**
223 * Sets the camera to be used for video recording in a video call.
224 *
225 * @param cameraId The id of the camera.
226 */
227 public abstract void setCamera(String cameraId);
228
229 /**
230 * Sets the surface to be used for displaying a preview of what the user's camera is
231 * currently capturing. When video transmission is enabled, this is the video signal which
232 * is sent to the remote device.
233 *
234 * @param surface The surface.
235 */
236 public abstract void setPreviewSurface(Surface surface);
237
238 /**
239 * Sets the surface to be used for displaying the video received from the remote device.
240 *
241 * @param surface The surface.
242 */
243 public abstract void setDisplaySurface(Surface surface);
244
245 /**
246 * Sets the device orientation, in degrees. Assumes that a standard portrait orientation of
247 * the device is 0 degrees.
248 *
249 * @param rotation The device orientation, in degrees.
250 */
251 public abstract void setDeviceOrientation(int rotation);
252
253 /**
254 * Sets camera zoom ratio.
255 *
256 * @param value The camera zoom ratio.
257 */
258 public abstract void setZoom(float value);
259
260 /**
261 * Issues a request to modify the properties of the current session. The request is sent to
262 * the remote device where it it handled by
Andrew Leeda80c872015-04-15 14:09:50 -0700263 * {@link VideoCall.Callback#onSessionModifyRequestReceived}.
Andrew Lee50aca232014-07-22 16:41:54 -0700264 * Some examples of session modification requests: upgrade call from audio to video,
265 * downgrade call from video to audio, pause video.
266 *
267 * @param requestProfile The requested call video properties.
268 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700269 public abstract void sendSessionModifyRequest(VideoProfile requestProfile);
Andrew Lee50aca232014-07-22 16:41:54 -0700270
271 /**
272 * Provides a response to a request to change the current call session video
273 * properties.
274 * This is in response to a request the InCall UI has received via
Andrew Leeda80c872015-04-15 14:09:50 -0700275 * {@link VideoCall.Callback#onSessionModifyRequestReceived}.
Andrew Lee50aca232014-07-22 16:41:54 -0700276 * The response is handled on the remove device by
Andrew Leeda80c872015-04-15 14:09:50 -0700277 * {@link VideoCall.Callback#onSessionModifyResponseReceived}.
Andrew Lee50aca232014-07-22 16:41:54 -0700278 *
279 * @param responseProfile The response call video properties.
280 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700281 public abstract void sendSessionModifyResponse(VideoProfile responseProfile);
Andrew Lee50aca232014-07-22 16:41:54 -0700282
283 /**
284 * Issues a request to the video provider to retrieve the camera capabilities.
285 * Camera capabilities are reported back to the caller via
Andrew Leeda80c872015-04-15 14:09:50 -0700286 * {@link VideoCall.Callback#onCameraCapabilitiesChanged(CameraCapabilities)}.
Andrew Lee50aca232014-07-22 16:41:54 -0700287 */
288 public abstract void requestCameraCapabilities();
289
290 /**
291 * Issues a request to the video telephony framework to retrieve the cumulative data usage for
292 * the current call. Data usage is reported back to the caller via
Andrew Leeda80c872015-04-15 14:09:50 -0700293 * {@link VideoCall.Callback#onCallDataUsageChanged}.
Andrew Lee50aca232014-07-22 16:41:54 -0700294 */
295 public abstract void requestCallDataUsage();
296
297 /**
298 * Provides the video telephony framework with the URI of an image to be displayed to remote
299 * devices when the video signal is paused.
300 *
301 * @param uri URI of image to display.
302 */
303 public abstract void setPauseImage(String uri);
304
305 /**
Andrew Leeda80c872015-04-15 14:09:50 -0700306 * Callback class which invokes callbacks after video call actions occur.
Andrew Lee50aca232014-07-22 16:41:54 -0700307 */
Andrew Leeda80c872015-04-15 14:09:50 -0700308 public static abstract class Callback {
Andrew Lee50aca232014-07-22 16:41:54 -0700309 /**
310 * Called when a session modification request is received from the remote device.
Andrew Lee14185762014-07-25 09:41:56 -0700311 * The remote request is sent via
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700312 * {@link Connection.VideoProvider#onSendSessionModifyRequest}. The InCall UI
Andrew Lee14185762014-07-25 09:41:56 -0700313 * is responsible for potentially prompting the user whether they wish to accept the new
314 * call profile (e.g. prompt user if they wish to accept an upgrade from an audio to a
315 * video call) and should call
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700316 * {@link Connection.VideoProvider#onSendSessionModifyResponse} to indicate
Andrew Lee14185762014-07-25 09:41:56 -0700317 * the video settings the user has agreed to.
Andrew Lee50aca232014-07-22 16:41:54 -0700318 *
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700319 * @param videoProfile The requested video call profile.
Andrew Lee50aca232014-07-22 16:41:54 -0700320 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700321 public abstract void onSessionModifyRequestReceived(VideoProfile videoProfile);
Andrew Lee50aca232014-07-22 16:41:54 -0700322
323 /**
324 * Called when a response to a session modification request is received from the remote
325 * device. The remote InCall UI sends the response using
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700326 * {@link Connection.VideoProvider#onSendSessionModifyResponse}.
Andrew Lee50aca232014-07-22 16:41:54 -0700327 *
328 * @param status Status of the session modify request. Valid values are
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700329 * {@link Connection.VideoProvider#SESSION_MODIFY_REQUEST_SUCCESS},
330 * {@link Connection.VideoProvider#SESSION_MODIFY_REQUEST_FAIL},
331 * {@link Connection.VideoProvider#SESSION_MODIFY_REQUEST_INVALID}
Andrew Lee50aca232014-07-22 16:41:54 -0700332 * @param requestedProfile The original request which was sent to the remote device.
333 * @param responseProfile The actual profile changes made by the remote device.
334 */
335 public abstract void onSessionModifyResponseReceived(int status,
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700336 VideoProfile requestedProfile, VideoProfile responseProfile);
Andrew Lee50aca232014-07-22 16:41:54 -0700337
338 /**
339 * Handles events related to the current session which the client may wish to handle.
340 * These are separate from requested changes to the session due to the underlying
341 * protocol or connection.
342 *
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700343 * Valid values are:
344 * {@link Connection.VideoProvider#SESSION_EVENT_RX_PAUSE},
345 * {@link Connection.VideoProvider#SESSION_EVENT_RX_RESUME},
346 * {@link Connection.VideoProvider#SESSION_EVENT_TX_START},
347 * {@link Connection.VideoProvider#SESSION_EVENT_TX_STOP},
348 * {@link Connection.VideoProvider#SESSION_EVENT_CAMERA_FAILURE},
349 * {@link Connection.VideoProvider#SESSION_EVENT_CAMERA_READY}
Andrew Lee50aca232014-07-22 16:41:54 -0700350 *
351 * @param event The event.
352 */
353 public abstract void onCallSessionEvent(int event);
354
355 /**
356 * Handles a change to the video dimensions from the remote caller (peer). This could
357 * happen if, for example, the peer changes orientation of their device.
358 *
359 * @param width The updated peer video width.
360 * @param height The updated peer video height.
361 */
362 public abstract void onPeerDimensionsChanged(int width, int height);
363
364 /**
Rekha Kumar07366812015-03-24 16:42:31 -0700365 * Handles a change to the video quality.
366 *
367 * @param videoQuality The updated peer video quality.
368 */
369 public abstract void onVideoQualityChanged(int videoQuality);
370
371 /**
Andrew Lee50aca232014-07-22 16:41:54 -0700372 * Handles an update to the total data used for the current session.
373 *
374 * @param dataUsage The updated data usage.
375 */
Rekha Kumar07366812015-03-24 16:42:31 -0700376 public abstract void onCallDataUsageChanged(long dataUsage);
Andrew Lee50aca232014-07-22 16:41:54 -0700377
378 /**
379 * Handles a change in camera capabilities.
380 *
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700381 * @param cameraCapabilities The changed camera capabilities.
Andrew Lee50aca232014-07-22 16:41:54 -0700382 */
383 public abstract void onCameraCapabilitiesChanged(
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700384 CameraCapabilities cameraCapabilities);
Andrew Lee50aca232014-07-22 16:41:54 -0700385 }
Andrew Leeda80c872015-04-15 14:09:50 -0700386
387 /**
388 * @deprecated Use {@code VideoCall.Callback} instead.
389 */
390 @Deprecated
391 public static abstract class Listener extends Callback { }
Andrew Lee50aca232014-07-22 16:41:54 -0700392 }
Sailesh Nepalab5d2822014-03-08 18:01:06 -0800393}