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