From be543d41191ab6354b32b446565c4f1b4c6f75f2 Mon Sep 17 00:00:00 2001 From: Jayant Chowdhary Date: Wed, 15 Aug 2018 13:16:14 -0700 Subject: [PATCH] cameraserver: Implement HIDL ICameraService skeleton. Implement basic ICameraService HIDL functions, along with HIDL<=> AIDL type conversions. Bug: 110364143 Test: (build) mm -j64 Test: lshal->android.frameworks.cameraservice.service@2.0 shows up Test: Sanity-> click pictures using GCA. Change-Id: I44c2a96b1ccc05941d075e2bdeb94a8378d53c67 Signed-off-by: Jayant Chowdhary --- camera/VendorTagDescriptor.cpp | 4 + camera/camera2/OutputConfiguration.cpp | 6 + camera/cameraserver/Android.bp | 46 ++++ camera/cameraserver/Android.mk | 42 ---- camera/cameraserver/main_cameraserver.cpp | 5 +- ...d.frameworks.cameraservice.service@2.0.xml | 11 + camera/include/camera/VendorTagDescriptor.h | 5 + .../camera/camera2/OutputConfiguration.h | 5 + services/camera/libcameraservice/Android.bp | 7 + .../camera/libcameraservice/CameraService.cpp | 8 + .../camera/libcameraservice/hidl/Convert.cpp | 227 ++++++++++++++++++ .../camera/libcameraservice/hidl/Convert.h | 90 +++++++ .../hidl/HidlCameraService.cpp | 148 ++++++++++++ .../libcameraservice/hidl/HidlCameraService.h | 86 +++++++ 14 files changed, 646 insertions(+), 44 deletions(-) create mode 100644 camera/cameraserver/Android.bp delete mode 100644 camera/cameraserver/Android.mk create mode 100644 camera/cameraserver/manifest_android.frameworks.cameraservice.service@2.0.xml create mode 100644 services/camera/libcameraservice/hidl/Convert.cpp create mode 100644 services/camera/libcameraservice/hidl/Convert.h create mode 100644 services/camera/libcameraservice/hidl/HidlCameraService.cpp create mode 100644 services/camera/libcameraservice/hidl/HidlCameraService.h diff --git a/camera/VendorTagDescriptor.cpp b/camera/VendorTagDescriptor.cpp index a86cc87da9..38ff37f51a 100644 --- a/camera/VendorTagDescriptor.cpp +++ b/camera/VendorTagDescriptor.cpp @@ -315,6 +315,10 @@ status_t VendorTagDescriptor::lookupTag(const String8& name, const String8& sect return OK; } +ssize_t VendorTagDescriptor::getSectionIndex(uint32_t tag) const { + return mTagToSectionMap.valueFor(tag); +} + void VendorTagDescriptor::dump(int fd, int verbosity, int indentation) const { size_t size = mTagToNameMap.size(); diff --git a/camera/camera2/OutputConfiguration.cpp b/camera/camera2/OutputConfiguration.cpp index feb04c24ed..321eb08bea 100644 --- a/camera/camera2/OutputConfiguration.cpp +++ b/camera/camera2/OutputConfiguration.cpp @@ -175,6 +175,12 @@ OutputConfiguration::OutputConfiguration(sp& gbp, int ro mIsShared = isShared; } +OutputConfiguration::OutputConfiguration( + const std::vector>& gbps, + int rotation, int surfaceSetID, int surfaceType, int width, int height, bool isShared) + : mGbps(gbps), mRotation(rotation), mSurfaceSetID(surfaceSetID), mSurfaceType(surfaceType), + mWidth(width), mHeight(height), mIsDeferred(false), mIsShared(isShared) { } + status_t OutputConfiguration::writeToParcel(android::Parcel* parcel) const { if (parcel == nullptr) return BAD_VALUE; diff --git a/camera/cameraserver/Android.bp b/camera/cameraserver/Android.bp new file mode 100644 index 0000000000..ef6930ca0c --- /dev/null +++ b/camera/cameraserver/Android.bp @@ -0,0 +1,46 @@ +// Copyright 2018 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. + +cc_binary { + name: "cameraserver", + + srcs: ["main_cameraserver.cpp"], + + shared_libs: [ + "libcameraservice", + "liblog", + "libutils", + "libui", + "libgui", + "libbinder", + "libhidltransport", + "android.hardware.camera.common@1.0", + "android.hardware.camera.provider@2.4", + "android.hardware.camera.device@1.0", + "android.hardware.camera.device@3.2", + ], + compile_multilib: "32", + cflags: [ + "-Wall", + "-Wextra", + "-Werror", + "-Wno-unused-parameter", + ], + + init_rc: ["cameraserver.rc"], + + vintf_fragments: [ + "manifest_android.frameworks.cameraservice.service@2.0.xml", + ], +} diff --git a/camera/cameraserver/Android.mk b/camera/cameraserver/Android.mk deleted file mode 100644 index b8c94e64e3..0000000000 --- a/camera/cameraserver/Android.mk +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright 2015 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. - -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - main_cameraserver.cpp - -LOCAL_SHARED_LIBRARIES := \ - libcameraservice \ - liblog \ - libutils \ - libui \ - libgui \ - libbinder \ - libhidltransport \ - android.hardware.camera.common@1.0 \ - android.hardware.camera.provider@2.4 \ - android.hardware.camera.device@1.0 \ - android.hardware.camera.device@3.2 - -LOCAL_MODULE:= cameraserver -LOCAL_32_BIT_ONLY := true - -LOCAL_CFLAGS += -Wall -Wextra -Werror -Wno-unused-parameter - -LOCAL_INIT_RC := cameraserver.rc - -include $(BUILD_EXECUTABLE) diff --git a/camera/cameraserver/main_cameraserver.cpp b/camera/cameraserver/main_cameraserver.cpp index 3972436a76..53b3d84894 100644 --- a/camera/cameraserver/main_cameraserver.cpp +++ b/camera/cameraserver/main_cameraserver.cpp @@ -26,8 +26,9 @@ int main(int argc __unused, char** argv __unused) { signal(SIGPIPE, SIG_IGN); - // Set 3 threads for HIDL calls - hardware::configureRpcThreadpool(3, /*willjoin*/ false); + // Set 5 threads for HIDL calls. Now cameraserver will serve HIDL calls in + // addition to consuming them from the Camera HAL as well. + hardware::configureRpcThreadpool(5, /*willjoin*/ false); sp proc(ProcessState::self()); sp sm = defaultServiceManager(); diff --git a/camera/cameraserver/manifest_android.frameworks.cameraservice.service@2.0.xml b/camera/cameraserver/manifest_android.frameworks.cameraservice.service@2.0.xml new file mode 100644 index 0000000000..601c7171b0 --- /dev/null +++ b/camera/cameraserver/manifest_android.frameworks.cameraservice.service@2.0.xml @@ -0,0 +1,11 @@ + + + android.frameworks.cameraservice.service + hwbinder + 2.0 + + ICameraService + default + + + diff --git a/camera/include/camera/VendorTagDescriptor.h b/camera/include/camera/VendorTagDescriptor.h index 904fba2919..c718c93aba 100644 --- a/camera/include/camera/VendorTagDescriptor.h +++ b/camera/include/camera/VendorTagDescriptor.h @@ -98,6 +98,11 @@ class VendorTagDescriptor : public Parcelable { */ void dump(int fd, int verbosity, int indentation) const; + /** + * Get Section for corresponding tag. + */ + ssize_t getSectionIndex(uint32_t tag) const; + /** * Read values VendorTagDescriptor object from the given parcel. * diff --git a/camera/include/camera/camera2/OutputConfiguration.h b/camera/include/camera/camera2/OutputConfiguration.h index a80f44b1f4..5b117fb14e 100644 --- a/camera/include/camera/camera2/OutputConfiguration.h +++ b/camera/include/camera/camera2/OutputConfiguration.h @@ -67,6 +67,11 @@ public: OutputConfiguration(sp& gbp, int rotation, int surfaceSetID = INVALID_SET_ID, bool isShared = false); + OutputConfiguration(const std::vector>& gbps, + int rotation, int surfaceSetID = INVALID_SET_ID, + int surfaceType = OutputConfiguration::SURFACE_TYPE_UNKNOWN, int width = 0, + int height = 0, bool isShared = false); + bool operator == (const OutputConfiguration& other) const { return ( mRotation == other.mRotation && mSurfaceSetID == other.mSurfaceSetID && diff --git a/services/camera/libcameraservice/Android.bp b/services/camera/libcameraservice/Android.bp index a1163ed646..b92c7d10c4 100644 --- a/services/camera/libcameraservice/Android.bp +++ b/services/camera/libcameraservice/Android.bp @@ -53,6 +53,8 @@ cc_library_shared { "device3/DistortionMapper.cpp", "gui/RingBufferConsumer.cpp", "utils/CameraThreadState.cpp", + "hidl/HidlCameraService.cpp", + "hidl/Convert.cpp", "utils/CameraTraces.cpp", "utils/AutoConditionLock.cpp", "utils/TagMonitor.cpp", @@ -67,6 +69,7 @@ cc_library_shared { "libbinder", "libcutils", "libmedia", + "libmediandk", "libmediautils", "libcamera_client", "libcamera_metadata", @@ -78,6 +81,9 @@ cc_library_shared { "libhidltransport", "libjpeg", "libmemunreachable", + "android.frameworks.cameraservice.common@2.0", + "android.frameworks.cameraservice.service@2.0", + "android.frameworks.cameraservice.device@2.0", "android.hardware.camera.common@1.0", "android.hardware.camera.provider@2.4", "android.hardware.camera.device@1.0", @@ -96,6 +102,7 @@ cc_library_shared { include_dirs: [ "system/media/private/camera/include", "frameworks/native/include/media/openmax", + "frameworks/av/media/ndk", ], export_include_dirs: ["."], diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index e69ce1f8b7..c7b4f5b09f 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -47,6 +47,8 @@ #include #include #include +#include "hidl/HidlCameraService.h" +#include #include #include #include @@ -78,6 +80,7 @@ namespace { namespace android { using binder::Status; +using frameworks::cameraservice::service::V2_0::implementation::HidlCameraService; using hardware::ICamera; using hardware::ICameraClient; using hardware::ICameraServiceProxy; @@ -142,6 +145,11 @@ void CameraService::onFirstRef() mUidPolicy = new UidPolicy(this); mUidPolicy->registerSelf(); + sp hcs = HidlCameraService::getInstance(this); + if (hcs->registerAsService() != android::OK) { + ALOGE("%s: Failed to register default android.frameworks.cameraservice.service@1.0", + __FUNCTION__); + } } status_t CameraService::enumerateProviders() { diff --git a/services/camera/libcameraservice/hidl/Convert.cpp b/services/camera/libcameraservice/hidl/Convert.cpp new file mode 100644 index 0000000000..53097c31be --- /dev/null +++ b/services/camera/libcameraservice/hidl/Convert.cpp @@ -0,0 +1,227 @@ +/* + * Copyright (C) 2018 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. + */ + +#include +#include +#include + +namespace android { +namespace hardware { +namespace cameraservice { +namespace utils { +namespace conversion { + +using hardware::graphics::bufferqueue::V1_0::utils::H2BGraphicBufferProducer; + +// Note: existing data in dst will be gone. Caller still owns the memory of src +void convertToHidl(const camera_metadata_t *src, HCameraMetadata* dst) { + if (src == nullptr) { + ALOGW("%s:attempt to convert empty metadata to Hidl", __FUNCTION__); + return; + } + size_t size = get_camera_metadata_size(src); + dst->setToExternal((uint8_t *) src, size); + return; +} + +int32_t convertFromHidl(HStreamConfigurationMode streamConfigurationMode) { + switch (streamConfigurationMode) { + case HStreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE: + return camera2::ICameraDeviceUser::CONSTRAINED_HIGH_SPEED_MODE; + case HStreamConfigurationMode::NORMAL_MODE: + return camera2::ICameraDeviceUser::NORMAL_MODE; + default: + // TODO: Fix this + return camera2::ICameraDeviceUser::VENDOR_MODE_START; + } +} + +int32_t convertFromHidl(HTemplateId templateId) { + switch(templateId) { + case HTemplateId::PREVIEW: + return camera2::ICameraDeviceUser::TEMPLATE_PREVIEW; + case HTemplateId::STILL_CAPTURE: + return camera2::ICameraDeviceUser::TEMPLATE_STILL_CAPTURE; + case HTemplateId::RECORD: + return camera2::ICameraDeviceUser::TEMPLATE_RECORD; + case HTemplateId::VIDEO_SNAPSHOT: + return camera2::ICameraDeviceUser::TEMPLATE_VIDEO_SNAPSHOT; + case HTemplateId::ZERO_SHUTTER_LAG: + return camera2::ICameraDeviceUser::TEMPLATE_ZERO_SHUTTER_LAG; + case HTemplateId::MANUAL: + return camera2::ICameraDeviceUser::TEMPLATE_MANUAL; + } +} + +int convertFromHidl(HOutputConfiguration::Rotation rotation) { + switch(rotation) { + case HOutputConfiguration::Rotation::R0: + return 0; + case HOutputConfiguration::Rotation::R90: + return 1; + case HOutputConfiguration::Rotation::R180: + return 2; + case HOutputConfiguration::Rotation::R270: + return 3; + } +} + +hardware::camera2::params::OutputConfiguration convertFromHidl( + const HOutputConfiguration &hOutputConfiguration) { + std::vector> iGBPs; + auto &windowHandles = hOutputConfiguration.windowHandles; + iGBPs.reserve(windowHandles.size()); + for (auto &handle : windowHandles) { + iGBPs.push_back(new H2BGraphicBufferProducer(AImageReader_getHGBPFromHandle(handle))); + } + hardware::camera2::params::OutputConfiguration outputConfiguration( + iGBPs, convertFromHidl(hOutputConfiguration.rotation), + hOutputConfiguration.windowGroupId, OutputConfiguration::SURFACE_TYPE_UNKNOWN, 0, 0, + (windowHandles.size() > 1)); + return outputConfiguration; +} + +// The camera metadata here is cloned. Since we're reading metadata over +// hwbinder we would need to clone it in order to avoid aligment issues. +bool convertFromHidl(const HCameraMetadata &src, CameraMetadata *dst) { + const camera_metadata_t *buffer = reinterpret_cast(src.data()); + size_t expectedSize = src.size(); + int res = validate_camera_metadata_structure(buffer, &expectedSize); + if (res == OK || res == CAMERA_METADATA_VALIDATION_SHIFTED) { + *dst = buffer; + } else { + ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__); + return false; + } + return true; +} + +HCameraDeviceStatus convertToHidlCameraDeviceStatus(int32_t status) { + HCameraDeviceStatus deviceStatus = HCameraDeviceStatus::STATUS_UNKNOWN; + switch(status) { + case hardware::ICameraServiceListener::STATUS_NOT_PRESENT: + deviceStatus = HCameraDeviceStatus::STATUS_NOT_PRESENT; + break; + case hardware::ICameraServiceListener::STATUS_PRESENT: + deviceStatus = HCameraDeviceStatus::STATUS_PRESENT; + break; + case hardware::ICameraServiceListener::STATUS_ENUMERATING: + deviceStatus = HCameraDeviceStatus::STATUS_ENUMERATING; + break; + case hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE: + deviceStatus = HCameraDeviceStatus::STATUS_NOT_AVAILABLE; + break; + default: + break; + } + return deviceStatus; +} + +HCaptureResultExtras convertToHidl(const CaptureResultExtras &captureResultExtras) { + HCaptureResultExtras hCaptureResultExtras; + hCaptureResultExtras.burstId = captureResultExtras.burstId; + hCaptureResultExtras.frameNumber = captureResultExtras.frameNumber; + hCaptureResultExtras.partialResultCount = captureResultExtras.partialResultCount; + hCaptureResultExtras.errorStreamId = captureResultExtras.errorStreamId; + return hCaptureResultExtras; +} + +HErrorCode convertToHidl(int32_t errorCode) { + switch(errorCode) { + case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED: + return HErrorCode::CAMERA_DISCONNECTED; + case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE : + return HErrorCode::CAMERA_DEVICE; + case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE: + return HErrorCode::CAMERA_SERVICE; + case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST: + return HErrorCode::CAMERA_REQUEST; + case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT: + return HErrorCode::CAMERA_RESULT; + case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER: + return HErrorCode::CAMERA_BUFFER; + case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISABLED: + return HErrorCode::CAMERA_DISABLED; + case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_INVALID_ERROR: + return HErrorCode::CAMERA_INVALID_ERROR; + default: + return HErrorCode::CAMERA_UNKNOWN_ERROR; + } +} + +void convertToHidl(const std::vector &src, + hidl_vec* dst) { + dst->resize(src.size()); + size_t i = 0; + for (auto &statusAndId : src) { + auto &a = (*dst)[i++]; + a.cameraId = statusAndId.cameraId.c_str(); + a.deviceStatus = convertToHidlCameraDeviceStatus(statusAndId.status); + } + return; +} + +void convertToHidl( + const hardware::camera2::utils::SubmitInfo &submitInfo, + frameworks::cameraservice::device::V2_0::SubmitInfo *hSubmitInfo) { + hSubmitInfo->requestId = submitInfo.mRequestId; + hSubmitInfo->lastFrameNumber = submitInfo.mLastFrameNumber; +} + +HStatus B2HStatus(const binder::Status &bStatus) { + HStatus status = HStatus::NO_ERROR; + if (bStatus.isOk()) { + // NO Error here + return status; + } + switch(bStatus.serviceSpecificErrorCode()) { + case hardware::ICameraService::ERROR_DISCONNECTED: + status = HStatus::DISCONNECTED; + break; + case hardware::ICameraService::ERROR_CAMERA_IN_USE: + status = HStatus::CAMERA_IN_USE; + break; + case hardware::ICameraService::ERROR_MAX_CAMERAS_IN_USE: + status = HStatus::MAX_CAMERAS_IN_USE; + break; + case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT: + status = HStatus::ILLEGAL_ARGUMENT; + break; + case hardware::ICameraService::ERROR_DEPRECATED_HAL: + // Should not reach here since we filtered legacy HALs earlier + status = HStatus::DEPRECATED_HAL; + break; + case hardware::ICameraService::ERROR_DISABLED: + status = HStatus::DISABLED; + break; + case hardware::ICameraService::ERROR_PERMISSION_DENIED: + status = HStatus::PERMISSION_DENIED; + break; + case hardware::ICameraService::ERROR_INVALID_OPERATION: + status = HStatus::INVALID_OPERATION; + break; + default: + status = HStatus::UNKNOWN_ERROR; + break; + } + return status; +} + +} //conversion +} // utils +} //cameraservice +} // hardware +} // android diff --git a/services/camera/libcameraservice/hidl/Convert.h b/services/camera/libcameraservice/hidl/Convert.h new file mode 100644 index 0000000000..ba2849ea55 --- /dev/null +++ b/services/camera/libcameraservice/hidl/Convert.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2018 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 CAMERASERVER_CONVERT_HIDL +#define CAMERASERVER_CONVERT_HIDL + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace android { +namespace hardware { +namespace cameraservice { +namespace utils { +namespace conversion { + +using hardware::camera2::impl::CaptureResultExtras; +using hardware::camera2::impl::PhysicalCaptureResultInfo; + +using HCameraMetadata = frameworks::cameraservice::service::V2_0::CameraMetadata; +using HCameraDeviceStatus = frameworks::cameraservice::service::V2_0::CameraDeviceStatus; +using HCameraStatusAndId = frameworks::cameraservice::service::V2_0::CameraStatusAndId; +using HCameraDeviceUser = frameworks::cameraservice::device::V2_0::ICameraDeviceUser; +using HCaptureResultExtras = frameworks::cameraservice::device::V2_0::CaptureResultExtras; +using HCaptureRequest = frameworks::cameraservice::device::V2_0::CaptureRequest; +using HErrorCode = frameworks::cameraservice::device::V2_0::ErrorCode; +using HGraphicBufferProducer = hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer; +using HOutputConfiguration = frameworks::cameraservice::device::V2_0::OutputConfiguration; +using HPhysicalCameraSettings = frameworks::cameraservice::device::V2_0::PhysicalCameraSettings; +using HPhysicalCaptureResultInfo = frameworks::cameraservice::device::V2_0::PhysicalCaptureResultInfo; +using HSubmitInfo = frameworks::cameraservice::device::V2_0::SubmitInfo; +using HStatus = frameworks::cameraservice::common::V2_0::Status; +using HStreamConfigurationMode = frameworks::cameraservice::device::V2_0::StreamConfigurationMode; +using HTemplateId = frameworks::cameraservice::device::V2_0::TemplateId; + +// Note: existing data in dst will be gone. Caller still owns the memory of src +void convertToHidl(const camera_metadata_t *src, HCameraMetadata* dst); + +int32_t convertFromHidl(HStreamConfigurationMode streamConfigurationMode); + +int32_t convertFromHidl(HTemplateId templateId); + +bool convertFromHidl(const HCameraMetadata &src, CameraMetadata *dst); + +hardware::camera2::params::OutputConfiguration convertFromHidl( + const HOutputConfiguration &hOutputConfiguration); + +HCameraDeviceStatus convertToHidlCameraDeviceStatus(int32_t status); + +void convertToHidl(const std::vector &src, + hidl_vec* dst); + +void convertToHidl(const hardware::camera2::utils::SubmitInfo &submitInfo, + HSubmitInfo *hSubmitInfo); + +HErrorCode convertToHidl(int32_t errorCode); + +HCaptureResultExtras convertToHidl(const CaptureResultExtras &captureResultExtras); + +HStatus B2HStatus(const binder::Status &bStatus); + +} // conversion +} // utils +} // cameraservice +} // hardware +} //android + +#endif //CAMERASERVER_CONVERT_TO_HIDL diff --git a/services/camera/libcameraservice/hidl/HidlCameraService.cpp b/services/camera/libcameraservice/hidl/HidlCameraService.cpp new file mode 100644 index 0000000000..981f431469 --- /dev/null +++ b/services/camera/libcameraservice/hidl/HidlCameraService.cpp @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2018 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. + */ + +#include + +#include + +#include + +namespace android { +namespace frameworks { +namespace cameraservice { +namespace service { +namespace V2_0 { +namespace implementation { + +using frameworks::cameraservice::service::V2_0::implementation::HidlCameraService; +using hardware::hidl_vec; +using hardware::cameraservice::utils::conversion::convertToHidl; +using hardware::cameraservice::utils::conversion::B2HStatus; +using hardware::Void; + +using HCameraMetadataType = android::frameworks::cameraservice::common::V2_0::CameraMetadataType; +using HVendorTag = android::frameworks::cameraservice::common::V2_0::VendorTag; +using HVendorTagSection = android::frameworks::cameraservice::common::V2_0::VendorTagSection; + +sp gHidlCameraService; + +sp HidlCameraService::getInstance(android::CameraService *cs) { + gHidlCameraService = new HidlCameraService(cs); + return gHidlCameraService; +} + +Return +HidlCameraService::getCameraCharacteristics(const hidl_string& cameraId, + getCameraCharacteristics_cb _hidl_cb) { + android::CameraMetadata cameraMetadata; + HStatus status = HStatus::NO_ERROR; + binder::Status serviceRet = + mAidlICameraService->getCameraCharacteristics(String16(cameraId.c_str()), &cameraMetadata); + HCameraMetadata hidlMetadata; + if (!serviceRet.isOk()) { + switch(serviceRet.serviceSpecificErrorCode()) { + // No ERROR_CAMERA_DISCONNECTED since we're in the same process. + case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT: + ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraId.c_str()); + status = HStatus::ILLEGAL_ARGUMENT; + break; + default: + ALOGE("Get camera characteristics from camera service failed: %s", + serviceRet.toString8().string()); + status = B2HStatus(serviceRet); + } + _hidl_cb(status, hidlMetadata); + return Void(); + } + const camera_metadata_t *rawMetadata = cameraMetadata.getAndLock(); + convertToHidl(rawMetadata, &hidlMetadata); + _hidl_cb(status, hidlMetadata); + cameraMetadata.unlock(rawMetadata); + return Void(); +} + +Return HidlCameraService::connectDevice(const sp& hCallback, + const hidl_string& cameraId, + connectDevice_cb _hidl_cb) { + // To silence Wunused-parameter. + (void)hCallback; + (void)cameraId; + (void)_hidl_cb; + + return Void(); +} + +Return HidlCameraService::addListener(const sp& hCsListener, + addListener_cb _hidl_cb) { + // To silence Wunused-parameter. + (void)hCsListener; + (void)_hidl_cb; + + return Void(); +} + +Return HidlCameraService::removeListener(const sp& hCsListener) { + if (hCsListener == nullptr) { + ALOGE("%s listener must not be NULL", __FUNCTION__); + return HStatus::ILLEGAL_ARGUMENT; + } + return HStatus::NO_ERROR; +} + +Return HidlCameraService::getCameraVendorTagSections(getCameraVendorTagSections_cb _hidl_cb) { + hidl_vec hVendorTagSections; + // TODO: Could this be just created on the stack since we don't set it to + // global cache or anything ? + HStatus hStatus = HStatus::NO_ERROR; + sp desc = new VendorTagDescriptor(); + binder::Status serviceRet = mAidlICameraService->getCameraVendorTagDescriptor(desc.get()); + + if (!serviceRet.isOk()) { + ALOGE("%s: Failed to get VendorTagDescriptor", __FUNCTION__); + _hidl_cb(B2HStatus(serviceRet), hVendorTagSections); + return Void(); + } + + const SortedVector* sectionNames = desc->getAllSectionNames(); + size_t numSections = sectionNames->size(); + std::vector> tagsBySection(numSections); + int tagCount = desc->getTagCount(); + std::vector tags(tagCount); + desc->getTagArray(tags.data()); + for (int i = 0; i < tagCount; i++) { + HVendorTag vt; + vt.tagId = tags[i]; + vt.tagName = desc->getTagName(tags[i]); + vt.tagType = (HCameraMetadataType) desc->getTagType(tags[i]); + ssize_t sectionIdx = desc->getSectionIndex(tags[i]); + tagsBySection[sectionIdx].push_back(vt); + } + hVendorTagSections.resize(numSections); + for (size_t s = 0; s < numSections; s++) { + hVendorTagSections[s].sectionName = (*sectionNames)[s].string(); + hVendorTagSections[s].tags = tagsBySection[s]; + } + _hidl_cb(hStatus, hVendorTagSections); + return Void(); +} + +} // implementation +} // V2_0 +} // service +} // cameraservice +} // frameworks +} // android + diff --git a/services/camera/libcameraservice/hidl/HidlCameraService.h b/services/camera/libcameraservice/hidl/HidlCameraService.h new file mode 100644 index 0000000000..e9daf28efe --- /dev/null +++ b/services/camera/libcameraservice/hidl/HidlCameraService.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2018 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_FRAMEWORKS_CAMERASERVICE_V2_0_CAMERASERVICE_H +#define ANDROID_FRAMEWORKS_CAMERASERVICE_V2_0_CAMERASERVICE_H + +#include +#include + +#include +#include +#include +#include + +#include + +#include + +namespace android { +namespace frameworks { +namespace cameraservice { +namespace service { +namespace V2_0 { +namespace implementation { + +using hardware::hidl_string; +using hardware::ICameraServiceListener; +using hardware::Return; + +using HCameraDeviceCallback = frameworks::cameraservice::device::V2_0::ICameraDeviceCallback; +using HCameraMetadata = frameworks::cameraservice::service::V2_0::CameraMetadata; +using HCameraService = frameworks::cameraservice::service::V2_0::ICameraService; +using HCameraServiceListener = frameworks::cameraservice::service::V2_0::ICameraServiceListener; +using HStatus = frameworks::cameraservice::common::V2_0::Status; +using HCameraStatusAndId = frameworks::cameraservice::service::V2_0::CameraStatusAndId; + +struct HidlCameraService final : public HCameraService { + + ~HidlCameraService() { }; + + // Methods from ::android::frameworks::cameraservice::service::V2.0::ICameraService follow. + + Return connectDevice(const sp& callback, + const hidl_string& cameraId, connectDevice_cb _hidl_cb) override; + + Return addListener(const sp& listener, + addListener_cb _hidl_cb) override; + + Return removeListener(const sp& listener) override; + + Return getCameraCharacteristics(const hidl_string& cameraId, + getCameraCharacteristics_cb _hidl_cb) override; + + Return getCameraVendorTagSections(getCameraVendorTagSections_cb _hidl_cb) override; + + // This method should only be called by the cameraservers main thread to + // instantiate the hidl cameraserver. + static sp getInstance(android::CameraService *cs); + +private: + HidlCameraService(android::CameraService *cs) : mAidlICameraService(cs) { }; + + android::CameraService * const mAidlICameraService = nullptr; +}; + +} // namespace implementation +} // namespace V2_0 +} // namespace service +} // namespace cameraservice +} // namespace frameworks +} // namespace android + +#endif // ANDROID_FRAMEWORKS_CAMERASERVICE_V2_0_CAMERASERVICE_H