IProCameraUser.cpp revision 634a51509ee50475f3e9f8ccf897e90fc72ded31
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 <system/camera_metadata.h>
28
29namespace android {
30
31typedef Parcel::WritableBlob WritableBlob;
32typedef Parcel::ReadableBlob ReadableBlob;
33
34enum {
35    DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
36    CONNECT,
37    EXCLUSIVE_TRY_LOCK,
38    EXCLUSIVE_LOCK,
39    EXCLUSIVE_UNLOCK,
40    HAS_EXCLUSIVE_LOCK,
41    SUBMIT_REQUEST,
42    CANCEL_REQUEST,
43    REQUEST_STREAM,
44    CANCEL_STREAM,
45};
46
47class BpProCameraUser: public BpInterface<IProCameraUser>
48{
49public:
50    BpProCameraUser(const sp<IBinder>& impl)
51        : BpInterface<IProCameraUser>(impl)
52    {
53    }
54
55    // disconnect from camera service
56    void disconnect()
57    {
58        ALOGV("disconnect");
59        Parcel data, reply;
60        data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
61        remote()->transact(DISCONNECT, data, &reply);
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 = metadataSize (int32)
113        size_t metadataSize = get_camera_metadata_compact_size(metadata);
114        data.writeInt32(static_cast<int32_t>(metadataSize));
115
116        // arg1 = metadata (blob)
117        WritableBlob blob;
118        {
119            data.writeBlob(metadataSize, &blob);
120            copy_camera_metadata(blob.data(), metadataSize, metadata);
121        }
122        blob.release();
123
124        // arg2 = streaming (bool)
125        data.writeInt32(streaming);
126
127        remote()->transact(SUBMIT_REQUEST, data, &reply);
128        return reply.readInt32();
129    }
130
131    virtual status_t cancelRequest(int requestId)
132    {
133        Parcel data, reply;
134        data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
135        data.writeInt32(requestId);
136
137        remote()->transact(CANCEL_REQUEST, data, &reply);
138        return reply.readInt32();
139    }
140
141    virtual status_t requestStream(int streamId)
142    {
143        Parcel data, reply;
144        data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
145        data.writeInt32(streamId);
146
147        remote()->transact(REQUEST_STREAM, data, &reply);
148        return reply.readInt32();
149    }
150    virtual status_t cancelStream(int streamId)
151    {
152        Parcel data, reply;
153        data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
154        data.writeInt32(streamId);
155
156        remote()->transact(CANCEL_STREAM, data, &reply);
157        return reply.readInt32();
158    }
159
160};
161
162IMPLEMENT_META_INTERFACE(ProCameraUser, "android.hardware.IProCameraUser");
163
164// ----------------------------------------------------------------------
165
166status_t BnProCameraUser::onTransact(
167    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
168{
169    switch(code) {
170        case DISCONNECT: {
171            ALOGV("DISCONNECT");
172            CHECK_INTERFACE(IProCameraUser, data, reply);
173            disconnect();
174            return NO_ERROR;
175        } break;
176        case CONNECT: {
177            CHECK_INTERFACE(IProCameraUser, data, reply);
178            sp<IProCameraCallbacks> cameraClient =
179                   interface_cast<IProCameraCallbacks>(data.readStrongBinder());
180            reply->writeInt32(connect(cameraClient));
181            return NO_ERROR;
182        } break;
183
184        /* Shared ProCameraUser */
185        case EXCLUSIVE_TRY_LOCK: {
186            CHECK_INTERFACE(IProCameraUser, data, reply);
187            reply->writeInt32(exclusiveTryLock());
188            return NO_ERROR;
189        } break;
190        case EXCLUSIVE_LOCK: {
191            CHECK_INTERFACE(IProCameraUser, data, reply);
192            reply->writeInt32(exclusiveLock());
193            return NO_ERROR;
194        } break;
195        case EXCLUSIVE_UNLOCK: {
196            CHECK_INTERFACE(IProCameraUser, data, reply);
197            reply->writeInt32(exclusiveUnlock());
198            return NO_ERROR;
199        } break;
200        case HAS_EXCLUSIVE_LOCK: {
201            CHECK_INTERFACE(IProCameraUser, data, reply);
202            reply->writeInt32(hasExclusiveLock());
203            return NO_ERROR;
204        } break;
205        case SUBMIT_REQUEST: {
206            CHECK_INTERFACE(IProCameraUser, data, reply);
207            camera_metadata_t* metadata;
208
209            // arg0 = metadataSize (int32)
210            size_t metadataSize = static_cast<size_t>(data.readInt32());
211
212            // NOTE: this doesn't make sense to me. shouldnt the blob
213            // know how big it is? why do we have to specify the size
214            // to Parcel::readBlob ?
215
216            ReadableBlob blob;
217            // arg1 = metadata (blob)
218            {
219                data.readBlob(metadataSize, &blob);
220                const camera_metadata_t* tmp =
221                        reinterpret_cast<const camera_metadata_t*>(blob.data());
222                size_t entry_capacity = get_camera_metadata_entry_capacity(tmp);
223                size_t data_capacity = get_camera_metadata_data_capacity(tmp);
224
225                metadata = allocate_camera_metadata(entry_capacity,
226                                                                 data_capacity);
227                copy_camera_metadata(metadata, metadataSize, tmp);
228            }
229            blob.release();
230
231            // arg2 = streaming (bool)
232            bool streaming = data.readInt32();
233
234            // return code: requestId (int32)
235            reply->writeInt32(submitRequest(metadata, streaming));
236
237            return NO_ERROR;
238        } break;
239        case CANCEL_REQUEST: {
240            CHECK_INTERFACE(IProCameraUser, data, reply);
241            int requestId = data.readInt32();
242            reply->writeInt32(cancelRequest(requestId));
243            return NO_ERROR;
244        } break;
245        case REQUEST_STREAM: {
246            CHECK_INTERFACE(IProCameraUser, data, reply);
247            int streamId = data.readInt32();
248            reply->writeInt32(requestStream(streamId));
249            return NO_ERROR;
250        } break;
251        case CANCEL_STREAM: {
252            CHECK_INTERFACE(IProCameraUser, data, reply);
253            int streamId = data.readInt32();
254            reply->writeInt32(cancelStream(streamId));
255            return NO_ERROR;
256        } break;
257        default:
258            return BBinder::onTransact(code, data, reply, flags);
259    }
260}
261
262// ----------------------------------------------------------------------------
263
264}; // namespace android
265