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