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