258 lines
8.6 KiB
C++
258 lines
8.6 KiB
C++
/*
|
|
* 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_NDEBUG 0
|
|
#define LOG_TAG "EmulatedCameraDeviceHwlImpl"
|
|
#include "EmulatedCameraDeviceHWLImpl.h"
|
|
|
|
#include <hardware/camera_common.h>
|
|
#include <log/log.h>
|
|
|
|
#include "EmulatedCameraDeviceSessionHWLImpl.h"
|
|
#include "utils/HWLUtils.h"
|
|
|
|
namespace android {
|
|
|
|
std::unique_ptr<CameraDeviceHwl> EmulatedCameraDeviceHwlImpl::Create(
|
|
uint32_t camera_id, std::unique_ptr<HalCameraMetadata> static_meta,
|
|
PhysicalDeviceMapPtr physical_devices,
|
|
std::shared_ptr<EmulatedTorchState> torch_state) {
|
|
auto device = std::unique_ptr<EmulatedCameraDeviceHwlImpl>(
|
|
new EmulatedCameraDeviceHwlImpl(camera_id, std::move(static_meta),
|
|
std::move(physical_devices),
|
|
torch_state));
|
|
|
|
if (device == nullptr) {
|
|
ALOGE("%s: Creating EmulatedCameraDeviceHwlImpl failed.", __FUNCTION__);
|
|
return nullptr;
|
|
}
|
|
|
|
status_t res = device->Initialize();
|
|
if (res != OK) {
|
|
ALOGE("%s: Initializing EmulatedCameraDeviceHwlImpl failed: %s (%d).",
|
|
__FUNCTION__, strerror(-res), res);
|
|
return nullptr;
|
|
}
|
|
|
|
ALOGI("%s: Created EmulatedCameraDeviceHwlImpl for camera %u", __FUNCTION__,
|
|
device->camera_id_);
|
|
|
|
return device;
|
|
}
|
|
|
|
EmulatedCameraDeviceHwlImpl::EmulatedCameraDeviceHwlImpl(
|
|
uint32_t camera_id, std::unique_ptr<HalCameraMetadata> static_meta,
|
|
PhysicalDeviceMapPtr physical_devices,
|
|
std::shared_ptr<EmulatedTorchState> torch_state)
|
|
: camera_id_(camera_id),
|
|
static_metadata_(std::move(static_meta)),
|
|
physical_device_map_(std::move(physical_devices)),
|
|
torch_state_(torch_state) {}
|
|
|
|
uint32_t EmulatedCameraDeviceHwlImpl::GetCameraId() const {
|
|
return camera_id_;
|
|
}
|
|
|
|
status_t EmulatedCameraDeviceHwlImpl::Initialize() {
|
|
auto ret = GetSensorCharacteristics(static_metadata_.get(),
|
|
&sensor_chars_[camera_id_]);
|
|
if (ret != OK) {
|
|
ALOGE("%s: Unable to extract sensor characteristics %s (%d)", __FUNCTION__,
|
|
strerror(-ret), ret);
|
|
return ret;
|
|
}
|
|
|
|
stream_configuration_map_ =
|
|
std::make_unique<StreamConfigurationMap>(*static_metadata_);
|
|
stream_configuration_map_max_resolution_ =
|
|
std::make_unique<StreamConfigurationMap>(*static_metadata_,
|
|
/*maxResolution*/ true);
|
|
|
|
for (const auto& it : *physical_device_map_) {
|
|
uint32_t physical_id = it.first;
|
|
HalCameraMetadata* physical_hal_metadata = it.second.second.get();
|
|
physical_stream_configuration_map_.emplace(
|
|
physical_id,
|
|
std::make_unique<StreamConfigurationMap>(*physical_hal_metadata));
|
|
physical_stream_configuration_map_max_resolution_.emplace(
|
|
physical_id, std::make_unique<StreamConfigurationMap>(
|
|
*physical_hal_metadata, /*maxResolution*/ true));
|
|
|
|
ret = GetSensorCharacteristics(physical_hal_metadata,
|
|
&sensor_chars_[physical_id]);
|
|
if (ret != OK) {
|
|
ALOGE("%s: Unable to extract camera %d sensor characteristics %s (%d)",
|
|
__FUNCTION__, physical_id, strerror(-ret), ret);
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
default_torch_strength_level_ = GetDefaultTorchStrengthLevel();
|
|
maximum_torch_strength_level_ = GetMaximumTorchStrengthLevel();
|
|
return OK;
|
|
}
|
|
|
|
status_t EmulatedCameraDeviceHwlImpl::GetResourceCost(
|
|
CameraResourceCost* cost) const {
|
|
// TODO: remove hardcode
|
|
cost->resource_cost = 100;
|
|
|
|
return OK;
|
|
}
|
|
|
|
status_t EmulatedCameraDeviceHwlImpl::GetCameraCharacteristics(
|
|
std::unique_ptr<HalCameraMetadata>* characteristics) const {
|
|
if (characteristics == nullptr) {
|
|
return BAD_VALUE;
|
|
}
|
|
|
|
*characteristics = HalCameraMetadata::Clone(static_metadata_.get());
|
|
|
|
return OK;
|
|
}
|
|
|
|
status_t EmulatedCameraDeviceHwlImpl::GetPhysicalCameraCharacteristics(
|
|
uint32_t physical_camera_id,
|
|
std::unique_ptr<HalCameraMetadata>* characteristics) const {
|
|
if (characteristics == nullptr) {
|
|
return BAD_VALUE;
|
|
}
|
|
|
|
if (physical_device_map_.get() == nullptr) {
|
|
ALOGE("%s: Camera %d is not a logical device!", __func__, camera_id_);
|
|
return NO_INIT;
|
|
}
|
|
|
|
if (physical_device_map_->find(physical_camera_id) ==
|
|
physical_device_map_->end()) {
|
|
ALOGE("%s: Physical camera id %d is not part of logical camera %d!",
|
|
__func__, physical_camera_id, camera_id_);
|
|
return BAD_VALUE;
|
|
}
|
|
|
|
*characteristics = HalCameraMetadata::Clone(
|
|
physical_device_map_->at(physical_camera_id).second.get());
|
|
|
|
return OK;
|
|
}
|
|
|
|
status_t EmulatedCameraDeviceHwlImpl::SetTorchMode(TorchMode mode) {
|
|
if (torch_state_.get() == nullptr) {
|
|
return INVALID_OPERATION;
|
|
}
|
|
|
|
// If torch strength control is supported, reset the torch strength level to
|
|
// default level whenever the torch is turned OFF.
|
|
if (maximum_torch_strength_level_ > 1) {
|
|
torch_state_->InitializeTorchDefaultLevel(default_torch_strength_level_);
|
|
torch_state_->InitializeSupportTorchStrengthLevel(true);
|
|
}
|
|
|
|
return torch_state_->SetTorchMode(mode);
|
|
}
|
|
|
|
status_t EmulatedCameraDeviceHwlImpl::TurnOnTorchWithStrengthLevel(int32_t torch_strength) {
|
|
if (torch_state_.get() == nullptr) {
|
|
return UNKNOWN_TRANSACTION;
|
|
}
|
|
|
|
// This API is supported if the maximum level is set to greater than 1.
|
|
if (maximum_torch_strength_level_ <= 1) {
|
|
ALOGE("Torch strength control feature is not supported.");
|
|
return UNKNOWN_TRANSACTION;
|
|
}
|
|
// Validate that the torch_strength is within the range.
|
|
if (torch_strength > maximum_torch_strength_level_ || torch_strength < 1) {
|
|
ALOGE("Torch strength value should be within the range.");
|
|
return BAD_VALUE;
|
|
}
|
|
|
|
return torch_state_->TurnOnTorchWithStrengthLevel(torch_strength);
|
|
}
|
|
|
|
status_t EmulatedCameraDeviceHwlImpl::GetTorchStrengthLevel(int32_t& torch_strength) const {
|
|
if (default_torch_strength_level_ < 1 && maximum_torch_strength_level_ <= 1) {
|
|
ALOGE("Torch strength control feature is not supported.");
|
|
return UNKNOWN_TRANSACTION;
|
|
}
|
|
|
|
torch_strength = torch_state_->GetTorchStrengthLevel();
|
|
ALOGV("Current torch strength level is: %d", torch_strength);
|
|
return OK;
|
|
}
|
|
|
|
status_t EmulatedCameraDeviceHwlImpl::DumpState(int /*fd*/) {
|
|
return OK;
|
|
}
|
|
|
|
status_t EmulatedCameraDeviceHwlImpl::CreateCameraDeviceSessionHwl(
|
|
CameraBufferAllocatorHwl* /*camera_allocator_hwl*/,
|
|
std::unique_ptr<CameraDeviceSessionHwl>* session) {
|
|
if (session == nullptr) {
|
|
ALOGE("%s: session is nullptr.", __FUNCTION__);
|
|
return BAD_VALUE;
|
|
}
|
|
|
|
std::unique_ptr<HalCameraMetadata> meta =
|
|
HalCameraMetadata::Clone(static_metadata_.get());
|
|
*session = EmulatedCameraDeviceSessionHwlImpl::Create(
|
|
camera_id_, std::move(meta), ClonePhysicalDeviceMap(physical_device_map_),
|
|
torch_state_);
|
|
if (*session == nullptr) {
|
|
ALOGE("%s: Cannot create EmulatedCameraDeviceSessionHWlImpl.", __FUNCTION__);
|
|
return BAD_VALUE;
|
|
}
|
|
|
|
if (torch_state_.get() != nullptr) {
|
|
torch_state_->AcquireFlashHw();
|
|
}
|
|
|
|
return OK;
|
|
}
|
|
|
|
bool EmulatedCameraDeviceHwlImpl::IsStreamCombinationSupported(
|
|
const StreamConfiguration& stream_config) {
|
|
return EmulatedSensor::IsStreamCombinationSupported(
|
|
camera_id_, stream_config, *stream_configuration_map_,
|
|
*stream_configuration_map_max_resolution_,
|
|
physical_stream_configuration_map_,
|
|
physical_stream_configuration_map_max_resolution_, sensor_chars_);
|
|
}
|
|
|
|
int32_t EmulatedCameraDeviceHwlImpl::GetDefaultTorchStrengthLevel() const {
|
|
camera_metadata_ro_entry entry;
|
|
int32_t default_level = 0;
|
|
auto ret = static_metadata_->Get(ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL, &entry);
|
|
if (ret == OK && (entry.count == 1)) {
|
|
default_level = *entry.data.i32;
|
|
ALOGV("Default torch strength level is %d", default_level);
|
|
}
|
|
return default_level;
|
|
}
|
|
|
|
int32_t EmulatedCameraDeviceHwlImpl::GetMaximumTorchStrengthLevel() const {
|
|
camera_metadata_ro_entry entry;
|
|
int32_t max_level = 0;
|
|
auto ret = static_metadata_->Get(ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL, &entry);
|
|
if (ret == OK && (entry.count == 1)) {
|
|
max_level = *entry.data.i32;
|
|
ALOGV("Maximum torch strength level is %d", max_level);
|
|
}
|
|
return max_level;
|
|
}
|
|
|
|
} // namespace android
|