1 /*
2 * Copyright (C) 2025 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/promptaction/js_level_order.h"
17
18 #include "base/subwindow/subwindow_manager.h"
19 #include "bridge/common/utils/engine_helper.h"
20 #include "core/components_ng/pattern/overlay/level_order.h"
21 #include "interfaces/napi/kits/utils/napi_utils.h"
22 #include "napi/native_api.h"
23 #include "napi/native_node_api.h"
24
25 namespace OHOS::Ace::Napi {
26 namespace {
27 const int32_t CLAMP_PARAM_TOTAL = 2;
28 #ifdef OHOS_STANDARD_SYSTEM
ContainerIsService()29 bool ContainerIsService()
30 {
31 auto containerId = Container::CurrentIdSafely();
32 // Get active container when current instanceid is less than 0
33 if (containerId < 0) {
34 auto container = Container::GetActive();
35 if (container) {
36 containerId = container->GetInstanceId();
37 }
38 }
39 // for pa service
40 return containerId >= MIN_PA_SERVICE_ID || containerId < 0;
41 }
42 #endif
43 } // namespace
44
Destructor(napi_env env,void * data,void * hint)45 void JSLevelOrder::Destructor(napi_env env, void* data, void* hint)
46 {
47 NG::LevelOrder* levelOrder = reinterpret_cast<NG::LevelOrder*>(data);
48 CHECK_NULL_VOID(levelOrder);
49 delete levelOrder;
50 levelOrder = nullptr;
51 }
52
GetOrder(napi_env env,std::optional<double> levelOrder)53 napi_value JSLevelOrder::GetOrder(napi_env env, std::optional<double> levelOrder)
54 {
55 if (!levelOrder.has_value()) {
56 return nullptr;
57 }
58
59 napi_value result = nullptr;
60 napi_create_double(env, levelOrder.value(), &result);
61 return result;
62 }
63
JSClamp(napi_env env,napi_callback_info info)64 napi_value JSLevelOrder::JSClamp(napi_env env, napi_callback_info info)
65 {
66 size_t argc = CLAMP_PARAM_TOTAL;
67 napi_value argv[CLAMP_PARAM_TOTAL] = { nullptr };
68 napi_value thisArg = nullptr;
69 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, nullptr));
70 if (argc < CLAMP_PARAM_TOTAL) {
71 NapiThrow(env, "The number of parameters is incorrect.", ERROR_CODE_PARAM_INVALID);
72 return nullptr;
73 }
74
75 NG::LevelOrder* levelOrder = new (std::nothrow) NG::LevelOrder();
76 napi_status status = napi_wrap(env, argv[0], levelOrder, Destructor, nullptr, nullptr);
77 if (status != napi_ok) {
78 LOGE("Failed to wrap LevelOrder.");
79 delete levelOrder;
80 return nullptr;
81 }
82
83 CHECK_NULL_RETURN(levelOrder, nullptr);
84 napi_valuetype valueType = napi_undefined;
85 napi_typeof(env, argv[1], &valueType);
86 if (valueType != napi_number) {
87 levelOrder->SetOrder(NG::LevelOrder::ORDER_DEFAULT);
88 return thisArg;
89 }
90
91 double order = NG::LevelOrder::ORDER_DEFAULT;
92 napi_get_value_double(env, argv[1], &order);
93 levelOrder->SetOrder(order);
94 return thisArg;
95 }
96
JSGetOrder(napi_env env,napi_callback_info info)97 napi_value JSLevelOrder::JSGetOrder(napi_env env, napi_callback_info info)
98 {
99 size_t argc = 1;
100 napi_value argv[1] = { nullptr };
101 napi_value thisArg = nullptr;
102 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, nullptr));
103 if (argc < 1) {
104 NapiThrow(env, "The number of parameters is incorrect.", ERROR_CODE_PARAM_INVALID);
105 return nullptr;
106 }
107
108 NG::LevelOrder* levelOrder = nullptr;
109 napi_status status = napi_unwrap(env, argv[0], reinterpret_cast<void**>(&levelOrder));
110 if (status != napi_ok || !levelOrder) {
111 LOGE("Failed to unwrap LevelOrder.");
112 return nullptr;
113 }
114
115 double order = levelOrder->GetOrder();
116 return GetOrder(env, std::make_optional(order));
117 }
118
JSGetTopOrder(napi_env env,napi_callback_info info)119 napi_value JSLevelOrder::JSGetTopOrder(napi_env env, napi_callback_info info)
120 {
121 #ifdef OHOS_STANDARD_SYSTEM
122 if (SystemProperties::GetExtSurfaceEnabled() || !ContainerIsService()) {
123 auto delegate = EngineHelper::GetCurrentDelegateSafely();
124 if (delegate) {
125 std::optional<double> topOrder = delegate->GetTopOrder();
126 return GetOrder(env, topOrder);
127 }
128 } else if (SubwindowManager::GetInstance() != nullptr) {
129 std::optional<double> topOrder = SubwindowManager::GetInstance()->GetTopOrder();
130 return GetOrder(env, topOrder);
131 }
132 #else
133 auto delegate = EngineHelper::GetCurrentDelegateSafely();
134 if (delegate) {
135 std::optional<double> topOrder = delegate->GetTopOrder();
136 return GetOrder(env, topOrder);
137 }
138 #endif
139 return nullptr;
140 }
141
JSGetBottomOrder(napi_env env,napi_callback_info info)142 napi_value JSLevelOrder::JSGetBottomOrder(napi_env env, napi_callback_info info)
143 {
144 #ifdef OHOS_STANDARD_SYSTEM
145 if (SystemProperties::GetExtSurfaceEnabled() || !ContainerIsService()) {
146 auto delegate = EngineHelper::GetCurrentDelegateSafely();
147 if (delegate) {
148 std::optional<double> bottomOrder = delegate->GetBottomOrder();
149 return GetOrder(env, bottomOrder);
150 }
151 } else if (SubwindowManager::GetInstance() != nullptr) {
152 std::optional<double> bottomOrder = SubwindowManager::GetInstance()->GetBottomOrder();
153 return GetOrder(env, bottomOrder);
154 }
155 #else
156 auto delegate = EngineHelper::GetCurrentDelegateSafely();
157 if (delegate) {
158 std::optional<double> bottomOrder = delegate->GetBottomOrder();
159 return GetOrder(env, bottomOrder);
160 }
161 #endif
162 return nullptr;
163 }
164
Define(napi_env env,napi_value exports)165 napi_status JSLevelOrder::Define(napi_env env, napi_value exports)
166 {
167 napi_value levelOrder = nullptr;
168 napi_create_object(env, &levelOrder);
169
170 napi_value clampFunc = nullptr;
171 napi_create_function(env, "clamp", NAPI_AUTO_LENGTH, JSClamp, nullptr, &clampFunc);
172 napi_set_named_property(env, levelOrder, "clamp", clampFunc);
173 napi_value getOrderFunc = nullptr;
174 napi_create_function(env, "getOrder", NAPI_AUTO_LENGTH, JSGetOrder, nullptr, &getOrderFunc);
175 napi_set_named_property(env, levelOrder, "getOrder", getOrderFunc);
176 napi_value getTopOrderFunc = nullptr;
177 napi_create_function(env, "getTopOrder", NAPI_AUTO_LENGTH, JSGetTopOrder, nullptr, &getTopOrderFunc);
178 napi_set_named_property(env, levelOrder, "getTopOrder", getTopOrderFunc);
179 napi_value getBottomOrderFunc = nullptr;
180 napi_create_function(env, "getBottomOrder", NAPI_AUTO_LENGTH, JSGetBottomOrder, nullptr, &getBottomOrderFunc);
181 napi_set_named_property(env, levelOrder, "getBottomOrder", getBottomOrderFunc);
182
183 napi_set_named_property(env, exports, "LevelOrder", levelOrder);
184 return napi_ok;
185 }
186 } // namespace OHOS::Ace::Napi
187