1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "EmulatedCameraDeviceHwlImpl"
19 #include "EmulatedCameraDeviceHWLImpl.h"
20
21 #include <hardware/camera_common.h>
22 #include <log/log.h>
23
24 #include "EmulatedCameraDeviceSessionHWLImpl.h"
25 #include "utils/HWLUtils.h"
26
27 namespace android {
28
Create(uint32_t camera_id,std::unique_ptr<HalCameraMetadata> static_meta,PhysicalDeviceMapPtr physical_devices,std::shared_ptr<EmulatedTorchState> torch_state)29 std::unique_ptr<CameraDeviceHwl> EmulatedCameraDeviceHwlImpl::Create(
30 uint32_t camera_id, std::unique_ptr<HalCameraMetadata> static_meta,
31 PhysicalDeviceMapPtr physical_devices,
32 std::shared_ptr<EmulatedTorchState> torch_state) {
33 auto device = std::unique_ptr<EmulatedCameraDeviceHwlImpl>(
34 new EmulatedCameraDeviceHwlImpl(camera_id, std::move(static_meta),
35 std::move(physical_devices),
36 torch_state));
37
38 if (device == nullptr) {
39 ALOGE("%s: Creating EmulatedCameraDeviceHwlImpl failed.", __FUNCTION__);
40 return nullptr;
41 }
42
43 status_t res = device->Initialize();
44 if (res != OK) {
45 ALOGE("%s: Initializing EmulatedCameraDeviceHwlImpl failed: %s (%d).",
46 __FUNCTION__, strerror(-res), res);
47 return nullptr;
48 }
49
50 ALOGI("%s: Created EmulatedCameraDeviceHwlImpl for camera %u", __FUNCTION__,
51 device->camera_id_);
52
53 return device;
54 }
55
EmulatedCameraDeviceHwlImpl(uint32_t camera_id,std::unique_ptr<HalCameraMetadata> static_meta,PhysicalDeviceMapPtr physical_devices,std::shared_ptr<EmulatedTorchState> torch_state)56 EmulatedCameraDeviceHwlImpl::EmulatedCameraDeviceHwlImpl(
57 uint32_t camera_id, std::unique_ptr<HalCameraMetadata> static_meta,
58 PhysicalDeviceMapPtr physical_devices,
59 std::shared_ptr<EmulatedTorchState> torch_state)
60 : camera_id_(camera_id),
61 static_metadata_(std::move(static_meta)),
62 physical_device_map_(std::move(physical_devices)),
63 torch_state_(torch_state) {}
64
GetCameraId() const65 uint32_t EmulatedCameraDeviceHwlImpl::GetCameraId() const {
66 return camera_id_;
67 }
68
Initialize()69 status_t EmulatedCameraDeviceHwlImpl::Initialize() {
70 auto ret = GetSensorCharacteristics(static_metadata_.get(),
71 &sensor_chars_[camera_id_]);
72 if (ret != OK) {
73 ALOGE("%s: Unable to extract sensor characteristics %s (%d)", __FUNCTION__,
74 strerror(-ret), ret);
75 return ret;
76 }
77
78 stream_configuration_map_ =
79 std::make_unique<StreamConfigurationMap>(*static_metadata_);
80 stream_configuration_map_max_resolution_ =
81 std::make_unique<StreamConfigurationMap>(*static_metadata_,
82 /*maxResolution*/ true);
83
84 for (const auto& it : *physical_device_map_) {
85 uint32_t physical_id = it.first;
86 HalCameraMetadata* physical_hal_metadata = it.second.second.get();
87 physical_stream_configuration_map_.emplace(
88 physical_id,
89 std::make_unique<StreamConfigurationMap>(*physical_hal_metadata));
90 physical_stream_configuration_map_max_resolution_.emplace(
91 physical_id, std::make_unique<StreamConfigurationMap>(
92 *physical_hal_metadata, /*maxResolution*/ true));
93
94 ret = GetSensorCharacteristics(physical_hal_metadata,
95 &sensor_chars_[physical_id]);
96 if (ret != OK) {
97 ALOGE("%s: Unable to extract camera %d sensor characteristics %s (%d)",
98 __FUNCTION__, physical_id, strerror(-ret), ret);
99 return ret;
100 }
101 }
102
103 default_torch_strength_level_ = GetDefaultTorchStrengthLevel();
104 maximum_torch_strength_level_ = GetMaximumTorchStrengthLevel();
105 return OK;
106 }
107
GetResourceCost(CameraResourceCost * cost) const108 status_t EmulatedCameraDeviceHwlImpl::GetResourceCost(
109 CameraResourceCost* cost) const {
110 // TODO: remove hardcode
111 cost->resource_cost = 100;
112
113 return OK;
114 }
115
GetCameraCharacteristics(std::unique_ptr<HalCameraMetadata> * characteristics) const116 status_t EmulatedCameraDeviceHwlImpl::GetCameraCharacteristics(
117 std::unique_ptr<HalCameraMetadata>* characteristics) const {
118 if (characteristics == nullptr) {
119 return BAD_VALUE;
120 }
121
122 *characteristics = HalCameraMetadata::Clone(static_metadata_.get());
123
124 return OK;
125 }
126
GetPhysicalCameraCharacteristics(uint32_t physical_camera_id,std::unique_ptr<HalCameraMetadata> * characteristics) const127 status_t EmulatedCameraDeviceHwlImpl::GetPhysicalCameraCharacteristics(
128 uint32_t physical_camera_id,
129 std::unique_ptr<HalCameraMetadata>* characteristics) const {
130 if (characteristics == nullptr) {
131 return BAD_VALUE;
132 }
133
134 if (physical_device_map_.get() == nullptr) {
135 ALOGE("%s: Camera %d is not a logical device!", __func__, camera_id_);
136 return NO_INIT;
137 }
138
139 if (physical_device_map_->find(physical_camera_id) ==
140 physical_device_map_->end()) {
141 ALOGE("%s: Physical camera id %d is not part of logical camera %d!",
142 __func__, physical_camera_id, camera_id_);
143 return BAD_VALUE;
144 }
145
146 *characteristics = HalCameraMetadata::Clone(
147 physical_device_map_->at(physical_camera_id).second.get());
148
149 return OK;
150 }
151
SetTorchMode(TorchMode mode)152 status_t EmulatedCameraDeviceHwlImpl::SetTorchMode(TorchMode mode) {
153 if (torch_state_.get() == nullptr) {
154 return INVALID_OPERATION;
155 }
156
157 // If torch strength control is supported, reset the torch strength level to
158 // default level whenever the torch is turned OFF.
159 if (maximum_torch_strength_level_ > 1) {
160 torch_state_->InitializeTorchDefaultLevel(default_torch_strength_level_);
161 torch_state_->InitializeSupportTorchStrengthLevel(true);
162 }
163
164 return torch_state_->SetTorchMode(mode);
165 }
166
TurnOnTorchWithStrengthLevel(int32_t torch_strength)167 status_t EmulatedCameraDeviceHwlImpl::TurnOnTorchWithStrengthLevel(int32_t torch_strength) {
168 if (torch_state_.get() == nullptr) {
169 return UNKNOWN_TRANSACTION;
170 }
171
172 // This API is supported if the maximum level is set to greater than 1.
173 if (maximum_torch_strength_level_ <= 1) {
174 ALOGE("Torch strength control feature is not supported.");
175 return UNKNOWN_TRANSACTION;
176 }
177 // Validate that the torch_strength is within the range.
178 if (torch_strength > maximum_torch_strength_level_ || torch_strength < 1) {
179 ALOGE("Torch strength value should be within the range.");
180 return BAD_VALUE;
181 }
182
183 return torch_state_->TurnOnTorchWithStrengthLevel(torch_strength);
184 }
185
GetTorchStrengthLevel(int32_t & torch_strength) const186 status_t EmulatedCameraDeviceHwlImpl::GetTorchStrengthLevel(int32_t& torch_strength) const {
187 if (default_torch_strength_level_ < 1 && maximum_torch_strength_level_ <= 1) {
188 ALOGE("Torch strength control feature is not supported.");
189 return UNKNOWN_TRANSACTION;
190 }
191
192 torch_strength = torch_state_->GetTorchStrengthLevel();
193 ALOGV("Current torch strength level is: %d", torch_strength);
194 return OK;
195 }
196
DumpState(int)197 status_t EmulatedCameraDeviceHwlImpl::DumpState(int /*fd*/) {
198 return OK;
199 }
200
CreateCameraDeviceSessionHwl(CameraBufferAllocatorHwl *,std::unique_ptr<CameraDeviceSessionHwl> * session)201 status_t EmulatedCameraDeviceHwlImpl::CreateCameraDeviceSessionHwl(
202 CameraBufferAllocatorHwl* /*camera_allocator_hwl*/,
203 std::unique_ptr<CameraDeviceSessionHwl>* session) {
204 if (session == nullptr) {
205 ALOGE("%s: session is nullptr.", __FUNCTION__);
206 return BAD_VALUE;
207 }
208
209 std::unique_ptr<HalCameraMetadata> meta =
210 HalCameraMetadata::Clone(static_metadata_.get());
211 *session = EmulatedCameraDeviceSessionHwlImpl::Create(
212 camera_id_, std::move(meta), ClonePhysicalDeviceMap(physical_device_map_),
213 torch_state_);
214 if (*session == nullptr) {
215 ALOGE("%s: Cannot create EmulatedCameraDeviceSessionHWlImpl.", __FUNCTION__);
216 return BAD_VALUE;
217 }
218
219 if (torch_state_.get() != nullptr) {
220 torch_state_->AcquireFlashHw();
221 }
222
223 return OK;
224 }
225
IsStreamCombinationSupported(const StreamConfiguration & stream_config)226 bool EmulatedCameraDeviceHwlImpl::IsStreamCombinationSupported(
227 const StreamConfiguration& stream_config) {
228 return EmulatedSensor::IsStreamCombinationSupported(
229 camera_id_, stream_config, *stream_configuration_map_,
230 *stream_configuration_map_max_resolution_,
231 physical_stream_configuration_map_,
232 physical_stream_configuration_map_max_resolution_, sensor_chars_);
233 }
234
GetDefaultTorchStrengthLevel() const235 int32_t EmulatedCameraDeviceHwlImpl::GetDefaultTorchStrengthLevel() const {
236 camera_metadata_ro_entry entry;
237 int32_t default_level = 0;
238 auto ret = static_metadata_->Get(ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL, &entry);
239 if (ret == OK && (entry.count == 1)) {
240 default_level = *entry.data.i32;
241 ALOGV("Default torch strength level is %d", default_level);
242 }
243 return default_level;
244 }
245
GetMaximumTorchStrengthLevel() const246 int32_t EmulatedCameraDeviceHwlImpl::GetMaximumTorchStrengthLevel() const {
247 camera_metadata_ro_entry entry;
248 int32_t max_level = 0;
249 auto ret = static_metadata_->Get(ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL, &entry);
250 if (ret == OK && (entry.count == 1)) {
251 max_level = *entry.data.i32;
252 ALOGV("Maximum torch strength level is %d", max_level);
253 }
254 return max_level;
255 }
256
257 } // namespace android
258