blob: 75a55afa6f94f3e868aa02b0c79e590ebed1e5eb [file] [log] [blame]
/*
* 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