• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "interfaces/napi/kits/utils/napi_utils.h"
17 
18 #include "bridge/common/utils/engine_helper.h"
19 #include "core/components_ng/pattern/overlay/level_order.h"
20 
21 namespace OHOS::Ace::Napi {
ParseFrameNode(napi_env env,napi_callback_info info)22 static NG::FrameNode* ParseFrameNode(napi_env env, napi_callback_info info)
23 {
24     size_t argc = 1;
25     napi_value argv[2] = { nullptr };
26     napi_value thisVar = nullptr;
27     void* data = nullptr;
28     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
29     NAPI_ASSERT(env, argc >= 1, "wrong number of argument\n");
30 
31     napi_value nodePtr = nullptr;
32     NAPI_CALL(env, napi_get_named_property(env, argv[0], "nodePtr_", &nodePtr));
33     napi_valuetype valueType = napi_undefined;
34     napi_typeof(env, nodePtr, &valueType);
35     NG::UINode* uiNode = nullptr;
36     if (valueType == napi_external) {
37         NAPI_CALL(env, napi_get_value_external(env, nodePtr, (void**)&uiNode));
38     }
39     CHECK_NULL_RETURN(uiNode, nullptr);
40     return reinterpret_cast<NG::FrameNode*>(uiNode);
41 }
42 
JSAddFrameNode(napi_env env,napi_callback_info info)43 static napi_value JSAddFrameNode(napi_env env, napi_callback_info info)
44 {
45     NG::FrameNode* frameNode = ParseFrameNode(env, info);
46     CHECK_NULL_RETURN(frameNode, nullptr);
47     size_t argc = 2;
48     napi_value argv[2] = { nullptr };
49     napi_value thisVar = nullptr;
50     void* data = nullptr;
51     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
52     auto delegate = EngineHelper::GetCurrentDelegateSafely();
53     if (!delegate) {
54         NapiThrow(env, "UI execution context not found.", ERROR_CODE_INTERNAL_ERROR);
55         return nullptr;
56     }
57     if (argc == 1) {
58         delegate->AddFrameNodeToOverlay(AceType::Claim(frameNode));
59     } else {
60         napi_valuetype valueType = napi_undefined;
61         napi_typeof(env, argv[1], &valueType);
62         if (valueType == napi_number) {
63             int32_t index = 0;
64             napi_get_value_int32(env, argv[1], &index);
65             delegate->AddFrameNodeToOverlay(AceType::Claim(frameNode), index);
66         } else {
67             NapiThrow(env, "the second paramter is not number.", ERROR_CODE_PARAM_INVALID);
68             return nullptr;
69         }
70     }
71     return nullptr;
72 }
73 
ParseLevelOrder(napi_env env,napi_value value)74 static std::optional<double> ParseLevelOrder(napi_env env, napi_value value)
75 {
76     napi_valuetype valueType = napi_undefined;
77     napi_typeof(env, value, &valueType);
78     if (valueType != napi_object) {
79         return std::nullopt;
80     }
81 
82     NG::LevelOrder* levelOrder = nullptr;
83     napi_status status = napi_unwrap(env, value, reinterpret_cast<void**>(&levelOrder));
84     if (status != napi_ok || !levelOrder) {
85         return std::nullopt;
86     }
87 
88     double order = levelOrder->GetOrder();
89     return std::make_optional(order);
90 }
91 
JSAddFrameNodeWithOrder(napi_env env,napi_callback_info info)92 static napi_value JSAddFrameNodeWithOrder(napi_env env, napi_callback_info info)
93 {
94     NG::FrameNode* frameNode = ParseFrameNode(env, info);
95     CHECK_NULL_RETURN(frameNode, nullptr);
96 
97     auto delegate = EngineHelper::GetCurrentDelegateSafely();
98     if (!delegate) {
99         return nullptr;
100     }
101 
102     size_t argc = 2;
103     napi_value argv[2] = { nullptr };
104     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
105     std::optional<double> levelOrder = std::nullopt;
106     if (argc > 1) {
107         levelOrder = ParseLevelOrder(env, argv[1]);
108     }
109 
110     delegate->AddFrameNodeWithOrder(AceType::Claim(frameNode), levelOrder);
111     return nullptr;
112 }
113 
JSRemoveFrameNode(napi_env env,napi_callback_info info)114 static napi_value JSRemoveFrameNode(napi_env env, napi_callback_info info)
115 {
116     NG::FrameNode* frameNode = ParseFrameNode(env, info);
117     CHECK_NULL_RETURN(frameNode, nullptr);
118     auto delegate = EngineHelper::GetCurrentDelegateSafely();
119     if (!delegate) {
120         NapiThrow(env, "UI execution context not found.", ERROR_CODE_INTERNAL_ERROR);
121         return nullptr;
122     }
123     delegate->RemoveFrameNodeOnOverlay(AceType::Claim(frameNode));
124     return nullptr;
125 }
126 
JSShowNode(napi_env env,napi_callback_info info)127 static napi_value JSShowNode(napi_env env, napi_callback_info info)
128 {
129     NG::FrameNode* frameNode = ParseFrameNode(env, info);
130     CHECK_NULL_RETURN(frameNode, nullptr);
131     auto delegate = EngineHelper::GetCurrentDelegateSafely();
132     if (!delegate) {
133         NapiThrow(env, "UI execution context not found.", ERROR_CODE_INTERNAL_ERROR);
134         return nullptr;
135     }
136     delegate->ShowNodeOnOverlay(AceType::Claim(frameNode));
137     return nullptr;
138 }
139 
JSHideNode(napi_env env,napi_callback_info info)140 static napi_value JSHideNode(napi_env env, napi_callback_info info)
141 {
142     NG::FrameNode* frameNode = ParseFrameNode(env, info);
143     CHECK_NULL_RETURN(frameNode, nullptr);
144     auto delegate = EngineHelper::GetCurrentDelegateSafely();
145     if (!delegate) {
146         NapiThrow(env, "UI execution context not found.", ERROR_CODE_INTERNAL_ERROR);
147         return nullptr;
148     }
149     delegate->HideNodeOnOverlay(AceType::Claim(frameNode));
150     return nullptr;
151 }
152 
JSShowAllFrameNodes(napi_env env,napi_callback_info info)153 static napi_value JSShowAllFrameNodes(napi_env env, napi_callback_info info)
154 {
155     auto delegate = EngineHelper::GetCurrentDelegateSafely();
156     if (!delegate) {
157         NapiThrow(env, "UI execution context not found.", ERROR_CODE_INTERNAL_ERROR);
158         return nullptr;
159     }
160     delegate->ShowAllNodesOnOverlay();
161     return nullptr;
162 }
163 
JSHideAllFrameNodes(napi_env env,napi_callback_info info)164 static napi_value JSHideAllFrameNodes(napi_env env, napi_callback_info info)
165 {
166     auto delegate = EngineHelper::GetCurrentDelegateSafely();
167     if (!delegate) {
168         NapiThrow(env, "UI execution context not found.", ERROR_CODE_INTERNAL_ERROR);
169         return nullptr;
170     }
171     delegate->HideAllNodesOnOverlay();
172     return nullptr;
173 }
174 
JSSetOverlayManagerOptions(napi_env env,napi_callback_info info)175 static napi_value JSSetOverlayManagerOptions(napi_env env, napi_callback_info info)
176 {
177     size_t argc = 1;
178     napi_value argv = nullptr;
179     napi_value thisVar = nullptr;
180     void* data = nullptr;
181     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &argv, &thisVar, &data));
182     NAPI_ASSERT(env, argc >= 1, "wrong number of argument\n");
183 
184     auto overlayInfo = NG::OverlayManagerInfo {
185         .renderRootOverlay = true,
186         .enableBackPressedEvent = false,
187     };
188     napi_value renderRootOverlayNApi = nullptr;
189     napi_value enableBackPressedEventNApi = nullptr;
190     napi_valuetype valueType = napi_undefined;
191     napi_typeof(env, argv, &valueType);
192     if (valueType == napi_object) {
193         napi_get_named_property(env, argv, "renderRootOverlay", &renderRootOverlayNApi);
194         napi_get_named_property(env, argv, "enableBackPressedEvent", &enableBackPressedEventNApi);
195         napi_get_value_bool(env, renderRootOverlayNApi, &overlayInfo.renderRootOverlay);
196         napi_get_value_bool(env, enableBackPressedEventNApi, &overlayInfo.enableBackPressedEvent);
197     } else if (valueType != napi_undefined && valueType != napi_null) {
198         NapiThrow(env, "The type of parameters is incorrect.", ERROR_CODE_PARAM_INVALID);
199         return nullptr;
200     }
201 
202     napi_value result = nullptr;
203     napi_get_boolean(env, false, &result);
204     auto delegate = EngineHelper::GetCurrentDelegateSafely();
205     if (!delegate) {
206         return result;
207     }
208     if (delegate->SetOverlayManagerOptions(overlayInfo)) {
209         napi_get_boolean(env, true, &result);
210         return result;
211     }
212     return result;
213 }
214 
JSGetOverlayManagerOptions(napi_env env,napi_callback_info info)215 static napi_value JSGetOverlayManagerOptions(napi_env env, napi_callback_info info)
216 {
217     napi_value result = nullptr;
218     napi_create_object(env, &result);
219     auto delegate = EngineHelper::GetCurrentDelegateSafely();
220     if (!delegate) {
221         return result;
222     }
223     std::optional<NG::OverlayManagerInfo> options = delegate->GetOverlayManagerOptions();
224     if (options.has_value()) {
225         napi_value renderRootOverlay = nullptr;
226         napi_get_boolean(env, options.value().renderRootOverlay, &renderRootOverlay);
227         napi_set_named_property(env, result, "renderRootOverlay", renderRootOverlay);
228     }
229     return result;
230 }
231 
OverlayManagerExport(napi_env env,napi_value exports)232 static napi_value OverlayManagerExport(napi_env env, napi_value exports)
233 {
234     napi_property_descriptor overlayManagerDesc[] = {
235         DECLARE_NAPI_FUNCTION("addFrameNode", JSAddFrameNode),
236         DECLARE_NAPI_FUNCTION("addFrameNodeWithOrder", JSAddFrameNodeWithOrder),
237         DECLARE_NAPI_FUNCTION("removeFrameNode", JSRemoveFrameNode),
238         DECLARE_NAPI_FUNCTION("showNode", JSShowNode),
239         DECLARE_NAPI_FUNCTION("hideNode", JSHideNode),
240         DECLARE_NAPI_FUNCTION("showAllFrameNodes", JSShowAllFrameNodes),
241         DECLARE_NAPI_FUNCTION("hideAllFrameNodes", JSHideAllFrameNodes),
242         DECLARE_NAPI_FUNCTION("setOverlayManagerOptions", JSSetOverlayManagerOptions),
243         DECLARE_NAPI_FUNCTION("getOverlayManagerOptions", JSGetOverlayManagerOptions)
244     };
245     NAPI_CALL(env, napi_define_properties(
246         env, exports, sizeof(overlayManagerDesc) / sizeof(overlayManagerDesc[0]), overlayManagerDesc));
247     return exports;
248 }
249 
250 static napi_module overlayManagerModule = {
251     .nm_version = 1,
252     .nm_flags = 0,
253     .nm_filename = nullptr,
254     .nm_register_func = OverlayManagerExport,
255     .nm_modname = "overlay",
256     .nm_priv = ((void*)0),
257     .reserved = { 0 },
258 };
259 
OverlayRegister()260 extern "C" __attribute__((constructor)) void OverlayRegister()
261 {
262     napi_module_register(&overlayManagerModule);
263 }
264 } // namespace OHOS::Ace::Napi
265