VideoCallImpl.java revision 75958420f2d294ceda517c2782b294002dc2969f
1/*
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.telecom;
18
19import android.os.Handler;
20import android.os.IBinder;
21import android.os.Looper;
22import android.os.Message;
23import android.os.RemoteException;
24import android.telecom.InCallService.VideoCall;
25import android.view.Surface;
26
27import com.android.internal.os.SomeArgs;
28import com.android.internal.telecom.IVideoCallback;
29import com.android.internal.telecom.IVideoProvider;
30
31/**
32 * Implementation of a Video Call, which allows InCallUi to communicate commands to the underlying
33 * {@link Connection.VideoProvider}, and direct callbacks from the
34 * {@link Connection.VideoProvider} to the appropriate {@link VideoCall.Listener}.
35 *
36 * {@hide}
37 */
38public class VideoCallImpl extends VideoCall {
39    private static final int MSG_RECEIVE_SESSION_MODIFY_REQUEST = 1;
40    private static final int MSG_RECEIVE_SESSION_MODIFY_RESPONSE = 2;
41    private static final int MSG_HANDLE_CALL_SESSION_EVENT = 3;
42    private static final int MSG_CHANGE_PEER_DIMENSIONS = 4;
43    private static final int MSG_CHANGE_CALL_DATA_USAGE = 5;
44    private static final int MSG_CHANGE_CAMERA_CAPABILITIES = 6;
45    private static final int MSG_CHANGE_VIDEO_QUALITY = 7;
46
47    private final IVideoProvider mVideoProvider;
48    private final VideoCallListenerBinder mBinder;
49    private VideoCall.Listener mVideoCallListener;
50
51    private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
52        @Override
53        public void binderDied() {
54            mVideoProvider.asBinder().unlinkToDeath(this, 0);
55        }
56    };
57
58    /**
59     * IVideoCallback stub implementation.
60     */
61    private final class VideoCallListenerBinder extends IVideoCallback.Stub {
62        @Override
63        public void receiveSessionModifyRequest(VideoProfile videoProfile) {
64            mHandler.obtainMessage(MSG_RECEIVE_SESSION_MODIFY_REQUEST,
65                    videoProfile).sendToTarget();
66        }
67
68        @Override
69        public void receiveSessionModifyResponse(int status, VideoProfile requestProfile,
70                VideoProfile responseProfile) {
71            SomeArgs args = SomeArgs.obtain();
72            args.arg1 = status;
73            args.arg2 = requestProfile;
74            args.arg3 = responseProfile;
75            mHandler.obtainMessage(MSG_RECEIVE_SESSION_MODIFY_RESPONSE, args).sendToTarget();
76        }
77
78        @Override
79        public void handleCallSessionEvent(int event) {
80            mHandler.obtainMessage(MSG_HANDLE_CALL_SESSION_EVENT, event).sendToTarget();
81        }
82
83        @Override
84        public void changePeerDimensions(int width, int height) {
85            SomeArgs args = SomeArgs.obtain();
86            args.arg1 = width;
87            args.arg2 = height;
88            mHandler.obtainMessage(MSG_CHANGE_PEER_DIMENSIONS, args).sendToTarget();
89        }
90
91        @Override
92        public void changeVideoQuality(int videoQuality) {
93            mHandler.obtainMessage(MSG_CHANGE_VIDEO_QUALITY, videoQuality, 0).sendToTarget();
94        }
95
96        @Override
97        public void changeCallDataUsage(long dataUsage) {
98            mHandler.obtainMessage(MSG_CHANGE_CALL_DATA_USAGE, dataUsage).sendToTarget();
99        }
100
101        @Override
102        public void changeCameraCapabilities(CameraCapabilities cameraCapabilities) {
103            mHandler.obtainMessage(MSG_CHANGE_CAMERA_CAPABILITIES,
104                    cameraCapabilities).sendToTarget();
105        }
106    }
107
108    /** Default handler used to consolidate binder method calls onto a single thread. */
109    private final Handler mHandler = new Handler(Looper.getMainLooper()) {
110        @Override
111        public void handleMessage(Message msg) {
112            if (mVideoCallListener == null) {
113                return;
114            }
115
116            SomeArgs args;
117            switch (msg.what) {
118                case MSG_RECEIVE_SESSION_MODIFY_REQUEST:
119                    mVideoCallListener.onSessionModifyRequestReceived((VideoProfile) msg.obj);
120                    break;
121                case MSG_RECEIVE_SESSION_MODIFY_RESPONSE:
122                    args = (SomeArgs) msg.obj;
123                    try {
124                        int status = (int) args.arg1;
125                        VideoProfile requestProfile = (VideoProfile) args.arg2;
126                        VideoProfile responseProfile = (VideoProfile) args.arg3;
127
128                        mVideoCallListener.onSessionModifyResponseReceived(
129                                status, requestProfile, responseProfile);
130                    } finally {
131                        args.recycle();
132                    }
133                    break;
134                case MSG_HANDLE_CALL_SESSION_EVENT:
135                    mVideoCallListener.onCallSessionEvent((int) msg.obj);
136                    break;
137                case MSG_CHANGE_PEER_DIMENSIONS:
138                    args = (SomeArgs) msg.obj;
139                    try {
140                        int width = (int) args.arg1;
141                        int height = (int) args.arg2;
142                        mVideoCallListener.onPeerDimensionsChanged(width, height);
143                    } finally {
144                        args.recycle();
145                    }
146                    break;
147                case MSG_CHANGE_CALL_DATA_USAGE:
148                    mVideoCallListener.onCallDataUsageChanged((long) msg.obj);
149                    break;
150                case MSG_CHANGE_CAMERA_CAPABILITIES:
151                    mVideoCallListener.onCameraCapabilitiesChanged(
152                            (CameraCapabilities) msg.obj);
153                    break;
154                case MSG_CHANGE_VIDEO_QUALITY:
155                    mVideoCallListener.onVideoQualityChanged(msg.arg1);
156                    break;
157                default:
158                    break;
159            }
160        }
161    };
162
163    /** {@hide} */
164    VideoCallImpl(IVideoProvider videoProvider) throws RemoteException {
165        mVideoProvider = videoProvider;
166        mVideoProvider.asBinder().linkToDeath(mDeathRecipient, 0);
167
168        mBinder = new VideoCallListenerBinder();
169        mVideoProvider.addVideoCallback(mBinder);
170    }
171
172    /** {@inheritDoc} */
173    public void setVideoCallListener(VideoCall.Listener videoCallListener) {
174        mVideoCallListener = videoCallListener;
175    }
176
177    /** {@inheritDoc} */
178    public void removeVideoCallListener() {
179        mVideoCallListener = null;
180        try {
181            mVideoProvider.removeVideoCallback(mBinder);
182        } catch (RemoteException e) {
183        }
184    }
185
186    /** {@inheritDoc} */
187    public void setCamera(String cameraId) {
188        try {
189            mVideoProvider.setCamera(cameraId);
190        } catch (RemoteException e) {
191        }
192    }
193
194    /** {@inheritDoc} */
195    public void setPreviewSurface(Surface surface) {
196        try {
197            mVideoProvider.setPreviewSurface(surface);
198        } catch (RemoteException e) {
199        }
200    }
201
202    /** {@inheritDoc} */
203    public void setDisplaySurface(Surface surface) {
204        try {
205            mVideoProvider.setDisplaySurface(surface);
206        } catch (RemoteException e) {
207        }
208    }
209
210    /** {@inheritDoc} */
211    public void setDeviceOrientation(int rotation) {
212        try {
213            mVideoProvider.setDeviceOrientation(rotation);
214        } catch (RemoteException e) {
215        }
216    }
217
218    /** {@inheritDoc} */
219    public void setZoom(float value) {
220        try {
221            mVideoProvider.setZoom(value);
222        } catch (RemoteException e) {
223        }
224    }
225
226    /** {@inheritDoc} */
227    public void sendSessionModifyRequest(VideoProfile requestProfile) {
228        try {
229            mVideoProvider.sendSessionModifyRequest(requestProfile);
230        } catch (RemoteException e) {
231        }
232    }
233
234    /** {@inheritDoc} */
235    public void sendSessionModifyResponse(VideoProfile responseProfile) {
236        try {
237            mVideoProvider.sendSessionModifyResponse(responseProfile);
238        } catch (RemoteException e) {
239        }
240    }
241
242    /** {@inheritDoc} */
243    public void requestCameraCapabilities() {
244        try {
245            mVideoProvider.requestCameraCapabilities();
246        } catch (RemoteException e) {
247        }
248    }
249
250    /** {@inheritDoc} */
251    public void requestCallDataUsage() {
252        try {
253            mVideoProvider.requestCallDataUsage();
254        } catch (RemoteException e) {
255        }
256    }
257
258    /** {@inheritDoc} */
259    public void setPauseImage(String uri) {
260        try {
261            mVideoProvider.setPauseImage(uri);
262        } catch (RemoteException e) {
263        }
264    }
265}
266