1 /*
2  * Copyright (c) 2024-2024 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 #include "ability/camera_ability.h"
16 #include "session/capture_session.h"
17 #include "camera_util.h"
18 #include "camera_log.h"
19 
20 namespace OHOS {
21 namespace CameraStandard {
22 
23 constexpr size_t VALID_RANGE_SIZE = 2;
24 
g_isValidZoomRaioRange(std::vector<float> range)25 bool g_isValidZoomRaioRange(std::vector<float> range)
26 {
27     return range.size() == VALID_RANGE_SIZE && range[0] <= range[1];
28 }
29 
HasFlash()30 bool CameraAbility::HasFlash()
31 {
32     bool onlyHasCloseMode = supportedFlashModes_.size() == 1 && supportedFlashModes_[0] == FLASH_MODE_CLOSE;
33     return !supportedFlashModes_.empty() && !onlyHasCloseMode;
34 }
35 
IsFlashModeSupported(FlashMode flashMode)36 bool CameraAbility::IsFlashModeSupported(FlashMode flashMode)
37 {
38     return std::find(
39         supportedFlashModes_.begin(), supportedFlashModes_.end(), flashMode) != supportedFlashModes_.end();
40 }
41 
GetSupportedFlashModes()42 std::vector<FlashMode> CameraAbility::GetSupportedFlashModes()
43 {
44     return supportedFlashModes_;
45 }
46 
IsExposureModeSupported(ExposureMode exposureMode)47 bool CameraAbility::IsExposureModeSupported(ExposureMode exposureMode)
48 {
49     return std::find(
50         supportedExposureModes_.begin(), supportedExposureModes_.end(), exposureMode) != supportedExposureModes_.end();
51 }
52 
GetSupportedExposureModes()53 std::vector<ExposureMode> CameraAbility::GetSupportedExposureModes()
54 {
55     return supportedExposureModes_;
56 }
57 
GetExposureBiasRange()58 std::vector<float> CameraAbility::GetExposureBiasRange()
59 {
60     return exposureBiasRange_;
61 }
62 
GetSupportedFocusModes()63 std::vector<FocusMode> CameraAbility::GetSupportedFocusModes()
64 {
65     return supportedFocusModes_;
66 }
67 
IsFocusModeSupported(FocusMode focusMode)68 bool CameraAbility::IsFocusModeSupported(FocusMode focusMode)
69 {
70     return std::find(supportedFocusModes_.begin(), supportedFocusModes_.end(), focusMode) != supportedFocusModes_.end();
71 }
72 
GetZoomRatioRange()73 std::vector<float> CameraAbility::GetZoomRatioRange()
74 {
75     return zoomRatioRange_.value_or(std::vector<float>{1.0f, 1.0f});
76 }
77 
GetSupportedBeautyTypes()78 std::vector<BeautyType> CameraAbility::GetSupportedBeautyTypes()
79 {
80     return supportedBeautyTypes_;
81 }
82 
GetSupportedBeautyRange(BeautyType beautyType)83 std::vector<int32_t> CameraAbility::GetSupportedBeautyRange(BeautyType beautyType)
84 {
85     auto it = supportedBeautyRangeMap_.find(beautyType);
86     if (it != supportedBeautyRangeMap_.end()) {
87         return it->second;
88     }
89     return {};
90 }
91 
GetSupportedColorEffects()92 std::vector<ColorEffect> CameraAbility::GetSupportedColorEffects()
93 {
94     return supportedColorEffects_;
95 }
96 
GetSupportedColorSpaces()97 std::vector<ColorSpace> CameraAbility::GetSupportedColorSpaces()
98 {
99     return supportedColorSpaces_;
100 }
101 
IsMacroSupported()102 bool CameraAbility::IsMacroSupported()
103 {
104     return isMacroSupported_.value_or(false);
105 }
106 
IsDepthFusionSupported()107 bool CameraAbility::IsDepthFusionSupported()
108 {
109     return isDepthFusionSupported_.value_or(false);
110 }
111 
GetDepthFusionThreshold()112 std::vector<float> CameraAbility::GetDepthFusionThreshold()
113 {
114     return getDepthFusionThreshold_.value_or(std::vector<float>{1.0f, 1.0f});
115 }
116 
GetSupportedPortraitEffects()117 std::vector<PortraitEffect> CameraAbility::GetSupportedPortraitEffects()
118 {
119     return supportedPortraitEffects_;
120 }
121 
GetSupportedVirtualApertures()122 std::vector<float> CameraAbility::GetSupportedVirtualApertures()
123 {
124     return supportedVirtualApertures_;
125 }
126 
GetSupportedPhysicalApertures()127 std::vector<std::vector<float>> CameraAbility::GetSupportedPhysicalApertures()
128 {
129     return supportedPhysicalApertures_;
130 }
131 
GetSupportedStabilizationMode()132 std::vector<VideoStabilizationMode> CameraAbility::GetSupportedStabilizationMode()
133 {
134     return supportedVideoStabilizationMode_;
135 }
136 
IsVideoStabilizationModeSupported(VideoStabilizationMode stabilizationMode)137 bool CameraAbility::IsVideoStabilizationModeSupported(VideoStabilizationMode stabilizationMode)
138 {
139     auto it = std::find(
140         supportedVideoStabilizationMode_.begin(), supportedVideoStabilizationMode_.end(), stabilizationMode);
141     return it != supportedVideoStabilizationMode_.end();
142 }
143 
GetSupportedExposureRange()144 std::vector<uint32_t> CameraAbility::GetSupportedExposureRange()
145 {
146     return supportedExposureRange_;
147 }
148 
IsFeatureSupported(SceneFeature sceneFeature)149 bool CameraAbility::IsFeatureSupported(SceneFeature sceneFeature)
150 {
151     return std::find(
152         supportedSceneFeature_.begin(), supportedSceneFeature_.end(), sceneFeature) != supportedSceneFeature_.end();
153 }
154 
IsLcdFlashSupported()155 bool CameraAbility::IsLcdFlashSupported()
156 {
157     return isLcdFlashSupported_;
158 }
159 
DumpCameraAbilityInfo()160 void CameraAbility::DumpCameraAbilityInfo()
161 {
162     auto logFunc = [](const std::string& label, const auto& container) {
163         std::string vecStr = Container2String(container.begin(), container.end());
164         MEDIA_DEBUG_LOG("%{public}s: %{public}s", label.c_str(), vecStr.c_str());
165     };
166 
167     logFunc("Supported Flash Modes", supportedFlashModes_);
168     logFunc("Supported Exposure Modes", supportedExposureModes_);
169     logFunc("Exposure Bias Range", exposureBiasRange_);
170     logFunc("Supported Focus Modes", supportedFocusModes_);
171     logFunc("Supported Color Effects", supportedColorEffects_);
172     logFunc("Supported Color Spaces", supportedColorSpaces_);
173     logFunc("Supported Portrait Effects", supportedPortraitEffects_);
174     logFunc("Supported Video Stabilization Modes", supportedVideoStabilizationMode_);
175     logFunc("Supported Beauty Types", supportedBeautyTypes_);
176     logFunc("Supported Exposure Range", supportedExposureRange_);
177     logFunc("Supported Scene Feature", supportedSceneFeature_);
178 
179     for (const auto& [type, range] : supportedBeautyRangeMap_) {
180         std::string vecStr = Container2String(range.begin(), range.end());
181         MEDIA_DEBUG_LOG("Beauty Types: %{public}d Supported Beauty Ranges: %{public}s", type, vecStr.c_str());
182     }
183 
184     logFunc("Supported Virtual Apertures", supportedVirtualApertures_);
185 
186     for (const auto& apertureList : supportedPhysicalApertures_) {
187         logFunc("Supported Physical Apertures", apertureList);
188     }
189 
190     if (zoomRatioRange_.has_value()) {
191         logFunc("Zoom Ratio Range", zoomRatioRange_.value());
192     } else {
193         MEDIA_DEBUG_LOG("Zoom Ratio Range: Not supported");
194     }
195 
196     if (isMacroSupported_.has_value()) {
197         MEDIA_DEBUG_LOG("Macro Supported: %{public}d", isMacroSupported_.value());
198     } else {
199         MEDIA_DEBUG_LOG("Macro Supported: Not supported");
200     }
201 
202     if (isDepthFusionSupported_.has_value()) {
203         MEDIA_DEBUG_LOG("Depth Fusion Supported: %{public}d", isDepthFusionSupported_.value());
204     } else {
205         MEDIA_DEBUG_LOG("Depth Fusion Supported: Not supported");
206     }
207 
208     if (getDepthFusionThreshold_.has_value()) {
209         logFunc("Depth Fusion Threshold", getDepthFusionThreshold_.value());
210     } else {
211         MEDIA_DEBUG_LOG("Depth Fusion Threshold: Not supported");
212     }
213 }
214 
~CameraAbilityContainer()215 CameraAbilityContainer::~CameraAbilityContainer()
216 {
217     conflictAbilities_.clear();
218 }
219 
OnAbilityChange()220 void CameraAbilityContainer::OnAbilityChange()
221 {
222     auto session = session_.promote();
223     if (session != nullptr) {
224         MEDIA_DEBUG_LOG("CameraAbilityContainer OnAbilityChange");
225         session->ExecuteAbilityChangeCallback();
226     }
227 }
228 
CameraAbilityContainer(std::vector<sptr<CameraAbility>> abilities,std::vector<sptr<CameraAbility>> conflictAbilities,wptr<CaptureSession> session)229 CameraAbilityContainer::CameraAbilityContainer(std::vector<sptr<CameraAbility>> abilities,
230     std::vector<sptr<CameraAbility>> conflictAbilities, wptr<CaptureSession> session)
231     : session_(session), conflictAbilities_(conflictAbilities)
232 {
233     PrepareSpecMaximumValue(abilities);
234 }
235 
PrepareSpecMaximumValue(std::vector<sptr<CameraAbility>> & abilities)236 void CameraAbilityContainer::PrepareSpecMaximumValue(std::vector<sptr<CameraAbility>>& abilities)
237 {
238     std::optional<std::vector<float>> tempRange;
239 
240     for (const auto& ability : abilities) {
241         if (!ability) {
242             continue;
243         }
244 
245         if (!IsMacroSupportedInSpec_) {
246             IsMacroSupportedInSpec_ = ability->IsMacroSupported();
247         }
248 
249         auto range = ability->GetZoomRatioRange();
250         if (!g_isValidZoomRaioRange(range)) {
251             continue;
252         }
253         if (!tempRange.has_value()) {
254             tempRange = range;
255         } else {
256             float min = std::min(tempRange.value()[0], range[0]);
257             float max = std::max(tempRange.value()[1], range[1]);
258             tempRange = std::vector<float>{min, max};
259         }
260     }
261 
262     zoomRatioRangeInSpec_ = tempRange.value_or(std::vector<float>{1.0, 1.0});
263     abilities.clear();
264 }
265 
FilterByZoomRatio(float zoomRatio)266 void CameraAbilityContainer::FilterByZoomRatio(float zoomRatio)
267 {
268     zoomRatioSet_ = zoomRatio;
269     if (lastIsMacroSupported_.has_value()) {
270         bool oldValue = lastIsMacroSupported_.value();
271         bool newValue = IsMacroSupported();
272         MEDIA_INFO_LOG("CameraAbilityContainer macroValue %{public}d", static_cast<int32_t>(newValue));
273         if (oldValue != newValue) {
274             OnAbilityChange();
275         }
276     }
277 }
278 
FilterByMacro(bool enableMacro)279 void CameraAbilityContainer::FilterByMacro(bool enableMacro)
280 {
281     enableMacroSet_ = enableMacro;
282     if (lastGetZoomRatioRange_.has_value()) {
283         std::vector<float> oldValue = lastGetZoomRatioRange_.value();
284         std::vector<float> newValue = GetZoomRatioRange();
285         MEDIA_INFO_LOG("CameraAbilityContainer zoomValue %{public}f %{public}f", newValue[0], newValue[1]);
286         if (oldValue[0] != newValue[0] || oldValue[1] != newValue[1]) {
287             OnAbilityChange();
288         }
289     }
290 }
291 
GetZoomRatioRange()292 std::vector<float> CameraAbilityContainer::GetZoomRatioRange()
293 {
294     bool enableMacro = enableMacroSet_.value_or(false);
295     if (!g_isValidZoomRaioRange(zoomRatioRangeInSpec_)) {
296         MEDIA_ERR_LOG("zoomRatioRangeInSpec_ invalid data");
297         return std::vector<float>{1.0f, 1.0f};
298     }
299     for (const auto& ability : conflictAbilities_) {
300         if (ability == nullptr) {
301             continue;
302         }
303         std::vector<float> range = ability->GetZoomRatioRange();
304         if (enableMacro == ability->IsMacroSupported() && g_isValidZoomRaioRange(range)) {
305             float min = std::max(zoomRatioRangeInSpec_[0], range[0]);
306             float max = std::min(zoomRatioRangeInSpec_[1], range[1]);
307             lastGetZoomRatioRange_ = {min, max};
308             return {min, max};
309         }
310     }
311     lastGetZoomRatioRange_ = zoomRatioRangeInSpec_;
312     return zoomRatioRangeInSpec_;
313 }
314 
IsMacroSupported()315 bool CameraAbilityContainer::IsMacroSupported()
316 {
317     float zoomRatio = zoomRatioSet_.value_or(1.0f);
318     for (const auto& ability : conflictAbilities_) {
319         if (ability == nullptr) {
320             continue;
321         }
322         std::vector<float> range = ability->GetZoomRatioRange();
323         if (g_isValidZoomRaioRange(range) && ability->IsMacroSupported()) {
324             bool isSupport = IsMacroSupportedInSpec_ && (range[0] <= zoomRatio && zoomRatio <= range[1]);
325             lastIsMacroSupported_ = isSupport;
326             return isSupport;
327         }
328     }
329     lastIsMacroSupported_ = IsMacroSupportedInSpec_;
330     return IsMacroSupportedInSpec_;
331 }
332 } // namespace CameraStandard
333 } // namespace OHOS