1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <mutex>
17 #include <securec.h>
18 #include "camera_metadata_info.h"
19 #include "camera_log.h"
20 #include "camera_manager.h"
21 #include "camera_rotation_api_utils.h"
22 #include "input/camera_device.h"
23 #include "input/camera_manager.h"
24 #include "metadata_common_utils.h"
25 #include "capture_scene_const.h"
26
27 using namespace std;
28
29 namespace OHOS {
30 namespace CameraStandard {
31 const std::unordered_map<camera_type_enum_t, CameraType> CameraDevice::metaToFwCameraType_ = {
32 {OHOS_CAMERA_TYPE_WIDE_ANGLE, CAMERA_TYPE_WIDE_ANGLE},
33 {OHOS_CAMERA_TYPE_ULTRA_WIDE, CAMERA_TYPE_ULTRA_WIDE},
34 {OHOS_CAMERA_TYPE_TELTPHOTO, CAMERA_TYPE_TELEPHOTO},
35 {OHOS_CAMERA_TYPE_TRUE_DEAPTH, CAMERA_TYPE_TRUE_DEPTH},
36 {OHOS_CAMERA_TYPE_LOGICAL, CAMERA_TYPE_UNSUPPORTED},
37 {OHOS_CAMERA_TYPE_UNSPECIFIED, CAMERA_TYPE_DEFAULT}
38 };
39
40 const std::unordered_map<camera_position_enum_t, CameraPosition> CameraDevice::metaToFwCameraPosition_ = {
41 {OHOS_CAMERA_POSITION_FRONT, CAMERA_POSITION_FRONT},
42 {OHOS_CAMERA_POSITION_BACK, CAMERA_POSITION_BACK},
43 {OHOS_CAMERA_POSITION_OTHER, CAMERA_POSITION_UNSPECIFIED}
44 };
45
46 const std::unordered_map<camera_connection_type_t, ConnectionType> CameraDevice::metaToFwConnectionType_ = {
47 {OHOS_CAMERA_CONNECTION_TYPE_REMOTE, CAMERA_CONNECTION_REMOTE},
48 {OHOS_CAMERA_CONNECTION_TYPE_USB_PLUGIN, CAMERA_CONNECTION_USB_PLUGIN},
49 {OHOS_CAMERA_CONNECTION_TYPE_BUILTIN, CAMERA_CONNECTION_BUILT_IN}
50 };
51
52 const std::unordered_map<camera_foldscreen_enum_t, CameraFoldScreenType> CameraDevice::metaToFwCameraFoldScreenType_ = {
53 {OHOS_CAMERA_FOLDSCREEN_INNER, CAMERA_FOLDSCREEN_INNER},
54 {OHOS_CAMERA_FOLDSCREEN_OUTER, CAMERA_FOLDSCREEN_OUTER},
55 {OHOS_CAMERA_FOLDSCREEN_OTHER, CAMERA_FOLDSCREEN_UNSPECIFIED}
56 };
57
CameraDevice(std::string cameraID,std::shared_ptr<Camera::CameraMetadata> metadata)58 CameraDevice::CameraDevice(std::string cameraID, std::shared_ptr<Camera::CameraMetadata> metadata)
59 : cameraID_(cameraID), baseAbility_(MetadataCommonUtils::CopyMetadata(metadata)),
60 cachedMetadata_(MetadataCommonUtils::CopyMetadata(metadata))
61 {
62 CHECK_EXECUTE(metadata != nullptr, init(metadata->get()));
63 }
64
CameraDevice(std::string cameraID,std::shared_ptr<OHOS::Camera::CameraMetadata> metadata,dmDeviceInfo deviceInfo)65 CameraDevice::CameraDevice(
66 std::string cameraID, std::shared_ptr<OHOS::Camera::CameraMetadata> metadata, dmDeviceInfo deviceInfo)
67 : cameraID_(cameraID), baseAbility_(MetadataCommonUtils::CopyMetadata(metadata)),
68 cachedMetadata_(MetadataCommonUtils::CopyMetadata(metadata))
69 {
70 dmDeviceInfo_.deviceName = deviceInfo.deviceName;
71 dmDeviceInfo_.deviceTypeId = deviceInfo.deviceTypeId;
72 dmDeviceInfo_.networkId = deviceInfo.networkId;
73 MEDIA_INFO_LOG("camera cameraid = %{public}s, devicename: = %{public}s", cameraID_.c_str(),
74 dmDeviceInfo_.deviceName.c_str());
75 if (metadata != nullptr) {
76 init(metadata->get());
77 }
78 }
79
CameraDevice(std::string cameraID,dmDeviceInfo deviceInfo,std::shared_ptr<OHOS::Camera::CameraMetadata> metadata)80 CameraDevice::CameraDevice(
81 std::string cameraID, dmDeviceInfo deviceInfo, std::shared_ptr<OHOS::Camera::CameraMetadata> metadata)
82 : cameraID_(cameraID)
83 {
84 dmDeviceInfo_.deviceName = deviceInfo.deviceName;
85 dmDeviceInfo_.deviceTypeId = deviceInfo.deviceTypeId;
86 dmDeviceInfo_.networkId = deviceInfo.networkId;
87 MEDIA_INFO_LOG("camera cameraid = %{public}s, devicename: = %{public}s", cameraID_.c_str(),
88 dmDeviceInfo_.deviceName.c_str());
89 CHECK_EXECUTE(metadata != nullptr, init(metadata->get()));
90 }
91
isFindModuleTypeTag(uint32_t & tagId)92 bool CameraDevice::isFindModuleTypeTag(uint32_t &tagId)
93 {
94 std::vector<vendorTag_t> infos;
95 int32_t ret = OHOS::Camera::GetAllVendorTags(infos);
96 if (ret == CAM_META_SUCCESS) {
97 for (auto info : infos) {
98 std::string tagName = info.tagName;
99 if (tagName == "hwSensorName") {
100 tagId = info.tagId;
101 return true;
102 }
103 }
104 }
105 return false;
106 }
107
init(common_metadata_header_t * metadata)108 void CameraDevice::init(common_metadata_header_t* metadata)
109 {
110 camera_metadata_item_t item;
111
112 int ret = Camera::FindCameraMetadataItem(metadata, OHOS_ABILITY_CAMERA_POSITION, &item);
113 if (ret == CAM_META_SUCCESS) {
114 auto itr = metaToFwCameraPosition_.find(static_cast<camera_position_enum_t>(item.data.u8[0]));
115 if (itr != metaToFwCameraPosition_.end()) {
116 cameraPosition_ = itr->second;
117 }
118 }
119
120 ret = Camera::FindCameraMetadataItem(metadata, OHOS_ABILITY_CAMERA_TYPE, &item);
121 if (ret == CAM_META_SUCCESS) {
122 auto itr = metaToFwCameraType_.find(static_cast<camera_type_enum_t>(item.data.u8[0]));
123 if (itr != metaToFwCameraType_.end()) {
124 cameraType_ = itr->second;
125 }
126 }
127
128 ret = Camera::FindCameraMetadataItem(metadata, OHOS_ABILITY_CAMERA_CONNECTION_TYPE, &item);
129 if (ret == CAM_META_SUCCESS) {
130 auto itr = metaToFwConnectionType_.find(static_cast<camera_connection_type_t>(item.data.u8[0]));
131 if (itr != metaToFwConnectionType_.end()) {
132 connectionType_ = itr->second;
133 }
134 }
135
136 ret = Camera::FindCameraMetadataItem(metadata, OHOS_ABILITY_CAMERA_FOLDSCREEN_TYPE, &item);
137 if (ret == CAM_META_SUCCESS) {
138 auto itr = metaToFwCameraFoldScreenType_.find(static_cast<camera_foldscreen_enum_t>(item.data.u8[0]));
139 if (itr != metaToFwCameraFoldScreenType_.end()) {
140 foldScreenType_ = itr->second;
141 }
142 }
143
144 ret = OHOS::Camera::FindCameraMetadataItem(metadata, OHOS_SENSOR_ORIENTATION, &item);
145 if (ret == CAM_META_SUCCESS) {
146 cameraOrientation_ = static_cast<uint32_t>(item.data.i32[0]);
147 }
148
149 ret = OHOS::Camera::FindCameraMetadataItem(metadata, OHOS_ABILITY_CAMERA_IS_RETRACTABLE, &item);
150 if (ret == CAM_META_SUCCESS) {
151 isRetractable_ = static_cast<bool>(item.data.u8[0]);
152 MEDIA_INFO_LOG("Get isRetractable_ = %{public}d", isRetractable_);
153 }
154
155 uint32_t moduleTypeTagId;
156 if (isFindModuleTypeTag(moduleTypeTagId)) {
157 ret = Camera::FindCameraMetadataItem(metadata, moduleTypeTagId, &item);
158 if (ret == CAM_META_SUCCESS) {
159 moduleType_ = item.data.ui32[0];
160 }
161 }
162
163 ret = OHOS::Camera::FindCameraMetadataItem(metadata, OHOS_ABILITY_CAMERA_FOLD_STATUS, &item);
164
165 foldStatus_ = (ret == CAM_META_SUCCESS) ? item.data.u8[0] : OHOS_CAMERA_FOLD_STATUS_NONFOLDABLE;
166
167 ret = Camera::FindCameraMetadataItem(metadata, OHOS_ABILITY_CAMERA_MODES, &item);
168 if (ret == CAM_META_SUCCESS) {
169 for (uint32_t i = 0; i < item.count; i++) {
170 auto it = g_metaToFwSupportedMode_.find(static_cast<HDI::Camera::V1_3::OperationMode>(item.data.u8[i]));
171 if (it != g_metaToFwSupportedMode_.end()) {
172 supportedModes_.emplace_back(it->second);
173 }
174 }
175 }
176
177 ret = Camera::FindCameraMetadataItem(metadata, OHOS_ABILITY_STATISTICS_DETECT_TYPE, &item);
178 if (ret == CAM_META_SUCCESS) {
179 for (uint32_t i = 0; i < item.count; i++) {
180 auto iterator = g_metaToFwCameraMetaDetect_.find(static_cast<StatisticsDetectType>(item.data.u8[i]));
181 if (iterator != g_metaToFwCameraMetaDetect_.end()) {
182 objectTypes_.push_back(iterator->second);
183 }
184 }
185 }
186
187 ret = Camera::FindCameraMetadataItem(metadata, OHOS_ABILITY_PRELAUNCH_AVAILABLE, &item);
188
189 isPrelaunch_ = (ret == CAM_META_SUCCESS && item.data.u8[0] == 1);
190
191 MEDIA_INFO_LOG("camera position: %{public}d, camera type: %{public}d, camera connection type: %{public}d, "
192 "camera foldScreen type: %{public}d, camera orientation: %{public}d, isretractable: %{public}d, "
193 "moduleType: %{public}u, foldStatus: %{public}d", cameraPosition_, cameraType_, connectionType_,
194 foldScreenType_, cameraOrientation_, isRetractable_, moduleType_, foldStatus_);
195 }
196
GetID()197 std::string CameraDevice::GetID()
198 {
199 return cameraID_;
200 }
201
GetMetadata()202 std::shared_ptr<Camera::CameraMetadata> CameraDevice::GetMetadata()
203 {
204 std::lock_guard<std::mutex> lock(cachedMetadataMutex_);
205 CHECK_ERROR_RETURN_RET(cachedMetadata_ != nullptr, cachedMetadata_);
206 auto cameraProxy = CameraManager::GetInstance()->GetServiceProxy();
207 CHECK_ERROR_RETURN_RET_LOG(cameraProxy == nullptr, nullptr, "GetMetadata Failed to get cameraProxy");
208 std::shared_ptr<OHOS::Camera::CameraMetadata> metadata;
209 cameraProxy->GetCameraAbility(cameraID_, metadata);
210 return metadata;
211 }
212
GetCachedMetadata()213 std::shared_ptr<Camera::CameraMetadata> CameraDevice::GetCachedMetadata()
214 {
215 std::lock_guard<std::mutex> lock(cachedMetadataMutex_);
216 return cachedMetadata_;
217 }
218
AddMetadata(std::shared_ptr<OHOS::Camera::CameraMetadata> srcMetadata)219 void CameraDevice::AddMetadata(std::shared_ptr<OHOS::Camera::CameraMetadata> srcMetadata)
220 {
221 std::lock_guard<std::mutex> lock(cachedMetadataMutex_);
222 cachedMetadata_ = MetadataCommonUtils::CopyMetadata(srcMetadata);
223 }
224
ResetMetadata()225 void CameraDevice::ResetMetadata()
226 {
227 std::lock_guard<std::mutex> lock(cachedMetadataMutex_);
228 CHECK_ERROR_RETURN(cachedMetadata_ == nullptr);
229 std::shared_ptr<OHOS::Camera::CameraMetadata> metadata = GetCameraAbility();
230 cachedMetadata_ = MetadataCommonUtils::CopyMetadata(metadata);
231 }
232
GetCameraAbility()233 const std::shared_ptr<OHOS::Camera::CameraMetadata> CameraDevice::GetCameraAbility()
234 {
235 auto cameraProxy = CameraManager::GetInstance()->GetServiceProxy();
236 CHECK_ERROR_RETURN_RET_LOG(cameraProxy == nullptr, nullptr, "GetCameraAbility Failed to get cameraProxy");
237 std::shared_ptr<OHOS::Camera::CameraMetadata> metadata;
238 cameraProxy->GetCameraAbility(cameraID_, metadata);
239 return metadata;
240 }
241
GetPosition()242 CameraPosition CameraDevice::GetPosition()
243 {
244 uint32_t apiCompatibleVersion = CameraApiVersion::GetApiVersion();
245 auto foldType = CameraManager::GetInstance()->GetFoldScreenType();
246 if (apiCompatibleVersion < CameraApiVersion::APIVersion::API_FOURTEEN && cameraPosition_ == CAMERA_POSITION_FRONT &&
247 (foldScreenType_ == CAMERA_FOLDSCREEN_INNER || foldStatus_ == OHOS_CAMERA_FOLD_STATUS_EXPANDED) &&
248 !foldType.empty() && (foldType[0] == '1' || foldType[0] == '4')) {
249 cameraPosition_ = CAMERA_POSITION_FOLD_INNER;
250 }
251 return cameraPosition_;
252 }
253
GetUsedAsPosition()254 CameraPosition CameraDevice::GetUsedAsPosition()
255 {
256 return usedAsCameraPosition_;
257 }
258
GetCameraType()259 CameraType CameraDevice::GetCameraType()
260 {
261 return cameraType_;
262 }
263
GetConnectionType()264 ConnectionType CameraDevice::GetConnectionType()
265 {
266 return connectionType_;
267 }
268
GetCameraFoldScreenType()269 CameraFoldScreenType CameraDevice::GetCameraFoldScreenType()
270 {
271 return foldScreenType_;
272 }
273
GetSupportedModes() const274 std::vector<SceneMode> CameraDevice::GetSupportedModes() const
275 {
276 return supportedModes_;
277 }
278
GetObjectTypes() const279 std::vector<MetadataObjectType> CameraDevice::GetObjectTypes() const
280 {
281 return objectTypes_;
282 }
283
IsPrelaunch() const284 bool CameraDevice::IsPrelaunch() const
285 {
286 return isPrelaunch_;
287 }
288
GetHostName()289 std::string CameraDevice::GetHostName()
290 {
291 return dmDeviceInfo_.deviceName;
292 }
293
GetDeviceType()294 uint16_t CameraDevice::GetDeviceType()
295 {
296 return dmDeviceInfo_.deviceTypeId;
297 }
298
GetNetWorkId()299 std::string CameraDevice::GetNetWorkId()
300 {
301 return dmDeviceInfo_.networkId;
302 }
303
GetCameraOrientation()304 uint32_t CameraDevice::GetCameraOrientation()
305 {
306 return cameraOrientation_;
307 }
308
GetisRetractable()309 bool CameraDevice::GetisRetractable()
310 {
311 return isRetractable_;
312 }
313
GetModuleType()314 uint32_t CameraDevice::GetModuleType()
315 {
316 return moduleType_;
317 }
318
GetZoomRatioRange()319 std::vector<float> CameraDevice::GetZoomRatioRange()
320 {
321 int32_t minIndex = 0;
322 int32_t maxIndex = 1;
323 std::vector<float> range;
324
325 CHECK_ERROR_RETURN_RET(!zoomRatioRange_.empty(), zoomRatioRange_);
326
327 int ret;
328 uint32_t zoomRangeCount = 2;
329 camera_metadata_item_t item;
330
331 CHECK_ERROR_RETURN_RET_LOG(cachedMetadata_ == nullptr, {},
332 "Failed to get zoom ratio range with cachedMetadata_ is nullptr");
333 ret = Camera::FindCameraMetadataItem(cachedMetadata_->get(), OHOS_ABILITY_ZOOM_RATIO_RANGE, &item);
334 CHECK_ERROR_RETURN_RET_LOG(ret != CAM_META_SUCCESS, {},
335 "Failed to get zoom ratio range with return code %{public}d", ret);
336 CHECK_ERROR_RETURN_RET_LOG(item.count != zoomRangeCount, {},
337 "Failed to get zoom ratio range with return code %{public}d", ret);
338 range = {item.data.f[minIndex], item.data.f[maxIndex]};
339
340 CHECK_ERROR_RETURN_RET_LOG(range[minIndex] > range[maxIndex], {},
341 "Invalid zoom range. min: %{public}f, max: %{public}f", range[minIndex], range[maxIndex]);
342 MEDIA_DEBUG_LOG("Zoom range min: %{public}f, max: %{public}f", range[minIndex], range[maxIndex]);
343
344 zoomRatioRange_ = range;
345 return zoomRatioRange_;
346 }
347
SetProfile(sptr<CameraOutputCapability> capability)348 void CameraDevice::SetProfile(sptr<CameraOutputCapability> capability)
349 {
350 CHECK_ERROR_RETURN(capability == nullptr);
351 modePreviewProfiles_[NORMAL] = capability->GetPreviewProfiles();
352 modePhotoProfiles_[NORMAL] = capability->GetPhotoProfiles();
353 modeVideoProfiles_[NORMAL] = capability->GetVideoProfiles();
354 modeDepthProfiles_[NORMAL] = capability->GetDepthProfiles();
355 modePreviewProfiles_[CAPTURE] = capability->GetPreviewProfiles();
356 modePhotoProfiles_[CAPTURE] = capability->GetPhotoProfiles();
357 modeDepthProfiles_[CAPTURE] = capability->GetDepthProfiles();
358 modePreviewProfiles_[VIDEO] = capability->GetPreviewProfiles();
359 modePhotoProfiles_[VIDEO] = capability->GetPhotoProfiles();
360 modeVideoProfiles_[VIDEO] = capability->GetVideoProfiles();
361 modeDepthProfiles_[VIDEO] = capability->GetDepthProfiles();
362 }
363
SetProfile(sptr<CameraOutputCapability> capability,int32_t modeName)364 void CameraDevice::SetProfile(sptr<CameraOutputCapability> capability, int32_t modeName)
365 {
366 CHECK_ERROR_RETURN(capability == nullptr);
367 modePreviewProfiles_[modeName] = capability->GetPreviewProfiles();
368 modePhotoProfiles_[modeName] = capability->GetPhotoProfiles();
369 modeVideoProfiles_[modeName] = capability->GetVideoProfiles();
370 modeDepthProfiles_[modeName] = capability->GetDepthProfiles();
371 }
372
GetExposureBiasRange()373 std::vector<float> CameraDevice::GetExposureBiasRange()
374 {
375 int32_t minIndex = 0;
376 int32_t maxIndex = 1;
377 uint32_t biasRangeCount = 2;
378
379 if (isConcurrentLimted_ == 1) {
380 std::vector<float> compensationRangeLimted = {};
381 for (int i = 0; i < limtedCapabilitySave_.compensation.count; i++) {
382 float num = static_cast<float>(limtedCapabilitySave_.compensation.range[i]);
383 compensationRangeLimted.push_back(num);
384 }
385 exposureBiasRange_ = compensationRangeLimted;
386 return exposureBiasRange_;
387 }
388
389 CHECK_ERROR_RETURN_RET(!exposureBiasRange_.empty(), exposureBiasRange_);
390
391 camera_metadata_item_t item;
392 int ret = Camera::FindCameraMetadataItem(GetMetadata()->get(), OHOS_ABILITY_AE_COMPENSATION_RANGE, &item);
393 CHECK_ERROR_RETURN_RET_LOG(ret != CAM_META_SUCCESS, {},
394 "Failed to get exposure compensation range with return code %{public}d", ret);
395 CHECK_ERROR_RETURN_RET_LOG(item.count != biasRangeCount, {},
396 "Invalid exposure compensation range count: %{public}d", item.count);
397 int32_t minRange = item.data.i32[minIndex];
398 int32_t maxRange = item.data.i32[maxIndex];
399
400 CHECK_ERROR_RETURN_RET_LOG(minRange > maxRange, {},
401 "Invalid exposure compensation range. min: %{public}d, max: %{public}d", minRange, maxRange);
402
403 MEDIA_DEBUG_LOG("Exposure hdi compensation min: %{public}d, max: %{public}d", minRange, maxRange);
404 exposureBiasRange_ = { static_cast<float>(minRange), static_cast<float>(maxRange) };
405 return exposureBiasRange_;
406 }
407
SetCameraDeviceUsedAsPosition(CameraPosition usedAsPosition)408 void CameraDevice::SetCameraDeviceUsedAsPosition(CameraPosition usedAsPosition)
409 {
410 MEDIA_INFO_LOG("CameraDevice::SetCameraDeviceUsedAsPosition params: %{public}u", usedAsPosition);
411 usedAsCameraPosition_ = usedAsPosition;
412 }
413
GetSupportedFoldStatus()414 uint32_t CameraDevice::GetSupportedFoldStatus()
415 {
416 return foldStatus_;
417 }
418 } // namespace CameraStandard
419 } // namespace OHOS
420