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