blob: e54abeebb8801fb63be33f65119d8815a3d91cee [file] [log] [blame]
Andrew Lee50aca232014-07-22 16:41:54 -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
Tyler Gunnef9f6f92014-09-12 22:16:17 -070017package android.telecom;
Andrew Lee50aca232014-07-22 16:41:54 -070018
Yorke Lee32f24732015-05-12 16:18:03 -070019import android.net.Uri;
Andrew Lee50aca232014-07-22 16:41:54 -070020import android.os.Handler;
21import android.os.IBinder;
22import android.os.Looper;
23import android.os.Message;
24import android.os.RemoteException;
Tyler Gunnef9f6f92014-09-12 22:16:17 -070025import android.telecom.InCallService.VideoCall;
Andrew Lee50aca232014-07-22 16:41:54 -070026import android.view.Surface;
27
28import com.android.internal.os.SomeArgs;
Tyler Gunnef9f6f92014-09-12 22:16:17 -070029import com.android.internal.telecom.IVideoCallback;
30import com.android.internal.telecom.IVideoProvider;
Andrew Lee50aca232014-07-22 16:41:54 -070031
32/**
33 * Implementation of a Video Call, which allows InCallUi to communicate commands to the underlying
Ihab Awadb19a0bc2014-08-07 19:46:01 -070034 * {@link Connection.VideoProvider}, and direct callbacks from the
35 * {@link Connection.VideoProvider} to the appropriate {@link VideoCall.Listener}.
36 *
37 * {@hide}
Andrew Lee50aca232014-07-22 16:41:54 -070038 */
39public class VideoCallImpl extends VideoCall {
Andrew Lee50aca232014-07-22 16:41:54 -070040
Ihab Awadb19a0bc2014-08-07 19:46:01 -070041 private final IVideoProvider mVideoProvider;
Andrew Lee50aca232014-07-22 16:41:54 -070042 private final VideoCallListenerBinder mBinder;
Andrew Leeda80c872015-04-15 14:09:50 -070043 private VideoCall.Callback mCallback;
Tyler Gunn45382162015-05-06 08:52:27 -070044 private int mVideoQuality = VideoProfile.QUALITY_UNKNOWN;
Tyler Gunn584ba6c2015-12-08 10:53:41 -080045 private int mVideoState = VideoProfile.STATE_AUDIO_ONLY;
Andrew Lee50aca232014-07-22 16:41:54 -070046
47 private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
48 @Override
49 public void binderDied() {
Ihab Awadb19a0bc2014-08-07 19:46:01 -070050 mVideoProvider.asBinder().unlinkToDeath(this, 0);
Andrew Lee50aca232014-07-22 16:41:54 -070051 }
52 };
53
54 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -070055 * IVideoCallback stub implementation.
Andrew Lee50aca232014-07-22 16:41:54 -070056 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -070057 private final class VideoCallListenerBinder extends IVideoCallback.Stub {
Andrew Lee50aca232014-07-22 16:41:54 -070058 @Override
Ihab Awadb19a0bc2014-08-07 19:46:01 -070059 public void receiveSessionModifyRequest(VideoProfile videoProfile) {
Tyler Gunne988cf72015-05-28 15:47:06 -070060 if (mHandler == null) {
61 return;
62 }
Andrew Lee011728f2015-04-23 15:47:06 -070063 mHandler.obtainMessage(MessageHandler.MSG_RECEIVE_SESSION_MODIFY_REQUEST,
Ihab Awadb19a0bc2014-08-07 19:46:01 -070064 videoProfile).sendToTarget();
Tyler Gunne988cf72015-05-28 15:47:06 -070065
Andrew Lee50aca232014-07-22 16:41:54 -070066 }
67
68 @Override
Ihab Awadb19a0bc2014-08-07 19:46:01 -070069 public void receiveSessionModifyResponse(int status, VideoProfile requestProfile,
70 VideoProfile responseProfile) {
Tyler Gunne988cf72015-05-28 15:47:06 -070071 if (mHandler == null) {
72 return;
73 }
Andrew Lee50aca232014-07-22 16:41:54 -070074 SomeArgs args = SomeArgs.obtain();
75 args.arg1 = status;
76 args.arg2 = requestProfile;
77 args.arg3 = responseProfile;
Andrew Lee011728f2015-04-23 15:47:06 -070078 mHandler.obtainMessage(MessageHandler.MSG_RECEIVE_SESSION_MODIFY_RESPONSE, args)
79 .sendToTarget();
Andrew Lee50aca232014-07-22 16:41:54 -070080 }
81
82 @Override
83 public void handleCallSessionEvent(int event) {
Tyler Gunne988cf72015-05-28 15:47:06 -070084 if (mHandler == null) {
85 return;
86 }
Andrew Lee011728f2015-04-23 15:47:06 -070087 mHandler.obtainMessage(MessageHandler.MSG_HANDLE_CALL_SESSION_EVENT, event)
88 .sendToTarget();
Andrew Lee50aca232014-07-22 16:41:54 -070089 }
90
91 @Override
92 public void changePeerDimensions(int width, int height) {
Tyler Gunne988cf72015-05-28 15:47:06 -070093 if (mHandler == null) {
94 return;
95 }
Andrew Lee50aca232014-07-22 16:41:54 -070096 SomeArgs args = SomeArgs.obtain();
97 args.arg1 = width;
98 args.arg2 = height;
Andrew Lee011728f2015-04-23 15:47:06 -070099 mHandler.obtainMessage(MessageHandler.MSG_CHANGE_PEER_DIMENSIONS, args).sendToTarget();
Andrew Lee50aca232014-07-22 16:41:54 -0700100 }
101
102 @Override
Rekha Kumar07366812015-03-24 16:42:31 -0700103 public void changeVideoQuality(int videoQuality) {
Tyler Gunne988cf72015-05-28 15:47:06 -0700104 if (mHandler == null) {
105 return;
106 }
Andrew Lee011728f2015-04-23 15:47:06 -0700107 mHandler.obtainMessage(MessageHandler.MSG_CHANGE_VIDEO_QUALITY, videoQuality, 0)
108 .sendToTarget();
Rekha Kumar07366812015-03-24 16:42:31 -0700109 }
110
111 @Override
112 public void changeCallDataUsage(long dataUsage) {
Tyler Gunne988cf72015-05-28 15:47:06 -0700113 if (mHandler == null) {
114 return;
115 }
Andrew Lee011728f2015-04-23 15:47:06 -0700116 mHandler.obtainMessage(MessageHandler.MSG_CHANGE_CALL_DATA_USAGE, dataUsage)
117 .sendToTarget();
Andrew Lee50aca232014-07-22 16:41:54 -0700118 }
119
120 @Override
Yorke Lee400470f2015-05-12 13:31:25 -0700121 public void changeCameraCapabilities(VideoProfile.CameraCapabilities cameraCapabilities) {
Tyler Gunne988cf72015-05-28 15:47:06 -0700122 if (mHandler == null) {
123 return;
124 }
Andrew Lee011728f2015-04-23 15:47:06 -0700125 mHandler.obtainMessage(MessageHandler.MSG_CHANGE_CAMERA_CAPABILITIES,
Andrew Lee50aca232014-07-22 16:41:54 -0700126 cameraCapabilities).sendToTarget();
127 }
128 }
129
130 /** Default handler used to consolidate binder method calls onto a single thread. */
Andrew Lee011728f2015-04-23 15:47:06 -0700131 private final class MessageHandler extends Handler {
132 private static final int MSG_RECEIVE_SESSION_MODIFY_REQUEST = 1;
133 private static final int MSG_RECEIVE_SESSION_MODIFY_RESPONSE = 2;
134 private static final int MSG_HANDLE_CALL_SESSION_EVENT = 3;
135 private static final int MSG_CHANGE_PEER_DIMENSIONS = 4;
136 private static final int MSG_CHANGE_CALL_DATA_USAGE = 5;
137 private static final int MSG_CHANGE_CAMERA_CAPABILITIES = 6;
138 private static final int MSG_CHANGE_VIDEO_QUALITY = 7;
139
140 public MessageHandler(Looper looper) {
141 super(looper);
142 }
143
Andrew Lee50aca232014-07-22 16:41:54 -0700144 @Override
145 public void handleMessage(Message msg) {
Andrew Leeda80c872015-04-15 14:09:50 -0700146 if (mCallback == null) {
Andrew Lee50aca232014-07-22 16:41:54 -0700147 return;
148 }
149
150 SomeArgs args;
151 switch (msg.what) {
152 case MSG_RECEIVE_SESSION_MODIFY_REQUEST:
Andrew Leeda80c872015-04-15 14:09:50 -0700153 mCallback.onSessionModifyRequestReceived((VideoProfile) msg.obj);
Andrew Lee50aca232014-07-22 16:41:54 -0700154 break;
155 case MSG_RECEIVE_SESSION_MODIFY_RESPONSE:
156 args = (SomeArgs) msg.obj;
157 try {
158 int status = (int) args.arg1;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700159 VideoProfile requestProfile = (VideoProfile) args.arg2;
160 VideoProfile responseProfile = (VideoProfile) args.arg3;
Andrew Lee50aca232014-07-22 16:41:54 -0700161
Andrew Leeda80c872015-04-15 14:09:50 -0700162 mCallback.onSessionModifyResponseReceived(
Andrew Lee50aca232014-07-22 16:41:54 -0700163 status, requestProfile, responseProfile);
164 } finally {
165 args.recycle();
166 }
167 break;
168 case MSG_HANDLE_CALL_SESSION_EVENT:
Andrew Leeda80c872015-04-15 14:09:50 -0700169 mCallback.onCallSessionEvent((int) msg.obj);
Andrew Lee50aca232014-07-22 16:41:54 -0700170 break;
171 case MSG_CHANGE_PEER_DIMENSIONS:
172 args = (SomeArgs) msg.obj;
173 try {
174 int width = (int) args.arg1;
175 int height = (int) args.arg2;
Andrew Leeda80c872015-04-15 14:09:50 -0700176 mCallback.onPeerDimensionsChanged(width, height);
Andrew Lee50aca232014-07-22 16:41:54 -0700177 } finally {
178 args.recycle();
179 }
180 break;
181 case MSG_CHANGE_CALL_DATA_USAGE:
Andrew Leeda80c872015-04-15 14:09:50 -0700182 mCallback.onCallDataUsageChanged((long) msg.obj);
Andrew Lee50aca232014-07-22 16:41:54 -0700183 break;
184 case MSG_CHANGE_CAMERA_CAPABILITIES:
Andrew Leeda80c872015-04-15 14:09:50 -0700185 mCallback.onCameraCapabilitiesChanged(
Yorke Lee400470f2015-05-12 13:31:25 -0700186 (VideoProfile.CameraCapabilities) msg.obj);
Andrew Lee50aca232014-07-22 16:41:54 -0700187 break;
Rekha Kumar07366812015-03-24 16:42:31 -0700188 case MSG_CHANGE_VIDEO_QUALITY:
Tyler Gunn45382162015-05-06 08:52:27 -0700189 mVideoQuality = msg.arg1;
Andrew Leeda80c872015-04-15 14:09:50 -0700190 mCallback.onVideoQualityChanged(msg.arg1);
Rekha Kumar07366812015-03-24 16:42:31 -0700191 break;
Andrew Lee50aca232014-07-22 16:41:54 -0700192 default:
193 break;
194 }
195 }
196 };
197
Andrew Lee011728f2015-04-23 15:47:06 -0700198 private Handler mHandler;
199
Tyler Gunn584ba6c2015-12-08 10:53:41 -0800200 VideoCallImpl(IVideoProvider videoProvider) throws RemoteException {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700201 mVideoProvider = videoProvider;
202 mVideoProvider.asBinder().linkToDeath(mDeathRecipient, 0);
Andrew Lee50aca232014-07-22 16:41:54 -0700203
204 mBinder = new VideoCallListenerBinder();
Tyler Gunn75958422015-04-15 14:23:42 -0700205 mVideoProvider.addVideoCallback(mBinder);
Andrew Lee50aca232014-07-22 16:41:54 -0700206 }
207
Andrew Lee011728f2015-04-23 15:47:06 -0700208 public void destroy() {
209 unregisterCallback(mCallback);
Andrew Lee50aca232014-07-22 16:41:54 -0700210 }
211
212 /** {@inheritDoc} */
Andrew Lee011728f2015-04-23 15:47:06 -0700213 public void registerCallback(VideoCall.Callback callback) {
214 registerCallback(callback, null);
215 }
216
217 /** {@inheritDoc} */
218 public void registerCallback(VideoCall.Callback callback, Handler handler) {
219 mCallback = callback;
220 if (handler == null) {
221 mHandler = new MessageHandler(Looper.getMainLooper());
222 } else {
223 mHandler = new MessageHandler(handler.getLooper());
224 }
225 }
226
227 /** {@inheritDoc} */
228 public void unregisterCallback(VideoCall.Callback callback) {
229 if (callback != mCallback) {
230 return;
231 }
232
Etan Cohen89427242015-04-23 12:26:37 -0700233 mCallback = null;
Tyler Gunn75958422015-04-15 14:23:42 -0700234 try {
235 mVideoProvider.removeVideoCallback(mBinder);
236 } catch (RemoteException e) {
237 }
238 }
239
240 /** {@inheritDoc} */
Andrew Lee50aca232014-07-22 16:41:54 -0700241 public void setCamera(String cameraId) {
242 try {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700243 mVideoProvider.setCamera(cameraId);
Andrew Lee50aca232014-07-22 16:41:54 -0700244 } catch (RemoteException e) {
245 }
246 }
247
248 /** {@inheritDoc} */
249 public void setPreviewSurface(Surface surface) {
250 try {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700251 mVideoProvider.setPreviewSurface(surface);
Andrew Lee50aca232014-07-22 16:41:54 -0700252 } catch (RemoteException e) {
253 }
254 }
255
256 /** {@inheritDoc} */
257 public void setDisplaySurface(Surface surface) {
258 try {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700259 mVideoProvider.setDisplaySurface(surface);
Andrew Lee50aca232014-07-22 16:41:54 -0700260 } catch (RemoteException e) {
261 }
262 }
263
264 /** {@inheritDoc} */
265 public void setDeviceOrientation(int rotation) {
266 try {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700267 mVideoProvider.setDeviceOrientation(rotation);
Andrew Lee50aca232014-07-22 16:41:54 -0700268 } catch (RemoteException e) {
269 }
270 }
271
272 /** {@inheritDoc} */
273 public void setZoom(float value) {
274 try {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700275 mVideoProvider.setZoom(value);
Andrew Lee50aca232014-07-22 16:41:54 -0700276 } catch (RemoteException e) {
277 }
278 }
279
Tyler Gunn45382162015-05-06 08:52:27 -0700280 /**
281 * Sends a session modification request to the video provider.
282 * <p>
283 * The {@link InCallService} will create the {@code requestProfile} based on the current
284 * video state (i.e. {@link Call.Details#getVideoState()}). It is, however, possible that the
285 * video state maintained by the {@link InCallService} could get out of sync with what is known
286 * by the {@link android.telecom.Connection.VideoProvider}. To remove ambiguity, the
287 * {@link VideoCallImpl} passes along the pre-modify video profile to the {@code VideoProvider}
288 * to ensure it has full context of the requested change.
289 *
290 * @param requestProfile The requested video profile.
291 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700292 public void sendSessionModifyRequest(VideoProfile requestProfile) {
Andrew Lee50aca232014-07-22 16:41:54 -0700293 try {
Tyler Gunn584ba6c2015-12-08 10:53:41 -0800294 VideoProfile originalProfile = new VideoProfile(mVideoState, mVideoQuality);
Tyler Gunn45382162015-05-06 08:52:27 -0700295
296 mVideoProvider.sendSessionModifyRequest(originalProfile, requestProfile);
Andrew Lee50aca232014-07-22 16:41:54 -0700297 } catch (RemoteException e) {
298 }
299 }
300
301 /** {@inheritDoc} */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700302 public void sendSessionModifyResponse(VideoProfile responseProfile) {
Andrew Lee50aca232014-07-22 16:41:54 -0700303 try {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700304 mVideoProvider.sendSessionModifyResponse(responseProfile);
Andrew Lee50aca232014-07-22 16:41:54 -0700305 } catch (RemoteException e) {
306 }
307 }
308
309 /** {@inheritDoc} */
310 public void requestCameraCapabilities() {
311 try {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700312 mVideoProvider.requestCameraCapabilities();
Andrew Lee50aca232014-07-22 16:41:54 -0700313 } catch (RemoteException e) {
314 }
315 }
316
317 /** {@inheritDoc} */
318 public void requestCallDataUsage() {
319 try {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700320 mVideoProvider.requestCallDataUsage();
Andrew Lee50aca232014-07-22 16:41:54 -0700321 } catch (RemoteException e) {
322 }
323 }
324
325 /** {@inheritDoc} */
Yorke Lee32f24732015-05-12 16:18:03 -0700326 public void setPauseImage(Uri uri) {
Andrew Lee50aca232014-07-22 16:41:54 -0700327 try {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700328 mVideoProvider.setPauseImage(uri);
Andrew Lee50aca232014-07-22 16:41:54 -0700329 } catch (RemoteException e) {
330 }
331 }
Tyler Gunn584ba6c2015-12-08 10:53:41 -0800332
333 /**
334 * Sets the video state for the current video call.
335 * @param videoState the new video state.
336 */
337 public void setVideoState(int videoState) {
338 mVideoState = videoState;
339 }
Rekha Kumar07366812015-03-24 16:42:31 -0700340}