blob: 62ef6816685c7710b0673eff92787f3ea6ab02a5 [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));
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700168 // TODO: Using unsecurePointer() has some associated security pitfalls
169 // (see declaration for details).
170 // Either document why it is safe in this case or address the
171 // issue (e.g. by copying).
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800172 VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*)
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700173 heapMem->mBuffers[bufferIndex]->unsecurePointer();
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800174 md->pHandle = const_cast<native_handle_t*>(frameData.getNativeHandle());
Yin-Chia Yehbe5d3e62017-09-22 11:32:53 -0700175 sDataCbTimestamp(timestamp, (int32_t) msgType, mem, bufferIndex, this);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800176 return hardware::Void();
177}
178
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700179hardware::Return<void> CameraHardwareInterface::handleCallbackTimestampBatch(
180 DataCallbackMsg msgType,
181 const hardware::hidl_vec<hardware::camera::device::V1_0::HandleTimestampMessage>& messages) {
182 std::vector<android::HandleTimestampMessage> msgs;
183 msgs.reserve(messages.size());
Yin-Chia Yehbe5d3e62017-09-22 11:32:53 -0700184 {
185 std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
186 for (const auto& hidl_msg : messages) {
187 if (mHidlMemPoolMap.count(hidl_msg.data) == 0) {
188 ALOGE("%s: memory pool ID %d not found", __FUNCTION__, hidl_msg.data);
189 return hardware::Void();
190 }
191 sp<CameraHeapMemory> mem(
192 static_cast<CameraHeapMemory *>(mHidlMemPoolMap.at(hidl_msg.data)->handle));
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700193
Yin-Chia Yehbe5d3e62017-09-22 11:32:53 -0700194 if (hidl_msg.bufferIndex >= mem->mNumBufs) {
195 ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
196 hidl_msg.bufferIndex, mem->mNumBufs);
197 return hardware::Void();
198 }
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700199 // TODO: Using unsecurePointer() has some associated security pitfalls
200 // (see declaration for details).
201 // Either document why it is safe in this case or address the
202 // issue (e.g. by copying).
Yin-Chia Yehbe5d3e62017-09-22 11:32:53 -0700203 VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*)
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700204 mem->mBuffers[hidl_msg.bufferIndex]->unsecurePointer();
Yin-Chia Yehbe5d3e62017-09-22 11:32:53 -0700205 md->pHandle = const_cast<native_handle_t*>(hidl_msg.frameData.getNativeHandle());
206
207 msgs.push_back({hidl_msg.timestamp, mem->mBuffers[hidl_msg.bufferIndex]});
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700208 }
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700209 }
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700210 mDataCbTimestampBatch((int32_t) msgType, msgs, mCbUser);
211 return hardware::Void();
212}
213
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800214std::pair<bool, uint64_t> CameraHardwareInterface::getBufferId(
215 ANativeWindowBuffer* anb) {
216 std::lock_guard<std::mutex> lock(mBufferIdMapLock);
217
218 buffer_handle_t& buf = anb->handle;
219 auto it = mBufferIdMap.find(buf);
220 if (it == mBufferIdMap.end()) {
221 uint64_t bufId = mNextBufferId++;
222 mBufferIdMap[buf] = bufId;
223 mReversedBufMap[bufId] = anb;
224 return std::make_pair(true, bufId);
225 } else {
226 return std::make_pair(false, it->second);
227 }
228}
229
230void CameraHardwareInterface::cleanupCirculatingBuffers() {
231 std::lock_guard<std::mutex> lock(mBufferIdMapLock);
232 mBufferIdMap.clear();
233 mReversedBufMap.clear();
234}
235
236hardware::Return<void>
237CameraHardwareInterface::dequeueBuffer(dequeueBuffer_cb _hidl_cb) {
238 ANativeWindow *a = mPreviewWindow.get();
239 if (a == nullptr) {
240 ALOGE("%s: preview window is null", __FUNCTION__);
241 return hardware::Void();
242 }
243 ANativeWindowBuffer* anb;
244 int rc = native_window_dequeue_buffer_and_wait(a, &anb);
245 Status s = Status::INTERNAL_ERROR;
246 uint64_t bufferId = 0;
247 uint32_t stride = 0;
248 hidl_handle buf = nullptr;
249 if (rc == OK) {
250 s = Status::OK;
251 auto pair = getBufferId(anb);
252 buf = (pair.first) ? anb->handle : nullptr;
253 bufferId = pair.second;
254 stride = anb->stride;
255 }
256
257 _hidl_cb(s, bufferId, buf, stride);
258 return hardware::Void();
259}
260
261hardware::Return<Status>
262CameraHardwareInterface::enqueueBuffer(uint64_t bufferId) {
263 ANativeWindow *a = mPreviewWindow.get();
264 if (a == nullptr) {
265 ALOGE("%s: preview window is null", __FUNCTION__);
266 return Status::INTERNAL_ERROR;
267 }
268 if (mReversedBufMap.count(bufferId) == 0) {
269 ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId);
270 return Status::ILLEGAL_ARGUMENT;
271 }
272 int rc = a->queueBuffer(a, mReversedBufMap.at(bufferId), -1);
273 if (rc == 0) {
274 return Status::OK;
275 }
276 return Status::INTERNAL_ERROR;
277}
278
279hardware::Return<Status>
280CameraHardwareInterface::cancelBuffer(uint64_t bufferId) {
281 ANativeWindow *a = mPreviewWindow.get();
282 if (a == nullptr) {
283 ALOGE("%s: preview window is null", __FUNCTION__);
284 return Status::INTERNAL_ERROR;
285 }
286 if (mReversedBufMap.count(bufferId) == 0) {
287 ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId);
288 return Status::ILLEGAL_ARGUMENT;
289 }
290 int rc = a->cancelBuffer(a, mReversedBufMap.at(bufferId), -1);
291 if (rc == 0) {
292 return Status::OK;
293 }
294 return Status::INTERNAL_ERROR;
295}
296
297hardware::Return<Status>
298CameraHardwareInterface::setBufferCount(uint32_t count) {
299 ANativeWindow *a = mPreviewWindow.get();
300 if (a != nullptr) {
301 // Workaround for b/27039775
302 // Previously, setting the buffer count would reset the buffer
303 // queue's flag that allows for all buffers to be dequeued on the
304 // producer side, instead of just the producer's declared max count,
305 // if no filled buffers have yet been queued by the producer. This
306 // reset no longer happens, but some HALs depend on this behavior,
307 // so it needs to be maintained for HAL backwards compatibility.
308 // Simulate the prior behavior by disconnecting/reconnecting to the
309 // window and setting the values again. This has the drawback of
310 // actually causing memory reallocation, which may not have happened
311 // in the past.
312 native_window_api_disconnect(a, NATIVE_WINDOW_API_CAMERA);
313 native_window_api_connect(a, NATIVE_WINDOW_API_CAMERA);
314 if (mPreviewScalingMode != NOT_SET) {
315 native_window_set_scaling_mode(a, mPreviewScalingMode);
316 }
317 if (mPreviewTransform != NOT_SET) {
318 native_window_set_buffers_transform(a, mPreviewTransform);
319 }
320 if (mPreviewWidth != NOT_SET) {
321 native_window_set_buffers_dimensions(a,
322 mPreviewWidth, mPreviewHeight);
323 native_window_set_buffers_format(a, mPreviewFormat);
324 }
325 if (mPreviewUsage != 0) {
326 native_window_set_usage(a, mPreviewUsage);
327 }
328 if (mPreviewSwapInterval != NOT_SET) {
329 a->setSwapInterval(a, mPreviewSwapInterval);
330 }
331 if (mPreviewCrop.left != NOT_SET) {
332 native_window_set_crop(a, &(mPreviewCrop));
333 }
334 }
335 int rc = native_window_set_buffer_count(a, count);
336 if (rc == OK) {
337 cleanupCirculatingBuffers();
338 return Status::OK;
339 }
340 return Status::INTERNAL_ERROR;
341}
342
343hardware::Return<Status>
344CameraHardwareInterface::setBuffersGeometry(
345 uint32_t w, uint32_t h, hardware::graphics::common::V1_0::PixelFormat format) {
346 Status s = Status::INTERNAL_ERROR;
347 ANativeWindow *a = mPreviewWindow.get();
348 if (a == nullptr) {
349 ALOGE("%s: preview window is null", __FUNCTION__);
350 return s;
351 }
352 mPreviewWidth = w;
353 mPreviewHeight = h;
354 mPreviewFormat = (int) format;
355 int rc = native_window_set_buffers_dimensions(a, w, h);
356 if (rc == OK) {
357 rc = native_window_set_buffers_format(a, mPreviewFormat);
358 }
359 if (rc == OK) {
360 cleanupCirculatingBuffers();
361 s = Status::OK;
362 }
363 return s;
364}
365
366hardware::Return<Status>
367CameraHardwareInterface::setCrop(int32_t left, int32_t top, int32_t right, int32_t bottom) {
368 Status s = Status::INTERNAL_ERROR;
369 ANativeWindow *a = mPreviewWindow.get();
370 if (a == nullptr) {
371 ALOGE("%s: preview window is null", __FUNCTION__);
372 return s;
373 }
374 mPreviewCrop.left = left;
375 mPreviewCrop.top = top;
376 mPreviewCrop.right = right;
377 mPreviewCrop.bottom = bottom;
378 int rc = native_window_set_crop(a, &mPreviewCrop);
379 if (rc == OK) {
380 s = Status::OK;
381 }
382 return s;
383}
384
385hardware::Return<Status>
Chia-I Wu67a0c0e2017-04-06 13:37:01 -0700386CameraHardwareInterface::setUsage(hardware::graphics::common::V1_0::BufferUsage usage) {
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800387 Status s = Status::INTERNAL_ERROR;
388 ANativeWindow *a = mPreviewWindow.get();
389 if (a == nullptr) {
390 ALOGE("%s: preview window is null", __FUNCTION__);
391 return s;
392 }
Emilian Peev050f5dc2017-05-18 14:43:56 +0100393 mPreviewUsage = static_cast<uint64_t> (usage);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800394 int rc = native_window_set_usage(a, mPreviewUsage);
395 if (rc == OK) {
396 cleanupCirculatingBuffers();
397 s = Status::OK;
398 }
399 return s;
400}
401
402hardware::Return<Status>
403CameraHardwareInterface::setSwapInterval(int32_t interval) {
404 Status s = Status::INTERNAL_ERROR;
405 ANativeWindow *a = mPreviewWindow.get();
406 if (a == nullptr) {
407 ALOGE("%s: preview window is null", __FUNCTION__);
408 return s;
409 }
410 mPreviewSwapInterval = interval;
411 int rc = a->setSwapInterval(a, interval);
412 if (rc == OK) {
413 s = Status::OK;
414 }
415 return s;
416}
417
418hardware::Return<void>
419CameraHardwareInterface::getMinUndequeuedBufferCount(getMinUndequeuedBufferCount_cb _hidl_cb) {
420 ANativeWindow *a = mPreviewWindow.get();
421 if (a == nullptr) {
422 ALOGE("%s: preview window is null", __FUNCTION__);
423 return hardware::Void();
424 }
425 int count = 0;
426 int rc = a->query(a, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &count);
427 Status s = Status::INTERNAL_ERROR;
428 if (rc == OK) {
429 s = Status::OK;
430 }
431 _hidl_cb(s, count);
432 return hardware::Void();
433}
434
435hardware::Return<Status>
436CameraHardwareInterface::setTimestamp(int64_t timestamp) {
437 Status s = Status::INTERNAL_ERROR;
438 ANativeWindow *a = mPreviewWindow.get();
439 if (a == nullptr) {
440 ALOGE("%s: preview window is null", __FUNCTION__);
441 return s;
442 }
443 int rc = native_window_set_buffers_timestamp(a, timestamp);
444 if (rc == OK) {
445 s = Status::OK;
446 }
447 return s;
448}
449
450status_t CameraHardwareInterface::setPreviewWindow(const sp<ANativeWindow>& buf)
451{
452 ALOGV("%s(%s) buf %p", __FUNCTION__, mName.string(), buf.get());
453 if (CC_LIKELY(mHidlDevice != nullptr)) {
454 mPreviewWindow = buf;
455 if (buf != nullptr) {
456 if (mPreviewScalingMode != NOT_SET) {
457 setPreviewScalingMode(mPreviewScalingMode);
458 }
459 if (mPreviewTransform != NOT_SET) {
460 setPreviewTransform(mPreviewTransform);
461 }
462 }
463 return CameraProviderManager::mapToStatusT(
464 mHidlDevice->setPreviewWindow(buf.get() ? this : nullptr));
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800465 }
466 return INVALID_OPERATION;
467}
468
469void CameraHardwareInterface::setCallbacks(notify_callback notify_cb,
470 data_callback data_cb,
471 data_callback_timestamp data_cb_timestamp,
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700472 data_callback_timestamp_batch data_cb_timestamp_batch,
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800473 void* user)
474{
475 mNotifyCb = notify_cb;
476 mDataCb = data_cb;
477 mDataCbTimestamp = data_cb_timestamp;
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700478 mDataCbTimestampBatch = data_cb_timestamp_batch;
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800479 mCbUser = user;
480
481 ALOGV("%s(%s)", __FUNCTION__, mName.string());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800482}
483
484void CameraHardwareInterface::enableMsgType(int32_t msgType)
485{
486 ALOGV("%s(%s)", __FUNCTION__, mName.string());
487 if (CC_LIKELY(mHidlDevice != nullptr)) {
488 mHidlDevice->enableMsgType(msgType);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800489 }
490}
491
492void CameraHardwareInterface::disableMsgType(int32_t msgType)
493{
494 ALOGV("%s(%s)", __FUNCTION__, mName.string());
495 if (CC_LIKELY(mHidlDevice != nullptr)) {
496 mHidlDevice->disableMsgType(msgType);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800497 }
498}
499
500int CameraHardwareInterface::msgTypeEnabled(int32_t msgType)
501{
502 ALOGV("%s(%s)", __FUNCTION__, mName.string());
503 if (CC_LIKELY(mHidlDevice != nullptr)) {
504 return mHidlDevice->msgTypeEnabled(msgType);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800505 }
506 return false;
507}
508
509status_t CameraHardwareInterface::startPreview()
510{
511 ALOGV("%s(%s)", __FUNCTION__, mName.string());
512 if (CC_LIKELY(mHidlDevice != nullptr)) {
513 return CameraProviderManager::mapToStatusT(
514 mHidlDevice->startPreview());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800515 }
516 return INVALID_OPERATION;
517}
518
519void CameraHardwareInterface::stopPreview()
520{
521 ALOGV("%s(%s)", __FUNCTION__, mName.string());
522 if (CC_LIKELY(mHidlDevice != nullptr)) {
523 mHidlDevice->stopPreview();
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800524 }
525}
526
527int CameraHardwareInterface::previewEnabled()
528{
529 ALOGV("%s(%s)", __FUNCTION__, mName.string());
530 if (CC_LIKELY(mHidlDevice != nullptr)) {
531 return mHidlDevice->previewEnabled();
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800532 }
533 return false;
534}
535
536status_t CameraHardwareInterface::storeMetaDataInBuffers(int enable)
537{
538 ALOGV("%s(%s)", __FUNCTION__, mName.string());
539 if (CC_LIKELY(mHidlDevice != nullptr)) {
540 return CameraProviderManager::mapToStatusT(
541 mHidlDevice->storeMetaDataInBuffers(enable));
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800542 }
543 return enable ? INVALID_OPERATION: OK;
544}
545
546status_t CameraHardwareInterface::startRecording()
547{
548 ALOGV("%s(%s)", __FUNCTION__, mName.string());
549 if (CC_LIKELY(mHidlDevice != nullptr)) {
550 return CameraProviderManager::mapToStatusT(
551 mHidlDevice->startRecording());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800552 }
553 return INVALID_OPERATION;
554}
555
556/**
557 * Stop a previously started recording.
558 */
559void CameraHardwareInterface::stopRecording()
560{
561 ALOGV("%s(%s)", __FUNCTION__, mName.string());
562 if (CC_LIKELY(mHidlDevice != nullptr)) {
563 mHidlDevice->stopRecording();
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800564 }
565}
566
567/**
568 * Returns true if recording is enabled.
569 */
570int CameraHardwareInterface::recordingEnabled()
571{
572 ALOGV("%s(%s)", __FUNCTION__, mName.string());
573 if (CC_LIKELY(mHidlDevice != nullptr)) {
574 return mHidlDevice->recordingEnabled();
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800575 }
576 return false;
577}
578
579void CameraHardwareInterface::releaseRecordingFrame(const sp<IMemory>& mem)
580{
581 ALOGV("%s(%s)", __FUNCTION__, mName.string());
582 ssize_t offset;
583 size_t size;
584 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
585 int heapId = heap->getHeapID();
586 int bufferIndex = offset / size;
587 if (CC_LIKELY(mHidlDevice != nullptr)) {
588 if (size == sizeof(VideoNativeHandleMetadata)) {
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700589 // TODO: Using unsecurePointer() has some associated security pitfalls
590 // (see declaration for details).
591 // Either document why it is safe in this case or address the
592 // issue (e.g. by copying).
593 VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) mem->unsecurePointer();
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800594 // Caching the handle here because md->pHandle will be subject to HAL's edit
595 native_handle_t* nh = md->pHandle;
596 hidl_handle frame = nh;
597 mHidlDevice->releaseRecordingFrameHandle(heapId, bufferIndex, frame);
598 native_handle_close(nh);
599 native_handle_delete(nh);
600 } else {
601 mHidlDevice->releaseRecordingFrame(heapId, bufferIndex);
602 }
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800603 }
604}
605
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700606void CameraHardwareInterface::releaseRecordingFrameBatch(const std::vector<sp<IMemory>>& frames)
607{
608 ALOGV("%s(%s)", __FUNCTION__, mName.string());
609 size_t n = frames.size();
610 std::vector<VideoFrameMessage> msgs;
611 msgs.reserve(n);
612 for (auto& mem : frames) {
613 if (CC_LIKELY(mHidlDevice != nullptr)) {
614 ssize_t offset;
615 size_t size;
616 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
617 if (size == sizeof(VideoNativeHandleMetadata)) {
618 uint32_t heapId = heap->getHeapID();
619 uint32_t bufferIndex = offset / size;
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700620 // TODO: Using unsecurePointer() has some associated security pitfalls
621 // (see declaration for details).
622 // Either document why it is safe in this case or address the
623 // issue (e.g. by copying).
624 VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) mem->unsecurePointer();
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700625 // Caching the handle here because md->pHandle will be subject to HAL's edit
626 native_handle_t* nh = md->pHandle;
627 VideoFrameMessage msg;
628 msgs.push_back({nh, heapId, bufferIndex});
629 } else {
630 ALOGE("%s only supports VideoNativeHandleMetadata mode", __FUNCTION__);
631 return;
632 }
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700633 }
634 }
635
636 mHidlDevice->releaseRecordingFrameHandleBatch(msgs);
637
638 for (auto& msg : msgs) {
639 native_handle_t* nh = const_cast<native_handle_t*>(msg.frameData.getNativeHandle());
640 native_handle_close(nh);
641 native_handle_delete(nh);
642 }
643}
644
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800645status_t CameraHardwareInterface::autoFocus()
646{
647 ALOGV("%s(%s)", __FUNCTION__, mName.string());
648 if (CC_LIKELY(mHidlDevice != nullptr)) {
649 return CameraProviderManager::mapToStatusT(
650 mHidlDevice->autoFocus());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800651 }
652 return INVALID_OPERATION;
653}
654
655status_t CameraHardwareInterface::cancelAutoFocus()
656{
657 ALOGV("%s(%s)", __FUNCTION__, mName.string());
658 if (CC_LIKELY(mHidlDevice != nullptr)) {
659 return CameraProviderManager::mapToStatusT(
660 mHidlDevice->cancelAutoFocus());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800661 }
662 return INVALID_OPERATION;
663}
664
665status_t CameraHardwareInterface::takePicture()
666{
667 ALOGV("%s(%s)", __FUNCTION__, mName.string());
668 if (CC_LIKELY(mHidlDevice != nullptr)) {
669 return CameraProviderManager::mapToStatusT(
670 mHidlDevice->takePicture());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800671 }
672 return INVALID_OPERATION;
673}
674
675status_t CameraHardwareInterface::cancelPicture()
676{
677 ALOGV("%s(%s)", __FUNCTION__, mName.string());
678 if (CC_LIKELY(mHidlDevice != nullptr)) {
679 return CameraProviderManager::mapToStatusT(
680 mHidlDevice->cancelPicture());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800681 }
682 return INVALID_OPERATION;
683}
684
685status_t CameraHardwareInterface::setParameters(const CameraParameters &params)
686{
687 ALOGV("%s(%s)", __FUNCTION__, mName.string());
688 if (CC_LIKELY(mHidlDevice != nullptr)) {
689 return CameraProviderManager::mapToStatusT(
690 mHidlDevice->setParameters(params.flatten().string()));
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800691 }
692 return INVALID_OPERATION;
693}
694
695CameraParameters CameraHardwareInterface::getParameters() const
696{
697 ALOGV("%s(%s)", __FUNCTION__, mName.string());
698 CameraParameters parms;
699 if (CC_LIKELY(mHidlDevice != nullptr)) {
700 hardware::hidl_string outParam;
701 mHidlDevice->getParameters(
702 [&outParam](const auto& outStr) {
703 outParam = outStr;
704 });
705 String8 tmp(outParam.c_str());
706 parms.unflatten(tmp);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800707 }
708 return parms;
709}
710
711status_t CameraHardwareInterface::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
712{
713 ALOGV("%s(%s)", __FUNCTION__, mName.string());
714 if (CC_LIKELY(mHidlDevice != nullptr)) {
715 return CameraProviderManager::mapToStatusT(
716 mHidlDevice->sendCommand((CommandType) cmd, arg1, arg2));
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800717 }
718 return INVALID_OPERATION;
719}
720
721/**
722 * Release the hardware resources owned by this object. Note that this is
723 * *not* done in the destructor.
724 */
725void CameraHardwareInterface::release() {
726 ALOGV("%s(%s)", __FUNCTION__, mName.string());
727 if (CC_LIKELY(mHidlDevice != nullptr)) {
728 mHidlDevice->close();
729 mHidlDevice.clear();
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800730 }
731}
732
733/**
734 * Dump state of the camera hardware
735 */
736status_t CameraHardwareInterface::dump(int fd, const Vector<String16>& /*args*/) const
737{
738 ALOGV("%s(%s)", __FUNCTION__, mName.string());
739 if (CC_LIKELY(mHidlDevice != nullptr)) {
740 native_handle_t* handle = native_handle_create(1,0);
741 handle->data[0] = fd;
742 Status s = mHidlDevice->dumpState(handle);
743 native_handle_delete(handle);
744 return CameraProviderManager::mapToStatusT(s);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800745 }
746 return OK; // It's fine if the HAL doesn't implement dump()
747}
748
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800749void CameraHardwareInterface::sNotifyCb(int32_t msg_type, int32_t ext1,
750 int32_t ext2, void *user)
751{
752 ALOGV("%s", __FUNCTION__);
753 CameraHardwareInterface *object =
754 static_cast<CameraHardwareInterface *>(user);
755 object->mNotifyCb(msg_type, ext1, ext2, object->mCbUser);
756}
757
758void CameraHardwareInterface::sDataCb(int32_t msg_type,
759 const camera_memory_t *data, unsigned int index,
760 camera_frame_metadata_t *metadata,
761 void *user)
762{
763 ALOGV("%s", __FUNCTION__);
764 CameraHardwareInterface *object =
765 static_cast<CameraHardwareInterface *>(user);
766 sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle));
767 if (index >= mem->mNumBufs) {
768 ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
769 index, mem->mNumBufs);
770 return;
771 }
772 object->mDataCb(msg_type, mem->mBuffers[index], metadata, object->mCbUser);
773}
774
775void CameraHardwareInterface::sDataCbTimestamp(nsecs_t timestamp, int32_t msg_type,
776 const camera_memory_t *data, unsigned index,
777 void *user)
778{
779 ALOGV("%s", __FUNCTION__);
780 CameraHardwareInterface *object =
781 static_cast<CameraHardwareInterface *>(user);
782 // Start refcounting the heap object from here on. When the clients
783 // drop all references, it will be destroyed (as well as the enclosed
784 // MemoryHeapBase.
785 sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle));
786 if (index >= mem->mNumBufs) {
787 ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
788 index, mem->mNumBufs);
789 return;
790 }
791 object->mDataCbTimestamp(timestamp, msg_type, mem->mBuffers[index], object->mCbUser);
792}
793
794camera_memory_t* CameraHardwareInterface::sGetMemory(
795 int fd, size_t buf_size, uint_t num_bufs,
796 void *user __attribute__((unused)))
797{
798 CameraHeapMemory *mem;
799 if (fd < 0) {
800 mem = new CameraHeapMemory(buf_size, num_bufs);
801 } else {
802 mem = new CameraHeapMemory(fd, buf_size, num_bufs);
803 }
804 mem->incStrong(mem);
805 return &mem->handle;
806}
807
808void CameraHardwareInterface::sPutMemory(camera_memory_t *data)
809{
810 if (!data) {
811 return;
812 }
813
814 CameraHeapMemory *mem = static_cast<CameraHeapMemory *>(data->handle);
815 mem->decStrong(mem);
816}
817
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800818}; // namespace android