blob: 89c6fb784da1c1e83ac0fd320f12d4043af76c83 [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>
Yin-Chia Yehb97babb2015-03-12 13:42:44 -070029#include <camera/camera2/OutputConfiguration.h>
Igor Murashkine7ee7632013-06-11 18:10:18 -070030
31namespace android {
32
33typedef Parcel::WritableBlob WritableBlob;
34typedef Parcel::ReadableBlob ReadableBlob;
35
36enum {
37 DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
38 SUBMIT_REQUEST,
Jianing Weicb0652e2014-03-12 18:29:36 -070039 SUBMIT_REQUEST_LIST,
Igor Murashkine7ee7632013-06-11 18:10:18 -070040 CANCEL_REQUEST,
Ruben Brunk29478402014-05-22 13:09:57 -070041 BEGIN_CONFIGURE,
42 END_CONFIGURE,
Igor Murashkine7ee7632013-06-11 18:10:18 -070043 DELETE_STREAM,
44 CREATE_STREAM,
45 CREATE_DEFAULT_REQUEST,
46 GET_CAMERA_INFO,
Zhijun He2ab500c2013-07-23 08:02:53 -070047 WAIT_UNTIL_IDLE,
Ruben Brunk29478402014-05-22 13:09:57 -070048 FLUSH
Igor Murashkine7ee7632013-06-11 18:10:18 -070049};
50
Igor Murashkin88aef232013-08-23 17:47:06 -070051namespace {
52 // Read empty strings without printing a false error message.
53 String16 readMaybeEmptyString16(const Parcel& parcel) {
54 size_t len;
55 const char16_t* str = parcel.readString16Inplace(&len);
56 if (str != NULL) {
57 return String16(str, len);
58 } else {
59 return String16();
60 }
61 }
62};
63
Igor Murashkine7ee7632013-06-11 18:10:18 -070064class BpCameraDeviceUser : public BpInterface<ICameraDeviceUser>
65{
66public:
67 BpCameraDeviceUser(const sp<IBinder>& impl)
68 : BpInterface<ICameraDeviceUser>(impl)
69 {
70 }
71
72 // disconnect from camera service
73 void disconnect()
74 {
75 ALOGV("disconnect");
76 Parcel data, reply;
77 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
78 remote()->transact(DISCONNECT, data, &reply);
79 reply.readExceptionCode();
80 }
81
Jianing Weicb0652e2014-03-12 18:29:36 -070082 virtual status_t submitRequest(sp<CaptureRequest> request, bool repeating,
83 int64_t *lastFrameNumber)
Igor Murashkine7ee7632013-06-11 18:10:18 -070084 {
85 Parcel data, reply;
86 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
87
88 // arg0 = CaptureRequest
89 if (request != 0) {
90 data.writeInt32(1);
91 request->writeToParcel(&data);
92 } else {
93 data.writeInt32(0);
94 }
95
96 // arg1 = streaming (bool)
Jianing Weicb0652e2014-03-12 18:29:36 -070097 data.writeInt32(repeating);
Igor Murashkine7ee7632013-06-11 18:10:18 -070098
99 remote()->transact(SUBMIT_REQUEST, data, &reply);
100
101 reply.readExceptionCode();
Jianing Weicb0652e2014-03-12 18:29:36 -0700102 status_t res = reply.readInt32();
103
104 status_t resFrameNumber = BAD_VALUE;
105 if (reply.readInt32() != 0) {
106 if (lastFrameNumber != NULL) {
107 resFrameNumber = reply.readInt64(lastFrameNumber);
108 }
109 }
110
John Lin19fa0fe2015-02-02 18:10:42 +0800111 if ((res < NO_ERROR) || (resFrameNumber != NO_ERROR)) {
Jianing Weicb0652e2014-03-12 18:29:36 -0700112 res = FAILED_TRANSACTION;
113 }
114 return res;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700115 }
116
Jianing Weicb0652e2014-03-12 18:29:36 -0700117 virtual status_t submitRequestList(List<sp<CaptureRequest> > requestList, bool repeating,
118 int64_t *lastFrameNumber)
119 {
120 Parcel data, reply;
121 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
122
123 data.writeInt32(requestList.size());
124
125 for (List<sp<CaptureRequest> >::iterator it = requestList.begin();
126 it != requestList.end(); ++it) {
127 sp<CaptureRequest> request = *it;
128 if (request != 0) {
129 data.writeInt32(1);
130 if (request->writeToParcel(&data) != OK) {
131 return BAD_VALUE;
132 }
133 } else {
134 data.writeInt32(0);
135 }
136 }
137
138 data.writeInt32(repeating);
139
140 remote()->transact(SUBMIT_REQUEST_LIST, data, &reply);
141
142 reply.readExceptionCode();
143 status_t res = reply.readInt32();
144
145 status_t resFrameNumber = BAD_VALUE;
146 if (reply.readInt32() != 0) {
147 if (lastFrameNumber != NULL) {
148 resFrameNumber = reply.readInt64(lastFrameNumber);
149 }
150 }
John Lin19fa0fe2015-02-02 18:10:42 +0800151 if ((res < NO_ERROR) || (resFrameNumber != NO_ERROR)) {
Jianing Weicb0652e2014-03-12 18:29:36 -0700152 res = FAILED_TRANSACTION;
153 }
154 return res;
155 }
156
157 virtual status_t cancelRequest(int requestId, int64_t *lastFrameNumber)
Igor Murashkine7ee7632013-06-11 18:10:18 -0700158 {
159 Parcel data, reply;
160 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
161 data.writeInt32(requestId);
162
163 remote()->transact(CANCEL_REQUEST, data, &reply);
164
165 reply.readExceptionCode();
Jianing Weicb0652e2014-03-12 18:29:36 -0700166 status_t res = reply.readInt32();
167
168 status_t resFrameNumber = BAD_VALUE;
169 if (reply.readInt32() != 0) {
170 if (lastFrameNumber != NULL) {
John Lin19fa0fe2015-02-02 18:10:42 +0800171 resFrameNumber = reply.readInt64(lastFrameNumber);
Jianing Weicb0652e2014-03-12 18:29:36 -0700172 }
173 }
174 if ((res != NO_ERROR) || (resFrameNumber != NO_ERROR)) {
175 res = FAILED_TRANSACTION;
176 }
177 return res;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700178 }
179
Ruben Brunk29478402014-05-22 13:09:57 -0700180 virtual status_t beginConfigure()
181 {
182 ALOGV("beginConfigure");
183 Parcel data, reply;
184 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
185 remote()->transact(BEGIN_CONFIGURE, data, &reply);
186 reply.readExceptionCode();
187 return reply.readInt32();
188 }
189
190 virtual status_t endConfigure()
191 {
192 ALOGV("endConfigure");
193 Parcel data, reply;
194 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
195 remote()->transact(END_CONFIGURE, data, &reply);
196 reply.readExceptionCode();
197 return reply.readInt32();
198 }
199
Igor Murashkine7ee7632013-06-11 18:10:18 -0700200 virtual status_t deleteStream(int streamId)
201 {
202 Parcel data, reply;
203 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
204 data.writeInt32(streamId);
205
206 remote()->transact(DELETE_STREAM, data, &reply);
207
208 reply.readExceptionCode();
209 return reply.readInt32();
210 }
211
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700212 virtual status_t createStream(const OutputConfiguration& outputConfiguration)
Igor Murashkine7ee7632013-06-11 18:10:18 -0700213 {
214 Parcel data, reply;
215 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700216 if (outputConfiguration.getGraphicBufferProducer() != NULL) {
217 data.writeInt32(1); // marker that OutputConfiguration is not null. Mimic aidl behavior
218 outputConfiguration.writeToParcel(data);
219 } else {
220 data.writeInt32(0);
221 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700222 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
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700397 status_t ret = BAD_VALUE;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700398 if (data.readInt32() != 0) {
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700399 OutputConfiguration outputConfiguration(data);
400 ret = createStream(outputConfiguration);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700401 } else {
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700402 ALOGE("%s: cannot take an empty OutputConfiguration", __FUNCTION__);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700403 }
404
Igor Murashkine7ee7632013-06-11 18:10:18 -0700405 reply->writeNoException();
406 ALOGV("%s: CREATE_STREAM: write noException", __FUNCTION__);
407 reply->writeInt32(ret);
408 ALOGV("%s: CREATE_STREAM: write ret = %d", __FUNCTION__, ret);
409
410 return NO_ERROR;
411 } break;
412
413 case CREATE_DEFAULT_REQUEST: {
414 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
415
416 int templateId = data.readInt32();
417
418 CameraMetadata request;
419 status_t ret;
420 ret = createDefaultRequest(templateId, &request);
421
422 reply->writeNoException();
423 reply->writeInt32(ret);
424
Igor Murashkin099b4572013-07-12 17:52:16 -0700425 // out-variables are after exception and return value
Igor Murashkine7ee7632013-06-11 18:10:18 -0700426 reply->writeInt32(1); // to mark presence of metadata object
427 request.writeToParcel(const_cast<Parcel*>(reply));
428
429 return NO_ERROR;
430 } break;
431 case GET_CAMERA_INFO: {
432 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
433
Igor Murashkin099b4572013-07-12 17:52:16 -0700434 CameraMetadata info;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700435 status_t ret;
Igor Murashkin099b4572013-07-12 17:52:16 -0700436 ret = getCameraInfo(&info);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700437
438 reply->writeNoException();
439 reply->writeInt32(ret);
440
Igor Murashkin099b4572013-07-12 17:52:16 -0700441 // out-variables are after exception and return value
442 reply->writeInt32(1); // to mark presence of metadata object
443 info.writeToParcel(reply);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700444
445 return NO_ERROR;
446 } break;
Zhijun He2ab500c2013-07-23 08:02:53 -0700447 case WAIT_UNTIL_IDLE: {
448 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
449 reply->writeNoException();
450 reply->writeInt32(waitUntilIdle());
451 return NO_ERROR;
452 } break;
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700453 case FLUSH: {
454 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
455 reply->writeNoException();
Jianing Weicb0652e2014-03-12 18:29:36 -0700456 int64_t lastFrameNumber = -1;
457 reply->writeInt32(flush(&lastFrameNumber));
458 reply->writeInt32(1);
459 reply->writeInt64(lastFrameNumber);
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700460 return NO_ERROR;
461 }
Ruben Brunkb2119af2014-05-09 19:57:56 -0700462 case BEGIN_CONFIGURE: {
463 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
464 reply->writeNoException();
465 reply->writeInt32(beginConfigure());
466 return NO_ERROR;
467 } break;
468 case END_CONFIGURE: {
469 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
470 reply->writeNoException();
471 reply->writeInt32(endConfigure());
472 return NO_ERROR;
473 } break;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700474 default:
475 return BBinder::onTransact(code, data, reply, flags);
476 }
477}
478
479// ----------------------------------------------------------------------------
480
481}; // namespace android