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