1 /*
2 **
3 ** Copyright 2013, 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_NDEBUG 0
19 #define LOG_TAG "ICameraDeviceUser"
20 #include <utils/Log.h>
21 #include <stdint.h>
22 #include <sys/types.h>
23 #include <binder/Parcel.h>
24 #include <camera/camera2/ICameraDeviceUser.h>
25 #include <gui/IGraphicBufferProducer.h>
26 #include <gui/Surface.h>
27 #include <camera/CameraMetadata.h>
28 #include <camera/camera2/CaptureRequest.h>
29 #include <camera/camera2/OutputConfiguration.h>
30
31 namespace android {
32
33 typedef Parcel::WritableBlob WritableBlob;
34 typedef Parcel::ReadableBlob ReadableBlob;
35
36 enum {
37 DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
38 SUBMIT_REQUEST,
39 SUBMIT_REQUEST_LIST,
40 CANCEL_REQUEST,
41 BEGIN_CONFIGURE,
42 END_CONFIGURE,
43 DELETE_STREAM,
44 CREATE_STREAM,
45 CREATE_INPUT_STREAM,
46 GET_INPUT_SURFACE,
47 CREATE_DEFAULT_REQUEST,
48 GET_CAMERA_INFO,
49 WAIT_UNTIL_IDLE,
50 FLUSH,
51 PREPARE,
52 TEAR_DOWN,
53 PREPARE2
54 };
55
56 namespace {
57 // Read empty strings without printing a false error message.
readMaybeEmptyString16(const Parcel & parcel)58 String16 readMaybeEmptyString16(const Parcel& parcel) {
59 size_t len;
60 const char16_t* str = parcel.readString16Inplace(&len);
61 if (str != NULL) {
62 return String16(str, len);
63 } else {
64 return String16();
65 }
66 }
67 };
68
69 class BpCameraDeviceUser : public BpInterface<ICameraDeviceUser>
70 {
71 public:
BpCameraDeviceUser(const sp<IBinder> & impl)72 BpCameraDeviceUser(const sp<IBinder>& impl)
73 : BpInterface<ICameraDeviceUser>(impl)
74 {
75 }
76
77 // disconnect from camera service
disconnect()78 void disconnect()
79 {
80 ALOGV("disconnect");
81 Parcel data, reply;
82 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
83 remote()->transact(DISCONNECT, data, &reply);
84 reply.readExceptionCode();
85 }
86
submitRequest(sp<CaptureRequest> request,bool repeating,int64_t * lastFrameNumber)87 virtual int submitRequest(sp<CaptureRequest> request, bool repeating,
88 int64_t *lastFrameNumber)
89 {
90 Parcel data, reply;
91 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
92
93 // arg0 = CaptureRequest
94 if (request != 0) {
95 data.writeInt32(1);
96 request->writeToParcel(&data);
97 } else {
98 data.writeInt32(0);
99 }
100
101 // arg1 = streaming (bool)
102 data.writeInt32(repeating);
103
104 remote()->transact(SUBMIT_REQUEST, data, &reply);
105
106 reply.readExceptionCode();
107 status_t res = reply.readInt32();
108
109 status_t resFrameNumber = BAD_VALUE;
110 if (reply.readInt32() != 0) {
111 if (lastFrameNumber != NULL) {
112 resFrameNumber = reply.readInt64(lastFrameNumber);
113 }
114 }
115
116 if (res < 0 || (resFrameNumber != NO_ERROR)) {
117 res = FAILED_TRANSACTION;
118 }
119 return res;
120 }
121
submitRequestList(List<sp<CaptureRequest>> requestList,bool repeating,int64_t * lastFrameNumber)122 virtual int submitRequestList(List<sp<CaptureRequest> > requestList, bool repeating,
123 int64_t *lastFrameNumber)
124 {
125 Parcel data, reply;
126 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
127
128 data.writeInt32(requestList.size());
129
130 for (List<sp<CaptureRequest> >::iterator it = requestList.begin();
131 it != requestList.end(); ++it) {
132 sp<CaptureRequest> request = *it;
133 if (request != 0) {
134 data.writeInt32(1);
135 if (request->writeToParcel(&data) != OK) {
136 return BAD_VALUE;
137 }
138 } else {
139 data.writeInt32(0);
140 }
141 }
142
143 data.writeInt32(repeating);
144
145 remote()->transact(SUBMIT_REQUEST_LIST, data, &reply);
146
147 reply.readExceptionCode();
148 status_t res = reply.readInt32();
149
150 status_t resFrameNumber = BAD_VALUE;
151 if (reply.readInt32() != 0) {
152 if (lastFrameNumber != NULL) {
153 resFrameNumber = reply.readInt64(lastFrameNumber);
154 }
155 }
156 if (res < 0 || (resFrameNumber != NO_ERROR)) {
157 res = FAILED_TRANSACTION;
158 }
159 return res;
160 }
161
cancelRequest(int requestId,int64_t * lastFrameNumber)162 virtual status_t cancelRequest(int requestId, int64_t *lastFrameNumber)
163 {
164 Parcel data, reply;
165 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
166 data.writeInt32(requestId);
167
168 remote()->transact(CANCEL_REQUEST, data, &reply);
169
170 reply.readExceptionCode();
171 status_t res = reply.readInt32();
172
173 status_t resFrameNumber = BAD_VALUE;
174 if (reply.readInt32() != 0) {
175 if (lastFrameNumber != NULL) {
176 resFrameNumber = reply.readInt64(lastFrameNumber);
177 }
178 }
179 if ((res != NO_ERROR) || (resFrameNumber != NO_ERROR)) {
180 res = FAILED_TRANSACTION;
181 }
182 return res;
183 }
184
beginConfigure()185 virtual status_t beginConfigure()
186 {
187 ALOGV("beginConfigure");
188 Parcel data, reply;
189 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
190 remote()->transact(BEGIN_CONFIGURE, data, &reply);
191 reply.readExceptionCode();
192 return reply.readInt32();
193 }
194
endConfigure(bool isConstrainedHighSpeed)195 virtual status_t endConfigure(bool isConstrainedHighSpeed)
196 {
197 ALOGV("endConfigure");
198 Parcel data, reply;
199 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
200 data.writeInt32(isConstrainedHighSpeed);
201
202 remote()->transact(END_CONFIGURE, data, &reply);
203 reply.readExceptionCode();
204 return reply.readInt32();
205 }
206
deleteStream(int streamId)207 virtual status_t deleteStream(int streamId)
208 {
209 Parcel data, reply;
210 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
211 data.writeInt32(streamId);
212
213 remote()->transact(DELETE_STREAM, data, &reply);
214
215 reply.readExceptionCode();
216 return reply.readInt32();
217 }
218
createStream(const OutputConfiguration & outputConfiguration)219 virtual status_t createStream(const OutputConfiguration& outputConfiguration)
220 {
221 Parcel data, reply;
222 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
223 if (outputConfiguration.getGraphicBufferProducer() != NULL) {
224 data.writeInt32(1); // marker that OutputConfiguration is not null. Mimic aidl behavior
225 outputConfiguration.writeToParcel(data);
226 } else {
227 data.writeInt32(0);
228 }
229 remote()->transact(CREATE_STREAM, data, &reply);
230
231 reply.readExceptionCode();
232 return reply.readInt32();
233 }
234
createInputStream(int width,int height,int format)235 virtual status_t createInputStream(int width, int height, int format)
236 {
237 Parcel data, reply;
238 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
239 data.writeInt32(width);
240 data.writeInt32(height);
241 data.writeInt32(format);
242
243 remote()->transact(CREATE_INPUT_STREAM, data, &reply);
244
245 reply.readExceptionCode();
246 return reply.readInt32();
247 }
248
249 // get the buffer producer of the input stream
getInputBufferProducer(sp<IGraphicBufferProducer> * producer)250 virtual status_t getInputBufferProducer(
251 sp<IGraphicBufferProducer> *producer) {
252 if (producer == NULL) {
253 return BAD_VALUE;
254 }
255
256 Parcel data, reply;
257 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
258
259 remote()->transact(GET_INPUT_SURFACE, data, &reply);
260
261 reply.readExceptionCode();
262 status_t result = reply.readInt32() ;
263 if (result != OK) {
264 return result;
265 }
266
267 sp<IGraphicBufferProducer> bp = NULL;
268 if (reply.readInt32() != 0) {
269 String16 name = readMaybeEmptyString16(reply);
270 bp = interface_cast<IGraphicBufferProducer>(
271 reply.readStrongBinder());
272 }
273
274 *producer = bp;
275
276 return *producer == NULL ? INVALID_OPERATION : OK;
277 }
278
279 // Create a request object from a template.
createDefaultRequest(int templateId,CameraMetadata * request)280 virtual status_t createDefaultRequest(int templateId,
281 /*out*/
282 CameraMetadata* request)
283 {
284 Parcel data, reply;
285 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
286 data.writeInt32(templateId);
287 remote()->transact(CREATE_DEFAULT_REQUEST, data, &reply);
288
289 reply.readExceptionCode();
290 status_t result = reply.readInt32();
291
292 CameraMetadata out;
293 if (reply.readInt32() != 0) {
294 out.readFromParcel(&reply);
295 }
296
297 if (request != NULL) {
298 request->swap(out);
299 }
300 return result;
301 }
302
303
getCameraInfo(CameraMetadata * info)304 virtual status_t getCameraInfo(CameraMetadata* info)
305 {
306 Parcel data, reply;
307 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
308 remote()->transact(GET_CAMERA_INFO, data, &reply);
309
310 reply.readExceptionCode();
311 status_t result = reply.readInt32();
312
313 CameraMetadata out;
314 if (reply.readInt32() != 0) {
315 out.readFromParcel(&reply);
316 }
317
318 if (info != NULL) {
319 info->swap(out);
320 }
321
322 return result;
323 }
324
waitUntilIdle()325 virtual status_t waitUntilIdle()
326 {
327 ALOGV("waitUntilIdle");
328 Parcel data, reply;
329 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
330 remote()->transact(WAIT_UNTIL_IDLE, data, &reply);
331 reply.readExceptionCode();
332 return reply.readInt32();
333 }
334
flush(int64_t * lastFrameNumber)335 virtual status_t flush(int64_t *lastFrameNumber)
336 {
337 ALOGV("flush");
338 Parcel data, reply;
339 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
340 remote()->transact(FLUSH, data, &reply);
341 reply.readExceptionCode();
342 status_t res = reply.readInt32();
343
344 status_t resFrameNumber = BAD_VALUE;
345 if (reply.readInt32() != 0) {
346 if (lastFrameNumber != NULL) {
347 resFrameNumber = reply.readInt64(lastFrameNumber);
348 }
349 }
350 if ((res != NO_ERROR) || (resFrameNumber != NO_ERROR)) {
351 res = FAILED_TRANSACTION;
352 }
353 return res;
354 }
355
prepare(int streamId)356 virtual status_t prepare(int streamId)
357 {
358 ALOGV("prepare");
359 Parcel data, reply;
360
361 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
362 data.writeInt32(streamId);
363
364 remote()->transact(PREPARE, data, &reply);
365
366 reply.readExceptionCode();
367 return reply.readInt32();
368 }
369
prepare2(int maxCount,int streamId)370 virtual status_t prepare2(int maxCount, int streamId)
371 {
372 ALOGV("prepare2");
373 Parcel data, reply;
374
375 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
376 data.writeInt32(maxCount);
377 data.writeInt32(streamId);
378
379 remote()->transact(PREPARE2, data, &reply);
380
381 reply.readExceptionCode();
382 return reply.readInt32();
383 }
384
tearDown(int streamId)385 virtual status_t tearDown(int streamId)
386 {
387 ALOGV("tearDown");
388 Parcel data, reply;
389
390 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
391 data.writeInt32(streamId);
392
393 remote()->transact(TEAR_DOWN, data, &reply);
394
395 reply.readExceptionCode();
396 return reply.readInt32();
397 }
398
399 private:
400
401
402 };
403
404 IMPLEMENT_META_INTERFACE(CameraDeviceUser,
405 "android.hardware.camera2.ICameraDeviceUser");
406
407 // ----------------------------------------------------------------------
408
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)409 status_t BnCameraDeviceUser::onTransact(
410 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
411 {
412 switch(code) {
413 case DISCONNECT: {
414 ALOGV("DISCONNECT");
415 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
416 disconnect();
417 reply->writeNoException();
418 return NO_ERROR;
419 } break;
420 case SUBMIT_REQUEST: {
421 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
422
423 // arg0 = request
424 sp<CaptureRequest> request;
425 if (data.readInt32() != 0) {
426 request = new CaptureRequest();
427 request->readFromParcel(const_cast<Parcel*>(&data));
428 }
429
430 // arg1 = streaming (bool)
431 bool repeating = data.readInt32();
432
433 // return code: requestId (int32)
434 reply->writeNoException();
435 int64_t lastFrameNumber = -1;
436 reply->writeInt32(submitRequest(request, repeating, &lastFrameNumber));
437 reply->writeInt32(1);
438 reply->writeInt64(lastFrameNumber);
439
440 return NO_ERROR;
441 } break;
442 case SUBMIT_REQUEST_LIST: {
443 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
444
445 List<sp<CaptureRequest> > requestList;
446 int requestListSize = data.readInt32();
447 for (int i = 0; i < requestListSize; i++) {
448 if (data.readInt32() != 0) {
449 sp<CaptureRequest> request = new CaptureRequest();
450 if (request->readFromParcel(const_cast<Parcel*>(&data)) != OK) {
451 return BAD_VALUE;
452 }
453 requestList.push_back(request);
454 } else {
455 sp<CaptureRequest> request = 0;
456 requestList.push_back(request);
457 ALOGE("A request is missing. Sending in null request.");
458 }
459 }
460
461 bool repeating = data.readInt32();
462
463 reply->writeNoException();
464 int64_t lastFrameNumber = -1;
465 reply->writeInt32(submitRequestList(requestList, repeating, &lastFrameNumber));
466 reply->writeInt32(1);
467 reply->writeInt64(lastFrameNumber);
468
469 return NO_ERROR;
470 } break;
471 case CANCEL_REQUEST: {
472 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
473 int requestId = data.readInt32();
474 reply->writeNoException();
475 int64_t lastFrameNumber = -1;
476 reply->writeInt32(cancelRequest(requestId, &lastFrameNumber));
477 reply->writeInt32(1);
478 reply->writeInt64(lastFrameNumber);
479 return NO_ERROR;
480 } break;
481 case DELETE_STREAM: {
482 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
483 int streamId = data.readInt32();
484 reply->writeNoException();
485 reply->writeInt32(deleteStream(streamId));
486 return NO_ERROR;
487 } break;
488 case CREATE_STREAM: {
489 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
490
491 status_t ret = BAD_VALUE;
492 if (data.readInt32() != 0) {
493 OutputConfiguration outputConfiguration(data);
494 ret = createStream(outputConfiguration);
495 } else {
496 ALOGE("%s: cannot take an empty OutputConfiguration", __FUNCTION__);
497 }
498
499 reply->writeNoException();
500 ALOGV("%s: CREATE_STREAM: write noException", __FUNCTION__);
501 reply->writeInt32(ret);
502 ALOGV("%s: CREATE_STREAM: write ret = %d", __FUNCTION__, ret);
503
504 return NO_ERROR;
505 } break;
506 case CREATE_INPUT_STREAM: {
507 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
508 int width, height, format;
509
510 width = data.readInt32();
511 height = data.readInt32();
512 format = data.readInt32();
513 status_t ret = createInputStream(width, height, format);
514
515 reply->writeNoException();
516 reply->writeInt32(ret);
517 return NO_ERROR;
518
519 } break;
520 case GET_INPUT_SURFACE: {
521 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
522
523 sp<IGraphicBufferProducer> bp;
524 status_t ret = getInputBufferProducer(&bp);
525 sp<IBinder> b(IInterface::asBinder(ret == OK ? bp : NULL));
526
527 reply->writeNoException();
528 reply->writeInt32(ret);
529 reply->writeInt32(1);
530 reply->writeString16(String16("camera input")); // name of surface
531 reply->writeStrongBinder(b);
532
533 return NO_ERROR;
534 } break;
535 case CREATE_DEFAULT_REQUEST: {
536 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
537
538 int templateId = data.readInt32();
539
540 CameraMetadata request;
541 status_t ret;
542 ret = createDefaultRequest(templateId, &request);
543
544 reply->writeNoException();
545 reply->writeInt32(ret);
546
547 // out-variables are after exception and return value
548 reply->writeInt32(1); // to mark presence of metadata object
549 request.writeToParcel(const_cast<Parcel*>(reply));
550
551 return NO_ERROR;
552 } break;
553 case GET_CAMERA_INFO: {
554 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
555
556 CameraMetadata info;
557 status_t ret;
558 ret = getCameraInfo(&info);
559
560 reply->writeNoException();
561 reply->writeInt32(ret);
562
563 // out-variables are after exception and return value
564 reply->writeInt32(1); // to mark presence of metadata object
565 info.writeToParcel(reply);
566
567 return NO_ERROR;
568 } break;
569 case WAIT_UNTIL_IDLE: {
570 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
571 reply->writeNoException();
572 reply->writeInt32(waitUntilIdle());
573 return NO_ERROR;
574 } break;
575 case FLUSH: {
576 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
577 reply->writeNoException();
578 int64_t lastFrameNumber = -1;
579 reply->writeInt32(flush(&lastFrameNumber));
580 reply->writeInt32(1);
581 reply->writeInt64(lastFrameNumber);
582 return NO_ERROR;
583 }
584 case BEGIN_CONFIGURE: {
585 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
586 reply->writeNoException();
587 reply->writeInt32(beginConfigure());
588 return NO_ERROR;
589 } break;
590 case END_CONFIGURE: {
591 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
592 bool isConstrainedHighSpeed = data.readInt32();
593 reply->writeNoException();
594 reply->writeInt32(endConfigure(isConstrainedHighSpeed));
595 return NO_ERROR;
596 } break;
597 case PREPARE: {
598 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
599 int streamId = data.readInt32();
600 reply->writeNoException();
601 reply->writeInt32(prepare(streamId));
602 return NO_ERROR;
603 } break;
604 case TEAR_DOWN: {
605 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
606 int streamId = data.readInt32();
607 reply->writeNoException();
608 reply->writeInt32(tearDown(streamId));
609 return NO_ERROR;
610 } break;
611 case PREPARE2: {
612 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
613 int maxCount = data.readInt32();
614 int streamId = data.readInt32();
615 reply->writeNoException();
616 reply->writeInt32(prepare2(maxCount, streamId));
617 return NO_ERROR;
618 } break;
619 default:
620 return BBinder::onTransact(code, data, reply, flags);
621 }
622 }
623
624 // ----------------------------------------------------------------------------
625
626 }; // namespace android
627