• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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