3 ** Copyright 2008, The Android Open Source Project
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
9 ** http://www.apache.org/licenses/LICENSE-2.0
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.
18 #define LOG_TAG "BpCameraService"
19 #include <utils/Log.h>
20 #include <utils/Errors.h>
21 #include <utils/String16.h>
25 #include <sys/types.h>
27 #include <binder/Parcel.h>
28 #include <binder/IPCThreadState.h>
29 #include <binder/IServiceManager.h>
31 #include <camera/ICameraService.h>
32 #include <camera/ICameraServiceListener.h>
33 #include <camera/ICamera.h>
34 #include <camera/ICameraClient.h>
35 #include <camera/camera2/ICameraDeviceUser.h>
36 #include <camera/camera2/ICameraDeviceCallbacks.h>
37 #include <camera/CameraMetadata.h>
38 #include <camera/VendorTagDescriptor.h>
46 EX_BAD_PARCELABLE = -2,
47 EX_ILLEGAL_ARGUMENT = -3,
49 EX_ILLEGAL_STATE = -5,
50 EX_HAS_REPLY_HEADER = -128, // special; see below
53 static bool readExceptionCode(Parcel& reply) {
54 int32_t exceptionCode = reply.readExceptionCode();
56 if (exceptionCode != 0) {
58 switch(exceptionCode) {
60 errorMsg = "Security";
62 case EX_BAD_PARCELABLE:
63 errorMsg = "BadParcelable";
66 errorMsg = "NullPointer";
68 case EX_ILLEGAL_STATE:
69 errorMsg = "IllegalState";
71 // Binder should be handling this code inside Parcel::readException
72 // but lets have a to-string here anyway just in case.
73 case EX_HAS_REPLY_HEADER:
74 errorMsg = "HasReplyHeader";
80 ALOGE("Binder transmission error %s (%d)", errorMsg, exceptionCode);
89 class BpCameraService: public BpInterface<ICameraService>
92 BpCameraService(const sp<IBinder>& impl)
93 : BpInterface<ICameraService>(impl)
97 // get number of cameras available that support standard camera operations
98 virtual int32_t getNumberOfCameras()
100 return getNumberOfCameras(CAMERA_TYPE_BACKWARD_COMPATIBLE);
103 // get number of cameras available of a given type
104 virtual int32_t getNumberOfCameras(int type)
107 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
108 data.writeInt32(type);
109 remote()->transact(BnCameraService::GET_NUMBER_OF_CAMERAS, data, &reply);
111 if (readExceptionCode(reply)) return 0;
112 return reply.readInt32();
115 // get information about a camera
116 virtual status_t getCameraInfo(int cameraId,
117 struct CameraInfo* cameraInfo) {
119 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
120 data.writeInt32(cameraId);
121 remote()->transact(BnCameraService::GET_CAMERA_INFO, data, &reply);
123 if (readExceptionCode(reply)) return -EPROTO;
124 status_t result = reply.readInt32();
125 if (reply.readInt32() != 0) {
126 cameraInfo->facing = reply.readInt32();
127 cameraInfo->orientation = reply.readInt32();
132 // get camera characteristics (static metadata)
133 virtual status_t getCameraCharacteristics(int cameraId,
134 CameraMetadata* cameraInfo) {
136 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
137 data.writeInt32(cameraId);
138 remote()->transact(BnCameraService::GET_CAMERA_CHARACTERISTICS, data, &reply);
140 if (readExceptionCode(reply)) return -EPROTO;
141 status_t result = reply.readInt32();
144 if (reply.readInt32() != 0) {
145 out.readFromParcel(&reply);
148 if (cameraInfo != NULL) {
149 cameraInfo->swap(out);
155 // Get enumeration and description of vendor tags for camera
156 virtual status_t getCameraVendorTagDescriptor(/*out*/sp<VendorTagDescriptor>& desc) {
158 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
159 remote()->transact(BnCameraService::GET_CAMERA_VENDOR_TAG_DESCRIPTOR, data, &reply);
161 if (readExceptionCode(reply)) return -EPROTO;
162 status_t result = reply.readInt32();
164 if (reply.readInt32() != 0) {
165 sp<VendorTagDescriptor> d;
166 if (VendorTagDescriptor::createFromParcel(&reply, /*out*/d) == OK) {
173 // connect to camera service (android.hardware.Camera)
174 virtual status_t connect(const sp<ICameraClient>& cameraClient, int cameraId,
175 const String16 &clientPackageName, int clientUid,
180 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
181 data.writeStrongBinder(IInterface::asBinder(cameraClient));
182 data.writeInt32(cameraId);
183 data.writeString16(clientPackageName);
184 data.writeInt32(clientUid);
187 status = remote()->transact(BnCameraService::CONNECT, data, &reply);
188 if (status != OK) return status;
190 if (readExceptionCode(reply)) return -EPROTO;
191 status = reply.readInt32();
192 if (reply.readInt32() != 0) {
193 device = interface_cast<ICamera>(reply.readStrongBinder());
198 // connect to camera service (android.hardware.Camera)
199 virtual status_t connectLegacy(const sp<ICameraClient>& cameraClient, int cameraId,
201 const String16 &clientPackageName, int clientUid,
202 /*out*/sp<ICamera>& device)
205 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
206 data.writeStrongBinder(IInterface::asBinder(cameraClient));
207 data.writeInt32(cameraId);
208 data.writeInt32(halVersion);
209 data.writeString16(clientPackageName);
210 data.writeInt32(clientUid);
213 status = remote()->transact(BnCameraService::CONNECT_LEGACY, data, &reply);
214 if (status != OK) return status;
216 if (readExceptionCode(reply)) return -EPROTO;
217 status = reply.readInt32();
218 if (reply.readInt32() != 0) {
219 device = interface_cast<ICamera>(reply.readStrongBinder());
224 virtual status_t setTorchMode(const String16& cameraId, bool enabled,
225 const sp<IBinder>& clientBinder)
228 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
229 data.writeString16(cameraId);
230 data.writeInt32(enabled ? 1 : 0);
231 data.writeStrongBinder(clientBinder);
232 remote()->transact(BnCameraService::SET_TORCH_MODE, data, &reply);
234 if (readExceptionCode(reply)) return -EPROTO;
235 return reply.readInt32();
238 // connect to camera service (android.hardware.camera2.CameraDevice)
239 virtual status_t connectDevice(
240 const sp<ICameraDeviceCallbacks>& cameraCb,
242 const String16& clientPackageName,
245 sp<ICameraDeviceUser>& device)
248 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
249 data.writeStrongBinder(IInterface::asBinder(cameraCb));
250 data.writeInt32(cameraId);
251 data.writeString16(clientPackageName);
252 data.writeInt32(clientUid);
255 status = remote()->transact(BnCameraService::CONNECT_DEVICE, data, &reply);
256 if (status != OK) return status;
258 if (readExceptionCode(reply)) return -EPROTO;
259 status = reply.readInt32();
260 if (reply.readInt32() != 0) {
261 device = interface_cast<ICameraDeviceUser>(reply.readStrongBinder());
266 virtual status_t addListener(const sp<ICameraServiceListener>& listener)
269 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
270 data.writeStrongBinder(IInterface::asBinder(listener));
271 remote()->transact(BnCameraService::ADD_LISTENER, data, &reply);
273 if (readExceptionCode(reply)) return -EPROTO;
274 return reply.readInt32();
277 virtual status_t removeListener(const sp<ICameraServiceListener>& listener)
280 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
281 data.writeStrongBinder(IInterface::asBinder(listener));
282 remote()->transact(BnCameraService::REMOVE_LISTENER, data, &reply);
284 if (readExceptionCode(reply)) return -EPROTO;
285 return reply.readInt32();
288 virtual status_t getLegacyParameters(int cameraId, String16* parameters) {
289 if (parameters == NULL) {
290 ALOGE("%s: parameters must not be null", __FUNCTION__);
295 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
297 data.writeInt32(cameraId);
298 remote()->transact(BnCameraService::GET_LEGACY_PARAMETERS, data, &reply);
299 if (readExceptionCode(reply)) return -EPROTO;
301 status_t res = data.readInt32();
302 int32_t length = data.readInt32(); // -1 means null
304 *parameters = data.readString16();
306 *parameters = String16();
312 virtual status_t supportsCameraApi(int cameraId, int apiVersion) {
315 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
316 data.writeInt32(cameraId);
317 data.writeInt32(apiVersion);
318 remote()->transact(BnCameraService::SUPPORTS_CAMERA_API, data, &reply);
319 if (readExceptionCode(reply)) return -EPROTO;
321 status_t res = data.readInt32();
325 virtual void notifySystemEvent(int32_t eventId, const int32_t* args, size_t len) {
327 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
328 data.writeInt32(eventId);
329 data.writeInt32Array(len, args);
330 remote()->transact(BnCameraService::NOTIFY_SYSTEM_EVENT, data, &reply,
331 IBinder::FLAG_ONEWAY);
336 IMPLEMENT_META_INTERFACE(CameraService, "android.hardware.ICameraService");
338 // ----------------------------------------------------------------------
340 status_t BnCameraService::onTransact(
341 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
344 case GET_NUMBER_OF_CAMERAS: {
345 CHECK_INTERFACE(ICameraService, data, reply);
346 reply->writeNoException();
347 reply->writeInt32(getNumberOfCameras(data.readInt32()));
350 case GET_CAMERA_INFO: {
351 CHECK_INTERFACE(ICameraService, data, reply);
352 CameraInfo cameraInfo = CameraInfo();
353 memset(&cameraInfo, 0, sizeof(cameraInfo));
354 status_t result = getCameraInfo(data.readInt32(), &cameraInfo);
355 reply->writeNoException();
356 reply->writeInt32(result);
358 // Fake a parcelable object here
359 reply->writeInt32(1); // means the parcelable is included
360 reply->writeInt32(cameraInfo.facing);
361 reply->writeInt32(cameraInfo.orientation);
364 case GET_CAMERA_CHARACTERISTICS: {
365 CHECK_INTERFACE(ICameraService, data, reply);
367 status_t result = getCameraCharacteristics(data.readInt32(), &info);
368 reply->writeNoException();
369 reply->writeInt32(result);
371 // out-variables are after exception and return value
372 reply->writeInt32(1); // means the parcelable is included
373 info.writeToParcel(reply);
376 case GET_CAMERA_VENDOR_TAG_DESCRIPTOR: {
377 CHECK_INTERFACE(ICameraService, data, reply);
378 sp<VendorTagDescriptor> d;
379 status_t result = getCameraVendorTagDescriptor(d);
380 reply->writeNoException();
381 reply->writeInt32(result);
383 // out-variables are after exception and return value
385 reply->writeInt32(0);
387 reply->writeInt32(1); // means the parcelable is included
388 d->writeToParcel(reply);
393 CHECK_INTERFACE(ICameraService, data, reply);
394 sp<ICameraClient> cameraClient =
395 interface_cast<ICameraClient>(data.readStrongBinder());
396 int32_t cameraId = data.readInt32();
397 const String16 clientName = data.readString16();
398 int32_t clientUid = data.readInt32();
400 status_t status = connect(cameraClient, cameraId,
401 clientName, clientUid, /*out*/camera);
402 reply->writeNoException();
403 reply->writeInt32(status);
404 if (camera != NULL) {
405 reply->writeInt32(1);
406 reply->writeStrongBinder(IInterface::asBinder(camera));
408 reply->writeInt32(0);
412 case CONNECT_DEVICE: {
413 CHECK_INTERFACE(ICameraService, data, reply);
414 sp<ICameraDeviceCallbacks> cameraClient =
415 interface_cast<ICameraDeviceCallbacks>(data.readStrongBinder());
416 int32_t cameraId = data.readInt32();
417 const String16 clientName = data.readString16();
418 int32_t clientUid = data.readInt32();
419 sp<ICameraDeviceUser> camera;
420 status_t status = connectDevice(cameraClient, cameraId,
421 clientName, clientUid, /*out*/camera);
422 reply->writeNoException();
423 reply->writeInt32(status);
424 if (camera != NULL) {
425 reply->writeInt32(1);
426 reply->writeStrongBinder(IInterface::asBinder(camera));
428 reply->writeInt32(0);
433 CHECK_INTERFACE(ICameraService, data, reply);
434 sp<ICameraServiceListener> listener =
435 interface_cast<ICameraServiceListener>(data.readStrongBinder());
436 reply->writeNoException();
437 reply->writeInt32(addListener(listener));
440 case REMOVE_LISTENER: {
441 CHECK_INTERFACE(ICameraService, data, reply);
442 sp<ICameraServiceListener> listener =
443 interface_cast<ICameraServiceListener>(data.readStrongBinder());
444 reply->writeNoException();
445 reply->writeInt32(removeListener(listener));
448 case GET_LEGACY_PARAMETERS: {
449 CHECK_INTERFACE(ICameraService, data, reply);
450 int cameraId = data.readInt32();
453 reply->writeNoException();
455 reply->writeInt32(getLegacyParameters(cameraId, ¶meters));
457 reply->writeInt32(1); // parameters is always available
458 reply->writeString16(parameters);
461 case SUPPORTS_CAMERA_API: {
462 CHECK_INTERFACE(ICameraService, data, reply);
463 int cameraId = data.readInt32();
464 int apiVersion = data.readInt32();
466 reply->writeNoException();
468 reply->writeInt32(supportsCameraApi(cameraId, apiVersion));
471 case CONNECT_LEGACY: {
472 CHECK_INTERFACE(ICameraService, data, reply);
473 sp<ICameraClient> cameraClient =
474 interface_cast<ICameraClient>(data.readStrongBinder());
475 int32_t cameraId = data.readInt32();
476 int32_t halVersion = data.readInt32();
477 const String16 clientName = data.readString16();
478 int32_t clientUid = data.readInt32();
480 status_t status = connectLegacy(cameraClient, cameraId, halVersion,
481 clientName, clientUid, /*out*/camera);
482 reply->writeNoException();
483 reply->writeInt32(status);
484 if (camera != NULL) {
485 reply->writeInt32(1);
486 reply->writeStrongBinder(IInterface::asBinder(camera));
488 reply->writeInt32(0);
492 case SET_TORCH_MODE: {
493 CHECK_INTERFACE(ICameraService, data, reply);
494 String16 cameraId = data.readString16();
495 bool enabled = data.readInt32() != 0 ? true : false;
496 const sp<IBinder> clientBinder = data.readStrongBinder();
497 status_t status = setTorchMode(cameraId, enabled, clientBinder);
498 reply->writeNoException();
499 reply->writeInt32(status);
502 case NOTIFY_SYSTEM_EVENT: {
503 CHECK_INTERFACE(ICameraService, data, reply);
504 int32_t eventId = data.readInt32();
505 int32_t len = data.readInt32();
507 ALOGE("%s: Received poorly formatted length in binder request: notifySystemEvent.",
509 return FAILED_TRANSACTION;
512 ALOGE("%s: Length %" PRIi32 " too long in binder request: notifySystemEvent.",
514 return FAILED_TRANSACTION;
517 memset(events, 0, sizeof(int32_t) * len);
518 status_t status = data.read(events, sizeof(int32_t) * len);
519 if (status != NO_ERROR) {
520 ALOGE("%s: Received poorly formatted binder request: notifySystemEvent.",
522 return FAILED_TRANSACTION;
524 notifySystemEvent(eventId, events, len);
528 return BBinder::onTransact(code, data, reply, flags);
532 // ----------------------------------------------------------------------------
534 }; // namespace android