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
SetTorchMode(TorchMode mode)185 status_t EmulatedCameraDeviceHwlImpl::SetTorchMode(TorchMode mode) {
186 if (torch_state_.get() == nullptr) {
187 return INVALID_OPERATION;
188 }
189
190 // If torch strength control is supported, reset the torch strength level to
191 // default level whenever the torch is turned OFF.
192 if (maximum_torch_strength_level_ > 1) {
193 torch_state_->InitializeTorchDefaultLevel(default_torch_strength_level_);
194 torch_state_->InitializeSupportTorchStrengthLevel(true);
195 }
196
197 return torch_state_->SetTorchMode(mode);
198 }
199
TurnOnTorchWithStrengthLevel(int32_t torch_strength)200 status_t EmulatedCameraDeviceHwlImpl::TurnOnTorchWithStrengthLevel(int32_t torch_strength) {
201 if (torch_state_.get() == nullptr) {
202 return UNKNOWN_TRANSACTION;
203 }
204
205 // This API is supported if the maximum level is set to greater than 1.
206 if (maximum_torch_strength_level_ <= 1) {
207 ALOGE("Torch strength control feature is not supported.");
208 return UNKNOWN_TRANSACTION;
209 }
210 // Validate that the torch_strength is within the range.
211 if (torch_strength > maximum_torch_strength_level_ || torch_strength < 1) {
212 ALOGE("Torch strength value should be within the range.");
213 return BAD_VALUE;
214 }
215
216 return torch_state_->TurnOnTorchWithStrengthLevel(torch_strength);
217 }
218
GetTorchStrengthLevel(int32_t & torch_strength) const219 status_t EmulatedCameraDeviceHwlImpl::GetTorchStrengthLevel(int32_t& torch_strength) const {
220 if (default_torch_strength_level_ < 1 && maximum_torch_strength_level_ <= 1) {
221 ALOGE("Torch strength control feature is not supported.");
222 return UNKNOWN_TRANSACTION;
223 }
224
225 torch_strength = torch_state_->GetTorchStrengthLevel();
226 ALOGV("Current torch strength level is: %d", torch_strength);
227 return OK;
228 }
229
ConstructDefaultRequestSettings(RequestTemplate type,std::unique_ptr<HalCameraMetadata> * request_settings)230 status_t EmulatedCameraDeviceHwlImpl::ConstructDefaultRequestSettings(
231 RequestTemplate type, std::unique_ptr<HalCameraMetadata>* request_settings) {
232 if (request_settings == nullptr) {
233 ALOGE("%s requestSettings is nullptr", __FUNCTION__);
234 return BAD_VALUE;
235 }
236
237 auto idx = static_cast<size_t>(type);
238 if (idx >= kTemplateCount) {
239 ALOGE("%s: Unexpected request type: %d", __FUNCTION__, type);
240 return BAD_VALUE;
241 }
242
243 if (device_info_->default_requests_[idx].get() == nullptr) {
244 ALOGE("%s: Unsupported request type: %d", __FUNCTION__, type);
245 return BAD_VALUE;
246 }
247
248 *request_settings = HalCameraMetadata::Clone(
249 device_info_->default_requests_[idx]->GetRawCameraMetadata());
250 return OK;
251 }
252
DumpState(int)253 status_t EmulatedCameraDeviceHwlImpl::DumpState(int /*fd*/) {
254 return OK;
255 }
256
CreateCameraDeviceSessionHwl(CameraBufferAllocatorHwl *,std::unique_ptr<CameraDeviceSessionHwl> * session)257 status_t EmulatedCameraDeviceHwlImpl::CreateCameraDeviceSessionHwl(
258 CameraBufferAllocatorHwl* /*camera_allocator_hwl*/,
259 std::unique_ptr<CameraDeviceSessionHwl>* session) {
260 if (session == nullptr) {
261 ALOGE("%s: session is nullptr.", __FUNCTION__);
262 return BAD_VALUE;
263 }
264
265 std::unique_ptr<EmulatedCameraDeviceInfo> deviceInfo =
266 EmulatedCameraDeviceInfo::Clone(*device_info_);
267 *session = EmulatedCameraDeviceSessionHwlImpl::Create(
268 camera_id_, std::move(deviceInfo),
269 ClonePhysicalDeviceMap(physical_device_map_), torch_state_);
270 if (*session == nullptr) {
271 ALOGE("%s: Cannot create EmulatedCameraDeviceSessionHWlImpl.", __FUNCTION__);
272 return BAD_VALUE;
273 }
274
275 if (torch_state_.get() != nullptr) {
276 torch_state_->AcquireFlashHw();
277 }
278
279 return OK;
280 }
281
IsStreamCombinationSupported(const StreamConfiguration & stream_config,const bool) const282 bool EmulatedCameraDeviceHwlImpl::IsStreamCombinationSupported(
283 const StreamConfiguration& stream_config,
284 const bool /*check_settings*/) const {
285 return EmulatedSensor::IsStreamCombinationSupported(
286 camera_id_, stream_config, *stream_configuration_map_,
287 *stream_configuration_map_max_resolution_,
288 physical_stream_configuration_map_,
289 physical_stream_configuration_map_max_resolution_, sensor_chars_);
290 }
291
GetDefaultTorchStrengthLevel() const292 int32_t EmulatedCameraDeviceHwlImpl::GetDefaultTorchStrengthLevel() const {
293 camera_metadata_ro_entry entry;
294 int32_t default_level = 0;
295 auto ret = static_metadata_->Get(ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL, &entry);
296 if (ret == OK && (entry.count == 1)) {
297 default_level = *entry.data.i32;
298 ALOGV("Default torch strength level is %d", default_level);
299 }
300 return default_level;
301 }
302
GetMaximumTorchStrengthLevel() const303 int32_t EmulatedCameraDeviceHwlImpl::GetMaximumTorchStrengthLevel() const {
304 camera_metadata_ro_entry entry;
305 int32_t max_level = 0;
306 auto ret = static_metadata_->Get(ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL, &entry);
307 if (ret == OK && (entry.count == 1)) {
308 max_level = *entry.data.i32;
309 ALOGV("Maximum torch strength level is %d", max_level);
310 }
311 return max_level;
312 }
313
314 } // namespace android
315