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 "mode/night_session_napi.h"
17 
18 #include "napi/native_common.h"
19 #include "uv.h"
20 
21 namespace OHOS {
22 namespace CameraStandard {
23 using namespace std;
24 
25 thread_local napi_ref NightSessionNapi::sConstructor_ = nullptr;
26 
NightSessionNapi()27 NightSessionNapi::NightSessionNapi() : env_(nullptr)
28 {
29 }
~NightSessionNapi()30 NightSessionNapi::~NightSessionNapi()
31 {
32     MEDIA_DEBUG_LOG("~NightSessionNapi is called");
33 }
NightSessionNapiDestructor(napi_env env,void * nativeObject,void * finalize_hint)34 void NightSessionNapi::NightSessionNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint)
35 {
36     MEDIA_DEBUG_LOG("NightSessionNapiDestructor is called");
37     NightSessionNapi* cameraObj = reinterpret_cast<NightSessionNapi*>(nativeObject);
38     if (cameraObj != nullptr) {
39         delete cameraObj;
40     }
41 }
Init(napi_env env,napi_value exports)42 napi_value NightSessionNapi::Init(napi_env env, napi_value exports)
43 {
44     MEDIA_DEBUG_LOG("Init is called");
45     napi_status status;
46     napi_value ctorObj;
47     std::vector<napi_property_descriptor> manual_exposure_props = {
48         DECLARE_NAPI_FUNCTION("getSupportedExposureRange", NightSessionNapi::GetSupportedExposureRange),
49         DECLARE_NAPI_FUNCTION("getExposure", NightSessionNapi::GetExposure),
50         DECLARE_NAPI_FUNCTION("setExposure", NightSessionNapi::SetExposure)
51     };
52     std::vector<std::vector<napi_property_descriptor>> descriptors = {camera_process_props, stabilization_props,
53         flash_props, auto_exposure_props, focus_props, zoom_props, filter_props, beauty_props,
54         color_effect_props, macro_props, color_management_props, manual_exposure_props};
55     std::vector<napi_property_descriptor> night_session_props = CameraNapiUtils::GetPropertyDescriptor(descriptors);
56     status = napi_define_class(env, NIGHT_SESSION_NAPI_CLASS_NAME, NAPI_AUTO_LENGTH,
57                                NightSessionNapiConstructor, nullptr,
58                                night_session_props.size(),
59                                night_session_props.data(), &ctorObj);
60     if (status == napi_ok) {
61         int32_t refCount = 1;
62         status = napi_create_reference(env, ctorObj, refCount, &sConstructor_);
63         if (status == napi_ok) {
64             status = napi_set_named_property(env, exports, NIGHT_SESSION_NAPI_CLASS_NAME, ctorObj);
65             if (status == napi_ok) {
66                 return exports;
67             }
68         }
69     }
70     MEDIA_ERR_LOG("Init call Failed!");
71     return nullptr;
72 }
73 
CreateCameraSession(napi_env env)74 napi_value NightSessionNapi::CreateCameraSession(napi_env env)
75 {
76     MEDIA_DEBUG_LOG("CreateCameraSession is called");
77     CAMERA_SYNC_TRACE;
78     napi_status status;
79     napi_value result = nullptr;
80     napi_value constructor;
81     status = napi_get_reference_value(env, sConstructor_, &constructor);
82     if (status == napi_ok) {
83         sCameraSession_ = CameraManager::GetInstance()->CreateCaptureSession(SceneMode::NIGHT);
84         if (sCameraSession_ == nullptr) {
85             MEDIA_ERR_LOG("Failed to create Camera session instance");
86             napi_get_undefined(env, &result);
87             return result;
88         }
89         status = napi_new_instance(env, constructor, 0, nullptr, &result);
90         sCameraSession_ = nullptr;
91         if (status == napi_ok && result != nullptr) {
92             MEDIA_DEBUG_LOG("success to create Camera session napi instance");
93             return result;
94         } else {
95             MEDIA_ERR_LOG("Failed to create Camera session napi instance");
96         }
97     }
98     MEDIA_ERR_LOG("Failed to create Camera session napi instance last");
99     napi_get_undefined(env, &result);
100     return result;
101 }
102 
GetSupportedExposureRange(napi_env env,napi_callback_info info)103 napi_value NightSessionNapi::GetSupportedExposureRange(napi_env env, napi_callback_info info)
104 {
105     MEDIA_DEBUG_LOG("GetSupportedExposureRange is called");
106     napi_status status;
107     napi_value result = nullptr;
108     size_t argc = ARGS_ZERO;
109     napi_value argv[ARGS_ZERO];
110     napi_value thisVar = nullptr;
111 
112     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
113 
114     napi_get_undefined(env, &result);
115     NightSessionNapi* nightSessionNapi = nullptr;
116     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&nightSessionNapi));
117     if (status == napi_ok && nightSessionNapi != nullptr) {
118         std::vector<uint32_t> vecExposureList;
119         int32_t retCode = nightSessionNapi->nightSession_->GetExposureRange(vecExposureList);
120         if (!CameraNapiUtils::CheckError(env, retCode)) {
121             return nullptr;
122         }
123         if (vecExposureList.empty() || napi_create_array(env, &result) != napi_ok) {
124             return result;
125         }
126         for (size_t i = 0; i < vecExposureList.size(); i++) {
127             uint32_t exposure = vecExposureList[i];
128             MEDIA_DEBUG_LOG("EXPOSURE_RANGE : exposure = %{public}d", vecExposureList[i]);
129             napi_value value;
130             napi_create_uint32(env, exposure, &value);
131             napi_set_element(env, result, i, value);
132         }
133         MEDIA_DEBUG_LOG("EXPOSURE_RANGE ExposureList size : %{public}zu", vecExposureList.size());
134     } else {
135         MEDIA_ERR_LOG("GetExposureBiasRange call Failed!");
136     }
137     return result;
138 }
139 
GetExposure(napi_env env,napi_callback_info info)140 napi_value NightSessionNapi::GetExposure(napi_env env, napi_callback_info info)
141 {
142     MEDIA_DEBUG_LOG("GetExposure is called");
143     napi_status status;
144     napi_value result = nullptr;
145     size_t argc = ARGS_ZERO;
146     napi_value argv[ARGS_ZERO];
147     napi_value thisVar = nullptr;
148 
149     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
150 
151     napi_get_undefined(env, &result);
152     NightSessionNapi* nightSessionNapi = nullptr;
153     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&nightSessionNapi));
154     if (status == napi_ok && nightSessionNapi!= nullptr) {
155         uint32_t exposureValue;
156         int32_t retCode = nightSessionNapi->nightSession_->GetExposure(exposureValue);
157         if (!CameraNapiUtils::CheckError(env, retCode)) {
158             return nullptr;
159         }
160         MEDIA_DEBUG_LOG("GetExposure : exposure = %{public}d", exposureValue);
161         napi_create_uint32(env, exposureValue, &result);
162     } else {
163         MEDIA_ERR_LOG("GetExposure call Failed!");
164     }
165     return result;
166 }
167 
SetExposure(napi_env env,napi_callback_info info)168 napi_value NightSessionNapi::SetExposure(napi_env env, napi_callback_info info)
169 {
170     MEDIA_DEBUG_LOG("SetExposure is called");
171     CAMERA_SYNC_TRACE;
172     napi_status status;
173     napi_value result = nullptr;
174     size_t argc = ARGS_ONE;
175     napi_value argv[ARGS_ONE] = {0};
176     napi_value thisVar = nullptr;
177 
178     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
179 
180     napi_get_undefined(env, &result);
181     NightSessionNapi* nightSessionNapi = nullptr;
182     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&nightSessionNapi));
183     if (status == napi_ok && nightSessionNapi != nullptr) {
184         uint32_t exposureValue;
185         napi_get_value_uint32(env, argv[PARAM0], &exposureValue);
186         MEDIA_DEBUG_LOG("SetExposure : exposure = %{public}d", exposureValue);
187         nightSessionNapi->nightSession_->LockForControl();
188         int32_t retCode = nightSessionNapi->nightSession_->SetExposure(exposureValue);
189         nightSessionNapi->nightSession_->UnlockForControl();
190         if (!CameraNapiUtils::CheckError(env, retCode)) {
191             return result;
192         }
193     } else {
194         MEDIA_ERR_LOG("SetExposure call Failed!");
195     }
196     return result;
197 }
198 
NightSessionNapiConstructor(napi_env env,napi_callback_info info)199 napi_value NightSessionNapi::NightSessionNapiConstructor(napi_env env, napi_callback_info info)
200 {
201     MEDIA_DEBUG_LOG("NightSessionNapiConstructor is called");
202     napi_status status;
203     napi_value result = nullptr;
204     napi_value thisVar = nullptr;
205 
206     napi_get_undefined(env, &result);
207     CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
208 
209     if (status == napi_ok && thisVar != nullptr) {
210         std::unique_ptr<NightSessionNapi> obj = std::make_unique<NightSessionNapi>();
211         obj->env_ = env;
212         if (sCameraSession_ == nullptr) {
213             MEDIA_ERR_LOG("sCameraSession_ is null");
214             return result;
215         }
216         obj->nightSession_ = static_cast<NightSession*>(sCameraSession_.GetRefPtr());
217         obj->cameraSession_ = obj->nightSession_;
218         if (obj->nightSession_ == nullptr) {
219             MEDIA_ERR_LOG("nightSession_ is null");
220             return result;
221         }
222         status = napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()),
223             NightSessionNapi::NightSessionNapiDestructor, nullptr, nullptr);
224         if (status == napi_ok) {
225             obj.release();
226             return thisVar;
227         } else {
228             MEDIA_ERR_LOG("NightSessionNapi Failure wrapping js to native napi");
229         }
230     }
231     MEDIA_ERR_LOG("NightSessionNapi call Failed!");
232     return result;
233 }
234 } // namespace CameraStandard
235 } // namespace OHOS