• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <ani.h>
17 #include <array>
18 #include <iostream>
19 #include <string>
20 #include <vector>
21 
22 #include "frameworks/base/utils/utils.h"
23 #include "frameworks/bridge/common/utils/engine_helper.h"
24 #include "frameworks/core/components_ng/pattern/toast/toast_layout_property.h"
25 #include "frameworks/base/utils/system_properties.h"
26 #include "frameworks/base/geometry/dimension.h"
27 #include "frameworks/core/components/common/properties/shadow.h"
28 #include "promptActionUtils.h"
29 
30 namespace OHOS::Ace::NG {
ContainerIsService()31 bool ContainerIsService()
32 {
33     auto containerId = Container::CurrentIdSafely();
34     // Get active container when current instanceid is less than 0
35     if (containerId < 0) {
36         auto container = Container::GetActive();
37         if (container) {
38             containerId = container->GetInstanceId();
39         }
40     }
41     // for pa service
42     return containerId >= MIN_PA_SERVICE_ID || containerId < 0;
43 }
44 
ContainerIsScenceBoard()45 bool ContainerIsScenceBoard()
46 {
47     auto container = Container::CurrentSafely();
48     if (!container) {
49         container = Container::GetActive();
50     }
51     return container && container->IsSceneBoardWindow();
52 }
53 } // OHOS::Ace::NG
54 
55 std::unordered_map<std::string, int> alignmentMap = {
56     {"TopStart", 0},
57     {"Top", 1},
58     {"TopEnd", 2},
59     {"Start", 3},
60     {"Center", 4},
61     {"End", 5},
62     {"BottomStart", 6},
63     {"Bottom", 7},
64     {"BottomEnd", 8}
65 };
66 
GetToastMessage(ani_env * env,ani_object options,std::string & messageString)67 bool GetToastMessage(ani_env *env, ani_object options, std::string& messageString)
68 {
69     ani_ref message_ref;
70     if (ANI_OK != env->Object_GetPropertyByName_Ref(options, "message", &message_ref)) {
71         return false;
72     }
73     if (GetIsStringObject(env, message_ref)) {
74         auto stringContent = ANIUtils_ANIStringToStdString(env, static_cast<ani_string>(message_ref));
75         messageString = stringContent;
76         return true;
77     }
78     if (GetIsResourceObject(env, message_ref)) {
79         ResourceInfo resourceInfo;
80         std::string messageStr;
81         if (!ParseResourceParam(env, static_cast<ani_object>(message_ref), resourceInfo)) {
82             return false;
83         }
84         if (!ParseString(resourceInfo, messageStr)) {
85             return false;
86         }
87         if (messageStr.size() == 0) {
88             return false;
89         }
90         messageString = messageStr;
91     }
92     return true;
93 }
GetToastDuration(ani_env * env,ani_object options,int32_t & durationInt)94 bool GetToastDuration(ani_env *env, ani_object options, int32_t& durationInt)
95 {
96     ani_ref duration_ref;
97     if (ANI_OK != env->Object_GetPropertyByName_Ref(options, "duration", &duration_ref)) {
98         return false;
99     }
100     if (GetIsUndefinedObject(env, duration_ref)) {
101         return false;
102     }
103     ani_double duration;
104     if (ANI_OK !=env->Object_CallMethodByName_Double(
105         static_cast<ani_object>(duration_ref), "doubleValue", nullptr, &duration)) {
106         return false;
107     }
108     durationInt = static_cast<int32_t>(duration);
109     return true;
110 }
GetToastBottom(ani_env * env,ani_object options,std::string & bottomString)111 bool GetToastBottom(ani_env *env, ani_object options, std::string& bottomString)
112 {
113     ani_ref bottom_ref;
114     if (ANI_OK != env->Object_GetPropertyByName_Ref(options, "bottom", &bottom_ref)) {
115         return false;
116     }
117     if (GetIsUndefinedObject(env, bottom_ref)) {
118         return false;
119     }
120     if (GetIsStringObject(env, bottom_ref)) {
121         auto stringContent = ANIUtils_ANIStringToStdString(env, static_cast<ani_string>(bottom_ref));
122         bottomString = stringContent;
123         return true;
124     }
125     if (GetIsNumberObject(env, bottom_ref)) {
126         ani_double bottom;
127         if (ANI_OK !=env->Object_CallMethodByName_Double(
128             static_cast<ani_object>(bottom_ref), "doubleValue", nullptr, &bottom)) {
129             return false;
130         }
131         double botm = static_cast<double>(bottom);
132         bottomString = std::to_string(botm);
133     }
134     return true;
135 }
GetToastShowMode(ani_env * env,ani_object options,OHOS::Ace::NG::ToastShowMode & showMode)136 bool GetToastShowMode(ani_env *env, ani_object options, OHOS::Ace::NG::ToastShowMode& showMode)
137 {
138     ani_ref showMode_ref;
139     if (ANI_OK != env->Object_GetPropertyByName_Ref(options, "showMode", &showMode_ref)) {
140         return false;
141     }
142     if (GetIsUndefinedObject(env, showMode_ref)) {
143         return false;
144     }
145     if (!GetIsToastShowModeEnum(env, showMode_ref)) {
146         return false;
147     }
148     ani_int showMode_int;
149     if (ANI_OK != env->EnumItem_GetValue_Int(static_cast<ani_enum_item>(showMode_ref), &showMode_int)) {
150         return false;
151     }
152     showMode = static_cast<OHOS::Ace::NG::ToastShowMode>(showMode_int);
153     return true;
154 }
GetToastAlignment(ani_env * env,ani_object options,int32_t & alignment)155 bool GetToastAlignment(ani_env *env, ani_object options, int32_t& alignment)
156 {
157     ani_ref alignment_ref;
158     if (ANI_OK != env->Object_GetPropertyByName_Ref(options, "alignment", &alignment_ref)) {
159         return false;
160     }
161     if (GetIsUndefinedObject(env, alignment_ref)) {
162         return false;
163     }
164     if (!GetIsAlignmentEnum(env, alignment_ref)) {
165         return false;
166     }
167     ani_string stringValue;
168     if (ANI_OK != env->EnumItem_GetValue_String(static_cast<ani_enum_item>(alignment_ref), &stringValue)) {
169         return false;
170     }
171     auto stringContent = ANIUtils_ANIStringToStdString(env, static_cast<ani_string>(stringValue));
172     auto it = alignmentMap.find(stringContent);
173     if (it != alignmentMap.end()) {
174         alignment = static_cast<int32_t>(it->second);
175     } else {
176         alignment = -1;
177         return false;
178     }
179     return true;
180 }
GetToastBackgroundBlurStyle(ani_env * env,ani_object options,std::optional<int32_t> & backgroundBlurStyle)181 bool GetToastBackgroundBlurStyle(ani_env *env, ani_object options, std::optional<int32_t>& backgroundBlurStyle)
182 {
183     ani_ref blurStyle_ref;
184     if (ANI_OK != env->Object_GetPropertyByName_Ref(options, "backgroundBlurStyle", &blurStyle_ref)) {
185         return false;
186     }
187     if (GetIsUndefinedObject(env, blurStyle_ref)) {
188         return false;
189     }
190     if (!GetIsBlurStyleEnum(env, blurStyle_ref)) {
191         return false;
192     }
193     ani_int blueStyle_int;
194     if (ANI_OK != env->EnumItem_GetValue_Int(static_cast<ani_enum_item>(blurStyle_ref), &blueStyle_int)) {
195         return false;
196     }
197     backgroundBlurStyle = static_cast<int32_t>(blueStyle_int);
198     std::cerr << "GetToastBackgroundBlurStyle blueStyle " << static_cast<int32_t>(blueStyle_int) << std::endl;
199     return true;
200 }
GetToastOffset(ani_env * env,ani_object options,std::optional<OHOS::Ace::DimensionOffset> & offset)201 bool GetToastOffset(ani_env *env, ani_object options, std::optional<OHOS::Ace::DimensionOffset>& offset)
202 {
203     ani_ref offset_ref;
204     if (ANI_OK != env->Object_GetPropertyByName_Ref(options, "offset", &offset_ref)) {
205         return false;
206     }
207     if (GetIsUndefinedObject(env, offset_ref)) {
208         return false;
209     }
210     ani_ref dx_ref;
211     if (ANI_OK != env->Object_GetPropertyByName_Ref(static_cast<ani_object>(offset_ref), "dx", &dx_ref)) {
212         return false;
213     }
214     ani_ref dy_ref;
215     if (ANI_OK != env->Object_GetPropertyByName_Ref(static_cast<ani_object>(offset_ref), "dy", &dy_ref)) {
216         return false;
217     }
218     OHOS::Ace::CalcDimension dx;
219     OHOS::Ace::CalcDimension dy;
220     if (!ParseLengthToDimension(env, dx_ref, OHOS::Ace::DimensionUnit::VP, dx)) {
221         return false;
222     }
223     if (!ParseLengthToDimension(env, dy_ref, OHOS::Ace::DimensionUnit::VP, dy)) {
224         return false;
225     }
226     offset = OHOS::Ace::DimensionOffset { dx, dy };
227     return true;
228 }
GetToastShadow(ani_env * env,ani_object options,std::optional<OHOS::Ace::Shadow> & shadow,bool & isTypeStyleShadow)229 bool GetToastShadow(ani_env *env, ani_object options, std::optional<OHOS::Ace::Shadow>& shadow,
230                     bool& isTypeStyleShadow)
231 {
232     ani_ref shadow_ref;
233     if (ANI_OK != env->Object_GetPropertyByName_Ref(options, "shadow", &shadow_ref)) {
234         return false;
235     }
236     if (GetIsUndefinedObject(env, shadow_ref)) {
237         return false;
238     }
239     OHOS::Ace::Shadow shadowProps;
240     if (GetIsShadowStyleEnum(env, shadow_ref)) {
241         ani_int shadow_int;
242         if (ANI_OK != env->EnumItem_GetValue_Int(static_cast<ani_enum_item>(shadow_ref), &shadow_int)) {
243             return false;
244         }
245         auto style = static_cast<OHOS::Ace::ShadowStyle>(shadow_int);
246         GetShadowFromTheme(style, shadowProps);
247         shadow = shadowProps;
248         return true;
249     }
250     if (GetIsShadowOptionsObject(env, shadow_ref)) {
251         bool ret = GetToastObjectShadow(env, static_cast<ani_object>(shadow_ref), shadowProps);
252         isTypeStyleShadow = false;
253         return ret;
254     }
255     return true;
256 }
GetToastBackgroundColor(ani_env * env,ani_object options,std::optional<OHOS::Ace::Color> & backgroundColor)257 bool GetToastBackgroundColor(ani_env* env, ani_object options, std::optional<OHOS::Ace::Color>& backgroundColor)
258 {
259     ani_ref resourceColor_ref;
260     if (ANI_OK != env->Object_GetPropertyByName_Ref(options, "backgroundColor", &resourceColor_ref)) {
261         return false;
262     }
263     if (GetIsUndefinedObject(env, resourceColor_ref)) {
264         return false;
265     }
266     OHOS::Ace::Color resourceColor;
267     if (ParseAniColor(env, resourceColor_ref, resourceColor)) {
268         backgroundColor = resourceColor;
269         return true;
270     }
271     return false;
272 }
GetToastTextColor(ani_env * env,ani_object options,std::optional<OHOS::Ace::Color> & textColor)273 bool GetToastTextColor(ani_env* env, ani_object options, std::optional<OHOS::Ace::Color>& textColor)
274 {
275     ani_ref resourceColor_ref;
276     if (ANI_OK != env->Object_GetPropertyByName_Ref(options, "textColor", &resourceColor_ref)) {
277         return false;
278     }
279     if (GetIsUndefinedObject(env, resourceColor_ref)) {
280         return false;
281     }
282     OHOS::Ace::Color resourceColor;
283     if (ParseAniColor(env, resourceColor_ref, resourceColor)) {
284         textColor = resourceColor;
285         return true;
286     }
287     return false;
288 }
GetToastEnableHoverMode(ani_env * env,ani_object options,bool & enableHoverMode)289 bool GetToastEnableHoverMode(ani_env* env, ani_object options, bool& enableHoverMode)
290 {
291     ani_ref mode_ref;
292     if (ANI_OK != env->Object_GetPropertyByName_Ref(options, "enableHoverMode", &mode_ref)) {
293         return false;
294     }
295     if (GetIsUndefinedObject(env, mode_ref)) {
296         return false;
297     }
298     ani_boolean modeValue;
299     if (ANI_OK != env->Object_CallMethodByName_Boolean(
300         static_cast<ani_object>(mode_ref), "unboxed", nullptr, &modeValue)) {
301         return false;
302     }
303     enableHoverMode = static_cast<bool>(modeValue);
304     return true;
305 }
GetToastHoverModeArea(ani_env * env,ani_object options,OHOS::Ace::HoverModeAreaType & hoverModeArea)306 bool GetToastHoverModeArea(ani_env* env, ani_object options, OHOS::Ace::HoverModeAreaType& hoverModeArea)
307 {
308     ani_ref area_ref;
309     if (ANI_OK != env->Object_GetPropertyByName_Ref(options, "hoverModeArea", &area_ref)) {
310         return false;
311     }
312     if (GetIsUndefinedObject(env, area_ref)) {
313         return false;
314     }
315     if (!GetIsHoverModeAreaEnum(env, area_ref)) {
316         return false;
317     }
318     ani_int area_int;
319     if (ANI_OK != env->EnumItem_GetValue_Int(static_cast<ani_enum_item>(area_ref), &area_int)) {
320         return false;
321     }
322     hoverModeArea = static_cast<OHOS::Ace::HoverModeAreaType>(area_int);
323     return true;
324 }
GetToastParams(ani_env * env,ani_object options,OHOS::Ace::NG::ToastInfo toastInfo)325 bool GetToastParams(ani_env* env, ani_object options, OHOS::Ace::NG::ToastInfo toastInfo)
326 {
327     if (GetIsUndefinedObject(env, options)) {
328         return false;
329     }
330     if (!GetIsShowToastOptionsObject(env, options)) {
331         return false;
332     }
333     GetToastMessage(env, options, toastInfo.message);
334     std::cout << "GetToastMessage :" << toastInfo.message.c_str() << std::endl;
335     GetToastDuration(env, options, toastInfo.duration);
336     std::cout << "GetToastDuration :" << toastInfo.duration << std::endl;
337     GetToastBottom(env, options, toastInfo.bottom);
338     std::cout << "GetToastBottom :" << toastInfo.bottom.c_str() << std::endl;
339     GetToastShowMode(env, options, toastInfo.showMode);
340     std::cout << "GetToastShowMode :" << static_cast<int32_t>(toastInfo.showMode) << std::endl;
341     GetToastAlignment(env, options, toastInfo.alignment);
342     std::cout << "GetToastAlignment :" << static_cast<int32_t>(toastInfo.alignment) << std::endl;
343     GetToastBackgroundBlurStyle(env, options, toastInfo.backgroundBlurStyle);
344     GetToastBackgroundColor(env, options, toastInfo.backgroundColor);
345     std::cout << "GetToastBackgroundColor :" << toastInfo.backgroundColor->ToString().c_str() << std::endl;
346     GetToastTextColor(env, options, toastInfo.textColor);
347     std::cout << "GetToastTextColor :" << toastInfo.textColor->ToString().c_str() << std::endl;
348     GetToastOffset(env, options, toastInfo.offset);
349     GetToastShadow(env, options, toastInfo.shadow, toastInfo.isTypeStyleShadow);
350     GetToastEnableHoverMode(env, options, toastInfo.enableHoverMode);
351     std::cout << "GetToastEnableHoverModer :" << toastInfo.enableHoverMode << std::endl;
352     GetToastHoverModeArea(env, options, toastInfo.hoverModeArea);
353     std::cout << "GetToastHoverModeArea :" << (int)toastInfo.hoverModeArea << std::endl;
354     return true;
355 }
HandleShowToast(OHOS::Ace::NG::ToastInfo & toastInfo,std::function<void (int32_t)> & toastCallback)356 bool HandleShowToast(OHOS::Ace::NG::ToastInfo& toastInfo, std::function<void(int32_t)>& toastCallback)
357 {
358     if ((OHOS::Ace::SystemProperties::GetExtSurfaceEnabled() || !OHOS::Ace::NG::ContainerIsService())
359         && !OHOS::Ace::NG::ContainerIsScenceBoard() && toastInfo.showMode == OHOS::Ace::NG::ToastShowMode::DEFAULT) {
360         auto delegate = OHOS::Ace::EngineHelper::GetCurrentDelegateSafely();
361         if (!delegate) {
362             return false;
363         }
364         delegate->ShowToast(toastInfo, std::move(toastCallback));
365     }
366     return true;
367 }
showToast(ani_env * env,ani_object options)368 static void showToast([[maybe_unused]] ani_env* env, ani_object options)
369 {
370     std::cout << "ani showToast start" << std::endl;
371     auto toastInfo = OHOS::Ace::NG::ToastInfo { .duration = -1,
372         .showMode = OHOS::Ace::NG::ToastShowMode::DEFAULT,
373         .alignment = -1 };
374     if (!GetToastParams(env, options, toastInfo)) {
375         return;
376     }
377     std::function<void(int32_t)> toastCallback = nullptr;
378     HandleShowToast(toastInfo, toastCallback);
379     std::cerr << "ShowToast end" << std::endl;
380 }
ANI_Constructor(ani_vm * vm,uint32_t * result)381 ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result)
382 {
383     std::cout << "ani ANI_Constructor start" << std::endl;
384 
385     ani_env *env;
386     if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) {
387         return ANI_ERROR;
388     }
389 
390     ani_namespace ns;
391     if (ANI_OK != env->FindNamespace("L@ohos/promptAction/promptAction;", &ns)) {
392         return ANI_ERROR;
393     }
394     std::array methods = {
395         ani_native_function {"showToast", nullptr, reinterpret_cast<void *>(showToast)},
396     };
397     if (ANI_OK != env->Namespace_BindNativeFunctions(ns, methods.data(), methods.size())) {
398         return ANI_ERROR;
399     }
400 
401     *result = ANI_VERSION_1;
402     std::cout << "ani ANI_Constructor end" << std::endl;
403     return ANI_OK;
404 }
405