1 /*
2 * Copyright (C) 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
16 #include "output/depth_data_napi.h"
17
18 #include "camera_log.h"
19 #include "camera_napi_utils.h"
20 #include "camera_util.h"
21 #include "napi/native_common.h"
22
23 namespace OHOS {
24 namespace CameraStandard {
25 namespace {
AsyncCompleteCallback(napi_env env,napi_status status,void * data)26 void AsyncCompleteCallback(napi_env env, napi_status status, void* data)
27 {
28 auto context = static_cast<DepthDataAsyncContext*>(data);
29 CAMERA_FINISH_ASYNC_TRACE(context->funcName, context->taskId);
30 napi_value result = nullptr;
31 napi_get_undefined(env, &result);
32 napi_resolve_deferred(env, context->deferred, result);
33 napi_delete_async_work(env, context->work);
34 delete context->objectInfo;
35 delete context;
36 }
37 } // namespace
38
39 thread_local napi_ref DepthDataNapi::sConstructor_ = nullptr;
40 thread_local napi_value DepthDataNapi::sFormat_ = nullptr;
41 thread_local napi_value DepthDataNapi::sDepthMap_ = nullptr;
42 thread_local napi_value DepthDataNapi::sQualityLevel_ = nullptr;
43 thread_local napi_value DepthDataNapi::sAccuracy_ = nullptr;
44 thread_local uint32_t DepthDataNapi::depthDataTaskId = DEPTH_DATA_TASKID;
45
DepthDataNapi()46 DepthDataNapi::DepthDataNapi() : env_(nullptr), format_(nullptr), depthMap_(nullptr),
47 qualityLevel_(nullptr), accuracy_(nullptr)
48 {}
49
~DepthDataNapi()50 DepthDataNapi::~DepthDataNapi()
51 {
52 MEDIA_DEBUG_LOG("~PhotoNapi is called");
53 }
54
55 // Constructor callback
DepthDataNapiConstructor(napi_env env,napi_callback_info info)56 napi_value DepthDataNapi::DepthDataNapiConstructor(napi_env env, napi_callback_info info)
57 {
58 MEDIA_DEBUG_LOG("DepthDataNapiConstructor is called");
59 napi_status status;
60 napi_value result = nullptr;
61 napi_value thisVar = nullptr;
62
63 napi_get_undefined(env, &result);
64 CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
65
66 if (status == napi_ok && thisVar != nullptr) {
67 std::unique_ptr<DepthDataNapi> obj = std::make_unique<DepthDataNapi>();
68 obj->env_ = env;
69 obj->format_ = sFormat_;
70 obj->depthMap_ = sDepthMap_;
71 obj->qualityLevel_ = sQualityLevel_;
72 obj->accuracy_ = sAccuracy_;
73 status = napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()),
74 DepthDataNapi::DepthDataNapiDestructor, nullptr, nullptr);
75 if (status == napi_ok) {
76 obj.release();
77 return thisVar;
78 } else {
79 MEDIA_ERR_LOG("Failure wrapping js to native napi");
80 }
81 }
82 MEDIA_ERR_LOG("DepthDataNapiConstructor call Failed!");
83 return result;
84 }
85
DepthDataNapiDestructor(napi_env env,void * nativeObject,void * finalize)86 void DepthDataNapi::DepthDataNapiDestructor(napi_env env, void *nativeObject, void *finalize)
87 {
88 MEDIA_DEBUG_LOG("DepthDataNapiDestructor is called");
89 DepthDataNapi* depthData = reinterpret_cast<DepthDataNapi*>(nativeObject);
90 if (depthData != nullptr) {
91 delete depthData;
92 }
93 }
94
Init(napi_env env,napi_value exports)95 napi_value DepthDataNapi::Init(napi_env env, napi_value exports)
96 {
97 MEDIA_DEBUG_LOG("Init is called");
98 napi_status status;
99 napi_value ctorObj;
100 int32_t refCount = PARAM1;
101
102 napi_property_descriptor depth_data_properties[] = {
103 DECLARE_NAPI_GETTER("format", GetFormat),
104 DECLARE_NAPI_GETTER("depthMap", GetDepthMap),
105 DECLARE_NAPI_GETTER("qualityLevel", GetQualityLevel),
106 DECLARE_NAPI_GETTER("dataAccurary", GetAccuracy),
107 DECLARE_NAPI_FUNCTION("release", Release),
108 };
109
110 status = napi_define_class(env, DEPTH_DATA_NAPI_CLASS_NAME, NAPI_AUTO_LENGTH,
111 DepthDataNapiConstructor, nullptr,
112 sizeof(depth_data_properties) / sizeof(depth_data_properties[PARAM0]),
113 depth_data_properties, &ctorObj);
114 if (status == napi_ok) {
115 if (napi_create_reference(env, ctorObj, refCount, &sConstructor_) == napi_ok) {
116 status = napi_set_named_property(env, exports, DEPTH_DATA_NAPI_CLASS_NAME, ctorObj);
117 CHECK_ERROR_RETURN_RET(status == napi_ok, exports);
118 }
119 }
120 MEDIA_ERR_LOG("Init call failed!");
121 return nullptr;
122 }
123
CreateDepthData(napi_env env,napi_value format,napi_value depthMap,napi_value qualityLevel,napi_value accuracy)124 napi_value DepthDataNapi::CreateDepthData(napi_env env, napi_value format, napi_value depthMap,
125 napi_value qualityLevel, napi_value accuracy)
126 {
127 MEDIA_DEBUG_LOG("CreateDepthData is called");
128 CAMERA_SYNC_TRACE;
129 napi_status status;
130 napi_value result = nullptr;
131 napi_value constructor;
132 napi_get_undefined(env, &result);
133
134 status = napi_get_reference_value(env, sConstructor_, &constructor);
135 if (status == napi_ok) {
136 sFormat_ = format;
137 sDepthMap_ = depthMap;
138 sQualityLevel_ = qualityLevel;
139 sAccuracy_ = accuracy;
140 status = napi_new_instance(env, constructor, 0, nullptr, &result);
141 sFormat_ = nullptr;
142 sDepthMap_ = nullptr;
143 sQualityLevel_ = nullptr;
144 sAccuracy_ = nullptr;
145 if (status == napi_ok && result != nullptr) {
146 return result;
147 } else {
148 MEDIA_ERR_LOG("Failed to create depthData obj instance");
149 }
150 }
151 napi_get_undefined(env, &result);
152 MEDIA_ERR_LOG("CreateDepthData call Failed");
153 return result;
154 }
155
GetFormat(napi_env env,napi_callback_info info)156 napi_value DepthDataNapi::GetFormat(napi_env env, napi_callback_info info)
157 {
158 MEDIA_DEBUG_LOG("GetFormat is called");
159 napi_status status;
160 napi_value result = nullptr;
161 size_t argc = ARGS_ZERO;
162 napi_value argv[ARGS_ZERO];
163 napi_value thisVar = nullptr;
164
165 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
166
167 napi_get_undefined(env, &result);
168 DepthDataNapi* depthDataNapi = nullptr;
169 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&depthDataNapi));
170 if (status == napi_ok && depthDataNapi != nullptr) {
171 result = depthDataNapi->format_;
172 return result;
173 }
174 napi_get_undefined(env, &result);
175 MEDIA_ERR_LOG("DepthDataNapi::GetFormat call Failed");
176 return result;
177 }
178
GetDepthMap(napi_env env,napi_callback_info info)179 napi_value DepthDataNapi::GetDepthMap(napi_env env, napi_callback_info info)
180 {
181 MEDIA_DEBUG_LOG("GetDepthMap is called");
182 napi_status status;
183 napi_value result = nullptr;
184 size_t argc = ARGS_ZERO;
185 napi_value argv[ARGS_ZERO];
186 napi_value thisVar = nullptr;
187
188 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
189
190 napi_get_undefined(env, &result);
191 DepthDataNapi* depthDataNapi = nullptr;
192 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&depthDataNapi));
193 if (status == napi_ok && depthDataNapi != nullptr) {
194 result = depthDataNapi->depthMap_;
195 return result;
196 }
197 napi_get_undefined(env, &result);
198 MEDIA_ERR_LOG("DepthDataNapi::GetDepthMap call Failed");
199 return result;
200 }
201
GetQualityLevel(napi_env env,napi_callback_info info)202 napi_value DepthDataNapi::GetQualityLevel(napi_env env, napi_callback_info info)
203 {
204 MEDIA_INFO_LOG("GetQualityLevel is called");
205 napi_status status;
206 napi_value result = nullptr;
207 size_t argc = ARGS_ZERO;
208 napi_value argv[ARGS_ZERO];
209 napi_value thisVar = nullptr;
210
211 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
212
213 napi_get_undefined(env, &result);
214 DepthDataNapi* depthDataNapi = nullptr;
215 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&depthDataNapi));
216 if (status == napi_ok && depthDataNapi != nullptr) {
217 result = depthDataNapi->qualityLevel_;
218 return result;
219 }
220 napi_get_undefined(env, &result);
221 MEDIA_ERR_LOG("DepthDataNapi::GetQualityLevel call Failed");
222 return result;
223 }
224
GetAccuracy(napi_env env,napi_callback_info info)225 napi_value DepthDataNapi::GetAccuracy(napi_env env, napi_callback_info info)
226 {
227 MEDIA_INFO_LOG("GetAccuracy is called");
228 napi_status status;
229 napi_value result = nullptr;
230 size_t argc = ARGS_ZERO;
231 napi_value argv[ARGS_ZERO];
232 napi_value thisVar = nullptr;
233
234 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
235
236 napi_get_undefined(env, &result);
237 DepthDataNapi* depthDataNapi = nullptr;
238 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&depthDataNapi));
239 if (status == napi_ok && depthDataNapi != nullptr) {
240 result = depthDataNapi->accuracy_;
241 return result;
242 }
243 napi_get_undefined(env, &result);
244 MEDIA_ERR_LOG("DepthDataNapi::GetAccuracy call Failed");
245 return result;
246 }
247
Release(napi_env env,napi_callback_info info)248 napi_value DepthDataNapi::Release(napi_env env, napi_callback_info info)
249 {
250 MEDIA_INFO_LOG("Release is called");
251 napi_status status;
252 napi_value result = nullptr;
253 napi_value resource = nullptr;
254 size_t argc = ARGS_ZERO;
255 napi_value argv[ARGS_ZERO];
256 napi_value thisVar = nullptr;
257
258 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
259
260 napi_get_undefined(env, &result);
261 std::unique_ptr<DepthDataAsyncContext> asyncContext = std::make_unique<DepthDataAsyncContext>();
262 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
263 if (status == napi_ok && asyncContext->objectInfo != nullptr) {
264 CAMERA_NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
265 CAMERA_NAPI_CREATE_RESOURCE_NAME(env, resource, "Release");
266
267 status = napi_create_async_work(
268 env, nullptr, resource,
269 [](napi_env env, void* data) {
270 auto context = static_cast<DepthDataAsyncContext*>(data);
271 context->status = false;
272 // Start async trace
273 context->funcName = "DepthDataNapi::Release";
274 context->taskId = CameraNapiUtils::IncrementAndGet(depthDataTaskId);
275 CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
276 if (context->objectInfo != nullptr) {
277 context->status = true;
278 context->objectInfo->format_ = nullptr;
279 context->objectInfo->depthMap_ = nullptr;
280 context->objectInfo->qualityLevel_ = nullptr;
281 context->objectInfo->accuracy_ = nullptr;
282 }
283 },
284 AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
285 if (status != napi_ok) {
286 MEDIA_ERR_LOG("Failed to create napi_create_async_work for DepthDataNapi::Release");
287 napi_get_undefined(env, &result);
288 } else {
289 napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
290 asyncContext.release();
291 }
292 } else {
293 MEDIA_ERR_LOG("Release call Failed!");
294 }
295 return result;
296 }
297
298 } // namespace CameraStandard
299 } // namespace OHOS
300