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 #ifndef INTERFACES_KITS_NAPI_GRAPHIC_COMMON_COMMON_H
17 #define INTERFACES_KITS_NAPI_GRAPHIC_COMMON_COMMON_H
18
19 #include <cstdint>
20 #include <node_api.h>
21 #include <node_api_types.h>
22 #include <memory>
23 #include <string>
24
25 #include "js_native_api.h"
26 #include "js_native_api_types.h"
27 #include "window_manager_hilog.h"
28 #include "dm_common.h"
29 #include "napi/native_api.h"
30
31 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, OHOS::Rosen::HILOG_DOMAIN_WINDOW,
32 "NapiWindowManagerCommonLayer" };
33
34 const int PARAM_NUMBER = 2; // 2: callback func input number, also reused by Promise
35
36 #define GNAPI_LOG(fmt, ...) OHOS::HiviewDFX::HiLog::Info(LABEL, \
37 "%{public}s:%{public}d " fmt, __func__, __LINE__, ##__VA_ARGS__)
38
39 #define GNAPI_ASSERT(env, assertion, fmt, ...) \
40 do { \
41 if (assertion) { \
42 GNAPI_LOG(fmt, ##__VA_ARGS__); \
43 return nullptr; \
44 } \
45 } while (0)
46
47 namespace OHOS {
48 napi_status SetMemberInt32(napi_env env, napi_value result, const char *key, int32_t value);
49 napi_status SetMemberUint32(napi_env env, napi_value result, const char *key, uint32_t value);
50 napi_status SetMemberUndefined(napi_env env, napi_value result, const char *key);
51
52 bool CheckCallingPermission(const std::string& permission);
53 void SetErrorInfo(napi_env env, Rosen::DmErrorCode wret, const std::string& errMessage,
54 napi_value result[], int count);
55 void ProcessPromise(napi_env env, Rosen::DmErrorCode wret, napi_deferred deferred,
56 napi_value result[], int count);
57 void ProcessCallback(napi_env env, napi_ref ref, napi_value result[], int count);
58 bool NAPICall(napi_env env, napi_status status);
59
60 template<typename ParamT>
61 struct AsyncCallbackInfo {
62 napi_async_work asyncWork;
63 napi_deferred deferred;
64 void (*async)(napi_env env, std::unique_ptr<ParamT>& param);
65 napi_value (*resolve)(napi_env env, std::unique_ptr<ParamT>& param);
66 std::unique_ptr<ParamT> param;
67 napi_ref ref;
68 };
69
70 template<typename ParamT>
AsyncFunc(napi_env env,void * data)71 void AsyncFunc(napi_env env, void *data)
72 {
73 AsyncCallbackInfo<ParamT> *info = reinterpret_cast<AsyncCallbackInfo<ParamT> *>(data);
74 if (info->async) {
75 info->async(env, info->param);
76 }
77 }
78
79 template<typename ParamT>
CompleteFunc(napi_env env,napi_status status,void * data)80 void CompleteFunc(napi_env env, napi_status status, void *data)
81 {
82 AsyncCallbackInfo<ParamT> *info = reinterpret_cast<AsyncCallbackInfo<ParamT> *>(data);
83 napi_value result[PARAM_NUMBER] = {nullptr};
84 if (info->param->wret == Rosen::DmErrorCode::DM_OK) {
85 napi_get_undefined(env, &result[0]);
86 result[1] = info->resolve(env, info->param);
87 } else {
88 SetErrorInfo(env, info->param->wret, info->param->errMessage, result, PARAM_NUMBER);
89 }
90 if (info->deferred) {
91 ProcessPromise(env, info->param->wret, info->deferred, result, PARAM_NUMBER);
92 } else {
93 ProcessCallback(env, info->ref, result, PARAM_NUMBER);
94 }
95 napi_delete_async_work(env, info->asyncWork);
96 delete info;
97 }
98
99 template<typename ParamT>
CreatePromise(napi_env env,napi_value resourceName,const std::string & funcname,AsyncCallbackInfo<ParamT> * info)100 napi_value CreatePromise(napi_env env, napi_value resourceName,
101 const std::string& funcname, AsyncCallbackInfo<ParamT>* info)
102 {
103 napi_value result = nullptr;
104 if (!NAPICall(env, napi_create_promise(env, &info->deferred, &result))) {
105 return nullptr;
106 }
107 return result;
108 }
109
110 template<typename ParamT>
CreateUndefined(napi_env env,napi_value resourceName,const std::string & funcname,AsyncCallbackInfo<ParamT> * info)111 napi_value CreateUndefined(napi_env env, napi_value resourceName,
112 const std::string& funcname, AsyncCallbackInfo<ParamT>* info)
113 {
114 napi_value result = nullptr;
115 if (!NAPICall(env, napi_get_undefined(env, &result))) {
116 return nullptr;
117 }
118 return result;
119 }
120
121 template<typename ParamT>
AsyncProcess(napi_env env,const std::string & funcname,void (* async)(napi_env env,std::unique_ptr<ParamT> & param),napi_value (* resolve)(napi_env env,std::unique_ptr<ParamT> & param),napi_ref & callbackRef,std::unique_ptr<ParamT> & param)122 napi_value AsyncProcess(napi_env env,
123 const std::string& funcname,
124 void(*async)(napi_env env, std::unique_ptr<ParamT>& param),
125 napi_value(*resolve)(napi_env env, std::unique_ptr<ParamT>& param),
126 napi_ref& callbackRef,
127 std::unique_ptr<ParamT>& param)
128 {
129 AsyncCallbackInfo<ParamT> *info = new AsyncCallbackInfo<ParamT> {
130 .async = async,
131 .resolve = resolve,
132 .param = std::move(param),
133 .ref = callbackRef,
134 };
135
136 napi_value resourceName = nullptr;
137 if (!NAPICall(env, napi_create_string_latin1(env, funcname.c_str(), NAPI_AUTO_LENGTH, &resourceName))) {
138 delete info;
139 if (callbackRef != nullptr) {
140 static_cast<void>(napi_delete_reference(env, callbackRef));
141 }
142 return nullptr;
143 }
144
145 napi_value result = nullptr;
146 if (callbackRef == nullptr) {
147 result = CreatePromise(env, resourceName, funcname, info);
148 } else {
149 result = CreateUndefined(env, resourceName, funcname, info);
150 }
151
152 if (result == nullptr) {
153 delete info;
154 if (callbackRef != nullptr) {
155 static_cast<void>(napi_delete_reference(env, callbackRef));
156 }
157 return nullptr;
158 }
159
160 if (!NAPICall(env, napi_create_async_work(env, nullptr, resourceName, AsyncFunc<ParamT>,
161 CompleteFunc<ParamT>, reinterpret_cast<void *>(info), &info->asyncWork))) {
162 delete info;
163 if (callbackRef != nullptr) {
164 static_cast<void>(napi_delete_reference(env, callbackRef));
165 }
166 return nullptr;
167 }
168 if (!NAPICall(env, napi_queue_async_work_with_qos(env, info->asyncWork, napi_qos_user_initiated))) {
169 delete info;
170 if (callbackRef != nullptr) {
171 static_cast<void>(napi_delete_reference(env, callbackRef));
172 }
173 return nullptr;
174 }
175
176 return result;
177 };
178 } // namespace OHOS
179
180 #endif // INTERFACES_KITS_NAPI_GRAPHIC_COMMON_COMMON_H
181