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