blob: 0c94bd482ea3b19dc85d1e41c84fd5b3fd3933b1 [file] [log] [blame]
Igor Murashkin634a5152013-02-20 17:15:11 -08001/*
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,
Igor Murashkinfa4cf9d2013-03-04 16:14:23 -080043 DELETE_STREAM,
Igor Murashkin985fd302013-02-20 18:24:43 -080044 CREATE_STREAM,
45 CREATE_DEFAULT_REQUEST,
Igor Murashkin7b33a742013-02-21 13:49:26 -080046 GET_CAMERA_INFO,
Igor Murashkin634a5152013-02-20 17:15:11 -080047};
48
Igor Murashkin985fd302013-02-20 18:24:43 -080049/**
50 * Caller becomes the owner of the new metadata
51 * 'const Parcel' doesnt prevent us from calling the read functions.
52 * which is interesting since it changes the internal state
53 */
54void readMetadata(const Parcel& data, camera_metadata_t** out) {
55 camera_metadata_t* metadata;
56
57 // arg0 = metadataSize (int32)
58 size_t metadataSize = static_cast<size_t>(data.readInt32());
59
60 if (metadataSize == 0) {
61 if (out) {
62 *out = NULL;
63 }
64 return;
65 }
66
67 // NOTE: this doesn't make sense to me. shouldnt the blob
68 // know how big it is? why do we have to specify the size
69 // to Parcel::readBlob ?
70
71 ReadableBlob blob;
72 // arg1 = metadata (blob)
73 {
74 data.readBlob(metadataSize, &blob);
75 const camera_metadata_t* tmp =
76 reinterpret_cast<const camera_metadata_t*>(blob.data());
77 size_t entry_capacity = get_camera_metadata_entry_capacity(tmp);
78 size_t data_capacity = get_camera_metadata_data_capacity(tmp);
79
80 metadata = allocate_camera_metadata(entry_capacity, data_capacity);
81 copy_camera_metadata(metadata, metadataSize, tmp);
82 }
83 blob.release();
84
85 if (out) {
86 *out = metadata;
87 } else {
88 free_camera_metadata(metadata);
89 }
90}
91
92/**
93 * Caller retains ownership of metadata
94 * - Write 2 (int32 + blob) args in the current position
95 */
96void writeMetadata(Parcel& data, camera_metadata_t* metadata) {
97 // arg0 = metadataSize (int32)
98 size_t metadataSize;
99
100 if (metadata == NULL) {
101 data.writeInt32(0);
102 return;
103 }
104
105 metadataSize = get_camera_metadata_compact_size(metadata);
106 data.writeInt32(static_cast<int32_t>(metadataSize));
107
108 // arg1 = metadata (blob)
109 WritableBlob blob;
110 {
111 data.writeBlob(metadataSize, &blob);
112 copy_camera_metadata(blob.data(), metadataSize, metadata);
113 }
114 blob.release();
115}
116
Igor Murashkin634a5152013-02-20 17:15:11 -0800117class BpProCameraUser: public BpInterface<IProCameraUser>
118{
119public:
120 BpProCameraUser(const sp<IBinder>& impl)
121 : BpInterface<IProCameraUser>(impl)
122 {
123 }
124
125 // disconnect from camera service
126 void disconnect()
127 {
128 ALOGV("disconnect");
129 Parcel data, reply;
130 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
131 remote()->transact(DISCONNECT, data, &reply);
132 }
133
134 virtual status_t connect(const sp<IProCameraCallbacks>& cameraClient)
135 {
136 Parcel data, reply;
137 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
138 data.writeStrongBinder(cameraClient->asBinder());
139 remote()->transact(CONNECT, data, &reply);
140 return reply.readInt32();
141 }
142
143 /* Shared ProCameraUser */
144
145 virtual status_t exclusiveTryLock()
146 {
147 Parcel data, reply;
148 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
149 remote()->transact(EXCLUSIVE_TRY_LOCK, data, &reply);
150 return reply.readInt32();
151 }
152 virtual status_t exclusiveLock()
153 {
154 Parcel data, reply;
155 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
156 remote()->transact(EXCLUSIVE_LOCK, data, &reply);
157 return reply.readInt32();
158 }
159
160 virtual status_t exclusiveUnlock()
161 {
162 Parcel data, reply;
163 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
164 remote()->transact(EXCLUSIVE_UNLOCK, data, &reply);
165 return reply.readInt32();
166 }
167
168 virtual bool hasExclusiveLock()
169 {
170 Parcel data, reply;
171 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
172 remote()->transact(HAS_EXCLUSIVE_LOCK, data, &reply);
173 return !!reply.readInt32();
174 }
175
176 virtual int submitRequest(camera_metadata_t* metadata, bool streaming)
177 {
178
179 Parcel data, reply;
180 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
181
Igor Murashkin985fd302013-02-20 18:24:43 -0800182 // arg0+arg1
183 writeMetadata(data, metadata);
Igor Murashkin634a5152013-02-20 17:15:11 -0800184
185 // arg2 = streaming (bool)
186 data.writeInt32(streaming);
187
188 remote()->transact(SUBMIT_REQUEST, data, &reply);
189 return reply.readInt32();
190 }
191
192 virtual status_t cancelRequest(int requestId)
193 {
194 Parcel data, reply;
195 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
196 data.writeInt32(requestId);
197
198 remote()->transact(CANCEL_REQUEST, data, &reply);
199 return reply.readInt32();
200 }
201
Igor Murashkinfa4cf9d2013-03-04 16:14:23 -0800202 virtual status_t deleteStream(int streamId)
Igor Murashkin634a5152013-02-20 17:15:11 -0800203 {
204 Parcel data, reply;
205 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
206 data.writeInt32(streamId);
207
Igor Murashkinfa4cf9d2013-03-04 16:14:23 -0800208 remote()->transact(DELETE_STREAM, data, &reply);
Igor Murashkin634a5152013-02-20 17:15:11 -0800209 return reply.readInt32();
210 }
211
Igor Murashkin985fd302013-02-20 18:24:43 -0800212 virtual status_t createStream(int width, int height, int format,
Igor Murashkin76f8b432013-02-20 19:15:15 -0800213 const sp<IGraphicBufferProducer>& bufferProducer,
Igor Murashkin985fd302013-02-20 18:24:43 -0800214 /*out*/
215 int* streamId)
216 {
217 Parcel data, reply;
218 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
219 data.writeInt32(width);
220 data.writeInt32(height);
221 data.writeInt32(format);
222
Igor Murashkin76f8b432013-02-20 19:15:15 -0800223 sp<IBinder> b(bufferProducer->asBinder());
224 data.writeStrongBinder(b);
225
Igor Murashkin985fd302013-02-20 18:24:43 -0800226 remote()->transact(CREATE_STREAM, data, &reply);
227
228 int sId = reply.readInt32();
229 if (streamId) {
230 *streamId = sId;
231 }
232 return reply.readInt32();
233 }
234
235 // Create a request object from a template.
236 virtual status_t createDefaultRequest(int templateId,
237 /*out*/
238 camera_metadata** request)
239 {
240 Parcel data, reply;
241 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
242 data.writeInt32(templateId);
243 remote()->transact(CREATE_DEFAULT_REQUEST, data, &reply);
244 readMetadata(reply, /*out*/request);
245 return reply.readInt32();
246 }
247
248
Igor Murashkin7b33a742013-02-21 13:49:26 -0800249 virtual status_t getCameraInfo(int cameraId, camera_metadata** info)
250 {
251 Parcel data, reply;
252 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
253 data.writeInt32(cameraId);
254 remote()->transact(GET_CAMERA_INFO, data, &reply);
255 readMetadata(reply, /*out*/info);
256 return reply.readInt32();
257 }
258
259
Igor Murashkin985fd302013-02-20 18:24:43 -0800260private:
261
262
Igor Murashkin634a5152013-02-20 17:15:11 -0800263};
264
265IMPLEMENT_META_INTERFACE(ProCameraUser, "android.hardware.IProCameraUser");
266
267// ----------------------------------------------------------------------
268
269status_t BnProCameraUser::onTransact(
270 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
271{
272 switch(code) {
273 case DISCONNECT: {
274 ALOGV("DISCONNECT");
275 CHECK_INTERFACE(IProCameraUser, data, reply);
276 disconnect();
277 return NO_ERROR;
278 } break;
279 case CONNECT: {
280 CHECK_INTERFACE(IProCameraUser, data, reply);
281 sp<IProCameraCallbacks> cameraClient =
282 interface_cast<IProCameraCallbacks>(data.readStrongBinder());
283 reply->writeInt32(connect(cameraClient));
284 return NO_ERROR;
285 } break;
286
287 /* Shared ProCameraUser */
288 case EXCLUSIVE_TRY_LOCK: {
289 CHECK_INTERFACE(IProCameraUser, data, reply);
290 reply->writeInt32(exclusiveTryLock());
291 return NO_ERROR;
292 } break;
293 case EXCLUSIVE_LOCK: {
294 CHECK_INTERFACE(IProCameraUser, data, reply);
295 reply->writeInt32(exclusiveLock());
296 return NO_ERROR;
297 } break;
298 case EXCLUSIVE_UNLOCK: {
299 CHECK_INTERFACE(IProCameraUser, data, reply);
300 reply->writeInt32(exclusiveUnlock());
301 return NO_ERROR;
302 } break;
303 case HAS_EXCLUSIVE_LOCK: {
304 CHECK_INTERFACE(IProCameraUser, data, reply);
305 reply->writeInt32(hasExclusiveLock());
306 return NO_ERROR;
307 } break;
308 case SUBMIT_REQUEST: {
309 CHECK_INTERFACE(IProCameraUser, data, reply);
310 camera_metadata_t* metadata;
Igor Murashkin985fd302013-02-20 18:24:43 -0800311 readMetadata(data, /*out*/&metadata);
Igor Murashkin634a5152013-02-20 17:15:11 -0800312
313 // arg2 = streaming (bool)
314 bool streaming = data.readInt32();
315
316 // return code: requestId (int32)
317 reply->writeInt32(submitRequest(metadata, streaming));
318
319 return NO_ERROR;
320 } break;
321 case CANCEL_REQUEST: {
322 CHECK_INTERFACE(IProCameraUser, data, reply);
323 int requestId = data.readInt32();
324 reply->writeInt32(cancelRequest(requestId));
325 return NO_ERROR;
326 } break;
Igor Murashkinfa4cf9d2013-03-04 16:14:23 -0800327 case DELETE_STREAM: {
Igor Murashkin634a5152013-02-20 17:15:11 -0800328 CHECK_INTERFACE(IProCameraUser, data, reply);
329 int streamId = data.readInt32();
Igor Murashkinfa4cf9d2013-03-04 16:14:23 -0800330 reply->writeInt32(deleteStream(streamId));
Igor Murashkin634a5152013-02-20 17:15:11 -0800331 return NO_ERROR;
332 } break;
Igor Murashkin985fd302013-02-20 18:24:43 -0800333 case CREATE_STREAM: {
334 CHECK_INTERFACE(IProCameraUser, data, reply);
335 int width, height, format;
336
337 width = data.readInt32();
338 height = data.readInt32();
339 format = data.readInt32();
340
Igor Murashkin76f8b432013-02-20 19:15:15 -0800341 sp<IGraphicBufferProducer> bp =
342 interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
Igor Murashkin985fd302013-02-20 18:24:43 -0800343
344 int streamId = -1;
345 status_t ret;
Igor Murashkin76f8b432013-02-20 19:15:15 -0800346 ret = createStream(width, height, format, bp, &streamId);
Igor Murashkin985fd302013-02-20 18:24:43 -0800347
348 reply->writeInt32(streamId);
349 reply->writeInt32(ret);
350
351 return NO_ERROR;
352 } break;
353
354 case CREATE_DEFAULT_REQUEST: {
355 CHECK_INTERFACE(IProCameraUser, data, reply);
356
357 int templateId = data.readInt32();
358
359 camera_metadata_t* request = NULL;
360 status_t ret;
361 ret = createDefaultRequest(templateId, &request);
362
363 writeMetadata(*reply, request);
364 reply->writeInt32(ret);
365
Igor Murashkin7b33a742013-02-21 13:49:26 -0800366 free_camera_metadata(request);
367
368 return NO_ERROR;
369 } break;
370 case GET_CAMERA_INFO: {
371 CHECK_INTERFACE(IProCameraUser, data, reply);
372
373 int cameraId = data.readInt32();
374
375 camera_metadata_t* info = NULL;
376 status_t ret;
377 ret = getCameraInfo(cameraId, &info);
378
379 writeMetadata(*reply, info);
380 reply->writeInt32(ret);
381
382 free_camera_metadata(info);
383
Igor Murashkin985fd302013-02-20 18:24:43 -0800384 return NO_ERROR;
385 } break;
Igor Murashkin634a5152013-02-20 17:15:11 -0800386 default:
387 return BBinder::onTransact(code, data, reply, flags);
388 }
389}
390
391// ----------------------------------------------------------------------------
392
393}; // namespace android