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