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