ICameraDeviceUser.cpp revision cb0652e5a850b2fcd919e977247e87239efaf70e
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
30namespace android {
31
32typedef Parcel::WritableBlob WritableBlob;
33typedef Parcel::ReadableBlob ReadableBlob;
34
35enum {
36    DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
37    SUBMIT_REQUEST,
38    SUBMIT_REQUEST_LIST,
39    CANCEL_REQUEST,
40    DELETE_STREAM,
41    CREATE_STREAM,
42    CREATE_DEFAULT_REQUEST,
43    GET_CAMERA_INFO,
44    WAIT_UNTIL_IDLE,
45    FLUSH
46};
47
48namespace {
49    // Read empty strings without printing a false error message.
50    String16 readMaybeEmptyString16(const Parcel& parcel) {
51        size_t len;
52        const char16_t* str = parcel.readString16Inplace(&len);
53        if (str != NULL) {
54            return String16(str, len);
55        } else {
56            return String16();
57        }
58    }
59};
60
61class BpCameraDeviceUser : public BpInterface<ICameraDeviceUser>
62{
63public:
64    BpCameraDeviceUser(const sp<IBinder>& impl)
65        : BpInterface<ICameraDeviceUser>(impl)
66    {
67    }
68
69    // disconnect from camera service
70    void disconnect()
71    {
72        ALOGV("disconnect");
73        Parcel data, reply;
74        data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
75        remote()->transact(DISCONNECT, data, &reply);
76        reply.readExceptionCode();
77    }
78
79    virtual status_t submitRequest(sp<CaptureRequest> request, bool repeating,
80                              int64_t *lastFrameNumber)
81    {
82        Parcel data, reply;
83        data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
84
85        // arg0 = CaptureRequest
86        if (request != 0) {
87            data.writeInt32(1);
88            request->writeToParcel(&data);
89        } else {
90            data.writeInt32(0);
91        }
92
93        // arg1 = streaming (bool)
94        data.writeInt32(repeating);
95
96        remote()->transact(SUBMIT_REQUEST, data, &reply);
97
98        reply.readExceptionCode();
99        status_t res = reply.readInt32();
100
101        status_t resFrameNumber = BAD_VALUE;
102        if (reply.readInt32() != 0) {
103            if (lastFrameNumber != NULL) {
104                resFrameNumber = reply.readInt64(lastFrameNumber);
105            }
106        }
107
108	if ((res != NO_ERROR) || (resFrameNumber != NO_ERROR)) {
109            res = FAILED_TRANSACTION;
110        }
111        return res;
112    }
113
114    virtual status_t submitRequestList(List<sp<CaptureRequest> > requestList, bool repeating,
115                                  int64_t *lastFrameNumber)
116    {
117        Parcel data, reply;
118        data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
119
120        data.writeInt32(requestList.size());
121
122        for (List<sp<CaptureRequest> >::iterator it = requestList.begin();
123                it != requestList.end(); ++it) {
124            sp<CaptureRequest> request = *it;
125            if (request != 0) {
126                data.writeInt32(1);
127                if (request->writeToParcel(&data) != OK) {
128                    return BAD_VALUE;
129                }
130            } else {
131                data.writeInt32(0);
132            }
133        }
134
135        data.writeInt32(repeating);
136
137        remote()->transact(SUBMIT_REQUEST_LIST, data, &reply);
138
139        reply.readExceptionCode();
140        status_t res = reply.readInt32();
141
142        status_t resFrameNumber = BAD_VALUE;
143        if (reply.readInt32() != 0) {
144            if (lastFrameNumber != NULL) {
145                resFrameNumber = reply.readInt64(lastFrameNumber);
146            }
147        }
148        if ((res != NO_ERROR) || (resFrameNumber != NO_ERROR)) {
149            res = FAILED_TRANSACTION;
150        }
151        return res;
152    }
153
154    virtual status_t cancelRequest(int requestId, int64_t *lastFrameNumber)
155    {
156        Parcel data, reply;
157        data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
158        data.writeInt32(requestId);
159
160        remote()->transact(CANCEL_REQUEST, data, &reply);
161
162        reply.readExceptionCode();
163        status_t res = reply.readInt32();
164
165        status_t resFrameNumber = BAD_VALUE;
166        if (reply.readInt32() != 0) {
167            if (lastFrameNumber != NULL) {
168                res = reply.readInt64(lastFrameNumber);
169            }
170        }
171        if ((res != NO_ERROR) || (resFrameNumber != NO_ERROR)) {
172            res = FAILED_TRANSACTION;
173        }
174        return res;
175    }
176
177    virtual status_t deleteStream(int streamId)
178    {
179        Parcel data, reply;
180        data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
181        data.writeInt32(streamId);
182
183        remote()->transact(DELETE_STREAM, data, &reply);
184
185        reply.readExceptionCode();
186        return reply.readInt32();
187    }
188
189    virtual status_t createStream(int width, int height, int format,
190                          const sp<IGraphicBufferProducer>& bufferProducer)
191    {
192        Parcel data, reply;
193        data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
194        data.writeInt32(width);
195        data.writeInt32(height);
196        data.writeInt32(format);
197
198        data.writeInt32(1); // marker that bufferProducer is not null
199        data.writeString16(String16("unknown_name")); // name of surface
200        sp<IBinder> b(bufferProducer->asBinder());
201        data.writeStrongBinder(b);
202
203        remote()->transact(CREATE_STREAM, data, &reply);
204
205        reply.readExceptionCode();
206        return reply.readInt32();
207    }
208
209    // Create a request object from a template.
210    virtual status_t createDefaultRequest(int templateId,
211                                          /*out*/
212                                          CameraMetadata* request)
213    {
214        Parcel data, reply;
215        data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
216        data.writeInt32(templateId);
217        remote()->transact(CREATE_DEFAULT_REQUEST, data, &reply);
218
219        reply.readExceptionCode();
220        status_t result = reply.readInt32();
221
222        CameraMetadata out;
223        if (reply.readInt32() != 0) {
224            out.readFromParcel(&reply);
225        }
226
227        if (request != NULL) {
228            request->swap(out);
229        }
230        return result;
231    }
232
233
234    virtual status_t getCameraInfo(CameraMetadata* info)
235    {
236        Parcel data, reply;
237        data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
238        remote()->transact(GET_CAMERA_INFO, data, &reply);
239
240        reply.readExceptionCode();
241        status_t result = reply.readInt32();
242
243        CameraMetadata out;
244        if (reply.readInt32() != 0) {
245            out.readFromParcel(&reply);
246        }
247
248        if (info != NULL) {
249            info->swap(out);
250        }
251
252        return result;
253    }
254
255    virtual status_t waitUntilIdle()
256    {
257        ALOGV("waitUntilIdle");
258        Parcel data, reply;
259        data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
260        remote()->transact(WAIT_UNTIL_IDLE, data, &reply);
261        reply.readExceptionCode();
262        return reply.readInt32();
263    }
264
265    virtual status_t flush(int64_t *lastFrameNumber)
266    {
267        ALOGV("flush");
268        Parcel data, reply;
269        data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
270        remote()->transact(FLUSH, data, &reply);
271        reply.readExceptionCode();
272        status_t res = reply.readInt32();
273
274        status_t resFrameNumber = BAD_VALUE;
275        if (reply.readInt32() != 0) {
276            if (lastFrameNumber != NULL) {
277                res = reply.readInt64(lastFrameNumber);
278            }
279        }
280        if ((res != NO_ERROR) || (resFrameNumber != NO_ERROR)) {
281            res = FAILED_TRANSACTION;
282        }
283        return res;
284    }
285
286private:
287
288
289};
290
291IMPLEMENT_META_INTERFACE(CameraDeviceUser,
292                         "android.hardware.camera2.ICameraDeviceUser");
293
294// ----------------------------------------------------------------------
295
296status_t BnCameraDeviceUser::onTransact(
297    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
298{
299    switch(code) {
300        case DISCONNECT: {
301            ALOGV("DISCONNECT");
302            CHECK_INTERFACE(ICameraDeviceUser, data, reply);
303            disconnect();
304            reply->writeNoException();
305            return NO_ERROR;
306        } break;
307        case SUBMIT_REQUEST: {
308            CHECK_INTERFACE(ICameraDeviceUser, data, reply);
309
310            // arg0 = request
311            sp<CaptureRequest> request;
312            if (data.readInt32() != 0) {
313                request = new CaptureRequest();
314                request->readFromParcel(const_cast<Parcel*>(&data));
315            }
316
317            // arg1 = streaming (bool)
318            bool repeating = data.readInt32();
319
320            // return code: requestId (int32)
321            reply->writeNoException();
322            int64_t lastFrameNumber = -1;
323            reply->writeInt32(submitRequest(request, repeating, &lastFrameNumber));
324            reply->writeInt32(1);
325            reply->writeInt64(lastFrameNumber);
326
327            return NO_ERROR;
328        } break;
329        case SUBMIT_REQUEST_LIST: {
330            CHECK_INTERFACE(ICameraDeviceUser, data, reply);
331
332            List<sp<CaptureRequest> > requestList;
333            int requestListSize = data.readInt32();
334            for (int i = 0; i < requestListSize; i++) {
335                if (data.readInt32() != 0) {
336                    sp<CaptureRequest> request = new CaptureRequest();
337                    if (request->readFromParcel(const_cast<Parcel*>(&data)) != OK) {
338                        return BAD_VALUE;
339                    }
340                    requestList.push_back(request);
341                } else {
342                    sp<CaptureRequest> request = 0;
343                    requestList.push_back(request);
344                    ALOGE("A request is missing. Sending in null request.");
345                }
346            }
347
348            bool repeating = data.readInt32();
349
350            reply->writeNoException();
351            int64_t lastFrameNumber = -1;
352            reply->writeInt32(submitRequestList(requestList, repeating, &lastFrameNumber));
353            reply->writeInt32(1);
354            reply->writeInt64(lastFrameNumber);
355
356            return NO_ERROR;
357        } break;
358        case CANCEL_REQUEST: {
359            CHECK_INTERFACE(ICameraDeviceUser, data, reply);
360            int requestId = data.readInt32();
361            reply->writeNoException();
362            int64_t lastFrameNumber = -1;
363            reply->writeInt32(cancelRequest(requestId, &lastFrameNumber));
364            reply->writeInt32(1);
365            reply->writeInt64(lastFrameNumber);
366            return NO_ERROR;
367        } break;
368        case DELETE_STREAM: {
369            CHECK_INTERFACE(ICameraDeviceUser, data, reply);
370            int streamId = data.readInt32();
371            reply->writeNoException();
372            reply->writeInt32(deleteStream(streamId));
373            return NO_ERROR;
374        } break;
375        case CREATE_STREAM: {
376            CHECK_INTERFACE(ICameraDeviceUser, data, reply);
377            int width, height, format;
378
379            width = data.readInt32();
380            ALOGV("%s: CREATE_STREAM: width = %d", __FUNCTION__, width);
381            height = data.readInt32();
382            ALOGV("%s: CREATE_STREAM: height = %d", __FUNCTION__, height);
383            format = data.readInt32();
384            ALOGV("%s: CREATE_STREAM: format = %d", __FUNCTION__, format);
385
386            sp<IGraphicBufferProducer> bp;
387            if (data.readInt32() != 0) {
388                String16 name = readMaybeEmptyString16(data);
389                bp = interface_cast<IGraphicBufferProducer>(
390                        data.readStrongBinder());
391
392                ALOGV("%s: CREATE_STREAM: bp = %p, name = %s", __FUNCTION__,
393                      bp.get(), String8(name).string());
394            } else {
395                ALOGV("%s: CREATE_STREAM: bp = unset, name = unset",
396                      __FUNCTION__);
397            }
398
399            status_t ret;
400            ret = createStream(width, height, format, bp);
401
402            reply->writeNoException();
403            ALOGV("%s: CREATE_STREAM: write noException", __FUNCTION__);
404            reply->writeInt32(ret);
405            ALOGV("%s: CREATE_STREAM: write ret = %d", __FUNCTION__, ret);
406
407            return NO_ERROR;
408        } break;
409
410        case CREATE_DEFAULT_REQUEST: {
411            CHECK_INTERFACE(ICameraDeviceUser, data, reply);
412
413            int templateId = data.readInt32();
414
415            CameraMetadata request;
416            status_t ret;
417            ret = createDefaultRequest(templateId, &request);
418
419            reply->writeNoException();
420            reply->writeInt32(ret);
421
422            // out-variables are after exception and return value
423            reply->writeInt32(1); // to mark presence of metadata object
424            request.writeToParcel(const_cast<Parcel*>(reply));
425
426            return NO_ERROR;
427        } break;
428        case GET_CAMERA_INFO: {
429            CHECK_INTERFACE(ICameraDeviceUser, data, reply);
430
431            CameraMetadata info;
432            status_t ret;
433            ret = getCameraInfo(&info);
434
435            reply->writeNoException();
436            reply->writeInt32(ret);
437
438            // out-variables are after exception and return value
439            reply->writeInt32(1); // to mark presence of metadata object
440            info.writeToParcel(reply);
441
442            return NO_ERROR;
443        } break;
444        case WAIT_UNTIL_IDLE: {
445            CHECK_INTERFACE(ICameraDeviceUser, data, reply);
446            reply->writeNoException();
447            reply->writeInt32(waitUntilIdle());
448            return NO_ERROR;
449        } break;
450        case FLUSH: {
451            CHECK_INTERFACE(ICameraDeviceUser, data, reply);
452            reply->writeNoException();
453            int64_t lastFrameNumber = -1;
454            reply->writeInt32(flush(&lastFrameNumber));
455            reply->writeInt32(1);
456            reply->writeInt64(lastFrameNumber);
457            return NO_ERROR;
458        }
459        default:
460            return BBinder::onTransact(code, data, reply, flags);
461    }
462}
463
464// ----------------------------------------------------------------------------
465
466}; // namespace android
467