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 "input/camera_profile_napi.h"
17 #include "input/camera_size_napi.h"
18
19 namespace OHOS {
20 namespace CameraStandard {
21 using OHOS::HiviewDFX::HiLog;
22 using OHOS::HiviewDFX::HiLogLabel;
23
24 thread_local napi_ref CameraProfileNapi::sConstructor_ = nullptr;
25 thread_local Profile* CameraProfileNapi::sCameraProfile_ = nullptr;
26
CameraProfileNapi()27 CameraProfileNapi::CameraProfileNapi() : env_(nullptr), wrapper_(nullptr)
28 {
29 }
30
~CameraProfileNapi()31 CameraProfileNapi::~CameraProfileNapi()
32 {
33 if (wrapper_ != nullptr) {
34 napi_delete_reference(env_, wrapper_);
35 }
36 if (cameraProfile_) {
37 cameraProfile_ = nullptr;
38 }
39 }
40
CameraProfileNapiDestructor(napi_env env,void * nativeObject,void * finalize_hint)41 void CameraProfileNapi::CameraProfileNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint)
42 {
43 MEDIA_DEBUG_LOG("CameraProfileNapiDestructor enter");
44 CameraProfileNapi* cameraProfileNapi = reinterpret_cast<CameraProfileNapi*>(nativeObject);
45 if (cameraProfileNapi != nullptr) {
46 MEDIA_INFO_LOG("CameraProfileNapi::CameraProfileNapiDestructor ~");
47 delete cameraProfileNapi;
48 }
49 }
50
Init(napi_env env,napi_value exports)51 napi_value CameraProfileNapi::Init(napi_env env, napi_value exports)
52 {
53 napi_status status;
54 napi_value ctorObj;
55 napi_property_descriptor camera_profile_props[] = {
56 DECLARE_NAPI_GETTER("format", GetCameraProfileFormat),
57 DECLARE_NAPI_GETTER("size", GetCameraProfileSize)
58 };
59 status = napi_define_class(env, CAMERA_PROFILE_NAPI_CLASS_NAME, NAPI_AUTO_LENGTH,
60 CameraProfileNapiConstructor, nullptr,
61 sizeof(camera_profile_props) / sizeof(camera_profile_props[PARAM0]),
62 camera_profile_props, &ctorObj);
63 if (status == napi_ok) {
64 int32_t refCount = 1;
65 status = napi_create_reference(env, ctorObj, refCount, &sConstructor_);
66 if (status == napi_ok) {
67 status = napi_set_named_property(env, exports, CAMERA_PROFILE_NAPI_CLASS_NAME, ctorObj);
68 if (status == napi_ok) {
69 return exports;
70 }
71 }
72 }
73 return nullptr;
74 }
75
76 // Constructor callback
CameraProfileNapiConstructor(napi_env env,napi_callback_info info)77 napi_value CameraProfileNapi::CameraProfileNapiConstructor(napi_env env, napi_callback_info info)
78 {
79 napi_status status;
80 napi_value result = nullptr;
81 napi_value thisVar = nullptr;
82
83 napi_get_undefined(env, &result);
84 CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
85
86 if (status == napi_ok && thisVar != nullptr) {
87 std::unique_ptr<CameraProfileNapi> obj = std::make_unique<CameraProfileNapi>();
88 obj->env_ = env;
89 obj->cameraProfile_ = sCameraProfile_;
90 MEDIA_INFO_LOG("CameraProfileNapi::CameraProfileNapiConstructor "
91 "size.width = %{public}d, size.height = %{public}d, "
92 "format = %{public}d",
93 obj->cameraProfile_->GetSize().width,
94 obj->cameraProfile_->GetSize().height,
95 obj->cameraProfile_->format_);
96 status = napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()),
97 CameraProfileNapi::CameraProfileNapiDestructor, nullptr, nullptr);
98 if (status == napi_ok) {
99 obj.release();
100 return thisVar;
101 } else {
102 MEDIA_ERR_LOG("Failure wrapping js to native napi");
103 }
104 }
105 return result;
106 }
107
CreateCameraProfile(napi_env env,Profile & profile)108 napi_value CameraProfileNapi::CreateCameraProfile(napi_env env, Profile &profile)
109 {
110 napi_status status;
111 napi_value result = nullptr;
112 napi_value constructor;
113
114 status = napi_get_reference_value(env, sConstructor_, &constructor);
115 if (status == napi_ok) {
116 CameraFormat format = profile.GetCameraFormat();
117 Size size = profile.GetSize();
118 MEDIA_INFO_LOG("CameraProfileNapi::CreateCameraProfile size.width = %{public}d, size.height = %{public}d",
119 size.width, size.height);
120 std::unique_ptr<Profile> profilePtr = std::make_unique<Profile>(format, size);
121 sCameraProfile_ = reinterpret_cast<Profile*>(profilePtr.get());
122 MEDIA_INFO_LOG("CameraProfileNapi::CreateCameraProfile sCameraProfile_ "
123 "size.width = %{public}d, size.height = %{public}d, format = %{public}d",
124 sCameraProfile_->GetSize().width, sCameraProfile_->GetSize().height, sCameraProfile_->format_);
125 status = napi_new_instance(env, constructor, 0, nullptr, &result);
126 if (status == napi_ok && result != nullptr) {
127 MEDIA_INFO_LOG("GetCameraProfileSize CreateCameraProfile napi_new_instance success");
128 return result;
129 } else {
130 MEDIA_ERR_LOG("Failed to create Camera obj instance");
131 }
132 }
133
134 napi_get_undefined(env, &result);
135 return result;
136 }
137
GetCameraProfileSize(napi_env env,napi_callback_info info)138 napi_value CameraProfileNapi::GetCameraProfileSize(napi_env env, napi_callback_info info)
139 {
140 napi_status status;
141 napi_value jsResult = nullptr;
142 napi_value undefinedResult = nullptr;
143 CameraProfileNapi* obj = nullptr;
144 Size cameraProfileSize;
145 napi_value thisVar = nullptr;
146
147 napi_get_undefined(env, &undefinedResult);
148 CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
149
150 MEDIA_INFO_LOG("GetCameraProfileSize cameraProfileSize thisVar");
151 if (status != napi_ok || thisVar == nullptr) {
152 MEDIA_ERR_LOG("Invalid arguments!");
153 return undefinedResult;
154 }
155
156 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
157 if ((status == napi_ok) && (obj != nullptr)) {
158 cameraProfileSize.height = obj->cameraProfile_->GetSize().height;
159 cameraProfileSize.width = obj->cameraProfile_->GetSize().width;
160 MEDIA_INFO_LOG("GetCameraProfileSize cameraProfileSize "
161 "size.width = %{public}d, size.height = %{public}d",
162 cameraProfileSize.width, cameraProfileSize.height);
163 jsResult = CameraSizeNapi::CreateCameraSize(env, cameraProfileSize);
164 return jsResult;
165 }
166
167 return undefinedResult;
168 }
169
GetCameraProfileFormat(napi_env env,napi_callback_info info)170 napi_value CameraProfileNapi::GetCameraProfileFormat(napi_env env, napi_callback_info info)
171 {
172 napi_status status;
173 napi_value jsResult = nullptr;
174 napi_value undefinedResult = nullptr;
175 CameraProfileNapi* obj = nullptr;
176 CameraFormat cameraProfileFormat;
177 napi_value thisVar = nullptr;
178
179 napi_get_undefined(env, &undefinedResult);
180 CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
181 MEDIA_INFO_LOG("GetCameraProfileSize cameraProfileSize thisVar");
182 if (status != napi_ok || thisVar == nullptr) {
183 MEDIA_ERR_LOG("Invalid arguments!");
184 return undefinedResult;
185 }
186
187 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
188 if ((status == napi_ok) && (obj != nullptr)) {
189 cameraProfileFormat = obj->cameraProfile_->GetCameraFormat();
190 MEDIA_INFO_LOG("GetCameraProfileFormat cameraProfileSize "
191 "size.width = %{public}d, size.height = %{public}d, format = %{public}d",
192 obj->cameraProfile_->size_.width,
193 obj->cameraProfile_->size_.height,
194 static_cast<int>(cameraProfileFormat));
195 status = napi_create_int32(env, static_cast<int>(cameraProfileFormat), &jsResult);
196 if (status == napi_ok) {
197 return jsResult;
198 } else {
199 MEDIA_ERR_LOG("Failed to get CameraProfileFormat!, errorCode : %{public}d", status);
200 }
201 }
202
203 return undefinedResult;
204 }
205
206 thread_local napi_ref CameraVideoProfileNapi::sVideoConstructor_ = nullptr;
207 thread_local VideoProfile CameraVideoProfileNapi::sVideoProfile_;
208
CameraVideoProfileNapi()209 CameraVideoProfileNapi::CameraVideoProfileNapi() : env_(nullptr), wrapper_(nullptr) {}
210
~CameraVideoProfileNapi()211 CameraVideoProfileNapi::~CameraVideoProfileNapi()
212 {
213 if (wrapper_ != nullptr) {
214 napi_delete_reference(env_, wrapper_);
215 }
216 }
217
CameraVideoProfileNapiDestructor(napi_env env,void * nativeObject,void * finalize_hint)218 void CameraVideoProfileNapi::CameraVideoProfileNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint)
219 {
220 CameraVideoProfileNapi* cameraVideoProfileNapi = reinterpret_cast<CameraVideoProfileNapi*>(nativeObject);
221 if (cameraVideoProfileNapi != nullptr) {
222 delete cameraVideoProfileNapi;
223 }
224 }
225
Init(napi_env env,napi_value exports)226 napi_value CameraVideoProfileNapi::Init(napi_env env, napi_value exports)
227 {
228 napi_status status;
229 napi_value ctorObj;
230
231 napi_property_descriptor camera_video_profile_props[] = {
232 DECLARE_NAPI_GETTER("format", CameraVideoProfileNapi::GetCameraProfileFormat),
233 DECLARE_NAPI_GETTER("size", CameraVideoProfileNapi::GetCameraProfileSize),
234 DECLARE_NAPI_GETTER("frameRateRange", GetFrameRateRange)
235 };
236
237 status = napi_define_class(env, CAMERA_VIDEO_PROFILE_NAPI_CLASS_NAME, NAPI_AUTO_LENGTH,
238 CameraVideoProfileNapiConstructor, nullptr,
239 sizeof(camera_video_profile_props) / sizeof(camera_video_profile_props[PARAM0]),
240 camera_video_profile_props, &ctorObj);
241 if (status == napi_ok) {
242 int32_t refCount = 1;
243 status = napi_create_reference(env, ctorObj, refCount, &sVideoConstructor_);
244 if (status == napi_ok) {
245 status = napi_set_named_property(env, exports, CAMERA_VIDEO_PROFILE_NAPI_CLASS_NAME, ctorObj);
246 if (status == napi_ok) {
247 return exports;
248 }
249 }
250 }
251
252 return nullptr;
253 }
254
255 // Constructor callback
CameraVideoProfileNapiConstructor(napi_env env,napi_callback_info info)256 napi_value CameraVideoProfileNapi::CameraVideoProfileNapiConstructor(napi_env env, napi_callback_info info)
257 {
258 napi_status status;
259 napi_value result = nullptr;
260 napi_value thisVar = nullptr;
261
262 napi_get_undefined(env, &result);
263 CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
264
265 if (status == napi_ok && thisVar != nullptr) {
266 std::unique_ptr<CameraVideoProfileNapi> obj = std::make_unique<CameraVideoProfileNapi>();
267 obj->env_ = env;
268 obj->videoProfile_ = sVideoProfile_;
269 status = napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()),
270 CameraVideoProfileNapi::CameraVideoProfileNapiDestructor, nullptr, &(obj->wrapper_));
271 if (status == napi_ok) {
272 obj.release();
273 return thisVar;
274 } else {
275 MEDIA_ERR_LOG("Failure wrapping js to native napi");
276 }
277 }
278
279 return result;
280 }
281
CreateCameraVideoProfile(napi_env env,VideoProfile & profile)282 napi_value CameraVideoProfileNapi::CreateCameraVideoProfile(napi_env env, VideoProfile &profile)
283 {
284 napi_status status;
285 napi_value result = nullptr;
286 napi_value constructor;
287
288 status = napi_get_reference_value(env, sVideoConstructor_, &constructor);
289 if (status == napi_ok) {
290 sVideoProfile_ = profile;
291 status = napi_new_instance(env, constructor, 0, nullptr, &result);
292 if (status == napi_ok && result != nullptr) {
293 return result;
294 } else {
295 MEDIA_ERR_LOG("Failed to create Camera obj instance");
296 }
297 }
298
299 napi_get_undefined(env, &result);
300 return result;
301 }
302
GetCameraProfileSize(napi_env env,napi_callback_info info)303 napi_value CameraVideoProfileNapi::GetCameraProfileSize(napi_env env, napi_callback_info info)
304 {
305 napi_status status;
306 napi_value jsResult = nullptr;
307 napi_value undefinedResult = nullptr;
308 CameraVideoProfileNapi* obj = nullptr;
309 Size cameraProfileSize;
310 napi_value thisVar = nullptr;
311
312 napi_get_undefined(env, &undefinedResult);
313 CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
314
315 if (status != napi_ok || thisVar == nullptr) {
316 MEDIA_ERR_LOG("Invalid arguments!");
317 return undefinedResult;
318 }
319
320 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
321 if ((status == napi_ok) && (obj != nullptr)) {
322 cameraProfileSize.width = obj->videoProfile_.GetSize().width;
323 cameraProfileSize.height = obj->videoProfile_.GetSize().height;
324 jsResult = CameraSizeNapi::CreateCameraSize(env, cameraProfileSize);
325 return jsResult;
326 }
327
328 return undefinedResult;
329 }
330
GetCameraProfileFormat(napi_env env,napi_callback_info info)331 napi_value CameraVideoProfileNapi::GetCameraProfileFormat(napi_env env, napi_callback_info info)
332 {
333 napi_status status;
334 napi_value jsResult = nullptr;
335 napi_value undefinedResult = nullptr;
336 CameraVideoProfileNapi* obj = nullptr;
337 CameraFormat CameraProfileFormat;
338 napi_value thisVar = nullptr;
339
340 napi_get_undefined(env, &undefinedResult);
341 CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
342
343 if (status != napi_ok || thisVar == nullptr) {
344 MEDIA_ERR_LOG("Invalid arguments!");
345 return undefinedResult;
346 }
347
348 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
349 if ((status == napi_ok) && (obj != nullptr)) {
350 CameraProfileFormat = obj->videoProfile_.GetCameraFormat();
351 status = napi_create_int32(env, CameraProfileFormat, &jsResult);
352 if (status == napi_ok) {
353 return jsResult;
354 } else {
355 MEDIA_ERR_LOG("Failed to get CameraProfileHeight!, errorCode : %{public}d", status);
356 }
357 }
358
359 return undefinedResult;
360 }
361
CreateJSArray(napi_env env,napi_status status,std::vector<int32_t> nativeArray)362 static napi_value CreateJSArray(napi_env env, napi_status status,
363 std::vector<int32_t> nativeArray)
364 {
365 napi_value jsArray = nullptr;
366 napi_value item = nullptr;
367
368 if (nativeArray.empty()) {
369 MEDIA_ERR_LOG("nativeArray is empty");
370 return jsArray;
371 }
372
373 status = napi_create_array(env, &jsArray);
374 if (status == napi_ok) {
375 for (size_t i = 0; i < nativeArray.size(); i++) {
376 napi_create_int32(env, nativeArray[i], &item);
377 MEDIA_INFO_LOG("CreateJSArray CreateCameraProfile success");
378 if (napi_set_element(env, jsArray, i, item) != napi_ok) {
379 MEDIA_ERR_LOG("Failed to create profile napi wrapper object");
380 return nullptr;
381 }
382 }
383 }
384 return jsArray;
385 }
386
387 // todo: should to using CreateFrameRateRange in CreateJSArray
GetFrameRateRange(napi_env env,napi_callback_info info)388 napi_value CameraVideoProfileNapi::GetFrameRateRange(napi_env env, napi_callback_info info)
389 {
390 napi_status status;
391 napi_value jsResult = nullptr;
392 napi_value undefinedResult = nullptr;
393 CameraVideoProfileNapi* obj = nullptr;
394 napi_value thisVar = nullptr;
395
396 napi_get_undefined(env, &undefinedResult);
397 CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
398
399 if (status != napi_ok || thisVar == nullptr) {
400 MEDIA_ERR_LOG("Invalid arguments!");
401 return undefinedResult;
402 }
403
404 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
405 if ((status == napi_ok) && (obj != nullptr)) {
406 std::vector<int32_t> frameRanges = obj->videoProfile_.GetFrameRates();
407 jsResult = CreateJSArray(env, status, frameRanges);
408 if (status == napi_ok) {
409 MEDIA_ERR_LOG("GetFrameRateRange success ");
410 return jsResult;
411 } else {
412 MEDIA_ERR_LOG("Failed to get FrameRateRanges!, errorCode : %{public}d", status);
413 }
414 }
415 return undefinedResult;
416 }
417 } // namespace CameraStandard
418 } // namespace OHOS
419