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
30 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, OHOS::Rosen::HILOG_DOMAIN_WINDOW,
31 "NapiWindowManagerCommonLayer" };
32
33 const int PARAM_NUMBER = 2; // 2: callback func input number, also reused by Promise
34
35 #define GNAPI_LOG(fmt, ...) OHOS::HiviewDFX::HiLog::Info(LABEL, \
36 "%{public}s:%{public}d " fmt, __func__, __LINE__, ##__VA_ARGS__)
37
38 #define GNAPI_ASSERT(env, assertion, fmt, ...) \
39 do { \
40 if (assertion) { \
41 GNAPI_LOG(fmt, ##__VA_ARGS__); \
42 return nullptr; \
43 } \
44 } while (0)
45
46 #define GNAPI_INNER(call) \
47 do { \
48 napi_status s = (call); \
49 if (s != napi_ok) { \
50 GNAPI_LOG(#call " is %{public}d", s); \
51 return s; \
52 } \
53 } while (0)
54
55 namespace OHOS {
56 napi_status SetMemberInt32(napi_env env, napi_value result, const char *key, int32_t value);
57 napi_status SetMemberUint32(napi_env env, napi_value result, const char *key, uint32_t value);
58 napi_status SetMemberUndefined(napi_env env, napi_value result, const char *key);
59
60 bool CheckCallingPermission(const std::string& permission);
61 void SetErrorInfo(napi_env env, Rosen::DmErrorCode wret, const std::string& errMessage,
62 napi_value result[], int count);
63 void ProcessPromise(napi_env env, Rosen::DmErrorCode wret, napi_deferred deferred,
64 napi_value result[], int count);
65 void ProcessCallback(napi_env env, napi_ref ref, napi_value result[], int count);
66 bool NAPICall(napi_env env, napi_status status);
67
68 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)69 napi_value AsyncProcess(napi_env env,
70 const std::string& funcname,
71 void(*async)(napi_env env, std::unique_ptr<ParamT>& param),
72 napi_value(*resolve)(napi_env env, std::unique_ptr<ParamT>& param),
73 napi_ref& callbackRef,
74 std::unique_ptr<ParamT>& param)
75 {
76 struct AsyncCallbackInfo {
77 napi_async_work asyncWork;
78 napi_deferred deferred;
79 void (*async)(napi_env env, std::unique_ptr<ParamT>& param);
80 napi_value (*resolve)(napi_env env, std::unique_ptr<ParamT>& param);
81 std::unique_ptr<ParamT> param;
82 napi_ref ref;
83 };
84
85 AsyncCallbackInfo *info = new AsyncCallbackInfo {
86 .async = async,
87 .resolve = resolve,
88 .param = std::move(param),
89 .ref = callbackRef,
90 };
91
92 napi_value resourceName = nullptr;
93 if (!NAPICall(env, napi_create_string_latin1(env, funcname.c_str(), NAPI_AUTO_LENGTH, &resourceName))) {
94 delete info;
95 return nullptr;
96 }
97
98 // decide use promise or callback
99 napi_value result = nullptr;
100 if (info->ref == nullptr) {
101 if (!NAPICall(env, napi_create_promise(env, &info->deferred, &result))) {
102 delete info;
103 return nullptr;
104 }
105 } else {
106 if (!NAPICall(env, napi_get_undefined(env, &result))) {
107 delete info;
108 return nullptr;
109 }
110 }
111
112 auto asyncFunc = [](napi_env env, void *data) {
113 AsyncCallbackInfo *info = reinterpret_cast<AsyncCallbackInfo *>(data);
114 if (info->async) {
115 info->async(env, info->param);
116 }
117 };
118
119 auto completeFunc = [](napi_env env, napi_status status, void *data) {
120 AsyncCallbackInfo *info = reinterpret_cast<AsyncCallbackInfo *>(data);
121 napi_value result[PARAM_NUMBER] = {nullptr};
122 if (info->param->wret == Rosen::DmErrorCode::DM_OK) {
123 napi_get_undefined(env, &result[0]);
124 result[1] = info->resolve(env, info->param);
125 } else {
126 SetErrorInfo(env, info->param->wret, info->param->errMessage, result, PARAM_NUMBER);
127 }
128 if (info->deferred) {
129 ProcessPromise(env, info->param->wret, info->deferred, result, PARAM_NUMBER);
130 } else {
131 ProcessCallback(env, info->ref, result, PARAM_NUMBER);
132 }
133 napi_delete_async_work(env, info->asyncWork);
134 delete info;
135 };
136 if (!NAPICall(env, napi_create_async_work(env, nullptr, resourceName, asyncFunc,
137 completeFunc, reinterpret_cast<void *>(info), &info->asyncWork))) {
138 delete info;
139 return nullptr;
140 }
141 if (!NAPICall(env, napi_queue_async_work(env, info->asyncWork))) {
142 delete info;
143 return nullptr;
144 }
145
146 return result;
147 };
148 } // namespace OHOS
149
150 #endif // INTERFACES_KITS_NAPI_GRAPHIC_COMMON_COMMON_H
151