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 android.net.Uri; 20import android.os.Handler; 21import android.os.IBinder; 22import android.os.Looper; 23import android.os.Message; 24import android.os.RemoteException; 25import android.telecom.Connection; 26import android.telecom.VideoProfile; 27import android.telecom.VideoProfile.CameraCapabilities; 28import android.view.Surface; 29 30import com.android.internal.os.SomeArgs; 31 32/** 33 * Subclass implementation of {@link Connection.VideoProvider}. This intermediates and 34 * communicates with the actual implementation of the video call provider in the IMS service; it is 35 * in essence, a wrapper around the IMS's video call provider implementation. 36 * 37 * This class maintains a binder by which the ImsVideoCallProvider's implementation can communicate 38 * its intent to invoke callbacks. In this class, the message across this binder is handled, and 39 * the superclass's methods are used to execute the callbacks. 40 * 41 * @hide 42 */ 43public class ImsVideoCallProviderWrapper extends Connection.VideoProvider { 44 private static final int MSG_RECEIVE_SESSION_MODIFY_REQUEST = 1; 45 private static final int MSG_RECEIVE_SESSION_MODIFY_RESPONSE = 2; 46 private static final int MSG_HANDLE_CALL_SESSION_EVENT = 3; 47 private static final int MSG_CHANGE_PEER_DIMENSIONS = 4; 48 private static final int MSG_CHANGE_CALL_DATA_USAGE = 5; 49 private static final int MSG_CHANGE_CAMERA_CAPABILITIES = 6; 50 private static final int MSG_CHANGE_VIDEO_QUALITY = 7; 51 52 private final IImsVideoCallProvider mVideoCallProvider; 53 private final ImsVideoCallCallback mBinder; 54 55 private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() { 56 @Override 57 public void binderDied() { 58 mVideoCallProvider.asBinder().unlinkToDeath(this, 0); 59 } 60 }; 61 62 /** 63 * IImsVideoCallCallback stub implementation. 64 */ 65 private final class ImsVideoCallCallback extends IImsVideoCallCallback.Stub { 66 @Override 67 public void receiveSessionModifyRequest(VideoProfile VideoProfile) { 68 mHandler.obtainMessage(MSG_RECEIVE_SESSION_MODIFY_REQUEST, 69 VideoProfile).sendToTarget(); 70 } 71 72 @Override 73 public void receiveSessionModifyResponse( 74 int status, VideoProfile requestProfile, VideoProfile responseProfile) { 75 SomeArgs args = SomeArgs.obtain(); 76 args.arg1 = status; 77 args.arg2 = requestProfile; 78 args.arg3 = responseProfile; 79 mHandler.obtainMessage(MSG_RECEIVE_SESSION_MODIFY_RESPONSE, args).sendToTarget(); 80 } 81 82 @Override 83 public void handleCallSessionEvent(int event) { 84 mHandler.obtainMessage(MSG_HANDLE_CALL_SESSION_EVENT, event).sendToTarget(); 85 } 86 87 @Override 88 public void changePeerDimensions(int width, int height) { 89 SomeArgs args = SomeArgs.obtain(); 90 args.arg1 = width; 91 args.arg2 = height; 92 mHandler.obtainMessage(MSG_CHANGE_PEER_DIMENSIONS, args).sendToTarget(); 93 } 94 95 @Override 96 public void changeVideoQuality(int videoQuality) { 97 mHandler.obtainMessage(MSG_CHANGE_VIDEO_QUALITY, videoQuality, 0).sendToTarget(); 98 } 99 100 @Override 101 public void changeCallDataUsage(long dataUsage) { 102 mHandler.obtainMessage(MSG_CHANGE_CALL_DATA_USAGE, dataUsage).sendToTarget(); 103 } 104 105 @Override 106 public void changeCameraCapabilities( 107 VideoProfile.CameraCapabilities cameraCapabilities) { 108 mHandler.obtainMessage(MSG_CHANGE_CAMERA_CAPABILITIES, 109 cameraCapabilities).sendToTarget(); 110 } 111 } 112 113 /** Default handler used to consolidate binder method calls onto a single thread. */ 114 private final Handler mHandler = new Handler(Looper.getMainLooper()) { 115 @Override 116 public void handleMessage(Message msg) { 117 SomeArgs args; 118 switch (msg.what) { 119 case MSG_RECEIVE_SESSION_MODIFY_REQUEST: 120 receiveSessionModifyRequest((VideoProfile) msg.obj); 121 break; 122 case MSG_RECEIVE_SESSION_MODIFY_RESPONSE: 123 args = (SomeArgs) msg.obj; 124 try { 125 int status = (int) args.arg1; 126 VideoProfile requestProfile = (VideoProfile) args.arg2; 127 VideoProfile responseProfile = (VideoProfile) args.arg3; 128 129 receiveSessionModifyResponse(status, requestProfile, responseProfile); 130 } finally { 131 args.recycle(); 132 } 133 break; 134 case MSG_HANDLE_CALL_SESSION_EVENT: 135 handleCallSessionEvent((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 changePeerDimensions(width, height); 143 } finally { 144 args.recycle(); 145 } 146 break; 147 case MSG_CHANGE_CALL_DATA_USAGE: 148 changeCallDataUsage((long) msg.obj); 149 break; 150 case MSG_CHANGE_CAMERA_CAPABILITIES: 151 changeCameraCapabilities((VideoProfile.CameraCapabilities) msg.obj); 152 break; 153 case MSG_CHANGE_VIDEO_QUALITY: 154 changeVideoQuality(msg.arg1); 155 break; 156 default: 157 break; 158 } 159 } 160 }; 161 162 /** 163 * Instantiates an instance of the ImsVideoCallProvider, taking in the binder for IMS's video 164 * call provider implementation. 165 * 166 * @param VideoProvider 167 */ 168 public ImsVideoCallProviderWrapper(IImsVideoCallProvider VideoProvider) 169 throws RemoteException { 170 mVideoCallProvider = VideoProvider; 171 mVideoCallProvider.asBinder().linkToDeath(mDeathRecipient, 0); 172 173 mBinder = new ImsVideoCallCallback(); 174 mVideoCallProvider.setCallback(mBinder); 175 } 176 177 /** @inheritDoc */ 178 public void onSetCamera(String cameraId) { 179 try { 180 mVideoCallProvider.setCamera(cameraId); 181 } catch (RemoteException e) { 182 } 183 } 184 185 /** @inheritDoc */ 186 public void onSetPreviewSurface(Surface surface) { 187 try { 188 mVideoCallProvider.setPreviewSurface(surface); 189 } catch (RemoteException e) { 190 } 191 } 192 193 /** @inheritDoc */ 194 public void onSetDisplaySurface(Surface surface) { 195 try { 196 mVideoCallProvider.setDisplaySurface(surface); 197 } catch (RemoteException e) { 198 } 199 } 200 201 /** @inheritDoc */ 202 public void onSetDeviceOrientation(int rotation) { 203 try { 204 mVideoCallProvider.setDeviceOrientation(rotation); 205 } catch (RemoteException e) { 206 } 207 } 208 209 /** @inheritDoc */ 210 public void onSetZoom(float value) { 211 try { 212 mVideoCallProvider.setZoom(value); 213 } catch (RemoteException e) { 214 } 215 } 216 217 /** @inheritDoc */ 218 public void onSendSessionModifyRequest(VideoProfile fromProfile, VideoProfile toProfile) { 219 try { 220 mVideoCallProvider.sendSessionModifyRequest(fromProfile, toProfile); 221 } catch (RemoteException e) { 222 } 223 } 224 225 /** @inheritDoc */ 226 public void onSendSessionModifyResponse(VideoProfile responseProfile) { 227 try { 228 mVideoCallProvider.sendSessionModifyResponse(responseProfile); 229 } catch (RemoteException e) { 230 } 231 } 232 233 /** @inheritDoc */ 234 public void onRequestCameraCapabilities() { 235 try { 236 mVideoCallProvider.requestCameraCapabilities(); 237 } catch (RemoteException e) { 238 } 239 } 240 241 /** @inheritDoc */ 242 public void onRequestConnectionDataUsage() { 243 try { 244 mVideoCallProvider.requestCallDataUsage(); 245 } catch (RemoteException e) { 246 } 247 } 248 249 /** @inheritDoc */ 250 public void onSetPauseImage(Uri uri) { 251 try { 252 mVideoCallProvider.setPauseImage(uri); 253 } catch (RemoteException e) { 254 } 255 } 256} 257