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_rotation_api_utils.h"
21 #include "input/camera_device.h"
22 #include "metadata_common_utils.h"
23 #include "capture_scene_const.h"
24 
25 using namespace std;
26 
27 namespace OHOS {
28 namespace CameraStandard {
29 const std::unordered_map<camera_type_enum_t, CameraType> CameraDevice::metaToFwCameraType_ = {
30     {OHOS_CAMERA_TYPE_WIDE_ANGLE, CAMERA_TYPE_WIDE_ANGLE},
31     {OHOS_CAMERA_TYPE_ULTRA_WIDE, CAMERA_TYPE_ULTRA_WIDE},
32     {OHOS_CAMERA_TYPE_TELTPHOTO, CAMERA_TYPE_TELEPHOTO},
33     {OHOS_CAMERA_TYPE_TRUE_DEAPTH, CAMERA_TYPE_TRUE_DEPTH},
34     {OHOS_CAMERA_TYPE_LOGICAL, CAMERA_TYPE_UNSUPPORTED},
35     {OHOS_CAMERA_TYPE_UNSPECIFIED, CAMERA_TYPE_DEFAULT}
36 };
37 
38 const std::unordered_map<camera_position_enum_t, CameraPosition> CameraDevice::metaToFwCameraPosition_ = {
39     {OHOS_CAMERA_POSITION_FRONT, CAMERA_POSITION_FRONT},
40     {OHOS_CAMERA_POSITION_BACK, CAMERA_POSITION_BACK},
41     {OHOS_CAMERA_POSITION_OTHER, CAMERA_POSITION_UNSPECIFIED}
42 };
43 
44 const std::unordered_map<camera_connection_type_t, ConnectionType> CameraDevice::metaToFwConnectionType_ = {
45     {OHOS_CAMERA_CONNECTION_TYPE_REMOTE, CAMERA_CONNECTION_REMOTE},
46     {OHOS_CAMERA_CONNECTION_TYPE_USB_PLUGIN, CAMERA_CONNECTION_USB_PLUGIN},
47     {OHOS_CAMERA_CONNECTION_TYPE_BUILTIN, CAMERA_CONNECTION_BUILT_IN}
48 };
49 
50 const std::unordered_map<camera_foldscreen_enum_t, CameraFoldScreenType> CameraDevice::metaToFwCameraFoldScreenType_ = {
51     {OHOS_CAMERA_FOLDSCREEN_INNER, CAMERA_FOLDSCREEN_INNER},
52     {OHOS_CAMERA_FOLDSCREEN_OUTER, CAMERA_FOLDSCREEN_OUTER},
53     {OHOS_CAMERA_FOLDSCREEN_OTHER, CAMERA_FOLDSCREEN_UNSPECIFIED}
54 };
55 
CameraDevice(std::string cameraID,std::shared_ptr<Camera::CameraMetadata> metadata)56 CameraDevice::CameraDevice(std::string cameraID, std::shared_ptr<Camera::CameraMetadata> metadata)
57     : cameraID_(cameraID), baseAbility_(MetadataCommonUtils::CopyMetadata(metadata)),
58       cachedMetadata_(MetadataCommonUtils::CopyMetadata(metadata))
59 {
60     if (metadata != nullptr) {
61         init(metadata->get());
62     }
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 
isFindModuleTypeTag(uint32_t & tagId)80 bool CameraDevice::isFindModuleTypeTag(uint32_t &tagId)
81 {
82     std::vector<vendorTag_t> infos;
83     int32_t ret = OHOS::Camera::GetAllVendorTags(infos);
84     if (ret == CAM_META_SUCCESS) {
85         for (auto info : infos) {
86             std::string tagName = info.tagName;
87             if (tagName == "hwSensorName") {
88                 tagId = info.tagId;
89                 return true;
90             }
91         }
92     }
93     return false;
94 }
95 
init(common_metadata_header_t * metadata)96 void CameraDevice::init(common_metadata_header_t* metadata)
97 {
98     camera_metadata_item_t item;
99 
100     int ret = Camera::FindCameraMetadataItem(metadata, OHOS_ABILITY_CAMERA_POSITION, &item);
101     if (ret == CAM_META_SUCCESS) {
102         auto itr = metaToFwCameraPosition_.find(static_cast<camera_position_enum_t>(item.data.u8[0]));
103         if (itr != metaToFwCameraPosition_.end()) {
104             cameraPosition_ = itr->second;
105         }
106     }
107 
108     ret = Camera::FindCameraMetadataItem(metadata, OHOS_ABILITY_CAMERA_TYPE, &item);
109     if (ret == CAM_META_SUCCESS) {
110         auto itr = metaToFwCameraType_.find(static_cast<camera_type_enum_t>(item.data.u8[0]));
111         if (itr != metaToFwCameraType_.end()) {
112             cameraType_ = itr->second;
113         }
114     }
115 
116     ret = Camera::FindCameraMetadataItem(metadata, OHOS_ABILITY_CAMERA_CONNECTION_TYPE, &item);
117     if (ret == CAM_META_SUCCESS) {
118         auto itr = metaToFwConnectionType_.find(static_cast<camera_connection_type_t>(item.data.u8[0]));
119         if (itr != metaToFwConnectionType_.end()) {
120             connectionType_ = itr->second;
121         }
122     }
123 
124     ret = Camera::FindCameraMetadataItem(metadata, OHOS_ABILITY_CAMERA_FOLDSCREEN_TYPE, &item);
125     if (ret == CAM_META_SUCCESS) {
126         auto itr = metaToFwCameraFoldScreenType_.find(static_cast<camera_foldscreen_enum_t>(item.data.u8[0]));
127         if (itr != metaToFwCameraFoldScreenType_.end()) {
128             foldScreenType_ = itr->second;
129         }
130     }
131 
132     ret = OHOS::Camera::FindCameraMetadataItem(metadata, OHOS_SENSOR_ORIENTATION, &item);
133     if (ret == CAM_META_SUCCESS) {
134         cameraOrientation_ = static_cast<uint32_t>(item.data.i32[0]);
135     }
136 
137     uint32_t moduleTypeTagId;
138     if (isFindModuleTypeTag(moduleTypeTagId)) {
139         ret = Camera::FindCameraMetadataItem(metadata, moduleTypeTagId, &item);
140         if (ret == CAM_META_SUCCESS) {
141             moduleType_ = item.data.ui32[0];
142         }
143     }
144 
145     ret = OHOS::Camera::FindCameraMetadataItem(metadata, OHOS_ABILITY_CAMERA_FOLD_STATUS, &item);
146 
147     foldStatus_ = (ret == CAM_META_SUCCESS) ? item.data.u8[0] : OHOS_CAMERA_FOLD_STATUS_NONFOLDABLE;
148 
149     MEDIA_INFO_LOG("camera position: %{public}d, camera type: %{public}d, camera connection type: %{public}d, "
150                    "camera foldScreen type: %{public}d, camera orientation: %{public}d, "
151                    "moduleType: %{public}u, foldStatus: %{public}d", cameraPosition_, cameraType_, connectionType_,
152                    foldScreenType_, cameraOrientation_, moduleType_, foldStatus_);
153 }
154 
GetID()155 std::string CameraDevice::GetID()
156 {
157     return cameraID_;
158 }
159 
GetMetadata()160 std::shared_ptr<Camera::CameraMetadata> CameraDevice::GetMetadata()
161 {
162     std::lock_guard<std::mutex> lock(cachedMetadataMutex_);
163     return cachedMetadata_;
164 }
165 
ResetMetadata()166 void CameraDevice::ResetMetadata()
167 {
168     std::lock_guard<std::mutex> lock(cachedMetadataMutex_);
169     cachedMetadata_ = MetadataCommonUtils::CopyMetadata(baseAbility_);
170 }
171 
GetCameraAbility()172 const std::shared_ptr<OHOS::Camera::CameraMetadata> CameraDevice::GetCameraAbility()
173 {
174     return baseAbility_;
175 }
176 
GetPosition()177 CameraPosition CameraDevice::GetPosition()
178 {
179     uint32_t apiCompatibleVersion = CameraApiVersion::GetApiVersion();
180     if (apiCompatibleVersion < CameraApiVersion::APIVersion::API_FOURTEEN && cameraPosition_ == CAMERA_POSITION_FRONT &&
181         foldScreenType_ == CAMERA_FOLDSCREEN_INNER) {
182         cameraPosition_ = CAMERA_POSITION_FOLD_INNER;
183     }
184     return cameraPosition_;
185 }
186 
GetUsedAsPosition()187 CameraPosition CameraDevice::GetUsedAsPosition()
188 {
189     return usedAsCameraPosition_;
190 }
191 
GetCameraType()192 CameraType CameraDevice::GetCameraType()
193 {
194     return cameraType_;
195 }
196 
GetConnectionType()197 ConnectionType CameraDevice::GetConnectionType()
198 {
199     return connectionType_;
200 }
201 
GetCameraFoldScreenType()202 CameraFoldScreenType CameraDevice::GetCameraFoldScreenType()
203 {
204     return foldScreenType_;
205 }
206 
GetHostName()207 std::string CameraDevice::GetHostName()
208 {
209     return dmDeviceInfo_.deviceName;
210 }
211 
GetDeviceType()212 uint16_t CameraDevice::GetDeviceType()
213 {
214     return dmDeviceInfo_.deviceTypeId;
215 }
216 
GetNetWorkId()217 std::string CameraDevice::GetNetWorkId()
218 {
219     return dmDeviceInfo_.networkId;
220 }
221 
GetCameraOrientation()222 uint32_t CameraDevice::GetCameraOrientation()
223 {
224     return cameraOrientation_;
225 }
226 
GetModuleType()227 uint32_t CameraDevice::GetModuleType()
228 {
229     return moduleType_;
230 }
231 
GetZoomRatioRange()232 std::vector<float> CameraDevice::GetZoomRatioRange()
233 {
234     int32_t minIndex = 0;
235     int32_t maxIndex = 1;
236     std::vector<float> range;
237 
238     if (!zoomRatioRange_.empty()) {
239         return zoomRatioRange_;
240     }
241 
242     int ret;
243     uint32_t zoomRangeCount = 2;
244     camera_metadata_item_t item;
245 
246     ret = Camera::FindCameraMetadataItem(baseAbility_->get(), OHOS_ABILITY_ZOOM_RATIO_RANGE, &item);
247     CHECK_ERROR_RETURN_RET_LOG(ret != CAM_META_SUCCESS, {},
248         "Failed to get zoom ratio range with return code %{public}d", ret);
249     CHECK_ERROR_RETURN_RET_LOG(item.count != zoomRangeCount, {},
250         "Failed to get zoom ratio range with return code %{public}d", ret);
251     range = {item.data.f[minIndex], item.data.f[maxIndex]};
252     CHECK_ERROR_RETURN_RET_LOG(range[minIndex] > range[maxIndex], {},
253         "Invalid zoom range. min: %{public}f, max: %{public}f", range[minIndex], range[maxIndex]);
254     MEDIA_DEBUG_LOG("Zoom range min: %{public}f, max: %{public}f", range[minIndex], range[maxIndex]);
255 
256     zoomRatioRange_ = range;
257     return zoomRatioRange_;
258 }
259 
SetProfile(sptr<CameraOutputCapability> capability)260 void CameraDevice::SetProfile(sptr<CameraOutputCapability> capability)
261 {
262     if (capability == nullptr) {
263         return;
264     }
265     modePreviewProfiles_[NORMAL] = capability->GetPreviewProfiles();
266     modePhotoProfiles_[NORMAL] = capability->GetPhotoProfiles();
267     modeVideoProfiles_[NORMAL] = capability->GetVideoProfiles();
268     modePreviewProfiles_[CAPTURE] = capability->GetPreviewProfiles();
269     modePhotoProfiles_[CAPTURE] = capability->GetPhotoProfiles();
270     modePreviewProfiles_[VIDEO] = capability->GetPreviewProfiles();
271     modePhotoProfiles_[VIDEO] = capability->GetPhotoProfiles();
272     modeVideoProfiles_[VIDEO] = capability->GetVideoProfiles();
273 }
274 
SetProfile(sptr<CameraOutputCapability> capability,int32_t modeName)275 void CameraDevice::SetProfile(sptr<CameraOutputCapability> capability, int32_t modeName)
276 {
277     if (capability == nullptr) {
278         return;
279     }
280     modePreviewProfiles_[modeName] = capability->GetPreviewProfiles();
281     modePhotoProfiles_[modeName] = capability->GetPhotoProfiles();
282     modeVideoProfiles_[modeName] = capability->GetVideoProfiles();
283 }
284 
GetExposureBiasRange()285 std::vector<float> CameraDevice::GetExposureBiasRange()
286 {
287     int32_t minIndex = 0;
288     int32_t maxIndex = 1;
289     std::vector<int32_t> range;
290 
291     if (!exposureBiasRange_.empty()) {
292         return exposureBiasRange_;
293     }
294 
295     int ret;
296     uint32_t biasRangeCount = 2;
297     camera_metadata_item_t item;
298     auto metadata = GetMetadata();
299     ret = Camera::FindCameraMetadataItem(metadata->get(), OHOS_ABILITY_AE_COMPENSATION_RANGE, &item);
300     if (ret != CAM_META_SUCCESS) {
301         MEDIA_ERR_LOG("Failed to get exposure compensation range with return code %{public}d", ret);
302         return {};
303     }
304     CHECK_ERROR_RETURN_RET_LOG(item.count != biasRangeCount, {},
305         "Invalid exposure compensation range count: %{public}d", item.count);
306 
307     range = { item.data.i32[minIndex], item.data.i32[maxIndex] };
308     CHECK_ERROR_RETURN_RET_LOG(range[minIndex] > range[maxIndex], {},
309         "Invalid exposure compensation range. min: %{public}d, max: %{public}d", range[minIndex], range[maxIndex]);
310 
311     MEDIA_DEBUG_LOG("Exposure hdi compensation min: %{public}d, max: %{public}d", range[minIndex], range[maxIndex]);
312     exposureBiasRange_ = { range[minIndex], range[maxIndex] };
313     return exposureBiasRange_;
314 }
315 
SetCameraDeviceUsedAsPosition(CameraPosition usedAsPosition)316 void CameraDevice::SetCameraDeviceUsedAsPosition(CameraPosition usedAsPosition)
317 {
318     MEDIA_INFO_LOG("CameraDevice::SetCameraDeviceUsedAsPosition params: %{public}u", usedAsPosition);
319     usedAsCameraPosition_ = usedAsPosition;
320 }
321 
GetSupportedFoldStatus()322 uint32_t CameraDevice::GetSupportedFoldStatus()
323 {
324     return foldStatus_;
325 }
326 } // namespace CameraStandard
327 } // namespace OHOS
328