blob: 7e43cd7aa726a4505379c73be334aa3e0c198005 [file] [log] [blame]
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "CamDevSession@3.2-impl"
18#include <android/log.h>
19
20#include <utils/Trace.h>
21#include <hardware/gralloc.h>
22#include <hardware/gralloc1.h>
23#include "CameraDeviceSession.h"
24
25namespace android {
26namespace hardware {
27namespace camera {
28namespace device {
29namespace V3_2 {
30namespace implementation {
31
32namespace {
33
34// Copy pasted from Hwc.cpp. Use this until gralloc mapper HAL is working
35class HandleImporter {
36public:
37 HandleImporter() : mInitialized(false) {}
38
39 bool initialize()
40 {
41 // allow only one client
42 if (mInitialized) {
43 return false;
44 }
45
46 if (!openGralloc()) {
47 return false;
48 }
49
50 mInitialized = true;
51 return true;
52 }
53
54 void cleanup()
55 {
56 if (!mInitialized) {
57 return;
58 }
59
60 closeGralloc();
61 mInitialized = false;
62 }
63
64 // In IComposer, any buffer_handle_t is owned by the caller and we need to
65 // make a clone for hwcomposer2. We also need to translate empty handle
66 // to nullptr. This function does that, in-place.
67 bool importBuffer(buffer_handle_t& handle)
68 {
69 if (!handle->numFds && !handle->numInts) {
70 handle = nullptr;
71 return true;
72 }
73
74 buffer_handle_t clone = cloneBuffer(handle);
75 if (!clone) {
76 return false;
77 }
78
79 handle = clone;
80 return true;
81 }
82
83 void freeBuffer(buffer_handle_t handle)
84 {
85 if (!handle) {
86 return;
87 }
88
89 releaseBuffer(handle);
90 }
91
92 bool importFence(const native_handle_t* handle, int& fd)
93 {
94 if (handle == nullptr || handle->numFds == 0) {
95 fd = -1;
96 } else if (handle->numFds == 1) {
97 fd = dup(handle->data[0]);
98 if (fd < 0) {
99 ALOGE("failed to dup fence fd %d", handle->data[0]);
100 return false;
101 }
102 } else {
103 ALOGE("invalid fence handle with %d file descriptors",
104 handle->numFds);
105 return false;
106 }
107
108 return true;
109 }
110
111 void closeFence(int fd)
112 {
113 if (fd >= 0) {
114 close(fd);
115 }
116 }
117
118private:
119 bool mInitialized;
120
121 // Some existing gralloc drivers do not support retaining more than once,
122 // when we are in passthrough mode.
123#ifdef BINDERIZED
124 bool openGralloc()
125 {
126 const hw_module_t* module;
127 int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
128 if (err) {
129 ALOGE("failed to get gralloc module");
130 return false;
131 }
132
133 uint8_t major = (module->module_api_version >> 8) & 0xff;
134 if (major > 1) {
135 ALOGE("unknown gralloc module major version %d", major);
136 return false;
137 }
138
139 if (major == 1) {
140 err = gralloc1_open(module, &mDevice);
141 if (err) {
142 ALOGE("failed to open gralloc1 device");
143 return false;
144 }
145
146 mRetain = reinterpret_cast<GRALLOC1_PFN_RETAIN>(
147 mDevice->getFunction(mDevice, GRALLOC1_FUNCTION_RETAIN));
148 mRelease = reinterpret_cast<GRALLOC1_PFN_RELEASE>(
149 mDevice->getFunction(mDevice, GRALLOC1_FUNCTION_RELEASE));
150 if (!mRetain || !mRelease) {
151 ALOGE("invalid gralloc1 device");
152 gralloc1_close(mDevice);
153 return false;
154 }
155 } else {
156 mModule = reinterpret_cast<const gralloc_module_t*>(module);
157 }
158
159 return true;
160 }
161
162 void closeGralloc()
163 {
164 if (mDevice) {
165 gralloc1_close(mDevice);
166 }
167 }
168
169 buffer_handle_t cloneBuffer(buffer_handle_t handle)
170 {
171 native_handle_t* clone = native_handle_clone(handle);
172 if (!clone) {
173 ALOGE("failed to clone buffer %p", handle);
174 return nullptr;
175 }
176
177 bool err;
178 if (mDevice) {
179 err = (mRetain(mDevice, clone) != GRALLOC1_ERROR_NONE);
180 } else {
181 err = (mModule->registerBuffer(mModule, clone) != 0);
182 }
183
184 if (err) {
185 ALOGE("failed to retain/register buffer %p", clone);
186 native_handle_close(clone);
187 native_handle_delete(clone);
188 return nullptr;
189 }
190
191 return clone;
192 }
193
194 void releaseBuffer(buffer_handle_t handle)
195 {
196 if (mDevice) {
197 mRelease(mDevice, handle);
198 } else {
199 mModule->unregisterBuffer(mModule, handle);
200 native_handle_close(handle);
201 native_handle_delete(const_cast<native_handle_t*>(handle));
202 }
203 }
204
205 // gralloc1
206 gralloc1_device_t* mDevice;
207 GRALLOC1_PFN_RETAIN mRetain;
208 GRALLOC1_PFN_RELEASE mRelease;
209
210 // gralloc0
211 const gralloc_module_t* mModule;
212#else
213 bool openGralloc() { return true; }
214 void closeGralloc() {}
215 buffer_handle_t cloneBuffer(buffer_handle_t handle) { return handle; }
216 void releaseBuffer(buffer_handle_t) {}
217#endif
218};
219
220HandleImporter sHandleImporter;
221
222} // Anonymous namespace
223
224CameraDeviceSession::CameraDeviceSession(
225 camera3_device_t* device, const sp<ICameraDeviceCallback>& callback) :
226 camera3_callback_ops({&sProcessCaptureResult, &sNotify}),
227 mDevice(device),
228 mCallback(callback) {
229
230 // For now, we init sHandleImporter but do not cleanup (keep it alive until
231 // HAL process ends)
232 sHandleImporter.initialize();
233
234 mInitFail = initialize();
235}
236
237bool CameraDeviceSession::initialize() {
238 /** Initialize device with callback functions */
239 ATRACE_BEGIN("camera3->initialize");
240 status_t res = mDevice->ops->initialize(mDevice, this);
241 ATRACE_END();
242
243 if (res != OK) {
244 ALOGE("%s: Unable to initialize HAL device: %s (%d)",
245 __FUNCTION__, strerror(-res), res);
246 mDevice->common.close(&mDevice->common);
247 mClosed = true;
248 return true;
249 }
250 return false;
251}
252
253CameraDeviceSession::~CameraDeviceSession() {
254 if (!isClosed()) {
255 ALOGE("CameraDeviceSession deleted before close!");
256 close();
257 }
258}
259
260bool CameraDeviceSession::isClosed() {
261 Mutex::Autolock _l(mStateLock);
262 return mClosed;
263}
264
265Status CameraDeviceSession::initStatus() const {
266 Mutex::Autolock _l(mStateLock);
267 Status status = Status::OK;
268 if (mInitFail) {
269 status = Status::INTERNAL_ERROR;
270 } else if (mDisconnected) {
271 status = Status::CAMERA_DISCONNECTED;
272 } else if (mClosed) {
273 status = Status::INTERNAL_ERROR;
274 }
275 return status;
276}
277
278void CameraDeviceSession::disconnect() {
279 Mutex::Autolock _l(mStateLock);
280 mDisconnected = true;
281 ALOGW("%s: Camera device is disconnected. Closing.", __FUNCTION__);
282 if (!mClosed) {
283 mDevice->common.close(&mDevice->common);
284 mClosed = true;
285 }
286}
287
288void CameraDeviceSession::dumpState(const native_handle_t* fd) {
289 if (!isClosed()) {
290 mDevice->ops->dump(mDevice, fd->data[0]);
291 }
292}
293
294Status CameraDeviceSession::importRequest(
295 const CaptureRequest& request,
296 hidl_vec<buffer_handle_t>& allBufs,
297 hidl_vec<int>& allFences) {
298 bool hasInputBuf = (request.inputBuffer.streamId != -1 &&
299 request.inputBuffer.buffer.getNativeHandle() == nullptr);
300 size_t numOutputBufs = request.outputBuffers.size();
301 size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0);
302 // Validate all I/O buffers
303 allBufs.resize(numBufs);
304 allFences.resize(numBufs);
305 for (size_t i = 0; i < numOutputBufs; i++) {
306 allBufs[i] = request.outputBuffers[i].buffer.getNativeHandle();
307 }
308 if (hasInputBuf) {
309 allBufs[numOutputBufs] = request.inputBuffer.buffer.getNativeHandle();
310 }
311 for (size_t i = 0; i < numBufs; i++) {
312 buffer_handle_t buf = allBufs[i];
313 sHandleImporter.importBuffer(buf);
314 if (buf == nullptr) {
315 ALOGE("%s: output buffer %zu is invalid!", __FUNCTION__, i);
316 cleanupInflightBufferFences(allBufs, i, allFences, 0);
317 return Status::INTERNAL_ERROR;
318 } else {
319 allBufs[i] = buf;
320 }
321 }
322
323 // All buffers are imported. Now validate output buffer acquire fences
324 for (size_t i = 0; i < numOutputBufs; i++) {
325 if (!sHandleImporter.importFence(
326 request.outputBuffers[i].acquireFence, allFences[i])) {
327 ALOGE("%s: output buffer %zu acquire fence is invalid", __FUNCTION__, i);
328 cleanupInflightBufferFences(allBufs, numBufs, allFences, i);
329 return Status::INTERNAL_ERROR;
330 }
331 }
332
333 // Validate input buffer acquire fences
334 if (hasInputBuf) {
335 if (!sHandleImporter.importFence(
336 request.inputBuffer.acquireFence, allFences[numOutputBufs])) {
337 ALOGE("%s: input buffer acquire fence is invalid", __FUNCTION__);
338 cleanupInflightBufferFences(allBufs, numBufs, allFences, numOutputBufs);
339 return Status::INTERNAL_ERROR;
340 }
341 }
342 return Status::OK;
343}
344
345void CameraDeviceSession::cleanupInflightBufferFences(
346 hidl_vec<buffer_handle_t>& allBufs, size_t numBufs,
347 hidl_vec<int>& allFences, size_t numFences) {
348 for (size_t j = 0; j < numBufs; j++) {
349 sHandleImporter.freeBuffer(allBufs[j]);
350 }
351 for (size_t j = 0; j < numFences; j++) {
352 sHandleImporter.closeFence(allFences[j]);
353 }
354}
355
356// Methods from ::android::hardware::camera::device::V3_2::ICameraDeviceSession follow.
357Return<void> CameraDeviceSession::constructDefaultRequestSettings(
358 RequestTemplate type, constructDefaultRequestSettings_cb _hidl_cb) {
359 Status status = initStatus();
360 CameraMetadata outMetadata;
361 const camera_metadata_t *rawRequest;
362 if (status == Status::OK) {
363 ATRACE_BEGIN("camera3->construct_default_request_settings");
364 rawRequest = mDevice->ops->construct_default_request_settings(mDevice, (int) type);
365 ATRACE_END();
366 if (rawRequest == nullptr) {
367 ALOGI("%s: template %d is not supported on this camera device",
368 __FUNCTION__, type);
369 status = Status::ILLEGAL_ARGUMENT;
370 } else {
371 convertToHidl(rawRequest, &outMetadata);
372 }
373 }
374 _hidl_cb(status, outMetadata);
375 return Void();
376}
377
378Return<void> CameraDeviceSession::configureStreams(
379 const StreamConfiguration& requestedConfiguration, configureStreams_cb _hidl_cb) {
380 Status status = initStatus();
381 if (!mInflightBuffers.empty()) {
382 ALOGE("%s: trying to configureStreams while there are still %zu inflight buffers!",
383 __FUNCTION__, mInflightBuffers.size());
384 status = Status::INTERNAL_ERROR;
385 }
386
387 HalStreamConfiguration outStreams;
388 if (status == Status::OK) {
389 camera3_stream_configuration_t stream_list;
390 hidl_vec<camera3_stream_t*> streams;
391
392 stream_list.operation_mode = (uint32_t) requestedConfiguration.operationMode;
393 stream_list.num_streams = requestedConfiguration.streams.size();
394 streams.resize(stream_list.num_streams);
395 stream_list.streams = streams.data();
396
397 mStreamMap.clear();
398 for (uint32_t i = 0; i < stream_list.num_streams; i++) {
399 Camera3Stream stream;
400 convertFromHidl(requestedConfiguration.streams[i], &stream);
401 mStreamMap[stream.mId] = stream;
402 streams[i] = &mStreamMap[stream.mId];
403 }
404
405 ATRACE_BEGIN("camera3->configure_streams");
406 status_t ret = mDevice->ops->configure_streams(mDevice, &stream_list);
407 ATRACE_END();
408
409 if (ret == -EINVAL) {
410 status = Status::ILLEGAL_ARGUMENT;
411 } else if (ret != OK) {
412 status = Status::INTERNAL_ERROR;
413 } else {
414 convertToHidl(stream_list, &outStreams);
415 }
416
417 }
418 _hidl_cb(status, outStreams);
419 return Void();
420}
421
422Return<Status> CameraDeviceSession::processCaptureRequest(const CaptureRequest& request) {
423 Status status = initStatus();
424 if (status != Status::OK) {
425 ALOGE("%s: camera init failed or disconnected", __FUNCTION__);
426 return status;
427 }
428
429 camera3_capture_request_t halRequest;
430 halRequest.frame_number = request.frameNumber;
431 bool converted = convertFromHidl(request.settings, &halRequest.settings);
432 if (!converted) {
433 ALOGE("%s: capture request settings metadata is corrupt!", __FUNCTION__);
434 return Status::INTERNAL_ERROR;
435 }
436
437 hidl_vec<buffer_handle_t> allBufs;
438 hidl_vec<int> allFences;
439 bool hasInputBuf = (request.inputBuffer.streamId != -1 &&
440 request.inputBuffer.buffer.getNativeHandle() == nullptr);
441 size_t numOutputBufs = request.outputBuffers.size();
442 size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0);
443 status = importRequest(request, allBufs, allFences);
444 if (status != Status::OK) {
445 return status;
446 }
447
448 if (hasInputBuf) {
449 auto key = std::make_pair(request.inputBuffer.streamId, request.frameNumber);
450 auto& bufCache = mInflightBuffers[key] = StreamBufferCache{};
451 // The last parameter (&bufCache) must be in heap, or we will
452 // send a pointer pointing to stack memory to HAL and later HAL will break
453 // when trying to accessing it after this call returned.
454 convertFromHidl(
455 allBufs[numOutputBufs], request.inputBuffer.status,
456 &mStreamMap[request.inputBuffer.streamId], allFences[numOutputBufs],
457 &bufCache);
458 halRequest.input_buffer = &(bufCache.mStreamBuffer);
459 } else {
460 halRequest.input_buffer = nullptr;
461 }
462
463 halRequest.num_output_buffers = numOutputBufs;
464 hidl_vec<camera3_stream_buffer_t> outHalBufs;
465 outHalBufs.resize(numOutputBufs);
466 for (size_t i = 0; i < numOutputBufs; i++) {
467 auto key = std::make_pair(request.outputBuffers[i].streamId, request.frameNumber);
468 auto& bufCache = mInflightBuffers[key] = StreamBufferCache{};
469 // The last parameter (&bufCache) must be in heap, or we will
470 // send a pointer pointing to stack memory to HAL and later HAL will break
471 // when trying to accessing it after this call returned.
472 convertFromHidl(
473 allBufs[i], request.outputBuffers[i].status,
474 &mStreamMap[request.outputBuffers[i].streamId], allFences[i],
475 &bufCache);
476 outHalBufs[i] = bufCache.mStreamBuffer;
477 }
478 halRequest.output_buffers = outHalBufs.data();
479
480 ATRACE_ASYNC_BEGIN("frame capture", request.frameNumber);
481 ATRACE_BEGIN("camera3->process_capture_request");
482 status_t ret = mDevice->ops->process_capture_request(mDevice, &halRequest);
483 ATRACE_END();
484 if (ret != OK) {
485 ALOGE("%s: HAL process_capture_request call failed!", __FUNCTION__);
486
487 cleanupInflightBufferFences(allBufs, numBufs, allFences, numBufs);
488 if (hasInputBuf) {
489 auto key = std::make_pair(request.inputBuffer.streamId, request.frameNumber);
490 mInflightBuffers.erase(key);
491 }
492 for (size_t i = 0; i < numOutputBufs; i++) {
493 auto key = std::make_pair(request.outputBuffers[i].streamId, request.frameNumber);
494 mInflightBuffers.erase(key);
495 }
496 return Status::INTERNAL_ERROR;
497 }
498
499 return Status::OK;
500}
501
502Return<Status> CameraDeviceSession::flush() {
503 Status status = initStatus();
504 if (status == Status::OK) {
505 // Flush is always supported on device 3.1 or later
506 status_t ret = mDevice->ops->flush(mDevice);
507 if (ret != OK) {
508 status = Status::INTERNAL_ERROR;
509 }
510 }
511 return status;
512}
513
514Return<void> CameraDeviceSession::close() {
515 Mutex::Autolock _l(mStateLock);
516 if (!mClosed) {
517 ATRACE_BEGIN("camera3->close");
518 mDevice->common.close(&mDevice->common);
519 ATRACE_END();
520 mClosed = true;
521 }
522 return Void();
523}
524
525/**
526 * Static callback forwarding methods from HAL to instance
527 */
528void CameraDeviceSession::sProcessCaptureResult(
529 const camera3_callback_ops *cb,
530 const camera3_capture_result *hal_result) {
531 CameraDeviceSession *d =
532 const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb));
533
534 uint32_t frameNumber = hal_result->frame_number;
535 bool hasInputBuf = (hal_result->input_buffer != nullptr);
536 size_t numOutputBufs = hal_result->num_output_buffers;
537 size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0);
538 Status status = Status::OK;
539 if (hasInputBuf) {
540 int streamId = static_cast<Camera3Stream*>(hal_result->input_buffer->stream)->mId;
541 // validate if buffer is inflight
542 auto key = std::make_pair(streamId, frameNumber);
543 if (d->mInflightBuffers.count(key) != 1) {
544 ALOGE("%s: input buffer for stream %d frame %d is not inflight!",
545 __FUNCTION__, streamId, frameNumber);
546 return;
547 }
548 }
549
550 for (size_t i = 0; i < numOutputBufs; i++) {
551 int streamId = static_cast<Camera3Stream*>(hal_result->output_buffers[i].stream)->mId;
552 // validate if buffer is inflight
553 auto key = std::make_pair(streamId, frameNumber);
554 if (d->mInflightBuffers.count(key) != 1) {
555 ALOGE("%s: output buffer for stream %d frame %d is not inflight!",
556 __FUNCTION__, streamId, frameNumber);
557 return;
558 }
559 }
560 // We don't need to validate/import fences here since we will be passing them to camera service
561 // within the scope of this function
562
563 CaptureResult result;
564 hidl_vec<native_handle_t*> releaseFences;
565 releaseFences.resize(numBufs);
566 result.frameNumber = frameNumber;
567 result.partialResult = hal_result->partial_result;
568 convertToHidl(hal_result->result, &result.result);
569 if (hasInputBuf) {
570 result.inputBuffer.streamId =
571 static_cast<Camera3Stream*>(hal_result->input_buffer->stream)->mId;
572 result.inputBuffer.buffer = nullptr;
573 result.inputBuffer.status = (BufferStatus) hal_result->input_buffer->status;
574 // skip acquire fence since it's no use to camera service
575 if (hal_result->input_buffer->release_fence != -1) {
576 releaseFences[numOutputBufs] = native_handle_create(/*numFds*/1, /*numInts*/0);
577 releaseFences[numOutputBufs]->data[0] = hal_result->input_buffer->release_fence;
578 result.inputBuffer.releaseFence = releaseFences[numOutputBufs];
579 }
580 } else {
581 result.inputBuffer.streamId = -1;
582 }
583
584 result.outputBuffers.resize(numOutputBufs);
585 for (size_t i = 0; i < numOutputBufs; i++) {
586 result.outputBuffers[i].streamId =
587 static_cast<Camera3Stream*>(hal_result->output_buffers[i].stream)->mId;
588 result.outputBuffers[i].buffer = nullptr;
589 result.outputBuffers[i].status = (BufferStatus) hal_result->output_buffers[i].status;
590 // skip acquire fence since it's of no use to camera service
591 if (hal_result->output_buffers[i].release_fence != -1) {
592 releaseFences[i] = native_handle_create(/*numFds*/1, /*numInts*/0);
593 releaseFences[i]->data[0] = hal_result->output_buffers[i].release_fence;
594 result.outputBuffers[i].releaseFence = releaseFences[i];
595 }
596 }
597
598 d->mCallback->processCaptureResult(result);
599
600 // Free cached buffer/fences.
601 if (hasInputBuf) {
602 int streamId = static_cast<Camera3Stream*>(hal_result->input_buffer->stream)->mId;
603 auto key = std::make_pair(streamId, frameNumber);
604 sHandleImporter.closeFence(d->mInflightBuffers[key].mStreamBuffer.acquire_fence);
605 sHandleImporter.freeBuffer(d->mInflightBuffers[key].mBuffer);
606 d->mInflightBuffers.erase(key);
607 }
608
609 for (size_t i = 0; i < numOutputBufs; i++) {
610 int streamId = static_cast<Camera3Stream*>(hal_result->output_buffers[i].stream)->mId;
611 auto key = std::make_pair(streamId, frameNumber);
612 sHandleImporter.closeFence(d->mInflightBuffers[key].mStreamBuffer.acquire_fence);
613 sHandleImporter.freeBuffer(d->mInflightBuffers[key].mBuffer);
614 d->mInflightBuffers.erase(key);
615 }
616
617 for (size_t i = 0; i < releaseFences.size(); i++) {
618 // We don't close the FD here as HAL needs to signal it later.
619 native_handle_delete(releaseFences[i]);
620 }
621
622}
623
624void CameraDeviceSession::sNotify(
625 const camera3_callback_ops *cb,
626 const camera3_notify_msg *msg) {
627 CameraDeviceSession *d =
628 const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb));
629 NotifyMsg hidlMsg;
630 convertToHidl(msg, &hidlMsg);
631 if (hidlMsg.type == (MsgType) CAMERA3_MSG_ERROR) {
632 if (d->mStreamMap.count(hidlMsg.msg.error.errorStreamId) != 1) {
633 ALOGE("%s: unknown stream ID %d reports an error!",
634 __FUNCTION__, hidlMsg.msg.error.errorStreamId);
635 }
636 return;
637 }
638 d->mCallback->notify(hidlMsg);
639}
640
641} // namespace implementation
642} // namespace V3_2
643} // namespace device
644} // namespace camera
645} // namespace hardware
646} // namespace android