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 "ICameraDeviceUser"
20 #include <utils/Log.h>
21 #include <stdint.h>
22 #include <sys/types.h>
23 #include <binder/Parcel.h>
24 #include <camera/camera2/ICameraDeviceUser.h>
25 #include <gui/IGraphicBufferProducer.h>
26 #include <gui/Surface.h>
27 #include <camera/CameraMetadata.h>
28 #include <camera/camera2/CaptureRequest.h>
29
30 namespace android {
31
32 typedef Parcel::WritableBlob WritableBlob;
33 typedef Parcel::ReadableBlob ReadableBlob;
34
35 enum {
36 DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
37 SUBMIT_REQUEST,
38 SUBMIT_REQUEST_LIST,
39 CANCEL_REQUEST,
40 BEGIN_CONFIGURE,
41 END_CONFIGURE,
42 DELETE_STREAM,
43 CREATE_STREAM,
44 CREATE_DEFAULT_REQUEST,
45 GET_CAMERA_INFO,
46 WAIT_UNTIL_IDLE,
47 FLUSH
48 };
49
50 namespace {
51 // Read empty strings without printing a false error message.
readMaybeEmptyString16(const Parcel & parcel)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
63 class BpCameraDeviceUser : public BpInterface<ICameraDeviceUser>
64 {
65 public:
BpCameraDeviceUser(const sp<IBinder> & impl)66 BpCameraDeviceUser(const sp<IBinder>& impl)
67 : BpInterface<ICameraDeviceUser>(impl)
68 {
69 }
70
71 // disconnect from camera service
disconnect()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
submitRequest(sp<CaptureRequest> request,bool repeating,int64_t * lastFrameNumber)81 virtual status_t submitRequest(sp<CaptureRequest> request, bool repeating,
82 int64_t *lastFrameNumber)
83 {
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)
96 data.writeInt32(repeating);
97
98 remote()->transact(SUBMIT_REQUEST, data, &reply);
99
100 reply.readExceptionCode();
101 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
110 if ((res != NO_ERROR) || (resFrameNumber != NO_ERROR)) {
111 res = FAILED_TRANSACTION;
112 }
113 return res;
114 }
115
submitRequestList(List<sp<CaptureRequest>> requestList,bool repeating,int64_t * lastFrameNumber)116 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 }
150 if ((res != NO_ERROR) || (resFrameNumber != NO_ERROR)) {
151 res = FAILED_TRANSACTION;
152 }
153 return res;
154 }
155
cancelRequest(int requestId,int64_t * lastFrameNumber)156 virtual status_t cancelRequest(int requestId, int64_t *lastFrameNumber)
157 {
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();
165 status_t res = reply.readInt32();
166
167 status_t resFrameNumber = BAD_VALUE;
168 if (reply.readInt32() != 0) {
169 if (lastFrameNumber != NULL) {
170 res = reply.readInt64(lastFrameNumber);
171 }
172 }
173 if ((res != NO_ERROR) || (resFrameNumber != NO_ERROR)) {
174 res = FAILED_TRANSACTION;
175 }
176 return res;
177 }
178
beginConfigure()179 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
endConfigure()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
deleteStream(int streamId)199 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
createStream(int width,int height,int format,const sp<IGraphicBufferProducer> & bufferProducer)211 virtual status_t createStream(int width, int height, int format,
212 const sp<IGraphicBufferProducer>& bufferProducer)
213 {
214 Parcel data, reply;
215 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
216 data.writeInt32(width);
217 data.writeInt32(height);
218 data.writeInt32(format);
219
220 data.writeInt32(1); // marker that bufferProducer is not null
221 data.writeString16(String16("unknown_name")); // name of surface
222 sp<IBinder> b(bufferProducer->asBinder());
223 data.writeStrongBinder(b);
224
225 remote()->transact(CREATE_STREAM, data, &reply);
226
227 reply.readExceptionCode();
228 return reply.readInt32();
229 }
230
231 // Create a request object from a template.
createDefaultRequest(int templateId,CameraMetadata * request)232 virtual status_t createDefaultRequest(int templateId,
233 /*out*/
234 CameraMetadata* request)
235 {
236 Parcel data, reply;
237 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
238 data.writeInt32(templateId);
239 remote()->transact(CREATE_DEFAULT_REQUEST, data, &reply);
240
241 reply.readExceptionCode();
242 status_t result = reply.readInt32();
243
244 CameraMetadata out;
245 if (reply.readInt32() != 0) {
246 out.readFromParcel(&reply);
247 }
248
249 if (request != NULL) {
250 request->swap(out);
251 }
252 return result;
253 }
254
255
getCameraInfo(CameraMetadata * info)256 virtual status_t getCameraInfo(CameraMetadata* info)
257 {
258 Parcel data, reply;
259 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
260 remote()->transact(GET_CAMERA_INFO, data, &reply);
261
262 reply.readExceptionCode();
263 status_t result = reply.readInt32();
264
265 CameraMetadata out;
266 if (reply.readInt32() != 0) {
267 out.readFromParcel(&reply);
268 }
269
270 if (info != NULL) {
271 info->swap(out);
272 }
273
274 return result;
275 }
276
waitUntilIdle()277 virtual status_t waitUntilIdle()
278 {
279 ALOGV("waitUntilIdle");
280 Parcel data, reply;
281 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
282 remote()->transact(WAIT_UNTIL_IDLE, data, &reply);
283 reply.readExceptionCode();
284 return reply.readInt32();
285 }
286
flush(int64_t * lastFrameNumber)287 virtual status_t flush(int64_t *lastFrameNumber)
288 {
289 ALOGV("flush");
290 Parcel data, reply;
291 data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
292 remote()->transact(FLUSH, data, &reply);
293 reply.readExceptionCode();
294 status_t res = reply.readInt32();
295
296 status_t resFrameNumber = BAD_VALUE;
297 if (reply.readInt32() != 0) {
298 if (lastFrameNumber != NULL) {
299 res = reply.readInt64(lastFrameNumber);
300 }
301 }
302 if ((res != NO_ERROR) || (resFrameNumber != NO_ERROR)) {
303 res = FAILED_TRANSACTION;
304 }
305 return res;
306 }
307
308 private:
309
310
311 };
312
313 IMPLEMENT_META_INTERFACE(CameraDeviceUser,
314 "android.hardware.camera2.ICameraDeviceUser");
315
316 // ----------------------------------------------------------------------
317
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)318 status_t BnCameraDeviceUser::onTransact(
319 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
320 {
321 switch(code) {
322 case DISCONNECT: {
323 ALOGV("DISCONNECT");
324 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
325 disconnect();
326 reply->writeNoException();
327 return NO_ERROR;
328 } break;
329 case SUBMIT_REQUEST: {
330 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
331
332 // arg0 = request
333 sp<CaptureRequest> request;
334 if (data.readInt32() != 0) {
335 request = new CaptureRequest();
336 request->readFromParcel(const_cast<Parcel*>(&data));
337 }
338
339 // arg1 = streaming (bool)
340 bool repeating = data.readInt32();
341
342 // return code: requestId (int32)
343 reply->writeNoException();
344 int64_t lastFrameNumber = -1;
345 reply->writeInt32(submitRequest(request, repeating, &lastFrameNumber));
346 reply->writeInt32(1);
347 reply->writeInt64(lastFrameNumber);
348
349 return NO_ERROR;
350 } break;
351 case SUBMIT_REQUEST_LIST: {
352 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
353
354 List<sp<CaptureRequest> > requestList;
355 int requestListSize = data.readInt32();
356 for (int i = 0; i < requestListSize; i++) {
357 if (data.readInt32() != 0) {
358 sp<CaptureRequest> request = new CaptureRequest();
359 if (request->readFromParcel(const_cast<Parcel*>(&data)) != OK) {
360 return BAD_VALUE;
361 }
362 requestList.push_back(request);
363 } else {
364 sp<CaptureRequest> request = 0;
365 requestList.push_back(request);
366 ALOGE("A request is missing. Sending in null request.");
367 }
368 }
369
370 bool repeating = data.readInt32();
371
372 reply->writeNoException();
373 int64_t lastFrameNumber = -1;
374 reply->writeInt32(submitRequestList(requestList, repeating, &lastFrameNumber));
375 reply->writeInt32(1);
376 reply->writeInt64(lastFrameNumber);
377
378 return NO_ERROR;
379 } break;
380 case CANCEL_REQUEST: {
381 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
382 int requestId = data.readInt32();
383 reply->writeNoException();
384 int64_t lastFrameNumber = -1;
385 reply->writeInt32(cancelRequest(requestId, &lastFrameNumber));
386 reply->writeInt32(1);
387 reply->writeInt64(lastFrameNumber);
388 return NO_ERROR;
389 } break;
390 case DELETE_STREAM: {
391 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
392 int streamId = data.readInt32();
393 reply->writeNoException();
394 reply->writeInt32(deleteStream(streamId));
395 return NO_ERROR;
396 } break;
397 case CREATE_STREAM: {
398 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
399 int width, height, format;
400
401 width = data.readInt32();
402 ALOGV("%s: CREATE_STREAM: width = %d", __FUNCTION__, width);
403 height = data.readInt32();
404 ALOGV("%s: CREATE_STREAM: height = %d", __FUNCTION__, height);
405 format = data.readInt32();
406 ALOGV("%s: CREATE_STREAM: format = %d", __FUNCTION__, format);
407
408 sp<IGraphicBufferProducer> bp;
409 if (data.readInt32() != 0) {
410 String16 name = readMaybeEmptyString16(data);
411 bp = interface_cast<IGraphicBufferProducer>(
412 data.readStrongBinder());
413
414 ALOGV("%s: CREATE_STREAM: bp = %p, name = %s", __FUNCTION__,
415 bp.get(), String8(name).string());
416 } else {
417 ALOGV("%s: CREATE_STREAM: bp = unset, name = unset",
418 __FUNCTION__);
419 }
420
421 status_t ret;
422 ret = createStream(width, height, format, bp);
423
424 reply->writeNoException();
425 ALOGV("%s: CREATE_STREAM: write noException", __FUNCTION__);
426 reply->writeInt32(ret);
427 ALOGV("%s: CREATE_STREAM: write ret = %d", __FUNCTION__, ret);
428
429 return NO_ERROR;
430 } break;
431
432 case CREATE_DEFAULT_REQUEST: {
433 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
434
435 int templateId = data.readInt32();
436
437 CameraMetadata request;
438 status_t ret;
439 ret = createDefaultRequest(templateId, &request);
440
441 reply->writeNoException();
442 reply->writeInt32(ret);
443
444 // out-variables are after exception and return value
445 reply->writeInt32(1); // to mark presence of metadata object
446 request.writeToParcel(const_cast<Parcel*>(reply));
447
448 return NO_ERROR;
449 } break;
450 case GET_CAMERA_INFO: {
451 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
452
453 CameraMetadata info;
454 status_t ret;
455 ret = getCameraInfo(&info);
456
457 reply->writeNoException();
458 reply->writeInt32(ret);
459
460 // out-variables are after exception and return value
461 reply->writeInt32(1); // to mark presence of metadata object
462 info.writeToParcel(reply);
463
464 return NO_ERROR;
465 } break;
466 case WAIT_UNTIL_IDLE: {
467 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
468 reply->writeNoException();
469 reply->writeInt32(waitUntilIdle());
470 return NO_ERROR;
471 } break;
472 case FLUSH: {
473 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
474 reply->writeNoException();
475 int64_t lastFrameNumber = -1;
476 reply->writeInt32(flush(&lastFrameNumber));
477 reply->writeInt32(1);
478 reply->writeInt64(lastFrameNumber);
479 return NO_ERROR;
480 }
481 case BEGIN_CONFIGURE: {
482 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
483 reply->writeNoException();
484 reply->writeInt32(beginConfigure());
485 return NO_ERROR;
486 } break;
487 case END_CONFIGURE: {
488 CHECK_INTERFACE(ICameraDeviceUser, data, reply);
489 reply->writeNoException();
490 reply->writeInt32(endConfigure());
491 return NO_ERROR;
492 } break;
493 default:
494 return BBinder::onTransact(code, data, reply, flags);
495 }
496 }
497
498 // ----------------------------------------------------------------------------
499
500 }; // namespace android
501