/* * Copyright (C) 2019 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 "GCH_HidlCameraProvider" //#define LOG_NDEBUG 0 #include #include #include "camera_device.h" #include "hidl_camera_device.h" #include "hidl_camera_provider.h" #include "hidl_utils.h" namespace android { namespace hardware { namespace camera { namespace provider { namespace V2_7 { namespace implementation { namespace hidl_utils = ::android::hardware::camera::implementation::hidl_utils; using ::android::google_camera_hal::CameraDevice; using ::android::hardware::Void; using ::android::hardware::camera::common::V1_0::CameraDeviceStatus; using ::android::hardware::camera::common::V1_0::TorchModeStatus; using ::android::hardware::camera::common::V1_0::VendorTagSection; const std::string HidlCameraProvider::kProviderName = "internal"; // "device@/internal/" const std::regex HidlCameraProvider::kDeviceNameRegex( "device@([0-9]+\\.[0-9]+)/internal/(.+)"); android::sp HidlCameraProvider::Create() { android::sp provider = new HidlCameraProvider(); status_t res = provider->Initialize(); if (res != OK) { ALOGE("%s: Initializing HidlCameraProvider failed: %s(%d)", __FUNCTION__, strerror(-res), res); return nullptr; } return provider; } status_t HidlCameraProvider::Initialize() { google_camera_provider_ = CameraProvider::Create(); if (google_camera_provider_ == nullptr) { ALOGE("%s: Creating CameraProvider failed.", __FUNCTION__); return NO_INIT; } camera_provider_callback_ = { .camera_device_status_change = google_camera_hal::CameraDeviceStatusChangeFunc( [this](std::string camera_id, google_camera_hal::CameraDeviceStatus new_status) { if (callbacks_ == nullptr) { ALOGE("%s: callbacks_ is null", __FUNCTION__); return; } CameraDeviceStatus hidl_camera_device_status; status_t res = hidl_utils::ConvertToHidlCameraDeviceStatus( new_status, &hidl_camera_device_status); if (res != OK) { ALOGE( "%s: Converting to hidl camera device status failed: %s(%d)", __FUNCTION__, strerror(-res), res); return; } std::unique_lock lock(callbacks_lock_); callbacks_->cameraDeviceStatusChange( "device@" + device::V3_7::implementation::HidlCameraDevice::kDeviceVersion + "/" + kProviderName + "/" + camera_id, hidl_camera_device_status); }), .physical_camera_device_status_change = google_camera_hal:: PhysicalCameraDeviceStatusChangeFunc([this]( std::string camera_id, std::string physical_camera_id, google_camera_hal::CameraDeviceStatus new_status) { if (callbacks_ == nullptr) { ALOGE("%s: callbacks_ is null", __FUNCTION__); return; } auto castResult = provider::V2_6::ICameraProviderCallback::castFrom(callbacks_); if (!castResult.isOk()) { ALOGE("%s: callbacks_ cannot be casted to version 2.6", __FUNCTION__); return; } sp callbacks_2_6_ = castResult; if (callbacks_2_6_ == nullptr) { ALOGE("%s: callbacks_2_6_ is null", __FUNCTION__); return; } CameraDeviceStatus hidl_camera_device_status; status_t res = hidl_utils::ConvertToHidlCameraDeviceStatus( new_status, &hidl_camera_device_status); if (res != OK) { ALOGE( "%s: Converting to hidl camera device status failed: %s(%d)", __FUNCTION__, strerror(-res), res); return; } std::unique_lock lock(callbacks_lock_); callbacks_2_6_->physicalCameraDeviceStatusChange( "device@" + device::V3_7::implementation::HidlCameraDevice::kDeviceVersion + "/" + kProviderName + "/" + camera_id, physical_camera_id, hidl_camera_device_status); }), .torch_mode_status_change = google_camera_hal::TorchModeStatusChangeFunc( [this](std::string camera_id, google_camera_hal::TorchModeStatus new_status) { if (callbacks_ == nullptr) { ALOGE("%s: callbacks_ is null", __FUNCTION__); return; } TorchModeStatus hidl_torch_status; status_t res = hidl_utils::ConvertToHidlTorchModeStatus( new_status, &hidl_torch_status); if (res != OK) { ALOGE("%s: Converting to hidl torch status failed: %s(%d)", __FUNCTION__, strerror(-res), res); return; } std::unique_lock lock(callbacks_lock_); callbacks_->torchModeStatusChange( "device@" + device::V3_7::implementation::HidlCameraDevice::kDeviceVersion + "/" + kProviderName + "/" + camera_id, hidl_torch_status); }), }; google_camera_provider_->SetCallback(&camera_provider_callback_); // purge pending malloc pages after initialization mallopt(M_PURGE, 0); return OK; } Return HidlCameraProvider::setCallback( const sp& callback) { bool first_time = false; { std::unique_lock lock(callbacks_lock_); first_time = callbacks_ == nullptr; callbacks_ = callback; } google_camera_provider_->TriggerDeferredCallbacks(); #ifdef __ANDROID_APEX__ if (first_time) { std::string ready_property_name = "vendor.camera.hal.ready.count"; int ready_count = property_get_int32(ready_property_name.c_str(), 0); property_set(ready_property_name.c_str(), std::to_string(++ready_count).c_str()); ALOGI("HidlCameraProvider::setCallback() first time ready count: %d ", ready_count); } #endif return Status::OK; } Return HidlCameraProvider::getVendorTags(getVendorTags_cb _hidl_cb) { hidl_vec hidl_vendor_tag_sections; std::vector hal_vendor_tag_sections; status_t res = google_camera_provider_->GetVendorTags(&hal_vendor_tag_sections); if (res != OK) { ALOGE("%s: Getting vendor tags failed: %s(%d)", __FUNCTION__, strerror(-res), res); _hidl_cb(Status::INTERNAL_ERROR, hidl_vendor_tag_sections); return Void(); } res = hidl_utils::ConvertToHidlVendorTagSections(hal_vendor_tag_sections, &hidl_vendor_tag_sections); if (res != OK) { ALOGE("%s: Converting to hidl vendor tags failed: %s(%d)", __FUNCTION__, strerror(-res), res); _hidl_cb(Status::INTERNAL_ERROR, hidl_vendor_tag_sections); return Void(); } _hidl_cb(Status::OK, hidl_vendor_tag_sections); return Void(); } Return HidlCameraProvider::getCameraIdList(getCameraIdList_cb _hidl_cb) { std::vector camera_ids; hidl_vec hidl_camera_ids; status_t res = google_camera_provider_->GetCameraIdList(&camera_ids); if (res != OK) { ALOGE("%s: Getting camera ID list failed: %s(%d)", __FUNCTION__, strerror(-res), res); _hidl_cb(Status::INTERNAL_ERROR, hidl_camera_ids); return Void(); } hidl_camera_ids.resize(camera_ids.size()); for (uint32_t i = 0; i < hidl_camera_ids.size(); i++) { // camera ID is in the form of "device@.//" hidl_camera_ids[i] = "device@" + device::V3_7::implementation::HidlCameraDevice::kDeviceVersion + "/" + kProviderName + "/" + std::to_string(camera_ids[i]); } _hidl_cb(Status::OK, hidl_camera_ids); return Void(); } Return HidlCameraProvider::getConcurrentStreamingCameraIds( getConcurrentStreamingCameraIds_cb _hidl_cb) { hidl_vec> hidl_camera_id_combinations; std::vector> camera_id_combinations; status_t res = google_camera_provider_->GetConcurrentStreamingCameraIds( &camera_id_combinations); if (res != OK) { ALOGE( "%s: Getting the combinations of concurrent streaming camera ids " "failed: %s(%d)", __FUNCTION__, strerror(-res), res); _hidl_cb(Status::INTERNAL_ERROR, hidl_camera_id_combinations); return Void(); } hidl_camera_id_combinations.resize(camera_id_combinations.size()); int i = 0; for (auto& combination : camera_id_combinations) { hidl_vec hidl_combination(combination.size()); int c = 0; for (auto& camera_id : combination) { hidl_combination[c] = std::to_string(camera_id); c++; } hidl_camera_id_combinations[i] = hidl_combination; i++; } _hidl_cb(Status::OK, hidl_camera_id_combinations); return Void(); } Return HidlCameraProvider::isConcurrentStreamCombinationSupported( const hidl_vec& configs, isConcurrentStreamCombinationSupported_cb _hidl_cb) { hidl_vec configs2_7; configs2_7.resize(configs.size()); for (size_t i = 0; i < configs.size(); i++) { configs2_7[i].cameraId = configs[i].cameraId; hidl_utils::ConvertStreamConfigurationV34ToV37( configs[i].streamConfiguration, &configs2_7[i].streamConfiguration); } return isConcurrentStreamCombinationSupported_2_7(configs2_7, _hidl_cb); } Return HidlCameraProvider::isConcurrentStreamCombinationSupported_2_7( const hidl_vec& configs, isConcurrentStreamCombinationSupported_cb _hidl_cb) { std::vector devices_stream_configs(configs.size()); status_t res = OK; size_t c = 0; for (auto& config : configs) { res = hidl_utils::ConverToHalStreamConfig( config.streamConfiguration, &devices_stream_configs[c].stream_configuration); if (res != OK) { ALOGE("%s: ConverToHalStreamConfig failed", __FUNCTION__); _hidl_cb(Status::INTERNAL_ERROR, false); return Void(); } uint32_t camera_id = atoi(config.cameraId.c_str()); devices_stream_configs[c].camera_id = camera_id; c++; } bool is_supported = false; res = google_camera_provider_->IsConcurrentStreamCombinationSupported( devices_stream_configs, &is_supported); if (res != OK) { ALOGE("%s: ConverToHalStreamConfig failed", __FUNCTION__); _hidl_cb(Status::INTERNAL_ERROR, false); return Void(); } _hidl_cb(Status::OK, is_supported); return Void(); } Return HidlCameraProvider::isSetTorchModeSupported( isSetTorchModeSupported_cb _hidl_cb) { bool is_supported = google_camera_provider_->IsSetTorchModeSupported(); _hidl_cb(Status::OK, is_supported); return Void(); } Return HidlCameraProvider::getCameraDeviceInterface_V1_x( const hidl_string& /*cameraDeviceName*/, getCameraDeviceInterface_V1_x_cb _hidl_cb) { _hidl_cb(Status::OPERATION_NOT_SUPPORTED, nullptr); return Void(); } bool HidlCameraProvider::ParseDeviceName(const hidl_string& device_name, std::string* device_version, std::string* camera_id) { std::string device_name_std(device_name.c_str()); std::smatch sm; if (std::regex_match(device_name_std, sm, HidlCameraProvider::kDeviceNameRegex)) { if (device_version != nullptr) { *device_version = sm[1]; } if (camera_id != nullptr) { *camera_id = sm[2]; } return true; } return false; } Return HidlCameraProvider::getCameraDeviceInterface_V3_x( const hidl_string& camera_device_name, getCameraDeviceInterface_V3_x_cb _hidl_cb) { std::unique_ptr google_camera_device; // Parse camera_device_name. std::string camera_id, device_version; bool match = ParseDeviceName(camera_device_name, &device_version, &camera_id); if (!match) { ALOGE("%s: Device name parse fail. ", __FUNCTION__); _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr); return Void(); } status_t res = google_camera_provider_->CreateCameraDevice( atoi(camera_id.c_str()), &google_camera_device); if (res != OK) { ALOGE("%s: Creating CameraDevice failed: %s(%d)", __FUNCTION__, strerror(-res), res); _hidl_cb(hidl_utils::ConvertToHidlStatus(res), nullptr); return Void(); } auto hidl_camera_device = device::V3_7::implementation::HidlCameraDevice::Create( std::move(google_camera_device)); if (hidl_camera_device == nullptr) { ALOGE("%s: Creating HidlCameraDevice failed", __FUNCTION__); _hidl_cb(Status::INTERNAL_ERROR, nullptr); return Void(); } _hidl_cb(Status::OK, hidl_camera_device.release()); return Void(); } Return HidlCameraProvider::notifyDeviceStateChange( hardware::hidl_bitfield /*newState*/) { return Void(); } } // namespace implementation } // namespace V2_7 } // namespace provider } // namespace camera } // namespace hardware } // namespace android