ICameraService.cpp revision 0f61d8f14aa368c9cd7076528e8096e10ed100a0
1/* 2** 3** Copyright 2008, The Android Open Source Project 4** 5** Licensed under the Apache License, Version 2.0 (the "License"); 6** you may not use this file except in compliance with the License. 7** You may obtain a copy of the License at 8** 9** http://www.apache.org/licenses/LICENSE-2.0 10** 11** Unless required by applicable law or agreed to in writing, software 12** distributed under the License is distributed on an "AS IS" BASIS, 13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14** See the License for the specific language governing permissions and 15** limitations under the License. 16*/ 17 18#define LOG_TAG "BpCameraService" 19#include <utils/Log.h> 20 21#include <stdint.h> 22#include <sys/types.h> 23 24#include <binder/Parcel.h> 25#include <binder/IPCThreadState.h> 26#include <binder/IServiceManager.h> 27 28#include <camera/ICameraService.h> 29#include <camera/ICameraServiceListener.h> 30#include <camera/IProCameraUser.h> 31#include <camera/IProCameraCallbacks.h> 32#include <camera/ICamera.h> 33#include <camera/ICameraClient.h> 34#include <camera/camera2/ICameraDeviceUser.h> 35#include <camera/camera2/ICameraDeviceCallbacks.h> 36 37namespace android { 38 39namespace { 40 41enum { 42 EX_SECURITY = -1, 43 EX_BAD_PARCELABLE = -2, 44 EX_ILLEGAL_ARGUMENT = -3, 45 EX_NULL_POINTER = -4, 46 EX_ILLEGAL_STATE = -5, 47 EX_HAS_REPLY_HEADER = -128, // special; see below 48}; 49 50static bool readExceptionCode(Parcel& reply) { 51 int32_t exceptionCode = reply.readExceptionCode(); 52 53 if (exceptionCode != 0) { 54 const char* errorMsg; 55 switch(exceptionCode) { 56 case EX_SECURITY: 57 errorMsg = "Security"; 58 break; 59 case EX_BAD_PARCELABLE: 60 errorMsg = "BadParcelable"; 61 break; 62 case EX_NULL_POINTER: 63 errorMsg = "NullPointer"; 64 break; 65 case EX_ILLEGAL_STATE: 66 errorMsg = "IllegalState"; 67 break; 68 // Binder should be handling this code inside Parcel::readException 69 // but lets have a to-string here anyway just in case. 70 case EX_HAS_REPLY_HEADER: 71 errorMsg = "HasReplyHeader"; 72 break; 73 default: 74 errorMsg = "Unknown"; 75 } 76 77 ALOGE("Binder transmission error %s (%d)", errorMsg, exceptionCode); 78 return true; 79 } 80 81 return false; 82} 83 84}; 85 86class BpCameraService: public BpInterface<ICameraService> 87{ 88public: 89 BpCameraService(const sp<IBinder>& impl) 90 : BpInterface<ICameraService>(impl) 91 { 92 } 93 94 // get number of cameras available 95 virtual int32_t getNumberOfCameras() 96 { 97 Parcel data, reply; 98 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); 99 remote()->transact(BnCameraService::GET_NUMBER_OF_CAMERAS, data, &reply); 100 101 if (readExceptionCode(reply)) return 0; 102 return reply.readInt32(); 103 } 104 105 // get information about a camera 106 virtual status_t getCameraInfo(int cameraId, 107 struct CameraInfo* cameraInfo) { 108 Parcel data, reply; 109 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); 110 data.writeInt32(cameraId); 111 remote()->transact(BnCameraService::GET_CAMERA_INFO, data, &reply); 112 113 if (readExceptionCode(reply)) return -EPROTO; 114 status_t result = reply.readInt32(); 115 if (reply.readInt32() != 0) { 116 cameraInfo->facing = reply.readInt32(); 117 cameraInfo->orientation = reply.readInt32(); 118 } 119 return result; 120 } 121 122 // connect to camera service (android.hardware.Camera) 123 virtual status_t connect(const sp<ICameraClient>& cameraClient, int cameraId, 124 const String16 &clientPackageName, int clientUid, 125 /*out*/ 126 sp<ICamera>& device) 127 { 128 Parcel data, reply; 129 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); 130 data.writeStrongBinder(cameraClient->asBinder()); 131 data.writeInt32(cameraId); 132 data.writeString16(clientPackageName); 133 data.writeInt32(clientUid); 134 remote()->transact(BnCameraService::CONNECT, data, &reply); 135 136 if (readExceptionCode(reply)) return -EPROTO; 137 status_t status = reply.readInt32(); 138 if (reply.readInt32() != 0) { 139 device = interface_cast<ICamera>(reply.readStrongBinder()); 140 } 141 return status; 142 } 143 144 // connect to camera service (pro client) 145 virtual status_t connectPro(const sp<IProCameraCallbacks>& cameraCb, int cameraId, 146 const String16 &clientPackageName, int clientUid, 147 /*out*/ 148 sp<IProCameraUser>& device) 149 { 150 Parcel data, reply; 151 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); 152 data.writeStrongBinder(cameraCb->asBinder()); 153 data.writeInt32(cameraId); 154 data.writeString16(clientPackageName); 155 data.writeInt32(clientUid); 156 remote()->transact(BnCameraService::CONNECT_PRO, data, &reply); 157 158 if (readExceptionCode(reply)) return -EPROTO; 159 status_t status = reply.readInt32(); 160 if (reply.readInt32() != 0) { 161 device = interface_cast<IProCameraUser>(reply.readStrongBinder()); 162 } 163 return status; 164 } 165 166 // connect to camera service (android.hardware.camera2.CameraDevice) 167 virtual status_t connectDevice( 168 const sp<ICameraDeviceCallbacks>& cameraCb, 169 int cameraId, 170 const String16& clientPackageName, 171 int clientUid, 172 /*out*/ 173 sp<ICameraDeviceUser>& device) 174 { 175 Parcel data, reply; 176 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); 177 data.writeStrongBinder(cameraCb->asBinder()); 178 data.writeInt32(cameraId); 179 data.writeString16(clientPackageName); 180 data.writeInt32(clientUid); 181 remote()->transact(BnCameraService::CONNECT_DEVICE, data, &reply); 182 183 if (readExceptionCode(reply)) return -EPROTO; 184 status_t status = reply.readInt32(); 185 if (reply.readInt32() != 0) { 186 device = interface_cast<ICameraDeviceUser>(reply.readStrongBinder()); 187 } 188 return status; 189 } 190 191 virtual status_t addListener(const sp<ICameraServiceListener>& listener) 192 { 193 Parcel data, reply; 194 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); 195 data.writeStrongBinder(listener->asBinder()); 196 remote()->transact(BnCameraService::ADD_LISTENER, data, &reply); 197 198 if (readExceptionCode(reply)) return -EPROTO; 199 return reply.readInt32(); 200 } 201 202 virtual status_t removeListener(const sp<ICameraServiceListener>& listener) 203 { 204 Parcel data, reply; 205 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); 206 data.writeStrongBinder(listener->asBinder()); 207 remote()->transact(BnCameraService::REMOVE_LISTENER, data, &reply); 208 209 if (readExceptionCode(reply)) return -EPROTO; 210 return reply.readInt32(); 211 } 212}; 213 214IMPLEMENT_META_INTERFACE(CameraService, "android.hardware.ICameraService"); 215 216// ---------------------------------------------------------------------- 217 218status_t BnCameraService::onTransact( 219 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 220{ 221 switch(code) { 222 case GET_NUMBER_OF_CAMERAS: { 223 CHECK_INTERFACE(ICameraService, data, reply); 224 reply->writeNoException(); 225 reply->writeInt32(getNumberOfCameras()); 226 return NO_ERROR; 227 } break; 228 case GET_CAMERA_INFO: { 229 CHECK_INTERFACE(ICameraService, data, reply); 230 CameraInfo cameraInfo = CameraInfo(); 231 memset(&cameraInfo, 0, sizeof(cameraInfo)); 232 status_t result = getCameraInfo(data.readInt32(), &cameraInfo); 233 reply->writeNoException(); 234 reply->writeInt32(result); 235 236 // Fake a parcelable object here 237 reply->writeInt32(1); // means the parcelable is included 238 reply->writeInt32(cameraInfo.facing); 239 reply->writeInt32(cameraInfo.orientation); 240 return NO_ERROR; 241 } break; 242 case CONNECT: { 243 CHECK_INTERFACE(ICameraService, data, reply); 244 sp<ICameraClient> cameraClient = 245 interface_cast<ICameraClient>(data.readStrongBinder()); 246 int32_t cameraId = data.readInt32(); 247 const String16 clientName = data.readString16(); 248 int32_t clientUid = data.readInt32(); 249 sp<ICamera> camera; 250 status_t status = connect(cameraClient, cameraId, 251 clientName, clientUid, /*out*/ camera); 252 reply->writeNoException(); 253 reply->writeInt32(status); 254 if (camera != NULL) { 255 reply->writeInt32(1); 256 reply->writeStrongBinder(camera->asBinder()); 257 } else { 258 reply->writeInt32(0); 259 } 260 return NO_ERROR; 261 } break; 262 case CONNECT_PRO: { 263 CHECK_INTERFACE(ICameraService, data, reply); 264 sp<IProCameraCallbacks> cameraClient = 265 interface_cast<IProCameraCallbacks>(data.readStrongBinder()); 266 int32_t cameraId = data.readInt32(); 267 const String16 clientName = data.readString16(); 268 int32_t clientUid = data.readInt32(); 269 sp<IProCameraUser> camera; 270 status_t status = connectPro(cameraClient, cameraId, 271 clientName, clientUid, /*out*/ camera); 272 reply->writeNoException(); 273 reply->writeInt32(status); 274 if (camera != NULL) { 275 reply->writeInt32(1); 276 reply->writeStrongBinder(camera->asBinder()); 277 } else { 278 reply->writeInt32(0); 279 } 280 return NO_ERROR; 281 } break; 282 case CONNECT_DEVICE: { 283 CHECK_INTERFACE(ICameraService, data, reply); 284 sp<ICameraDeviceCallbacks> cameraClient = 285 interface_cast<ICameraDeviceCallbacks>(data.readStrongBinder()); 286 int32_t cameraId = data.readInt32(); 287 const String16 clientName = data.readString16(); 288 int32_t clientUid = data.readInt32(); 289 sp<ICameraDeviceUser> camera; 290 status_t status = connectDevice(cameraClient, cameraId, 291 clientName, clientUid, /*out*/ camera); 292 reply->writeNoException(); 293 reply->writeInt32(status); 294 if (camera != NULL) { 295 reply->writeInt32(1); 296 reply->writeStrongBinder(camera->asBinder()); 297 } else { 298 reply->writeInt32(0); 299 } 300 return NO_ERROR; 301 } break; 302 case ADD_LISTENER: { 303 CHECK_INTERFACE(ICameraService, data, reply); 304 sp<ICameraServiceListener> listener = 305 interface_cast<ICameraServiceListener>(data.readStrongBinder()); 306 reply->writeNoException(); 307 reply->writeInt32(addListener(listener)); 308 return NO_ERROR; 309 } break; 310 case REMOVE_LISTENER: { 311 CHECK_INTERFACE(ICameraService, data, reply); 312 sp<ICameraServiceListener> listener = 313 interface_cast<ICameraServiceListener>(data.readStrongBinder()); 314 reply->writeNoException(); 315 reply->writeInt32(removeListener(listener)); 316 return NO_ERROR; 317 } break; 318 default: 319 return BBinder::onTransact(code, data, reply, flags); 320 } 321} 322 323// ---------------------------------------------------------------------------- 324 325}; // namespace android 326