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
106 device_info_ = EmulatedCameraDeviceInfo::Create(
107 HalCameraMetadata::Clone(static_metadata_.get()));
108 if (device_info_ == nullptr) {
109 ALOGE("%s: Unable to create device info for camera %d", __FUNCTION__,
110 camera_id_);
111 return NO_INIT;
112 }
113
114 return OK;
115 }
116
GetResourceCost(CameraResourceCost * cost) const117 status_t EmulatedCameraDeviceHwlImpl::GetResourceCost(
118 CameraResourceCost* cost) const {
119 // TODO: remove hardcode
120 cost->resource_cost = 100;
121
122 return OK;
123 }
124
GetCameraCharacteristics(std::unique_ptr<HalCameraMetadata> * characteristics) const125 status_t EmulatedCameraDeviceHwlImpl::GetCameraCharacteristics(
126 std::unique_ptr<HalCameraMetadata>* characteristics) const {
127 if (characteristics == nullptr) {
128 return BAD_VALUE;
129 }
130
131 *characteristics = HalCameraMetadata::Clone(static_metadata_.get());
132
133 return OK;
134 }
135
136 // For EmulatedCameraDevice, we return the static characteristics directly.
137 // In GCH, it will retrieve the entries corresponding to Available Keys listed
138 // in CameraCharacteristics#getAvailableSessionCharacteristicsKeys and generate
139 // the session characteristics to be returned.
GetSessionCharacteristics(const StreamConfiguration &,std::unique_ptr<HalCameraMetadata> & characteristics) const140 status_t EmulatedCameraDeviceHwlImpl::GetSessionCharacteristics(
141 const StreamConfiguration& /*session_config*/,
142 std::unique_ptr<HalCameraMetadata>& characteristics) const {
143 characteristics = HalCameraMetadata::Clone(static_metadata_.get());
144 return OK;
145 }
146
GetPhysicalCameraIds() const147 std::vector<uint32_t> EmulatedCameraDeviceHwlImpl::GetPhysicalCameraIds() const {
148 std::vector<uint32_t> ret;
149 if (physical_device_map_.get() == nullptr ||
150 physical_device_map_->size() == 0) {
151 return ret;
152 }
153 ret.reserve(physical_device_map_->size());
154 for (const auto& entry : *physical_device_map_) {
155 ret.emplace_back(entry.first);
156 }
157 return ret;
158 }
159
GetPhysicalCameraCharacteristics(uint32_t physical_camera_id,std::unique_ptr<HalCameraMetadata> * characteristics) const160 status_t EmulatedCameraDeviceHwlImpl::GetPhysicalCameraCharacteristics(
161 uint32_t physical_camera_id,
162 std::unique_ptr<HalCameraMetadata>* characteristics) const {
163 if (characteristics == nullptr) {
164 return BAD_VALUE;
165 }
166
167 if (physical_device_map_.get() == nullptr) {
168 ALOGE("%s: Camera %d is not a logical device!", __func__, camera_id_);
169 return NO_INIT;
170 }
171
172 if (physical_device_map_->find(physical_camera_id) ==
173 physical_device_map_->end()) {
174 ALOGE("%s: Physical camera id %d is not part of logical camera %d!",
175 __func__, physical_camera_id, camera_id_);
176 return BAD_VALUE;
177 }
178
179 *characteristics = HalCameraMetadata::Clone(
180 physical_device_map_->at(physical_camera_id).second.get());
181
182 return OK;
183 }
184
GetMemoryConfig() const185 google_camera_hal::HwlMemoryConfig EmulatedCameraDeviceHwlImpl::GetMemoryConfig() const {
186 return HwlMemoryConfig();
187 }
188
SetTorchMode(TorchMode mode)189 status_t EmulatedCameraDeviceHwlImpl::SetTorchMode(TorchMode mode) {
190 if (torch_state_.get() == nullptr) {
191 return INVALID_OPERATION;
192 }
193
194 // If torch strength control is supported, reset the torch strength level to
195 // default level whenever the torch is turned OFF.
196 if (maximum_torch_strength_level_ > 1) {
197 torch_state_->InitializeTorchDefaultLevel(default_torch_strength_level_);
198 torch_state_->InitializeSupportTorchStrengthLevel(true);
199 }
200
201 return torch_state_->SetTorchMode(mode);
202 }
203
TurnOnTorchWithStrengthLevel(int32_t torch_strength)204 status_t EmulatedCameraDeviceHwlImpl::TurnOnTorchWithStrengthLevel(int32_t torch_strength) {
205 if (torch_state_.get() == nullptr) {
206 return UNKNOWN_TRANSACTION;
207 }
208
209 // This API is supported if the maximum level is set to greater than 1.
210 if (maximum_torch_strength_level_ <= 1) {
211 ALOGE("Torch strength control feature is not supported.");
212 return UNKNOWN_TRANSACTION;
213 }
214 // Validate that the torch_strength is within the range.
215 if (torch_strength > maximum_torch_strength_level_ || torch_strength < 1) {
216 ALOGE("Torch strength value should be within the range.");
217 return BAD_VALUE;
218 }
219
220 return torch_state_->TurnOnTorchWithStrengthLevel(torch_strength);
221 }
222
GetTorchStrengthLevel(int32_t & torch_strength) const223 status_t EmulatedCameraDeviceHwlImpl::GetTorchStrengthLevel(int32_t& torch_strength) const {
224 if (default_torch_strength_level_ < 1 && maximum_torch_strength_level_ <= 1) {
225 ALOGE("Torch strength control feature is not supported.");
226 return UNKNOWN_TRANSACTION;
227 }
228
229 torch_strength = torch_state_->GetTorchStrengthLevel();
230 ALOGV("Current torch strength level is: %d", torch_strength);
231 return OK;
232 }
233
ConstructDefaultRequestSettings(RequestTemplate type,std::unique_ptr<HalCameraMetadata> * request_settings)234 status_t EmulatedCameraDeviceHwlImpl::ConstructDefaultRequestSettings(
235 RequestTemplate type, std::unique_ptr<HalCameraMetadata>* request_settings) {
236 if (request_settings == nullptr) {
237 ALOGE("%s requestSettings is nullptr", __FUNCTION__);
238 return BAD_VALUE;
239 }
240
241 auto idx = static_cast<size_t>(type);
242 if (idx >= kTemplateCount) {
243 ALOGE("%s: Unexpected request type: %d", __FUNCTION__, type);
244 return BAD_VALUE;
245 }
246
247 if (device_info_->default_requests_[idx].get() == nullptr) {
248 ALOGE("%s: Unsupported request type: %d", __FUNCTION__, type);
249 return BAD_VALUE;
250 }
251
252 *request_settings = HalCameraMetadata::Clone(
253 device_info_->default_requests_[idx]->GetRawCameraMetadata());
254 return OK;
255 }
256
DumpState(int)257 status_t EmulatedCameraDeviceHwlImpl::DumpState(int /*fd*/) {
258 return OK;
259 }
260
CreateCameraDeviceSessionHwl(CameraBufferAllocatorHwl *,std::unique_ptr<CameraDeviceSessionHwl> * session)261 status_t EmulatedCameraDeviceHwlImpl::CreateCameraDeviceSessionHwl(
262 CameraBufferAllocatorHwl* /*camera_allocator_hwl*/,
263 std::unique_ptr<CameraDeviceSessionHwl>* session) {
264 if (session == nullptr) {
265 ALOGE("%s: session is nullptr.", __FUNCTION__);
266 return BAD_VALUE;
267 }
268
269 std::unique_ptr<EmulatedCameraDeviceInfo> deviceInfo =
270 EmulatedCameraDeviceInfo::Clone(*device_info_);
271 *session = EmulatedCameraDeviceSessionHwlImpl::Create(
272 camera_id_, std::move(deviceInfo),
273 ClonePhysicalDeviceMap(physical_device_map_), torch_state_);
274 if (*session == nullptr) {
275 ALOGE("%s: Cannot create EmulatedCameraDeviceSessionHWlImpl.", __FUNCTION__);
276 return BAD_VALUE;
277 }
278
279 if (torch_state_.get() != nullptr) {
280 torch_state_->AcquireFlashHw();
281 }
282
283 return OK;
284 }
285
IsStreamCombinationSupported(const StreamConfiguration & stream_config,const bool) const286 bool EmulatedCameraDeviceHwlImpl::IsStreamCombinationSupported(
287 const StreamConfiguration& stream_config,
288 const bool /*check_settings*/) const {
289 return EmulatedSensor::IsStreamCombinationSupported(
290 camera_id_, stream_config, *stream_configuration_map_,
291 *stream_configuration_map_max_resolution_,
292 physical_stream_configuration_map_,
293 physical_stream_configuration_map_max_resolution_, sensor_chars_);
294 }
295
GetDefaultTorchStrengthLevel() const296 int32_t EmulatedCameraDeviceHwlImpl::GetDefaultTorchStrengthLevel() const {
297 camera_metadata_ro_entry entry;
298 int32_t default_level = 0;
299 auto ret = static_metadata_->Get(ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL, &entry);
300 if (ret == OK && (entry.count == 1)) {
301 default_level = *entry.data.i32;
302 ALOGV("Default torch strength level is %d", default_level);
303 }
304 return default_level;
305 }
306
GetMaximumTorchStrengthLevel() const307 int32_t EmulatedCameraDeviceHwlImpl::GetMaximumTorchStrengthLevel() const {
308 camera_metadata_ro_entry entry;
309 int32_t max_level = 0;
310 auto ret = static_metadata_->Get(ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL, &entry);
311 if (ret == OK && (entry.count == 1)) {
312 max_level = *entry.data.i32;
313 ALOGV("Maximum torch strength level is %d", max_level);
314 }
315 return max_level;
316 }
317
318 } // namespace android
319