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 
20 namespace OHOS::Ace::Napi {
ParseFrameNode(napi_env env, napi_callback_info info)21 static NG::FrameNode* ParseFrameNode(napi_env env, napi_callback_info info)
22 {
23     size_t argc = 1;
24     napi_value argv[2] = { nullptr };
25     napi_value thisVar = nullptr;
26     void* data = nullptr;
27     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
28     NAPI_ASSERT(env, argc >= 1, "wrong number of argument\n");
29 
30     napi_value nodePtr = nullptr;
31     NAPI_CALL(env, napi_get_named_property(env, argv[0], "nodePtr_", &nodePtr));
32     napi_valuetype valueType = napi_undefined;
33     napi_typeof(env, nodePtr, &valueType);
34     NG::UINode* uiNode = nullptr;
35     if (valueType == napi_external) {
36         NAPI_CALL(env, napi_get_value_external(env, nodePtr, (void**)&uiNode));
37     }
38     CHECK_NULL_RETURN(uiNode, nullptr);
39     return reinterpret_cast<NG::FrameNode*>(uiNode);
40 }
41 
JSAddFrameNode(napi_env env, napi_callback_info info)42 static napi_value JSAddFrameNode(napi_env env, napi_callback_info info)
43 {
44     NG::FrameNode* frameNode = ParseFrameNode(env, info);
45     CHECK_NULL_RETURN(frameNode, nullptr);
46     size_t argc = 2;
47     napi_value argv[2] = { nullptr };
48     napi_value thisVar = nullptr;
49     void* data = nullptr;
50     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
51     auto delegate = EngineHelper::GetCurrentDelegateSafely();
52     if (!delegate) {
53         NapiThrow(env, "UI execution context not found.", ERROR_CODE_INTERNAL_ERROR);
54         return nullptr;
55     }
56     if (argc == 1) {
57         delegate->AddFrameNodeToOverlay(AceType::Claim(frameNode));
58     } else {
59         napi_valuetype valueType = napi_undefined;
60         napi_typeof(env, argv[1], &valueType);
61         if (valueType == napi_number) {
62             int32_t index = 0;
63             napi_get_value_int32(env, argv[1], &index);
64             delegate->AddFrameNodeToOverlay(AceType::Claim(frameNode), index);
65         } else {
66             NapiThrow(env, "the second paramter is not number.", ERROR_CODE_PARAM_INVALID);
67             return nullptr;
68         }
69     }
70     return nullptr;
71 }
72 
JSRemoveFrameNode(napi_env env, napi_callback_info info)73 static napi_value JSRemoveFrameNode(napi_env env, napi_callback_info info)
74 {
75     NG::FrameNode* frameNode = ParseFrameNode(env, info);
76     CHECK_NULL_RETURN(frameNode, nullptr);
77     auto delegate = EngineHelper::GetCurrentDelegateSafely();
78     if (!delegate) {
79         NapiThrow(env, "UI execution context not found.", ERROR_CODE_INTERNAL_ERROR);
80         return nullptr;
81     }
82     delegate->RemoveFrameNodeOnOverlay(AceType::Claim(frameNode));
83     return nullptr;
84 }
85 
JSShowNode(napi_env env, napi_callback_info info)86 static napi_value JSShowNode(napi_env env, napi_callback_info info)
87 {
88     NG::FrameNode* frameNode = ParseFrameNode(env, info);
89     CHECK_NULL_RETURN(frameNode, nullptr);
90     auto delegate = EngineHelper::GetCurrentDelegateSafely();
91     if (!delegate) {
92         NapiThrow(env, "UI execution context not found.", ERROR_CODE_INTERNAL_ERROR);
93         return nullptr;
94     }
95     delegate->ShowNodeOnOverlay(AceType::Claim(frameNode));
96     return nullptr;
97 }
98 
JSHideNode(napi_env env, napi_callback_info info)99 static napi_value JSHideNode(napi_env env, napi_callback_info info)
100 {
101     NG::FrameNode* frameNode = ParseFrameNode(env, info);
102     CHECK_NULL_RETURN(frameNode, nullptr);
103     auto delegate = EngineHelper::GetCurrentDelegateSafely();
104     if (!delegate) {
105         NapiThrow(env, "UI execution context not found.", ERROR_CODE_INTERNAL_ERROR);
106         return nullptr;
107     }
108     delegate->HideNodeOnOverlay(AceType::Claim(frameNode));
109     return nullptr;
110 }
111 
JSShowAllFrameNodes(napi_env env, napi_callback_info info)112 static napi_value JSShowAllFrameNodes(napi_env env, napi_callback_info info)
113 {
114     auto delegate = EngineHelper::GetCurrentDelegateSafely();
115     if (!delegate) {
116         NapiThrow(env, "UI execution context not found.", ERROR_CODE_INTERNAL_ERROR);
117         return nullptr;
118     }
119     delegate->ShowAllNodesOnOverlay();
120     return nullptr;
121 }
122 
JSHideAllFrameNodes(napi_env env, napi_callback_info info)123 static napi_value JSHideAllFrameNodes(napi_env env, napi_callback_info info)
124 {
125     auto delegate = EngineHelper::GetCurrentDelegateSafely();
126     if (!delegate) {
127         NapiThrow(env, "UI execution context not found.", ERROR_CODE_INTERNAL_ERROR);
128         return nullptr;
129     }
130     delegate->HideAllNodesOnOverlay();
131     return nullptr;
132 }
133 
OverlayManagerExport(napi_env env, napi_value exports)134 static napi_value OverlayManagerExport(napi_env env, napi_value exports)
135 {
136     napi_property_descriptor overlayManagerDesc[] = {
137         DECLARE_NAPI_FUNCTION("addFrameNode", JSAddFrameNode),
138         DECLARE_NAPI_FUNCTION("removeFrameNode", JSRemoveFrameNode),
139         DECLARE_NAPI_FUNCTION("showNode", JSShowNode),
140         DECLARE_NAPI_FUNCTION("hideNode", JSHideNode),
141         DECLARE_NAPI_FUNCTION("showAllFrameNodes", JSShowAllFrameNodes),
142         DECLARE_NAPI_FUNCTION("hideAllFrameNodes", JSHideAllFrameNodes)
143     };
144     NAPI_CALL(env, napi_define_properties(
145         env, exports, sizeof(overlayManagerDesc) / sizeof(overlayManagerDesc[0]), overlayManagerDesc));
146     return exports;
147 }
148 
149 static napi_module overlayManagerModule = {
150     .nm_version = 1,
151     .nm_flags = 0,
152     .nm_filename = nullptr,
153     .nm_register_func = OverlayManagerExport,
154     .nm_modname = "overlay",
155     .nm_priv = ((void*)0),
156     .reserved = { 0 },
157 };
158 
OverlayRegister()159 extern "C" __attribute__((constructor)) void OverlayRegister()
160 {
161     napi_module_register(&overlayManagerModule);
162 }
163 } // namespace OHOS::Ace::Napi
164