blob: 522d521b5b470fa458d3a7959c1eec35fefff531 [file] [log] [blame]
Yin-Chia Yeh4717c472017-02-13 10:56:40 -08001/*
2 * Copyright (C) 2017 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#define LOG_TAG "CameraHardwareInterface"
17//#define LOG_NDEBUG 0
18
19#include <inttypes.h>
Yin-Chia Yeh06760662017-04-17 17:37:03 -070020#include <media/hardware/HardwareAPI.h> // For VideoNativeHandleMetadata
Yin-Chia Yeh4717c472017-02-13 10:56:40 -080021#include "CameraHardwareInterface.h"
22
23namespace android {
24
25using namespace hardware::camera::device::V1_0;
26using namespace hardware::camera::common::V1_0;
27using hardware::hidl_handle;
28
29CameraHardwareInterface::~CameraHardwareInterface()
30{
31 ALOGI("Destroying camera %s", mName.string());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -080032 if (mHidlDevice != nullptr) {
33 mHidlDevice->close();
34 mHidlDevice.clear();
35 cleanupCirculatingBuffers();
36 }
37}
38
Yin-Chia Yeh4717c472017-02-13 10:56:40 -080039status_t CameraHardwareInterface::initialize(sp<CameraProviderManager> manager) {
Yin-Chia Yeh4717c472017-02-13 10:56:40 -080040 ALOGI("Opening camera %s", mName.string());
41
Steven Moreland5ff9c912017-03-09 23:13:00 -080042 status_t ret = manager->openSession(mName.string(), this, &mHidlDevice);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -080043 if (ret != OK) {
44 ALOGE("%s: openSession failed! %s (%d)", __FUNCTION__, strerror(-ret), ret);
45 }
46 return ret;
47}
48
49status_t CameraHardwareInterface::setPreviewScalingMode(int scalingMode)
50{
51 int rc = OK;
52 mPreviewScalingMode = scalingMode;
53 if (mPreviewWindow != nullptr) {
54 rc = native_window_set_scaling_mode(mPreviewWindow.get(),
55 scalingMode);
56 }
57 return rc;
58}
59
60status_t CameraHardwareInterface::setPreviewTransform(int transform) {
61 int rc = OK;
62 mPreviewTransform = transform;
63 if (mPreviewWindow != nullptr) {
64 rc = native_window_set_buffers_transform(mPreviewWindow.get(),
65 mPreviewTransform);
66 }
67 return rc;
68}
69
70/**
71 * Implementation of android::hardware::camera::device::V1_0::ICameraDeviceCallback
72 */
73hardware::Return<void> CameraHardwareInterface::notifyCallback(
74 NotifyCallbackMsg msgType, int32_t ext1, int32_t ext2) {
75 sNotifyCb((int32_t) msgType, ext1, ext2, (void*) this);
76 return hardware::Void();
77}
78
79hardware::Return<uint32_t> CameraHardwareInterface::registerMemory(
80 const hardware::hidl_handle& descriptor,
81 uint32_t bufferSize, uint32_t bufferCount) {
82 if (descriptor->numFds != 1) {
83 ALOGE("%s: camera memory descriptor has numFds %d (expect 1)",
84 __FUNCTION__, descriptor->numFds);
85 return 0;
86 }
87 if (descriptor->data[0] < 0) {
88 ALOGE("%s: camera memory descriptor has FD %d (expect >= 0)",
89 __FUNCTION__, descriptor->data[0]);
90 return 0;
91 }
92
93 camera_memory_t* mem = sGetMemory(descriptor->data[0], bufferSize, bufferCount, this);
94 sp<CameraHeapMemory> camMem(static_cast<CameraHeapMemory *>(mem->handle));
95 int memPoolId = camMem->mHeap->getHeapID();
96 if (memPoolId < 0) {
97 ALOGE("%s: CameraHeapMemory has FD %d (expect >= 0)", __FUNCTION__, memPoolId);
98 return 0;
99 }
Yin-Chia Yehc3424df2017-09-07 16:30:46 -0700100 std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800101 mHidlMemPoolMap.insert(std::make_pair(memPoolId, mem));
102 return memPoolId;
103}
104
105hardware::Return<void> CameraHardwareInterface::unregisterMemory(uint32_t memId) {
Yin-Chia Yehbe5d3e62017-09-22 11:32:53 -0700106 camera_memory_t* mem = nullptr;
107 {
108 std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
109 if (mHidlMemPoolMap.count(memId) == 0) {
110 ALOGE("%s: memory pool ID %d not found", __FUNCTION__, memId);
111 return hardware::Void();
112 }
113 mem = mHidlMemPoolMap.at(memId);
114 mHidlMemPoolMap.erase(memId);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800115 }
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800116 sPutMemory(mem);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800117 return hardware::Void();
118}
119
120hardware::Return<void> CameraHardwareInterface::dataCallback(
121 DataCallbackMsg msgType, uint32_t data, uint32_t bufferIndex,
122 const hardware::camera::device::V1_0::CameraFrameMetadata& metadata) {
Yin-Chia Yehbe5d3e62017-09-22 11:32:53 -0700123 camera_memory_t* mem = nullptr;
124 {
125 std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
126 if (mHidlMemPoolMap.count(data) == 0) {
127 ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
128 return hardware::Void();
129 }
130 mem = mHidlMemPoolMap.at(data);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800131 }
132 camera_frame_metadata_t md;
133 md.number_of_faces = metadata.faces.size();
134 md.faces = (camera_face_t*) metadata.faces.data();
Yin-Chia Yehbe5d3e62017-09-22 11:32:53 -0700135 sDataCb((int32_t) msgType, mem, bufferIndex, &md, this);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800136 return hardware::Void();
137}
138
139hardware::Return<void> CameraHardwareInterface::dataCallbackTimestamp(
140 DataCallbackMsg msgType, uint32_t data,
141 uint32_t bufferIndex, int64_t timestamp) {
Yin-Chia Yehbe5d3e62017-09-22 11:32:53 -0700142 camera_memory_t* mem = nullptr;
143 {
144 std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
145 if (mHidlMemPoolMap.count(data) == 0) {
146 ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
147 return hardware::Void();
148 }
149 mem = mHidlMemPoolMap.at(data);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800150 }
Yin-Chia Yehbe5d3e62017-09-22 11:32:53 -0700151 sDataCbTimestamp(timestamp, (int32_t) msgType, mem, bufferIndex, this);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800152 return hardware::Void();
153}
154
155hardware::Return<void> CameraHardwareInterface::handleCallbackTimestamp(
156 DataCallbackMsg msgType, const hidl_handle& frameData, uint32_t data,
157 uint32_t bufferIndex, int64_t timestamp) {
Yin-Chia Yehbe5d3e62017-09-22 11:32:53 -0700158 camera_memory_t* mem = nullptr;
159 {
160 std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
161 if (mHidlMemPoolMap.count(data) == 0) {
162 ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
163 return hardware::Void();
164 }
165 mem = mHidlMemPoolMap.at(data);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800166 }
Yin-Chia Yehbe5d3e62017-09-22 11:32:53 -0700167 sp<CameraHeapMemory> heapMem(static_cast<CameraHeapMemory *>(mem->handle));
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800168 VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*)
Yin-Chia Yehbe5d3e62017-09-22 11:32:53 -0700169 heapMem->mBuffers[bufferIndex]->pointer();
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800170 md->pHandle = const_cast<native_handle_t*>(frameData.getNativeHandle());
Yin-Chia Yehbe5d3e62017-09-22 11:32:53 -0700171 sDataCbTimestamp(timestamp, (int32_t) msgType, mem, bufferIndex, this);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800172 return hardware::Void();
173}
174
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700175hardware::Return<void> CameraHardwareInterface::handleCallbackTimestampBatch(
176 DataCallbackMsg msgType,
177 const hardware::hidl_vec<hardware::camera::device::V1_0::HandleTimestampMessage>& messages) {
178 std::vector<android::HandleTimestampMessage> msgs;
179 msgs.reserve(messages.size());
Yin-Chia Yehbe5d3e62017-09-22 11:32:53 -0700180 {
181 std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
182 for (const auto& hidl_msg : messages) {
183 if (mHidlMemPoolMap.count(hidl_msg.data) == 0) {
184 ALOGE("%s: memory pool ID %d not found", __FUNCTION__, hidl_msg.data);
185 return hardware::Void();
186 }
187 sp<CameraHeapMemory> mem(
188 static_cast<CameraHeapMemory *>(mHidlMemPoolMap.at(hidl_msg.data)->handle));
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700189
Yin-Chia Yehbe5d3e62017-09-22 11:32:53 -0700190 if (hidl_msg.bufferIndex >= mem->mNumBufs) {
191 ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
192 hidl_msg.bufferIndex, mem->mNumBufs);
193 return hardware::Void();
194 }
195 VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*)
196 mem->mBuffers[hidl_msg.bufferIndex]->pointer();
197 md->pHandle = const_cast<native_handle_t*>(hidl_msg.frameData.getNativeHandle());
198
199 msgs.push_back({hidl_msg.timestamp, mem->mBuffers[hidl_msg.bufferIndex]});
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700200 }
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700201 }
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700202 mDataCbTimestampBatch((int32_t) msgType, msgs, mCbUser);
203 return hardware::Void();
204}
205
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800206std::pair<bool, uint64_t> CameraHardwareInterface::getBufferId(
207 ANativeWindowBuffer* anb) {
208 std::lock_guard<std::mutex> lock(mBufferIdMapLock);
209
210 buffer_handle_t& buf = anb->handle;
211 auto it = mBufferIdMap.find(buf);
212 if (it == mBufferIdMap.end()) {
213 uint64_t bufId = mNextBufferId++;
214 mBufferIdMap[buf] = bufId;
215 mReversedBufMap[bufId] = anb;
216 return std::make_pair(true, bufId);
217 } else {
218 return std::make_pair(false, it->second);
219 }
220}
221
222void CameraHardwareInterface::cleanupCirculatingBuffers() {
223 std::lock_guard<std::mutex> lock(mBufferIdMapLock);
224 mBufferIdMap.clear();
225 mReversedBufMap.clear();
226}
227
228hardware::Return<void>
229CameraHardwareInterface::dequeueBuffer(dequeueBuffer_cb _hidl_cb) {
230 ANativeWindow *a = mPreviewWindow.get();
231 if (a == nullptr) {
232 ALOGE("%s: preview window is null", __FUNCTION__);
233 return hardware::Void();
234 }
235 ANativeWindowBuffer* anb;
236 int rc = native_window_dequeue_buffer_and_wait(a, &anb);
237 Status s = Status::INTERNAL_ERROR;
238 uint64_t bufferId = 0;
239 uint32_t stride = 0;
240 hidl_handle buf = nullptr;
241 if (rc == OK) {
242 s = Status::OK;
243 auto pair = getBufferId(anb);
244 buf = (pair.first) ? anb->handle : nullptr;
245 bufferId = pair.second;
246 stride = anb->stride;
247 }
248
249 _hidl_cb(s, bufferId, buf, stride);
250 return hardware::Void();
251}
252
253hardware::Return<Status>
254CameraHardwareInterface::enqueueBuffer(uint64_t bufferId) {
255 ANativeWindow *a = mPreviewWindow.get();
256 if (a == nullptr) {
257 ALOGE("%s: preview window is null", __FUNCTION__);
258 return Status::INTERNAL_ERROR;
259 }
260 if (mReversedBufMap.count(bufferId) == 0) {
261 ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId);
262 return Status::ILLEGAL_ARGUMENT;
263 }
264 int rc = a->queueBuffer(a, mReversedBufMap.at(bufferId), -1);
265 if (rc == 0) {
266 return Status::OK;
267 }
268 return Status::INTERNAL_ERROR;
269}
270
271hardware::Return<Status>
272CameraHardwareInterface::cancelBuffer(uint64_t bufferId) {
273 ANativeWindow *a = mPreviewWindow.get();
274 if (a == nullptr) {
275 ALOGE("%s: preview window is null", __FUNCTION__);
276 return Status::INTERNAL_ERROR;
277 }
278 if (mReversedBufMap.count(bufferId) == 0) {
279 ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId);
280 return Status::ILLEGAL_ARGUMENT;
281 }
282 int rc = a->cancelBuffer(a, mReversedBufMap.at(bufferId), -1);
283 if (rc == 0) {
284 return Status::OK;
285 }
286 return Status::INTERNAL_ERROR;
287}
288
289hardware::Return<Status>
290CameraHardwareInterface::setBufferCount(uint32_t count) {
291 ANativeWindow *a = mPreviewWindow.get();
292 if (a != nullptr) {
293 // Workaround for b/27039775
294 // Previously, setting the buffer count would reset the buffer
295 // queue's flag that allows for all buffers to be dequeued on the
296 // producer side, instead of just the producer's declared max count,
297 // if no filled buffers have yet been queued by the producer. This
298 // reset no longer happens, but some HALs depend on this behavior,
299 // so it needs to be maintained for HAL backwards compatibility.
300 // Simulate the prior behavior by disconnecting/reconnecting to the
301 // window and setting the values again. This has the drawback of
302 // actually causing memory reallocation, which may not have happened
303 // in the past.
304 native_window_api_disconnect(a, NATIVE_WINDOW_API_CAMERA);
305 native_window_api_connect(a, NATIVE_WINDOW_API_CAMERA);
306 if (mPreviewScalingMode != NOT_SET) {
307 native_window_set_scaling_mode(a, mPreviewScalingMode);
308 }
309 if (mPreviewTransform != NOT_SET) {
310 native_window_set_buffers_transform(a, mPreviewTransform);
311 }
312 if (mPreviewWidth != NOT_SET) {
313 native_window_set_buffers_dimensions(a,
314 mPreviewWidth, mPreviewHeight);
315 native_window_set_buffers_format(a, mPreviewFormat);
316 }
317 if (mPreviewUsage != 0) {
318 native_window_set_usage(a, mPreviewUsage);
319 }
320 if (mPreviewSwapInterval != NOT_SET) {
321 a->setSwapInterval(a, mPreviewSwapInterval);
322 }
323 if (mPreviewCrop.left != NOT_SET) {
324 native_window_set_crop(a, &(mPreviewCrop));
325 }
326 }
327 int rc = native_window_set_buffer_count(a, count);
328 if (rc == OK) {
329 cleanupCirculatingBuffers();
330 return Status::OK;
331 }
332 return Status::INTERNAL_ERROR;
333}
334
335hardware::Return<Status>
336CameraHardwareInterface::setBuffersGeometry(
337 uint32_t w, uint32_t h, hardware::graphics::common::V1_0::PixelFormat format) {
338 Status s = Status::INTERNAL_ERROR;
339 ANativeWindow *a = mPreviewWindow.get();
340 if (a == nullptr) {
341 ALOGE("%s: preview window is null", __FUNCTION__);
342 return s;
343 }
344 mPreviewWidth = w;
345 mPreviewHeight = h;
346 mPreviewFormat = (int) format;
347 int rc = native_window_set_buffers_dimensions(a, w, h);
348 if (rc == OK) {
349 rc = native_window_set_buffers_format(a, mPreviewFormat);
350 }
351 if (rc == OK) {
352 cleanupCirculatingBuffers();
353 s = Status::OK;
354 }
355 return s;
356}
357
358hardware::Return<Status>
359CameraHardwareInterface::setCrop(int32_t left, int32_t top, int32_t right, int32_t bottom) {
360 Status s = Status::INTERNAL_ERROR;
361 ANativeWindow *a = mPreviewWindow.get();
362 if (a == nullptr) {
363 ALOGE("%s: preview window is null", __FUNCTION__);
364 return s;
365 }
366 mPreviewCrop.left = left;
367 mPreviewCrop.top = top;
368 mPreviewCrop.right = right;
369 mPreviewCrop.bottom = bottom;
370 int rc = native_window_set_crop(a, &mPreviewCrop);
371 if (rc == OK) {
372 s = Status::OK;
373 }
374 return s;
375}
376
377hardware::Return<Status>
Chia-I Wu67a0c0e2017-04-06 13:37:01 -0700378CameraHardwareInterface::setUsage(hardware::graphics::common::V1_0::BufferUsage usage) {
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800379 Status s = Status::INTERNAL_ERROR;
380 ANativeWindow *a = mPreviewWindow.get();
381 if (a == nullptr) {
382 ALOGE("%s: preview window is null", __FUNCTION__);
383 return s;
384 }
Emilian Peev050f5dc2017-05-18 14:43:56 +0100385 mPreviewUsage = static_cast<uint64_t> (usage);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800386 int rc = native_window_set_usage(a, mPreviewUsage);
387 if (rc == OK) {
388 cleanupCirculatingBuffers();
389 s = Status::OK;
390 }
391 return s;
392}
393
394hardware::Return<Status>
395CameraHardwareInterface::setSwapInterval(int32_t interval) {
396 Status s = Status::INTERNAL_ERROR;
397 ANativeWindow *a = mPreviewWindow.get();
398 if (a == nullptr) {
399 ALOGE("%s: preview window is null", __FUNCTION__);
400 return s;
401 }
402 mPreviewSwapInterval = interval;
403 int rc = a->setSwapInterval(a, interval);
404 if (rc == OK) {
405 s = Status::OK;
406 }
407 return s;
408}
409
410hardware::Return<void>
411CameraHardwareInterface::getMinUndequeuedBufferCount(getMinUndequeuedBufferCount_cb _hidl_cb) {
412 ANativeWindow *a = mPreviewWindow.get();
413 if (a == nullptr) {
414 ALOGE("%s: preview window is null", __FUNCTION__);
415 return hardware::Void();
416 }
417 int count = 0;
418 int rc = a->query(a, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &count);
419 Status s = Status::INTERNAL_ERROR;
420 if (rc == OK) {
421 s = Status::OK;
422 }
423 _hidl_cb(s, count);
424 return hardware::Void();
425}
426
427hardware::Return<Status>
428CameraHardwareInterface::setTimestamp(int64_t timestamp) {
429 Status s = Status::INTERNAL_ERROR;
430 ANativeWindow *a = mPreviewWindow.get();
431 if (a == nullptr) {
432 ALOGE("%s: preview window is null", __FUNCTION__);
433 return s;
434 }
435 int rc = native_window_set_buffers_timestamp(a, timestamp);
436 if (rc == OK) {
437 s = Status::OK;
438 }
439 return s;
440}
441
442status_t CameraHardwareInterface::setPreviewWindow(const sp<ANativeWindow>& buf)
443{
444 ALOGV("%s(%s) buf %p", __FUNCTION__, mName.string(), buf.get());
445 if (CC_LIKELY(mHidlDevice != nullptr)) {
446 mPreviewWindow = buf;
447 if (buf != nullptr) {
448 if (mPreviewScalingMode != NOT_SET) {
449 setPreviewScalingMode(mPreviewScalingMode);
450 }
451 if (mPreviewTransform != NOT_SET) {
452 setPreviewTransform(mPreviewTransform);
453 }
454 }
455 return CameraProviderManager::mapToStatusT(
456 mHidlDevice->setPreviewWindow(buf.get() ? this : nullptr));
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800457 }
458 return INVALID_OPERATION;
459}
460
461void CameraHardwareInterface::setCallbacks(notify_callback notify_cb,
462 data_callback data_cb,
463 data_callback_timestamp data_cb_timestamp,
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700464 data_callback_timestamp_batch data_cb_timestamp_batch,
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800465 void* user)
466{
467 mNotifyCb = notify_cb;
468 mDataCb = data_cb;
469 mDataCbTimestamp = data_cb_timestamp;
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700470 mDataCbTimestampBatch = data_cb_timestamp_batch;
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800471 mCbUser = user;
472
473 ALOGV("%s(%s)", __FUNCTION__, mName.string());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800474}
475
476void CameraHardwareInterface::enableMsgType(int32_t msgType)
477{
478 ALOGV("%s(%s)", __FUNCTION__, mName.string());
479 if (CC_LIKELY(mHidlDevice != nullptr)) {
480 mHidlDevice->enableMsgType(msgType);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800481 }
482}
483
484void CameraHardwareInterface::disableMsgType(int32_t msgType)
485{
486 ALOGV("%s(%s)", __FUNCTION__, mName.string());
487 if (CC_LIKELY(mHidlDevice != nullptr)) {
488 mHidlDevice->disableMsgType(msgType);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800489 }
490}
491
492int CameraHardwareInterface::msgTypeEnabled(int32_t msgType)
493{
494 ALOGV("%s(%s)", __FUNCTION__, mName.string());
495 if (CC_LIKELY(mHidlDevice != nullptr)) {
496 return mHidlDevice->msgTypeEnabled(msgType);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800497 }
498 return false;
499}
500
501status_t CameraHardwareInterface::startPreview()
502{
503 ALOGV("%s(%s)", __FUNCTION__, mName.string());
504 if (CC_LIKELY(mHidlDevice != nullptr)) {
505 return CameraProviderManager::mapToStatusT(
506 mHidlDevice->startPreview());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800507 }
508 return INVALID_OPERATION;
509}
510
511void CameraHardwareInterface::stopPreview()
512{
513 ALOGV("%s(%s)", __FUNCTION__, mName.string());
514 if (CC_LIKELY(mHidlDevice != nullptr)) {
515 mHidlDevice->stopPreview();
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800516 }
517}
518
519int CameraHardwareInterface::previewEnabled()
520{
521 ALOGV("%s(%s)", __FUNCTION__, mName.string());
522 if (CC_LIKELY(mHidlDevice != nullptr)) {
523 return mHidlDevice->previewEnabled();
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800524 }
525 return false;
526}
527
528status_t CameraHardwareInterface::storeMetaDataInBuffers(int enable)
529{
530 ALOGV("%s(%s)", __FUNCTION__, mName.string());
531 if (CC_LIKELY(mHidlDevice != nullptr)) {
532 return CameraProviderManager::mapToStatusT(
533 mHidlDevice->storeMetaDataInBuffers(enable));
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800534 }
535 return enable ? INVALID_OPERATION: OK;
536}
537
538status_t CameraHardwareInterface::startRecording()
539{
540 ALOGV("%s(%s)", __FUNCTION__, mName.string());
541 if (CC_LIKELY(mHidlDevice != nullptr)) {
542 return CameraProviderManager::mapToStatusT(
543 mHidlDevice->startRecording());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800544 }
545 return INVALID_OPERATION;
546}
547
548/**
549 * Stop a previously started recording.
550 */
551void CameraHardwareInterface::stopRecording()
552{
553 ALOGV("%s(%s)", __FUNCTION__, mName.string());
554 if (CC_LIKELY(mHidlDevice != nullptr)) {
555 mHidlDevice->stopRecording();
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800556 }
557}
558
559/**
560 * Returns true if recording is enabled.
561 */
562int CameraHardwareInterface::recordingEnabled()
563{
564 ALOGV("%s(%s)", __FUNCTION__, mName.string());
565 if (CC_LIKELY(mHidlDevice != nullptr)) {
566 return mHidlDevice->recordingEnabled();
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800567 }
568 return false;
569}
570
571void CameraHardwareInterface::releaseRecordingFrame(const sp<IMemory>& mem)
572{
573 ALOGV("%s(%s)", __FUNCTION__, mName.string());
574 ssize_t offset;
575 size_t size;
576 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
577 int heapId = heap->getHeapID();
578 int bufferIndex = offset / size;
579 if (CC_LIKELY(mHidlDevice != nullptr)) {
580 if (size == sizeof(VideoNativeHandleMetadata)) {
581 VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) mem->pointer();
582 // Caching the handle here because md->pHandle will be subject to HAL's edit
583 native_handle_t* nh = md->pHandle;
584 hidl_handle frame = nh;
585 mHidlDevice->releaseRecordingFrameHandle(heapId, bufferIndex, frame);
586 native_handle_close(nh);
587 native_handle_delete(nh);
588 } else {
589 mHidlDevice->releaseRecordingFrame(heapId, bufferIndex);
590 }
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800591 }
592}
593
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700594void CameraHardwareInterface::releaseRecordingFrameBatch(const std::vector<sp<IMemory>>& frames)
595{
596 ALOGV("%s(%s)", __FUNCTION__, mName.string());
597 size_t n = frames.size();
598 std::vector<VideoFrameMessage> msgs;
599 msgs.reserve(n);
600 for (auto& mem : frames) {
601 if (CC_LIKELY(mHidlDevice != nullptr)) {
602 ssize_t offset;
603 size_t size;
604 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
605 if (size == sizeof(VideoNativeHandleMetadata)) {
606 uint32_t heapId = heap->getHeapID();
607 uint32_t bufferIndex = offset / size;
608 VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) mem->pointer();
609 // Caching the handle here because md->pHandle will be subject to HAL's edit
610 native_handle_t* nh = md->pHandle;
611 VideoFrameMessage msg;
612 msgs.push_back({nh, heapId, bufferIndex});
613 } else {
614 ALOGE("%s only supports VideoNativeHandleMetadata mode", __FUNCTION__);
615 return;
616 }
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700617 }
618 }
619
620 mHidlDevice->releaseRecordingFrameHandleBatch(msgs);
621
622 for (auto& msg : msgs) {
623 native_handle_t* nh = const_cast<native_handle_t*>(msg.frameData.getNativeHandle());
624 native_handle_close(nh);
625 native_handle_delete(nh);
626 }
627}
628
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800629status_t CameraHardwareInterface::autoFocus()
630{
631 ALOGV("%s(%s)", __FUNCTION__, mName.string());
632 if (CC_LIKELY(mHidlDevice != nullptr)) {
633 return CameraProviderManager::mapToStatusT(
634 mHidlDevice->autoFocus());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800635 }
636 return INVALID_OPERATION;
637}
638
639status_t CameraHardwareInterface::cancelAutoFocus()
640{
641 ALOGV("%s(%s)", __FUNCTION__, mName.string());
642 if (CC_LIKELY(mHidlDevice != nullptr)) {
643 return CameraProviderManager::mapToStatusT(
644 mHidlDevice->cancelAutoFocus());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800645 }
646 return INVALID_OPERATION;
647}
648
649status_t CameraHardwareInterface::takePicture()
650{
651 ALOGV("%s(%s)", __FUNCTION__, mName.string());
652 if (CC_LIKELY(mHidlDevice != nullptr)) {
653 return CameraProviderManager::mapToStatusT(
654 mHidlDevice->takePicture());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800655 }
656 return INVALID_OPERATION;
657}
658
659status_t CameraHardwareInterface::cancelPicture()
660{
661 ALOGV("%s(%s)", __FUNCTION__, mName.string());
662 if (CC_LIKELY(mHidlDevice != nullptr)) {
663 return CameraProviderManager::mapToStatusT(
664 mHidlDevice->cancelPicture());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800665 }
666 return INVALID_OPERATION;
667}
668
669status_t CameraHardwareInterface::setParameters(const CameraParameters &params)
670{
671 ALOGV("%s(%s)", __FUNCTION__, mName.string());
672 if (CC_LIKELY(mHidlDevice != nullptr)) {
673 return CameraProviderManager::mapToStatusT(
674 mHidlDevice->setParameters(params.flatten().string()));
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800675 }
676 return INVALID_OPERATION;
677}
678
679CameraParameters CameraHardwareInterface::getParameters() const
680{
681 ALOGV("%s(%s)", __FUNCTION__, mName.string());
682 CameraParameters parms;
683 if (CC_LIKELY(mHidlDevice != nullptr)) {
684 hardware::hidl_string outParam;
685 mHidlDevice->getParameters(
686 [&outParam](const auto& outStr) {
687 outParam = outStr;
688 });
689 String8 tmp(outParam.c_str());
690 parms.unflatten(tmp);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800691 }
692 return parms;
693}
694
695status_t CameraHardwareInterface::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
696{
697 ALOGV("%s(%s)", __FUNCTION__, mName.string());
698 if (CC_LIKELY(mHidlDevice != nullptr)) {
699 return CameraProviderManager::mapToStatusT(
700 mHidlDevice->sendCommand((CommandType) cmd, arg1, arg2));
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800701 }
702 return INVALID_OPERATION;
703}
704
705/**
706 * Release the hardware resources owned by this object. Note that this is
707 * *not* done in the destructor.
708 */
709void CameraHardwareInterface::release() {
710 ALOGV("%s(%s)", __FUNCTION__, mName.string());
711 if (CC_LIKELY(mHidlDevice != nullptr)) {
712 mHidlDevice->close();
713 mHidlDevice.clear();
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800714 }
715}
716
717/**
718 * Dump state of the camera hardware
719 */
720status_t CameraHardwareInterface::dump(int fd, const Vector<String16>& /*args*/) const
721{
722 ALOGV("%s(%s)", __FUNCTION__, mName.string());
723 if (CC_LIKELY(mHidlDevice != nullptr)) {
724 native_handle_t* handle = native_handle_create(1,0);
725 handle->data[0] = fd;
726 Status s = mHidlDevice->dumpState(handle);
727 native_handle_delete(handle);
728 return CameraProviderManager::mapToStatusT(s);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800729 }
730 return OK; // It's fine if the HAL doesn't implement dump()
731}
732
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800733void CameraHardwareInterface::sNotifyCb(int32_t msg_type, int32_t ext1,
734 int32_t ext2, void *user)
735{
736 ALOGV("%s", __FUNCTION__);
737 CameraHardwareInterface *object =
738 static_cast<CameraHardwareInterface *>(user);
739 object->mNotifyCb(msg_type, ext1, ext2, object->mCbUser);
740}
741
742void CameraHardwareInterface::sDataCb(int32_t msg_type,
743 const camera_memory_t *data, unsigned int index,
744 camera_frame_metadata_t *metadata,
745 void *user)
746{
747 ALOGV("%s", __FUNCTION__);
748 CameraHardwareInterface *object =
749 static_cast<CameraHardwareInterface *>(user);
750 sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle));
751 if (index >= mem->mNumBufs) {
752 ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
753 index, mem->mNumBufs);
754 return;
755 }
756 object->mDataCb(msg_type, mem->mBuffers[index], metadata, object->mCbUser);
757}
758
759void CameraHardwareInterface::sDataCbTimestamp(nsecs_t timestamp, int32_t msg_type,
760 const camera_memory_t *data, unsigned index,
761 void *user)
762{
763 ALOGV("%s", __FUNCTION__);
764 CameraHardwareInterface *object =
765 static_cast<CameraHardwareInterface *>(user);
766 // Start refcounting the heap object from here on. When the clients
767 // drop all references, it will be destroyed (as well as the enclosed
768 // MemoryHeapBase.
769 sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle));
770 if (index >= mem->mNumBufs) {
771 ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
772 index, mem->mNumBufs);
773 return;
774 }
775 object->mDataCbTimestamp(timestamp, msg_type, mem->mBuffers[index], object->mCbUser);
776}
777
778camera_memory_t* CameraHardwareInterface::sGetMemory(
779 int fd, size_t buf_size, uint_t num_bufs,
780 void *user __attribute__((unused)))
781{
782 CameraHeapMemory *mem;
783 if (fd < 0) {
784 mem = new CameraHeapMemory(buf_size, num_bufs);
785 } else {
786 mem = new CameraHeapMemory(fd, buf_size, num_bufs);
787 }
788 mem->incStrong(mem);
789 return &mem->handle;
790}
791
792void CameraHardwareInterface::sPutMemory(camera_memory_t *data)
793{
794 if (!data) {
795 return;
796 }
797
798 CameraHeapMemory *mem = static_cast<CameraHeapMemory *>(data->handle);
799 mem->decStrong(mem);
800}
801
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800802}; // namespace android