ICameraService.cpp revision 2b59be89dc245b6e2475d9e8b0c5f2392370e71e
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#include <camera/CameraMetadata.h> 37 38namespace android { 39 40namespace { 41 42enum { 43 EX_SECURITY = -1, 44 EX_BAD_PARCELABLE = -2, 45 EX_ILLEGAL_ARGUMENT = -3, 46 EX_NULL_POINTER = -4, 47 EX_ILLEGAL_STATE = -5, 48 EX_HAS_REPLY_HEADER = -128, // special; see below 49}; 50 51static bool readExceptionCode(Parcel& reply) { 52 int32_t exceptionCode = reply.readExceptionCode(); 53 54 if (exceptionCode != 0) { 55 const char* errorMsg; 56 switch(exceptionCode) { 57 case EX_SECURITY: 58 errorMsg = "Security"; 59 break; 60 case EX_BAD_PARCELABLE: 61 errorMsg = "BadParcelable"; 62 break; 63 case EX_NULL_POINTER: 64 errorMsg = "NullPointer"; 65 break; 66 case EX_ILLEGAL_STATE: 67 errorMsg = "IllegalState"; 68 break; 69 // Binder should be handling this code inside Parcel::readException 70 // but lets have a to-string here anyway just in case. 71 case EX_HAS_REPLY_HEADER: 72 errorMsg = "HasReplyHeader"; 73 break; 74 default: 75 errorMsg = "Unknown"; 76 } 77 78 ALOGE("Binder transmission error %s (%d)", errorMsg, exceptionCode); 79 return true; 80 } 81 82 return false; 83} 84 85}; 86 87class BpCameraService: public BpInterface<ICameraService> 88{ 89public: 90 BpCameraService(const sp<IBinder>& impl) 91 : BpInterface<ICameraService>(impl) 92 { 93 } 94 95 // get number of cameras available 96 virtual int32_t getNumberOfCameras() 97 { 98 Parcel data, reply; 99 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); 100 remote()->transact(BnCameraService::GET_NUMBER_OF_CAMERAS, data, &reply); 101 102 if (readExceptionCode(reply)) return 0; 103 return reply.readInt32(); 104 } 105 106 // get information about a camera 107 virtual status_t getCameraInfo(int cameraId, 108 struct CameraInfo* cameraInfo) { 109 Parcel data, reply; 110 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); 111 data.writeInt32(cameraId); 112 remote()->transact(BnCameraService::GET_CAMERA_INFO, data, &reply); 113 114 if (readExceptionCode(reply)) return -EPROTO; 115 status_t result = reply.readInt32(); 116 if (reply.readInt32() != 0) { 117 cameraInfo->facing = reply.readInt32(); 118 cameraInfo->orientation = reply.readInt32(); 119 } 120 return result; 121 } 122 123 // get camera characteristics (static metadata) 124 virtual status_t getCameraCharacteristics(int cameraId, 125 CameraMetadata* cameraInfo) { 126 Parcel data, reply; 127 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); 128 data.writeInt32(cameraId); 129 remote()->transact(BnCameraService::GET_CAMERA_CHARACTERISTICS, data, &reply); 130 131 if (readExceptionCode(reply)) return -EPROTO; 132 status_t result = reply.readInt32(); 133 134 CameraMetadata out; 135 if (reply.readInt32() != 0) { 136 out.readFromParcel(&reply); 137 } 138 139 if (cameraInfo != NULL) { 140 cameraInfo->swap(out); 141 } 142 143 return result; 144 } 145 146 // connect to camera service (android.hardware.Camera) 147 virtual status_t connect(const sp<ICameraClient>& cameraClient, int cameraId, 148 const String16 &clientPackageName, int clientUid, 149 /*out*/ 150 sp<ICamera>& device) 151 { 152 Parcel data, reply; 153 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); 154 data.writeStrongBinder(cameraClient->asBinder()); 155 data.writeInt32(cameraId); 156 data.writeString16(clientPackageName); 157 data.writeInt32(clientUid); 158 remote()->transact(BnCameraService::CONNECT, data, &reply); 159 160 if (readExceptionCode(reply)) return -EPROTO; 161 status_t status = reply.readInt32(); 162 if (reply.readInt32() != 0) { 163 device = interface_cast<ICamera>(reply.readStrongBinder()); 164 } 165 return status; 166 } 167 168 // connect to camera service (pro client) 169 virtual status_t connectPro(const sp<IProCameraCallbacks>& cameraCb, int cameraId, 170 const String16 &clientPackageName, int clientUid, 171 /*out*/ 172 sp<IProCameraUser>& device) 173 { 174 Parcel data, reply; 175 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); 176 data.writeStrongBinder(cameraCb->asBinder()); 177 data.writeInt32(cameraId); 178 data.writeString16(clientPackageName); 179 data.writeInt32(clientUid); 180 remote()->transact(BnCameraService::CONNECT_PRO, data, &reply); 181 182 if (readExceptionCode(reply)) return -EPROTO; 183 status_t status = reply.readInt32(); 184 if (reply.readInt32() != 0) { 185 device = interface_cast<IProCameraUser>(reply.readStrongBinder()); 186 } 187 return status; 188 } 189 190 // connect to camera service (android.hardware.camera2.CameraDevice) 191 virtual status_t connectDevice( 192 const sp<ICameraDeviceCallbacks>& cameraCb, 193 int cameraId, 194 const String16& clientPackageName, 195 int clientUid, 196 /*out*/ 197 sp<ICameraDeviceUser>& device) 198 { 199 Parcel data, reply; 200 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); 201 data.writeStrongBinder(cameraCb->asBinder()); 202 data.writeInt32(cameraId); 203 data.writeString16(clientPackageName); 204 data.writeInt32(clientUid); 205 remote()->transact(BnCameraService::CONNECT_DEVICE, data, &reply); 206 207 if (readExceptionCode(reply)) return -EPROTO; 208 status_t status = reply.readInt32(); 209 if (reply.readInt32() != 0) { 210 device = interface_cast<ICameraDeviceUser>(reply.readStrongBinder()); 211 } 212 return status; 213 } 214 215 virtual status_t addListener(const sp<ICameraServiceListener>& listener) 216 { 217 Parcel data, reply; 218 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); 219 data.writeStrongBinder(listener->asBinder()); 220 remote()->transact(BnCameraService::ADD_LISTENER, data, &reply); 221 222 if (readExceptionCode(reply)) return -EPROTO; 223 return reply.readInt32(); 224 } 225 226 virtual status_t removeListener(const sp<ICameraServiceListener>& listener) 227 { 228 Parcel data, reply; 229 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); 230 data.writeStrongBinder(listener->asBinder()); 231 remote()->transact(BnCameraService::REMOVE_LISTENER, data, &reply); 232 233 if (readExceptionCode(reply)) return -EPROTO; 234 return reply.readInt32(); 235 } 236}; 237 238IMPLEMENT_META_INTERFACE(CameraService, "android.hardware.ICameraService"); 239 240// ---------------------------------------------------------------------- 241 242status_t BnCameraService::onTransact( 243 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 244{ 245 switch(code) { 246 case GET_NUMBER_OF_CAMERAS: { 247 CHECK_INTERFACE(ICameraService, data, reply); 248 reply->writeNoException(); 249 reply->writeInt32(getNumberOfCameras()); 250 return NO_ERROR; 251 } break; 252 case GET_CAMERA_INFO: { 253 CHECK_INTERFACE(ICameraService, data, reply); 254 CameraInfo cameraInfo = CameraInfo(); 255 memset(&cameraInfo, 0, sizeof(cameraInfo)); 256 status_t result = getCameraInfo(data.readInt32(), &cameraInfo); 257 reply->writeNoException(); 258 reply->writeInt32(result); 259 260 // Fake a parcelable object here 261 reply->writeInt32(1); // means the parcelable is included 262 reply->writeInt32(cameraInfo.facing); 263 reply->writeInt32(cameraInfo.orientation); 264 return NO_ERROR; 265 } break; 266 case GET_CAMERA_CHARACTERISTICS: { 267 CHECK_INTERFACE(ICameraService, data, reply); 268 CameraMetadata info; 269 status_t result = getCameraCharacteristics(data.readInt32(), &info); 270 reply->writeNoException(); 271 reply->writeInt32(result); 272 273 // out-variables are after exception and return value 274 reply->writeInt32(1); // means the parcelable is included 275 info.writeToParcel(reply); 276 return NO_ERROR; 277 } break; 278 case CONNECT: { 279 CHECK_INTERFACE(ICameraService, data, reply); 280 sp<ICameraClient> cameraClient = 281 interface_cast<ICameraClient>(data.readStrongBinder()); 282 int32_t cameraId = data.readInt32(); 283 const String16 clientName = data.readString16(); 284 int32_t clientUid = data.readInt32(); 285 sp<ICamera> camera; 286 status_t status = connect(cameraClient, cameraId, 287 clientName, clientUid, /*out*/ camera); 288 reply->writeNoException(); 289 reply->writeInt32(status); 290 if (camera != NULL) { 291 reply->writeInt32(1); 292 reply->writeStrongBinder(camera->asBinder()); 293 } else { 294 reply->writeInt32(0); 295 } 296 return NO_ERROR; 297 } break; 298 case CONNECT_PRO: { 299 CHECK_INTERFACE(ICameraService, data, reply); 300 sp<IProCameraCallbacks> cameraClient = 301 interface_cast<IProCameraCallbacks>(data.readStrongBinder()); 302 int32_t cameraId = data.readInt32(); 303 const String16 clientName = data.readString16(); 304 int32_t clientUid = data.readInt32(); 305 sp<IProCameraUser> camera; 306 status_t status = connectPro(cameraClient, cameraId, 307 clientName, clientUid, /*out*/ camera); 308 reply->writeNoException(); 309 reply->writeInt32(status); 310 if (camera != NULL) { 311 reply->writeInt32(1); 312 reply->writeStrongBinder(camera->asBinder()); 313 } else { 314 reply->writeInt32(0); 315 } 316 return NO_ERROR; 317 } break; 318 case CONNECT_DEVICE: { 319 CHECK_INTERFACE(ICameraService, data, reply); 320 sp<ICameraDeviceCallbacks> cameraClient = 321 interface_cast<ICameraDeviceCallbacks>(data.readStrongBinder()); 322 int32_t cameraId = data.readInt32(); 323 const String16 clientName = data.readString16(); 324 int32_t clientUid = data.readInt32(); 325 sp<ICameraDeviceUser> camera; 326 status_t status = connectDevice(cameraClient, cameraId, 327 clientName, clientUid, /*out*/ camera); 328 reply->writeNoException(); 329 reply->writeInt32(status); 330 if (camera != NULL) { 331 reply->writeInt32(1); 332 reply->writeStrongBinder(camera->asBinder()); 333 } else { 334 reply->writeInt32(0); 335 } 336 return NO_ERROR; 337 } break; 338 case ADD_LISTENER: { 339 CHECK_INTERFACE(ICameraService, data, reply); 340 sp<ICameraServiceListener> listener = 341 interface_cast<ICameraServiceListener>(data.readStrongBinder()); 342 reply->writeNoException(); 343 reply->writeInt32(addListener(listener)); 344 return NO_ERROR; 345 } break; 346 case REMOVE_LISTENER: { 347 CHECK_INTERFACE(ICameraService, data, reply); 348 sp<ICameraServiceListener> listener = 349 interface_cast<ICameraServiceListener>(data.readStrongBinder()); 350 reply->writeNoException(); 351 reply->writeInt32(removeListener(listener)); 352 return NO_ERROR; 353 } break; 354 default: 355 return BBinder::onTransact(code, data, reply, flags); 356 } 357} 358 359// ---------------------------------------------------------------------------- 360 361}; // namespace android 362