ICameraDeviceUser.cpp revision 88aef23d00a509693a955b6a207c0fb023fbc92d
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    CANCEL_REQUEST,
39    DELETE_STREAM,
40    CREATE_STREAM,
41    CREATE_DEFAULT_REQUEST,
42    GET_CAMERA_INFO,
43    WAIT_UNTIL_IDLE,
44};
45
46namespace {
47    // Read empty strings without printing a false error message.
48    String16 readMaybeEmptyString16(const Parcel& parcel) {
49        size_t len;
50        const char16_t* str = parcel.readString16Inplace(&len);
51        if (str != NULL) {
52            return String16(str, len);
53        } else {
54            return String16();
55        }
56    }
57};
58
59class BpCameraDeviceUser : public BpInterface<ICameraDeviceUser>
60{
61public:
62    BpCameraDeviceUser(const sp<IBinder>& impl)
63        : BpInterface<ICameraDeviceUser>(impl)
64    {
65    }
66
67    // disconnect from camera service
68    void disconnect()
69    {
70        ALOGV("disconnect");
71        Parcel data, reply;
72        data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
73        remote()->transact(DISCONNECT, data, &reply);
74        reply.readExceptionCode();
75    }
76
77    virtual int submitRequest(sp<CaptureRequest> request, bool streaming)
78    {
79        Parcel data, reply;
80        data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
81
82        // arg0 = CaptureRequest
83        if (request != 0) {
84            data.writeInt32(1);
85            request->writeToParcel(&data);
86        } else {
87            data.writeInt32(0);
88        }
89
90        // arg1 = streaming (bool)
91        data.writeInt32(streaming);
92
93        remote()->transact(SUBMIT_REQUEST, data, &reply);
94
95        reply.readExceptionCode();
96        return reply.readInt32();
97    }
98
99    virtual status_t cancelRequest(int requestId)
100    {
101        Parcel data, reply;
102        data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
103        data.writeInt32(requestId);
104
105        remote()->transact(CANCEL_REQUEST, data, &reply);
106
107        reply.readExceptionCode();
108        return reply.readInt32();
109    }
110
111    virtual status_t deleteStream(int streamId)
112    {
113        Parcel data, reply;
114        data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
115        data.writeInt32(streamId);
116
117        remote()->transact(DELETE_STREAM, data, &reply);
118
119        reply.readExceptionCode();
120        return reply.readInt32();
121    }
122
123    virtual status_t createStream(int width, int height, int format,
124                          const sp<IGraphicBufferProducer>& bufferProducer)
125    {
126        Parcel data, reply;
127        data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
128        data.writeInt32(width);
129        data.writeInt32(height);
130        data.writeInt32(format);
131
132        data.writeInt32(1); // marker that bufferProducer is not null
133        data.writeString16(String16("unknown_name")); // name of surface
134        sp<IBinder> b(bufferProducer->asBinder());
135        data.writeStrongBinder(b);
136
137        remote()->transact(CREATE_STREAM, data, &reply);
138
139        reply.readExceptionCode();
140        return reply.readInt32();
141    }
142
143    // Create a request object from a template.
144    virtual status_t createDefaultRequest(int templateId,
145                                          /*out*/
146                                          CameraMetadata* request)
147    {
148        Parcel data, reply;
149        data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
150        data.writeInt32(templateId);
151        remote()->transact(CREATE_DEFAULT_REQUEST, data, &reply);
152
153        reply.readExceptionCode();
154        status_t result = reply.readInt32();
155
156        CameraMetadata out;
157        if (reply.readInt32() != 0) {
158            out.readFromParcel(&reply);
159        }
160
161        if (request != NULL) {
162            request->swap(out);
163        }
164        return result;
165    }
166
167
168    virtual status_t getCameraInfo(CameraMetadata* info)
169    {
170        Parcel data, reply;
171        data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
172        remote()->transact(GET_CAMERA_INFO, data, &reply);
173
174        reply.readExceptionCode();
175        status_t result = reply.readInt32();
176
177        CameraMetadata out;
178        if (reply.readInt32() != 0) {
179            out.readFromParcel(&reply);
180        }
181
182        if (info != NULL) {
183            info->swap(out);
184        }
185
186        return result;
187    }
188
189    virtual status_t waitUntilIdle()
190    {
191        ALOGV("waitUntilIdle");
192        Parcel data, reply;
193        data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
194        remote()->transact(WAIT_UNTIL_IDLE, data, &reply);
195        reply.readExceptionCode();
196        return reply.readInt32();
197    }
198
199private:
200
201
202};
203
204IMPLEMENT_META_INTERFACE(CameraDeviceUser,
205                         "android.hardware.camera2.ICameraDeviceUser");
206
207// ----------------------------------------------------------------------
208
209status_t BnCameraDeviceUser::onTransact(
210    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
211{
212    switch(code) {
213        case DISCONNECT: {
214            ALOGV("DISCONNECT");
215            CHECK_INTERFACE(ICameraDeviceUser, data, reply);
216            disconnect();
217            reply->writeNoException();
218            return NO_ERROR;
219        } break;
220        case SUBMIT_REQUEST: {
221            CHECK_INTERFACE(ICameraDeviceUser, data, reply);
222
223            // arg0 = request
224            sp<CaptureRequest> request;
225            if (data.readInt32() != 0) {
226                request = new CaptureRequest();
227                request->readFromParcel(const_cast<Parcel*>(&data));
228            }
229
230            // arg1 = streaming (bool)
231            bool streaming = data.readInt32();
232
233            // return code: requestId (int32)
234            reply->writeNoException();
235            reply->writeInt32(submitRequest(request, streaming));
236
237            return NO_ERROR;
238        } break;
239        case CANCEL_REQUEST: {
240            CHECK_INTERFACE(ICameraDeviceUser, data, reply);
241            int requestId = data.readInt32();
242            reply->writeNoException();
243            reply->writeInt32(cancelRequest(requestId));
244            return NO_ERROR;
245        } break;
246        case DELETE_STREAM: {
247            CHECK_INTERFACE(ICameraDeviceUser, data, reply);
248            int streamId = data.readInt32();
249            reply->writeNoException();
250            reply->writeInt32(deleteStream(streamId));
251            return NO_ERROR;
252        } break;
253        case CREATE_STREAM: {
254            CHECK_INTERFACE(ICameraDeviceUser, data, reply);
255            int width, height, format;
256
257            width = data.readInt32();
258            ALOGV("%s: CREATE_STREAM: width = %d", __FUNCTION__, width);
259            height = data.readInt32();
260            ALOGV("%s: CREATE_STREAM: height = %d", __FUNCTION__, height);
261            format = data.readInt32();
262            ALOGV("%s: CREATE_STREAM: format = %d", __FUNCTION__, format);
263
264            sp<IGraphicBufferProducer> bp;
265            if (data.readInt32() != 0) {
266                String16 name = readMaybeEmptyString16(data);
267                bp = interface_cast<IGraphicBufferProducer>(
268                        data.readStrongBinder());
269
270                ALOGV("%s: CREATE_STREAM: bp = %p, name = %s", __FUNCTION__,
271                      bp.get(), String8(name).string());
272            } else {
273                ALOGV("%s: CREATE_STREAM: bp = unset, name = unset",
274                      __FUNCTION__);
275            }
276
277            status_t ret;
278            ret = createStream(width, height, format, bp);
279
280            reply->writeNoException();
281            ALOGV("%s: CREATE_STREAM: write noException", __FUNCTION__);
282            reply->writeInt32(ret);
283            ALOGV("%s: CREATE_STREAM: write ret = %d", __FUNCTION__, ret);
284
285            return NO_ERROR;
286        } break;
287
288        case CREATE_DEFAULT_REQUEST: {
289            CHECK_INTERFACE(ICameraDeviceUser, data, reply);
290
291            int templateId = data.readInt32();
292
293            CameraMetadata request;
294            status_t ret;
295            ret = createDefaultRequest(templateId, &request);
296
297            reply->writeNoException();
298            reply->writeInt32(ret);
299
300            // out-variables are after exception and return value
301            reply->writeInt32(1); // to mark presence of metadata object
302            request.writeToParcel(const_cast<Parcel*>(reply));
303
304            return NO_ERROR;
305        } break;
306        case GET_CAMERA_INFO: {
307            CHECK_INTERFACE(ICameraDeviceUser, data, reply);
308
309            CameraMetadata info;
310            status_t ret;
311            ret = getCameraInfo(&info);
312
313            reply->writeNoException();
314            reply->writeInt32(ret);
315
316            // out-variables are after exception and return value
317            reply->writeInt32(1); // to mark presence of metadata object
318            info.writeToParcel(reply);
319
320            return NO_ERROR;
321        } break;
322        case WAIT_UNTIL_IDLE: {
323            CHECK_INTERFACE(ICameraDeviceUser, data, reply);
324            reply->writeNoException();
325            reply->writeInt32(waitUntilIdle());
326            return NO_ERROR;
327        } break;
328        default:
329            return BBinder::onTransact(code, data, reply, flags);
330    }
331}
332
333// ----------------------------------------------------------------------------
334
335}; // namespace android
336