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 com.android.ims.internal;
18
19import com.android.internal.os.SomeArgs;
20
21import android.net.Uri;
22import android.os.Handler;
23import android.os.Looper;
24import android.os.Message;
25import android.os.RemoteException;
26import android.telecom.Connection;
27import android.telecom.VideoProfile;
28import android.telecom.VideoProfile.CameraCapabilities;
29import android.view.Surface;
30
31public abstract class ImsVideoCallProvider {
32    private static final int MSG_SET_CALLBACK = 1;
33    private static final int MSG_SET_CAMERA = 2;
34    private static final int MSG_SET_PREVIEW_SURFACE = 3;
35    private static final int MSG_SET_DISPLAY_SURFACE = 4;
36    private static final int MSG_SET_DEVICE_ORIENTATION = 5;
37    private static final int MSG_SET_ZOOM = 6;
38    private static final int MSG_SEND_SESSION_MODIFY_REQUEST = 7;
39    private static final int MSG_SEND_SESSION_MODIFY_RESPONSE = 8;
40    private static final int MSG_REQUEST_CAMERA_CAPABILITIES = 9;
41    private static final int MSG_REQUEST_CALL_DATA_USAGE = 10;
42    private static final int MSG_SET_PAUSE_IMAGE = 11;
43
44    private final ImsVideoCallProviderBinder mBinder;
45
46    private IImsVideoCallCallback mCallback;
47
48    /**
49     * Default handler used to consolidate binder method calls onto a single thread.
50     */
51    private final Handler mProviderHandler = new Handler(Looper.getMainLooper()) {
52        @Override
53        public void handleMessage(Message msg) {
54            switch (msg.what) {
55                case MSG_SET_CALLBACK:
56                    mCallback = (IImsVideoCallCallback) msg.obj;
57                    break;
58                case MSG_SET_CAMERA:
59                    onSetCamera((String) msg.obj);
60                    break;
61                case MSG_SET_PREVIEW_SURFACE:
62                    onSetPreviewSurface((Surface) msg.obj);
63                    break;
64                case MSG_SET_DISPLAY_SURFACE:
65                    onSetDisplaySurface((Surface) msg.obj);
66                    break;
67                case MSG_SET_DEVICE_ORIENTATION:
68                    onSetDeviceOrientation(msg.arg1);
69                    break;
70                case MSG_SET_ZOOM:
71                    onSetZoom((Float) msg.obj);
72                    break;
73                case MSG_SEND_SESSION_MODIFY_REQUEST: {
74                    SomeArgs args = (SomeArgs) msg.obj;
75                    try {
76                        VideoProfile fromProfile = (VideoProfile) args.arg1;
77                        VideoProfile toProfile = (VideoProfile) args.arg2;
78
79                        onSendSessionModifyRequest(fromProfile, toProfile);
80                    } finally {
81                        args.recycle();
82                    }
83                    break;
84                }
85                case MSG_SEND_SESSION_MODIFY_RESPONSE:
86                    onSendSessionModifyResponse((VideoProfile) msg.obj);
87                    break;
88                case MSG_REQUEST_CAMERA_CAPABILITIES:
89                    onRequestCameraCapabilities();
90                    break;
91                case MSG_REQUEST_CALL_DATA_USAGE:
92                    onRequestCallDataUsage();
93                    break;
94                case MSG_SET_PAUSE_IMAGE:
95                    onSetPauseImage((Uri) msg.obj);
96                    break;
97                default:
98                    break;
99            }
100        }
101    };
102
103    /**
104     * IImsVideoCallProvider stub implementation.
105     */
106    private final class ImsVideoCallProviderBinder extends IImsVideoCallProvider.Stub {
107        public void setCallback(IImsVideoCallCallback callback) {
108            mProviderHandler.obtainMessage(MSG_SET_CALLBACK, callback).sendToTarget();
109        }
110
111        public void setCamera(String cameraId) {
112            mProviderHandler.obtainMessage(MSG_SET_CAMERA, cameraId).sendToTarget();
113        }
114
115        public void setPreviewSurface(Surface surface) {
116            mProviderHandler.obtainMessage(MSG_SET_PREVIEW_SURFACE, surface).sendToTarget();
117        }
118
119        public void setDisplaySurface(Surface surface) {
120            mProviderHandler.obtainMessage(MSG_SET_DISPLAY_SURFACE, surface).sendToTarget();
121        }
122
123        public void setDeviceOrientation(int rotation) {
124            mProviderHandler.obtainMessage(MSG_SET_DEVICE_ORIENTATION, rotation, 0).sendToTarget();
125        }
126
127        public void setZoom(float value) {
128            mProviderHandler.obtainMessage(MSG_SET_ZOOM, value).sendToTarget();
129        }
130
131        public void sendSessionModifyRequest(VideoProfile fromProfile, VideoProfile toProfile) {
132            SomeArgs args = SomeArgs.obtain();
133            args.arg1 = fromProfile;
134            args.arg2 = toProfile;
135            mProviderHandler.obtainMessage(MSG_SEND_SESSION_MODIFY_REQUEST, args).sendToTarget();
136        }
137
138        public void sendSessionModifyResponse(VideoProfile responseProfile) {
139            mProviderHandler.obtainMessage(
140                    MSG_SEND_SESSION_MODIFY_RESPONSE, responseProfile).sendToTarget();
141        }
142
143        public void requestCameraCapabilities() {
144            mProviderHandler.obtainMessage(MSG_REQUEST_CAMERA_CAPABILITIES).sendToTarget();
145        }
146
147        public void requestCallDataUsage() {
148            mProviderHandler.obtainMessage(MSG_REQUEST_CALL_DATA_USAGE).sendToTarget();
149        }
150
151        public void setPauseImage(Uri uri) {
152            mProviderHandler.obtainMessage(MSG_SET_PAUSE_IMAGE, uri).sendToTarget();
153        }
154    }
155
156    public ImsVideoCallProvider() {
157        mBinder = new ImsVideoCallProviderBinder();
158    }
159
160    /**
161     * Returns binder object which can be used across IPC methods.
162     */
163    public final IImsVideoCallProvider getInterface() {
164        return mBinder;
165    }
166
167    /** @see Connection.VideoProvider#onSetCamera */
168    public abstract void onSetCamera(String cameraId);
169
170    /** @see Connection.VideoProvider#onSetPreviewSurface */
171    public abstract void onSetPreviewSurface(Surface surface);
172
173    /** @see Connection.VideoProvider#onSetDisplaySurface */
174    public abstract void onSetDisplaySurface(Surface surface);
175
176    /** @see Connection.VideoProvider#onSetDeviceOrientation */
177    public abstract void onSetDeviceOrientation(int rotation);
178
179    /** @see Connection.VideoProvider#onSetZoom */
180    public abstract void onSetZoom(float value);
181
182    /** @see Connection.VideoProvider#onSendSessionModifyRequest */
183    public abstract void onSendSessionModifyRequest(VideoProfile fromProfile,
184            VideoProfile toProfile);
185
186    /** @see Connection.VideoProvider#onSendSessionModifyResponse */
187    public abstract void onSendSessionModifyResponse(VideoProfile responseProfile);
188
189    /** @see Connection.VideoProvider#onRequestCameraCapabilities */
190    public abstract void onRequestCameraCapabilities();
191
192    /** @see Connection.VideoProvider#onRequestCallDataUsage */
193    public abstract void onRequestCallDataUsage();
194
195    /** @see Connection.VideoProvider#onSetPauseImage */
196    public abstract void onSetPauseImage(Uri uri);
197
198    /** @see Connection.VideoProvider#receiveSessionModifyRequest */
199    public void receiveSessionModifyRequest(VideoProfile VideoProfile) {
200        if (mCallback != null) {
201            try {
202                mCallback.receiveSessionModifyRequest(VideoProfile);
203            } catch (RemoteException ignored) {
204            }
205        }
206    }
207
208    /** @see Connection.VideoProvider#receiveSessionModifyResponse */
209    public void receiveSessionModifyResponse(
210            int status, VideoProfile requestedProfile, VideoProfile responseProfile) {
211        if (mCallback != null) {
212            try {
213                mCallback.receiveSessionModifyResponse(status, requestedProfile, responseProfile);
214            } catch (RemoteException ignored) {
215            }
216        }
217    }
218
219    /** @see Connection.VideoProvider#handleCallSessionEvent */
220    public void handleCallSessionEvent(int event) {
221        if (mCallback != null) {
222            try {
223                mCallback.handleCallSessionEvent(event);
224            } catch (RemoteException ignored) {
225            }
226        }
227    }
228
229    /** @see Connection.VideoProvider#changePeerDimensions */
230    public void changePeerDimensions(int width, int height) {
231        if (mCallback != null) {
232            try {
233                mCallback.changePeerDimensions(width, height);
234            } catch (RemoteException ignored) {
235            }
236        }
237    }
238
239    /** @see Connection.VideoProvider#changeCallDataUsage */
240    public void changeCallDataUsage(long dataUsage) {
241        if (mCallback != null) {
242            try {
243                mCallback.changeCallDataUsage(dataUsage);
244            } catch (RemoteException ignored) {
245            }
246        }
247    }
248
249    /** @see Connection.VideoProvider#changeCameraCapabilities */
250    public void changeCameraCapabilities(CameraCapabilities CameraCapabilities) {
251        if (mCallback != null) {
252            try {
253                mCallback.changeCameraCapabilities(CameraCapabilities);
254            } catch (RemoteException ignored) {
255            }
256        }
257    }
258
259    /** @see Connection.VideoProvider#changeVideoQuality */
260    public void changeVideoQuality(int videoQuality) {
261        if (mCallback != null) {
262            try {
263                mCallback.changeVideoQuality(videoQuality);
264            } catch (RemoteException ignored) {
265            }
266        }
267    }
268}
269