blob: c8072d13d623f4e5ba7c21ede90d09f079fac800 [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;
45 private Call mCall;
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) {
Andrew Lee011728f2015-04-23 15:47:06 -070060 mHandler.obtainMessage(MessageHandler.MSG_RECEIVE_SESSION_MODIFY_REQUEST,
Ihab Awadb19a0bc2014-08-07 19:46:01 -070061 videoProfile).sendToTarget();
Andrew Lee50aca232014-07-22 16:41:54 -070062 }
63
64 @Override
Ihab Awadb19a0bc2014-08-07 19:46:01 -070065 public void receiveSessionModifyResponse(int status, VideoProfile requestProfile,
66 VideoProfile responseProfile) {
Andrew Lee50aca232014-07-22 16:41:54 -070067 SomeArgs args = SomeArgs.obtain();
68 args.arg1 = status;
69 args.arg2 = requestProfile;
70 args.arg3 = responseProfile;
Andrew Lee011728f2015-04-23 15:47:06 -070071 mHandler.obtainMessage(MessageHandler.MSG_RECEIVE_SESSION_MODIFY_RESPONSE, args)
72 .sendToTarget();
Andrew Lee50aca232014-07-22 16:41:54 -070073 }
74
75 @Override
76 public void handleCallSessionEvent(int event) {
Andrew Lee011728f2015-04-23 15:47:06 -070077 mHandler.obtainMessage(MessageHandler.MSG_HANDLE_CALL_SESSION_EVENT, event)
78 .sendToTarget();
Andrew Lee50aca232014-07-22 16:41:54 -070079 }
80
81 @Override
82 public void changePeerDimensions(int width, int height) {
83 SomeArgs args = SomeArgs.obtain();
84 args.arg1 = width;
85 args.arg2 = height;
Andrew Lee011728f2015-04-23 15:47:06 -070086 mHandler.obtainMessage(MessageHandler.MSG_CHANGE_PEER_DIMENSIONS, args).sendToTarget();
Andrew Lee50aca232014-07-22 16:41:54 -070087 }
88
89 @Override
Rekha Kumar07366812015-03-24 16:42:31 -070090 public void changeVideoQuality(int videoQuality) {
Andrew Lee011728f2015-04-23 15:47:06 -070091 mHandler.obtainMessage(MessageHandler.MSG_CHANGE_VIDEO_QUALITY, videoQuality, 0)
92 .sendToTarget();
Rekha Kumar07366812015-03-24 16:42:31 -070093 }
94
95 @Override
96 public void changeCallDataUsage(long dataUsage) {
Andrew Lee011728f2015-04-23 15:47:06 -070097 mHandler.obtainMessage(MessageHandler.MSG_CHANGE_CALL_DATA_USAGE, dataUsage)
98 .sendToTarget();
Andrew Lee50aca232014-07-22 16:41:54 -070099 }
100
101 @Override
Yorke Lee400470f2015-05-12 13:31:25 -0700102 public void changeCameraCapabilities(VideoProfile.CameraCapabilities cameraCapabilities) {
Andrew Lee011728f2015-04-23 15:47:06 -0700103 mHandler.obtainMessage(MessageHandler.MSG_CHANGE_CAMERA_CAPABILITIES,
Andrew Lee50aca232014-07-22 16:41:54 -0700104 cameraCapabilities).sendToTarget();
105 }
106 }
107
108 /** Default handler used to consolidate binder method calls onto a single thread. */
Andrew Lee011728f2015-04-23 15:47:06 -0700109 private final class MessageHandler extends Handler {
110 private static final int MSG_RECEIVE_SESSION_MODIFY_REQUEST = 1;
111 private static final int MSG_RECEIVE_SESSION_MODIFY_RESPONSE = 2;
112 private static final int MSG_HANDLE_CALL_SESSION_EVENT = 3;
113 private static final int MSG_CHANGE_PEER_DIMENSIONS = 4;
114 private static final int MSG_CHANGE_CALL_DATA_USAGE = 5;
115 private static final int MSG_CHANGE_CAMERA_CAPABILITIES = 6;
116 private static final int MSG_CHANGE_VIDEO_QUALITY = 7;
117
118 public MessageHandler(Looper looper) {
119 super(looper);
120 }
121
Andrew Lee50aca232014-07-22 16:41:54 -0700122 @Override
123 public void handleMessage(Message msg) {
Andrew Leeda80c872015-04-15 14:09:50 -0700124 if (mCallback == null) {
Andrew Lee50aca232014-07-22 16:41:54 -0700125 return;
126 }
127
128 SomeArgs args;
129 switch (msg.what) {
130 case MSG_RECEIVE_SESSION_MODIFY_REQUEST:
Andrew Leeda80c872015-04-15 14:09:50 -0700131 mCallback.onSessionModifyRequestReceived((VideoProfile) msg.obj);
Andrew Lee50aca232014-07-22 16:41:54 -0700132 break;
133 case MSG_RECEIVE_SESSION_MODIFY_RESPONSE:
134 args = (SomeArgs) msg.obj;
135 try {
136 int status = (int) args.arg1;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700137 VideoProfile requestProfile = (VideoProfile) args.arg2;
138 VideoProfile responseProfile = (VideoProfile) args.arg3;
Andrew Lee50aca232014-07-22 16:41:54 -0700139
Andrew Leeda80c872015-04-15 14:09:50 -0700140 mCallback.onSessionModifyResponseReceived(
Andrew Lee50aca232014-07-22 16:41:54 -0700141 status, requestProfile, responseProfile);
142 } finally {
143 args.recycle();
144 }
145 break;
146 case MSG_HANDLE_CALL_SESSION_EVENT:
Andrew Leeda80c872015-04-15 14:09:50 -0700147 mCallback.onCallSessionEvent((int) msg.obj);
Andrew Lee50aca232014-07-22 16:41:54 -0700148 break;
149 case MSG_CHANGE_PEER_DIMENSIONS:
150 args = (SomeArgs) msg.obj;
151 try {
152 int width = (int) args.arg1;
153 int height = (int) args.arg2;
Andrew Leeda80c872015-04-15 14:09:50 -0700154 mCallback.onPeerDimensionsChanged(width, height);
Andrew Lee50aca232014-07-22 16:41:54 -0700155 } finally {
156 args.recycle();
157 }
158 break;
159 case MSG_CHANGE_CALL_DATA_USAGE:
Andrew Leeda80c872015-04-15 14:09:50 -0700160 mCallback.onCallDataUsageChanged((long) msg.obj);
Andrew Lee50aca232014-07-22 16:41:54 -0700161 break;
162 case MSG_CHANGE_CAMERA_CAPABILITIES:
Andrew Leeda80c872015-04-15 14:09:50 -0700163 mCallback.onCameraCapabilitiesChanged(
Yorke Lee400470f2015-05-12 13:31:25 -0700164 (VideoProfile.CameraCapabilities) msg.obj);
Andrew Lee50aca232014-07-22 16:41:54 -0700165 break;
Rekha Kumar07366812015-03-24 16:42:31 -0700166 case MSG_CHANGE_VIDEO_QUALITY:
Tyler Gunn45382162015-05-06 08:52:27 -0700167 mVideoQuality = msg.arg1;
Andrew Leeda80c872015-04-15 14:09:50 -0700168 mCallback.onVideoQualityChanged(msg.arg1);
Rekha Kumar07366812015-03-24 16:42:31 -0700169 break;
Andrew Lee50aca232014-07-22 16:41:54 -0700170 default:
171 break;
172 }
173 }
174 };
175
Andrew Lee011728f2015-04-23 15:47:06 -0700176 private Handler mHandler;
177
Tyler Gunn45382162015-05-06 08:52:27 -0700178 VideoCallImpl(IVideoProvider videoProvider, Call call) throws RemoteException {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700179 mVideoProvider = videoProvider;
180 mVideoProvider.asBinder().linkToDeath(mDeathRecipient, 0);
Andrew Lee50aca232014-07-22 16:41:54 -0700181
182 mBinder = new VideoCallListenerBinder();
Tyler Gunn75958422015-04-15 14:23:42 -0700183 mVideoProvider.addVideoCallback(mBinder);
Tyler Gunn45382162015-05-06 08:52:27 -0700184 mCall = call;
Andrew Lee50aca232014-07-22 16:41:54 -0700185 }
186
Andrew Lee011728f2015-04-23 15:47:06 -0700187 public void destroy() {
188 unregisterCallback(mCallback);
Andrew Lee50aca232014-07-22 16:41:54 -0700189 }
190
191 /** {@inheritDoc} */
Andrew Lee011728f2015-04-23 15:47:06 -0700192 public void registerCallback(VideoCall.Callback callback) {
193 registerCallback(callback, null);
194 }
195
196 /** {@inheritDoc} */
197 public void registerCallback(VideoCall.Callback callback, Handler handler) {
198 mCallback = callback;
199 if (handler == null) {
200 mHandler = new MessageHandler(Looper.getMainLooper());
201 } else {
202 mHandler = new MessageHandler(handler.getLooper());
203 }
204 }
205
206 /** {@inheritDoc} */
207 public void unregisterCallback(VideoCall.Callback callback) {
208 if (callback != mCallback) {
209 return;
210 }
211
Etan Cohen89427242015-04-23 12:26:37 -0700212 mCallback = null;
Tyler Gunn75958422015-04-15 14:23:42 -0700213 try {
214 mVideoProvider.removeVideoCallback(mBinder);
215 } catch (RemoteException e) {
216 }
217 }
218
219 /** {@inheritDoc} */
Andrew Lee50aca232014-07-22 16:41:54 -0700220 public void setCamera(String cameraId) {
221 try {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700222 mVideoProvider.setCamera(cameraId);
Andrew Lee50aca232014-07-22 16:41:54 -0700223 } catch (RemoteException e) {
224 }
225 }
226
227 /** {@inheritDoc} */
228 public void setPreviewSurface(Surface surface) {
229 try {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700230 mVideoProvider.setPreviewSurface(surface);
Andrew Lee50aca232014-07-22 16:41:54 -0700231 } catch (RemoteException e) {
232 }
233 }
234
235 /** {@inheritDoc} */
236 public void setDisplaySurface(Surface surface) {
237 try {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700238 mVideoProvider.setDisplaySurface(surface);
Andrew Lee50aca232014-07-22 16:41:54 -0700239 } catch (RemoteException e) {
240 }
241 }
242
243 /** {@inheritDoc} */
244 public void setDeviceOrientation(int rotation) {
245 try {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700246 mVideoProvider.setDeviceOrientation(rotation);
Andrew Lee50aca232014-07-22 16:41:54 -0700247 } catch (RemoteException e) {
248 }
249 }
250
251 /** {@inheritDoc} */
252 public void setZoom(float value) {
253 try {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700254 mVideoProvider.setZoom(value);
Andrew Lee50aca232014-07-22 16:41:54 -0700255 } catch (RemoteException e) {
256 }
257 }
258
Tyler Gunn45382162015-05-06 08:52:27 -0700259 /**
260 * Sends a session modification request to the video provider.
261 * <p>
262 * The {@link InCallService} will create the {@code requestProfile} based on the current
263 * video state (i.e. {@link Call.Details#getVideoState()}). It is, however, possible that the
264 * video state maintained by the {@link InCallService} could get out of sync with what is known
265 * by the {@link android.telecom.Connection.VideoProvider}. To remove ambiguity, the
266 * {@link VideoCallImpl} passes along the pre-modify video profile to the {@code VideoProvider}
267 * to ensure it has full context of the requested change.
268 *
269 * @param requestProfile The requested video profile.
270 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700271 public void sendSessionModifyRequest(VideoProfile requestProfile) {
Andrew Lee50aca232014-07-22 16:41:54 -0700272 try {
Tyler Gunn45382162015-05-06 08:52:27 -0700273 VideoProfile originalProfile = new VideoProfile(mCall.getDetails().getVideoState(),
274 mVideoQuality);
275
276 mVideoProvider.sendSessionModifyRequest(originalProfile, requestProfile);
Andrew Lee50aca232014-07-22 16:41:54 -0700277 } catch (RemoteException e) {
278 }
279 }
280
281 /** {@inheritDoc} */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700282 public void sendSessionModifyResponse(VideoProfile responseProfile) {
Andrew Lee50aca232014-07-22 16:41:54 -0700283 try {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700284 mVideoProvider.sendSessionModifyResponse(responseProfile);
Andrew Lee50aca232014-07-22 16:41:54 -0700285 } catch (RemoteException e) {
286 }
287 }
288
289 /** {@inheritDoc} */
290 public void requestCameraCapabilities() {
291 try {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700292 mVideoProvider.requestCameraCapabilities();
Andrew Lee50aca232014-07-22 16:41:54 -0700293 } catch (RemoteException e) {
294 }
295 }
296
297 /** {@inheritDoc} */
298 public void requestCallDataUsage() {
299 try {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700300 mVideoProvider.requestCallDataUsage();
Andrew Lee50aca232014-07-22 16:41:54 -0700301 } catch (RemoteException e) {
302 }
303 }
304
305 /** {@inheritDoc} */
Yorke Lee32f24732015-05-12 16:18:03 -0700306 public void setPauseImage(Uri uri) {
Andrew Lee50aca232014-07-22 16:41:54 -0700307 try {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700308 mVideoProvider.setPauseImage(uri);
Andrew Lee50aca232014-07-22 16:41:54 -0700309 } catch (RemoteException e) {
310 }
311 }
Rekha Kumar07366812015-03-24 16:42:31 -0700312}