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
41 namespace android {
42
43 namespace {
44
45 enum {
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
readExceptionCode(Parcel & reply)54 static 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
90 class BpCameraService: public BpInterface<ICameraService>
91 {
92 public:
BpCameraService(const sp<IBinder> & impl)93 BpCameraService(const sp<IBinder>& impl)
94 : BpInterface<ICameraService>(impl)
95 {
96 }
97
98 // get number of cameras available
getNumberOfCameras()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
getCameraInfo(int cameraId,struct CameraInfo * cameraInfo)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)
getCameraCharacteristics(int cameraId,CameraMetadata * cameraInfo)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
getCameraVendorTagDescriptor(sp<VendorTagDescriptor> & desc)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)
connect(const sp<ICameraClient> & cameraClient,int cameraId,const String16 & clientPackageName,int clientUid,sp<ICamera> & device)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)
connectLegacy(const sp<ICameraClient> & cameraClient,int cameraId,int halVersion,const String16 & clientPackageName,int clientUid,sp<ICamera> & device)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)
connectPro(const sp<IProCameraCallbacks> & cameraCb,int cameraId,const String16 & clientPackageName,int clientUid,sp<IProCameraUser> & device)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)
connectDevice(const sp<ICameraDeviceCallbacks> & cameraCb,int cameraId,const String16 & clientPackageName,int clientUid,sp<ICameraDeviceUser> & device)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
addListener(const sp<ICameraServiceListener> & listener)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
removeListener(const sp<ICameraServiceListener> & listener)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
getLegacyParameters(int cameraId,String16 * parameters)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
supportsCameraApi(int cameraId,int apiVersion)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
317 IMPLEMENT_META_INTERFACE(CameraService, "android.hardware.ICameraService");
318
319 // ----------------------------------------------------------------------
320
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)321 status_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