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