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 "IProCameraUser"
20#include <utils/Log.h>
21#include <stdint.h>
22#include <sys/types.h>
23#include <binder/Parcel.h>
24#include <camera/IProCameraUser.h>
25#include <gui/IGraphicBufferProducer.h>
26#include <gui/Surface.h>
27#include "camera/CameraMetadata.h"
28
29namespace android {
30
31enum {
32    DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
33    CONNECT,
34    EXCLUSIVE_TRY_LOCK,
35    EXCLUSIVE_LOCK,
36    EXCLUSIVE_UNLOCK,
37    HAS_EXCLUSIVE_LOCK,
38    SUBMIT_REQUEST,
39    CANCEL_REQUEST,
40    DELETE_STREAM,
41    CREATE_STREAM,
42    CREATE_DEFAULT_REQUEST,
43    GET_CAMERA_INFO,
44};
45
46class BpProCameraUser: public BpInterface<IProCameraUser>
47{
48public:
49    BpProCameraUser(const sp<IBinder>& impl)
50        : BpInterface<IProCameraUser>(impl)
51    {
52    }
53
54    // disconnect from camera service
55    void disconnect()
56    {
57        ALOGV("disconnect");
58        Parcel data, reply;
59        data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
60        remote()->transact(DISCONNECT, data, &reply);
61        reply.readExceptionCode();
62    }
63
64    virtual status_t connect(const sp<IProCameraCallbacks>& cameraClient)
65    {
66        Parcel data, reply;
67        data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
68        data.writeStrongBinder(cameraClient->asBinder());
69        remote()->transact(CONNECT, data, &reply);
70        return reply.readInt32();
71    }
72
73    /* Shared ProCameraUser */
74
75    virtual status_t exclusiveTryLock()
76    {
77        Parcel data, reply;
78        data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
79        remote()->transact(EXCLUSIVE_TRY_LOCK, data, &reply);
80        return reply.readInt32();
81    }
82    virtual status_t exclusiveLock()
83    {
84        Parcel data, reply;
85        data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
86        remote()->transact(EXCLUSIVE_LOCK, data, &reply);
87        return reply.readInt32();
88    }
89
90    virtual status_t exclusiveUnlock()
91    {
92        Parcel data, reply;
93        data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
94        remote()->transact(EXCLUSIVE_UNLOCK, data, &reply);
95        return reply.readInt32();
96    }
97
98    virtual bool hasExclusiveLock()
99    {
100        Parcel data, reply;
101        data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
102        remote()->transact(HAS_EXCLUSIVE_LOCK, data, &reply);
103        return !!reply.readInt32();
104    }
105
106    virtual int submitRequest(camera_metadata_t* metadata, bool streaming)
107    {
108
109        Parcel data, reply;
110        data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
111
112        // arg0+arg1
113        CameraMetadata::writeToParcel(data, metadata);
114
115        // arg2 = streaming (bool)
116        data.writeInt32(streaming);
117
118        remote()->transact(SUBMIT_REQUEST, data, &reply);
119        return reply.readInt32();
120    }
121
122    virtual status_t cancelRequest(int requestId)
123    {
124        Parcel data, reply;
125        data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
126        data.writeInt32(requestId);
127
128        remote()->transact(CANCEL_REQUEST, data, &reply);
129        return reply.readInt32();
130    }
131
132    virtual status_t deleteStream(int streamId)
133    {
134        Parcel data, reply;
135        data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
136        data.writeInt32(streamId);
137
138        remote()->transact(DELETE_STREAM, data, &reply);
139        return reply.readInt32();
140    }
141
142    virtual status_t createStream(int width, int height, int format,
143                          const sp<IGraphicBufferProducer>& bufferProducer,
144                          /*out*/
145                          int* streamId)
146    {
147        Parcel data, reply;
148        data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
149        data.writeInt32(width);
150        data.writeInt32(height);
151        data.writeInt32(format);
152
153        sp<IBinder> b(bufferProducer->asBinder());
154        data.writeStrongBinder(b);
155
156        remote()->transact(CREATE_STREAM, data, &reply);
157
158        int sId = reply.readInt32();
159        if (streamId) {
160            *streamId = sId;
161        }
162        return reply.readInt32();
163    }
164
165    // Create a request object from a template.
166    virtual status_t createDefaultRequest(int templateId,
167                                 /*out*/
168                                  camera_metadata** request)
169    {
170        Parcel data, reply;
171        data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
172        data.writeInt32(templateId);
173        remote()->transact(CREATE_DEFAULT_REQUEST, data, &reply);
174        CameraMetadata::readFromParcel(reply, /*out*/request);
175        return reply.readInt32();
176    }
177
178
179    virtual status_t getCameraInfo(int cameraId, camera_metadata** info)
180    {
181        Parcel data, reply;
182        data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
183        data.writeInt32(cameraId);
184        remote()->transact(GET_CAMERA_INFO, data, &reply);
185        CameraMetadata::readFromParcel(reply, /*out*/info);
186        return reply.readInt32();
187    }
188
189
190private:
191
192
193};
194
195IMPLEMENT_META_INTERFACE(ProCameraUser, "android.hardware.IProCameraUser");
196
197// ----------------------------------------------------------------------
198
199status_t BnProCameraUser::onTransact(
200    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
201{
202    switch(code) {
203        case DISCONNECT: {
204            ALOGV("DISCONNECT");
205            CHECK_INTERFACE(IProCameraUser, data, reply);
206            disconnect();
207            reply->writeNoException();
208            return NO_ERROR;
209        } break;
210        case CONNECT: {
211            CHECK_INTERFACE(IProCameraUser, data, reply);
212            sp<IProCameraCallbacks> cameraClient =
213                   interface_cast<IProCameraCallbacks>(data.readStrongBinder());
214            reply->writeInt32(connect(cameraClient));
215            return NO_ERROR;
216        } break;
217
218        /* Shared ProCameraUser */
219        case EXCLUSIVE_TRY_LOCK: {
220            CHECK_INTERFACE(IProCameraUser, data, reply);
221            reply->writeInt32(exclusiveTryLock());
222            return NO_ERROR;
223        } break;
224        case EXCLUSIVE_LOCK: {
225            CHECK_INTERFACE(IProCameraUser, data, reply);
226            reply->writeInt32(exclusiveLock());
227            return NO_ERROR;
228        } break;
229        case EXCLUSIVE_UNLOCK: {
230            CHECK_INTERFACE(IProCameraUser, data, reply);
231            reply->writeInt32(exclusiveUnlock());
232            return NO_ERROR;
233        } break;
234        case HAS_EXCLUSIVE_LOCK: {
235            CHECK_INTERFACE(IProCameraUser, data, reply);
236            reply->writeInt32(hasExclusiveLock());
237            return NO_ERROR;
238        } break;
239        case SUBMIT_REQUEST: {
240            CHECK_INTERFACE(IProCameraUser, data, reply);
241            camera_metadata_t* metadata;
242            CameraMetadata::readFromParcel(data, /*out*/&metadata);
243
244            // arg2 = streaming (bool)
245            bool streaming = data.readInt32();
246
247            // return code: requestId (int32)
248            reply->writeInt32(submitRequest(metadata, streaming));
249
250            return NO_ERROR;
251        } break;
252        case CANCEL_REQUEST: {
253            CHECK_INTERFACE(IProCameraUser, data, reply);
254            int requestId = data.readInt32();
255            reply->writeInt32(cancelRequest(requestId));
256            return NO_ERROR;
257        } break;
258        case DELETE_STREAM: {
259            CHECK_INTERFACE(IProCameraUser, data, reply);
260            int streamId = data.readInt32();
261            reply->writeInt32(deleteStream(streamId));
262            return NO_ERROR;
263        } break;
264        case CREATE_STREAM: {
265            CHECK_INTERFACE(IProCameraUser, data, reply);
266            int width, height, format;
267
268            width = data.readInt32();
269            height = data.readInt32();
270            format = data.readInt32();
271
272            sp<IGraphicBufferProducer> bp =
273               interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
274
275            int streamId = -1;
276            status_t ret;
277            ret = createStream(width, height, format, bp, &streamId);
278
279            reply->writeInt32(streamId);
280            reply->writeInt32(ret);
281
282            return NO_ERROR;
283        } break;
284
285        case CREATE_DEFAULT_REQUEST: {
286            CHECK_INTERFACE(IProCameraUser, data, reply);
287
288            int templateId = data.readInt32();
289
290            camera_metadata_t* request = NULL;
291            status_t ret;
292            ret = createDefaultRequest(templateId, &request);
293
294            CameraMetadata::writeToParcel(*reply, request);
295            reply->writeInt32(ret);
296
297            free_camera_metadata(request);
298
299            return NO_ERROR;
300        } break;
301        case GET_CAMERA_INFO: {
302            CHECK_INTERFACE(IProCameraUser, data, reply);
303
304            int cameraId = data.readInt32();
305
306            camera_metadata_t* info = NULL;
307            status_t ret;
308            ret = getCameraInfo(cameraId, &info);
309
310            CameraMetadata::writeToParcel(*reply, info);
311            reply->writeInt32(ret);
312
313            free_camera_metadata(info);
314
315            return NO_ERROR;
316        } break;
317        default:
318            return BBinder::onTransact(code, data, reply, flags);
319    }
320}
321
322// ----------------------------------------------------------------------------
323
324}; // namespace android
325