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