blob: ad659553f5a0b44deb629eb8799c89341c1d0f09 [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,
40 DELETE_STREAM,
41 CREATE_STREAM,
42 CREATE_DEFAULT_REQUEST,
43 GET_CAMERA_INFO,
Zhijun He2ab500c2013-07-23 08:02:53 -070044 WAIT_UNTIL_IDLE,
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -070045 FLUSH
Igor Murashkine7ee7632013-06-11 18:10:18 -070046};
47
Igor Murashkin88aef232013-08-23 17:47:06 -070048namespace {
49 // Read empty strings without printing a false error message.
50 String16 readMaybeEmptyString16(const Parcel& parcel) {
51 size_t len;
52 const char16_t* str = parcel.readString16Inplace(&len);
53 if (str != NULL) {
54 return String16(str, len);
55 } else {
56 return String16();
57 }
58 }
59};
60
Igor Murashkine7ee7632013-06-11 18:10:18 -070061class BpCameraDeviceUser : public BpInterface<ICameraDeviceUser>
62{
63public:
64 BpCameraDeviceUser(const sp<IBinder>& impl)
65 : BpInterface<ICameraDeviceUser>(impl)
66 {
67 }
68
69 // disconnect from camera service
70 void disconnect()
71 {
72 ALOGV("disconnect");
73 Parcel data, reply;
74 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
75 remote()->transact(DISCONNECT, data, &reply);
76 reply.readExceptionCode();
77 }
78
Jianing Weicb0652e2014-03-12 18:29:36 -070079 virtual status_t submitRequest(sp<CaptureRequest> request, bool repeating,
80 int64_t *lastFrameNumber)
Igor Murashkine7ee7632013-06-11 18:10:18 -070081 {
82 Parcel data, reply;
83 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
84
85 // arg0 = CaptureRequest
86 if (request != 0) {
87 data.writeInt32(1);
88 request->writeToParcel(&data);
89 } else {
90 data.writeInt32(0);
91 }
92
93 // arg1 = streaming (bool)
Jianing Weicb0652e2014-03-12 18:29:36 -070094 data.writeInt32(repeating);
Igor Murashkine7ee7632013-06-11 18:10:18 -070095
96 remote()->transact(SUBMIT_REQUEST, data, &reply);
97
98 reply.readExceptionCode();
Jianing Weicb0652e2014-03-12 18:29:36 -070099 status_t res = reply.readInt32();
100
101 status_t resFrameNumber = BAD_VALUE;
102 if (reply.readInt32() != 0) {
103 if (lastFrameNumber != NULL) {
104 resFrameNumber = reply.readInt64(lastFrameNumber);
105 }
106 }
107
108 if ((res != NO_ERROR) || (resFrameNumber != NO_ERROR)) {
109 res = FAILED_TRANSACTION;
110 }
111 return res;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700112 }
113
Jianing Weicb0652e2014-03-12 18:29:36 -0700114 virtual status_t submitRequestList(List<sp<CaptureRequest> > requestList, bool repeating,
115 int64_t *lastFrameNumber)
116 {
117 Parcel data, reply;
118 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
119
120 data.writeInt32(requestList.size());
121
122 for (List<sp<CaptureRequest> >::iterator it = requestList.begin();
123 it != requestList.end(); ++it) {
124 sp<CaptureRequest> request = *it;
125 if (request != 0) {
126 data.writeInt32(1);
127 if (request->writeToParcel(&data) != OK) {
128 return BAD_VALUE;
129 }
130 } else {
131 data.writeInt32(0);
132 }
133 }
134
135 data.writeInt32(repeating);
136
137 remote()->transact(SUBMIT_REQUEST_LIST, data, &reply);
138
139 reply.readExceptionCode();
140 status_t res = reply.readInt32();
141
142 status_t resFrameNumber = BAD_VALUE;
143 if (reply.readInt32() != 0) {
144 if (lastFrameNumber != NULL) {
145 resFrameNumber = reply.readInt64(lastFrameNumber);
146 }
147 }
148 if ((res != NO_ERROR) || (resFrameNumber != NO_ERROR)) {
149 res = FAILED_TRANSACTION;
150 }
151 return res;
152 }
153
154 virtual status_t cancelRequest(int requestId, int64_t *lastFrameNumber)
Igor Murashkine7ee7632013-06-11 18:10:18 -0700155 {
156 Parcel data, reply;
157 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
158 data.writeInt32(requestId);
159
160 remote()->transact(CANCEL_REQUEST, data, &reply);
161
162 reply.readExceptionCode();
Jianing Weicb0652e2014-03-12 18:29:36 -0700163 status_t res = reply.readInt32();
164
165 status_t resFrameNumber = BAD_VALUE;
166 if (reply.readInt32() != 0) {
167 if (lastFrameNumber != NULL) {
168 res = reply.readInt64(lastFrameNumber);
169 }
170 }
171 if ((res != NO_ERROR) || (resFrameNumber != NO_ERROR)) {
172 res = FAILED_TRANSACTION;
173 }
174 return res;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700175 }
176
177 virtual status_t deleteStream(int streamId)
178 {
179 Parcel data, reply;
180 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
181 data.writeInt32(streamId);
182
183 remote()->transact(DELETE_STREAM, data, &reply);
184
185 reply.readExceptionCode();
186 return reply.readInt32();
187 }
188
189 virtual status_t createStream(int width, int height, int format,
190 const sp<IGraphicBufferProducer>& bufferProducer)
191 {
192 Parcel data, reply;
193 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
194 data.writeInt32(width);
195 data.writeInt32(height);
196 data.writeInt32(format);
197
198 data.writeInt32(1); // marker that bufferProducer is not null
199 data.writeString16(String16("unknown_name")); // name of surface
200 sp<IBinder> b(bufferProducer->asBinder());
201 data.writeStrongBinder(b);
202
203 remote()->transact(CREATE_STREAM, data, &reply);
204
205 reply.readExceptionCode();
206 return reply.readInt32();
207 }
208
209 // Create a request object from a template.
210 virtual status_t createDefaultRequest(int templateId,
211 /*out*/
212 CameraMetadata* request)
213 {
214 Parcel data, reply;
215 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
216 data.writeInt32(templateId);
217 remote()->transact(CREATE_DEFAULT_REQUEST, data, &reply);
218
219 reply.readExceptionCode();
220 status_t result = reply.readInt32();
221
222 CameraMetadata out;
223 if (reply.readInt32() != 0) {
224 out.readFromParcel(&reply);
225 }
226
227 if (request != NULL) {
228 request->swap(out);
229 }
230 return result;
231 }
232
233
Igor Murashkin099b4572013-07-12 17:52:16 -0700234 virtual status_t getCameraInfo(CameraMetadata* info)
Igor Murashkine7ee7632013-06-11 18:10:18 -0700235 {
236 Parcel data, reply;
237 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
Igor Murashkine7ee7632013-06-11 18:10:18 -0700238 remote()->transact(GET_CAMERA_INFO, data, &reply);
239
Igor Murashkine7ee7632013-06-11 18:10:18 -0700240 reply.readExceptionCode();
241 status_t result = reply.readInt32();
242
Igor Murashkin099b4572013-07-12 17:52:16 -0700243 CameraMetadata out;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700244 if (reply.readInt32() != 0) {
Igor Murashkin099b4572013-07-12 17:52:16 -0700245 out.readFromParcel(&reply);
246 }
247
248 if (info != NULL) {
249 info->swap(out);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700250 }
251
252 return result;
253 }
254
Zhijun He2ab500c2013-07-23 08:02:53 -0700255 virtual status_t waitUntilIdle()
256 {
257 ALOGV("waitUntilIdle");
258 Parcel data, reply;
259 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
260 remote()->transact(WAIT_UNTIL_IDLE, data, &reply);
261 reply.readExceptionCode();
262 return reply.readInt32();
263 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700264
Jianing Weicb0652e2014-03-12 18:29:36 -0700265 virtual status_t flush(int64_t *lastFrameNumber)
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700266 {
267 ALOGV("flush");
268 Parcel data, reply;
269 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
270 remote()->transact(FLUSH, data, &reply);
271 reply.readExceptionCode();
Jianing Weicb0652e2014-03-12 18:29:36 -0700272 status_t res = reply.readInt32();
273
274 status_t resFrameNumber = BAD_VALUE;
275 if (reply.readInt32() != 0) {
276 if (lastFrameNumber != NULL) {
277 res = reply.readInt64(lastFrameNumber);
278 }
279 }
280 if ((res != NO_ERROR) || (resFrameNumber != NO_ERROR)) {
281 res = FAILED_TRANSACTION;
282 }
283 return res;
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700284 }
285
Igor Murashkine7ee7632013-06-11 18:10:18 -0700286private:
287
288
289};
290
291IMPLEMENT_META_INTERFACE(CameraDeviceUser,
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -0700292 "android.hardware.camera2.ICameraDeviceUser");
Igor Murashkine7ee7632013-06-11 18:10:18 -0700293
294// ----------------------------------------------------------------------
295
296status_t BnCameraDeviceUser::onTransact(
297 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
298{
299 switch(code) {
300 case DISCONNECT: {
301 ALOGV("DISCONNECT");
302 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
303 disconnect();
304 reply->writeNoException();
305 return NO_ERROR;
306 } break;
307 case SUBMIT_REQUEST: {
308 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
309
310 // arg0 = request
311 sp<CaptureRequest> request;
312 if (data.readInt32() != 0) {
313 request = new CaptureRequest();
314 request->readFromParcel(const_cast<Parcel*>(&data));
315 }
316
317 // arg1 = streaming (bool)
Jianing Weicb0652e2014-03-12 18:29:36 -0700318 bool repeating = data.readInt32();
Igor Murashkine7ee7632013-06-11 18:10:18 -0700319
320 // return code: requestId (int32)
321 reply->writeNoException();
Jianing Weicb0652e2014-03-12 18:29:36 -0700322 int64_t lastFrameNumber = -1;
323 reply->writeInt32(submitRequest(request, repeating, &lastFrameNumber));
324 reply->writeInt32(1);
325 reply->writeInt64(lastFrameNumber);
326
327 return NO_ERROR;
328 } break;
329 case SUBMIT_REQUEST_LIST: {
330 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
331
332 List<sp<CaptureRequest> > requestList;
333 int requestListSize = data.readInt32();
334 for (int i = 0; i < requestListSize; i++) {
335 if (data.readInt32() != 0) {
336 sp<CaptureRequest> request = new CaptureRequest();
337 if (request->readFromParcel(const_cast<Parcel*>(&data)) != OK) {
338 return BAD_VALUE;
339 }
340 requestList.push_back(request);
341 } else {
342 sp<CaptureRequest> request = 0;
343 requestList.push_back(request);
344 ALOGE("A request is missing. Sending in null request.");
345 }
346 }
347
348 bool repeating = data.readInt32();
349
350 reply->writeNoException();
351 int64_t lastFrameNumber = -1;
352 reply->writeInt32(submitRequestList(requestList, repeating, &lastFrameNumber));
353 reply->writeInt32(1);
354 reply->writeInt64(lastFrameNumber);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700355
356 return NO_ERROR;
357 } break;
358 case CANCEL_REQUEST: {
359 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
360 int requestId = data.readInt32();
361 reply->writeNoException();
Jianing Weicb0652e2014-03-12 18:29:36 -0700362 int64_t lastFrameNumber = -1;
363 reply->writeInt32(cancelRequest(requestId, &lastFrameNumber));
364 reply->writeInt32(1);
365 reply->writeInt64(lastFrameNumber);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700366 return NO_ERROR;
367 } break;
368 case DELETE_STREAM: {
369 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
370 int streamId = data.readInt32();
371 reply->writeNoException();
372 reply->writeInt32(deleteStream(streamId));
373 return NO_ERROR;
374 } break;
375 case CREATE_STREAM: {
376 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
377 int width, height, format;
378
379 width = data.readInt32();
380 ALOGV("%s: CREATE_STREAM: width = %d", __FUNCTION__, width);
381 height = data.readInt32();
382 ALOGV("%s: CREATE_STREAM: height = %d", __FUNCTION__, height);
383 format = data.readInt32();
384 ALOGV("%s: CREATE_STREAM: format = %d", __FUNCTION__, format);
385
386 sp<IGraphicBufferProducer> bp;
387 if (data.readInt32() != 0) {
Igor Murashkin88aef232013-08-23 17:47:06 -0700388 String16 name = readMaybeEmptyString16(data);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700389 bp = interface_cast<IGraphicBufferProducer>(
390 data.readStrongBinder());
391
392 ALOGV("%s: CREATE_STREAM: bp = %p, name = %s", __FUNCTION__,
393 bp.get(), String8(name).string());
394 } else {
395 ALOGV("%s: CREATE_STREAM: bp = unset, name = unset",
396 __FUNCTION__);
397 }
398
399 status_t ret;
400 ret = createStream(width, height, format, bp);
401
402 reply->writeNoException();
403 ALOGV("%s: CREATE_STREAM: write noException", __FUNCTION__);
404 reply->writeInt32(ret);
405 ALOGV("%s: CREATE_STREAM: write ret = %d", __FUNCTION__, ret);
406
407 return NO_ERROR;
408 } break;
409
410 case CREATE_DEFAULT_REQUEST: {
411 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
412
413 int templateId = data.readInt32();
414
415 CameraMetadata request;
416 status_t ret;
417 ret = createDefaultRequest(templateId, &request);
418
419 reply->writeNoException();
420 reply->writeInt32(ret);
421
Igor Murashkin099b4572013-07-12 17:52:16 -0700422 // out-variables are after exception and return value
Igor Murashkine7ee7632013-06-11 18:10:18 -0700423 reply->writeInt32(1); // to mark presence of metadata object
424 request.writeToParcel(const_cast<Parcel*>(reply));
425
426 return NO_ERROR;
427 } break;
428 case GET_CAMERA_INFO: {
429 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
430
Igor Murashkin099b4572013-07-12 17:52:16 -0700431 CameraMetadata info;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700432 status_t ret;
Igor Murashkin099b4572013-07-12 17:52:16 -0700433 ret = getCameraInfo(&info);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700434
435 reply->writeNoException();
436 reply->writeInt32(ret);
437
Igor Murashkin099b4572013-07-12 17:52:16 -0700438 // out-variables are after exception and return value
439 reply->writeInt32(1); // to mark presence of metadata object
440 info.writeToParcel(reply);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700441
442 return NO_ERROR;
443 } break;
Zhijun He2ab500c2013-07-23 08:02:53 -0700444 case WAIT_UNTIL_IDLE: {
445 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
446 reply->writeNoException();
447 reply->writeInt32(waitUntilIdle());
448 return NO_ERROR;
449 } break;
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700450 case FLUSH: {
451 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
452 reply->writeNoException();
Jianing Weicb0652e2014-03-12 18:29:36 -0700453 int64_t lastFrameNumber = -1;
454 reply->writeInt32(flush(&lastFrameNumber));
455 reply->writeInt32(1);
456 reply->writeInt64(lastFrameNumber);
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700457 return NO_ERROR;
458 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700459 default:
460 return BBinder::onTransact(code, data, reply, flags);
461 }
462}
463
464// ----------------------------------------------------------------------------
465
466}; // namespace android