blob: d1d63d5f63365a2adaf4bd81b9e21831162f94b9 [file] [log] [blame]
Igor Murashkine7ee7632013-06-11 18:10:18 -07001/*
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>
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070024#include <camera/camera2/ICameraDeviceUser.h>
Igor Murashkine7ee7632013-06-11 18:10:18 -070025#include <gui/IGraphicBufferProducer.h>
26#include <gui/Surface.h>
27#include <camera/CameraMetadata.h>
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070028#include <camera/camera2/CaptureRequest.h>
Igor Murashkine7ee7632013-06-11 18:10:18 -070029
30namespace android {
31
32typedef Parcel::WritableBlob WritableBlob;
33typedef Parcel::ReadableBlob ReadableBlob;
34
35enum {
36 DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
37 SUBMIT_REQUEST,
Jianing Weicb0652e2014-03-12 18:29:36 -070038 SUBMIT_REQUEST_LIST,
Igor Murashkine7ee7632013-06-11 18:10:18 -070039 CANCEL_REQUEST,
Ruben Brunk29478402014-05-22 13:09:57 -070040 BEGIN_CONFIGURE,
41 END_CONFIGURE,
Igor Murashkine7ee7632013-06-11 18:10:18 -070042 DELETE_STREAM,
43 CREATE_STREAM,
44 CREATE_DEFAULT_REQUEST,
45 GET_CAMERA_INFO,
Zhijun He2ab500c2013-07-23 08:02:53 -070046 WAIT_UNTIL_IDLE,
Ruben Brunk29478402014-05-22 13:09:57 -070047 FLUSH
Igor Murashkine7ee7632013-06-11 18:10:18 -070048};
49
Igor Murashkin88aef232013-08-23 17:47:06 -070050namespace {
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
Igor Murashkine7ee7632013-06-11 18:10:18 -070063class 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
Jianing Weicb0652e2014-03-12 18:29:36 -070081 virtual status_t submitRequest(sp<CaptureRequest> request, bool repeating,
82 int64_t *lastFrameNumber)
Igor Murashkine7ee7632013-06-11 18:10:18 -070083 {
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)
Jianing Weicb0652e2014-03-12 18:29:36 -070096 data.writeInt32(repeating);
Igor Murashkine7ee7632013-06-11 18:10:18 -070097
98 remote()->transact(SUBMIT_REQUEST, data, &reply);
99
100 reply.readExceptionCode();
Jianing Weicb0652e2014-03-12 18:29:36 -0700101 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
John Lin19fa0fe2015-02-02 18:10:42 +0800110 if ((res < NO_ERROR) || (resFrameNumber != NO_ERROR)) {
Jianing Weicb0652e2014-03-12 18:29:36 -0700111 res = FAILED_TRANSACTION;
112 }
113 return res;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700114 }
115
Jianing Weicb0652e2014-03-12 18:29:36 -0700116 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 }
John Lin19fa0fe2015-02-02 18:10:42 +0800150 if ((res < NO_ERROR) || (resFrameNumber != NO_ERROR)) {
Jianing Weicb0652e2014-03-12 18:29:36 -0700151 res = FAILED_TRANSACTION;
152 }
153 return res;
154 }
155
156 virtual status_t cancelRequest(int requestId, int64_t *lastFrameNumber)
Igor Murashkine7ee7632013-06-11 18:10:18 -0700157 {
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();
Jianing Weicb0652e2014-03-12 18:29:36 -0700165 status_t res = reply.readInt32();
166
167 status_t resFrameNumber = BAD_VALUE;
168 if (reply.readInt32() != 0) {
169 if (lastFrameNumber != NULL) {
John Lin19fa0fe2015-02-02 18:10:42 +0800170 resFrameNumber = reply.readInt64(lastFrameNumber);
Jianing Weicb0652e2014-03-12 18:29:36 -0700171 }
172 }
173 if ((res != NO_ERROR) || (resFrameNumber != NO_ERROR)) {
174 res = FAILED_TRANSACTION;
175 }
176 return res;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700177 }
178
Ruben Brunk29478402014-05-22 13:09:57 -0700179 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
Igor Murashkine7ee7632013-06-11 18:10:18 -0700199 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
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800211 virtual status_t createStream(
Igor Murashkine7ee7632013-06-11 18:10:18 -0700212 const sp<IGraphicBufferProducer>& bufferProducer)
213 {
214 Parcel data, reply;
215 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
Igor Murashkine7ee7632013-06-11 18:10:18 -0700216
217 data.writeInt32(1); // marker that bufferProducer is not null
218 data.writeString16(String16("unknown_name")); // name of surface
Marco Nelissenf8880202014-11-14 07:58:25 -0800219 sp<IBinder> b(IInterface::asBinder(bufferProducer));
Igor Murashkine7ee7632013-06-11 18:10:18 -0700220 data.writeStrongBinder(b);
221
222 remote()->transact(CREATE_STREAM, data, &reply);
223
224 reply.readExceptionCode();
225 return reply.readInt32();
226 }
227
228 // Create a request object from a template.
229 virtual status_t createDefaultRequest(int templateId,
230 /*out*/
231 CameraMetadata* request)
232 {
233 Parcel data, reply;
234 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
235 data.writeInt32(templateId);
236 remote()->transact(CREATE_DEFAULT_REQUEST, data, &reply);
237
238 reply.readExceptionCode();
239 status_t result = reply.readInt32();
240
241 CameraMetadata out;
242 if (reply.readInt32() != 0) {
243 out.readFromParcel(&reply);
244 }
245
246 if (request != NULL) {
247 request->swap(out);
248 }
249 return result;
250 }
251
252
Igor Murashkin099b4572013-07-12 17:52:16 -0700253 virtual status_t getCameraInfo(CameraMetadata* info)
Igor Murashkine7ee7632013-06-11 18:10:18 -0700254 {
255 Parcel data, reply;
256 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
Igor Murashkine7ee7632013-06-11 18:10:18 -0700257 remote()->transact(GET_CAMERA_INFO, data, &reply);
258
Igor Murashkine7ee7632013-06-11 18:10:18 -0700259 reply.readExceptionCode();
260 status_t result = reply.readInt32();
261
Igor Murashkin099b4572013-07-12 17:52:16 -0700262 CameraMetadata out;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700263 if (reply.readInt32() != 0) {
Igor Murashkin099b4572013-07-12 17:52:16 -0700264 out.readFromParcel(&reply);
265 }
266
267 if (info != NULL) {
268 info->swap(out);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700269 }
270
271 return result;
272 }
273
Zhijun He2ab500c2013-07-23 08:02:53 -0700274 virtual status_t waitUntilIdle()
275 {
276 ALOGV("waitUntilIdle");
277 Parcel data, reply;
278 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
279 remote()->transact(WAIT_UNTIL_IDLE, data, &reply);
280 reply.readExceptionCode();
281 return reply.readInt32();
282 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700283
Jianing Weicb0652e2014-03-12 18:29:36 -0700284 virtual status_t flush(int64_t *lastFrameNumber)
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700285 {
286 ALOGV("flush");
287 Parcel data, reply;
288 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
289 remote()->transact(FLUSH, data, &reply);
290 reply.readExceptionCode();
Jianing Weicb0652e2014-03-12 18:29:36 -0700291 status_t res = reply.readInt32();
292
293 status_t resFrameNumber = BAD_VALUE;
294 if (reply.readInt32() != 0) {
295 if (lastFrameNumber != NULL) {
John Lin19fa0fe2015-02-02 18:10:42 +0800296 resFrameNumber = reply.readInt64(lastFrameNumber);
Jianing Weicb0652e2014-03-12 18:29:36 -0700297 }
298 }
299 if ((res != NO_ERROR) || (resFrameNumber != NO_ERROR)) {
300 res = FAILED_TRANSACTION;
301 }
302 return res;
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700303 }
304
Igor Murashkine7ee7632013-06-11 18:10:18 -0700305private:
306
307
308};
309
310IMPLEMENT_META_INTERFACE(CameraDeviceUser,
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -0700311 "android.hardware.camera2.ICameraDeviceUser");
Igor Murashkine7ee7632013-06-11 18:10:18 -0700312
313// ----------------------------------------------------------------------
314
315status_t BnCameraDeviceUser::onTransact(
316 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
317{
318 switch(code) {
319 case DISCONNECT: {
320 ALOGV("DISCONNECT");
321 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
322 disconnect();
323 reply->writeNoException();
324 return NO_ERROR;
325 } break;
326 case SUBMIT_REQUEST: {
327 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
328
329 // arg0 = request
330 sp<CaptureRequest> request;
331 if (data.readInt32() != 0) {
332 request = new CaptureRequest();
333 request->readFromParcel(const_cast<Parcel*>(&data));
334 }
335
336 // arg1 = streaming (bool)
Jianing Weicb0652e2014-03-12 18:29:36 -0700337 bool repeating = data.readInt32();
Igor Murashkine7ee7632013-06-11 18:10:18 -0700338
339 // return code: requestId (int32)
340 reply->writeNoException();
Jianing Weicb0652e2014-03-12 18:29:36 -0700341 int64_t lastFrameNumber = -1;
342 reply->writeInt32(submitRequest(request, repeating, &lastFrameNumber));
343 reply->writeInt32(1);
344 reply->writeInt64(lastFrameNumber);
345
346 return NO_ERROR;
347 } break;
348 case SUBMIT_REQUEST_LIST: {
349 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
350
351 List<sp<CaptureRequest> > requestList;
352 int requestListSize = data.readInt32();
353 for (int i = 0; i < requestListSize; i++) {
354 if (data.readInt32() != 0) {
355 sp<CaptureRequest> request = new CaptureRequest();
356 if (request->readFromParcel(const_cast<Parcel*>(&data)) != OK) {
357 return BAD_VALUE;
358 }
359 requestList.push_back(request);
360 } else {
361 sp<CaptureRequest> request = 0;
362 requestList.push_back(request);
363 ALOGE("A request is missing. Sending in null request.");
364 }
365 }
366
367 bool repeating = data.readInt32();
368
369 reply->writeNoException();
370 int64_t lastFrameNumber = -1;
371 reply->writeInt32(submitRequestList(requestList, repeating, &lastFrameNumber));
372 reply->writeInt32(1);
373 reply->writeInt64(lastFrameNumber);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700374
375 return NO_ERROR;
376 } break;
377 case CANCEL_REQUEST: {
378 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
379 int requestId = data.readInt32();
380 reply->writeNoException();
Jianing Weicb0652e2014-03-12 18:29:36 -0700381 int64_t lastFrameNumber = -1;
382 reply->writeInt32(cancelRequest(requestId, &lastFrameNumber));
383 reply->writeInt32(1);
384 reply->writeInt64(lastFrameNumber);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700385 return NO_ERROR;
386 } break;
387 case DELETE_STREAM: {
388 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
389 int streamId = data.readInt32();
390 reply->writeNoException();
391 reply->writeInt32(deleteStream(streamId));
392 return NO_ERROR;
393 } break;
394 case CREATE_STREAM: {
395 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700396
397 sp<IGraphicBufferProducer> bp;
398 if (data.readInt32() != 0) {
Igor Murashkin88aef232013-08-23 17:47:06 -0700399 String16 name = readMaybeEmptyString16(data);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700400 bp = interface_cast<IGraphicBufferProducer>(
401 data.readStrongBinder());
402
403 ALOGV("%s: CREATE_STREAM: bp = %p, name = %s", __FUNCTION__,
404 bp.get(), String8(name).string());
405 } else {
406 ALOGV("%s: CREATE_STREAM: bp = unset, name = unset",
407 __FUNCTION__);
408 }
409
410 status_t ret;
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800411 ret = createStream(bp);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700412
413 reply->writeNoException();
414 ALOGV("%s: CREATE_STREAM: write noException", __FUNCTION__);
415 reply->writeInt32(ret);
416 ALOGV("%s: CREATE_STREAM: write ret = %d", __FUNCTION__, ret);
417
418 return NO_ERROR;
419 } break;
420
421 case CREATE_DEFAULT_REQUEST: {
422 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
423
424 int templateId = data.readInt32();
425
426 CameraMetadata request;
427 status_t ret;
428 ret = createDefaultRequest(templateId, &request);
429
430 reply->writeNoException();
431 reply->writeInt32(ret);
432
Igor Murashkin099b4572013-07-12 17:52:16 -0700433 // out-variables are after exception and return value
Igor Murashkine7ee7632013-06-11 18:10:18 -0700434 reply->writeInt32(1); // to mark presence of metadata object
435 request.writeToParcel(const_cast<Parcel*>(reply));
436
437 return NO_ERROR;
438 } break;
439 case GET_CAMERA_INFO: {
440 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
441
Igor Murashkin099b4572013-07-12 17:52:16 -0700442 CameraMetadata info;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700443 status_t ret;
Igor Murashkin099b4572013-07-12 17:52:16 -0700444 ret = getCameraInfo(&info);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700445
446 reply->writeNoException();
447 reply->writeInt32(ret);
448
Igor Murashkin099b4572013-07-12 17:52:16 -0700449 // out-variables are after exception and return value
450 reply->writeInt32(1); // to mark presence of metadata object
451 info.writeToParcel(reply);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700452
453 return NO_ERROR;
454 } break;
Zhijun He2ab500c2013-07-23 08:02:53 -0700455 case WAIT_UNTIL_IDLE: {
456 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
457 reply->writeNoException();
458 reply->writeInt32(waitUntilIdle());
459 return NO_ERROR;
460 } break;
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700461 case FLUSH: {
462 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
463 reply->writeNoException();
Jianing Weicb0652e2014-03-12 18:29:36 -0700464 int64_t lastFrameNumber = -1;
465 reply->writeInt32(flush(&lastFrameNumber));
466 reply->writeInt32(1);
467 reply->writeInt64(lastFrameNumber);
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700468 return NO_ERROR;
469 }
Ruben Brunkb2119af2014-05-09 19:57:56 -0700470 case BEGIN_CONFIGURE: {
471 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
472 reply->writeNoException();
473 reply->writeInt32(beginConfigure());
474 return NO_ERROR;
475 } break;
476 case END_CONFIGURE: {
477 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
478 reply->writeNoException();
479 reply->writeInt32(endConfigure());
480 return NO_ERROR;
481 } break;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700482 default:
483 return BBinder::onTransact(code, data, reply, flags);
484 }
485}
486
487// ----------------------------------------------------------------------------
488
489}; // namespace android