diff --git a/camera/Android.bp b/camera/Android.bp index 83a2803580..0240751c5a 100644 --- a/camera/Android.bp +++ b/camera/Android.bp @@ -7,6 +7,7 @@ subdirs = [ "device/3.2", "device/3.2/default", "device/3.3", + "device/3.3/default", "metadata/3.2", "provider/2.4", "provider/2.4/default", diff --git a/camera/device/3.2/default/CameraDevice.cpp b/camera/device/3.2/default/CameraDevice.cpp index 637a1e6616..295ee32865 100644 --- a/camera/device/3.2/default/CameraDevice.cpp +++ b/camera/device/3.2/default/CameraDevice.cpp @@ -177,7 +177,7 @@ Return CameraDevice::open(const sp& callback, open_ if (callback == nullptr) { ALOGE("%s: cannot open camera %s. callback is null!", __FUNCTION__, mCameraId.c_str()); - _hidl_cb(Status::ILLEGAL_ARGUMENT, session); + _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr); return Void(); } @@ -186,7 +186,7 @@ Return CameraDevice::open(const sp& callback, open_ // this must be a disconnected camera ALOGE("%s: cannot open camera %s. camera is disconnected!", __FUNCTION__, mCameraId.c_str()); - _hidl_cb(Status::CAMERA_DISCONNECTED, session); + _hidl_cb(Status::CAMERA_DISCONNECTED, nullptr); return Void(); } else { mLock.lock(); @@ -239,7 +239,7 @@ Return CameraDevice::open(const sp& callback, open_ return Void(); } - session = new CameraDeviceSession( + session = createSession( device, info.static_camera_characteristics, callback); if (session == nullptr) { ALOGE("%s: camera device session allocation failed", __FUNCTION__); @@ -255,9 +255,19 @@ Return CameraDevice::open(const sp& callback, open_ return Void(); } mSession = session; + + IF_ALOGV() { + session->getInterface()->interfaceChain([]( + ::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) { + ALOGV("Session interface chain:"); + for (auto iface : interfaceChain) { + ALOGV(" %s", iface.c_str()); + } + }); + } mLock.unlock(); } - _hidl_cb(status, session); + _hidl_cb(status, session->getInterface()); return Void(); } @@ -286,6 +296,13 @@ Return CameraDevice::dumpState(const ::android::hardware::hidl_handle& han session->dumpState(handle); return Void(); } + +sp CameraDevice::createSession(camera3_device_t* device, + const camera_metadata_t* deviceInfo, + const sp& callback) { + return new CameraDeviceSession(device, deviceInfo, callback); +} + // End of methods from ::android::hardware::camera::device::V3_2::ICameraDevice. } // namespace implementation diff --git a/camera/device/3.2/default/CameraDeviceSession.cpp b/camera/device/3.2/default/CameraDeviceSession.cpp index fcd134f45e..d6a04bc56b 100644 --- a/camera/device/3.2/default/CameraDeviceSession.cpp +++ b/camera/device/3.2/default/CameraDeviceSession.cpp @@ -49,7 +49,6 @@ CameraDeviceSession::CameraDeviceSession( mDerivePostRawSensKey(false), mNumPartialResults(1), mResultBatcher(callback) { - mDeviceInfo = deviceInfo; camera_metadata_entry partialResultsCount = mDeviceInfo.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT); @@ -328,7 +327,8 @@ void CameraDeviceSession::ResultBatcher::setBatchedStreams( mStreamsToBatch = streamsToBatch; } -void CameraDeviceSession::ResultBatcher::setResultMetadataQueue(std::shared_ptr q) { +void CameraDeviceSession::ResultBatcher::setResultMetadataQueue( + std::shared_ptr q) { Mutex::Autolock _l(mLock); mResultMetadataQueue = q; } @@ -387,7 +387,8 @@ void CameraDeviceSession::ResultBatcher::checkAndRemoveFirstBatch() { } } -void CameraDeviceSession::ResultBatcher::sendBatchShutterCbsLocked(std::shared_ptr batch) { +void CameraDeviceSession::ResultBatcher::sendBatchShutterCbsLocked( + std::shared_ptr batch) { if (batch->mShutterDelivered) { ALOGW("%s: batch shutter callback already sent!", __FUNCTION__); return; @@ -441,7 +442,8 @@ void CameraDeviceSession::ResultBatcher::pushStreamBuffer( } } -void CameraDeviceSession::ResultBatcher::sendBatchBuffersLocked(std::shared_ptr batch) { +void CameraDeviceSession::ResultBatcher::sendBatchBuffersLocked( + std::shared_ptr batch) { sendBatchBuffersLocked(batch, mStreamsToBatch); } @@ -736,7 +738,7 @@ void CameraDeviceSession::ResultBatcher::processCaptureResult(CaptureResult& res // Methods from ::android::hardware::camera::device::V3_2::ICameraDeviceSession follow. Return CameraDeviceSession::constructDefaultRequestSettings( - RequestTemplate type, constructDefaultRequestSettings_cb _hidl_cb) { + RequestTemplate type, ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb) { Status status = initStatus(); CameraMetadata outMetadata; const camera_metadata_t *rawRequest; @@ -802,7 +804,8 @@ android_dataspace CameraDeviceSession::mapToLegacyDataspace( } Return CameraDeviceSession::configureStreams( - const StreamConfiguration& requestedConfiguration, configureStreams_cb _hidl_cb) { + const StreamConfiguration& requestedConfiguration, + ICameraDeviceSession::configureStreams_cb _hidl_cb) { Status status = initStatus(); HalStreamConfiguration outStreams; @@ -960,13 +963,13 @@ void CameraDeviceSession::updateBufferCaches(const hidl_vec& caches } Return CameraDeviceSession::getCaptureRequestMetadataQueue( - getCaptureRequestMetadataQueue_cb _hidl_cb) { + ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb) { _hidl_cb(*mRequestMetadataQueue->getDesc()); return Void(); } Return CameraDeviceSession::getCaptureResultMetadataQueue( - getCaptureResultMetadataQueue_cb _hidl_cb) { + ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb) { _hidl_cb(*mResultMetadataQueue->getDesc()); return Void(); } @@ -974,7 +977,7 @@ Return CameraDeviceSession::getCaptureResultMetadataQueue( Return CameraDeviceSession::processCaptureRequest( const hidl_vec& requests, const hidl_vec& cachesToRemove, - processCaptureRequest_cb _hidl_cb) { + ICameraDeviceSession::processCaptureRequest_cb _hidl_cb) { updateBufferCaches(cachesToRemove); uint32_t numRequestProcessed = 0; diff --git a/camera/device/3.2/default/CameraDeviceSession.h b/camera/device/3.2/default/CameraDeviceSession.h index 2fe189fde1..69e2e2c802 100644 --- a/camera/device/3.2/default/CameraDeviceSession.h +++ b/camera/device/3.2/default/CameraDeviceSession.h @@ -55,6 +55,8 @@ using ::android::hardware::hidl_string; using ::android::sp; using ::android::Mutex; +struct Camera3Stream; + /** * Function pointer types with C calling convention to * use for HAL callback functions. @@ -69,12 +71,12 @@ extern "C" { const camera3_notify_msg_t *); } -struct CameraDeviceSession : public ICameraDeviceSession, private camera3_callback_ops { +struct CameraDeviceSession : public virtual RefBase, protected camera3_callback_ops { CameraDeviceSession(camera3_device_t*, const camera_metadata_t* deviceInfo, const sp&); - ~CameraDeviceSession(); + virtual ~CameraDeviceSession(); // Call by CameraDevice to dump active device states void dumpState(const native_handle_t* fd); // Caller must use this method to check if CameraDeviceSession ctor failed @@ -83,23 +85,35 @@ struct CameraDeviceSession : public ICameraDeviceSession, private camera3_callba void disconnect(); bool isClosed(); - // Methods from ::android::hardware::camera::device::V3_2::ICameraDeviceSession follow. + // Retrieve the HIDL interface, split into its own class to avoid inheritance issues when + // dealing with minor version revs and simultaneous implementation and interface inheritance + virtual sp getInterface() { + return new TrampolineSessionInterface_3_2(this); + } + +protected: + + // Methods from ::android::hardware::camera::device::V3_2::ICameraDeviceSession follow + Return constructDefaultRequestSettings( - RequestTemplate type, constructDefaultRequestSettings_cb _hidl_cb) override; + RequestTemplate type, + ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb); Return configureStreams( - const StreamConfiguration& requestedConfiguration, configureStreams_cb _hidl_cb) override; + const StreamConfiguration& requestedConfiguration, + ICameraDeviceSession::configureStreams_cb _hidl_cb); Return getCaptureRequestMetadataQueue( - getCaptureRequestMetadataQueue_cb _hidl_cb) override; + ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb); Return getCaptureResultMetadataQueue( - getCaptureResultMetadataQueue_cb _hidl_cb) override; + ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb); Return processCaptureRequest( const hidl_vec& requests, const hidl_vec& cachesToRemove, - processCaptureRequest_cb _hidl_cb) override; - Return flush() override; - Return close() override; + ICameraDeviceSession::processCaptureRequest_cb _hidl_cb); + Return flush(); + Return close(); + +protected: -private: // protecting mClosed/mDisconnected/mInitFail mutable Mutex mStateLock; // device is closed either @@ -302,6 +316,52 @@ private: */ static callbacks_process_capture_result_t sProcessCaptureResult; static callbacks_notify_t sNotify; + +private: + + struct TrampolineSessionInterface_3_2 : public ICameraDeviceSession { + TrampolineSessionInterface_3_2(sp parent) : + mParent(parent) {} + + virtual Return constructDefaultRequestSettings( + V3_2::RequestTemplate type, + V3_2::ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb) override { + return mParent->constructDefaultRequestSettings(type, _hidl_cb); + } + + virtual Return configureStreams( + const V3_2::StreamConfiguration& requestedConfiguration, + V3_2::ICameraDeviceSession::configureStreams_cb _hidl_cb) override { + return mParent->configureStreams(requestedConfiguration, _hidl_cb); + } + + virtual Return processCaptureRequest(const hidl_vec& requests, + const hidl_vec& cachesToRemove, + V3_2::ICameraDeviceSession::processCaptureRequest_cb _hidl_cb) override { + return mParent->processCaptureRequest(requests, cachesToRemove, _hidl_cb); + } + + virtual Return getCaptureRequestMetadataQueue( + V3_2::ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb) override { + return mParent->getCaptureRequestMetadataQueue(_hidl_cb); + } + + virtual Return getCaptureResultMetadataQueue( + V3_2::ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb) override { + return mParent->getCaptureResultMetadataQueue(_hidl_cb); + } + + virtual Return flush() override { + return mParent->flush(); + } + + virtual Return close() override { + return mParent->close(); + } + + private: + sp mParent; + }; }; } // namespace implementation diff --git a/camera/device/3.2/default/CameraDevice_3_2.h b/camera/device/3.2/default/CameraDevice_3_2.h index 4e8606757c..9534707bd0 100644 --- a/camera/device/3.2/default/CameraDevice_3_2.h +++ b/camera/device/3.2/default/CameraDevice_3_2.h @@ -80,7 +80,13 @@ struct CameraDevice : public ICameraDevice { Return dumpState(const ::android::hardware::hidl_handle& fd) override; /* End of Methods from ::android::hardware::camera::device::V3_2::ICameraDevice */ -private: +protected: + + // Overridden by child implementations for returning different versions of CameraDeviceSession + virtual sp createSession(camera3_device_t*, + const camera_metadata_t* deviceInfo, + const sp&); + const sp mModule; const std::string mCameraId; // const after ctor diff --git a/camera/device/3.3/default/Android.bp b/camera/device/3.3/default/Android.bp new file mode 100644 index 0000000000..b1e9b46d8f --- /dev/null +++ b/camera/device/3.3/default/Android.bp @@ -0,0 +1,30 @@ +cc_library_shared { + name: "camera.device@3.3-impl", + defaults: ["hidl_defaults"], + proprietary: true, + srcs: ["CameraDevice.cpp", + "CameraDeviceSession.cpp", + "convert.cpp"], + shared_libs: [ + "libhidlbase", + "libhidltransport", + "libutils", + "libcutils", + "camera.device@3.2-impl", + "android.hardware.camera.device@3.2", + "android.hardware.camera.device@3.3", + "android.hardware.camera.provider@2.4", + "android.hardware.graphics.mapper@2.0", + "liblog", + "libhardware", + "libcamera_metadata", + "libfmq" + ], + static_libs: [ + "android.hardware.camera.common@1.0-helper" + ], + export_include_dirs: ["."], + export_shared_lib_headers: [ + "libfmq", + ] +} diff --git a/camera/device/3.3/default/CameraDevice.cpp b/camera/device/3.3/default/CameraDevice.cpp new file mode 100644 index 0000000000..ce5e1de239 --- /dev/null +++ b/camera/device/3.3/default/CameraDevice.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "CamDev@3.3-impl" +#include + +#include +#include +#include "CameraDevice_3_3.h" +#include + +namespace android { +namespace hardware { +namespace camera { +namespace device { +namespace V3_3 { +namespace implementation { + +using ::android::hardware::camera::common::V1_0::Status; +using namespace ::android::hardware::camera::device; + +CameraDevice::CameraDevice( + sp module, const std::string& cameraId, + const SortedVector>& cameraDeviceNames) : + V3_2::implementation::CameraDevice(module, cameraId, cameraDeviceNames) { +} + +CameraDevice::~CameraDevice() { +} + +sp CameraDevice::createSession(camera3_device_t* device, + const camera_metadata_t* deviceInfo, + const sp& callback) { + sp session = new CameraDeviceSession(device, deviceInfo, callback); + IF_ALOGV() { + session->getInterface()->interfaceChain([]( + ::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) { + ALOGV("Session interface chain:"); + for (auto iface : interfaceChain) { + ALOGV(" %s", iface.c_str()); + } + }); + } + return session; +} + +// End of methods from ::android::hardware::camera::device::V3_2::ICameraDevice. + +} // namespace implementation +} // namespace V3_3 +} // namespace device +} // namespace camera +} // namespace hardware +} // namespace android diff --git a/camera/device/3.3/default/CameraDeviceSession.cpp b/camera/device/3.3/default/CameraDeviceSession.cpp new file mode 100644 index 0000000000..f877895ebb --- /dev/null +++ b/camera/device/3.3/default/CameraDeviceSession.cpp @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "CamDevSession@3.3-impl" +#include + +#include +#include +#include +#include +#include "CameraDeviceSession.h" + +namespace android { +namespace hardware { +namespace camera { +namespace device { +namespace V3_3 { +namespace implementation { + +CameraDeviceSession::CameraDeviceSession( + camera3_device_t* device, + const camera_metadata_t* deviceInfo, + const sp& callback) : + V3_2::implementation::CameraDeviceSession(device, deviceInfo, callback) { +} + +CameraDeviceSession::~CameraDeviceSession() { +} + +Return CameraDeviceSession::configureStreams_3_3( + const StreamConfiguration& requestedConfiguration, + ICameraDeviceSession::configureStreams_3_3_cb _hidl_cb) { + Status status = initStatus(); + HalStreamConfiguration outStreams; + + // hold the inflight lock for entire configureStreams scope since there must not be any + // inflight request/results during stream configuration. + Mutex::Autolock _l(mInflightLock); + if (!mInflightBuffers.empty()) { + ALOGE("%s: trying to configureStreams while there are still %zu inflight buffers!", + __FUNCTION__, mInflightBuffers.size()); + _hidl_cb(Status::INTERNAL_ERROR, outStreams); + return Void(); + } + + if (!mInflightAETriggerOverrides.empty()) { + ALOGE("%s: trying to configureStreams while there are still %zu inflight" + " trigger overrides!", __FUNCTION__, + mInflightAETriggerOverrides.size()); + _hidl_cb(Status::INTERNAL_ERROR, outStreams); + return Void(); + } + + if (!mInflightRawBoostPresent.empty()) { + ALOGE("%s: trying to configureStreams while there are still %zu inflight" + " boost overrides!", __FUNCTION__, + mInflightRawBoostPresent.size()); + _hidl_cb(Status::INTERNAL_ERROR, outStreams); + return Void(); + } + + if (status != Status::OK) { + _hidl_cb(status, outStreams); + return Void(); + } + + camera3_stream_configuration_t stream_list; + hidl_vec streams; + + stream_list.operation_mode = (uint32_t) requestedConfiguration.operationMode; + stream_list.num_streams = requestedConfiguration.streams.size(); + streams.resize(stream_list.num_streams); + stream_list.streams = streams.data(); + + for (uint32_t i = 0; i < stream_list.num_streams; i++) { + int id = requestedConfiguration.streams[i].id; + + if (mStreamMap.count(id) == 0) { + Camera3Stream stream; + V3_2::implementation::convertFromHidl(requestedConfiguration.streams[i], &stream); + mStreamMap[id] = stream; + mStreamMap[id].data_space = mapToLegacyDataspace( + mStreamMap[id].data_space); + mCirculatingBuffers.emplace(stream.mId, CirculatingBuffers{}); + } else { + // width/height/format must not change, but usage/rotation might need to change + if (mStreamMap[id].stream_type != + (int) requestedConfiguration.streams[i].streamType || + mStreamMap[id].width != requestedConfiguration.streams[i].width || + mStreamMap[id].height != requestedConfiguration.streams[i].height || + mStreamMap[id].format != (int) requestedConfiguration.streams[i].format || + mStreamMap[id].data_space != + mapToLegacyDataspace( static_cast ( + requestedConfiguration.streams[i].dataSpace))) { + ALOGE("%s: stream %d configuration changed!", __FUNCTION__, id); + _hidl_cb(Status::INTERNAL_ERROR, outStreams); + return Void(); + } + mStreamMap[id].rotation = (int) requestedConfiguration.streams[i].rotation; + mStreamMap[id].usage = (uint32_t) requestedConfiguration.streams[i].usage; + } + streams[i] = &mStreamMap[id]; + } + + ATRACE_BEGIN("camera3->configure_streams"); + status_t ret = mDevice->ops->configure_streams(mDevice, &stream_list); + ATRACE_END(); + + // In case Hal returns error most likely it was not able to release + // the corresponding resources of the deleted streams. + if (ret == OK) { + // delete unused streams, note we do this after adding new streams to ensure new stream + // will not have the same address as deleted stream, and HAL has a chance to reference + // the to be deleted stream in configure_streams call + for(auto it = mStreamMap.begin(); it != mStreamMap.end();) { + int id = it->first; + bool found = false; + for (const auto& stream : requestedConfiguration.streams) { + if (id == stream.id) { + found = true; + break; + } + } + if (!found) { + // Unmap all buffers of deleted stream + // in case the configuration call succeeds and HAL + // is able to release the corresponding resources too. + cleanupBuffersLocked(id); + it = mStreamMap.erase(it); + } else { + ++it; + } + } + + // Track video streams + mVideoStreamIds.clear(); + for (const auto& stream : requestedConfiguration.streams) { + if (stream.streamType == V3_2::StreamType::OUTPUT && + stream.usage & + graphics::common::V1_0::BufferUsage::VIDEO_ENCODER) { + mVideoStreamIds.push_back(stream.id); + } + } + mResultBatcher.setBatchedStreams(mVideoStreamIds); + } + + if (ret == -EINVAL) { + status = Status::ILLEGAL_ARGUMENT; + } else if (ret != OK) { + status = Status::INTERNAL_ERROR; + } else { + convertToHidl(stream_list, &outStreams); + mFirstRequest = true; + } + + _hidl_cb(status, outStreams); + return Void(); +} + +} // namespace implementation +} // namespace V3_3 +} // namespace device +} // namespace camera +} // namespace hardware +} // namespace android diff --git a/camera/device/3.3/default/CameraDeviceSession.h b/camera/device/3.3/default/CameraDeviceSession.h new file mode 100644 index 0000000000..dd52b35b8e --- /dev/null +++ b/camera/device/3.3/default/CameraDeviceSession.h @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_CAMERA_DEVICE_V3_3_CAMERADEVICE3SESSION_H +#define ANDROID_HARDWARE_CAMERA_DEVICE_V3_3_CAMERADEVICE3SESSION_H + +#include +#include +#include <../../3.2/default/CameraDeviceSession.h> +#include +#include +#include +#include +#include +#include +#include +#include "CameraMetadata.h" +#include "HandleImporter.h" +#include "hardware/camera3.h" +#include "hardware/camera_common.h" +#include "utils/Mutex.h" + +namespace android { +namespace hardware { +namespace camera { +namespace device { +namespace V3_3 { +namespace implementation { + +using namespace ::android::hardware::camera::device; +using ::android::hardware::camera::device::V3_2::CaptureRequest; +using ::android::hardware::camera::device::V3_2::StreamConfiguration; +using ::android::hardware::camera::device::V3_3::HalStreamConfiguration; +using ::android::hardware::camera::device::V3_3::ICameraDeviceSession; +using ::android::hardware::camera::common::V1_0::Status; +using ::android::hardware::camera::common::V1_0::helper::HandleImporter; +using ::android::hardware::kSynchronizedReadWrite; +using ::android::hardware::MessageQueue; +using ::android::hardware::MQDescriptorSync; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::hidl_vec; +using ::android::hardware::hidl_string; +using ::android::sp; +using ::android::Mutex; + +struct CameraDeviceSession : public V3_2::implementation::CameraDeviceSession { + + CameraDeviceSession(camera3_device_t*, + const camera_metadata_t* deviceInfo, + const sp&); + virtual ~CameraDeviceSession(); + + virtual sp getInterface() override { + return new TrampolineSessionInterface_3_3(this); + } + +protected: + // Methods from v3.2 and earlier will trampoline to inherited implementation + + // New methods for v3.3 + + Return configureStreams_3_3( + const StreamConfiguration& requestedConfiguration, + ICameraDeviceSession::configureStreams_3_3_cb _hidl_cb); +private: + + struct TrampolineSessionInterface_3_3 : public ICameraDeviceSession { + TrampolineSessionInterface_3_3(sp parent) : + mParent(parent) {} + + virtual Return constructDefaultRequestSettings( + V3_2::RequestTemplate type, + V3_3::ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb) override { + return mParent->constructDefaultRequestSettings(type, _hidl_cb); + } + + virtual Return configureStreams( + const V3_2::StreamConfiguration& requestedConfiguration, + V3_3::ICameraDeviceSession::configureStreams_cb _hidl_cb) override { + return mParent->configureStreams(requestedConfiguration, _hidl_cb); + } + + virtual Return processCaptureRequest(const hidl_vec& requests, + const hidl_vec& cachesToRemove, + V3_3::ICameraDeviceSession::processCaptureRequest_cb _hidl_cb) override { + return mParent->processCaptureRequest(requests, cachesToRemove, _hidl_cb); + } + + virtual Return getCaptureRequestMetadataQueue( + V3_3::ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb) override { + return mParent->getCaptureRequestMetadataQueue(_hidl_cb); + } + + virtual Return getCaptureResultMetadataQueue( + V3_3::ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb) override { + return mParent->getCaptureResultMetadataQueue(_hidl_cb); + } + + virtual Return flush() override { + return mParent->flush(); + } + + virtual Return close() override { + return mParent->close(); + } + + virtual Return configureStreams_3_3( + const StreamConfiguration& requestedConfiguration, configureStreams_3_3_cb _hidl_cb) override { + return mParent->configureStreams_3_3(requestedConfiguration, _hidl_cb); + } + + private: + sp mParent; + }; +}; + +} // namespace implementation +} // namespace V3_3 +} // namespace device +} // namespace camera +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_CAMERA_DEVICE_V3_3_CAMERADEVICE3SESSION_H diff --git a/camera/device/3.3/default/CameraDevice_3_3.h b/camera/device/3.3/default/CameraDevice_3_3.h new file mode 100644 index 0000000000..18b3fe8e81 --- /dev/null +++ b/camera/device/3.3/default/CameraDevice_3_3.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_CAMERA_DEVICE_V3_3_CAMERADEVICE_H +#define ANDROID_HARDWARE_CAMERA_DEVICE_V3_3_CAMERADEVICE_H + +#include "utils/Mutex.h" +#include "CameraModule.h" +#include "CameraMetadata.h" +#include "CameraDeviceSession.h" +#include <../../3.2/default/CameraDevice_3_2.h> + +#include +#include +#include + +namespace android { +namespace hardware { +namespace camera { +namespace device { +namespace V3_3 { +namespace implementation { + +using namespace ::android::hardware::camera::device; +using ::android::hardware::camera::common::V1_0::helper::CameraModule; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::hidl_vec; +using ::android::hardware::hidl_string; +using ::android::sp; + +/* + * The camera device HAL implementation is opened lazily (via the open call) + */ +struct CameraDevice : public V3_2::implementation::CameraDevice { + + // Called by provider HAL. + // Provider HAL must ensure the uniqueness of CameraDevice object per cameraId, or there could + // be multiple CameraDevice trying to access the same physical camera. Also, provider will have + // to keep track of all CameraDevice objects in order to notify CameraDevice when the underlying + // camera is detached. + // Delegates nearly all work to CameraDevice_3_2 + CameraDevice(sp module, + const std::string& cameraId, + const SortedVector>& cameraDeviceNames); + ~CameraDevice(); + +protected: + virtual sp createSession(camera3_device_t*, + const camera_metadata_t* deviceInfo, + const sp&) override; + +}; + +} // namespace implementation +} // namespace V3_3 +} // namespace device +} // namespace camera +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_CAMERA_DEVICE_V3_3_CAMERADEVICE_H diff --git a/camera/device/3.3/default/OWNERS b/camera/device/3.3/default/OWNERS new file mode 100644 index 0000000000..18acfee145 --- /dev/null +++ b/camera/device/3.3/default/OWNERS @@ -0,0 +1,6 @@ +cychen@google.com +epeev@google.com +etalvala@google.com +shuzhenwang@google.com +yinchiayeh@google.com +zhijunhe@google.com diff --git a/camera/device/3.3/default/convert.cpp b/camera/device/3.3/default/convert.cpp new file mode 100644 index 0000000000..dae190b03c --- /dev/null +++ b/camera/device/3.3/default/convert.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "android.hardware.camera.device@3.3-convert-impl" +#include + +#include "include/convert.h" + +namespace android { +namespace hardware { +namespace camera { +namespace device { +namespace V3_3 { +namespace implementation { + +using ::android::hardware::graphics::common::V1_0::Dataspace; +using ::android::hardware::graphics::common::V1_0::PixelFormat; +using ::android::hardware::camera::device::V3_2::BufferUsageFlags; + +void convertToHidl(const Camera3Stream* src, HalStream* dst) { + dst->overrideDataSpace = src->data_space; + dst->v3_2.id = src->mId; + dst->v3_2.overrideFormat = (PixelFormat) src->format; + dst->v3_2.maxBuffers = src->max_buffers; + if (src->stream_type == CAMERA3_STREAM_OUTPUT) { + dst->v3_2.consumerUsage = (BufferUsageFlags)0; + dst->v3_2.producerUsage = (BufferUsageFlags)src->usage; + } else if (src->stream_type == CAMERA3_STREAM_INPUT) { + dst->v3_2.producerUsage = (BufferUsageFlags)0; + dst->v3_2.consumerUsage = (BufferUsageFlags)src->usage; + } else { + //Should not reach here per current HIDL spec, but we might end up adding + // bi-directional stream to HIDL. + ALOGW("%s: Stream type %d is not currently supported!", + __FUNCTION__, src->stream_type); + } +} + +void convertToHidl(const camera3_stream_configuration_t& src, HalStreamConfiguration* dst) { + dst->streams.resize(src.num_streams); + for (uint32_t i = 0; i < src.num_streams; i++) { + convertToHidl(static_cast(src.streams[i]), &dst->streams[i]); + } + return; +} + +} // namespace implementation +} // namespace V3_3 +} // namespace device +} // namespace camera +} // namespace hardware +} // namespace android diff --git a/camera/device/3.3/default/include/convert.h b/camera/device/3.3/default/include/convert.h new file mode 100644 index 0000000000..23bb79796c --- /dev/null +++ b/camera/device/3.3/default/include/convert.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HARDWARE_INTERFACES_CAMERA_DEVICE_V3_3_DEFAULT_INCLUDE_CONVERT_H_ + +#define HARDWARE_INTERFACES_CAMERA_DEVICE_V3_3_DEFAULT_INCLUDE_CONVERT_H_ + +#include + + +#include +#include +#include "hardware/camera3.h" +#include "../../3.2/default/include/convert.h" + +namespace android { +namespace hardware { +namespace camera { +namespace device { +namespace V3_3 { +namespace implementation { + +using ::android::hardware::camera::device::V3_2::implementation::Camera3Stream; + +void convertToHidl(const Camera3Stream* src, HalStream* dst); + +void convertToHidl(const camera3_stream_configuration_t& src, HalStreamConfiguration* dst); + +} // namespace implementation +} // namespace V3_3 +} // namespace device +} // namespace camera +} // namespace hardware +} // namespace android + +#endif // HARDWARE_INTERFACES_CAMERA_DEVICE_V3_3_DEFAULT_INCLUDE_CONVERT_H_ diff --git a/camera/provider/2.4/default/Android.bp b/camera/provider/2.4/default/Android.bp index f2a2d2e71e..c0b35912f7 100644 --- a/camera/provider/2.4/default/Android.bp +++ b/camera/provider/2.4/default/Android.bp @@ -11,8 +11,10 @@ cc_library_shared { "libcutils", "android.hardware.camera.device@1.0", "android.hardware.camera.device@3.2", + "android.hardware.camera.device@3.3", "camera.device@1.0-impl", "camera.device@3.2-impl", + "camera.device@3.3-impl", "android.hardware.camera.provider@2.4", "android.hardware.camera.common@1.0", "android.hardware.graphics.mapper@2.0", @@ -43,6 +45,7 @@ cc_binary { "libutils", "android.hardware.camera.device@1.0", "android.hardware.camera.device@3.2", + "android.hardware.camera.device@3.3", "android.hardware.camera.provider@2.4", "android.hardware.camera.common@1.0", ], diff --git a/camera/provider/2.4/default/CameraProvider.cpp b/camera/provider/2.4/default/CameraProvider.cpp index 19f7bdd7b2..d50168a20b 100644 --- a/camera/provider/2.4/default/CameraProvider.cpp +++ b/camera/provider/2.4/default/CameraProvider.cpp @@ -15,11 +15,13 @@ */ #define LOG_TAG "CamProvider@2.4-impl" +//#define LOG_NDEBUG 0 #include #include "CameraProvider.h" #include "CameraDevice_1_0.h" -#include "CameraDevice_3_2.h" +#include "CameraDevice_3_3.h" +#include #include #include @@ -36,6 +38,7 @@ const char *kLegacyProviderName = "legacy/0"; // "device@/legacy/" const std::regex kDeviceNameRE("device@([0-9]+\\.[0-9]+)/legacy/(.+)"); const char *kHAL3_2 = "3.2"; +const char *kHAL3_3 = "3.3"; const char *kHAL1_0 = "1.0"; const int kMaxCameraDeviceNameLen = 128; const int kMaxCameraIdLen = 16; @@ -140,8 +143,9 @@ int CameraProvider::getCameraDeviceVersion(const hidl_string& deviceName) { if (!match) { return -1; } - if (deviceVersion == kHAL3_2) { - // maybe switched to 3.4 or define the hidl version enum later + if (deviceVersion == kHAL3_3) { + return CAMERA_DEVICE_API_VERSION_3_3; + } else if (deviceVersion == kHAL3_2) { return CAMERA_DEVICE_API_VERSION_3_2; } else if (deviceVersion == kHAL1_0) { return CAMERA_DEVICE_API_VERSION_1_0; @@ -158,10 +162,12 @@ std::string CameraProvider::getHidlDeviceName( deviceVersion != CAMERA_DEVICE_API_VERSION_3_4 ) { return hidl_string(""); } - const char* versionStr = (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) ? kHAL1_0 : kHAL3_2; + bool isV1 = deviceVersion == CAMERA_DEVICE_API_VERSION_1_0; + int versionMajor = isV1 ? 1 : 3; + int versionMinor = isV1 ? 0 : mPreferredHal3MinorVersion; char deviceName[kMaxCameraDeviceNameLen]; - snprintf(deviceName, sizeof(deviceName), "device@%s/legacy/%s", - versionStr, cameraId.c_str()); + snprintf(deviceName, sizeof(deviceName), "device@%d.%d/legacy/%s", + versionMajor, versionMinor, cameraId.c_str()); return deviceName; } @@ -205,6 +211,19 @@ bool CameraProvider::initialize() { return true; } + mPreferredHal3MinorVersion = property_get_int32("ro.camera.wrapper.hal3TrebleMinorVersion", 3); + ALOGV("Preferred HAL 3 minor version is %d", mPreferredHal3MinorVersion); + switch(mPreferredHal3MinorVersion) { + case 2: + case 3: + // OK + break; + default: + ALOGW("Unknown minor camera device HAL version %d in property " + "'camera.wrapper.hal3TrebleMinorVersion', defaulting to 3", mPreferredHal3MinorVersion); + mPreferredHal3MinorVersion = 3; + } + mNumberOfLegacyCameras = mModule->getNumberOfCameras(); for (int i = 0; i < mNumberOfLegacyCameras; i++) { struct camera_info info; @@ -461,23 +480,45 @@ Return CameraProvider::getCameraDeviceInterface_V3_x( return Void(); } - sp device = - new android::hardware::camera::device::V3_2::implementation::CameraDevice( + // Since some Treble HAL revisions can map to the same legacy HAL version(s), we default + // to the newest possible Treble HAL revision, but allow for override if needed via + // system property. + sp device; + switch (mPreferredHal3MinorVersion) { + case 2: { // Map legacy camera device v3 HAL to Treble camera device HAL v3.2 + ALOGV("Constructing v3.2 camera device"); + sp deviceImpl = + new android::hardware::camera::device::V3_2::implementation::CameraDevice( mModule, cameraId, mCameraDeviceNames); - - if (device == nullptr) { - ALOGE("%s: cannot allocate camera device for id %s", __FUNCTION__, cameraId.c_str()); - _hidl_cb(Status::INTERNAL_ERROR, nullptr); - return Void(); + if (deviceImpl == nullptr || deviceImpl->isInitFailed()) { + ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str()); + device = nullptr; + _hidl_cb(Status::INTERNAL_ERROR, nullptr); + return Void(); + } + device = deviceImpl; + break; + } + case 3: { // Map legacy camera device v3 HAL to Treble camera device HAL v3.3 + ALOGV("Constructing v3.3 camera device"); + sp deviceImpl = + new android::hardware::camera::device::V3_3::implementation::CameraDevice( + mModule, cameraId, mCameraDeviceNames); + if (deviceImpl == nullptr || deviceImpl->isInitFailed()) { + ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str()); + device = nullptr; + _hidl_cb(Status::INTERNAL_ERROR, nullptr); + return Void(); + } + device = deviceImpl; + break; + } + default: + ALOGE("%s: Unknown HAL minor version %d!", __FUNCTION__, mPreferredHal3MinorVersion); + device = nullptr; + _hidl_cb(Status::INTERNAL_ERROR, nullptr); + return Void(); } - - if (device->isInitFailed()) { - ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str()); - device = nullptr; - _hidl_cb(Status::INTERNAL_ERROR, nullptr); - return Void(); - } - _hidl_cb (Status::OK, device); return Void(); } diff --git a/camera/provider/2.4/default/CameraProvider.h b/camera/provider/2.4/default/CameraProvider.h index 75971fa3a0..4980711bcf 100644 --- a/camera/provider/2.4/default/CameraProvider.h +++ b/camera/provider/2.4/default/CameraProvider.h @@ -82,6 +82,8 @@ private: // (cameraId string, hidl device name) pairs SortedVector> mCameraDeviceNames; + int mPreferredHal3MinorVersion; + // Must be queried before using any APIs. // APIs will only work when this returns true bool mInitFailed; @@ -91,13 +93,13 @@ private: bool setUpVendorTags(); int checkCameraVersion(int id, camera_info info); + // create HIDL device name from camera ID and legacy device version + std::string getHidlDeviceName(std::string cameraId, int deviceVersion); + // extract legacy camera ID/device version from a HIDL device name static std::string getLegacyCameraId(const hidl_string& deviceName); static int getCameraDeviceVersion(const hidl_string& deviceName); - // create HIDL device name from camera ID and device version - static std::string getHidlDeviceName(std::string cameraId, int deviceVersion); - // convert conventional HAL status to HIDL Status static Status getHidlStatus(int);