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 "camera_xcollie.h"
17 #include "input/camera_napi.h"
18 #include "napi/native_common.h"
19 
20 namespace OHOS {
21 namespace CameraStandard {
22 using namespace std;
23 thread_local napi_ref CameraNapi::sConstructor_ = nullptr;
24 thread_local napi_ref g_ignoreRef_ = nullptr;
25 
CameraNapi()26 CameraNapi::CameraNapi() : env_(nullptr)
27 {
28     MEDIA_INFO_LOG("CameraNapi::CameraNapi constructor");
29 }
30 
~CameraNapi()31 CameraNapi::~CameraNapi()
32 {
33     MEDIA_INFO_LOG("CameraNapi::~CameraNapi destructor");
34 }
35 
36 // Constructor callback
CameraNapiConstructor(napi_env env,napi_callback_info info)37 napi_value CameraNapi::CameraNapiConstructor(napi_env env, napi_callback_info info)
38 {
39     MEDIA_DEBUG_LOG("CameraNapiConstructor is called");
40     napi_status status;
41     napi_value result = nullptr;
42     napi_value thisVar = nullptr;
43 
44     napi_get_undefined(env, &result);
45     CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
46 
47     if (status == napi_ok && thisVar != nullptr) {
48         std::unique_ptr<CameraNapi> obj = std::make_unique<CameraNapi>();
49         if (obj != nullptr) {
50             obj->env_ = env;
51             status = napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()),
52                                CameraNapi::CameraNapiDestructor, nullptr, nullptr);
53             if (status == napi_ok) {
54                 (void)obj.release();
55                 return thisVar;
56             } else {
57                 MEDIA_ERR_LOG("CameraNapiConstructor Failure wrapping js to native napi");
58             }
59         }
60     }
61     MEDIA_ERR_LOG("CameraNapiConstructor call Failed!");
62     return result;
63 }
64 
CameraNapiDestructor(napi_env env,void * nativeObject,void * finalize_hint)65 void CameraNapi::CameraNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint)
66 {
67     MEDIA_DEBUG_LOG("CameraNapiDestructor is called");
68     CameraNapi* camera = reinterpret_cast<CameraNapi*>(nativeObject);
69     if (camera != nullptr) {
70         delete camera;
71     }
72 }
73 
Init(napi_env env,napi_value exports)74 napi_value CameraNapi::Init(napi_env env, napi_value exports)
75 {
76     MEDIA_DEBUG_LOG("Init is called");
77     napi_status status;
78     napi_value ctorObj;
79     int32_t refCount = 1;
80     napi_property_descriptor camera_properties[] = {
81         DECLARE_NAPI_FUNCTION("getCameraManagerTest", CreateCameraManagerInstance)
82     };
83 
84     napi_property_descriptor camera_static_prop[] = {
85         DECLARE_NAPI_STATIC_FUNCTION("getCameraManager", CreateCameraManagerInstance),
86         DECLARE_NAPI_STATIC_FUNCTION("getModeManager", CreateModeManagerInstance),
87         DECLARE_NAPI_PROPERTY("FlashMode", CreateObjectWithMap(env, "FlashMode", mapFlashMode, g_ignoreRef_)),
88         DECLARE_NAPI_PROPERTY("ExposureMode", CreateObjectWithMap(env, "ExposureMode", mapExposureMode, g_ignoreRef_)),
89         DECLARE_NAPI_PROPERTY(
90             "ExposureState", CreateObjectWithMap(env, "ExposureState", mapExposureState, g_ignoreRef_)),
91         DECLARE_NAPI_PROPERTY("FocusMode", CreateObjectWithMap(env, "FocusMode", mapFocusMode, g_ignoreRef_)),
92         DECLARE_NAPI_PROPERTY("QualityPrioritization",
93             CreateObjectWithMap(env, "QualityPrioritization", mapQualityPrioritization, g_ignoreRef_)),
94         DECLARE_NAPI_PROPERTY("FocusState", CreateObjectWithMap(env, "FocusState", mapFocusState, g_ignoreRef_)),
95         DECLARE_NAPI_PROPERTY(
96             "CameraPosition", CreateObjectWithMap(env, "CameraPosition", mapCameraPosition, g_ignoreRef_)),
97         DECLARE_NAPI_PROPERTY("CameraType", CreateObjectWithMap(env, "CameraType", mapCameraType, g_ignoreRef_)),
98         DECLARE_NAPI_PROPERTY(
99             "ConnectionType", CreateObjectWithMap(env, "ConnectionType", mapConnectionType, g_ignoreRef_)),
100         DECLARE_NAPI_PROPERTY("CameraFormat", CreateObjectWithMap(env, "CameraFormat", mapCameraFormat, g_ignoreRef_)),
101         DECLARE_NAPI_PROPERTY("CameraStatus", CreateObjectWithMap(env, "CameraStatus", mapCameraStatus, g_ignoreRef_)),
102         DECLARE_NAPI_PROPERTY(
103             "ImageRotation", CreateObjectWithMap(env, "ImageRotation", mapImageRotation, g_ignoreRef_)),
104         DECLARE_NAPI_PROPERTY("QualityLevel", CreateObjectWithMap(env, "QualityLevel", mapQualityLevel, g_ignoreRef_)),
105         DECLARE_NAPI_PROPERTY("VideoStabilizationMode",
106             CreateObjectWithMap(env, "VideoStabilizationMode", mapVideoStabilizationMode, g_ignoreRef_)),
107         DECLARE_NAPI_PROPERTY(
108             "MetadataObjectType", CreateObjectWithMap(env, "MetadataObjectType", mapMetadataObjectType, g_ignoreRef_)),
109         DECLARE_NAPI_PROPERTY("HostNameType", CreateObjectWithMap(env, "HostNameType", mapHostNameType, g_ignoreRef_)),
110         DECLARE_NAPI_PROPERTY("CameraMode", CreateObjectWithMap(env, "SceneMode", mapSceneMode, g_ignoreRef_)),
111         DECLARE_NAPI_PROPERTY("SceneMode", CreateObjectWithMap(env, "SceneMode", mapSceneMode, g_ignoreRef_)),
112         DECLARE_NAPI_PROPERTY(
113             "PreconfigType", CreateObjectWithMap(env, "PreconfigType", mapPreconfigType, g_ignoreRef_)),
114         DECLARE_NAPI_PROPERTY(
115             "PreconfigRatio", CreateObjectWithMap(env, "PreconfigRatio", mapPreconfigRatio, g_ignoreRef_)),
116         DECLARE_NAPI_PROPERTY("FilterType", CreateObjectWithMap(env, "FilterType", mapFilterType, g_ignoreRef_)),
117         DECLARE_NAPI_PROPERTY("BeautyType", CreateObjectWithMap(env, "BeautyType", mapBeautyType, g_ignoreRef_)),
118         DECLARE_NAPI_PROPERTY(
119             "PortraitEffect", CreateObjectWithMap(env, "PortraitEffect", mapPortraitEffect, g_ignoreRef_)),
120         DECLARE_NAPI_PROPERTY("TorchMode", CreateObjectWithMap(env, "TorchMode", mapTorchMode, g_ignoreRef_)),
121         DECLARE_NAPI_PROPERTY(
122             "CameraErrorCode", CreateObjectWithMap(env, "CameraErrorCode", mapCameraErrorCode, g_ignoreRef_)),
123         DECLARE_NAPI_PROPERTY("CameraInputErrorCode",
124             CreateObjectWithMap(env, "CameraInputErrorCode", mapCameraInputErrorCode, g_ignoreRef_)),
125         DECLARE_NAPI_PROPERTY("CaptureSessionErrorCode",
126             CreateObjectWithMap(env, "CaptureSessionErrorCode", mapCaptureSessionErrorCode, g_ignoreRef_)),
127         DECLARE_NAPI_PROPERTY("PreviewOutputErrorCode",
128             CreateObjectWithMap(env, "PreviewOutputErrorCode", mapPreviewOutputErrorCode, g_ignoreRef_)),
129         DECLARE_NAPI_PROPERTY("PhotoOutputErrorCode",
130             CreateObjectWithMap(env, "PhotoOutputErrorCode", mapPhotoOutputErrorCode, g_ignoreRef_)),
131         DECLARE_NAPI_PROPERTY("VideoOutputErrorCode",
132             CreateObjectWithMap(env, "VideoOutputErrorCode", mapVideoOutputErrorCode, g_ignoreRef_)),
133         DECLARE_NAPI_PROPERTY("MetadataOutputErrorCode",
134             CreateObjectWithMap(env, "MetadataOutputErrorCode", mapMetadataOutputErrorCode, g_ignoreRef_)),
135         DECLARE_NAPI_PROPERTY("DeferredDeliveryImageType",
136             CreateObjectWithMap(env, "DeferredDeliveryImageType", mapDeferredDeliveryImageType, g_ignoreRef_)),
137         DECLARE_NAPI_PROPERTY(
138             "SmoothZoomMode", CreateObjectWithMap(env, "SmoothZoomMode", mapSmoothZoomMode, g_ignoreRef_)),
139         DECLARE_NAPI_PROPERTY(
140             "ColorEffectType", CreateObjectWithMap(env, "ColorEffectType", mapColorEffectType, g_ignoreRef_)),
141         DECLARE_NAPI_PROPERTY(
142             "RestoreParamType", CreateObjectWithMap(env, "RestoreParamType", mapRestoreParamType, g_ignoreRef_)),
143         DECLARE_NAPI_PROPERTY("ExposureMeteringMode",
144             CreateObjectWithMap(env, "ExposureMeteringMode", mapExposureMeteringMode, g_ignoreRef_)),
145         DECLARE_NAPI_PROPERTY("EffectSuggestionType",
146             CreateObjectWithMap(env, "EffectSuggestionType", mapEffectSuggestionType, g_ignoreRef_)),
147         DECLARE_NAPI_PROPERTY("VideoMetaType",
148             CreateObjectWithMap(env, "VideoMetaType", mapVideoMetaType, g_ignoreRef_)),
149         DECLARE_NAPI_PROPERTY("PolicyType", CreateObjectWithMap(env, "PolicyType", mapPolicyType, g_ignoreRef_)),
150         DECLARE_NAPI_PROPERTY(
151             "SceneFeatureType", CreateObjectWithMap(env, "SceneFeatureType", mapSceneFeatureType, g_ignoreRef_)),
152         DECLARE_NAPI_PROPERTY("FoldStatus", CreateObjectWithMap(env, "FoldStatus", mapFoldStatus, g_ignoreRef_)),
153         DECLARE_NAPI_PROPERTY(
154             "LightPaintingType", CreateObjectWithMap(env, "LightPaintingType", mapLightPaintingType, g_ignoreRef_)),
155         DECLARE_NAPI_PROPERTY("TimeLapseRecordState",
156             CreateObjectWithMap(env, "TimeLapseRecordState", mapTimeLapseRecordState, g_ignoreRef_)),
157         DECLARE_NAPI_PROPERTY("TimeLapsePreviewType",
158             CreateObjectWithMap(env, "TimeLapsePreviewType", mapTimeLapsePreviewType, g_ignoreRef_)),
159         DECLARE_NAPI_PROPERTY("VideoCodecType",
160             CreateObjectWithMap(env, "VideoCodecType", mapVideoCodecType, g_ignoreRef_)),
161         DECLARE_NAPI_PROPERTY("TripodStatus",
162             CreateObjectWithMap(env, "TripodStatus", mapTripodStatus, g_ignoreRef_)),
163         DECLARE_NAPI_PROPERTY("Emotion",
164             CreateObjectWithMap(env, "Emotion", mapMetaFaceEmotion, g_ignoreRef_)),
165         DECLARE_NAPI_PROPERTY("UsageType", CreateObjectWithMap(env, "UsageType", mapUsageType, g_ignoreRef_)),
166         DECLARE_NAPI_PROPERTY("PortraitThemeType",
167             CreateObjectWithMap(env, "PortraitThemeType", mapPortraitThemeType, g_ignoreRef_)),
168     };
169 
170     status = napi_define_class(env, CAMERA_LIB_NAPI_CLASS_NAME, NAPI_AUTO_LENGTH, CameraNapiConstructor,
171                                nullptr, sizeof(camera_properties) / sizeof(camera_properties[PARAM0]),
172                                camera_properties, &ctorObj);
173     if (status == napi_ok) {
174         if (napi_create_reference(env, ctorObj, refCount, &sConstructor_) == napi_ok) {
175             status = napi_set_named_property(env, exports, CAMERA_LIB_NAPI_CLASS_NAME, ctorObj);
176             if (status == napi_ok && napi_define_properties(env, exports,
177                 sizeof(camera_static_prop) / sizeof(camera_static_prop[PARAM0]), camera_static_prop) == napi_ok) {
178                 return exports;
179             }
180         }
181     }
182     MEDIA_ERR_LOG("Init call Failed!");
183     return nullptr;
184 }
185 
AddNamedProperty(napi_env env,napi_value object,const std::string name,int32_t enumValue)186 napi_status CameraNapi::AddNamedProperty(napi_env env, napi_value object,
187                                          const std::string name, int32_t enumValue)
188 {
189     napi_status status;
190     napi_value enumNapiValue;
191 
192     status = napi_create_int32(env, enumValue, &enumNapiValue);
193     if (status == napi_ok) {
194         status = napi_set_named_property(env, object, name.c_str(), enumNapiValue);
195     }
196 
197     return status;
198 }
199 
CreateCameraManagerInstance(napi_env env,napi_callback_info info)200 napi_value CameraNapi::CreateCameraManagerInstance(napi_env env, napi_callback_info info)
201 {
202     MEDIA_INFO_LOG("CreateCameraManagerInstance is called");
203     napi_value result = nullptr;
204     size_t argc = ARGS_ONE;
205     napi_value argv[ARGS_ONE] = {0};
206     napi_value thisVar = nullptr;
207 
208     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
209 
210     napi_get_undefined(env, &result);
211     result = CameraManagerNapi::CreateCameraManager(env);
212     return result;
213 }
214 
CreateModeManagerInstance(napi_env env,napi_callback_info info)215 napi_value CameraNapi::CreateModeManagerInstance(napi_env env, napi_callback_info info)
216 {
217     MEDIA_INFO_LOG("CreateModeManagerInstance is called");
218     napi_value result = nullptr;
219     size_t argc = ARGS_ONE;
220     napi_value argv[ARGS_ONE] = {0};
221     napi_value thisVar = nullptr;
222 
223     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
224 
225     napi_get_undefined(env, &result);
226     result = ModeManagerNapi::CreateModeManager(env);
227     return result;
228 }
229 
CreateObjectWithMap(napi_env env,const std::string objectName,const std::unordered_map<std::string,int32_t> & inputMap,napi_ref & outputRef)230 napi_value CameraNapi::CreateObjectWithMap(napi_env env,
231                                            const std::string objectName,
232                                            const std::unordered_map<std::string, int32_t>& inputMap,
233                                            napi_ref& outputRef)
234 {
235     MEDIA_DEBUG_LOG("Create %{public}s is called", objectName.c_str());
236     napi_value result = nullptr;
237     napi_status status;
238 
239     status = napi_create_object(env, &result);
240     if (status == napi_ok) {
241         std::string propName;
242         for (auto itr = inputMap.begin(); itr != inputMap.end(); ++itr) {
243             propName = itr->first;
244             status = AddNamedProperty(env, result, propName, itr->second);
245             if (status != napi_ok) {
246                 MEDIA_ERR_LOG("Failed to add %{public}s property!", objectName.c_str());
247                 break;
248             }
249             propName.clear();
250         }
251     }
252     if (status == napi_ok) {
253         status = napi_create_reference(env, result, 1, &outputRef);
254         if (status == napi_ok) {
255             return result;
256         }
257     }
258     MEDIA_ERR_LOG("Create %{public}s call Failed!", objectName.c_str());
259     napi_get_undefined(env, &result);
260 
261     return result;
262 }
263 } // namespace CameraStandard
264 } // namespace OHOS
265