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#include <utils/Errors.h> 21#include <utils/String16.h> 22 23#include <stdint.h> 24#include <sys/types.h> 25 26#include <binder/Parcel.h> 27#include <binder/IPCThreadState.h> 28#include <binder/IServiceManager.h> 29 30#include <camera/ICameraService.h> 31#include <camera/ICameraServiceListener.h> 32#include <camera/IProCameraUser.h> 33#include <camera/IProCameraCallbacks.h> 34#include <camera/ICamera.h> 35#include <camera/ICameraClient.h> 36#include <camera/camera2/ICameraDeviceUser.h> 37#include <camera/camera2/ICameraDeviceCallbacks.h> 38#include <camera/CameraMetadata.h> 39#include <camera/VendorTagDescriptor.h> 40 41namespace android { 42 43namespace { 44 45enum { 46 EX_SECURITY = -1, 47 EX_BAD_PARCELABLE = -2, 48 EX_ILLEGAL_ARGUMENT = -3, 49 EX_NULL_POINTER = -4, 50 EX_ILLEGAL_STATE = -5, 51 EX_HAS_REPLY_HEADER = -128, // special; see below 52}; 53 54static bool readExceptionCode(Parcel& reply) { 55 int32_t exceptionCode = reply.readExceptionCode(); 56 57 if (exceptionCode != 0) { 58 const char* errorMsg; 59 switch(exceptionCode) { 60 case EX_SECURITY: 61 errorMsg = "Security"; 62 break; 63 case EX_BAD_PARCELABLE: 64 errorMsg = "BadParcelable"; 65 break; 66 case EX_NULL_POINTER: 67 errorMsg = "NullPointer"; 68 break; 69 case EX_ILLEGAL_STATE: 70 errorMsg = "IllegalState"; 71 break; 72 // Binder should be handling this code inside Parcel::readException 73 // but lets have a to-string here anyway just in case. 74 case EX_HAS_REPLY_HEADER: 75 errorMsg = "HasReplyHeader"; 76 break; 77 default: 78 errorMsg = "Unknown"; 79 } 80 81 ALOGE("Binder transmission error %s (%d)", errorMsg, exceptionCode); 82 return true; 83 } 84 85 return false; 86} 87 88}; 89 90class BpCameraService: public BpInterface<ICameraService> 91{ 92public: 93 BpCameraService(const sp<IBinder>& impl) 94 : BpInterface<ICameraService>(impl) 95 { 96 } 97 98 // get number of cameras available 99 virtual int32_t getNumberOfCameras() 100 { 101 Parcel data, reply; 102 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); 103 remote()->transact(BnCameraService::GET_NUMBER_OF_CAMERAS, data, &reply); 104 105 if (readExceptionCode(reply)) return 0; 106 return reply.readInt32(); 107 } 108 109 // get information about a camera 110 virtual status_t getCameraInfo(int cameraId, 111 struct CameraInfo* cameraInfo) { 112 Parcel data, reply; 113 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); 114 data.writeInt32(cameraId); 115 remote()->transact(BnCameraService::GET_CAMERA_INFO, data, &reply); 116 117 if (readExceptionCode(reply)) return -EPROTO; 118 status_t result = reply.readInt32(); 119 if (reply.readInt32() != 0) { 120 cameraInfo->facing = reply.readInt32(); 121 cameraInfo->orientation = reply.readInt32(); 122 } 123 return result; 124 } 125 126 // get camera characteristics (static metadata) 127 virtual status_t getCameraCharacteristics(int cameraId, 128 CameraMetadata* cameraInfo) { 129 Parcel data, reply; 130 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); 131 data.writeInt32(cameraId); 132 remote()->transact(BnCameraService::GET_CAMERA_CHARACTERISTICS, data, &reply); 133 134 if (readExceptionCode(reply)) return -EPROTO; 135 status_t result = reply.readInt32(); 136 137 CameraMetadata out; 138 if (reply.readInt32() != 0) { 139 out.readFromParcel(&reply); 140 } 141 142 if (cameraInfo != NULL) { 143 cameraInfo->swap(out); 144 } 145 146 return result; 147 } 148 149 // Get enumeration and description of vendor tags for camera 150 virtual status_t getCameraVendorTagDescriptor(/*out*/sp<VendorTagDescriptor>& desc) { 151 Parcel data, reply; 152 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); 153 remote()->transact(BnCameraService::GET_CAMERA_VENDOR_TAG_DESCRIPTOR, data, &reply); 154 155 if (readExceptionCode(reply)) return -EPROTO; 156 status_t result = reply.readInt32(); 157 158 if (reply.readInt32() != 0) { 159 sp<VendorTagDescriptor> d; 160 if (VendorTagDescriptor::createFromParcel(&reply, /*out*/d) == OK) { 161 desc = d; 162 } 163 } 164 return result; 165 } 166 167 // connect to camera service (android.hardware.Camera) 168 virtual status_t connect(const sp<ICameraClient>& cameraClient, int cameraId, 169 const String16 &clientPackageName, int clientUid, 170 /*out*/ 171 sp<ICamera>& device) 172 { 173 Parcel data, reply; 174 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); 175 data.writeStrongBinder(cameraClient->asBinder()); 176 data.writeInt32(cameraId); 177 data.writeString16(clientPackageName); 178 data.writeInt32(clientUid); 179 remote()->transact(BnCameraService::CONNECT, data, &reply); 180 181 if (readExceptionCode(reply)) return -EPROTO; 182 status_t status = reply.readInt32(); 183 if (reply.readInt32() != 0) { 184 device = interface_cast<ICamera>(reply.readStrongBinder()); 185 } 186 return status; 187 } 188 189 // connect to camera service (android.hardware.Camera) 190 virtual status_t connectLegacy(const sp<ICameraClient>& cameraClient, int cameraId, 191 int halVersion, 192 const String16 &clientPackageName, int clientUid, 193 /*out*/sp<ICamera>& device) 194 { 195 Parcel data, reply; 196 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); 197 data.writeStrongBinder(cameraClient->asBinder()); 198 data.writeInt32(cameraId); 199 data.writeInt32(halVersion); 200 data.writeString16(clientPackageName); 201 data.writeInt32(clientUid); 202 remote()->transact(BnCameraService::CONNECT_LEGACY, data, &reply); 203 204 if (readExceptionCode(reply)) return -EPROTO; 205 status_t status = reply.readInt32(); 206 if (reply.readInt32() != 0) { 207 device = interface_cast<ICamera>(reply.readStrongBinder()); 208 } 209 return status; 210 } 211 212 // connect to camera service (pro client) 213 virtual status_t connectPro(const sp<IProCameraCallbacks>& cameraCb, int cameraId, 214 const String16 &clientPackageName, int clientUid, 215 /*out*/ 216 sp<IProCameraUser>& device) 217 { 218 Parcel data, reply; 219 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); 220 data.writeStrongBinder(cameraCb->asBinder()); 221 data.writeInt32(cameraId); 222 data.writeString16(clientPackageName); 223 data.writeInt32(clientUid); 224 remote()->transact(BnCameraService::CONNECT_PRO, data, &reply); 225 226 if (readExceptionCode(reply)) return -EPROTO; 227 status_t status = reply.readInt32(); 228 if (reply.readInt32() != 0) { 229 device = interface_cast<IProCameraUser>(reply.readStrongBinder()); 230 } 231 return status; 232 } 233 234 // connect to camera service (android.hardware.camera2.CameraDevice) 235 virtual status_t connectDevice( 236 const sp<ICameraDeviceCallbacks>& cameraCb, 237 int cameraId, 238 const String16& clientPackageName, 239 int clientUid, 240 /*out*/ 241 sp<ICameraDeviceUser>& device) 242 { 243 Parcel data, reply; 244 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); 245 data.writeStrongBinder(cameraCb->asBinder()); 246 data.writeInt32(cameraId); 247 data.writeString16(clientPackageName); 248 data.writeInt32(clientUid); 249 remote()->transact(BnCameraService::CONNECT_DEVICE, data, &reply); 250 251 if (readExceptionCode(reply)) return -EPROTO; 252 status_t status = reply.readInt32(); 253 if (reply.readInt32() != 0) { 254 device = interface_cast<ICameraDeviceUser>(reply.readStrongBinder()); 255 } 256 return status; 257 } 258 259 virtual status_t addListener(const sp<ICameraServiceListener>& listener) 260 { 261 Parcel data, reply; 262 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); 263 data.writeStrongBinder(listener->asBinder()); 264 remote()->transact(BnCameraService::ADD_LISTENER, data, &reply); 265 266 if (readExceptionCode(reply)) return -EPROTO; 267 return reply.readInt32(); 268 } 269 270 virtual status_t removeListener(const sp<ICameraServiceListener>& listener) 271 { 272 Parcel data, reply; 273 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); 274 data.writeStrongBinder(listener->asBinder()); 275 remote()->transact(BnCameraService::REMOVE_LISTENER, data, &reply); 276 277 if (readExceptionCode(reply)) return -EPROTO; 278 return reply.readInt32(); 279 } 280 281 virtual status_t getLegacyParameters(int cameraId, String16* parameters) { 282 if (parameters == NULL) { 283 ALOGE("%s: parameters must not be null", __FUNCTION__); 284 return BAD_VALUE; 285 } 286 287 Parcel data, reply; 288 289 data.writeInt32(cameraId); 290 remote()->transact(BnCameraService::GET_LEGACY_PARAMETERS, data, &reply); 291 if (readExceptionCode(reply)) return -EPROTO; 292 293 status_t res = data.readInt32(); 294 int32_t length = data.readInt32(); // -1 means null 295 if (length > 0) { 296 *parameters = data.readString16(); 297 } else { 298 *parameters = String16(); 299 } 300 301 return res; 302 } 303 304 virtual status_t supportsCameraApi(int cameraId, int apiVersion) { 305 Parcel data, reply; 306 307 data.writeInt32(cameraId); 308 data.writeInt32(apiVersion); 309 remote()->transact(BnCameraService::SUPPORTS_CAMERA_API, data, &reply); 310 if (readExceptionCode(reply)) return -EPROTO; 311 312 status_t res = data.readInt32(); 313 return res; 314 } 315}; 316 317IMPLEMENT_META_INTERFACE(CameraService, "android.hardware.ICameraService"); 318 319// ---------------------------------------------------------------------- 320 321status_t BnCameraService::onTransact( 322 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 323{ 324 switch(code) { 325 case GET_NUMBER_OF_CAMERAS: { 326 CHECK_INTERFACE(ICameraService, data, reply); 327 reply->writeNoException(); 328 reply->writeInt32(getNumberOfCameras()); 329 return NO_ERROR; 330 } break; 331 case GET_CAMERA_INFO: { 332 CHECK_INTERFACE(ICameraService, data, reply); 333 CameraInfo cameraInfo = CameraInfo(); 334 memset(&cameraInfo, 0, sizeof(cameraInfo)); 335 status_t result = getCameraInfo(data.readInt32(), &cameraInfo); 336 reply->writeNoException(); 337 reply->writeInt32(result); 338 339 // Fake a parcelable object here 340 reply->writeInt32(1); // means the parcelable is included 341 reply->writeInt32(cameraInfo.facing); 342 reply->writeInt32(cameraInfo.orientation); 343 return NO_ERROR; 344 } break; 345 case GET_CAMERA_CHARACTERISTICS: { 346 CHECK_INTERFACE(ICameraService, data, reply); 347 CameraMetadata info; 348 status_t result = getCameraCharacteristics(data.readInt32(), &info); 349 reply->writeNoException(); 350 reply->writeInt32(result); 351 352 // out-variables are after exception and return value 353 reply->writeInt32(1); // means the parcelable is included 354 info.writeToParcel(reply); 355 return NO_ERROR; 356 } break; 357 case GET_CAMERA_VENDOR_TAG_DESCRIPTOR: { 358 CHECK_INTERFACE(ICameraService, data, reply); 359 sp<VendorTagDescriptor> d; 360 status_t result = getCameraVendorTagDescriptor(d); 361 reply->writeNoException(); 362 reply->writeInt32(result); 363 364 // out-variables are after exception and return value 365 if (d == NULL) { 366 reply->writeInt32(0); 367 } else { 368 reply->writeInt32(1); // means the parcelable is included 369 d->writeToParcel(reply); 370 } 371 return NO_ERROR; 372 } break; 373 case CONNECT: { 374 CHECK_INTERFACE(ICameraService, data, reply); 375 sp<ICameraClient> cameraClient = 376 interface_cast<ICameraClient>(data.readStrongBinder()); 377 int32_t cameraId = data.readInt32(); 378 const String16 clientName = data.readString16(); 379 int32_t clientUid = data.readInt32(); 380 sp<ICamera> camera; 381 status_t status = connect(cameraClient, cameraId, 382 clientName, clientUid, /*out*/camera); 383 reply->writeNoException(); 384 reply->writeInt32(status); 385 if (camera != NULL) { 386 reply->writeInt32(1); 387 reply->writeStrongBinder(camera->asBinder()); 388 } else { 389 reply->writeInt32(0); 390 } 391 return NO_ERROR; 392 } break; 393 case CONNECT_PRO: { 394 CHECK_INTERFACE(ICameraService, data, reply); 395 sp<IProCameraCallbacks> cameraClient = 396 interface_cast<IProCameraCallbacks>(data.readStrongBinder()); 397 int32_t cameraId = data.readInt32(); 398 const String16 clientName = data.readString16(); 399 int32_t clientUid = data.readInt32(); 400 sp<IProCameraUser> camera; 401 status_t status = connectPro(cameraClient, cameraId, 402 clientName, clientUid, /*out*/camera); 403 reply->writeNoException(); 404 reply->writeInt32(status); 405 if (camera != NULL) { 406 reply->writeInt32(1); 407 reply->writeStrongBinder(camera->asBinder()); 408 } else { 409 reply->writeInt32(0); 410 } 411 return NO_ERROR; 412 } break; 413 case CONNECT_DEVICE: { 414 CHECK_INTERFACE(ICameraService, data, reply); 415 sp<ICameraDeviceCallbacks> cameraClient = 416 interface_cast<ICameraDeviceCallbacks>(data.readStrongBinder()); 417 int32_t cameraId = data.readInt32(); 418 const String16 clientName = data.readString16(); 419 int32_t clientUid = data.readInt32(); 420 sp<ICameraDeviceUser> camera; 421 status_t status = connectDevice(cameraClient, cameraId, 422 clientName, clientUid, /*out*/camera); 423 reply->writeNoException(); 424 reply->writeInt32(status); 425 if (camera != NULL) { 426 reply->writeInt32(1); 427 reply->writeStrongBinder(camera->asBinder()); 428 } else { 429 reply->writeInt32(0); 430 } 431 return NO_ERROR; 432 } break; 433 case ADD_LISTENER: { 434 CHECK_INTERFACE(ICameraService, data, reply); 435 sp<ICameraServiceListener> listener = 436 interface_cast<ICameraServiceListener>(data.readStrongBinder()); 437 reply->writeNoException(); 438 reply->writeInt32(addListener(listener)); 439 return NO_ERROR; 440 } break; 441 case REMOVE_LISTENER: { 442 CHECK_INTERFACE(ICameraService, data, reply); 443 sp<ICameraServiceListener> listener = 444 interface_cast<ICameraServiceListener>(data.readStrongBinder()); 445 reply->writeNoException(); 446 reply->writeInt32(removeListener(listener)); 447 return NO_ERROR; 448 } break; 449 case GET_LEGACY_PARAMETERS: { 450 CHECK_INTERFACE(ICameraService, data, reply); 451 int cameraId = data.readInt32(); 452 String16 parameters; 453 454 reply->writeNoException(); 455 // return value 456 reply->writeInt32(getLegacyParameters(cameraId, ¶meters)); 457 // out parameters 458 reply->writeInt32(1); // parameters is always available 459 reply->writeString16(parameters); 460 return NO_ERROR; 461 } break; 462 case SUPPORTS_CAMERA_API: { 463 CHECK_INTERFACE(ICameraService, data, reply); 464 int cameraId = data.readInt32(); 465 int apiVersion = data.readInt32(); 466 467 reply->writeNoException(); 468 // return value 469 reply->writeInt32(supportsCameraApi(cameraId, apiVersion)); 470 return NO_ERROR; 471 } break; 472 case CONNECT_LEGACY: { 473 CHECK_INTERFACE(ICameraService, data, reply); 474 sp<ICameraClient> cameraClient = 475 interface_cast<ICameraClient>(data.readStrongBinder()); 476 int32_t cameraId = data.readInt32(); 477 int32_t halVersion = data.readInt32(); 478 const String16 clientName = data.readString16(); 479 int32_t clientUid = data.readInt32(); 480 sp<ICamera> camera; 481 status_t status = connectLegacy(cameraClient, cameraId, halVersion, 482 clientName, clientUid, /*out*/camera); 483 reply->writeNoException(); 484 reply->writeInt32(status); 485 if (camera != NULL) { 486 reply->writeInt32(1); 487 reply->writeStrongBinder(camera->asBinder()); 488 } else { 489 reply->writeInt32(0); 490 } 491 return NO_ERROR; 492 } break; 493 default: 494 return BBinder::onTransact(code, data, reply, flags); 495 } 496} 497 498// ---------------------------------------------------------------------------- 499 500}; // namespace android 501